Commit 37669d067c43a3807df848f0caf67cbeab3e1b33
1 parent
c8e84dc1
wip: add account management page
Showing
23 changed files
with
372 additions
and
16 deletions
mock/demo/system.ts
0 → 100644
1 | +import { MockMethod } from 'vite-plugin-mock'; | |
2 | +import { resultPageSuccess } from '../_util'; | |
3 | + | |
4 | +const list = (() => { | |
5 | + const result: any[] = []; | |
6 | + for (let index = 0; index < 20; index++) { | |
7 | + result.push({ | |
8 | + id: `${index}`, | |
9 | + account: '@first', | |
10 | + email: '@email', | |
11 | + nickname: '@cname()', | |
12 | + role: '@first', | |
13 | + updateTime: '@datetime', | |
14 | + remark: '@cword(0,20)', | |
15 | + }); | |
16 | + } | |
17 | + return result; | |
18 | +})(); | |
19 | + | |
20 | +export default [ | |
21 | + { | |
22 | + url: '/api/system/getAccountList', | |
23 | + timeout: 100, | |
24 | + method: 'get', | |
25 | + response: ({ query }) => { | |
26 | + const { page = 1, pageSize = 20 } = query; | |
27 | + return resultPageSuccess(page, pageSize, list); | |
28 | + }, | |
29 | + }, | |
30 | +] as MockMethod[]; | ... | ... |
mock/demo/table-demo.ts
src/api/demo/model/systemModel.ts
0 → 100644
1 | +import { BasicPageParams, BasicFetchResult } from '/@/api/model/baseModel'; | |
2 | + | |
3 | +export type Params = BasicPageParams & { | |
4 | + account?: string; | |
5 | + nickname?: string; | |
6 | +}; | |
7 | + | |
8 | +export interface DemoListItem { | |
9 | + id: string; | |
10 | + account: string; | |
11 | + email: string; | |
12 | + nickname: string; | |
13 | + role: number; | |
14 | + updateTime: string; | |
15 | + remark: string; | |
16 | +} | |
17 | + | |
18 | +/** | |
19 | + * @description: Request list return value | |
20 | + */ | |
21 | +export type DemoListGetResultModel = BasicFetchResult<DemoListItem>; | ... | ... |
src/api/demo/system.ts
0 → 100644
1 | +import { Params, DemoListGetResultModel } from './model/systemModel'; | |
2 | +import { defHttp } from '/@/utils/http/axios'; | |
3 | + | |
4 | +enum Api { | |
5 | + // The address does not exist | |
6 | + AccountList = '/system/getAccountList', | |
7 | +} | |
8 | + | |
9 | +export const getAccountList = (params: Params) => | |
10 | + defHttp.get<DemoListGetResultModel>({ url: Api.AccountList, params }); | ... | ... |
src/components/Table/src/style/index.less
... | ... | @@ -4,6 +4,7 @@ |
4 | 4 | |
5 | 5 | .@{prefix-cls} { |
6 | 6 | &-form-container { |
7 | + width: 100%; | |
7 | 8 | padding: 16px; |
8 | 9 | |
9 | 10 | .ant-form { |
... | ... | @@ -50,8 +51,8 @@ |
50 | 51 | |
51 | 52 | // |
52 | 53 | .ant-table { |
53 | - // width: 100%; | |
54 | - // overflow-x: hidden; | |
54 | + width: 100%; | |
55 | + overflow-x: hidden; | |
55 | 56 | // border: none; |
56 | 57 | |
57 | 58 | &-title { |
... | ... | @@ -159,15 +160,15 @@ |
159 | 160 | // overflow-y: hidden !important; |
160 | 161 | // } |
161 | 162 | |
162 | - // .ant-table-fixed { | |
163 | - // border-bottom: none; | |
164 | - // } | |
163 | + // .ant-table-fixed { | |
164 | + // border-bottom: none; | |
165 | + // } | |
165 | 166 | // } |
166 | 167 | |
167 | 168 | // .ant-table-bordered .ant-table-thead > tr:not(:last-child) > th, |
168 | 169 | // .ant-table-tbody > tr > td { |
169 | 170 | // word-break: break-word; |
170 | - // border-color: @border-color !important; | |
171 | + // // border-color: @border-color !important; | |
171 | 172 | // } |
172 | 173 | |
173 | 174 | .ant-table-footer { | ... | ... |
src/locales/lang/en/routes/demo/system.ts
0 → 100644
src/locales/lang/zh_CN/routes/demo/system.ts
0 → 100644
src/router/menus/modules/demo/system.ts
0 → 100644
1 | +import type { MenuModule } from '/@/router/types'; | |
2 | +import { t } from '/@/hooks/web/useI18n'; | |
3 | + | |
4 | +const menu: MenuModule = { | |
5 | + orderNo: 2000, | |
6 | + menu: { | |
7 | + name: t('routes.demo.system.moduleName'), | |
8 | + path: '/system', | |
9 | + children: [ | |
10 | + { | |
11 | + path: 'account', | |
12 | + name: t('routes.demo.system.account'), | |
13 | + }, | |
14 | + ], | |
15 | + }, | |
16 | +}; | |
17 | +export default menu; | ... | ... |
src/router/routes/modules/dashboard.ts
src/router/routes/modules/demo/charts.ts
src/router/routes/modules/demo/comp.ts
src/router/routes/modules/demo/feat.ts
src/router/routes/modules/demo/iframe.ts
src/router/routes/modules/demo/level.ts
src/router/routes/modules/demo/page.ts
src/router/routes/modules/demo/permission.ts
src/router/routes/modules/demo/system.ts
0 → 100644
1 | +import type { AppRouteModule } from '/@/router/types'; | |
2 | + | |
3 | +import { LAYOUT } from '/@/router/constant'; | |
4 | +import { t } from '/@/hooks/web/useI18n'; | |
5 | + | |
6 | +const system: AppRouteModule = { | |
7 | + path: '/system', | |
8 | + name: 'System', | |
9 | + component: LAYOUT, | |
10 | + redirect: '/system/account', | |
11 | + meta: { | |
12 | + icon: 'ion:settings-outline', | |
13 | + title: t('routes.demo.system.moduleName'), | |
14 | + }, | |
15 | + children: [ | |
16 | + { | |
17 | + path: 'account', | |
18 | + name: 'Account', | |
19 | + meta: { | |
20 | + title: t('routes.demo.system.account'), | |
21 | + }, | |
22 | + component: () => import('/@/views/demo/system/account/index.vue'), | |
23 | + }, | |
24 | + ], | |
25 | +}; | |
26 | + | |
27 | +export default system; | ... | ... |
src/router/routes/modules/home.ts
src/views/biz/.gitkeep deleted
100644 → 0
src/views/demo/.gitkeep deleted
100644 → 0
src/views/demo/system/account/AccountModal.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit"> | |
3 | + <BasicForm @register="registerForm" /> | |
4 | + </BasicModal> | |
5 | +</template> | |
6 | +<script lang="ts"> | |
7 | + import { defineComponent, ref, computed, unref } from 'vue'; | |
8 | + import { BasicModal, useModalInner } from '/@/components/Modal'; | |
9 | + import { BasicForm, useForm } from '/@/components/Form/index'; | |
10 | + import { accountFormSchema } from './account.data'; | |
11 | + export default defineComponent({ | |
12 | + name: 'AccountModal', | |
13 | + components: { BasicModal, BasicForm }, | |
14 | + setup() { | |
15 | + const isUpdate = ref(true); | |
16 | + | |
17 | + const [registerForm, { setFieldsValue, validate }] = useForm({ | |
18 | + labelWidth: 100, | |
19 | + schemas: accountFormSchema, | |
20 | + showActionButtonGroup: false, | |
21 | + actionColOptions: { | |
22 | + span: 23, | |
23 | + }, | |
24 | + }); | |
25 | + | |
26 | + const [registerModal, { setModalProps }] = useModalInner((data) => { | |
27 | + isUpdate.value = !!data?.isUpdate; | |
28 | + | |
29 | + if (unref(isUpdate)) { | |
30 | + setFieldsValue({ | |
31 | + ...data.record, | |
32 | + }); | |
33 | + } | |
34 | + }); | |
35 | + | |
36 | + const getTitle = computed(() => (!unref(isUpdate) ? '新增账号' : '编辑账号')); | |
37 | + | |
38 | + async function handleSubmit() { | |
39 | + try { | |
40 | + const values = await validate(); | |
41 | + setModalProps({ confirmLoading: true }); | |
42 | + // TODO custom api | |
43 | + console.log(values); | |
44 | + } finally { | |
45 | + setModalProps({ confirmLoading: true }); | |
46 | + } | |
47 | + } | |
48 | + | |
49 | + return { registerModal, registerForm, getTitle, handleSubmit }; | |
50 | + }, | |
51 | + }); | |
52 | +</script> | ... | ... |
src/views/demo/system/account/account.data.ts
0 → 100644
1 | +import { BasicColumn } from '/@/components/Table'; | |
2 | +import { FormSchema } from '/@/components/Table'; | |
3 | + | |
4 | +export const columns: BasicColumn[] = [ | |
5 | + { | |
6 | + title: 'ID', | |
7 | + dataIndex: 'id', | |
8 | + width: 80, | |
9 | + }, | |
10 | + { | |
11 | + title: '用户名', | |
12 | + dataIndex: 'account', | |
13 | + width: 120, | |
14 | + }, | |
15 | + { | |
16 | + title: '昵称', | |
17 | + dataIndex: 'nickname', | |
18 | + width: 120, | |
19 | + }, | |
20 | + { | |
21 | + title: '邮箱', | |
22 | + dataIndex: 'email', | |
23 | + width: 200, | |
24 | + }, | |
25 | + { | |
26 | + title: '更新时间', | |
27 | + dataIndex: 'updateTime', | |
28 | + width: 180, | |
29 | + }, | |
30 | + { | |
31 | + title: '角色', | |
32 | + dataIndex: 'role', | |
33 | + width: 200, | |
34 | + }, | |
35 | + { | |
36 | + title: '备注', | |
37 | + dataIndex: 'remark', | |
38 | + width: 200, | |
39 | + }, | |
40 | +]; | |
41 | + | |
42 | +export const searchFormSchema: FormSchema[] = [ | |
43 | + { | |
44 | + field: 'account', | |
45 | + label: '用户名', | |
46 | + component: 'Input', | |
47 | + colProps: { span: 8 }, | |
48 | + }, | |
49 | + { | |
50 | + field: 'nickname', | |
51 | + label: '昵称', | |
52 | + component: 'Input', | |
53 | + colProps: { span: 8 }, | |
54 | + }, | |
55 | +]; | |
56 | + | |
57 | +export const accountFormSchema: FormSchema[] = [ | |
58 | + { | |
59 | + field: 'account', | |
60 | + label: '用户名', | |
61 | + component: 'Input', | |
62 | + required: true, | |
63 | + }, | |
64 | + { | |
65 | + field: 'nickname', | |
66 | + label: '昵称', | |
67 | + component: 'Input', | |
68 | + required: true, | |
69 | + }, | |
70 | + { | |
71 | + label: '邮箱', | |
72 | + field: 'email', | |
73 | + component: 'Input', | |
74 | + required: true, | |
75 | + }, | |
76 | + // TODO | |
77 | + { | |
78 | + label: '角色', | |
79 | + field: 'role', | |
80 | + component: 'Input', | |
81 | + required: true, | |
82 | + }, | |
83 | + { | |
84 | + label: '备注', | |
85 | + field: 'remark', | |
86 | + component: 'InputTextArea', | |
87 | + }, | |
88 | +]; | ... | ... |
src/views/demo/system/account/index.vue
0 → 100644
1 | +<template> | |
2 | + <div :class="[prefixCls]"> | |
3 | + <BasicTable @register="registerTable"> | |
4 | + <template #toolbar> | |
5 | + <a-button type="primary" @click="handleCreateAccount"> 新增账号 </a-button> | |
6 | + </template> | |
7 | + <template #action="{ record }"> | |
8 | + <TableAction | |
9 | + :actions="[ | |
10 | + { | |
11 | + label: '编辑', | |
12 | + onClick: handleEdit.bind(null, record), | |
13 | + }, | |
14 | + { | |
15 | + label: '删除', | |
16 | + color: 'error', | |
17 | + popConfirm: { | |
18 | + title: '是否确认删除', | |
19 | + confirm: handleDelete.bind(null, record), | |
20 | + }, | |
21 | + }, | |
22 | + ]" | |
23 | + /> | |
24 | + </template> | |
25 | + </BasicTable> | |
26 | + <AccountModal @register="registerModal" /> | |
27 | + </div> | |
28 | +</template> | |
29 | +<script lang="ts"> | |
30 | + import { defineComponent } from 'vue'; | |
31 | + | |
32 | + import { useDesign } from '/@/hooks/web/useDesign'; | |
33 | + import { BasicTable, useTable, TableAction } from '/@/components/Table'; | |
34 | + import { getAccountList } from '/@/api/demo/system'; | |
35 | + | |
36 | + import { useModal } from '/@/components/Modal'; | |
37 | + import AccountModal from './AccountModal.vue'; | |
38 | + | |
39 | + import { columns, searchFormSchema } from './account.data'; | |
40 | + | |
41 | + export default defineComponent({ | |
42 | + name: 'AccountManagement', | |
43 | + components: { BasicTable, AccountModal, TableAction }, | |
44 | + setup() { | |
45 | + const { prefixCls } = useDesign('account-management'); | |
46 | + | |
47 | + const [registerModal, { openModal }] = useModal(); | |
48 | + const [registerTable] = useTable({ | |
49 | + title: '账号列表', | |
50 | + api: getAccountList, | |
51 | + columns, | |
52 | + formConfig: { | |
53 | + labelWidth: 120, | |
54 | + schemas: searchFormSchema, | |
55 | + }, | |
56 | + useSearchForm: true, | |
57 | + showTableSetting: true, | |
58 | + actionColumn: { | |
59 | + width: 160, | |
60 | + title: '操作', | |
61 | + dataIndex: 'action', | |
62 | + slots: { customRender: 'action' }, | |
63 | + }, | |
64 | + }); | |
65 | + | |
66 | + function handleCreateAccount() { | |
67 | + openModal(true, { | |
68 | + isUpdate: false, | |
69 | + }); | |
70 | + } | |
71 | + | |
72 | + function handleEdit(record: Recordable) { | |
73 | + openModal(true, { | |
74 | + record, | |
75 | + isUpdate: true, | |
76 | + }); | |
77 | + } | |
78 | + | |
79 | + function handleDelete(record: Recordable) { | |
80 | + console.log(record); | |
81 | + } | |
82 | + | |
83 | + return { | |
84 | + prefixCls, | |
85 | + registerTable, | |
86 | + registerModal, | |
87 | + handleCreateAccount, | |
88 | + handleEdit, | |
89 | + handleDelete, | |
90 | + }; | |
91 | + }, | |
92 | + }); | |
93 | +</script> | |
94 | +<style lang="less" scoped> | |
95 | + @prefix-cls: ~'@{namespace}-account-management'; | |
96 | + | |
97 | + .@{prefix-cls} { | |
98 | + display: flex; | |
99 | + } | |
100 | +</style> | ... | ... |