This commit is contained in:
ktianc 2022-09-16 17:34:17 +08:00
parent 23cec8f081
commit 782ba23435
54 changed files with 128 additions and 4882 deletions

View File

@ -54,30 +54,30 @@ export default [
}
},
// 登录接口
{
url: '/user/login',
method: 'post',
timeout,
response: ({ body }) => {
const data = body
let hasUser = false
for (const user of List) {
if (user.username === data.username && user.password === data.password) {
hasUser = true
return {
code: result_code,
data: user
}
}
}
if (!hasUser) {
return {
code: '500',
message: '账号或密码错误'
}
}
}
},
// {
// url: '/user/login',
// method: 'post',
// timeout,
// response: ({ body }) => {
// const data = body
// let hasUser = false
// for (const user of List) {
// if (user.username === data.username && user.password === data.password) {
// hasUser = true
// return {
// code: result_code,
// data: user
// }
// }
// }
// if (!hasUser) {
// return {
// code: '500',
// message: '手机号或密码错误'
// }
// }
// }
// },
// 退出接口
{
url: '/user/loginOut',

View File

@ -1,12 +1,12 @@
import request from '@/config/axios'
import type { UserType } from './types'
import type { UserLoginType, UserType } from './types'
interface RoleParams {
roleName: string
}
export const loginApi = (data: UserType): Promise<IResponse<UserType>> => {
return request.post({ url: '/user/login', data })
export const loginApi = (data: UserLoginType): Promise<IResponse> => {
return request.post({ url: '/api/auth/login', data })
}
export const loginOutApi = (): Promise<IResponse> => {

View File

@ -1,10 +1,10 @@
export type UserLoginType = {
username: string
telephone: string
password: string
}
export type UserType = {
username: string
telephone: string
password: string
role: string
roleId: string

View File

@ -52,7 +52,7 @@ export const appModules: AppState = {
sizeMap: ['default', 'large', 'small'],
mobile: false, // 是否是移动端
title: import.meta.env.VITE_APP_TITLE, // 标题
pageLoading: false, // 路由跳转loading
pageLoading: true, // 路由跳转loading
breadcrumb: true, // 面包屑
breadcrumbIcon: true, // 面包屑图标
@ -68,7 +68,7 @@ export const appModules: AppState = {
fixedHeader: true, // 固定toolheader
footer: true, // 显示页脚
greyMode: false, // 是否开始灰色模式,用于特殊悼念日
dynamicRouter: wsCache.get('dynamicRouter') || false, // 是否动态路由
dynamicRouter: wsCache.get('dynamicRouter') || true, // 是否动态路由
layout: wsCache.get('layout') || 'classic', // layout布局
isDark: wsCache.get('isDark') || false, // 是否是暗黑模式

View File

@ -29,7 +29,7 @@ const config: {
/**
*
*/
result_code: '0000',
result_code: '200',
/**
*

View File

@ -43,7 +43,7 @@ service.interceptors.request.use(
},
(error: AxiosError) => {
// Do something with request error
console.log(error) // for debug
console.log('请求报错', error) // for debug
Promise.reject(error)
}
)
@ -61,8 +61,16 @@ service.interceptors.response.use(
}
},
(error: AxiosError) => {
console.log('err' + error) // for debug
ElMessage.error(error.message)
console.log('err' + error)
let { message } = error
if (message == 'Network Error') {
message = '后端接口连接异常'
} else if (message.includes('timeout')) {
message = '系统接口请求超时'
} else if (message.includes('Request failed with status code')) {
message = '系统接口' + message.substr(message.length - 3) + '异常'
}
ElMessage.error(message)
return Promise.reject(error)
}
)

View File

@ -87,6 +87,7 @@ export default {
welcome: 'Welcome to the system',
message: 'Backstage management system',
username: 'Username',
telephone: 'Telephone',
password: 'Password',
register: 'Register',
checkPassword: 'Confirm password',
@ -96,6 +97,7 @@ export default {
hasUser: 'Existing account? Go to login',
forgetPassword: 'Forget password',
usernamePlaceholder: 'Please input username',
telephonePlaceholder: 'Please input telephone',
passwordPlaceholder: 'Please input password',
code: 'Verification code',
codePlaceholder: 'Please input verification code'

View File

@ -87,6 +87,7 @@ export default {
welcome: '欢迎使用本系统',
message: '开箱即用的中后台管理系统',
username: '用户名',
telephone: '手机号',
password: '密码',
register: '注册',
checkPassword: '确认密码',
@ -96,6 +97,7 @@ export default {
hasUser: '已有账号?去登录',
forgetPassword: '忘记密码',
usernamePlaceholder: '请输入用户名',
telephonePlaceholder: '请输入手机号',
passwordPlaceholder: '请输入密码',
code: '验证码',
codePlaceholder: '请输入验证码'

View File

@ -87,432 +87,6 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
}
}
]
},
{
path: '/external-link',
component: Layout,
meta: {},
name: 'ExternalLink',
children: [
{
path: 'https://element-plus-admin-doc.cn/',
name: 'DocumentLink',
meta: {
title: t('router.document'),
icon: 'clarity:document-solid'
}
}
]
},
{
path: '/guide',
component: Layout,
name: 'Guide',
meta: {},
children: [
{
path: 'index',
component: () => import('@/views/Guide/Guide.vue'),
name: 'GuideDemo',
meta: {
title: t('router.guide'),
icon: 'cib:telegram-plane'
}
}
]
},
{
path: '/components',
component: Layout,
name: 'ComponentsDemo',
meta: {
title: t('router.component'),
icon: 'bx:bxs-component',
alwaysShow: true
},
children: [
{
path: 'form',
component: getParentLayout(),
redirect: '/components/form/default-form',
name: 'Form',
meta: {
title: t('router.form'),
alwaysShow: true
},
children: [
{
path: 'default-form',
component: () => import('@/views/Components/Form/DefaultForm.vue'),
name: 'DefaultForm',
meta: {
title: t('router.defaultForm')
}
},
{
path: 'use-form',
component: () => import('@/views/Components/Form/UseFormDemo.vue'),
name: 'UseForm',
meta: {
title: 'UseForm'
}
},
{
path: 'ref-form',
component: () => import('@/views/Components/Form/RefForm.vue'),
name: 'RefForm',
meta: {
title: 'RefForm'
}
}
]
},
{
path: 'table',
component: getParentLayout(),
redirect: '/components/table/default-table',
name: 'TableDemo',
meta: {
title: t('router.table'),
alwaysShow: true
},
children: [
{
path: 'default-table',
component: () => import('@/views/Components/Table/DefaultTable.vue'),
name: 'DefaultTable',
meta: {
title: t('router.defaultTable')
}
},
{
path: 'use-table',
component: () => import('@/views/Components/Table/UseTableDemo.vue'),
name: 'UseTable',
meta: {
title: 'UseTable'
}
},
{
path: 'ref-table',
component: () => import('@/views/Components/Table/RefTable.vue'),
name: 'RefTable',
meta: {
title: 'RefTable'
}
}
]
},
{
path: 'editor-demo',
component: getParentLayout(),
redirect: '/components/editor-demo/editor',
name: 'EditorDemo',
meta: {
title: t('router.editor'),
alwaysShow: true
},
children: [
{
path: 'editor',
component: () => import('@/views/Components/Editor/Editor.vue'),
name: 'Editor',
meta: {
title: t('router.richText')
}
}
]
},
{
path: 'search',
component: () => import('@/views/Components/Search.vue'),
name: 'Search',
meta: {
title: t('router.search')
}
},
{
path: 'descriptions',
component: () => import('@/views/Components/Descriptions.vue'),
name: 'Descriptions',
meta: {
title: t('router.descriptions')
}
},
{
path: 'image-viewer',
component: () => import('@/views/Components/ImageViewer.vue'),
name: 'ImageViewer',
meta: {
title: t('router.imageViewer')
}
},
{
path: 'dialog',
component: () => import('@/views/Components/Dialog.vue'),
name: 'Dialog',
meta: {
title: t('router.dialog')
}
},
{
path: 'icon',
component: () => import('@/views/Components/Icon.vue'),
name: 'Icon',
meta: {
title: t('router.icon')
}
},
{
path: 'echart',
component: () => import('@/views/Components/Echart.vue'),
name: 'Echart',
meta: {
title: t('router.echart')
}
},
{
path: 'count-to',
component: () => import('@/views/Components/CountTo.vue'),
name: 'CountTo',
meta: {
title: t('router.countTo')
}
},
{
path: 'qrcode',
component: () => import('@/views/Components/Qrcode.vue'),
name: 'Qrcode',
meta: {
title: t('router.qrcode')
}
},
{
path: 'highlight',
component: () => import('@/views/Components/Highlight.vue'),
name: 'Highlight',
meta: {
title: t('router.highlight')
}
},
{
path: 'infotip',
component: () => import('@/views/Components/Infotip.vue'),
name: 'Infotip',
meta: {
title: t('router.infotip')
}
},
{
path: 'input-password',
component: () => import('@/views/Components/InputPassword.vue'),
name: 'InputPassword',
meta: {
title: t('router.inputPassword')
}
},
{
path: 'sticky',
component: () => import('@/views/Components/Sticky.vue'),
name: 'Sticky',
meta: {
title: t('router.sticky')
}
}
]
},
{
path: '/hooks',
component: Layout,
redirect: '/hooks/useWatermark',
name: 'Hooks',
meta: {
title: 'hooks',
icon: 'ic:outline-webhook',
alwaysShow: true
},
children: [
{
path: 'useWatermark',
component: () => import('@/views/hooks/useWatermark.vue'),
name: 'UseWatermark',
meta: {
title: 'useWatermark'
}
},
{
path: 'useCrudSchemas',
component: () => import('@/views/hooks/useCrudSchemas.vue'),
name: 'UseCrudSchemas',
meta: {
title: 'useCrudSchemas'
}
}
]
},
{
path: '/level',
component: Layout,
redirect: '/level/menu1/menu1-1/menu1-1-1',
name: 'Level',
meta: {
title: t('router.level'),
icon: 'carbon:skill-level-advanced'
},
children: [
{
path: 'menu1',
name: 'Menu1',
component: getParentLayout(),
redirect: '/level/menu1/menu1-1/menu1-1-1',
meta: {
title: t('router.menu1')
},
children: [
{
path: 'menu1-1',
name: 'Menu11',
component: getParentLayout(),
redirect: '/level/menu1/menu1-1/menu1-1-1',
meta: {
title: t('router.menu11'),
alwaysShow: true
},
children: [
{
path: 'menu1-1-1',
name: 'Menu111',
component: () => import('@/views/Level/Menu111.vue'),
meta: {
title: t('router.menu111')
}
}
]
},
{
path: 'menu1-2',
name: 'Menu12',
component: () => import('@/views/Level/Menu12.vue'),
meta: {
title: t('router.menu12')
}
}
]
},
{
path: 'menu2',
name: 'Menu2',
component: () => import('@/views/Level/Menu2.vue'),
meta: {
title: t('router.menu2')
}
}
]
},
{
path: '/example',
component: Layout,
redirect: '/example/example-dialog',
name: 'Example',
meta: {
title: t('router.example'),
icon: 'ep:management',
alwaysShow: true
},
children: [
{
path: 'example-dialog',
component: () => import('@/views/Example/Dialog/ExampleDialog.vue'),
name: 'ExampleDialog',
meta: {
title: t('router.exampleDialog')
}
},
{
path: 'example-page',
component: () => import('@/views/Example/Page/ExamplePage.vue'),
name: 'ExamplePage',
meta: {
title: t('router.examplePage')
}
},
{
path: 'example-add',
component: () => import('@/views/Example/Page/ExampleAdd.vue'),
name: 'ExampleAdd',
meta: {
title: t('router.exampleAdd'),
noTagsView: true,
noCache: true,
hidden: true,
canTo: true,
activeMenu: '/example/example-page'
}
},
{
path: 'example-edit',
component: () => import('@/views/Example/Page/ExampleEdit.vue'),
name: 'ExampleEdit',
meta: {
title: t('router.exampleEdit'),
noTagsView: true,
noCache: true,
hidden: true,
canTo: true,
activeMenu: '/example/example-page'
}
},
{
path: 'example-detail',
component: () => import('@/views/Example/Page/ExampleDetail.vue'),
name: 'ExampleDetail',
meta: {
title: t('router.exampleDetail'),
noTagsView: true,
noCache: true,
hidden: true,
canTo: true,
activeMenu: '/example/example-page'
}
}
]
},
{
path: '/error',
component: Layout,
redirect: '/error/404',
name: 'Error',
meta: {
title: t('router.errorPage'),
icon: 'ci:error',
alwaysShow: true
},
children: [
{
path: '404-demo',
component: () => import('@/views/Error/404.vue'),
name: '404Demo',
meta: {
title: '404'
}
},
{
path: '403-demo',
component: () => import('@/views/Error/403.vue'),
name: '403Demo',
meta: {
title: '403'
}
},
{
path: '500-demo',
component: () => import('@/views/Error/500.vue'),
name: '500Demo',
meta: {
title: '500'
}
}
]
}
// {
// path: '/authorization',

View File

@ -12,6 +12,7 @@ export const useAppStore = defineStore({
id: 'app',
state: (): AppState => appModules,
persist: {
// 开启持久化存储
enabled: true
},
getters: {

View File

@ -0,0 +1,52 @@
import { defineStore } from 'pinia'
import { store } from '../index'
import { UserLoginType } from '@/api/login/types'
import { loginApi } from '@/api/login'
export interface AuthState {
token: string
is_reset_password: boolean
user_id: number
}
export const useAuthStore = defineStore({
id: 'auth',
state: (): AuthState => ({
token: '',
is_reset_password: false,
user_id: 0
}),
persist: {
// 开启持久化存储
enabled: true
},
getters: {
getToken(): string {
return this.token
},
getUserId(): number {
return this.user_id
},
getIsResetPassword(): boolean {
return this.is_reset_password
}
},
actions: {
async login(formData: UserLoginType) {
const res = await loginApi(formData)
if (res) {
console.log('登录成功', res)
} else {
console.log('登录失败', res)
}
// this.token = token
// this.is_reset_password = is_reset_password
// this.user_id = user_id
return res
}
}
})
export const useAuthStoreWithOut = () => {
return useAuthStore(store)
}

View File

@ -13,6 +13,7 @@ export const useDictStore = defineStore({
dictObj: {}
}),
persist: {
// 开启持久化存储
enabled: true
},
getters: {

View File

@ -10,6 +10,7 @@ export const useLocaleStore = defineStore({
id: 'locales',
state: (): LocaleState => localeModules,
persist: {
// 开启持久化存储
enabled: true
},
getters: {

View File

@ -20,6 +20,7 @@ export const usePermissionStore = defineStore({
menuTabRouters: []
}),
persist: {
// 开启持久化存储
enabled: true
},
getters: {

View File

@ -1,100 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { CountTo } from '@/components/CountTo'
import { ElRow, ElCol, ElInputNumber, ElInput, ElButton } from 'element-plus'
import { ref, unref } from 'vue'
const { t } = useI18n()
const countRef = ref<ComponentRef<typeof CountTo>>()
const startVal = ref(0)
const endVal = ref(1314512)
const duration = ref(3000)
const decimals = ref(0)
const separator = ref(',')
const prefix = ref('¥ ')
const suffix = ref(' rmb')
const autoplay = ref(false)
const start = () => {
unref(countRef)?.start()
}
const pauseResume = () => {
unref(countRef)?.pauseResume()
}
</script>
<template>
<ContentWrap :title="t('countToDemo.countTo')" :message="t('countToDemo.countToDes')">
<div class="text-center mb-40px">
<CountTo
ref="countRef"
:start-val="startVal"
:end-val="endVal"
:duration="duration"
:decimals="decimals"
:separator="separator"
:prefix="prefix"
:suffix="suffix"
:autoplay="autoplay"
class="text-30px font-bold text-[var(--el-color-primary)]"
/>
</div>
<ElRow :gutter="20" justify="space-between">
<ElCol :xl="8" :lg="8" :md="12" :sm="24" :xs="24">
<div class="flex mb-20px items-center">
<span class="min-w-90px text-right">{{ t('countToDemo.startVal') }}</span>
<ElInputNumber v-model="startVal" :min="0" />
</div>
</ElCol>
<ElCol :xl="8" :lg="8" :md="12" :sm="24" :xs="24">
<div class="flex mb-20px items-center">
<span class="min-w-90px text-right">{{ t('countToDemo.endVal') }}</span>
<ElInputNumber v-model="endVal" :min="1" />
</div>
</ElCol>
<ElCol :xl="8" :lg="8" :md="12" :sm="24" :xs="24">
<div class="flex mb-20px items-center">
<span class="min-w-90px text-right">{{ t('countToDemo.duration') }}</span>
<ElInputNumber v-model="duration" :min="1000" />
</div>
</ElCol>
<ElCol :xl="8" :lg="8" :md="12" :sm="24" :xs="24">
<div class="flex mb-20px items-center">
<span class="min-w-90px text-right">{{ t('countToDemo.separator') }}</span>
<ElInput v-model="separator" />
</div>
</ElCol>
<ElCol :xl="8" :lg="8" :md="12" :sm="24" :xs="24">
<div class="flex mb-20px items-center">
<span class="min-w-90px text-right">{{ t('countToDemo.prefix') }}</span>
<ElInput v-model="prefix" />
</div>
</ElCol>
<ElCol :xl="8" :lg="8" :md="12" :sm="24" :xs="24">
<div class="flex mb-20px items-center">
<span class="min-w-90px text-right">{{ t('countToDemo.suffix') }}</span>
<ElInput v-model="suffix" />
</div>
</ElCol>
<ElCol :span="24">
<div class="text-center">
<ElButton type="primary" @click="start">{{ t('countToDemo.start') }}</ElButton>
<ElButton @click="pauseResume">
{{ t('countToDemo.pause') }}/{{ t('countToDemo.resume') }}
</ElButton>
</div>
</ElCol>
</ElRow>
</ContentWrap>
</template>

View File

@ -1,142 +0,0 @@
<script setup lang="ts">
import { Descriptions } from '@/components/Descriptions'
import { useI18n } from '@/hooks/web/useI18n'
import { reactive, unref } from 'vue'
import { Form } from '@/components/Form'
import { ElFormItem, ElInput, ElButton } from 'element-plus'
import { useValidator } from '@/hooks/web/useValidator'
import { useForm } from '@/hooks/web/useForm'
const { required } = useValidator()
const { t } = useI18n()
const data = reactive({
username: 'chenkl',
nickName: '梦似花落。',
age: 26,
phone: '13655971xxxx',
email: '502431556@qq.com',
addr: '这是一个很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的地址',
sex: '男',
certy: '3505831994xxxxxxxx'
})
const schema = reactive<DescriptionsSchema[]>([
{
field: 'username',
label: t('descriptionsDemo.username')
},
{
field: 'nickName',
label: t('descriptionsDemo.nickName')
},
{
field: 'phone',
label: t('descriptionsDemo.phone')
},
{
field: 'email',
label: t('descriptionsDemo.email')
},
{
field: 'addr',
label: t('descriptionsDemo.addr'),
span: 24
}
])
const form = reactive({
username: '',
nickName: '',
phone: '',
email: '',
addr: ''
})
const rules = reactive({
username: [required()],
nickName: [required()],
phone: [required()],
email: [required()],
addr: [required()]
})
const { register, elFormRef } = useForm()
const formValidation = () => {
unref(elFormRef)!.validate((isValid) => {
console.log(isValid)
})
}
</script>
<template>
<Descriptions
:title="t('descriptionsDemo.descriptions')"
:message="t('descriptionsDemo.descriptionsDes')"
:data="data"
:schema="schema"
/>
<Form is-custom :model="form" :rules="rules" @register="register">
<Descriptions :title="t('descriptionsDemo.form')" :data="data" :schema="schema" class="mt-20px">
<template #username-label="scope">
<span class="is-required--item">{{ scope.label }}</span>
</template>
<template #nickName-label="scope">
<span class="is-required--item">{{ scope.label }}</span>
</template>
<template #phone-label="scope">
<span class="is-required--item">{{ scope.label }}</span>
</template>
<template #email-label="scope">
<span class="is-required--item">{{ scope.label }}</span>
</template>
<template #addr-label="scope">
<span class="is-required--item">{{ scope.label }}</span>
</template>
<template #username>
<ElFormItem prop="username">
<ElInput v-model="form.username" />
</ElFormItem>
</template>
<template #nickName>
<ElFormItem prop="nickName">
<ElInput v-model="form.nickName" />
</ElFormItem>
</template>
<template #phone>
<ElFormItem prop="phone">
<ElInput v-model="form.phone" />
</ElFormItem>
</template>
<template #email>
<ElFormItem prop="email">
<ElInput v-model="form.email" />
</ElFormItem>
</template>
<template #addr>
<ElFormItem prop="addr">
<ElInput v-model="form.addr" />
</ElFormItem>
</template>
</Descriptions>
<div class="text-center mt-10px">
<ElButton @click="formValidation"> {{ t('formDemo.formValidation') }} </ElButton>
</div>
</Form>
</template>
<style lang="less" scoped>
.is-required--item {
position: relative;
&::before {
margin-right: 4px;
color: var(--el-color-danger);
content: '*';
}
}
</style>

View File

@ -1,147 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { Dialog } from '@/components/Dialog'
import { ElButton } from 'element-plus'
import { useI18n } from '@/hooks/web/useI18n'
import { ref, reactive, unref } from 'vue'
import { Form, FormExpose } from '@/components/Form'
import { useValidator } from '@/hooks/web/useValidator'
import { getDictOneApi } from '@/api/common'
const { required } = useValidator()
const { t } = useI18n()
const dialogVisible = ref(false)
const dialogVisible2 = ref(false)
const schema = reactive<FormSchema[]>([
{
field: 'field1',
label: t('formDemo.input'),
component: 'Input',
formItemProps: {
rules: [required()]
}
},
{
field: 'field2',
label: t('formDemo.select'),
component: 'Select',
componentProps: {
options: [
{
label: 'option1',
value: '1'
},
{
label: 'option2',
value: '2'
}
]
}
},
{
field: 'field3',
label: t('formDemo.radio'),
component: 'Radio',
componentProps: {
options: [
{
label: 'option-1',
value: '1'
},
{
label: 'option-2',
value: '2'
}
]
}
},
{
field: 'field4',
label: t('formDemo.checkbox'),
component: 'Checkbox',
value: [],
componentProps: {
options: [
{
label: 'option-1',
value: '1'
},
{
label: 'option-2',
value: '2'
},
{
label: 'option-3',
value: '3'
}
]
}
},
{
field: 'field5',
component: 'DatePicker',
label: t('formDemo.datePicker'),
componentProps: {
type: 'date'
}
},
{
field: 'field6',
component: 'TimeSelect',
label: t('formDemo.timeSelect')
}
])
const getDictOne = async () => {
const res = await getDictOneApi()
if (res) {
schema[1].componentProps!.options = res.data
}
}
getDictOne()
const formRef = ref<FormExpose>()
const formSubmit = () => {
unref(formRef)
?.getElFormRef()
?.validate((valid) => {
if (valid) {
console.log('submit success')
} else {
console.log('submit fail')
}
})
}
</script>
<template>
<ContentWrap :title="t('dialogDemo.dialog')" :message="t('dialogDemo.dialogDes')">
<ElButton type="primary" @click="dialogVisible = !dialogVisible">
{{ t('dialogDemo.open') }}
</ElButton>
<ElButton type="primary" @click="dialogVisible2 = !dialogVisible2">
{{ t('dialogDemo.combineWithForm') }}
</ElButton>
<Dialog v-model="dialogVisible" :title="t('dialogDemo.dialog')">
<div v-for="v in 10000" :key="v">{{ v }}</div>
<template #footer>
<ElButton @click="dialogVisible = false">{{ t('dialogDemo.close') }}</ElButton>
</template>
</Dialog>
<Dialog v-model="dialogVisible2" :title="t('dialogDemo.dialog')">
<Form ref="formRef" :schema="schema" />
<template #footer>
<ElButton type="primary" @click="formSubmit">{{ t('dialogDemo.submit') }}</ElButton>
<ElButton @click="dialogVisible2 = false">{{ t('dialogDemo.close') }}</ElButton>
</template>
</Dialog>
</ContentWrap>
</template>

View File

@ -1,36 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { pieOptions, barOptions, lineOptions, wordOptions } from '@/views/Dashboard/echarts-data'
import { Echart } from '@/components/Echart'
import { ElRow, ElCol, ElCard } from 'element-plus'
const { t } = useI18n()
</script>
<template>
<ContentWrap :title="t('echartDemo.echart')" :message="t('echartDemo.echartDes')">
<ElRow :gutter="20" justify="space-between">
<ElCol :xl="10" :lg="10" :md="24" :sm="24" :xs="24">
<ElCard shadow="hover" class="mb-20px">
<Echart :options="pieOptions" :height="300" />
</ElCard>
</ElCol>
<ElCol :xl="14" :lg="14" :md="24" :sm="24" :xs="24">
<ElCard shadow="hover" class="mb-20px">
<Echart :options="barOptions" :height="300" />
</ElCard>
</ElCol>
<ElCol :span="24">
<ElCard shadow="hover" class="mb-20px">
<Echart :options="lineOptions" :height="350" />
</ElCard>
</ElCol>
<ElCol :span="24">
<ElCard shadow="hover" class="mb-20px">
<Echart :options="wordOptions" :height="300" />
</ElCard>
</ElCol>
</ElRow>
</ContentWrap>
</template>

View File

@ -1,32 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { Editor, EditorExpose } from '@/components/Editor'
import { useI18n } from '@/hooks/web/useI18n'
import { IDomEditor } from '@wangeditor/editor'
import { ref, onMounted, unref } from 'vue'
const { t } = useI18n()
const change = (editor: IDomEditor) => {
console.log(editor.getHtml())
}
const editorRef = ref<typeof Editor & EditorExpose>()
const defaultHtml = ref('')
onMounted(async () => {
const editor = await unref(editorRef)?.getEditorRef()
console.log(editor)
})
setTimeout(() => {
defaultHtml.value = '<p>hello <strong>world</strong></p>'
}, 3000)
</script>
<template>
<ContentWrap :title="t('richText.richText')" :message="t('richText.richTextDes')">
<Editor v-model="defaultHtml" ref="editorRef" @change="change" />
</ContentWrap>
</template>

File diff suppressed because it is too large Load Diff

View File

@ -1,269 +0,0 @@
<script setup lang="ts">
import { Form, FormExpose } from '@/components/Form'
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { reactive, unref, ref } from 'vue'
import { ElButton } from 'element-plus'
import { useValidator } from '@/hooks/web/useValidator'
import { getDictOneApi } from '@/api/common'
const { required } = useValidator()
const { t } = useI18n()
const schema = reactive<FormSchema[]>([
{
field: 'field1',
label: t('formDemo.input'),
component: 'Input',
formItemProps: {
rules: [required()]
}
},
{
field: 'field2',
label: t('formDemo.select'),
component: 'Select',
componentProps: {
options: [
{
label: 'option1',
value: '1'
},
{
label: 'option2',
value: '2'
}
]
}
},
{
field: 'field3',
label: t('formDemo.radio'),
component: 'Radio',
componentProps: {
options: [
{
label: 'option-1',
value: '1'
},
{
label: 'option-2',
value: '2'
}
]
}
},
{
field: 'field4',
label: t('formDemo.checkbox'),
component: 'Checkbox',
value: [],
componentProps: {
options: [
{
label: 'option-1',
value: '1'
},
{
label: 'option-2',
value: '2'
},
{
label: 'option-3',
value: '3'
}
]
}
},
{
field: 'field5',
component: 'DatePicker',
label: t('formDemo.datePicker'),
componentProps: {
type: 'date'
}
},
{
field: 'field6',
component: 'TimeSelect',
label: t('formDemo.timeSelect')
}
])
const formRef = ref<FormExpose>()
const changeLabelWidth = (width: number | string) => {
unref(formRef)?.setProps({
labelWidth: width
})
}
const changeSize = (size: string) => {
unref(formRef)?.setProps({
size
})
}
const changeDisabled = (bool: boolean) => {
unref(formRef)?.setProps({
disabled: bool
})
}
const changeSchema = (del: boolean) => {
if (del) {
unref(formRef)?.delSchema('field2')
} else if (!del && schema[1].field !== 'field2') {
unref(formRef)?.addSchema(
{
field: 'field2',
label: t('formDemo.select'),
component: 'Select',
componentProps: {
options: [
{
label: 'option1',
value: '1'
},
{
label: 'option2',
value: '2'
}
]
}
},
1
)
}
}
const setValue = (reset: boolean) => {
const elFormRef = unref(formRef)?.getElFormRef()
if (reset) {
elFormRef?.resetFields()
} else {
unref(formRef)?.setValues({
field1: 'field1',
field2: '2',
field3: '2',
field4: ['1', '3'],
field5: '2022-01-27',
field6: '17:00'
})
}
}
const index = ref(7)
const setLabel = () => {
unref(formRef)?.setSchema([
{
field: 'field2',
path: 'label',
value: `${t('formDemo.select')} ${index.value}`
},
{
field: 'field2',
path: 'componentProps.options',
value: [
{
label: 'option-1',
value: '1'
},
{
label: 'option-2',
value: '2'
},
{
label: 'option-3',
value: '3'
}
]
}
])
index.value++
}
const addItem = () => {
if (unref(index) % 2 === 0) {
unref(formRef)?.addSchema({
field: `field${unref(index)}`,
label: `${t('formDemo.input')}${unref(index)}`,
component: 'Input'
})
} else {
unref(formRef)?.addSchema(
{
field: `field${unref(index)}`,
label: `${t('formDemo.input')}${unref(index)}`,
component: 'Input'
},
unref(index)
)
}
index.value++
}
const formValidation = () => {
const elFormRef = unref(formRef)?.getElFormRef()
elFormRef?.validate()?.catch(() => {})
}
const verifyReset = () => {
const elFormRef = unref(formRef)?.getElFormRef()
elFormRef?.resetFields()
}
const getDictOne = async () => {
const res = await getDictOneApi()
if (res) {
unref(formRef)?.setSchema([
{
field: 'field2',
path: 'componentProps.options',
value: res.data
}
])
}
}
</script>
<template>
<ContentWrap :title="`RefForm ${t('formDemo.operate')}`">
<ElButton @click="changeLabelWidth(150)">{{ t('formDemo.change') }} labelWidth</ElButton>
<ElButton @click="changeLabelWidth('auto')">{{ t('formDemo.restore') }} labelWidth</ElButton>
<ElButton @click="changeSize('large')">{{ t('formDemo.change') }} size</ElButton>
<ElButton @click="changeSize('default')">{{ t('formDemo.restore') }} size</ElButton>
<ElButton @click="changeDisabled(true)">{{ t('formDemo.disabled') }}</ElButton>
<ElButton @click="changeDisabled(false)">{{ t('formDemo.disablement') }}</ElButton>
<ElButton @click="changeSchema(true)">
{{ t('formDemo.delete') }} {{ t('formDemo.select') }}
</ElButton>
<ElButton @click="changeSchema(false)">
{{ t('formDemo.add') }} {{ t('formDemo.select') }}
</ElButton>
<ElButton @click="setValue(false)">{{ t('formDemo.setValue') }}</ElButton>
<ElButton @click="setValue(true)">{{ t('formDemo.resetValue') }}</ElButton>
<ElButton @click="setLabel">
{{ t('formDemo.set') }} {{ t('formDemo.select') }} label
</ElButton>
<ElButton @click="addItem"> {{ t('formDemo.add') }} {{ t('formDemo.subitem') }} </ElButton>
<ElButton @click="formValidation"> {{ t('formDemo.formValidation') }} </ElButton>
<ElButton @click="verifyReset"> {{ t('formDemo.verifyReset') }} </ElButton>
<ElButton @click="getDictOne">
{{ t('searchDemo.dynamicOptions') }}
</ElButton>
</ContentWrap>
<ContentWrap :title="`RefForm ${t('formDemo.example')}`">
<Form :schema="schema" ref="formRef" />
</ContentWrap>
</template>

View File

@ -1,279 +0,0 @@
<script setup lang="ts">
import { Form } from '@/components/Form'
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { useForm } from '@/hooks/web/useForm'
import { reactive, unref, ref } from 'vue'
import { ElButton } from 'element-plus'
import { useValidator } from '@/hooks/web/useValidator'
import { getDictOneApi } from '@/api/common'
const { required } = useValidator()
const { t } = useI18n()
const schema = reactive<FormSchema[]>([
{
field: 'field1',
label: t('formDemo.input'),
component: 'Input',
formItemProps: {
rules: [required()]
}
},
{
field: 'field2',
label: t('formDemo.select'),
component: 'Select',
componentProps: {
options: [
{
label: 'option1',
value: '1'
},
{
label: 'option2',
value: '2'
}
]
}
},
{
field: 'field3',
label: t('formDemo.radio'),
component: 'Radio',
componentProps: {
options: [
{
label: 'option-1',
value: '1'
},
{
label: 'option-2',
value: '2'
}
]
}
},
{
field: 'field4',
label: t('formDemo.checkbox'),
component: 'Checkbox',
value: [],
componentProps: {
options: [
{
label: 'option-1',
value: '1'
},
{
label: 'option-2',
value: '2'
},
{
label: 'option-3',
value: '3'
}
]
}
},
{
field: 'field5',
component: 'DatePicker',
label: t('formDemo.datePicker'),
componentProps: {
type: 'date'
}
},
{
field: 'field6',
component: 'TimeSelect',
label: t('formDemo.timeSelect')
}
])
const { register, methods, elFormRef } = useForm({
schema
})
const changeLabelWidth = (width: number | string) => {
const { setProps } = methods
setProps({
labelWidth: width
})
}
const changeSize = (size: string) => {
const { setProps } = methods
setProps({
size
})
}
const changeDisabled = (bool: boolean) => {
const { setProps } = methods
setProps({
disabled: bool
})
}
const changeSchema = (del: boolean) => {
const { delSchema, addSchema } = methods
if (del) {
delSchema('field2')
} else if (!del && schema[1].field !== 'field2') {
addSchema(
{
field: 'field2',
label: t('formDemo.select'),
component: 'Select',
componentProps: {
options: [
{
label: 'option1',
value: '1'
},
{
label: 'option2',
value: '2'
}
]
}
},
1
)
}
}
const setValue = (reset: boolean) => {
const { setValues } = methods
if (reset) {
unref(elFormRef)?.resetFields()
} else {
setValues({
field1: 'field1',
field2: '2',
field3: '2',
field4: ['1', '3'],
field5: '2022-01-27',
field6: '17:00'
})
}
}
const index = ref(7)
const setLabel = () => {
const { setSchema } = methods
setSchema([
{
field: 'field2',
path: 'label',
value: `${t('formDemo.select')} ${index.value}`
},
{
field: 'field2',
path: 'componentProps.options',
value: [
{
label: 'option-1',
value: '1'
},
{
label: 'option-2',
value: '2'
},
{
label: 'option-3',
value: '3'
}
]
}
])
index.value++
}
const addItem = () => {
const { addSchema } = methods
if (unref(index) % 2 === 0) {
addSchema({
field: `field${unref(index)}`,
label: `${t('formDemo.input')}${unref(index)}`,
component: 'Input'
})
} else {
addSchema(
{
field: `field${unref(index)}`,
label: `${t('formDemo.input')}${unref(index)}`,
component: 'Input'
},
unref(index)
)
}
index.value++
}
const formValidation = () => {
unref(elFormRef)!.validate((isValid) => {
console.log(isValid)
})
}
const verifyReset = () => {
unref(elFormRef)?.resetFields()
}
const getDictOne = async () => {
const res = await getDictOneApi()
if (res) {
const { setSchema } = methods
setSchema([
{
field: 'field2',
path: 'componentProps.options',
value: res.data
}
])
}
}
</script>
<template>
<ContentWrap :title="`UseForm ${t('formDemo.operate')}`">
<ElButton @click="changeLabelWidth(150)">{{ t('formDemo.change') }} labelWidth</ElButton>
<ElButton @click="changeLabelWidth('auto')">{{ t('formDemo.restore') }} labelWidth</ElButton>
<ElButton @click="changeSize('large')">{{ t('formDemo.change') }} size</ElButton>
<ElButton @click="changeSize('default')">{{ t('formDemo.restore') }} size</ElButton>
<ElButton @click="changeDisabled(true)">{{ t('formDemo.disabled') }}</ElButton>
<ElButton @click="changeDisabled(false)">{{ t('formDemo.disablement') }}</ElButton>
<ElButton @click="changeSchema(true)">
{{ t('formDemo.delete') }} {{ t('formDemo.select') }}
</ElButton>
<ElButton @click="changeSchema(false)">
{{ t('formDemo.add') }} {{ t('formDemo.select') }}
</ElButton>
<ElButton @click="setValue(false)">{{ t('formDemo.setValue') }}</ElButton>
<ElButton @click="setValue(true)">{{ t('formDemo.resetValue') }}</ElButton>
<ElButton @click="setLabel">
{{ t('formDemo.set') }} {{ t('formDemo.select') }} label
</ElButton>
<ElButton @click="addItem"> {{ t('formDemo.add') }} {{ t('formDemo.subitem') }} </ElButton>
<ElButton @click="formValidation"> {{ t('formDemo.formValidation') }} </ElButton>
<ElButton @click="verifyReset"> {{ t('formDemo.verifyReset') }} </ElButton>
<ElButton @click="getDictOne">
{{ t('searchDemo.dynamicOptions') }}
</ElButton>
</ContentWrap>
<ContentWrap :title="`UseForm ${t('formDemo.example')}`">
<Form @register="register" />
</ContentWrap>
</template>

View File

@ -1,20 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { Highlight } from '@/components/Highlight'
import { ElMessage } from 'element-plus'
const { t } = useI18n()
const keyClick = (key: string) => {
ElMessage.info(key)
}
</script>
<template>
<ContentWrap :title="t('highlightDemo.highlight')">
<Highlight :keys="[t('highlightDemo.keys1'), t('highlightDemo.keys2')]" @click="keyClick">
{{ t('highlightDemo.message') }}
</Highlight>
</ContentWrap>
</template>

View File

@ -1,62 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { Infotip } from '@/components/Infotip'
import { ElButton } from 'element-plus'
import { useIcon } from '@/hooks/web/useIcon'
const { t } = useI18n()
const keyClick = (key: string) => {
if (key === t('iconDemo.accessAddress')) {
window.open('https://iconify.design/')
}
}
const peoples = useIcon({ icon: 'svg-icon:peoples' })
const money = useIcon({ icon: 'svg-icon:money' })
const aim = useIcon({ icon: 'ep:aim' })
const alarmClock = useIcon({ icon: 'ep:alarm-clock' })
</script>
<template>
<Infotip
:show-index="false"
:title="`${t('iconDemo.recommendedUse')}${t('iconDemo.iconify')}`"
:schema="[
{
label: t('iconDemo.recommendeDes'),
keys: ['Iconify']
},
{
label: t('iconDemo.accessAddress'),
keys: [t('iconDemo.accessAddress')]
}
]"
@click="keyClick"
/>
<ContentWrap :title="t('iconDemo.localIcon')">
<div class="flex justify-between">
<Icon icon="svg-icon:peoples" />
<Icon icon="svg-icon:money" />
<Icon icon="svg-icon:message" />
<Icon icon="svg-icon:shopping" />
</div>
</ContentWrap>
<ContentWrap :title="t('iconDemo.iconify')">
<div class="flex justify-between">
<Icon icon="ep:aim" />
<Icon icon="ep:alarm-clock" />
<Icon icon="ep:baseball" />
<Icon icon="ep:chat-line-round" />
</div>
</ContentWrap>
<ContentWrap title="useIcon">
<div class="flex justify-between">
<ElButton :icon="peoples">Button</ElButton>
<ElButton :icon="money">Button</ElButton>
<ElButton :icon="aim">Button</ElButton>
<ElButton :icon="alarmClock">Button</ElButton>
</div>
</ContentWrap>
</template>

View File

@ -1,30 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { createImageViewer } from '@/components/ImageViewer'
import { ElButton } from 'element-plus'
import { useI18n } from '@/hooks/web/useI18n'
const { t } = useI18n()
const open = () => {
createImageViewer({
urlList: [
'https://img1.baidu.com/it/u=657828739,1486746195&fm=26&fmt=auto&gp=0.jpg',
'https://img0.baidu.com/it/u=3114228356,677481409&fm=26&fmt=auto&gp=0.jpg',
'https://img1.baidu.com/it/u=508846955,3814747122&fm=26&fmt=auto&gp=0.jpg',
'https://img1.baidu.com/it/u=3536647690,3616605490&fm=26&fmt=auto&gp=0.jpg',
'https://img1.baidu.com/it/u=4087287201,1148061266&fm=26&fmt=auto&gp=0.jpg',
'https://img2.baidu.com/it/u=3429163260,2974496379&fm=26&fmt=auto&gp=0.jpg'
]
})
}
</script>
<template>
<ContentWrap
:title="t('imageViewerDemo.imageViewer')"
:message="t('imageViewerDemo.imageViewerDes')"
>
<ElButton type="primary" @click="open">{{ t('imageViewerDemo.open') }}</ElButton>
</ContentWrap>
</template>

View File

@ -1,33 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { Infotip } from '@/components/Infotip'
const { t } = useI18n()
const keyClick = (key: string) => {
if (key === t('iconDemo.accessAddress')) {
window.open('https://iconify.design/')
}
}
</script>
<template>
<ContentWrap :title="t('infotipDemo.infotip')" :message="t('infotipDemo.infotipDes')">
<Infotip
:show-index="false"
:title="`${t('iconDemo.recommendedUse')}${t('iconDemo.iconify')}`"
:schema="[
{
label: t('iconDemo.recommendeDes'),
keys: ['Iconify']
},
{
label: t('iconDemo.accessAddress'),
keys: [t('iconDemo.accessAddress')]
}
]"
@click="keyClick"
/>
</ContentWrap>
</template>

View File

@ -1,21 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { InputPassword } from '@/components/InputPassword'
import { ref } from 'vue'
const { t } = useI18n()
const password = ref('')
</script>
<template>
<ContentWrap
:title="t('inputPasswordDemo.title')"
:message="t('inputPasswordDemo.inputPasswordDes')"
>
<InputPassword v-model="password" class="mb-20px" />
<InputPassword v-model="password" strength />
<InputPassword v-model="password" strength disabled class="mt-20px" />
</ContentWrap>
</template>

View File

@ -1,108 +0,0 @@
<script setup lang="ts">
import { Qrcode } from '@/components/Qrcode'
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { computed, ref, unref } from 'vue'
import { useAppStore } from '@/store/modules/app'
import { ElRow, ElCard, ElCol, ElMessage } from 'element-plus'
// @ts-ignore
import logoImg from '@/assets/imgs/logo.png'
const appStore = useAppStore()
const { t } = useI18n()
const title = computed(() => appStore.getTitle)
const asyncTitle = ref('')
setTimeout(() => {
asyncTitle.value = unref(title)
}, 3000)
const codeClick = () => {
ElMessage.info(t('qrcodeDemo.click'))
}
const disabledClick = () => {
ElMessage.info(t('qrcodeDemo.invalid'))
}
</script>
<template>
<ContentWrap :title="t('qrcodeDemo.qrcode')" :message="t('qrcodeDemo.qrcodeDes')">
<ElRow :gutter="20" justify="space-between">
<ElCol :xl="6" :lg="6" :md="12" :sm="24" :xs="24">
<ElCard shadow="hover" class="mb-10px text-center">
<div class="font-bold">{{ t('qrcodeDemo.basicUsage') }}</div>
<Qrcode :text="title" />
</ElCard>
</ElCol>
<ElCol :xl="6" :lg="6" :md="12" :sm="24" :xs="24">
<ElCard shadow="hover" class="mb-10px text-center">
<div class="font-bold">{{ t('qrcodeDemo.imgTag') }}</div>
<Qrcode :text="title" tag="img" />
</ElCard>
</ElCol>
<ElCol :xl="6" :lg="6" :md="12" :sm="24" :xs="24">
<ElCard shadow="hover" class="mb-10px text-center">
<div class="font-bold">{{ t('qrcodeDemo.style') }}</div>
<Qrcode
:text="title"
:options="{
color: {
dark: '#55D187',
light: '#2d8cf0'
}
}"
/>
</ElCard>
</ElCol>
<ElCol :xl="6" :lg="6" :md="12" :sm="24" :xs="24">
<ElCard shadow="hover" class="mb-10px text-center">
<div class="font-bold">{{ t('qrcodeDemo.click') }}</div>
<Qrcode :text="title" @click="codeClick" />
</ElCard>
</ElCol>
<ElCol :xl="6" :lg="6" :md="12" :sm="24" :xs="24">
<ElCard shadow="hover" class="mb-10px text-center">
<div class="font-bold">{{ t('qrcodeDemo.asynchronousContent') }}</div>
<Qrcode :text="asyncTitle" />
</ElCard>
</ElCol>
<ElCol :xl="6" :lg="6" :md="12" :sm="24" :xs="24">
<ElCard shadow="hover" class="mb-10px text-center">
<div class="font-bold">{{ t('qrcodeDemo.invalid') }}</div>
<Qrcode :text="title" disabled @disabled-click="disabledClick" />
</ElCard>
</ElCol>
<ElCol :xl="6" :lg="6" :md="12" :sm="24" :xs="24">
<ElCard shadow="hover" class="mb-10px text-center">
<div class="font-bold">{{ t('qrcodeDemo.logoConfig') }}</div>
<Qrcode :text="title" :logo="logoImg" />
</ElCard>
</ElCol>
<ElCol :xl="6" :lg="6" :md="12" :sm="24" :xs="24">
<ElCard shadow="hover" class="mb-10px text-center">
<div class="font-bold">{{ t('qrcodeDemo.logoStyle') }}</div>
<Qrcode
:text="title"
:logo="{
src: logoImg,
logoSize: 0.2,
borderSize: 0.05,
borderRadius: 50,
bgColor: 'blue'
}"
/>
</ElCard>
</ElCol>
<ElCol :xl="6" :lg="6" :md="12" :sm="24" :xs="24">
<ElCard shadow="hover" class="mb-10px text-center">
<div class="font-bold">{{ t('qrcodeDemo.size') }}</div>
<Qrcode :text="title" :width="100" />
</ElCard>
</ElCol>
</ElRow>
</ContentWrap>
</template>

View File

@ -1,226 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { Search } from '@/components/Search'
import { reactive, ref, unref } from 'vue'
import { useValidator } from '@/hooks/web/useValidator'
import { ElButton } from 'element-plus'
import { getDictOneApi } from '@/api/common'
const { required } = useValidator()
const { t } = useI18n()
const schema = reactive<FormSchema[]>([
{
field: 'field1',
label: t('formDemo.input'),
component: 'Input',
formItemProps: {
rules: [required()]
}
},
{
field: 'field2',
label: t('formDemo.select'),
component: 'Select',
componentProps: {
options: [
{
label: 'option1',
value: '1'
},
{
label: 'option2',
value: '2'
}
],
onChange: (value: string) => {
console.log(value)
}
}
},
{
field: 'field3',
label: t('formDemo.radio'),
component: 'Radio',
componentProps: {
options: [
{
label: 'option-1',
value: '1'
},
{
label: 'option-2',
value: '2'
}
]
}
},
{
field: 'field5',
component: 'DatePicker',
label: t('formDemo.datePicker'),
componentProps: {
type: 'date'
}
},
{
field: 'field6',
component: 'TimeSelect',
label: t('formDemo.timeSelect')
},
{
field: 'field8',
label: t('formDemo.input'),
component: 'Input',
formItemProps: {
rules: [required()]
}
},
{
field: 'field9',
label: t('formDemo.input'),
component: 'Input',
formItemProps: {
rules: [required()]
}
},
{
field: 'field10',
label: t('formDemo.input'),
component: 'Input',
formItemProps: {
rules: [required()]
}
},
{
field: 'field11',
label: t('formDemo.input'),
component: 'Input',
formItemProps: {
rules: [required()]
}
},
{
field: 'field12',
label: t('formDemo.input'),
component: 'Input',
formItemProps: {
rules: [required()]
}
},
{
field: 'field13',
label: t('formDemo.input'),
component: 'Input',
formItemProps: {
rules: [required()]
}
},
{
field: 'field14',
label: t('formDemo.input'),
component: 'Input',
formItemProps: {
rules: [required()]
}
},
{
field: 'field15',
label: t('formDemo.input'),
component: 'Input',
formItemProps: {
rules: [required()]
}
},
{
field: 'field16',
label: t('formDemo.input'),
component: 'Input',
formItemProps: {
rules: [required()]
}
},
{
field: 'field17',
label: t('formDemo.input'),
component: 'Input',
formItemProps: {
rules: [required()]
}
},
{
field: 'field18',
label: t('formDemo.input'),
component: 'Input',
formItemProps: {
rules: [required()]
}
}
])
const isGrid = ref(false)
const changeGrid = (grid: boolean) => {
isGrid.value = grid
}
const layout = ref('inline')
const changeLayout = () => {
layout.value = unref(layout) === 'inline' ? 'bottom' : 'inline'
}
const buttomPosition = ref('left')
const changePosition = (position: string) => {
layout.value = 'bottom'
buttomPosition.value = position
}
const getDictOne = async () => {
const res = await getDictOneApi()
if (res) {
schema[1].componentProps!.options = res.data
console.log(res.data)
}
}
</script>
<template>
<ContentWrap :title="`${t('searchDemo.search')} ${t('searchDemo.operate')}`">
<ElButton @click="changeGrid(true)">{{ t('searchDemo.grid') }}</ElButton>
<ElButton @click="changeGrid(false)">
{{ t('searchDemo.restore') }} {{ t('searchDemo.grid') }}
</ElButton>
<ElButton @click="changeLayout">
{{ t('searchDemo.button') }} {{ t('searchDemo.position') }}
</ElButton>
<ElButton @click="changePosition('left')">
{{ t('searchDemo.bottom') }} {{ t('searchDemo.position') }}-{{ t('searchDemo.left') }}
</ElButton>
<ElButton @click="changePosition('center')">
{{ t('searchDemo.bottom') }} {{ t('searchDemo.position') }}-{{ t('searchDemo.center') }}
</ElButton>
<ElButton @click="changePosition('right')">
{{ t('searchDemo.bottom') }} {{ t('searchDemo.position') }}-{{ t('searchDemo.right') }}
</ElButton>
<ElButton @click="getDictOne">
{{ t('searchDemo.dynamicOptions') }}
</ElButton>
</ContentWrap>
<ContentWrap :title="t('searchDemo.search')" :message="t('searchDemo.searchDes')">
<Search
:schema="schema"
:is-col="isGrid"
:layout="layout"
:buttom-position="buttomPosition"
expand
expand-field="field6"
/>
</ContentWrap>
</template>

View File

@ -1,62 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { Sticky } from '@/components/Sticky'
import { ElAffix } from 'element-plus'
const { t } = useI18n()
</script>
<template>
<ContentWrap :title="t('stickyDemo.sticky')">
<Sticky :offset="90">
<div style="padding: 10px; background-color: lightblue"> Sticky 距离顶部90px </div>
</Sticky>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<el-affix :offset="150">
<div style="padding: 10px; background-color: lightblue">Affix 距离顶部150px </div>
</el-affix>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<el-affix :offset="150" position="bottom">
<div style="padding: 10px; background-color: lightblue">Affix 距离底部150px </div>
</el-affix>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
<Sticky :offset="90" position="bottom">
<div style="padding: 10px; background-color: lightblue"> Sticky 距离底部90px </div>
</Sticky>
<p style="margin: 80px">Content</p>
<p style="margin: 80px">Content</p>
</ContentWrap>
</template>

View File

@ -1,100 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { Table } from '@/components/Table'
import { getTableListApi } from '@/api/table'
import { TableData } from '@/api/table/types'
import { ref, h } from 'vue'
import { ElTag, ElButton } from 'element-plus'
interface Params {
pageIndex?: number
pageSize?: number
}
const { t } = useI18n()
const columns: TableColumn[] = [
{
field: 'index',
label: t('tableDemo.index'),
type: 'index'
},
{
field: 'title',
label: t('tableDemo.title')
},
{
field: 'author',
label: t('tableDemo.author')
},
{
field: 'display_time',
label: t('tableDemo.displayTime')
},
{
field: 'importance',
label: t('tableDemo.importance'),
formatter: (_: Recordable, __: TableColumn, cellValue: number) => {
return h(
ElTag,
{
type: cellValue === 1 ? 'success' : cellValue === 2 ? 'warning' : 'danger'
},
() =>
cellValue === 1
? t('tableDemo.important')
: cellValue === 2
? t('tableDemo.good')
: t('tableDemo.commonly')
)
}
},
{
field: 'pageviews',
label: t('tableDemo.pageviews')
},
{
field: 'action',
label: t('tableDemo.action')
}
]
const loading = ref(true)
let tableDataList = ref<TableData[]>([])
const getTableList = async (params?: Params) => {
const res = await getTableListApi(
params || {
pageIndex: 1,
pageSize: 10
}
)
.catch(() => {})
.finally(() => {
loading.value = false
})
if (res) {
tableDataList.value = res.data.list
}
}
getTableList()
const acitonFn = (data: TableSlotDefault) => {
console.log(data)
}
</script>
<template>
<ContentWrap :title="t('tableDemo.table')" :message="t('tableDemo.tableDes')">
<Table :columns="columns" :data="tableDataList" :loading="loading">
<template #action="data">
<ElButton type="primary" @click="acitonFn(data as TableSlotDefault)">
{{ t('tableDemo.action') }}
</ElButton>
</template>
</Table>
</ContentWrap>
</template>

View File

@ -1,181 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { Table, TableExpose } from '@/components/Table'
import { getTableListApi } from '@/api/table'
import { TableData } from '@/api/table/types'
import { ref, h, reactive, unref } from 'vue'
import { ElTag, ElButton } from 'element-plus'
import { useTable } from '@/hooks/web/useTable'
const { t } = useI18n()
const columns = reactive<TableColumn[]>([
{
field: 'index',
label: t('tableDemo.index'),
type: 'index'
},
{
field: 'content',
label: t('tableDemo.header'),
children: [
{
field: 'title',
label: t('tableDemo.title')
},
{
field: 'author',
label: t('tableDemo.author')
},
{
field: 'display_time',
label: t('tableDemo.displayTime')
},
{
field: 'importance',
label: t('tableDemo.importance'),
formatter: (_: Recordable, __: TableColumn, cellValue: number) => {
return h(
ElTag,
{
type: cellValue === 1 ? 'success' : cellValue === 2 ? 'warning' : 'danger'
},
() =>
cellValue === 1
? t('tableDemo.important')
: cellValue === 2
? t('tableDemo.good')
: t('tableDemo.commonly')
)
}
},
{
field: 'pageviews',
label: t('tableDemo.pageviews')
}
]
},
{
field: 'action',
label: t('tableDemo.action')
}
])
const { register, tableObject, methods } = useTable<TableData>({
getListApi: getTableListApi,
response: {
list: 'list',
total: 'total'
},
props: {
columns
}
})
const { getList } = methods
getList()
const tableRef = ref<TableExpose>()
const acitonFn = (data: TableSlotDefault) => {
console.log(data)
}
const paginationObj = ref<Pagination>()
const showPagination = (show: boolean) => {
if (show) {
paginationObj.value = {
total: tableObject.total
}
} else {
paginationObj.value = undefined
}
}
const reserveIndex = (custom: boolean) => {
unref(tableRef)?.setProps({
reserveIndex: custom
})
}
const showSelections = (show: boolean) => {
unref(tableRef)?.setProps({
selection: show
})
}
const index = ref(1)
const changeTitle = () => {
unref(tableRef)?.setColumn([
{
field: 'title',
path: 'label',
value: `${t('tableDemo.title')}${unref(index)}`
}
])
index.value++
}
const showExpandedRows = (show: boolean) => {
unref(tableRef)?.setProps({
expand: show
})
}
const selectAllNone = () => {
unref(tableRef)?.elTableRef?.toggleAllSelection()
}
</script>
<template>
<ContentWrap :title="`RefTable ${t('tableDemo.operate')}`">
<ElButton @click="showPagination(true)">
{{ t('tableDemo.show') }} {{ t('tableDemo.pagination') }}
</ElButton>
<ElButton @click="showPagination(false)">
{{ t('tableDemo.hidden') }} {{ t('tableDemo.pagination') }}
</ElButton>
<ElButton @click="reserveIndex(true)">{{ t('tableDemo.reserveIndex') }}</ElButton>
<ElButton @click="reserveIndex(false)">{{ t('tableDemo.restoreIndex') }}</ElButton>
<ElButton @click="showSelections(true)">{{ t('tableDemo.showSelections') }}</ElButton>
<ElButton @click="showSelections(false)">{{ t('tableDemo.hiddenSelections') }}</ElButton>
<ElButton @click="changeTitle">{{ t('tableDemo.changeTitle') }}</ElButton>
<ElButton @click="showExpandedRows(true)">{{ t('tableDemo.showExpandedRows') }}</ElButton>
<ElButton @click="showExpandedRows(false)">{{ t('tableDemo.hiddenExpandedRows') }}</ElButton>
<ElButton @click="selectAllNone">{{ t('tableDemo.selectAllNone') }}</ElButton>
</ContentWrap>
<ContentWrap :title="`RefTable ${t('tableDemo.example')}`">
<Table
ref="tableRef"
v-model:pageSize="tableObject.pageSize"
v-model:currentPage="tableObject.currentPage"
:data="tableObject.tableList"
:loading="tableObject.loading"
:pagination="paginationObj"
@register="register"
>
<template #action="data">
<ElButton type="primary" @click="acitonFn(data as TableSlotDefault)">
{{ t('tableDemo.action') }}
</ElButton>
</template>
<template #expand="data">
<div class="ml-30px">
<div>{{ t('tableDemo.title') }}{{ data.row.title }}</div>
<div>{{ t('tableDemo.author') }}{{ data.row.author }}</div>
<div>{{ t('tableDemo.displayTime') }}{{ data.row.display_time }}</div>
</div>
</template>
</Table>
</ContentWrap>
</template>

View File

@ -1,180 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { Table } from '@/components/Table'
import { getTableListApi } from '@/api/table'
import { TableData } from '@/api/table/types'
import { ref, h, reactive, unref } from 'vue'
import { ElTag, ElButton } from 'element-plus'
import { useTable } from '@/hooks/web/useTable'
const { register, tableObject, methods, elTableRef } = useTable<TableData>({
getListApi: getTableListApi,
response: {
list: 'list',
total: 'total'
}
})
const { getList } = methods
getList()
const { t } = useI18n()
const columns = reactive<TableColumn[]>([
{
field: 'index',
label: t('tableDemo.index'),
type: 'index'
},
{
field: 'content',
label: t('tableDemo.header'),
children: [
{
field: 'title',
label: t('tableDemo.title')
},
{
field: 'author',
label: t('tableDemo.author')
},
{
field: 'display_time',
label: t('tableDemo.displayTime')
},
{
field: 'importance',
label: t('tableDemo.importance'),
formatter: (_: Recordable, __: TableColumn, cellValue: number) => {
return h(
ElTag,
{
type: cellValue === 1 ? 'success' : cellValue === 2 ? 'warning' : 'danger'
},
() =>
cellValue === 1
? t('tableDemo.important')
: cellValue === 2
? t('tableDemo.good')
: t('tableDemo.commonly')
)
}
},
{
field: 'pageviews',
label: t('tableDemo.pageviews')
}
]
},
{
field: 'action',
label: t('tableDemo.action')
}
])
const acitonFn = (data: TableSlotDefault) => {
console.log(data)
}
const paginationObj = ref<Pagination>()
const showPagination = (show: boolean) => {
if (show) {
paginationObj.value = {
total: tableObject.total
}
} else {
paginationObj.value = undefined
}
}
const reserveIndex = (custom: boolean) => {
const { setProps } = methods
setProps({
reserveIndex: custom
})
}
const showSelections = (show: boolean) => {
const { setProps } = methods
setProps({
selection: show
})
}
const index = ref(1)
const changeTitle = () => {
const { setColumn } = methods
setColumn([
{
field: 'title',
path: 'label',
value: `${t('tableDemo.title')}${unref(index)}`
}
])
index.value++
}
const showExpandedRows = (show: boolean) => {
const { setProps } = methods
setProps({
expand: show
})
}
const selectAllNone = () => {
unref(elTableRef)?.toggleAllSelection()
}
</script>
<template>
<ContentWrap :title="`UseTable ${t('tableDemo.operate')}`">
<ElButton @click="showPagination(true)">
{{ t('tableDemo.show') }} {{ t('tableDemo.pagination') }}
</ElButton>
<ElButton @click="showPagination(false)">
{{ t('tableDemo.hidden') }} {{ t('tableDemo.pagination') }}
</ElButton>
<ElButton @click="reserveIndex(true)">{{ t('tableDemo.reserveIndex') }}</ElButton>
<ElButton @click="reserveIndex(false)">{{ t('tableDemo.restoreIndex') }}</ElButton>
<ElButton @click="showSelections(true)">{{ t('tableDemo.showSelections') }}</ElButton>
<ElButton @click="showSelections(false)">{{ t('tableDemo.hiddenSelections') }}</ElButton>
<ElButton @click="changeTitle">{{ t('tableDemo.changeTitle') }}</ElButton>
<ElButton @click="showExpandedRows(true)">{{ t('tableDemo.showExpandedRows') }}</ElButton>
<ElButton @click="showExpandedRows(false)">{{ t('tableDemo.hiddenExpandedRows') }}</ElButton>
<ElButton @click="selectAllNone">{{ t('tableDemo.selectAllNone') }}</ElButton>
</ContentWrap>
<ContentWrap :title="`UseTable ${t('tableDemo.example')}`">
<Table
v-model:pageSize="tableObject.pageSize"
v-model:currentPage="tableObject.currentPage"
:columns="columns"
:data="tableObject.tableList"
:loading="tableObject.loading"
:pagination="paginationObj"
@register="register"
>
<template #action="data">
<ElButton type="primary" @click="acitonFn(data as TableSlotDefault)">
{{ t('tableDemo.action') }}
</ElButton>
</template>
<template #expand="data">
<div class="ml-30px">
<div>{{ t('tableDemo.title') }}{{ data.row.title }}</div>
<div>{{ t('tableDemo.author') }}{{ data.row.author }}</div>
<div>{{ t('tableDemo.displayTime') }}{{ data.row.display_time }}</div>
</div>
</template>
</Table>
</ContentWrap>
</template>

View File

@ -1,273 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { Search } from '@/components/Search'
import { Dialog } from '@/components/Dialog'
import { useI18n } from '@/hooks/web/useI18n'
import { ElButton, ElTag } from 'element-plus'
import { Table } from '@/components/Table'
import { getTableListApi, saveTableApi, delTableListApi } from '@/api/table'
import { useTable } from '@/hooks/web/useTable'
import { TableData } from '@/api/table/types'
import { h, ref, unref, reactive } from 'vue'
import Write from './components/Write.vue'
import Detail from './components/Detail.vue'
import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
const { register, tableObject, methods } = useTable<TableData>({
getListApi: getTableListApi,
delListApi: delTableListApi,
response: {
list: 'list',
total: 'total'
}
})
const { getList, setSearchParams } = methods
getList()
const { t } = useI18n()
const crudSchemas = reactive<CrudSchema[]>([
{
field: 'index',
label: t('tableDemo.index'),
type: 'index',
form: {
show: false
},
detail: {
show: false
}
},
{
field: 'title',
label: t('tableDemo.title'),
search: {
show: true
},
form: {
colProps: {
span: 24
}
},
detail: {
span: 24
}
},
{
field: 'author',
label: t('tableDemo.author')
},
{
field: 'display_time',
label: t('tableDemo.displayTime'),
form: {
component: 'DatePicker',
componentProps: {
type: 'datetime',
valueFormat: 'YYYY-MM-DD HH:mm:ss'
}
}
},
{
field: 'importance',
label: t('tableDemo.importance'),
formatter: (_: Recordable, __: TableColumn, cellValue: number) => {
return h(
ElTag,
{
type: cellValue === 1 ? 'success' : cellValue === 2 ? 'warning' : 'danger'
},
() =>
cellValue === 1
? t('tableDemo.important')
: cellValue === 2
? t('tableDemo.good')
: t('tableDemo.commonly')
)
},
form: {
component: 'Select',
componentProps: {
style: {
width: '100%'
},
options: [
{
label: '重要',
value: 3
},
{
label: '良好',
value: 2
},
{
label: '一般',
value: 1
}
]
}
}
},
{
field: 'pageviews',
label: t('tableDemo.pageviews'),
form: {
component: 'InputNumber',
value: 0
}
},
{
field: 'content',
label: t('exampleDemo.content'),
table: {
show: false
},
form: {
component: 'Editor',
colProps: {
span: 24
}
},
detail: {
span: 24
}
},
{
field: 'action',
width: '260px',
label: t('tableDemo.action'),
form: {
show: false
},
detail: {
show: false
}
}
])
const { allSchemas } = useCrudSchemas(crudSchemas)
const dialogVisible = ref(false)
const dialogTitle = ref('')
const AddAction = () => {
dialogTitle.value = t('exampleDemo.add')
tableObject.currentRow = null
dialogVisible.value = true
actionType.value = ''
}
const delLoading = ref(false)
const delData = async (row: TableData | null, multiple: boolean) => {
tableObject.currentRow = row
const { delList, getSelections } = methods
const selections = await getSelections()
delLoading.value = true
await delList(
multiple ? selections.map((v) => v.id) : [tableObject.currentRow?.id as string],
multiple
).finally(() => {
delLoading.value = false
})
}
const actionType = ref('')
const action = (row: TableData, type: string) => {
dialogTitle.value = t(type === 'edit' ? 'exampleDemo.edit' : 'exampleDemo.detail')
actionType.value = type
tableObject.currentRow = row
dialogVisible.value = true
}
const writeRef = ref<ComponentRef<typeof Write>>()
const loading = ref(false)
const save = async () => {
const write = unref(writeRef)
await write?.elFormRef?.validate(async (isValid) => {
if (isValid) {
loading.value = true
const data = (await write?.getFormData()) as TableData
const res = await saveTableApi(data)
.catch(() => {})
.finally(() => {
loading.value = false
})
if (res) {
dialogVisible.value = false
tableObject.currentPage = 1
getList()
}
}
})
}
</script>
<template>
<ContentWrap>
<Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
<div class="mb-10px">
<ElButton type="primary" @click="AddAction">{{ t('exampleDemo.add') }}</ElButton>
<ElButton :loading="delLoading" type="danger" @click="delData(null, true)">
{{ t('exampleDemo.del') }}
</ElButton>
</div>
<Table
v-model:pageSize="tableObject.pageSize"
v-model:currentPage="tableObject.currentPage"
:columns="allSchemas.tableColumns"
:data="tableObject.tableList"
:loading="tableObject.loading"
:pagination="{
total: tableObject.total
}"
@register="register"
>
<template #action="{ row }">
<ElButton type="primary" v-hasPermi="['example:dialog:edit']" @click="action(row, 'edit')">
{{ t('exampleDemo.edit') }}
</ElButton>
<ElButton
type="success"
v-hasPermi="['example:dialog:view']"
@click="action(row, 'detail')"
>
{{ t('exampleDemo.detail') }}
</ElButton>
<ElButton type="danger" v-hasPermi="['example:dialog:delete']" @click="delData(row, false)">
{{ t('exampleDemo.del') }}
</ElButton>
</template>
</Table>
</ContentWrap>
<Dialog v-model="dialogVisible" :title="dialogTitle">
<Write
v-if="actionType !== 'detail'"
ref="writeRef"
:form-schema="allSchemas.formSchema"
:current-row="tableObject.currentRow"
/>
<Detail
v-if="actionType === 'detail'"
:detail-schema="allSchemas.detailSchema"
:current-row="tableObject.currentRow"
/>
<template #footer>
<ElButton v-if="actionType !== 'detail'" type="primary" :loading="loading" @click="save">
{{ t('exampleDemo.save') }}
</ElButton>
<ElButton @click="dialogVisible = false">{{ t('dialogDemo.close') }}</ElButton>
</template>
</Dialog>
</template>

View File

@ -1,40 +0,0 @@
<script setup lang="ts">
import { PropType } from 'vue'
import type { TableData } from '@/api/table/types'
import { Descriptions } from '@/components/Descriptions'
import { useI18n } from '@/hooks/web/useI18n'
import { ElTag } from 'element-plus'
const { t } = useI18n()
defineProps({
currentRow: {
type: Object as PropType<Nullable<TableData>>,
default: () => null
},
detailSchema: {
type: Array as PropType<DescriptionsSchema[]>,
default: () => []
}
})
</script>
<template>
<Descriptions :schema="detailSchema" :data="currentRow || {}">
<template #importance="{ row }: { row: TableData }">
<ElTag :type="row.importance === 1 ? 'success' : row.importance === 2 ? 'warning' : 'danger'">
{{
row.importance === 1
? t('tableDemo.important')
: row.importance === 2
? t('tableDemo.good')
: t('tableDemo.commonly')
}}
</ElTag>
</template>
<template #content="{ row }: { row: TableData }">
<div v-html="row.content"></div>
</template>
</Descriptions>
</template>

View File

@ -1,55 +0,0 @@
<script setup lang="ts">
import { Form } from '@/components/Form'
import { useForm } from '@/hooks/web/useForm'
import { PropType, reactive, watch } from 'vue'
import { TableData } from '@/api/table/types'
import { useValidator } from '@/hooks/web/useValidator'
const { required } = useValidator()
const props = defineProps({
currentRow: {
type: Object as PropType<Nullable<TableData>>,
default: () => null
},
formSchema: {
type: Array as PropType<FormSchema[]>,
default: () => []
}
})
const rules = reactive({
title: [required()],
author: [required()],
importance: [required()],
pageviews: [required()],
display_time: [required()],
content: [required()]
})
const { register, methods, elFormRef } = useForm({
schema: props.formSchema
})
watch(
() => props.currentRow,
(currentRow) => {
if (!currentRow) return
const { setValues } = methods
setValues(currentRow)
},
{
deep: true,
immediate: true
}
)
defineExpose({
elFormRef,
getFormData: methods.getFormData
})
</script>
<template>
<Form :rules="rules" @register="register" />
</template>

View File

@ -1,52 +0,0 @@
<script setup lang="ts">
import Write from './components/Write.vue'
import { ContentDetailWrap } from '@/components/ContentDetailWrap'
import { ref, unref } from 'vue'
import { ElButton } from 'element-plus'
import { useI18n } from '@/hooks/web/useI18n'
import { useRouter } from 'vue-router'
import { saveTableApi } from '@/api/table'
import { TableData } from '@/api/table/types'
import { useEmitt } from '@/hooks/web/useEmitt'
const { emitter } = useEmitt()
const { push } = useRouter()
const { t } = useI18n()
const writeRef = ref<ComponentRef<typeof Write>>()
const loading = ref(false)
const save = async () => {
const write = unref(writeRef)
await write?.elFormRef?.validate(async (isValid) => {
if (isValid) {
loading.value = true
const data = (await write?.getFormData()) as TableData
const res = await saveTableApi(data)
.catch(() => {})
.finally(() => {
loading.value = false
})
if (res) {
emitter.emit('getList', 'add')
push('/example/example-page')
}
}
})
}
</script>
<template>
<ContentDetailWrap :title="t('exampleDemo.add')" @back="push('/example/example-page')">
<Write ref="writeRef" />
<template #right>
<ElButton type="primary" :loading="loading" @click="save">
{{ t('exampleDemo.save') }}
</ElButton>
</template>
</ContentDetailWrap>
</template>

View File

@ -1,32 +0,0 @@
<script setup lang="ts">
import Detail from './components/Detail.vue'
import { ContentDetailWrap } from '@/components/ContentDetailWrap'
import { ref } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
import { useRouter, useRoute } from 'vue-router'
import { getTableDetApi } from '@/api/table'
import { TableData } from '@/api/table/types'
const { push } = useRouter()
const { query } = useRoute()
const { t } = useI18n()
const currentRow = ref<Nullable<TableData>>(null)
const getTableDet = async () => {
const res = await getTableDetApi(query.id as string)
if (res) {
currentRow.value = res.data
}
}
getTableDet()
</script>
<template>
<ContentDetailWrap :title="t('exampleDemo.detail')" @back="push('/example/example-page')">
<Detail :current-row="currentRow" />
</ContentDetailWrap>
</template>

View File

@ -1,64 +0,0 @@
<script setup lang="ts">
import Write from './components/Write.vue'
import { ContentDetailWrap } from '@/components/ContentDetailWrap'
import { ref, unref } from 'vue'
import { ElButton } from 'element-plus'
import { useI18n } from '@/hooks/web/useI18n'
import { useRouter, useRoute } from 'vue-router'
import { saveTableApi, getTableDetApi } from '@/api/table'
import { TableData } from '@/api/table/types'
import { useEmitt } from '@/hooks/web/useEmitt'
const { emitter } = useEmitt()
const { push } = useRouter()
const { query } = useRoute()
const { t } = useI18n()
const currentRow = ref<Nullable<TableData>>(null)
const getTableDet = async () => {
const res = await getTableDetApi(query.id as string)
if (res) {
currentRow.value = res.data
}
}
getTableDet()
const writeRef = ref<ComponentRef<typeof Write>>()
const loading = ref(false)
const save = async () => {
const write = unref(writeRef)
const validate = await write?.elFormRef?.validate()?.catch(() => {})
if (validate) {
loading.value = true
const data = (await write?.getFormData()) as TableData
const res = await saveTableApi(data)
.catch(() => {})
.finally(() => {
loading.value = false
})
if (res) {
emitter.emit('getList', 'edit')
push('/example/example-page')
}
}
}
</script>
<template>
<ContentDetailWrap :title="t('exampleDemo.edit')" @back="push('/example/example-page')">
<Write ref="writeRef" :current-row="currentRow" />
<template #right>
<ElButton type="primary" :loading="loading" @click="save">
{{ t('exampleDemo.save') }}
</ElButton>
</template>
</ContentDetailWrap>
</template>

View File

@ -1,164 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { Search } from '@/components/Search'
import { useI18n } from '@/hooks/web/useI18n'
import { ElButton, ElTag } from 'element-plus'
import { Table } from '@/components/Table'
import { getTableListApi, delTableListApi } from '@/api/table'
import { useTable } from '@/hooks/web/useTable'
import { TableData } from '@/api/table/types'
import { h, reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useEmitt } from '@/hooks/web/useEmitt'
import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
defineOptions({
name: 'ExamplePage'
})
const { push } = useRouter()
const { register, tableObject, methods } = useTable<TableData>({
getListApi: getTableListApi,
delListApi: delTableListApi,
response: {
list: 'list',
total: 'total'
}
})
const { getList, setSearchParams } = methods
getList()
useEmitt({
name: 'getList',
callback: (type: string) => {
if (type === 'add') {
tableObject.currentPage = 1
}
getList()
}
})
const { t } = useI18n()
const crudSchemas = reactive<CrudSchema[]>([
{
field: 'index',
label: t('tableDemo.index'),
type: 'index'
},
{
field: 'title',
label: t('tableDemo.title'),
search: {
show: true
}
},
{
field: 'author',
label: t('tableDemo.author')
},
{
field: 'display_time',
label: t('tableDemo.displayTime')
},
{
field: 'importance',
label: t('tableDemo.importance'),
formatter: (_: Recordable, __: TableColumn, cellValue: number) => {
return h(
ElTag,
{
type: cellValue === 1 ? 'success' : cellValue === 2 ? 'warning' : 'danger'
},
() =>
cellValue === 1
? t('tableDemo.important')
: cellValue === 2
? t('tableDemo.good')
: t('tableDemo.commonly')
)
}
},
{
field: 'pageviews',
label: t('tableDemo.pageviews')
},
{
field: 'content',
label: t('exampleDemo.content'),
table: {
show: false
}
},
{
field: 'action',
width: '260px',
label: t('tableDemo.action')
}
])
const { allSchemas } = useCrudSchemas(crudSchemas)
const AddAction = () => {
push('/example/example-add')
}
const delLoading = ref(false)
const delData = async (row: TableData | null, multiple: boolean) => {
tableObject.currentRow = row
const { delList, getSelections } = methods
const selections = await getSelections()
delLoading.value = true
await delList(
multiple ? selections.map((v) => v.id) : [tableObject.currentRow?.id as string],
multiple
).finally(() => {
delLoading.value = false
})
}
const action = (row: TableData, type: string) => {
push(`/example/example-${type}?id=${row.id}`)
}
</script>
<template>
<ContentWrap>
<Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
<div class="mb-10px">
<ElButton type="primary" @click="AddAction">{{ t('exampleDemo.add') }}</ElButton>
<ElButton :loading="delLoading" type="danger" @click="delData(null, true)">
{{ t('exampleDemo.del') }}
</ElButton>
</div>
<Table
v-model:pageSize="tableObject.pageSize"
v-model:currentPage="tableObject.currentPage"
:columns="allSchemas.tableColumns"
:data="tableObject.tableList"
:loading="tableObject.loading"
:pagination="{
total: tableObject.total
}"
@register="register"
>
<template #action="{ row }">
<ElButton type="primary" @click="action(row, 'edit')">
{{ t('exampleDemo.edit') }}
</ElButton>
<ElButton type="success" @click="action(row, 'detail')">
{{ t('exampleDemo.detail') }}
</ElButton>
<ElButton type="danger" @click="delData(row, false)">
{{ t('exampleDemo.del') }}
</ElButton>
</template>
</Table>
</ContentWrap>
</template>

View File

@ -1,65 +0,0 @@
<script setup lang="ts">
import { PropType, reactive } from 'vue'
import type { TableData } from '@/api/table/types'
import { Descriptions } from '@/components/Descriptions'
import { useI18n } from '@/hooks/web/useI18n'
import { ElTag } from 'element-plus'
const { t } = useI18n()
defineProps({
currentRow: {
type: Object as PropType<Nullable<TableData>>,
default: () => null
}
})
const schema = reactive<DescriptionsSchema[]>([
{
field: 'title',
label: t('exampleDemo.title'),
span: 24
},
{
field: 'author',
label: t('exampleDemo.author')
},
{
field: 'display_time',
label: t('exampleDemo.displayTime')
},
{
field: 'importance',
label: t('exampleDemo.importance')
},
{
field: 'pageviews',
label: t('exampleDemo.pageviews')
},
{
field: 'content',
label: t('exampleDemo.content'),
span: 24
}
])
</script>
<template>
<Descriptions :schema="schema" :data="currentRow || {}">
<template #importance="{ row }: { row: TableData }">
<ElTag :type="row.importance === 1 ? 'success' : row.importance === 2 ? 'warning' : 'danger'">
{{
row.importance === 1
? t('tableDemo.important')
: row.importance === 2
? t('tableDemo.good')
: t('tableDemo.commonly')
}}
</ElTag>
</template>
<template #content="{ row }: { row: TableData }">
<div v-html="row.content"></div>
</template>
</Descriptions>
</template>

View File

@ -1,146 +0,0 @@
<script setup lang="ts">
import { Form } from '@/components/Form'
import { useForm } from '@/hooks/web/useForm'
import { PropType, reactive, watch } from 'vue'
import { TableData } from '@/api/table/types'
import { useI18n } from '@/hooks/web/useI18n'
import { useValidator } from '@/hooks/web/useValidator'
import { IDomEditor } from '@wangeditor/editor'
const { required } = useValidator()
const props = defineProps({
currentRow: {
type: Object as PropType<Nullable<TableData>>,
default: () => null
}
})
const { t } = useI18n()
const schema = reactive<FormSchema[]>([
{
field: 'title',
label: t('exampleDemo.title'),
component: 'Input',
formItemProps: {
rules: [required()]
},
colProps: {
span: 24
}
},
{
field: 'author',
label: t('exampleDemo.author'),
component: 'Input',
formItemProps: {
rules: [required()]
}
},
{
field: 'display_time',
label: t('exampleDemo.displayTime'),
component: 'DatePicker',
componentProps: {
type: 'datetime',
valueFormat: 'YYYY-MM-DD HH:mm:ss'
},
formItemProps: {
rules: [required()]
}
},
{
field: 'importance',
label: t('exampleDemo.importance'),
component: 'Select',
formItemProps: {
rules: [required()]
},
componentProps: {
options: [
{
label: '重要',
value: 3
},
{
label: '良好',
value: 2
},
{
label: '一般',
value: 1
}
]
}
},
{
field: 'pageviews',
label: t('exampleDemo.pageviews'),
component: 'InputNumber',
value: 0,
formItemProps: {
rules: [required()]
}
},
{
field: 'content',
component: 'Editor',
colProps: {
span: 24
},
componentProps: {
defaultHtml: '',
onChange: (edit: IDomEditor) => {
const { setValues } = methods
setValues({
content: edit.getHtml()
})
}
},
label: t('exampleDemo.content')
}
])
const rules = reactive({
title: [required()],
author: [required()],
importance: [required()],
pageviews: [required()],
display_time: [required()],
content: [required()]
})
const { register, methods, elFormRef } = useForm({
schema
})
watch(
() => props.currentRow,
(currentRow) => {
if (!currentRow) return
const { setValues, setSchema } = methods
setValues(currentRow)
setSchema([
{
field: 'content',
path: 'componentProps.defaultHtml',
value: currentRow.content
}
])
},
{
deep: true,
immediate: true
}
)
defineExpose({
elFormRef,
getFormData: methods.getFormData
})
</script>
<template>
<Form :rules="rules" @register="register" />
</template>

View File

@ -1,20 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { useIntro } from '@/hooks/web/useIntro'
import { ElButton } from 'element-plus'
const { t } = useI18n()
const { introRef } = useIntro()
const guideStart = () => {
introRef.start()
}
</script>
<template>
<ContentWrap :title="t('guideDemo.guide')" :message="t('guideDemo.message')">
<ElButton type="primary" @click="guideStart">{{ t('guideDemo.start') }}</ElButton>
</ContentWrap>
</template>

View File

@ -1,20 +0,0 @@
<script setup lang="ts">
import { ElInput } from 'element-plus'
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { ref } from 'vue'
defineOptions({
name: 'Menu111'
})
const { t } = useI18n()
const text = ref('')
</script>
<template>
<ContentWrap :title="t('levelDemo.menu')">
<div class="flex items-center"> Menu111: <ElInput v-model="text" class="pl-20px" /> </div>
</ContentWrap>
</template>

View File

@ -1,20 +0,0 @@
<script setup lang="ts">
import { ElInput } from 'element-plus'
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { ref } from 'vue'
defineOptions({
name: 'Menu12'
})
const { t } = useI18n()
const text = ref('')
</script>
<template>
<ContentWrap :title="t('levelDemo.menu')">
<div class="flex items-center"> Menu12: <ElInput v-model="text" class="pl-20px" /> </div>
</ContentWrap>
</template>

View File

@ -1,20 +0,0 @@
<script setup lang="ts">
import { ElInput } from 'element-plus'
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { ref } from 'vue'
defineOptions({
name: 'Menu2'
})
const { t } = useI18n()
const text = ref('')
</script>
<template>
<ContentWrap :title="t('levelDemo.menu')">
<div class="flex items-center"> Menu2: <ElInput v-model="text" class="pl-20px" /> </div>
</ContentWrap>
</template>

View File

@ -4,13 +4,14 @@ import { Form } from '@/components/Form'
import { useI18n } from '@/hooks/web/useI18n'
import { ElButton, ElCheckbox, ElLink } from 'element-plus'
import { useForm } from '@/hooks/web/useForm'
import { loginApi, getTestRoleApi, getAdminRoleApi } from '@/api/login'
import { getTestRoleApi, getAdminRoleApi } from '@/api/login'
import { useCache } from '@/hooks/web/useCache'
import { useAppStore } from '@/store/modules/app'
import { useAuthStoreWithOut } from '@/store/modules/auth'
import { usePermissionStore } from '@/store/modules/permission'
import { useRouter } from 'vue-router'
import type { RouteLocationNormalizedLoaded, RouteRecordRaw } from 'vue-router'
import { UserType } from '@/api/login/types'
import { UserType, UserLoginType } from '@/api/login/types'
import { useValidator } from '@/hooks/web/useValidator'
const { required } = useValidator()
@ -21,6 +22,8 @@ const appStore = useAppStore()
const permissionStore = usePermissionStore()
const authStore = useAuthStoreWithOut()
const { currentRoute, addRoute, push } = useRouter()
const { wsCache } = useCache()
@ -28,7 +31,7 @@ const { wsCache } = useCache()
const { t } = useI18n()
const rules = {
username: [required()],
telephone: [required()],
password: [required()]
}
@ -40,15 +43,15 @@ const schema = reactive<FormSchema[]>([
}
},
{
field: 'username',
label: t('login.username'),
value: 'admin',
field: 'telephone',
label: t('login.telephone'),
value: '15093430559',
component: 'Input',
colProps: {
span: 24
},
componentProps: {
placeholder: t('login.usernamePlaceholder')
placeholder: t('login.telephonePlaceholder')
}
},
{
@ -123,10 +126,10 @@ const signIn = async () => {
if (isValid) {
loading.value = true
const { getFormData } = methods
const formData = await getFormData<UserType>()
const formData = await getFormData<UserLoginType>()
try {
const res = await loginApi(formData)
const res = await authStore.login(formData)
if (res) {
wsCache.set(appStore.getUserInfo, res.data)
@ -154,18 +157,18 @@ const getRole = async () => {
const { getFormData } = methods
const formData = await getFormData<UserType>()
const params = {
roleName: formData.username
roleName: formData.telephone
}
// admin -
// test -
const res =
formData.username === 'admin' ? await getAdminRoleApi(params) : await getTestRoleApi(params)
formData.telephone === 'admin' ? await getAdminRoleApi(params) : await getTestRoleApi(params)
if (res) {
const { wsCache } = useCache()
const routers = res.data || []
wsCache.set('roleRouters', routers)
formData.username === 'admin'
formData.telephone === 'admin'
? await permissionStore.generateRoutes('admin', routers).catch(() => {})
: await permissionStore.generateRoutes('test', routers).catch(() => {})

View File

@ -1,222 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { Search } from '@/components/Search'
import { useI18n } from '@/hooks/web/useI18n'
import { ElButton, ElTag } from 'element-plus'
import { Table } from '@/components/Table'
import { getTableListApi, delTableListApi } from '@/api/table'
import { useTable } from '@/hooks/web/useTable'
import { TableData } from '@/api/table/types'
import { h, ref, reactive } from 'vue'
import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
import { useDictStore } from '@/store/modules/dict'
import { getDictOneApi } from '@/api/common'
const dictStore = useDictStore()
const { register, tableObject, methods } = useTable<TableData>({
getListApi: getTableListApi,
delListApi: delTableListApi,
response: {
list: 'list',
total: 'total'
}
})
const { getList, setSearchParams } = methods
getList()
const { t } = useI18n()
const crudSchemas = reactive<CrudSchema[]>([
{
field: 'index',
label: t('tableDemo.index'),
type: 'index',
form: {
show: false
},
detail: {
show: false
}
},
{
field: 'title',
label: t('tableDemo.title'),
search: {
show: true
},
form: {
colProps: {
span: 24
}
},
detail: {
span: 24
}
},
{
field: 'author',
label: t('tableDemo.author')
},
{
field: 'display_time',
label: t('tableDemo.displayTime'),
form: {
component: 'DatePicker',
componentProps: {
type: 'datetime',
valueFormat: 'YYYY-MM-DD HH:mm:ss'
}
}
},
{
field: 'importance',
label: t('tableDemo.importance'),
formatter: (_: Recordable, __: TableColumn, cellValue: number) => {
return h(
ElTag,
{
type: cellValue === 1 ? 'success' : cellValue === 2 ? 'warning' : 'danger'
},
() =>
cellValue === 1
? t('tableDemo.important')
: cellValue === 2
? t('tableDemo.good')
: t('tableDemo.commonly')
)
},
search: {
show: true,
component: 'Select',
componentProps: {
options: dictStore.getDictObj.importance
}
},
form: {
component: 'Select',
componentProps: {
options: [
{
label: '重要',
value: 3
},
{
label: '良好',
value: 2
},
{
label: '一般',
value: 1
}
]
}
}
},
{
field: 'importance2',
label: `${t('tableDemo.importance')}2`,
search: {
show: true,
component: 'Select',
dictName: 'importance'
}
},
{
field: 'importance3',
label: `${t('tableDemo.importance')}3`,
search: {
show: true,
component: 'Select',
api: async () => {
const res = await getDictOneApi()
return res.data
}
}
},
{
field: 'pageviews',
label: t('tableDemo.pageviews'),
form: {
component: 'InputNumber',
value: 0
}
},
{
field: 'content',
label: t('exampleDemo.content'),
table: {
show: false
},
form: {
component: 'Editor',
colProps: {
span: 24
}
},
detail: {
span: 24
}
},
{
field: 'action',
width: '260px',
label: t('tableDemo.action'),
form: {
show: false
},
detail: {
show: false
}
}
])
const { allSchemas } = useCrudSchemas(crudSchemas)
const delLoading = ref(false)
const delData = async (row: TableData | null, multiple: boolean) => {
tableObject.currentRow = row
const { delList, getSelections } = methods
const selections = await getSelections()
delLoading.value = true
await delList(
multiple ? selections.map((v) => v.id) : [tableObject.currentRow?.id as string],
multiple
).finally(() => {
delLoading.value = false
})
}
</script>
<template>
<ContentWrap>
<Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
<div class="mb-10px">
<ElButton :loading="delLoading" type="danger" @click="delData(null, true)">
{{ t('exampleDemo.del') }}
</ElButton>
</div>
<Table
v-model:pageSize="tableObject.pageSize"
v-model:currentPage="tableObject.currentPage"
:columns="allSchemas.tableColumns"
:data="tableObject.tableList"
:loading="tableObject.loading"
:pagination="{
total: tableObject.total
}"
@register="register"
>
<template #action="{ row }">
<ElButton type="danger" @click="delData(row, false)">
{{ t('exampleDemo.del') }}
</ElButton>
</template>
</Table>
</ContentWrap>
</template>

View File

@ -1,32 +0,0 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { ElButton } from 'element-plus'
import { useWatermark } from '@/hooks/web/useWatermark'
import { computed, onBeforeUnmount } from 'vue'
import { useAppStore } from '@/store/modules/app'
const appStore = useAppStore()
const title = computed(() => appStore.getTitle)
const { setWatermark, clear } = useWatermark()
const { t } = useI18n()
onBeforeUnmount(() => {
clear()
})
</script>
<template>
<ContentWrap title="useWatermark">
<ElButton type="primary" @click="setWatermark(title)">
{{ t('watermarkDemo.createdWatermark') }}
</ElButton>
<ElButton type="danger" @click="clear">{{ t('watermarkDemo.clearWatermark') }}</ElButton>
<ElButton type="warning" @click="setWatermark(`New${title}`)">
{{ t('watermarkDemo.resetWatermark') }}
</ElButton>
</ContentWrap>
</template>

View File

@ -37,4 +37,5 @@ declare interface AxiosConfig {
declare interface IResponse<T = any> {
code: string
data: T extends any ? T : T & any
message: string
}

View File

@ -115,11 +115,11 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
}
},
server: {
port: 4000,
port: 5000,
proxy: {
// 选项写法
'/api': {
target: 'http://127.0.0.1:8000',
target: 'http://127.0.0.1:9000',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
@ -127,7 +127,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
hmr: {
overlay: false
},
host: '0.0.0.0'
host: '127.0.0.1'
},
optimizeDeps: {
include: [

View File

@ -53,8 +53,7 @@ async def login_for_access_token(request: Request, data: dict = Depends(authenti
"telephone": user.telephone,
"name": user.name,
"nickname": user.nickname,
"avatar": user.avatar,
"roles": [{"name": i.name, "value": i.role_key} for i in user.roles]
"avatar": user.avatar
}
}
await VadminLoginRecord.create_login_record(telephone=user.telephone, status=data.get("status"), request=request,
@ -75,22 +74,6 @@ async def get_user_info(auth: AdminAuth = Depends(full_admin)):
return SuccessResponse(result)
@app.get("/getPermCode/", summary="获取当前登录用户所有权限")
async def get_perm_code(auth: AdminAuth = Depends(full_admin)):
roles = []
for i in auth.admin.roles:
if i.is_admin:
return SuccessResponse(["*:*:*"])
roles.append(i.id)
permissions = set()
for data_id in roles:
role_obj = await RoleDal(auth.db).get_data(data_id, options=[VadminRole.menus])
for menu in role_obj.menus:
if menu.perms and menu.status:
permissions.add(menu.perms)
return SuccessResponse(list(permissions))
@app.get("/getMenuList/", summary="获取当前用户菜单树")
async def get_menu_list(auth: AdminAuth = Depends(full_admin)):
datas = await MenuDal(auth.db).get_routers(auth.admin)

View File

@ -13,8 +13,7 @@ class SuccessResponse(Response):
self.data = {
"code": code,
"message": msg,
"result": data,
"type": "success",
"data": data
}
self.data.update(kwargs)
super().__init__(content=self.data, status_code=status)
@ -24,13 +23,11 @@ class ErrorResponse(Response):
"""
失败响应
"""
def __init__(self, msg=None, code=http.HTTP_ERROR, status=http_status.HTTP_400_BAD_REQUEST
, **kwargs):
def __init__(self, msg=None, code=http.HTTP_ERROR, status=http_status.HTTP_200_OK, **kwargs):
self.data = {
"code": code,
"message": msg,
"result": [],
"type": "error",
"data": []
}
self.data.update(kwargs)
super().__init__(content=self.data, status_code=status)

View File

@ -7,5 +7,5 @@
# @desc : 简要说明
HTTP_SUCCESS = 0
HTTP_ERROR = 1
HTTP_SUCCESS = 200
HTTP_ERROR = 400