Commit 718c52c3faff473133d57d0e70922ac587e720ee
1 parent
eea414e0
feat: update
Showing
77 changed files
with
3393 additions
and
365 deletions
Too many changes to show.
To preserve performance only 77 of 83 files are displayed.
.env
.pnpm-debug.log
0 → 100644
1 | +{ | ||
2 | + "0 error pnpm": { | ||
3 | + "code": "ERR_PNPM_UNSUPPORTED_ENGINE", | ||
4 | + "packageId": "/Users/sanmu/Documents/teach/vue-vben-admin", | ||
5 | + "wanted": { | ||
6 | + "pnpm": ">=8.1.0" | ||
7 | + }, | ||
8 | + "current": { | ||
9 | + "node": "v18.14.1", | ||
10 | + "pnpm": "7.4.1" | ||
11 | + }, | ||
12 | + "err": { | ||
13 | + "name": "pnpm", | ||
14 | + "message": "Unsupported engine for /Users/sanmu/Documents/teach/vue-vben-admin: wanted: {\"pnpm\":\">=8.1.0\"} (current: {\"node\":\"v18.14.1\",\"pnpm\":\"7.4.1\"})", | ||
15 | + "code": "ERR_PNPM_UNSUPPORTED_ENGINE", | ||
16 | + "stack": "pnpm: Unsupported engine for /Users/sanmu/Documents/teach/vue-vben-admin: wanted: {\"pnpm\":\">=8.1.0\"} (current: {\"node\":\"v18.14.1\",\"pnpm\":\"7.4.1\"})\n at checkEngine (/Users/zhusen/.nvm/versions/node/v16.13.0/lib/node_modules/pnpm/dist/pnpm.cjs:43094:16)\n at checkPackage (/Users/zhusen/.nvm/versions/node/v16.13.0/lib/node_modules/pnpm/dist/pnpm.cjs:43677:74)\n at packageIsInstallable (/Users/zhusen/.nvm/versions/node/v16.13.0/lib/node_modules/pnpm/dist/pnpm.cjs:43700:61)\n at exports2.default (/Users/zhusen/.nvm/versions/node/v16.13.0/lib/node_modules/pnpm/dist/pnpm.cjs:49525:46)\n at async run (/Users/zhusen/.nvm/versions/node/v16.13.0/lib/node_modules/pnpm/dist/pnpm.cjs:192508:29)\n at async runPnpm (/Users/zhusen/.nvm/versions/node/v16.13.0/lib/node_modules/pnpm/dist/pnpm.cjs:192771:5)\n at async /Users/zhusen/.nvm/versions/node/v16.13.0/lib/node_modules/pnpm/dist/pnpm.cjs:192763:7" | ||
17 | + } | ||
18 | + } | ||
19 | +} | ||
0 | \ No newline at end of file | 20 | \ No newline at end of file |
mock/demo/table-demo.ts
@@ -37,6 +37,14 @@ const demoList = (() => { | @@ -37,6 +37,14 @@ const demoList = (() => { | ||
37 | time: `@time('HH:mm')`, | 37 | time: `@time('HH:mm')`, |
38 | 'no|100000-10000000': 100000, | 38 | 'no|100000-10000000': 100000, |
39 | 'status|1': ['normal', 'enable', 'disable'], | 39 | 'status|1': ['normal', 'enable', 'disable'], |
40 | + no1: '字段内容', | ||
41 | + no2: '字段内容', | ||
42 | + no3: '字段内容', | ||
43 | + no4: '字段内容', | ||
44 | + no5: '字段内容', | ||
45 | + no6: '字段内容', | ||
46 | + no7: '字段内容', | ||
47 | + no8: '字段内容', | ||
40 | }); | 48 | }); |
41 | } | 49 | } |
42 | return result; | 50 | return result; |
mock/sys/user.ts
@@ -11,7 +11,7 @@ export function createFakeUserList() { | @@ -11,7 +11,7 @@ export function createFakeUserList() { | ||
11 | desc: 'manager', | 11 | desc: 'manager', |
12 | password: '123456', | 12 | password: '123456', |
13 | token: 'fakeToken1', | 13 | token: 'fakeToken1', |
14 | - homePath: '/dashboard/analysis', | 14 | + homePath: '/home', |
15 | roles: [ | 15 | roles: [ |
16 | { | 16 | { |
17 | roleName: 'Super Admin', | 17 | roleName: 'Super Admin', |
package.json
@@ -17,7 +17,7 @@ | @@ -17,7 +17,7 @@ | ||
17 | }, | 17 | }, |
18 | "scripts": { | 18 | "scripts": { |
19 | "bootstrap": "pnpm install", | 19 | "bootstrap": "pnpm install", |
20 | - "build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build", | 20 | + "build": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build", |
21 | "build:analyze": "cross-env NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build --mode analyze", | 21 | "build:analyze": "cross-env NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build --mode analyze", |
22 | "build:docker": "vite build --mode docker", | 22 | "build:docker": "vite build --mode docker", |
23 | "build:no-cache": "pnpm clean:cache && npm run build", | 23 | "build:no-cache": "pnpm clean:cache && npm run build", |
@@ -151,4 +151,4 @@ | @@ -151,4 +151,4 @@ | ||
151 | "node": ">=16.15.1", | 151 | "node": ">=16.15.1", |
152 | "pnpm": ">=8.1.0" | 152 | "pnpm": ">=8.1.0" |
153 | } | 153 | } |
154 | -} | 154 | -} |
155 | +} | ||
155 | \ No newline at end of file | 156 | \ No newline at end of file |
src/api/demo/system.ts
@@ -13,17 +13,21 @@ import { | @@ -13,17 +13,21 @@ import { | ||
13 | import { defHttp } from '/@/utils/http/axios'; | 13 | import { defHttp } from '/@/utils/http/axios'; |
14 | 14 | ||
15 | enum Api { | 15 | enum Api { |
16 | - AccountList = '/system/getAccountList', | 16 | + AccountList = '/order/erp/users/list_by_page', |
17 | IsAccountExist = '/system/accountExist', | 17 | IsAccountExist = '/system/accountExist', |
18 | DeptList = '/system/getDeptList', | 18 | DeptList = '/system/getDeptList', |
19 | setRoleStatus = '/system/setRoleStatus', | 19 | setRoleStatus = '/system/setRoleStatus', |
20 | MenuList = '/system/getMenuList', | 20 | MenuList = '/system/getMenuList', |
21 | - RolePageList = '/system/getRoleListByPage', | 21 | + RolePageList = '/order/erp/roles/list_by_page', |
22 | GetAllRoleList = '/system/getAllRoleList', | 22 | GetAllRoleList = '/system/getAllRoleList', |
23 | } | 23 | } |
24 | 24 | ||
25 | -export const getAccountList = (params: AccountParams) => | ||
26 | - defHttp.get<AccountListGetResultModel>({ url: Api.AccountList, params }); | 25 | +export const getAccountList = async (params: AccountParams) => { |
26 | + const res = await defHttp.post<AccountListGetResultModel>({ url: Api.AccountList, params }); | ||
27 | + return new Promise((resolve) => { | ||
28 | + resolve(res.records); | ||
29 | + }); | ||
30 | +}; | ||
27 | 31 | ||
28 | export const getDeptList = (params?: DeptListItem) => | 32 | export const getDeptList = (params?: DeptListItem) => |
29 | defHttp.get<DeptListGetResultModel>({ url: Api.DeptList, params }); | 33 | defHttp.get<DeptListGetResultModel>({ url: Api.DeptList, params }); |
@@ -31,8 +35,12 @@ export const getDeptList = (params?: DeptListItem) => | @@ -31,8 +35,12 @@ export const getDeptList = (params?: DeptListItem) => | ||
31 | export const getMenuList = (params?: MenuParams) => | 35 | export const getMenuList = (params?: MenuParams) => |
32 | defHttp.get<MenuListGetResultModel>({ url: Api.MenuList, params }); | 36 | defHttp.get<MenuListGetResultModel>({ url: Api.MenuList, params }); |
33 | 37 | ||
34 | -export const getRoleListByPage = (params?: RolePageParams) => | ||
35 | - defHttp.get<RolePageListGetResultModel>({ url: Api.RolePageList, params }); | 38 | +export const getRoleListByPage = async (params?: RolePageParams) => { |
39 | + const res = await defHttp.post<RolePageListGetResultModel>({ url: Api.RolePageList, params }); | ||
40 | + return new Promise((resolve) => { | ||
41 | + resolve(res.records); | ||
42 | + }); | ||
43 | +}; | ||
36 | 44 | ||
37 | export const getAllRoleList = (params?: RoleParams) => | 45 | export const getAllRoleList = (params?: RoleParams) => |
38 | defHttp.get<RoleListGetResultModel>({ url: Api.GetAllRoleList, params }); | 46 | defHttp.get<RoleListGetResultModel>({ url: Api.GetAllRoleList, params }); |
src/api/demo/table.ts
1 | import { defHttp } from '/@/utils/http/axios'; | 1 | import { defHttp } from '/@/utils/http/axios'; |
2 | import { DemoParams, DemoListGetResultModel } from './model/tableModel'; | 2 | import { DemoParams, DemoListGetResultModel } from './model/tableModel'; |
3 | +import { find } from 'lodash-es'; | ||
4 | +import { FIELDS_BASE_INFO } from '/@/views/project/order/tableData'; | ||
3 | 5 | ||
4 | enum Api { | 6 | enum Api { |
5 | DEMO_LIST = '/table/getDemoList', | 7 | DEMO_LIST = '/table/getDemoList', |
8 | + ORDER = '/order/erp/order/list_by_page', | ||
9 | + DICT_INIT = '/order/erp/dictionary/get_all', | ||
10 | + APPROVE = '/order/erp/audit/list_by_page', | ||
11 | + CHECK = '/order/erp/audit/do_audit', | ||
6 | } | 12 | } |
7 | 13 | ||
8 | /** | 14 | /** |
9 | * @description: Get sample list value | 15 | * @description: Get sample list value |
10 | */ | 16 | */ |
11 | 17 | ||
12 | -export const demoListApi = (params: DemoParams) => | ||
13 | - defHttp.get<DemoListGetResultModel>({ | ||
14 | - url: Api.DEMO_LIST, | 18 | +export const demoListApi = async (params: DemoParams) => { |
19 | + const res = await defHttp.post<DemoListGetResultModel>({ | ||
20 | + url: Api.ORDER, | ||
15 | params, | 21 | params, |
16 | headers: { | 22 | headers: { |
17 | // @ts-ignore | 23 | // @ts-ignore |
18 | ignoreCancelToken: true, | 24 | ignoreCancelToken: true, |
19 | }, | 25 | }, |
20 | }); | 26 | }); |
27 | + return new Promise((resolve) => { | ||
28 | + resolve(res.records); | ||
29 | + }); | ||
30 | +}; | ||
31 | + | ||
32 | +export const demoApproveListApi = async (params: DemoParams) => { | ||
33 | + const res = await defHttp.post<DemoListGetResultModel>({ | ||
34 | + url: Api.APPROVE, | ||
35 | + params, | ||
36 | + }); | ||
37 | + | ||
38 | + res.records = res.records.map((item) => { | ||
39 | + item.fields = []; | ||
40 | + Object.entries(item.fieldInfos.baseFields).map(([key, value]) => { | ||
41 | + if (value === 'UN_LOCKED') { | ||
42 | + const obj = find(FIELDS_BASE_INFO, { field: key }); | ||
43 | + item.fields.push(obj?.label); | ||
44 | + } | ||
45 | + }); | ||
46 | + item.fields = item.fields.join(','); | ||
47 | + return item; | ||
48 | + }); | ||
49 | + | ||
50 | + return new Promise((resolve) => { | ||
51 | + resolve(res.records); | ||
52 | + }); | ||
53 | +}; | ||
54 | + | ||
55 | +export const demoApproveCheckApi = async (params: DemoParams) => { | ||
56 | + const res = await defHttp.post<DemoListGetResultModel>({ | ||
57 | + url: Api.CHECK, | ||
58 | + params, | ||
59 | + headers: { | ||
60 | + // @ts-ignore | ||
61 | + ignoreCancelToken: true, | ||
62 | + }, | ||
63 | + }); | ||
64 | + return new Promise((resolve) => { | ||
65 | + resolve(res); | ||
66 | + }); | ||
67 | +}; | ||
68 | + | ||
69 | +export const getInitDictData = async () => { | ||
70 | + const res = await defHttp.post({ | ||
71 | + url: Api.DICT_INIT, | ||
72 | + params: {}, | ||
73 | + headers: { | ||
74 | + // @ts-ignore | ||
75 | + ignoreCancelToken: true, | ||
76 | + }, | ||
77 | + }); | ||
78 | + | ||
79 | + return res; | ||
80 | +}; |
src/api/project/account.ts
0 → 100644
1 | +import { defHttp } from '/@/utils/http/axios'; | ||
2 | + | ||
3 | +enum Api { | ||
4 | + ROLE_LIST = '/order/erp/roles/all', | ||
5 | + USER_LIST = '/order/erp/users/list_by_page', | ||
6 | + USER_ADD = '/order/erp/roles/add', | ||
7 | + USER_EDIT = '/order/erp/roles/edit', | ||
8 | + USER_DELETE = '/order/erp/roles/delete', | ||
9 | +} | ||
10 | + | ||
11 | +export const getRoleList = async (params: any) => { | ||
12 | + return defHttp.post<any>({ | ||
13 | + url: Api.ROLE_LIST, | ||
14 | + params, | ||
15 | + }); | ||
16 | +}; | ||
17 | + | ||
18 | +export const getUserList = async (params: any) => { | ||
19 | + const res = await defHttp.post<any>({ | ||
20 | + url: Api.USER_LIST, | ||
21 | + params, | ||
22 | + }); | ||
23 | + return new Promise((resolve) => { | ||
24 | + resolve(res.records); | ||
25 | + }); | ||
26 | +}; | ||
27 | + | ||
28 | +// export const getAccountList = async (params: AccountParams) => { | ||
29 | +// const res = await defHttp.post<AccountListGetResultModel>({ url: Api.AccountList, params }); | ||
30 | +// return new Promise((resolve) => { | ||
31 | +// resolve(res.records); | ||
32 | +// }); | ||
33 | +// }; | ||
34 | + | ||
35 | +export const userAdd = async (params: any) => { | ||
36 | + return defHttp.post<any>({ | ||
37 | + url: Api.USER_ADD, | ||
38 | + params, | ||
39 | + }); | ||
40 | +}; | ||
41 | + | ||
42 | +export const userEdit = async (params: any) => { | ||
43 | + return defHttp.post<any>({ | ||
44 | + url: Api.USER_EDIT, | ||
45 | + params, | ||
46 | + }); | ||
47 | +}; | ||
48 | + | ||
49 | +export const userDelete = async (params: any) => { | ||
50 | + return defHttp.post<any>({ | ||
51 | + url: Api.USER_DELETE, | ||
52 | + params, | ||
53 | + }); | ||
54 | +}; |
src/api/project/approve.ts
0 → 100644
1 | +import { find, isEmpty } from 'lodash-es'; | ||
2 | +import { defHttp } from '/@/utils/http/axios'; | ||
3 | +import { FIELDS_BASE_INFO, FIELDS_PROFIT_INFO } from '/@/views/project/order/tableData'; | ||
4 | + | ||
5 | +enum Api { | ||
6 | + APPROVE = '/order/erp/audit/wait_audit_list', | ||
7 | + APPROVE_ED = '/order/erp/audit/audit_list', | ||
8 | + AUDIT = '/order/erp/audit/do_audit', | ||
9 | +} | ||
10 | + | ||
11 | +export const approveAuditApi = async (params: any) => | ||
12 | + defHttp.post<any>( | ||
13 | + { | ||
14 | + url: Api.AUDIT, | ||
15 | + params, | ||
16 | + }, | ||
17 | + { message: '操作成功' }, | ||
18 | + ); | ||
19 | + | ||
20 | +export const getWaitListApi = async (params: DemoParams) => { | ||
21 | + const res = await defHttp.post({ | ||
22 | + url: Api.APPROVE, | ||
23 | + params, | ||
24 | + }); | ||
25 | + | ||
26 | + console.log('%c [ ]-26', 'font-size:13px; background:pink; color:#bf2c9f;', 123); | ||
27 | + res.records = res.records.map((item) => { | ||
28 | + item.fields = []; | ||
29 | + !isEmpty(item.fieldInfos.baseFields) && | ||
30 | + Object.entries(item.fieldInfos.baseFields).map(([key, value]) => { | ||
31 | + if (value === 'UN_LOCKED') { | ||
32 | + const obj = find(FIELDS_BASE_INFO, { field: key }); | ||
33 | + item.fields.push(obj?.label); | ||
34 | + } | ||
35 | + }); | ||
36 | + !isEmpty(item.fieldInfos.baseFields) && | ||
37 | + Object.entries(item.fieldInfos.profitAnalysisFields).map(([key, value]) => { | ||
38 | + if (value === 'UN_LOCKED') { | ||
39 | + const obj = find(FIELDS_PROFIT_INFO, { field: `profitAnalysisFields.${key}` }); | ||
40 | + item.fields.push(obj?.label); | ||
41 | + } | ||
42 | + }); | ||
43 | + item.fields = item.fields.join(','); | ||
44 | + return item; | ||
45 | + }); | ||
46 | + console.log( | ||
47 | + '%c [ res.records ]-27', | ||
48 | + 'font-size:13px; background:pink; color:#bf2c9f;', | ||
49 | + res.records, | ||
50 | + ); | ||
51 | + | ||
52 | + return new Promise((resolve) => { | ||
53 | + resolve(res.records); | ||
54 | + }); | ||
55 | +}; | ||
56 | + | ||
57 | +export const getApprovedListApi = async (params: any) => { | ||
58 | + const res = await defHttp.post({ | ||
59 | + url: Api.APPROVE_ED, | ||
60 | + | ||
61 | + params, | ||
62 | + }); | ||
63 | + | ||
64 | + res.records = res.records.map((item) => { | ||
65 | + item.fields = []; | ||
66 | + Object.entries(item.fieldInfos.baseFields).map(([key, value]) => { | ||
67 | + if (value === 'UN_LOCKED') { | ||
68 | + const obj = find(FIELDS_BASE_INFO, { field: key }); | ||
69 | + item.fields.push(obj?.label); | ||
70 | + } | ||
71 | + }); | ||
72 | + item.fields = item.fields.join(','); | ||
73 | + return item; | ||
74 | + }); | ||
75 | + | ||
76 | + return new Promise((resolve) => { | ||
77 | + resolve(res.records); | ||
78 | + }); | ||
79 | +}; |
src/api/project/global.ts
0 → 100644
1 | +import { defHttp } from '/@/utils/http/axios'; | ||
2 | + | ||
3 | +enum Api { | ||
4 | + DATA = '/order/erp/index/data', | ||
5 | + CHART_DATA = '/order/erp/index/chartData', | ||
6 | +} | ||
7 | + | ||
8 | +export const getApiData = async () => { | ||
9 | + const res = await defHttp.get<any>({ url: Api.DATA }); | ||
10 | + return res; | ||
11 | +}; | ||
12 | + | ||
13 | +export const getChartData = async () => { | ||
14 | + const res = await defHttp.get<any>({ url: Api.CHART_DATA }); | ||
15 | + return res; | ||
16 | +}; |
src/api/project/order.ts
0 → 100644
1 | +import axios from 'axios'; | ||
2 | +import { defHttp } from '/@/utils/http/axios'; | ||
3 | +import { useUserStoreWithOut } from '/@/store/modules/user'; | ||
4 | +import { useOrderStoreWithOut } from '/@/store/modules/order'; | ||
5 | + | ||
6 | +enum Api { | ||
7 | + ORDER_CREATE = '/order/erp/order/add', | ||
8 | + UPDATE = '/order/erp/order/edit', | ||
9 | + ORDER = '/order/erp/order/list_by_page', | ||
10 | + FIELD_AUTH = '/order/erp/order/field_unlock_apply', | ||
11 | + EXPORT = '/order/erp/order/export', | ||
12 | + UPLOAD = '/api/localStorage/upload', | ||
13 | + | ||
14 | + DICT_INIT = '/order/erp/dictionary/get_all', | ||
15 | + DICT_ADD = '/order/erp/dictionary/add', | ||
16 | + DICT_UPDATE = '/order/erp/dictionary/edit', | ||
17 | + DICT_DELETE = '/order/erp/dictionary/delete', | ||
18 | + DICT_LIST = '/order/erp/dictionary/list_by_page', | ||
19 | + | ||
20 | + ANALYSIS = '/order/erp/profit/analysis', | ||
21 | +} | ||
22 | + | ||
23 | +export const orderCreate = async (data: any) => { | ||
24 | + const res = await defHttp.post<any>({ url: Api.ORDER_CREATE, data }, { message: '保存成功' }); | ||
25 | + return res; | ||
26 | +}; | ||
27 | + | ||
28 | +export const orderUpdate = async (data: any) => { | ||
29 | + const res = await defHttp.post<any>({ url: Api.UPDATE, data }); | ||
30 | + return res; | ||
31 | +}; | ||
32 | + | ||
33 | +export const orderAuth = (data: any) => | ||
34 | + defHttp.post<any>({ url: Api.FIELD_AUTH, data }, { message: '操作成功' }); | ||
35 | + | ||
36 | +export const orderAnalysis = async (data: any) => { | ||
37 | + const res = await defHttp.post<any>({ url: Api.ANALYSIS, data }); | ||
38 | + return res; | ||
39 | +}; | ||
40 | + | ||
41 | +export const orderExport = async (data: any = {}) => { | ||
42 | + // const res = await defHttp.post<any>({ url: Api.EXPORT, data }); | ||
43 | + const userStore = useUserStoreWithOut(); | ||
44 | + | ||
45 | + const token = userStore.getToken; | ||
46 | + | ||
47 | + axios({ | ||
48 | + url: '/basic-api' + Api.EXPORT, | ||
49 | + method: 'post', | ||
50 | + responseType: 'blob', | ||
51 | + headers: { Authorization: `Bearer ${token}` }, | ||
52 | + data, | ||
53 | + }) | ||
54 | + .then((response) => { | ||
55 | + // 创建一个新的 Blob 对象,它包含了服务器响应的数据(即你的 Excel 文件) | ||
56 | + const blob = new Blob([response.data]); // Excel 的 MIME 类型 | ||
57 | + const downloadUrl = window.URL.createObjectURL(blob); | ||
58 | + const a = document.createElement('a'); | ||
59 | + a.href = downloadUrl; | ||
60 | + a.download = '订单.xlsx'; // 你可以为文件命名 | ||
61 | + document.body.appendChild(a); | ||
62 | + a.click(); // 模拟点击操作来下载文件 | ||
63 | + URL.revokeObjectURL(downloadUrl); // 释放掉 blob 对象所占用的内存 | ||
64 | + document.body.removeChild(a); | ||
65 | + }) | ||
66 | + .catch((error) => { | ||
67 | + // 处理错误 | ||
68 | + console.error('导出错误', error); | ||
69 | + }); | ||
70 | +}; | ||
71 | + | ||
72 | +export const getInitDictData = async () => { | ||
73 | + const res = await defHttp.post({ | ||
74 | + url: Api.DICT_INIT, | ||
75 | + }); | ||
76 | + | ||
77 | + return res; | ||
78 | +}; | ||
79 | + | ||
80 | +export async function uploadImg(params, onUploadProgress: (progressEvent: ProgressEvent) => void) { | ||
81 | + const res = await defHttp.uploadFile( | ||
82 | + { | ||
83 | + url: Api.UPLOAD, | ||
84 | + onUploadProgress, | ||
85 | + }, | ||
86 | + { | ||
87 | + file: params.file, | ||
88 | + data: { name: params.file.name }, | ||
89 | + }, | ||
90 | + ); | ||
91 | + return Promise.resolve({ data: { thumbUrl: res.data } }); | ||
92 | +} | ||
93 | + | ||
94 | +export const getOrderList = async (params: DemoParams) => { | ||
95 | + const res = await defHttp.post<DemoListGetResultModel>({ | ||
96 | + url: Api.ORDER, | ||
97 | + params, | ||
98 | + headers: { | ||
99 | + // @ts-ignore | ||
100 | + ignoreCancelToken: true, | ||
101 | + }, | ||
102 | + }); | ||
103 | + const orderStore = useOrderStoreWithOut(); | ||
104 | + orderStore.setTotal(res.total); | ||
105 | + return new Promise((resolve) => { | ||
106 | + resolve({ | ||
107 | + items: res.records, | ||
108 | + total: res.total, | ||
109 | + }); | ||
110 | + }); | ||
111 | +}; | ||
112 | + | ||
113 | +export const dictCreate = async (data: any) => { | ||
114 | + const res = await defHttp.post<any>({ url: Api.DICT_ADD, data }, { message: '保存成功' }); | ||
115 | + return res; | ||
116 | +}; | ||
117 | + | ||
118 | +export const dictUpdate = async (data: any) => { | ||
119 | + const res = await defHttp.post<any>({ url: Api.DICT_UPDATE, data }, { message: '保存成功' }); | ||
120 | + return res; | ||
121 | +}; | ||
122 | + | ||
123 | +export const dictDelete = async (data: any) => { | ||
124 | + const res = await defHttp.post<any>({ url: Api.DICT_DELETE, data }, { message: '保存成功' }); | ||
125 | + return res; | ||
126 | +}; | ||
127 | + | ||
128 | +export const dictList = async (data: any) => { | ||
129 | + const res = await defHttp.post<any>({ url: Api.DICT_LIST, data: { ...data, pageSize: 1000 } }); | ||
130 | + return res; | ||
131 | +}; |
src/api/sys/model/userModel.ts
@@ -2,8 +2,10 @@ | @@ -2,8 +2,10 @@ | ||
2 | * @description: Login interface parameters | 2 | * @description: Login interface parameters |
3 | */ | 3 | */ |
4 | export interface LoginParams { | 4 | export interface LoginParams { |
5 | - username: string; | 5 | + userName: string; |
6 | password: string; | 6 | password: string; |
7 | + imgCaptchaCode: string; | ||
8 | + imgCaptchaUuid: string; | ||
7 | } | 9 | } |
8 | 10 | ||
9 | export interface RoleInfo { | 11 | export interface RoleInfo { |
src/api/sys/user.ts
@@ -4,7 +4,8 @@ import { LoginParams, LoginResultModel, GetUserInfoModel } from './model/userMod | @@ -4,7 +4,8 @@ import { LoginParams, LoginResultModel, GetUserInfoModel } from './model/userMod | ||
4 | import { ErrorMessageMode } from '/#/axios'; | 4 | import { ErrorMessageMode } from '/#/axios'; |
5 | 5 | ||
6 | enum Api { | 6 | enum Api { |
7 | - Login = '/login', | 7 | + // Login = '/login', |
8 | + Login = '/order/erp/auth/login_by_pwd', | ||
8 | Logout = '/logout', | 9 | Logout = '/logout', |
9 | GetUserInfo = '/getUserInfo', | 10 | GetUserInfo = '/getUserInfo', |
10 | GetPermCode = '/getPermCode', | 11 | GetPermCode = '/getPermCode', |
@@ -53,3 +54,7 @@ export function testRetry() { | @@ -53,3 +54,7 @@ export function testRetry() { | ||
53 | }, | 54 | }, |
54 | ); | 55 | ); |
55 | } | 56 | } |
57 | + | ||
58 | +export function getImageCaptcha() { | ||
59 | + return defHttp.post({ url: '/order/erp/captcha/get_img_captcha_code' }); | ||
60 | +} |
src/components/FieldUpload/index.ts
0 → 100644
src/components/FieldUpload/src/FieldUpload.vue
0 → 100644
1 | +<template> | ||
2 | + <Upload | ||
3 | + v-model:file-list="fileList" | ||
4 | + name="file" | ||
5 | + list-type="picture-card" | ||
6 | + class="avatar-uploader" | ||
7 | + :show-upload-list="false" | ||
8 | + action="/api/localStorage/upload" | ||
9 | + accept=".jpg,.jpeg,.gif,.png,.webp" | ||
10 | + :data="handleData" | ||
11 | + > | ||
12 | + <img v-if="imgUrl" :src="imgUrl" alt="avatar" width="100" height="100" /> | ||
13 | + <div v-else> | ||
14 | + <loading-outlined v-if="loading" /> | ||
15 | + <plus-outlined v-else /> | ||
16 | + <div class="ant-upload-text">上传</div> | ||
17 | + </div> | ||
18 | + </Upload> | ||
19 | +</template> | ||
20 | +<script lang="ts" setup> | ||
21 | + import { defineProps, ref } from 'vue'; | ||
22 | + | ||
23 | + import { Upload, message } from 'ant-design-vue'; | ||
24 | + import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue'; | ||
25 | + import type { UploadChangeParam, UploadProps } from 'ant-design-vue'; | ||
26 | + | ||
27 | + const props = defineProps({ | ||
28 | + imgUrl: String, // 期望 'value' 是一个字符串。根据您的需求调整类型。 | ||
29 | + }); | ||
30 | + console.log('%c [ props ]-29', 'font-size:13px; background:pink; color:#bf2c9f;', props); | ||
31 | + | ||
32 | + function getBase64(img: Blob, callback: (base64Url: string) => void) { | ||
33 | + const reader = new FileReader(); | ||
34 | + reader.addEventListener('load', () => callback(reader.result as string)); | ||
35 | + reader.readAsDataURL(img); | ||
36 | + } | ||
37 | + const handleData = (data) => { | ||
38 | + console.log('%c [ data ]-32', 'font-size:13px; background:pink; color:#bf2c9f;', data); | ||
39 | + return { name: data.name }; | ||
40 | + }; | ||
41 | + | ||
42 | + const fileList = ref([]); | ||
43 | + const loading = ref<boolean>(false); | ||
44 | + const imageUrl = ref<string>(''); | ||
45 | + | ||
46 | + const handleChange = (info: UploadChangeParam) => { | ||
47 | + // if (info.file.status === 'uploading') { | ||
48 | + // loading.value = true; | ||
49 | + // return; | ||
50 | + // } | ||
51 | + // if (info.file.status === 'done') { | ||
52 | + // // Get this url from response in real world. | ||
53 | + // getBase64(info.file.originFileObj, (base64Url: string) => { | ||
54 | + // imageUrl.value = base64Url; | ||
55 | + // loading.value = false; | ||
56 | + // }); | ||
57 | + // } | ||
58 | + // if (info.file.status === 'error') { | ||
59 | + // loading.value = false; | ||
60 | + // message.error('upload error'); | ||
61 | + // } | ||
62 | + }; | ||
63 | + | ||
64 | + const beforeUpload = (file: UploadProps['fileList'][number]) => { | ||
65 | + const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'; | ||
66 | + if (!isJpgOrPng) { | ||
67 | + message.error('You can only upload JPG file!'); | ||
68 | + } | ||
69 | + const isLt2M = file.size / 1024 / 1024 < 2; | ||
70 | + if (!isLt2M) { | ||
71 | + message.error('图片最大10MB!'); | ||
72 | + } | ||
73 | + return isJpgOrPng && isLt2M; | ||
74 | + }; | ||
75 | +</script> | ||
76 | +<style scoped> | ||
77 | + .avatar-uploader > .ant-upload { | ||
78 | + width: 128px; | ||
79 | + height: 128px; | ||
80 | + } | ||
81 | + | ||
82 | + .ant-upload-select-picture-card i { | ||
83 | + color: #999; | ||
84 | + font-size: 32px; | ||
85 | + } | ||
86 | + | ||
87 | + .ant-upload-select-picture-card .ant-upload-text { | ||
88 | + margin-top: 8px; | ||
89 | + color: #666; | ||
90 | + } | ||
91 | +</style> |
src/components/Form/src/BasicForm.vue
@@ -117,14 +117,19 @@ | @@ -117,14 +117,19 @@ | ||
117 | const getSchema = computed((): FormSchema[] => { | 117 | const getSchema = computed((): FormSchema[] => { |
118 | const schemas: FormSchema[] = unref(schemaRef) || (unref(getProps).schemas as any); | 118 | const schemas: FormSchema[] = unref(schemaRef) || (unref(getProps).schemas as any); |
119 | for (const schema of schemas) { | 119 | for (const schema of schemas) { |
120 | - const { defaultValue, component, componentProps,isHandleDateDefaultValue = true } = schema; | 120 | + const { |
121 | + defaultValue, | ||
122 | + component, | ||
123 | + componentProps, | ||
124 | + isHandleDateDefaultValue = true, | ||
125 | + } = schema; | ||
121 | // handle date type | 126 | // handle date type |
122 | if (isHandleDateDefaultValue && defaultValue && dateItemType.includes(component)) { | 127 | if (isHandleDateDefaultValue && defaultValue && dateItemType.includes(component)) { |
123 | - const valueFormat =componentProps ? componentProps['valueFormat'] : null; | 128 | + const valueFormat = componentProps ? componentProps['valueFormat'] : null; |
124 | if (!Array.isArray(defaultValue)) { | 129 | if (!Array.isArray(defaultValue)) { |
125 | - schema.defaultValue = valueFormat | ||
126 | - ? dateUtil(defaultValue).format(valueFormat) | ||
127 | - : dateUtil(defaultValue); | 130 | + schema.defaultValue = valueFormat |
131 | + ? dateUtil(defaultValue).format(valueFormat) | ||
132 | + : dateUtil(defaultValue); | ||
128 | } else { | 133 | } else { |
129 | const def: any[] = []; | 134 | const def: any[] = []; |
130 | defaultValue.forEach((item) => { | 135 | defaultValue.forEach((item) => { |
src/components/Form/src/componentMap.ts
@@ -29,6 +29,8 @@ import ApiTreeSelect from './components/ApiTreeSelect.vue'; | @@ -29,6 +29,8 @@ import ApiTreeSelect from './components/ApiTreeSelect.vue'; | ||
29 | import ApiCascader from './components/ApiCascader.vue'; | 29 | import ApiCascader from './components/ApiCascader.vue'; |
30 | import ApiTransfer from './components/ApiTransfer.vue'; | 30 | import ApiTransfer from './components/ApiTransfer.vue'; |
31 | import { BasicUpload } from '/@/components/Upload'; | 31 | import { BasicUpload } from '/@/components/Upload'; |
32 | +import FieldUpload from '/@/components/FieldUpload'; | ||
33 | + | ||
32 | import { StrengthMeter } from '/@/components/StrengthMeter'; | 34 | import { StrengthMeter } from '/@/components/StrengthMeter'; |
33 | import { IconPicker } from '/@/components/Icon'; | 35 | import { IconPicker } from '/@/components/Icon'; |
34 | import { CountdownInput } from '/@/components/CountDown'; | 36 | import { CountdownInput } from '/@/components/CountDown'; |
@@ -71,6 +73,7 @@ componentMap.set('IconPicker', IconPicker); | @@ -71,6 +73,7 @@ componentMap.set('IconPicker', IconPicker); | ||
71 | componentMap.set('InputCountDown', CountdownInput); | 73 | componentMap.set('InputCountDown', CountdownInput); |
72 | 74 | ||
73 | componentMap.set('Upload', BasicUpload); | 75 | componentMap.set('Upload', BasicUpload); |
76 | +componentMap.set('FieldUpload', FieldUpload); | ||
74 | componentMap.set('Divider', Divider); | 77 | componentMap.set('Divider', Divider); |
75 | 78 | ||
76 | export function add(compName: ComponentType, component: Component) { | 79 | export function add(compName: ComponentType, component: Component) { |
src/components/Form/src/types/index.ts
@@ -110,6 +110,7 @@ export type ComponentType = | @@ -110,6 +110,7 @@ export type ComponentType = | ||
110 | | 'Switch' | 110 | | 'Switch' |
111 | | 'StrengthMeter' | 111 | | 'StrengthMeter' |
112 | | 'Upload' | 112 | | 'Upload' |
113 | + | 'FieldUpload' | ||
113 | | 'IconPicker' | 114 | | 'IconPicker' |
114 | | 'Render' | 115 | | 'Render' |
115 | | 'Slider' | 116 | | 'Slider' |
src/components/Table/src/BasicTable.vue
@@ -457,4 +457,16 @@ | @@ -457,4 +457,16 @@ | ||
457 | } | 457 | } |
458 | } | 458 | } |
459 | } | 459 | } |
460 | + | ||
461 | + .ant-table { | ||
462 | + font-size: 15px !important; | ||
463 | + } | ||
464 | + | ||
465 | + .ant-table-middle { | ||
466 | + font-size: 14px !important; | ||
467 | + } | ||
468 | + | ||
469 | + .ant-table-small { | ||
470 | + font-size: 13px !important; | ||
471 | + } | ||
460 | </style> | 472 | </style> |
src/components/Table/src/components/settings/ColumnSetting.vue
@@ -12,7 +12,7 @@ | @@ -12,7 +12,7 @@ | ||
12 | > | 12 | > |
13 | <template #title> | 13 | <template #title> |
14 | <div :class="`${prefixCls}__popover-title`"> | 14 | <div :class="`${prefixCls}__popover-title`"> |
15 | - <Checkbox | 15 | + <!-- <Checkbox |
16 | :indeterminate="indeterminate" | 16 | :indeterminate="indeterminate" |
17 | v-model:checked="checkAll" | 17 | v-model:checked="checkAll" |
18 | @change="onCheckAllChange" | 18 | @change="onCheckAllChange" |
@@ -22,7 +22,7 @@ | @@ -22,7 +22,7 @@ | ||
22 | 22 | ||
23 | <Checkbox v-model:checked="checkIndex" @change="handleIndexCheckChange"> | 23 | <Checkbox v-model:checked="checkIndex" @change="handleIndexCheckChange"> |
24 | {{ t('component.table.settingIndexColumnShow') }} | 24 | {{ t('component.table.settingIndexColumnShow') }} |
25 | - </Checkbox> | 25 | + </Checkbox> --> |
26 | 26 | ||
27 | <Checkbox | 27 | <Checkbox |
28 | v-model:checked="checkSelect" | 28 | v-model:checked="checkSelect" |
@@ -43,12 +43,12 @@ | @@ -43,12 +43,12 @@ | ||
43 | <CheckboxGroup v-model:value="checkedList" @change="onChange" ref="columnListRef"> | 43 | <CheckboxGroup v-model:value="checkedList" @change="onChange" ref="columnListRef"> |
44 | <template v-for="item in plainOptions" :key="item.value"> | 44 | <template v-for="item in plainOptions" :key="item.value"> |
45 | <div :class="`${prefixCls}__check-item`" v-if="!('ifShow' in item && !item.ifShow)"> | 45 | <div :class="`${prefixCls}__check-item`" v-if="!('ifShow' in item && !item.ifShow)"> |
46 | - <DragOutlined class="table-column-drag-icon" /> | 46 | + <!-- <DragOutlined class="table-column-drag-icon" /> --> |
47 | <Checkbox :value="item.value"> | 47 | <Checkbox :value="item.value"> |
48 | {{ item.label }} | 48 | {{ item.label }} |
49 | </Checkbox> | 49 | </Checkbox> |
50 | 50 | ||
51 | - <Tooltip | 51 | + <!-- <Tooltip |
52 | placement="bottomLeft" | 52 | placement="bottomLeft" |
53 | :mouseLeaveDelay="0.4" | 53 | :mouseLeaveDelay="0.4" |
54 | :getPopupContainer="getPopupContainer" | 54 | :getPopupContainer="getPopupContainer" |
@@ -88,7 +88,7 @@ | @@ -88,7 +88,7 @@ | ||
88 | ]" | 88 | ]" |
89 | @click="handleColumnFixed(item, 'right')" | 89 | @click="handleColumnFixed(item, 'right')" |
90 | /> | 90 | /> |
91 | - </Tooltip> | 91 | + </Tooltip> --> |
92 | </div> | 92 | </div> |
93 | </template> | 93 | </template> |
94 | </CheckboxGroup> | 94 | </CheckboxGroup> |
@@ -156,6 +156,7 @@ | @@ -156,6 +156,7 @@ | ||
156 | setup(_, { emit, attrs }) { | 156 | setup(_, { emit, attrs }) { |
157 | const { t } = useI18n(); | 157 | const { t } = useI18n(); |
158 | const table = useTableContext(); | 158 | const table = useTableContext(); |
159 | + const originColumns = getColumns(); // 配置的列 | ||
159 | 160 | ||
160 | const defaultRowSelection = omit(table.getRowSelection(), 'selectedRowKeys'); | 161 | const defaultRowSelection = omit(table.getRowSelection(), 'selectedRowKeys'); |
161 | let inited = false; | 162 | let inited = false; |
@@ -236,14 +237,37 @@ | @@ -236,14 +237,37 @@ | ||
236 | const checkList = table | 237 | const checkList = table |
237 | .getColumns({ ignoreAction: true, ignoreIndex: true }) | 238 | .getColumns({ ignoreAction: true, ignoreIndex: true }) |
238 | .map((item) => { | 239 | .map((item) => { |
239 | - if (item.defaultHidden) { | ||
240 | - return ''; | 240 | + if (item.children) { |
241 | + return item.children.map((item) => { | ||
242 | + if (item.defaultHidden) { | ||
243 | + return ''; | ||
244 | + } | ||
245 | + return item.dataIndex || item.title; | ||
246 | + }); | ||
247 | + } else { | ||
248 | + if (item.defaultHidden) { | ||
249 | + return ''; | ||
250 | + } | ||
251 | + return item.dataIndex || item.title; | ||
241 | } | 252 | } |
242 | - return item.dataIndex || item.title; | ||
243 | }) | 253 | }) |
254 | + .flat() | ||
244 | .filter(Boolean) as string[]; | 255 | .filter(Boolean) as string[]; |
245 | - plainOptions.value = columns; | 256 | + |
257 | + // plainOptions.value = columns; | ||
246 | plainSortOptions.value = columns; | 258 | plainSortOptions.value = columns; |
259 | + plainOptions.value = columns | ||
260 | + .map((item) => { | ||
261 | + if (item.children) { | ||
262 | + return item.children.map((item) => ({ | ||
263 | + ...item, | ||
264 | + label: item.title, | ||
265 | + value: item.dataIndex || item.title, | ||
266 | + })); | ||
267 | + } | ||
268 | + return item; | ||
269 | + }) | ||
270 | + .flat(); | ||
247 | // 更新缓存配置 | 271 | // 更新缓存配置 |
248 | table.setCacheColumns?.(columns); | 272 | table.setCacheColumns?.(columns); |
249 | !isReset && (cachePlainOptions.value = cloneDeep(columns)); | 273 | !isReset && (cachePlainOptions.value = cloneDeep(columns)); |
@@ -282,12 +306,22 @@ | @@ -282,12 +306,22 @@ | ||
282 | const len = plainSortOptions.value.length; | 306 | const len = plainSortOptions.value.length; |
283 | state.checkAll = checkedList.length === len; | 307 | state.checkAll = checkedList.length === len; |
284 | const sortList = unref(plainSortOptions).map((item) => item.value); | 308 | const sortList = unref(plainSortOptions).map((item) => item.value); |
309 | + | ||
285 | checkedList.sort((prev, next) => { | 310 | checkedList.sort((prev, next) => { |
286 | return sortList.indexOf(prev) - sortList.indexOf(next); | 311 | return sortList.indexOf(prev) - sortList.indexOf(next); |
287 | }); | 312 | }); |
288 | unref(plainSortOptions).forEach((item) => { | 313 | unref(plainSortOptions).forEach((item) => { |
289 | - (item as BasicColumn).defaultHidden = !checkedList.includes(item.value); | 314 | + // 若存在children则,便利children |
315 | + if (item.children) { | ||
316 | + item.children.forEach((item) => { | ||
317 | + (item as BasicColumn).defaultHidden = !checkedList.includes(item.value); | ||
318 | + }); | ||
319 | + return; | ||
320 | + } else { | ||
321 | + (item as BasicColumn).defaultHidden = !checkedList.includes(item.value); | ||
322 | + } | ||
290 | }); | 323 | }); |
324 | + | ||
291 | setColumns(checkedList); | 325 | setColumns(checkedList); |
292 | } | 326 | } |
293 | 327 | ||
@@ -388,17 +422,63 @@ | @@ -388,17 +422,63 @@ | ||
388 | function setColumns(columns: BasicColumn[] | string[]) { | 422 | function setColumns(columns: BasicColumn[] | string[]) { |
389 | isSetPropsFromThis = true; | 423 | isSetPropsFromThis = true; |
390 | isSetColumnsFromThis = true; | 424 | isSetColumnsFromThis = true; |
391 | - table.setColumns(columns); | ||
392 | - const data: ColumnChangeParam[] = unref(plainSortOptions).map((col) => { | ||
393 | - const visible = | ||
394 | - columns.findIndex( | ||
395 | - (c: BasicColumn | string) => | ||
396 | - c === col.value || (typeof c !== 'string' && c.dataIndex === col.value), | ||
397 | - ) !== -1; | ||
398 | - return { dataIndex: col.value, fixed: col.fixed, visible }; | ||
399 | - }); | ||
400 | 425 | ||
401 | - emit('columns-change', data); | 426 | + const newColumns = plainSortOptions.value |
427 | + .map((col) => { | ||
428 | + if (col.children) { | ||
429 | + return { | ||
430 | + ...col, | ||
431 | + children: col.children.map((c) => { | ||
432 | + if (columns.includes(c.dataIndex as string)) { | ||
433 | + return { | ||
434 | + ...c, | ||
435 | + defaultHidden: false, | ||
436 | + }; | ||
437 | + } | ||
438 | + return { | ||
439 | + ...c, | ||
440 | + defaultHidden: true, | ||
441 | + }; | ||
442 | + }), | ||
443 | + }; | ||
444 | + } else { | ||
445 | + if (columns.includes(col.dataIndex as string)) { | ||
446 | + return { | ||
447 | + ...col, | ||
448 | + defaultHidden: false, | ||
449 | + }; | ||
450 | + } | ||
451 | + return { | ||
452 | + ...col, | ||
453 | + defaultHidden: true, | ||
454 | + }; | ||
455 | + } | ||
456 | + }) | ||
457 | + .filter((col) => { | ||
458 | + if (col.children) { | ||
459 | + const newChildren = col.children.filter((c) => !c.defaultHidden); | ||
460 | + if (!newChildren.length) return false; | ||
461 | + col.children = newChildren; | ||
462 | + return true; | ||
463 | + } | ||
464 | + return !col.defaultHidden; | ||
465 | + }); | ||
466 | + | ||
467 | + table.setColumns(newColumns); | ||
468 | + | ||
469 | + // const columns = unref(plainSortOptions).map(col => { | ||
470 | + // if(col.) | ||
471 | + // }) | ||
472 | + // const data: ColumnChangeParam[] = unref(plainSortOptions).map((col) => { | ||
473 | + // const visible = | ||
474 | + // columns.findIndex( | ||
475 | + // (c: BasicColumn | string) => | ||
476 | + // c === col.value || (typeof c !== 'string' && c.dataIndex === col.value), | ||
477 | + // ) !== -1; | ||
478 | + // return { dataIndex: col.value, fixed: col.fixed, visible }; | ||
479 | + // }); | ||
480 | + | ||
481 | + // emit('columns-change', data); | ||
402 | } | 482 | } |
403 | 483 | ||
404 | function getPopupContainer() { | 484 | function getPopupContainer() { |
@@ -457,7 +537,7 @@ | @@ -457,7 +537,7 @@ | ||
457 | display: flex; | 537 | display: flex; |
458 | align-items: center; | 538 | align-items: center; |
459 | min-width: 100%; | 539 | min-width: 100%; |
460 | - padding: 4px 16px 8px 0; | 540 | + padding: 4px 16px 8px; |
461 | 541 | ||
462 | .ant-checkbox-wrapper { | 542 | .ant-checkbox-wrapper { |
463 | width: 100%; | 543 | width: 100%; |
src/components/Table/src/hooks/useDataSource.ts
@@ -307,6 +307,7 @@ export function useDataSource( | @@ -307,6 +307,7 @@ export function useDataSource( | ||
307 | const isArrayResult = Array.isArray(res); | 307 | const isArrayResult = Array.isArray(res); |
308 | 308 | ||
309 | let resultItems: Recordable[] = isArrayResult ? res : get(res, listField); | 309 | let resultItems: Recordable[] = isArrayResult ? res : get(res, listField); |
310 | + console.log('%c [ res ]-311', 'font-size:13px; background:pink; color:#bf2c9f;', res); | ||
310 | const resultTotal: number = isArrayResult ? res.length : get(res, totalField); | 311 | const resultTotal: number = isArrayResult ? res.length : get(res, totalField); |
311 | 312 | ||
312 | // 假如数据变少,导致总页数变少并小于当前选中页码,通过getPaginationRef获取到的页码是不正确的,需获取正确的页码再次执行 | 313 | // 假如数据变少,导致总页数变少并小于当前选中页码,通过getPaginationRef获取到的页码是不正确的,需获取正确的页码再次执行 |
src/components/Upload/src/FileList.vue
@@ -46,6 +46,12 @@ | @@ -46,6 +46,12 @@ | ||
46 | </thead> | 46 | </thead> |
47 | <tbody> | 47 | <tbody> |
48 | {dataSource.map((record = {}, index) => { | 48 | {dataSource.map((record = {}, index) => { |
49 | + console.log( | ||
50 | + '%c [ record ]-49', | ||
51 | + 'font-size:13px; background:pink; color:#bf2c9f;', | ||
52 | + record, | ||
53 | + ); | ||
54 | + | ||
49 | return ( | 55 | return ( |
50 | <tr class="file-table-tr" key={`${index + record.name || ''}`}> | 56 | <tr class="file-table-tr" key={`${index + record.name || ''}`}> |
51 | {columnList.map((item) => { | 57 | {columnList.map((item) => { |
src/design/theme.less
src/enums/exceptionEnum.ts
src/enums/pageEnum.ts
@@ -2,7 +2,7 @@ export enum PageEnum { | @@ -2,7 +2,7 @@ export enum PageEnum { | ||
2 | // basic login path | 2 | // basic login path |
3 | BASE_LOGIN = '/login', | 3 | BASE_LOGIN = '/login', |
4 | // basic home path | 4 | // basic home path |
5 | - BASE_HOME = '/dashboard', | 5 | + BASE_HOME = '/', |
6 | // error page path | 6 | // error page path |
7 | ERROR_PAGE = '/exception', | 7 | ERROR_PAGE = '/exception', |
8 | // error log page path | 8 | // error log page path |
src/hooks/component/order.ts
0 → 100644
1 | +// useOrderInfo.js | ||
2 | +import { computed } from 'vue'; | ||
3 | +import { map } from 'lodash-es'; | ||
4 | + | ||
5 | +export function useOrderInfo(orderStore) { | ||
6 | + // 确保 transformDictInfo 函数是可用的,可以将其导入或在此文件中定义 | ||
7 | + const transformDictInfo = (item) => ({ | ||
8 | + label: item.dictValue, | ||
9 | + value: item.dictValue, | ||
10 | + }); | ||
11 | + | ||
12 | + const customerCode = computed(() => { | ||
13 | + const dictInfo = orderStore.getDictInfo; | ||
14 | + | ||
15 | + return map(dictInfo?.customerCode, transformDictInfo); | ||
16 | + }); | ||
17 | + | ||
18 | + const projectNo = computed(() => { | ||
19 | + const dictInfo = orderStore.getDictInfo; | ||
20 | + return map(dictInfo?.projectNo, transformDictInfo); | ||
21 | + }); | ||
22 | + | ||
23 | + const productionDepartment = computed(() => { | ||
24 | + const dictInfo = orderStore.getDictInfo; | ||
25 | + return map(dictInfo?.productionDepartment, transformDictInfo); | ||
26 | + }); | ||
27 | + | ||
28 | + const innerNo = computed(() => { | ||
29 | + const dictInfo = orderStore.getDictInfo; | ||
30 | + return map(dictInfo?.innerNo, transformDictInfo); | ||
31 | + }); | ||
32 | + | ||
33 | + const poColor = computed(() => { | ||
34 | + const dictInfo = orderStore.getDictInfo; | ||
35 | + return map(dictInfo?.poColor, transformDictInfo); | ||
36 | + }); | ||
37 | + | ||
38 | + const cnColor = computed(() => { | ||
39 | + const dictInfo = orderStore.getDictInfo; | ||
40 | + return map(dictInfo?.cnColor, transformDictInfo); | ||
41 | + }); | ||
42 | + | ||
43 | + const productStyle = computed(() => { | ||
44 | + const dictInfo = orderStore.getDictInfo; | ||
45 | + return map(dictInfo?.productStyle, transformDictInfo); | ||
46 | + }); | ||
47 | + | ||
48 | + const outboundType = computed(() => { | ||
49 | + const dictInfo = orderStore.getDictInfo; | ||
50 | + return map(dictInfo?.outboundType, transformDictInfo); | ||
51 | + }); | ||
52 | + | ||
53 | + const packetType = computed(() => { | ||
54 | + const dictInfo = orderStore.getDictInfo; | ||
55 | + return map(dictInfo?.packetType, transformDictInfo); | ||
56 | + }); | ||
57 | + | ||
58 | + const ideaSource = computed(() => { | ||
59 | + const dictInfo = orderStore.getDictInfo; | ||
60 | + return map(dictInfo?.ideaSource, transformDictInfo); | ||
61 | + }); | ||
62 | + | ||
63 | + const manualPreform = computed(() => { | ||
64 | + const dictInfo = orderStore.getDictInfo; | ||
65 | + return map(dictInfo?.manualPreform, transformDictInfo); | ||
66 | + }); | ||
67 | + | ||
68 | + const endCheckResult = computed(() => { | ||
69 | + const dictInfo = orderStore.getDictInfo; | ||
70 | + return map(dictInfo?.endCheckResult, transformDictInfo); | ||
71 | + }); | ||
72 | + | ||
73 | + const midCheckResult = computed(() => { | ||
74 | + const dictInfo = orderStore.getDictInfo; | ||
75 | + return map(dictInfo?.midCheckResult, transformDictInfo); | ||
76 | + }); | ||
77 | + | ||
78 | + console.log('%c [ ]-78', 'font-size:13px; background:pink; color:#bf2c9f;', endCheckResult); | ||
79 | + return { | ||
80 | + customerCode, | ||
81 | + projectNo, | ||
82 | + productionDepartment, | ||
83 | + innerNo, | ||
84 | + poColor, | ||
85 | + cnColor, | ||
86 | + productStyle, | ||
87 | + outboundType, | ||
88 | + packetType, | ||
89 | + ideaSource, | ||
90 | + manualPreform, | ||
91 | + midCheckResult, | ||
92 | + endCheckResult, | ||
93 | + }; | ||
94 | +} |
src/layouts/default/header/components/user-dropdown/index.vue
@@ -11,7 +11,7 @@ | @@ -11,7 +11,7 @@ | ||
11 | 11 | ||
12 | <template #overlay> | 12 | <template #overlay> |
13 | <Menu @click="handleMenuClick"> | 13 | <Menu @click="handleMenuClick"> |
14 | - <MenuItem | 14 | + <!-- <MenuItem |
15 | key="doc" | 15 | key="doc" |
16 | :text="t('layout.header.dropdownItemDoc')" | 16 | :text="t('layout.header.dropdownItemDoc')" |
17 | icon="ion:document-text-outline" | 17 | icon="ion:document-text-outline" |
@@ -23,7 +23,7 @@ | @@ -23,7 +23,7 @@ | ||
23 | key="lock" | 23 | key="lock" |
24 | :text="t('layout.header.tooltipLock')" | 24 | :text="t('layout.header.tooltipLock')" |
25 | icon="ion:lock-closed-outline" | 25 | icon="ion:lock-closed-outline" |
26 | - /> | 26 | + /> --> |
27 | <MenuItem | 27 | <MenuItem |
28 | key="logout" | 28 | key="logout" |
29 | :text="t('layout.header.dropdownItemLoginOut')" | 29 | :text="t('layout.header.dropdownItemLoginOut')" |
src/layouts/default/header/index.vue
@@ -33,24 +33,24 @@ | @@ -33,24 +33,24 @@ | ||
33 | 33 | ||
34 | <!-- action --> | 34 | <!-- action --> |
35 | <div :class="`${prefixCls}-action`"> | 35 | <div :class="`${prefixCls}-action`"> |
36 | - <AppSearch :class="`${prefixCls}-action__item `" v-if="getShowSearch" /> | 36 | + <!-- <AppSearch :class="`${prefixCls}-action__item `" v-if="getShowSearch" /> --> |
37 | 37 | ||
38 | <ErrorAction v-if="getUseErrorHandle" :class="`${prefixCls}-action__item error-action`" /> | 38 | <ErrorAction v-if="getUseErrorHandle" :class="`${prefixCls}-action__item error-action`" /> |
39 | 39 | ||
40 | - <Notify v-if="getShowNotice" :class="`${prefixCls}-action__item notify-item`" /> | 40 | + <!-- <Notify v-if="getShowNotice" :class="`${prefixCls}-action__item notify-item`" /> --> |
41 | 41 | ||
42 | <FullScreen v-if="getShowFullScreen" :class="`${prefixCls}-action__item fullscreen-item`" /> | 42 | <FullScreen v-if="getShowFullScreen" :class="`${prefixCls}-action__item fullscreen-item`" /> |
43 | 43 | ||
44 | - <AppLocalePicker | 44 | + <!-- <AppLocalePicker |
45 | v-if="getShowLocalePicker" | 45 | v-if="getShowLocalePicker" |
46 | :reload="true" | 46 | :reload="true" |
47 | :showText="false" | 47 | :showText="false" |
48 | :class="`${prefixCls}-action__item`" | 48 | :class="`${prefixCls}-action__item`" |
49 | - /> | 49 | + /> --> |
50 | 50 | ||
51 | <UserDropDown :theme="getHeaderTheme" /> | 51 | <UserDropDown :theme="getHeaderTheme" /> |
52 | 52 | ||
53 | - <SettingDrawer v-if="getShowSetting" :class="`${prefixCls}-action__item`" /> | 53 | + <!-- <SettingDrawer v-if="getShowSetting" :class="`${prefixCls}-action__item`" /> --> |
54 | </div> | 54 | </div> |
55 | </Header> | 55 | </Header> |
56 | </template> | 56 | </template> |
src/layouts/default/index.vue
@@ -3,9 +3,12 @@ | @@ -3,9 +3,12 @@ | ||
3 | <LayoutFeatures /> | 3 | <LayoutFeatures /> |
4 | <LayoutHeader fixed v-if="getShowFullHeaderRef" /> | 4 | <LayoutHeader fixed v-if="getShowFullHeaderRef" /> |
5 | <Layout :class="[layoutClass]"> | 5 | <Layout :class="[layoutClass]"> |
6 | + <!-- 左侧菜单 --> | ||
6 | <LayoutSideBar v-if="getShowSidebar || getIsMobile" /> | 7 | <LayoutSideBar v-if="getShowSidebar || getIsMobile" /> |
7 | <Layout :class="`${prefixCls}-main`"> | 8 | <Layout :class="`${prefixCls}-main`"> |
9 | + <!-- 顶部header --> | ||
8 | <LayoutMultipleHeader /> | 10 | <LayoutMultipleHeader /> |
11 | + <!-- 内容区域 --> | ||
9 | <LayoutContent /> | 12 | <LayoutContent /> |
10 | <LayoutFooter /> | 13 | <LayoutFooter /> |
11 | </Layout> | 14 | </Layout> |
src/layouts/default/menu/index.vue
@@ -140,7 +140,7 @@ | @@ -140,7 +140,7 @@ | ||
140 | 140 | ||
141 | function renderMenu() { | 141 | function renderMenu() { |
142 | const { menus, ...menuProps } = unref(getCommonProps); | 142 | const { menus, ...menuProps } = unref(getCommonProps); |
143 | - // console.log(menus); | 143 | + console.log(menus); |
144 | if (!menus || !menus.length) return null; | 144 | if (!menus || !menus.length) return null; |
145 | return !props.isHorizontal ? ( | 145 | return !props.isHorizontal ? ( |
146 | <SimpleMenu {...menuProps} isSplitMenu={unref(getSplit)} items={menus} /> | 146 | <SimpleMenu {...menuProps} isSplitMenu={unref(getSplit)} items={menus} /> |
src/locales/lang/zh-CN/routes/dashboard.ts
src/locales/lang/zh-CN/sys.ts
@@ -67,8 +67,8 @@ export default { | @@ -67,8 +67,8 @@ export default { | ||
67 | signUpFormTitle: '注册', | 67 | signUpFormTitle: '注册', |
68 | forgetFormTitle: '重置密码', | 68 | forgetFormTitle: '重置密码', |
69 | 69 | ||
70 | - signInTitle: '开箱即用的中后台管理系统', | ||
71 | - signInDesc: '输入您的个人详细信息开始使用!', | 70 | + signInTitle: '订单管理系统', |
71 | + signInDesc: '', | ||
72 | policy: '我同意xxx隐私政策', | 72 | policy: '我同意xxx隐私政策', |
73 | scanSign: `扫码后点击"确认",即可完成登录`, | 73 | scanSign: `扫码后点击"确认",即可完成登录`, |
74 | 74 |
src/main.ts
@@ -40,7 +40,7 @@ async function bootstrap() { | @@ -40,7 +40,7 @@ async function bootstrap() { | ||
40 | await setupI18n(app); | 40 | await setupI18n(app); |
41 | 41 | ||
42 | // Configure routing | 42 | // Configure routing |
43 | - // 配置路由 | 43 | + // 配置路由,把一些常量不需要权限判断的路有页面放在这里 |
44 | setupRouter(app); | 44 | setupRouter(app); |
45 | 45 | ||
46 | // router-guard | 46 | // router-guard |
src/router/guard/permissionGuard.ts
@@ -25,7 +25,7 @@ export function createPermissionGuard(router: Router) { | @@ -25,7 +25,7 @@ export function createPermissionGuard(router: Router) { | ||
25 | userStore.getUserInfo.homePath && | 25 | userStore.getUserInfo.homePath && |
26 | userStore.getUserInfo.homePath !== PageEnum.BASE_HOME | 26 | userStore.getUserInfo.homePath !== PageEnum.BASE_HOME |
27 | ) { | 27 | ) { |
28 | - next(userStore.getUserInfo.homePath); | 28 | + next('/home'); |
29 | return; | 29 | return; |
30 | } | 30 | } |
31 | 31 |
src/router/menus/index.ts
@@ -63,10 +63,12 @@ async function getAsyncMenus() { | @@ -63,10 +63,12 @@ async function getAsyncMenus() { | ||
63 | return show; | 63 | return show; |
64 | }); | 64 | }); |
65 | }; | 65 | }; |
66 | + | ||
66 | if (isBackMode()) { | 67 | if (isBackMode()) { |
67 | return menuFilter(permissionStore.getBackMenuList); | 68 | return menuFilter(permissionStore.getBackMenuList); |
68 | } | 69 | } |
69 | - if (isRouteMappingMode()) { | 70 | + // if (isRouteMappingMode()) { |
71 | + if (true) { | ||
70 | return menuFilter(permissionStore.getFrontMenuList); | 72 | return menuFilter(permissionStore.getFrontMenuList); |
71 | } | 73 | } |
72 | return staticMenus; | 74 | return staticMenus; |
src/router/routes/index.ts
@@ -7,7 +7,7 @@ import { PageEnum } from '/@/enums/pageEnum'; | @@ -7,7 +7,7 @@ import { PageEnum } from '/@/enums/pageEnum'; | ||
7 | import { t } from '/@/hooks/web/useI18n'; | 7 | import { t } from '/@/hooks/web/useI18n'; |
8 | 8 | ||
9 | // import.meta.glob() 直接引入所有的模块 Vite 独有的功能 | 9 | // import.meta.glob() 直接引入所有的模块 Vite 独有的功能 |
10 | -const modules = import.meta.glob('./modules/**/*.ts', { eager: true }); | 10 | +const modules = import.meta.glob('./modules/project/*.ts', { eager: true }); |
11 | const routeModuleList: AppRouteModule[] = []; | 11 | const routeModuleList: AppRouteModule[] = []; |
12 | 12 | ||
13 | // 加入到路由集合中 | 13 | // 加入到路由集合中 |
@@ -40,6 +40,7 @@ export const LoginRoute: AppRouteRecordRaw = { | @@ -40,6 +40,7 @@ export const LoginRoute: AppRouteRecordRaw = { | ||
40 | 40 | ||
41 | // Basic routing without permission | 41 | // Basic routing without permission |
42 | // 未经许可的基本路由 | 42 | // 未经许可的基本路由 |
43 | +// 没有权限要求,所有人都看得到 | ||
43 | export const basicRoutes = [ | 44 | export const basicRoutes = [ |
44 | LoginRoute, | 45 | LoginRoute, |
45 | RootRoute, | 46 | RootRoute, |
src/router/routes/modules/demo/system.ts
@@ -21,7 +21,7 @@ const system: AppRouteModule = { | @@ -21,7 +21,7 @@ const system: AppRouteModule = { | ||
21 | title: t('routes.demo.system.account'), | 21 | title: t('routes.demo.system.account'), |
22 | ignoreKeepAlive: false, | 22 | ignoreKeepAlive: false, |
23 | }, | 23 | }, |
24 | - component: () => import('/@/views/demo/system/account/index.vue'), | 24 | + component: () => import('/@/views/project/system/account/index.vue'), |
25 | }, | 25 | }, |
26 | { | 26 | { |
27 | path: 'account_detail/:id', | 27 | path: 'account_detail/:id', |
@@ -33,7 +33,7 @@ const system: AppRouteModule = { | @@ -33,7 +33,7 @@ const system: AppRouteModule = { | ||
33 | showMenu: false, | 33 | showMenu: false, |
34 | currentActiveMenu: '/system/account', | 34 | currentActiveMenu: '/system/account', |
35 | }, | 35 | }, |
36 | - component: () => import('/@/views/demo/system/account/AccountDetail.vue'), | 36 | + component: () => import('/@/views/project/system/account/AccountDetail.vue'), |
37 | }, | 37 | }, |
38 | { | 38 | { |
39 | path: 'role', | 39 | path: 'role', |
src/router/routes/modules/project/approve.ts
0 → 100644
1 | +import type { AppRouteModule } from '/@/router/types'; | ||
2 | + | ||
3 | +import { LAYOUT } from '/@/router/constant'; | ||
4 | + | ||
5 | +const order: AppRouteModule = { | ||
6 | + path: '/approve', | ||
7 | + name: 'Approve', | ||
8 | + component: LAYOUT, | ||
9 | + redirect: '/approve', | ||
10 | + meta: { | ||
11 | + hideChildrenInMenu: true, | ||
12 | + orderNo: 3, | ||
13 | + icon: 'ion:grid-outline', | ||
14 | + title: '审批管理', | ||
15 | + }, | ||
16 | + children: [ | ||
17 | + { | ||
18 | + path: '', | ||
19 | + name: 'Approve', | ||
20 | + component: () => import('/@/views/project/approve/index.vue'), | ||
21 | + meta: { | ||
22 | + // affix: true, | ||
23 | + title: '审批管理', | ||
24 | + }, | ||
25 | + }, | ||
26 | + // { | ||
27 | + // path: 'workbench', | ||
28 | + // name: 'Workbench', | ||
29 | + // component: () => import('/@/views/dashboard/workbench/index.vue'), | ||
30 | + // meta: { | ||
31 | + // title: t('routes.dashboard.workbench'), | ||
32 | + // }, | ||
33 | + // }, | ||
34 | + ], | ||
35 | +}; | ||
36 | + | ||
37 | +export default order; |
src/router/routes/modules/dashboard.ts renamed to src/router/routes/modules/project/dashboard.ts
@@ -4,33 +4,34 @@ import { LAYOUT } from '/@/router/constant'; | @@ -4,33 +4,34 @@ import { LAYOUT } from '/@/router/constant'; | ||
4 | import { t } from '/@/hooks/web/useI18n'; | 4 | import { t } from '/@/hooks/web/useI18n'; |
5 | 5 | ||
6 | const dashboard: AppRouteModule = { | 6 | const dashboard: AppRouteModule = { |
7 | - path: '/dashboard', | ||
8 | - name: 'Dashboard', | 7 | + path: '/home', |
8 | + name: 'Analysis', | ||
9 | component: LAYOUT, | 9 | component: LAYOUT, |
10 | - redirect: '/dashboard/analysis', | 10 | + redirect: '/home', |
11 | meta: { | 11 | meta: { |
12 | - orderNo: 10, | 12 | + hideChildrenInMenu: true, |
13 | + orderNo: 1, | ||
13 | icon: 'ion:grid-outline', | 14 | icon: 'ion:grid-outline', |
14 | - title: t('routes.dashboard.dashboard'), | 15 | + title: t('routes.dashboard.home'), |
15 | }, | 16 | }, |
16 | children: [ | 17 | children: [ |
17 | { | 18 | { |
18 | - path: 'analysis', | 19 | + path: '', |
19 | name: 'Analysis', | 20 | name: 'Analysis', |
20 | component: () => import('/@/views/dashboard/analysis/index.vue'), | 21 | component: () => import('/@/views/dashboard/analysis/index.vue'), |
21 | meta: { | 22 | meta: { |
22 | // affix: true, | 23 | // affix: true, |
23 | - title: t('routes.dashboard.analysis'), | ||
24 | - }, | ||
25 | - }, | ||
26 | - { | ||
27 | - path: 'workbench', | ||
28 | - name: 'Workbench', | ||
29 | - component: () => import('/@/views/dashboard/workbench/index.vue'), | ||
30 | - meta: { | ||
31 | - title: t('routes.dashboard.workbench'), | 24 | + title: '首页', |
32 | }, | 25 | }, |
33 | }, | 26 | }, |
27 | + // { | ||
28 | + // path: 'workbench', | ||
29 | + // name: 'Workbench', | ||
30 | + // component: () => import('/@/views/dashboard/workbench/index.vue'), | ||
31 | + // meta: { | ||
32 | + // title: t('routes.dashboard.workbench'), | ||
33 | + // }, | ||
34 | + // }, | ||
34 | ], | 35 | ], |
35 | }; | 36 | }; |
36 | 37 |
src/router/routes/modules/project/order.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 order: AppRouteModule = { | ||
7 | + path: '/order', | ||
8 | + name: 'Order', | ||
9 | + component: LAYOUT, | ||
10 | + redirect: '/order', | ||
11 | + meta: { | ||
12 | + hideChildrenInMenu: true, | ||
13 | + orderNo: 2, | ||
14 | + icon: 'ion:grid-outline', | ||
15 | + title: '订单管理', | ||
16 | + }, | ||
17 | + children: [ | ||
18 | + { | ||
19 | + path: '', | ||
20 | + name: 'Order', | ||
21 | + component: () => import('/@/views/project/order/index.vue'), | ||
22 | + meta: { | ||
23 | + // affix: true, | ||
24 | + title: '订单管理', | ||
25 | + }, | ||
26 | + }, | ||
27 | + // { | ||
28 | + // path: 'workbench', | ||
29 | + // name: 'Workbench', | ||
30 | + // component: () => import('/@/views/dashboard/workbench/index.vue'), | ||
31 | + // meta: { | ||
32 | + // title: t('routes.dashboard.workbench'), | ||
33 | + // }, | ||
34 | + // }, | ||
35 | + ], | ||
36 | +}; | ||
37 | + | ||
38 | +export default order; |
src/router/routes/modules/project/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 | + orderNo: 3, | ||
13 | + icon: 'ion:settings-outline', | ||
14 | + title: t('routes.demo.system.moduleName'), | ||
15 | + }, | ||
16 | + children: [ | ||
17 | + { | ||
18 | + path: 'account', | ||
19 | + name: 'AccountManagement', | ||
20 | + meta: { | ||
21 | + title: t('routes.demo.system.account'), | ||
22 | + ignoreKeepAlive: false, | ||
23 | + }, | ||
24 | + component: () => import('/@/views/project/account/index.vue'), | ||
25 | + }, | ||
26 | + { | ||
27 | + path: 'account_detail/:id', | ||
28 | + name: 'AccountDetail', | ||
29 | + meta: { | ||
30 | + hideMenu: true, | ||
31 | + title: t('routes.demo.system.account_detail'), | ||
32 | + ignoreKeepAlive: true, | ||
33 | + showMenu: false, | ||
34 | + currentActiveMenu: '/system/account', | ||
35 | + }, | ||
36 | + component: () => import('/@/views/project/account/AccountDetail.vue'), | ||
37 | + }, | ||
38 | + // { | ||
39 | + // path: 'role', | ||
40 | + // name: 'RoleManagement', | ||
41 | + // meta: { | ||
42 | + // title: t('routes.demo.system.role'), | ||
43 | + // ignoreKeepAlive: true, | ||
44 | + // }, | ||
45 | + // component: () => import('/@/views/demo/system/role/index.vue'), | ||
46 | + // }, | ||
47 | + // { | ||
48 | + // path: 'menu', | ||
49 | + // name: 'MenuManagement', | ||
50 | + // meta: { | ||
51 | + // title: t('routes.demo.system.menu'), | ||
52 | + // ignoreKeepAlive: true, | ||
53 | + // }, | ||
54 | + // component: () => import('/@/views/demo/system/menu/index.vue'), | ||
55 | + // }, | ||
56 | + // { | ||
57 | + // path: 'dept', | ||
58 | + // name: 'DeptManagement', | ||
59 | + // meta: { | ||
60 | + // title: t('routes.demo.system.dept'), | ||
61 | + // ignoreKeepAlive: true, | ||
62 | + // }, | ||
63 | + // component: () => import('/@/views/demo/system/dept/index.vue'), | ||
64 | + // }, | ||
65 | + // { | ||
66 | + // path: 'changePassword', | ||
67 | + // name: 'ChangePassword', | ||
68 | + // meta: { | ||
69 | + // title: t('routes.demo.system.password'), | ||
70 | + // ignoreKeepAlive: true, | ||
71 | + // }, | ||
72 | + // component: () => import('/@/views/demo/system/password/index.vue'), | ||
73 | + // }, | ||
74 | + ], | ||
75 | +}; | ||
76 | + | ||
77 | +export default system; |
src/settings/projectSetting.ts
@@ -25,6 +25,7 @@ const setting: ProjectConfig = { | @@ -25,6 +25,7 @@ const setting: ProjectConfig = { | ||
25 | settingButtonPosition: SettingButtonPositionEnum.AUTO, | 25 | settingButtonPosition: SettingButtonPositionEnum.AUTO, |
26 | 26 | ||
27 | // Permission mode | 27 | // Permission mode |
28 | + // permissionMode: PermissionModeEnum.ROLE, | ||
28 | permissionMode: PermissionModeEnum.ROUTE_MAPPING, | 29 | permissionMode: PermissionModeEnum.ROUTE_MAPPING, |
29 | 30 | ||
30 | // Permission-related cache is stored in sessionStorage or localStorage | 31 | // Permission-related cache is stored in sessionStorage or localStorage |
src/store/modules/app.ts
@@ -48,6 +48,11 @@ export const useAppStore = defineStore({ | @@ -48,6 +48,11 @@ export const useAppStore = defineStore({ | ||
48 | }, | 48 | }, |
49 | 49 | ||
50 | getProjectConfig(state): ProjectConfig { | 50 | getProjectConfig(state): ProjectConfig { |
51 | + console.log( | ||
52 | + '%c [ state.projectConfig ]-52', | ||
53 | + 'font-size:13px; background:pink; color:#bf2c9f;', | ||
54 | + state.projectConfig, | ||
55 | + ); | ||
51 | return state.projectConfig || ({} as ProjectConfig); | 56 | return state.projectConfig || ({} as ProjectConfig); |
52 | }, | 57 | }, |
53 | 58 |
src/store/modules/data.ts
0 → 100644
1 | +import { forEach } from '/@/utils/helper/treeHelper'; | ||
2 | +import type { UserInfo } from '/#/store'; | ||
3 | +import { defineStore } from 'pinia'; | ||
4 | +import { store } from '/@/store'; | ||
5 | +import { RoleEnum } from '/@/enums/roleEnum'; | ||
6 | + | ||
7 | +import { getApiData, getChartData } from '/@/api/project/global'; | ||
8 | +import { formatToDate } from '/@/utils/dateUtil'; | ||
9 | + | ||
10 | +interface UserState { | ||
11 | + userInfo: Nullable<UserInfo>; | ||
12 | + token?: string; | ||
13 | + roleList: RoleEnum[]; | ||
14 | + sessionTimeout?: boolean; | ||
15 | + lastUpdateTime: number; | ||
16 | +} | ||
17 | + | ||
18 | +export const useDataStore = defineStore({ | ||
19 | + id: 'app-data', | ||
20 | + state: (): UserState => ({ | ||
21 | + // user info | ||
22 | + data: {}, | ||
23 | + // token | ||
24 | + chartData: {}, | ||
25 | + }), | ||
26 | + getters: { | ||
27 | + getData(state) { | ||
28 | + return state.data; | ||
29 | + }, | ||
30 | + getChartData(state) { | ||
31 | + return state.chartData; | ||
32 | + }, | ||
33 | + }, | ||
34 | + actions: { | ||
35 | + setData(info) { | ||
36 | + this.data = info ? info : ''; | ||
37 | + }, | ||
38 | + setChartData(data) { | ||
39 | + this.chartData = data; | ||
40 | + }, | ||
41 | + | ||
42 | + async getFetchData(): Promise<any> { | ||
43 | + try { | ||
44 | + const data = await getApiData(); | ||
45 | + this.data = data; | ||
46 | + } catch (error) { | ||
47 | + return Promise.reject(error); | ||
48 | + } | ||
49 | + }, | ||
50 | + async getFetchChartData(): Promise<any> { | ||
51 | + try { | ||
52 | + const data = await getChartData(); | ||
53 | + const x = [], | ||
54 | + y = []; | ||
55 | + data.forEach((value) => { | ||
56 | + x.push(formatToDate(value.dateTime)); | ||
57 | + y.push(value.orderCount); | ||
58 | + }); | ||
59 | + this.chartData = { x, y }; | ||
60 | + } catch (error) { | ||
61 | + return Promise.reject(error); | ||
62 | + } | ||
63 | + }, | ||
64 | + }, | ||
65 | +}); | ||
66 | + | ||
67 | +// Need to be used outside the setup | ||
68 | +export function useDataStoreWithOut() { | ||
69 | + return useDataStore(store); | ||
70 | +} |
src/store/modules/order.ts
0 → 100644
1 | +import type { UserInfo } from '/#/store'; | ||
2 | +import type { ErrorMessageMode } from '/#/axios'; | ||
3 | +import { defineStore } from 'pinia'; | ||
4 | +import { store } from '/@/store'; | ||
5 | +import { RoleEnum } from '/@/enums/roleEnum'; | ||
6 | +import { PageEnum } from '/@/enums/pageEnum'; | ||
7 | +import { ROLES_KEY, TOKEN_KEY, USER_INFO_KEY } from '/@/enums/cacheEnum'; | ||
8 | +import { getAuthCache, setAuthCache } from '/@/utils/auth'; | ||
9 | +import { GetUserInfoModel, LoginParams } from '/@/api/sys/model/userModel'; | ||
10 | +import { doLogout, getUserInfo, loginApi, getImageCaptcha } from '/@/api/sys/user'; | ||
11 | +import { useI18n } from '/@/hooks/web/useI18n'; | ||
12 | +import { useMessage } from '/@/hooks/web/useMessage'; | ||
13 | +import { router } from '/@/router'; | ||
14 | +import { usePermissionStore } from '/@/store/modules/permission'; | ||
15 | +import { RouteRecordRaw } from 'vue-router'; | ||
16 | +import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic'; | ||
17 | +import { h } from 'vue'; | ||
18 | +import { getInitDictData } from '/@/api/project/order'; | ||
19 | +import { groupBy } from 'lodash-es'; | ||
20 | + | ||
21 | +interface UserState { | ||
22 | + userInfo: Nullable<UserInfo>; | ||
23 | + token?: string; | ||
24 | + roleList: RoleEnum[]; | ||
25 | + sessionTimeout?: boolean; | ||
26 | + lastUpdateTime: number; | ||
27 | +} | ||
28 | + | ||
29 | +export const useOrderStore = defineStore({ | ||
30 | + id: 'app-order', | ||
31 | + state: (): UserState => ({ | ||
32 | + // user info | ||
33 | + dicts: {}, | ||
34 | + // token | ||
35 | + total: 0, | ||
36 | + // roleList | ||
37 | + roleList: [], | ||
38 | + // Whether the login expired | ||
39 | + sessionTimeout: false, | ||
40 | + // Last fetch time | ||
41 | + lastUpdateTime: 0, | ||
42 | + }), | ||
43 | + getters: { | ||
44 | + getDictInfo(state): UserInfo { | ||
45 | + return state.dicts; | ||
46 | + }, | ||
47 | + getTotal(state) { | ||
48 | + return state.total; | ||
49 | + }, | ||
50 | + getToken(state): string { | ||
51 | + return state.token || getAuthCache<string>(TOKEN_KEY); | ||
52 | + }, | ||
53 | + getRoleList(state): RoleEnum[] { | ||
54 | + return state.roleList.length > 0 ? state.roleList : getAuthCache<RoleEnum[]>(ROLES_KEY); | ||
55 | + }, | ||
56 | + getSessionTimeout(state): boolean { | ||
57 | + return !!state.sessionTimeout; | ||
58 | + }, | ||
59 | + getLastUpdateTime(state): number { | ||
60 | + return state.lastUpdateTime; | ||
61 | + }, | ||
62 | + }, | ||
63 | + actions: { | ||
64 | + setToken(info: string | undefined) { | ||
65 | + this.token = info ? info : ''; // for null or undefined value | ||
66 | + setAuthCache(TOKEN_KEY, info); | ||
67 | + }, | ||
68 | + setTotal(total) { | ||
69 | + this.total = total; | ||
70 | + }, | ||
71 | + setRoleList(roleList: RoleEnum[]) { | ||
72 | + this.roleList = roleList; | ||
73 | + setAuthCache(ROLES_KEY, roleList); | ||
74 | + }, | ||
75 | + setUserInfo(info: UserInfo | null) { | ||
76 | + this.userInfo = info; | ||
77 | + this.lastUpdateTime = new Date().getTime(); | ||
78 | + setAuthCache(USER_INFO_KEY, info); | ||
79 | + }, | ||
80 | + setSessionTimeout(flag: boolean) { | ||
81 | + this.sessionTimeout = flag; | ||
82 | + }, | ||
83 | + resetState() { | ||
84 | + this.userInfo = null; | ||
85 | + this.token = ''; | ||
86 | + this.roleList = []; | ||
87 | + this.sessionTimeout = false; | ||
88 | + }, | ||
89 | + /** | ||
90 | + * @description: login | ||
91 | + */ | ||
92 | + async getDict(): Promise<GetUserInfoModel | null> { | ||
93 | + try { | ||
94 | + const data = await getInitDictData(); | ||
95 | + console.log('%c [ data ]-95', 'font-size:13px; background:pink; color:#bf2c9f;', data); | ||
96 | + this.dicts = groupBy(data, 'dictCode'); | ||
97 | + } catch (error) { | ||
98 | + return Promise.reject(error); | ||
99 | + } | ||
100 | + }, | ||
101 | + async afterLoginAction(userInfo): Promise<GetUserInfoModel | null> { | ||
102 | + if (!this.getToken) return null; | ||
103 | + // get user info | ||
104 | + // const userInfo = await this.getUserInfoAction(); | ||
105 | + | ||
106 | + const sessionTimeout = this.sessionTimeout; | ||
107 | + if (sessionTimeout) { | ||
108 | + this.setSessionTimeout(false); | ||
109 | + } else { | ||
110 | + const permissionStore = usePermissionStore(); | ||
111 | + if (!permissionStore.isDynamicAddedRoute) { | ||
112 | + const routes = await permissionStore.buildRoutesAction(); | ||
113 | + routes.forEach((route) => { | ||
114 | + router.addRoute(route as unknown as RouteRecordRaw); | ||
115 | + }); | ||
116 | + router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw); | ||
117 | + permissionStore.setDynamicAddedRoute(true); | ||
118 | + } | ||
119 | + await router.replace('home'); | ||
120 | + } | ||
121 | + return userInfo; | ||
122 | + }, | ||
123 | + async getUserInfoAction(): Promise<UserInfo | null> { | ||
124 | + // if (!this.getToken) return null; | ||
125 | + // const userInfo = await getUserInfo(); | ||
126 | + // const { roles = [] } = userInfo; | ||
127 | + // if (isArray(roles)) { | ||
128 | + // const roleList = roles.map((item) => item.value) as RoleEnum[]; | ||
129 | + // this.setRoleList(roleList); | ||
130 | + // } else { | ||
131 | + // userInfo.roles = []; | ||
132 | + // this.setRoleList([]); | ||
133 | + // } | ||
134 | + // this.setUserInfo(userInfo); | ||
135 | + // return userInfo; | ||
136 | + return {}; | ||
137 | + }, | ||
138 | + /** | ||
139 | + * @description: logout | ||
140 | + */ | ||
141 | + async logout(goLogin = false) { | ||
142 | + if (this.getToken) { | ||
143 | + try { | ||
144 | + await doLogout(); | ||
145 | + } catch { | ||
146 | + console.log('注销Token失败'); | ||
147 | + } | ||
148 | + } | ||
149 | + this.setToken(undefined); | ||
150 | + this.setSessionTimeout(false); | ||
151 | + this.setUserInfo(null); | ||
152 | + goLogin && router.push(PageEnum.BASE_LOGIN); | ||
153 | + }, | ||
154 | + | ||
155 | + /** | ||
156 | + * @description: Confirm before logging out | ||
157 | + */ | ||
158 | + confirmLoginOut() { | ||
159 | + const { createConfirm } = useMessage(); | ||
160 | + const { t } = useI18n(); | ||
161 | + createConfirm({ | ||
162 | + iconType: 'warning', | ||
163 | + title: () => h('span', t('sys.app.logoutTip')), | ||
164 | + content: () => h('span', t('sys.app.logoutMessage')), | ||
165 | + onOk: async () => { | ||
166 | + await this.logout(true); | ||
167 | + }, | ||
168 | + }); | ||
169 | + }, | ||
170 | + | ||
171 | + /** | ||
172 | + * 获取图片验证码 | ||
173 | + */ | ||
174 | + async getImageCaptcha() { | ||
175 | + return await getImageCaptcha(); | ||
176 | + }, | ||
177 | + }, | ||
178 | +}); | ||
179 | + | ||
180 | +// Need to be used outside the setup | ||
181 | +export function useOrderStoreWithOut() { | ||
182 | + return useOrderStore(store); | ||
183 | +} |
src/store/modules/permission.ts
@@ -116,8 +116,10 @@ export const usePermissionStore = defineStore({ | @@ -116,8 +116,10 @@ export const usePermissionStore = defineStore({ | ||
116 | 116 | ||
117 | let routes: AppRouteRecordRaw[] = []; | 117 | let routes: AppRouteRecordRaw[] = []; |
118 | const roleList = toRaw(userStore.getRoleList) || []; | 118 | const roleList = toRaw(userStore.getRoleList) || []; |
119 | - const { permissionMode = projectSetting.permissionMode } = appStore.getProjectConfig; | ||
120 | - | 119 | + // dddd |
120 | + // const { permissionMode = projectSetting.permissionMode } = appStore.getProjectConfig; | ||
121 | + const permissionMode = projectSetting.permissionMode; | ||
122 | + // const permissionMode = PermissionModeEnum.ROUTE_MAPPING; | ||
121 | // 路由过滤器 在 函数filter 作为回调传入遍历使用 | 123 | // 路由过滤器 在 函数filter 作为回调传入遍历使用 |
122 | const routeFilter = (route: AppRouteRecordRaw) => { | 124 | const routeFilter = (route: AppRouteRecordRaw) => { |
123 | const { meta } = route; | 125 | const { meta } = route; |
@@ -167,7 +169,6 @@ export const usePermissionStore = defineStore({ | @@ -167,7 +169,6 @@ export const usePermissionStore = defineStore({ | ||
167 | } | 169 | } |
168 | return; | 170 | return; |
169 | }; | 171 | }; |
170 | - | ||
171 | switch (permissionMode) { | 172 | switch (permissionMode) { |
172 | // 角色权限 | 173 | // 角色权限 |
173 | case PermissionModeEnum.ROLE: | 174 | case PermissionModeEnum.ROLE: |
@@ -178,6 +179,8 @@ export const usePermissionStore = defineStore({ | @@ -178,6 +179,8 @@ export const usePermissionStore = defineStore({ | ||
178 | // Convert multi-level routing to level 2 routing | 179 | // Convert multi-level routing to level 2 routing |
179 | // 将多级路由转换为 2 级路由 | 180 | // 将多级路由转换为 2 级路由 |
180 | routes = flatMultiLevelRoutes(routes); | 181 | routes = flatMultiLevelRoutes(routes); |
182 | + | ||
183 | + routes = asyncRoutes; | ||
181 | break; | 184 | break; |
182 | 185 | ||
183 | // 路由映射, 默认进入该case | 186 | // 路由映射, 默认进入该case |
src/store/modules/user.ts
@@ -7,7 +7,7 @@ import { PageEnum } from '/@/enums/pageEnum'; | @@ -7,7 +7,7 @@ import { PageEnum } from '/@/enums/pageEnum'; | ||
7 | import { ROLES_KEY, TOKEN_KEY, USER_INFO_KEY } from '/@/enums/cacheEnum'; | 7 | import { ROLES_KEY, TOKEN_KEY, USER_INFO_KEY } from '/@/enums/cacheEnum'; |
8 | import { getAuthCache, setAuthCache } from '/@/utils/auth'; | 8 | import { getAuthCache, setAuthCache } from '/@/utils/auth'; |
9 | import { GetUserInfoModel, LoginParams } from '/@/api/sys/model/userModel'; | 9 | import { GetUserInfoModel, LoginParams } from '/@/api/sys/model/userModel'; |
10 | -import { doLogout, getUserInfo, loginApi } from '/@/api/sys/user'; | 10 | +import { doLogout, getUserInfo, loginApi, getImageCaptcha } from '/@/api/sys/user'; |
11 | import { useI18n } from '/@/hooks/web/useI18n'; | 11 | import { useI18n } from '/@/hooks/web/useI18n'; |
12 | import { useMessage } from '/@/hooks/web/useMessage'; | 12 | import { useMessage } from '/@/hooks/web/useMessage'; |
13 | import { router } from '/@/router'; | 13 | import { router } from '/@/router'; |
@@ -89,21 +89,24 @@ export const useUserStore = defineStore({ | @@ -89,21 +89,24 @@ export const useUserStore = defineStore({ | ||
89 | }, | 89 | }, |
90 | ): Promise<GetUserInfoModel | null> { | 90 | ): Promise<GetUserInfoModel | null> { |
91 | try { | 91 | try { |
92 | - const { goHome = true, mode, ...loginParams } = params; | 92 | + const { mode, ...loginParams } = params; |
93 | const data = await loginApi(loginParams, mode); | 93 | const data = await loginApi(loginParams, mode); |
94 | - const { token } = data; | 94 | + const { token, user } = data; |
95 | 95 | ||
96 | - // save token | ||
97 | this.setToken(token); | 96 | this.setToken(token); |
98 | - return this.afterLoginAction(goHome); | 97 | + // this.setToken( |
98 | + // 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImF1dGgiOiJkZXB0OmVkaXQsdXNlcjpsaXN0LHJvbGVzOmFkZCx1c2VyOmFkZCxkZXB0OmFkZCxtZW51OmRlbCxyb2xlczpkZWwsbWVudTplZGl0LG1lbnU6bGlzdCxzdG9yYWdlOmxpc3Qsam9iOmVkaXQscm9sZXM6bGlzdCx1c2VyOmRlbCxkaWN0OmFkZCxkZXB0Omxpc3QsbWVudTphZGQsam9iOmRlbCxqb2I6bGlzdCx1c2VyOmVkaXQscm9sZXM6ZWRpdCxkaWN0OmRlbCxqb2I6YWRkLGRpY3Q6ZWRpdCxkZXB0OmRlbCIsImV4cCI6MTY5NjE0NTUzN30.Q9hcwnG9uJP3HHjwpd_3ZrV7LrZlMIL6JJBe0rcfqldE8SPq8JkBKElrGeu7GoCAc5EyN6wUUYcriwV5VhpZqQ', | ||
99 | + // ); | ||
100 | + // 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ4bXMiLCJhdXRoIjoiZGVwdDplZGl0LHVzZXI6bGlzdCxyb2xlczphZGQsdXNlcjphZGQsZGVwdDphZGQsbWVudTpkZWwscm9sZXM6ZGVsLG1lbnU6ZWRpdCxtZW51Omxpc3Qsc3RvcmFnZTpsaXN0LGpvYjplZGl0LHJvbGVzOmxpc3QsdXNlcjpkZWwsZGljdDphZGQsZGVwdDpsaXN0LG1lbnU6YWRkLGpvYjpkZWwsam9iOmxpc3QsdXNlcjplZGl0LHJvbGVzOmVkaXQsZGljdDpkZWwsam9iOmFkZCxkaWN0OmVkaXQsZGVwdDpkZWwiLCJleHAiOjE2OTUxNDIwNDF9.Wj-CyJGbMps_9a84TQkJgBSNnj22OVAEVLsEKvVHdyxkQORIwvxpOzT7gr2l-8VbUJ3wLatG0OUe-6smoaoTbA', | ||
101 | + return this.afterLoginAction(user); | ||
99 | } catch (error) { | 102 | } catch (error) { |
100 | return Promise.reject(error); | 103 | return Promise.reject(error); |
101 | } | 104 | } |
102 | }, | 105 | }, |
103 | - async afterLoginAction(goHome?: boolean): Promise<GetUserInfoModel | null> { | 106 | + async afterLoginAction(userInfo): Promise<GetUserInfoModel | null> { |
104 | if (!this.getToken) return null; | 107 | if (!this.getToken) return null; |
105 | // get user info | 108 | // get user info |
106 | - const userInfo = await this.getUserInfoAction(); | 109 | + // const userInfo = await this.getUserInfoAction(); |
107 | 110 | ||
108 | const sessionTimeout = this.sessionTimeout; | 111 | const sessionTimeout = this.sessionTimeout; |
109 | if (sessionTimeout) { | 112 | if (sessionTimeout) { |
@@ -118,39 +121,40 @@ export const useUserStore = defineStore({ | @@ -118,39 +121,40 @@ export const useUserStore = defineStore({ | ||
118 | router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw); | 121 | router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw); |
119 | permissionStore.setDynamicAddedRoute(true); | 122 | permissionStore.setDynamicAddedRoute(true); |
120 | } | 123 | } |
121 | - goHome && (await router.replace(userInfo?.homePath || PageEnum.BASE_HOME)); | 124 | + await router.replace('home'); |
122 | } | 125 | } |
123 | return userInfo; | 126 | return userInfo; |
124 | }, | 127 | }, |
125 | async getUserInfoAction(): Promise<UserInfo | null> { | 128 | async getUserInfoAction(): Promise<UserInfo | null> { |
126 | - if (!this.getToken) return null; | ||
127 | - const userInfo = await getUserInfo(); | ||
128 | - const { roles = [] } = userInfo; | ||
129 | - if (isArray(roles)) { | ||
130 | - const roleList = roles.map((item) => item.value) as RoleEnum[]; | ||
131 | - this.setRoleList(roleList); | ||
132 | - } else { | ||
133 | - userInfo.roles = []; | ||
134 | - this.setRoleList([]); | ||
135 | - } | ||
136 | - this.setUserInfo(userInfo); | ||
137 | - return userInfo; | 129 | + // if (!this.getToken) return null; |
130 | + // const userInfo = await getUserInfo(); | ||
131 | + // const { roles = [] } = userInfo; | ||
132 | + // if (isArray(roles)) { | ||
133 | + // const roleList = roles.map((item) => item.value) as RoleEnum[]; | ||
134 | + // this.setRoleList(roleList); | ||
135 | + // } else { | ||
136 | + // userInfo.roles = []; | ||
137 | + // this.setRoleList([]); | ||
138 | + // } | ||
139 | + // this.setUserInfo(userInfo); | ||
140 | + // return userInfo; | ||
141 | + return {}; | ||
138 | }, | 142 | }, |
139 | /** | 143 | /** |
140 | * @description: logout | 144 | * @description: logout |
141 | */ | 145 | */ |
142 | async logout(goLogin = false) { | 146 | async logout(goLogin = false) { |
143 | - if (this.getToken) { | ||
144 | - try { | ||
145 | - await doLogout(); | ||
146 | - } catch { | ||
147 | - console.log('注销Token失败'); | ||
148 | - } | ||
149 | - } | 147 | + // if (this.getToken) { |
148 | + // try { | ||
149 | + // await doLogout(); | ||
150 | + // } catch { | ||
151 | + // console.log('注销Token失败'); | ||
152 | + // } | ||
153 | + // } | ||
150 | this.setToken(undefined); | 154 | this.setToken(undefined); |
151 | this.setSessionTimeout(false); | 155 | this.setSessionTimeout(false); |
152 | this.setUserInfo(null); | 156 | this.setUserInfo(null); |
153 | - goLogin && router.push(PageEnum.BASE_LOGIN); | 157 | + router.push(PageEnum.BASE_LOGIN); |
154 | }, | 158 | }, |
155 | 159 | ||
156 | /** | 160 | /** |
@@ -168,6 +172,13 @@ export const useUserStore = defineStore({ | @@ -168,6 +172,13 @@ export const useUserStore = defineStore({ | ||
168 | }, | 172 | }, |
169 | }); | 173 | }); |
170 | }, | 174 | }, |
175 | + | ||
176 | + /** | ||
177 | + * 获取图片验证码 | ||
178 | + */ | ||
179 | + async getImageCaptcha() { | ||
180 | + return await getImageCaptcha(); | ||
181 | + }, | ||
171 | }, | 182 | }, |
172 | }); | 183 | }); |
173 | 184 |
src/utils/http/axios/Axios.ts
@@ -13,8 +13,12 @@ import { AxiosCanceler } from './axiosCancel'; | @@ -13,8 +13,12 @@ import { AxiosCanceler } from './axiosCancel'; | ||
13 | import { isFunction } from '/@/utils/is'; | 13 | import { isFunction } from '/@/utils/is'; |
14 | import { cloneDeep } from 'lodash-es'; | 14 | import { cloneDeep } from 'lodash-es'; |
15 | import { ContentTypeEnum, RequestEnum } from '/@/enums/httpEnum'; | 15 | import { ContentTypeEnum, RequestEnum } from '/@/enums/httpEnum'; |
16 | +import { useMessage } from '/@/hooks/web/useMessage'; | ||
17 | +import { router } from '/@/router'; | ||
18 | +import { useUserStoreWithOut } from '/@/store/modules/user'; | ||
16 | 19 | ||
17 | export * from './axiosTransform'; | 20 | export * from './axiosTransform'; |
21 | +const { createMessage } = useMessage(); | ||
18 | 22 | ||
19 | /** | 23 | /** |
20 | * @description: axios module | 24 | * @description: axios module |
@@ -206,6 +210,7 @@ export class VAxios { | @@ -206,6 +210,7 @@ export class VAxios { | ||
206 | const transform = this.getTransform(); | 210 | const transform = this.getTransform(); |
207 | 211 | ||
208 | const { requestOptions } = this.options; | 212 | const { requestOptions } = this.options; |
213 | + const { message } = options || {}; | ||
209 | 214 | ||
210 | const opt: RequestOptions = Object.assign({}, requestOptions, options); | 215 | const opt: RequestOptions = Object.assign({}, requestOptions, options); |
211 | 216 | ||
@@ -218,9 +223,23 @@ export class VAxios { | @@ -218,9 +223,23 @@ export class VAxios { | ||
218 | conf = this.supportFormData(conf); | 223 | conf = this.supportFormData(conf); |
219 | 224 | ||
220 | return new Promise((resolve, reject) => { | 225 | return new Promise((resolve, reject) => { |
226 | + const userStore = useUserStoreWithOut(); | ||
227 | + | ||
221 | this.axiosInstance | 228 | this.axiosInstance |
222 | .request<any, AxiosResponse<Result>>(conf) | 229 | .request<any, AxiosResponse<Result>>(conf) |
223 | .then((res: AxiosResponse<Result>) => { | 230 | .then((res: AxiosResponse<Result>) => { |
231 | + if (res.data.result === 401) { | ||
232 | + userStore.setToken(''); | ||
233 | + createMessage.error(res.data.message); | ||
234 | + return router.push('/login'); | ||
235 | + } | ||
236 | + if (res.data.result !== 0 && res.data.message) { | ||
237 | + return createMessage.error(res.data.message); | ||
238 | + } | ||
239 | + | ||
240 | + if (message && res.data.result === 0) { | ||
241 | + createMessage.success(message); | ||
242 | + } | ||
224 | if (transformResponseHook && isFunction(transformResponseHook)) { | 243 | if (transformResponseHook && isFunction(transformResponseHook)) { |
225 | try { | 244 | try { |
226 | const ret = transformResponseHook(res, opt); | 245 | const ret = transformResponseHook(res, opt); |
@@ -233,6 +252,7 @@ export class VAxios { | @@ -233,6 +252,7 @@ export class VAxios { | ||
233 | resolve(res as unknown as Promise<T>); | 252 | resolve(res as unknown as Promise<T>); |
234 | }) | 253 | }) |
235 | .catch((e: Error | AxiosError) => { | 254 | .catch((e: Error | AxiosError) => { |
255 | + console.log('%c [ e ]-257', 'font-size:13px; background:pink; color:#bf2c9f;', e); | ||
236 | if (requestCatchHook && isFunction(requestCatchHook)) { | 256 | if (requestCatchHook && isFunction(requestCatchHook)) { |
237 | reject(requestCatchHook(e, opt)); | 257 | reject(requestCatchHook(e, opt)); |
238 | return; | 258 | return; |
src/utils/http/axios/index.ts
@@ -45,16 +45,16 @@ const transform: AxiosTransform = { | @@ -45,16 +45,16 @@ const transform: AxiosTransform = { | ||
45 | } | 45 | } |
46 | // 错误的时候返回 | 46 | // 错误的时候返回 |
47 | 47 | ||
48 | - const { data } = res; | ||
49 | - if (!data) { | 48 | + const { data: bodyData } = res; |
49 | + if (!bodyData) { | ||
50 | // return '[HTTP] Request has no return value'; | 50 | // return '[HTTP] Request has no return value'; |
51 | throw new Error(t('sys.api.apiRequestFailed')); | 51 | throw new Error(t('sys.api.apiRequestFailed')); |
52 | } | 52 | } |
53 | // 这里 code,result,message为 后台统一的字段,需要在 types.ts内修改为项目自己的接口返回格式 | 53 | // 这里 code,result,message为 后台统一的字段,需要在 types.ts内修改为项目自己的接口返回格式 |
54 | - const { code, result, message } = data; | 54 | + const { result, data, message } = bodyData; |
55 | 55 | ||
56 | // 这里逻辑可以根据项目进行修改 | 56 | // 这里逻辑可以根据项目进行修改 |
57 | - const hasSuccess = data && Reflect.has(data, 'code') && code === ResultEnum.SUCCESS; | 57 | + const hasSuccess = bodyData && Reflect.has(bodyData, 'result') && result === ResultEnum.SUCCESS; |
58 | if (hasSuccess) { | 58 | if (hasSuccess) { |
59 | let successMsg = message; | 59 | let successMsg = message; |
60 | 60 | ||
@@ -67,13 +67,13 @@ const transform: AxiosTransform = { | @@ -67,13 +67,13 @@ const transform: AxiosTransform = { | ||
67 | } else if (options.successMessageMode === 'message') { | 67 | } else if (options.successMessageMode === 'message') { |
68 | createMessage.success(successMsg); | 68 | createMessage.success(successMsg); |
69 | } | 69 | } |
70 | - return result; | 70 | + return data; |
71 | } | 71 | } |
72 | 72 | ||
73 | // 在此处根据自己项目的实际情况对不同的code执行不同的操作 | 73 | // 在此处根据自己项目的实际情况对不同的code执行不同的操作 |
74 | // 如果不希望中断当前请求,请return数据,否则直接抛出异常即可 | 74 | // 如果不希望中断当前请求,请return数据,否则直接抛出异常即可 |
75 | let timeoutMsg = ''; | 75 | let timeoutMsg = ''; |
76 | - switch (code) { | 76 | + switch (result) { |
77 | case ResultEnum.TIMEOUT: | 77 | case ResultEnum.TIMEOUT: |
78 | timeoutMsg = t('sys.api.timeoutMessage'); | 78 | timeoutMsg = t('sys.api.timeoutMessage'); |
79 | const userStore = useUserStoreWithOut(); | 79 | const userStore = useUserStoreWithOut(); |
src/utils/project.ts
0 → 100644
src/views/dashboard/analysis/components/GrowCard.vue
@@ -6,21 +6,21 @@ | @@ -6,21 +6,21 @@ | ||
6 | :loading="loading" | 6 | :loading="loading" |
7 | :title="item.title" | 7 | :title="item.title" |
8 | class="md:w-1/4 w-full !md:mt-0" | 8 | class="md:w-1/4 w-full !md:mt-0" |
9 | - :class="{ '!md:mr-4': index + 1 < 4, '!mt-4': index > 0 }" | 9 | + :class="{ '!md:mr-4': index + 1 < 5, '!mt-4': index > 0 }" |
10 | > | 10 | > |
11 | - <template #extra> | 11 | + <!-- <template #extra> |
12 | <Tag :color="item.color">{{ item.action }}</Tag> | 12 | <Tag :color="item.color">{{ item.action }}</Tag> |
13 | - </template> | 13 | + </template> --> |
14 | 14 | ||
15 | <div class="py-4 px-4 flex justify-between items-center"> | 15 | <div class="py-4 px-4 flex justify-between items-center"> |
16 | - <CountTo prefix="$" :startVal="1" :endVal="item.value" class="text-2xl" /> | ||
17 | - <Icon :icon="item.icon" :size="40" /> | 16 | + <CountTo :startVal="1" :endVal="item.value" class="text-2xl" /> |
17 | + <!-- <Icon :icon="item.icon" :size="40" /> --> | ||
18 | </div> | 18 | </div> |
19 | 19 | ||
20 | - <div class="p-2 px-4 flex justify-between"> | 20 | + <!-- <div class="p-2 px-4 flex justify-between"> |
21 | <span>总{{ item.title }}</span> | 21 | <span>总{{ item.title }}</span> |
22 | <CountTo prefix="$" :startVal="1" :endVal="item.total" /> | 22 | <CountTo prefix="$" :startVal="1" :endVal="item.total" /> |
23 | - </div> | 23 | + </div> --> |
24 | </Card> | 24 | </Card> |
25 | </template> | 25 | </template> |
26 | </div> | 26 | </div> |
@@ -30,6 +30,56 @@ | @@ -30,6 +30,56 @@ | ||
30 | import Icon from '@/components/Icon/Icon.vue'; | 30 | import Icon from '@/components/Icon/Icon.vue'; |
31 | import { Tag, Card } from 'ant-design-vue'; | 31 | import { Tag, Card } from 'ant-design-vue'; |
32 | import { growCardList } from '../data'; | 32 | import { growCardList } from '../data'; |
33 | + import { useDataStoreWithOut } from '/@/store/modules/data'; | ||
34 | + import { computed } from 'vue'; | ||
35 | + | ||
36 | + const dataStore = useDataStoreWithOut(); | ||
37 | + | ||
38 | + const growCardList = computed(() => { | ||
39 | + const data = dataStore.getData; | ||
40 | + return [ | ||
41 | + { | ||
42 | + title: '订单完成', | ||
43 | + icon: 'visit-count|svg', | ||
44 | + value: data?.orderFinishedCount || 0, | ||
45 | + total: 120000, | ||
46 | + color: 'green', | ||
47 | + action: '月', | ||
48 | + }, | ||
49 | + { | ||
50 | + title: '跟单和质检中', | ||
51 | + icon: 'total-sales|svg', | ||
52 | + value: data?.orderInspectingCount || 0, | ||
53 | + total: 500000, | ||
54 | + color: 'blue', | ||
55 | + action: '月', | ||
56 | + }, | ||
57 | + { | ||
58 | + title: '利润分析表待审核', | ||
59 | + icon: 'download-count|svg', | ||
60 | + value: data?.orderProfitWaitAuditCount || 0, | ||
61 | + total: 120000, | ||
62 | + color: 'orange', | ||
63 | + action: '周', | ||
64 | + }, | ||
65 | + { | ||
66 | + title: '项目报告书待审核', | ||
67 | + icon: 'transaction|svg', | ||
68 | + value: data?.orderReportWaitAuditCount || 0, | ||
69 | + total: 50000, | ||
70 | + color: 'purple', | ||
71 | + action: '年', | ||
72 | + }, | ||
73 | + { | ||
74 | + title: '订单初始化', | ||
75 | + icon: 'transaction|svg', | ||
76 | + value: 5000, | ||
77 | + total: 50000, | ||
78 | + color: 'purple', | ||
79 | + action: '年', | ||
80 | + }, | ||
81 | + ]; | ||
82 | + }); | ||
33 | 83 | ||
34 | defineProps({ | 84 | defineProps({ |
35 | loading: { | 85 | loading: { |
src/views/dashboard/analysis/components/SiteAnalysis.vue
@@ -24,12 +24,12 @@ | @@ -24,12 +24,12 @@ | ||
24 | const tabListTitle = [ | 24 | const tabListTitle = [ |
25 | { | 25 | { |
26 | key: 'tab1', | 26 | key: 'tab1', |
27 | - tab: '流量趋势', | ||
28 | - }, | ||
29 | - { | ||
30 | - key: 'tab2', | ||
31 | - tab: '访问量', | 27 | + tab: '订单趋势', |
32 | }, | 28 | }, |
29 | + // { | ||
30 | + // key: 'tab2', | ||
31 | + // tab: '访问量', | ||
32 | + // }, | ||
33 | ]; | 33 | ]; |
34 | 34 | ||
35 | function onTabChange(key) { | 35 | function onTabChange(key) { |
src/views/dashboard/analysis/components/VisitAnalysis.vue
1 | <template> | 1 | <template> |
2 | <div ref="chartRef" :style="{ height, width }"></div> | 2 | <div ref="chartRef" :style="{ height, width }"></div> |
3 | </template> | 3 | </template> |
4 | -<script lang="ts"> | ||
5 | - import { basicProps } from './props'; | ||
6 | -</script> | 4 | + |
7 | <script lang="ts" setup> | 5 | <script lang="ts" setup> |
8 | - import { onMounted, ref, Ref } from 'vue'; | 6 | + import { ref, Ref, watchEffect } from 'vue'; |
9 | import { useECharts } from '/@/hooks/web/useECharts'; | 7 | import { useECharts } from '/@/hooks/web/useECharts'; |
8 | + import { basicProps } from './props'; | ||
9 | + import { max } from 'lodash-es'; | ||
10 | + import { useDataStoreWithOut } from '/@/store/modules/data'; | ||
10 | 11 | ||
11 | defineProps({ | 12 | defineProps({ |
12 | ...basicProps, | 13 | ...basicProps, |
13 | }); | 14 | }); |
14 | const chartRef = ref<HTMLDivElement | null>(null); | 15 | const chartRef = ref<HTMLDivElement | null>(null); |
15 | const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); | 16 | const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); |
16 | - | ||
17 | - onMounted(() => { | 17 | + const dataStore = useDataStoreWithOut(); |
18 | + watchEffect(() => { | ||
19 | + const data = dataStore?.getChartData || {}; | ||
20 | + const maxY = data?.y ? max(data?.y) : 0; | ||
18 | setOptions({ | 21 | setOptions({ |
19 | tooltip: { | 22 | tooltip: { |
20 | trigger: 'axis', | 23 | trigger: 'axis', |
@@ -28,7 +31,7 @@ | @@ -28,7 +31,7 @@ | ||
28 | xAxis: { | 31 | xAxis: { |
29 | type: 'category', | 32 | type: 'category', |
30 | boundaryGap: false, | 33 | boundaryGap: false, |
31 | - data: [...new Array(18)].map((_item, index) => `${index + 6}:00`), | 34 | + data: data?.x, |
32 | splitLine: { | 35 | splitLine: { |
33 | show: true, | 36 | show: true, |
34 | lineStyle: { | 37 | lineStyle: { |
@@ -44,7 +47,7 @@ | @@ -44,7 +47,7 @@ | ||
44 | yAxis: [ | 47 | yAxis: [ |
45 | { | 48 | { |
46 | type: 'value', | 49 | type: 'value', |
47 | - max: 80000, | 50 | + max: maxY + 20, |
48 | splitNumber: 4, | 51 | splitNumber: 4, |
49 | axisTick: { | 52 | axisTick: { |
50 | show: false, | 53 | show: false, |
@@ -61,28 +64,25 @@ | @@ -61,28 +64,25 @@ | ||
61 | series: [ | 64 | series: [ |
62 | { | 65 | { |
63 | smooth: true, | 66 | smooth: true, |
64 | - data: [ | ||
65 | - 111, 222, 4000, 18000, 33333, 55555, 66666, 33333, 14000, 36000, 66666, 44444, 22222, | ||
66 | - 11111, 4000, 2000, 500, 333, 222, 111, | ||
67 | - ], | 67 | + data: data?.y, |
68 | type: 'line', | 68 | type: 'line', |
69 | areaStyle: {}, | 69 | areaStyle: {}, |
70 | itemStyle: { | 70 | itemStyle: { |
71 | color: '#5ab1ef', | 71 | color: '#5ab1ef', |
72 | }, | 72 | }, |
73 | }, | 73 | }, |
74 | - { | ||
75 | - smooth: true, | ||
76 | - data: [ | ||
77 | - 33, 66, 88, 333, 3333, 5000, 18000, 3000, 1200, 13000, 22000, 11000, 2221, 1201, 390, | ||
78 | - 198, 60, 30, 22, 11, | ||
79 | - ], | ||
80 | - type: 'line', | ||
81 | - areaStyle: {}, | ||
82 | - itemStyle: { | ||
83 | - color: '#019680', | ||
84 | - }, | ||
85 | - }, | 74 | + // { |
75 | + // smooth: true, | ||
76 | + // data: [ | ||
77 | + // 33, 66, 88, 333, 3333, 5000, 18000, 3000, 1200, 13000, 22000, 11000, 2221, 1201, 390, | ||
78 | + // 198, 60, 30, 22, 11, | ||
79 | + // ], | ||
80 | + // type: 'line', | ||
81 | + // areaStyle: {}, | ||
82 | + // itemStyle: { | ||
83 | + // color: '#019680', | ||
84 | + // }, | ||
85 | + // }, | ||
86 | ], | 86 | ], |
87 | }); | 87 | }); |
88 | }); | 88 | }); |
src/views/dashboard/analysis/data.ts
@@ -9,7 +9,7 @@ export interface GrowCardItem { | @@ -9,7 +9,7 @@ export interface GrowCardItem { | ||
9 | 9 | ||
10 | export const growCardList: GrowCardItem[] = [ | 10 | export const growCardList: GrowCardItem[] = [ |
11 | { | 11 | { |
12 | - title: '访问数', | 12 | + title: '订单完成', |
13 | icon: 'visit-count|svg', | 13 | icon: 'visit-count|svg', |
14 | value: 2000, | 14 | value: 2000, |
15 | total: 120000, | 15 | total: 120000, |
@@ -17,7 +17,7 @@ export const growCardList: GrowCardItem[] = [ | @@ -17,7 +17,7 @@ export const growCardList: GrowCardItem[] = [ | ||
17 | action: '月', | 17 | action: '月', |
18 | }, | 18 | }, |
19 | { | 19 | { |
20 | - title: '成交额', | 20 | + title: '跟单和质检中', |
21 | icon: 'total-sales|svg', | 21 | icon: 'total-sales|svg', |
22 | value: 20000, | 22 | value: 20000, |
23 | total: 500000, | 23 | total: 500000, |
@@ -25,7 +25,7 @@ export const growCardList: GrowCardItem[] = [ | @@ -25,7 +25,7 @@ export const growCardList: GrowCardItem[] = [ | ||
25 | action: '月', | 25 | action: '月', |
26 | }, | 26 | }, |
27 | { | 27 | { |
28 | - title: '下载数', | 28 | + title: '利润分析表待审核', |
29 | icon: 'download-count|svg', | 29 | icon: 'download-count|svg', |
30 | value: 8000, | 30 | value: 8000, |
31 | total: 120000, | 31 | total: 120000, |
@@ -33,7 +33,15 @@ export const growCardList: GrowCardItem[] = [ | @@ -33,7 +33,15 @@ export const growCardList: GrowCardItem[] = [ | ||
33 | action: '周', | 33 | action: '周', |
34 | }, | 34 | }, |
35 | { | 35 | { |
36 | - title: '成交数', | 36 | + title: '项目报告书待审核', |
37 | + icon: 'transaction|svg', | ||
38 | + value: 5000, | ||
39 | + total: 50000, | ||
40 | + color: 'purple', | ||
41 | + action: '年', | ||
42 | + }, | ||
43 | + { | ||
44 | + title: '订单初始化', | ||
37 | icon: 'transaction|svg', | 45 | icon: 'transaction|svg', |
38 | value: 5000, | 46 | value: 5000, |
39 | total: 50000, | 47 | total: 50000, |
src/views/dashboard/analysis/index.vue
@@ -2,22 +2,26 @@ | @@ -2,22 +2,26 @@ | ||
2 | <div class="p-4"> | 2 | <div class="p-4"> |
3 | <GrowCard :loading="loading" class="enter-y" /> | 3 | <GrowCard :loading="loading" class="enter-y" /> |
4 | <SiteAnalysis class="!my-4 enter-y" :loading="loading" /> | 4 | <SiteAnalysis class="!my-4 enter-y" :loading="loading" /> |
5 | - <div class="md:flex enter-y"> | 5 | + <!-- <div class="md:flex enter-y"> |
6 | <VisitRadar class="md:w-1/3 w-full" :loading="loading" /> | 6 | <VisitRadar class="md:w-1/3 w-full" :loading="loading" /> |
7 | <VisitSource class="md:w-1/3 !md:mx-4 !md:my-0 !my-4 w-full" :loading="loading" /> | 7 | <VisitSource class="md:w-1/3 !md:mx-4 !md:my-0 !my-4 w-full" :loading="loading" /> |
8 | <SalesProductPie class="md:w-1/3 w-full" :loading="loading" /> | 8 | <SalesProductPie class="md:w-1/3 w-full" :loading="loading" /> |
9 | - </div> | 9 | + </div> --> |
10 | </div> | 10 | </div> |
11 | </template> | 11 | </template> |
12 | <script lang="ts" setup> | 12 | <script lang="ts" setup> |
13 | - import { ref } from 'vue'; | 13 | + import { onMounted, ref } from 'vue'; |
14 | import GrowCard from './components/GrowCard.vue'; | 14 | import GrowCard from './components/GrowCard.vue'; |
15 | import SiteAnalysis from './components/SiteAnalysis.vue'; | 15 | import SiteAnalysis from './components/SiteAnalysis.vue'; |
16 | - import VisitSource from './components/VisitSource.vue'; | ||
17 | - import VisitRadar from './components/VisitRadar.vue'; | ||
18 | - import SalesProductPie from './components/SalesProductPie.vue'; | 16 | + import { useDataStoreWithOut } from '/@/store/modules/data'; |
19 | 17 | ||
20 | const loading = ref(true); | 18 | const loading = ref(true); |
19 | + const dataStore = useDataStoreWithOut(); | ||
20 | + | ||
21 | + onMounted(() => { | ||
22 | + dataStore.getFetchData(); | ||
23 | + dataStore.getFetchChartData(); | ||
24 | + }); | ||
21 | 25 | ||
22 | setTimeout(() => { | 26 | setTimeout(() => { |
23 | loading.value = false; | 27 | loading.value = false; |
src/views/demo/permission/back/Btn.vue
@@ -87,6 +87,7 @@ | @@ -87,6 +87,7 @@ | ||
87 | userStore.setToken(token); | 87 | userStore.setToken(token); |
88 | 88 | ||
89 | // 重新获取用户信息和菜单 | 89 | // 重新获取用户信息和菜单 |
90 | + | ||
90 | userStore.getUserInfoAction(); | 91 | userStore.getUserInfoAction(); |
91 | permissionStore.changePermissionCode(); | 92 | permissionStore.changePermissionCode(); |
92 | } | 93 | } |
src/views/demo/system/account/account.data.ts deleted
100644 → 0
1 | -import { getAllRoleList, isAccountExist } from '/@/api/demo/system'; | ||
2 | -import { BasicColumn, FormSchema } from '/@/components/Table'; | ||
3 | - | ||
4 | -export const columns: BasicColumn[] = [ | ||
5 | - { | ||
6 | - title: '用户名', | ||
7 | - dataIndex: 'account', | ||
8 | - width: 120, | ||
9 | - }, | ||
10 | - { | ||
11 | - title: '昵称', | ||
12 | - dataIndex: 'nickname', | ||
13 | - width: 120, | ||
14 | - }, | ||
15 | - { | ||
16 | - title: '邮箱', | ||
17 | - dataIndex: 'email', | ||
18 | - width: 120, | ||
19 | - }, | ||
20 | - { | ||
21 | - title: '创建时间', | ||
22 | - dataIndex: 'createTime', | ||
23 | - width: 180, | ||
24 | - }, | ||
25 | - { | ||
26 | - title: '角色', | ||
27 | - dataIndex: 'role', | ||
28 | - width: 200, | ||
29 | - }, | ||
30 | - { | ||
31 | - title: '备注', | ||
32 | - dataIndex: 'remark', | ||
33 | - }, | ||
34 | -]; | ||
35 | - | ||
36 | -export const searchFormSchema: FormSchema[] = [ | ||
37 | - { | ||
38 | - field: 'account', | ||
39 | - label: '用户名', | ||
40 | - component: 'Input', | ||
41 | - colProps: { span: 8 }, | ||
42 | - }, | ||
43 | - { | ||
44 | - field: 'nickname', | ||
45 | - label: '昵称', | ||
46 | - component: 'Input', | ||
47 | - colProps: { span: 8 }, | ||
48 | - }, | ||
49 | -]; | ||
50 | - | ||
51 | -export const accountFormSchema: FormSchema[] = [ | ||
52 | - { | ||
53 | - field: 'account', | ||
54 | - label: '用户名', | ||
55 | - component: 'Input', | ||
56 | - helpMessage: ['本字段演示异步验证', '不能输入带有admin的用户名'], | ||
57 | - rules: [ | ||
58 | - { | ||
59 | - required: true, | ||
60 | - message: '请输入用户名', | ||
61 | - }, | ||
62 | - { | ||
63 | - validator(_, value) { | ||
64 | - return new Promise((resolve, reject) => { | ||
65 | - isAccountExist(value) | ||
66 | - .then(() => resolve()) | ||
67 | - .catch((err) => { | ||
68 | - reject(err.message || '验证失败'); | ||
69 | - }); | ||
70 | - }); | ||
71 | - }, | ||
72 | - }, | ||
73 | - ], | ||
74 | - }, | ||
75 | - { | ||
76 | - field: 'pwd', | ||
77 | - label: '密码', | ||
78 | - component: 'InputPassword', | ||
79 | - required: true, | ||
80 | - ifShow: false, | ||
81 | - }, | ||
82 | - { | ||
83 | - label: '角色', | ||
84 | - field: 'role', | ||
85 | - component: 'ApiSelect', | ||
86 | - componentProps: { | ||
87 | - api: getAllRoleList, | ||
88 | - labelField: 'roleName', | ||
89 | - valueField: 'roleValue', | ||
90 | - }, | ||
91 | - required: true, | ||
92 | - }, | ||
93 | - { | ||
94 | - field: 'dept', | ||
95 | - label: '所属部门', | ||
96 | - component: 'TreeSelect', | ||
97 | - componentProps: { | ||
98 | - fieldNames: { | ||
99 | - label: 'deptName', | ||
100 | - key: 'id', | ||
101 | - value: 'id', | ||
102 | - }, | ||
103 | - getPopupContainer: () => document.body, | ||
104 | - }, | ||
105 | - required: true, | ||
106 | - }, | ||
107 | - { | ||
108 | - field: 'nickname', | ||
109 | - label: '昵称', | ||
110 | - component: 'Input', | ||
111 | - required: true, | ||
112 | - }, | ||
113 | - | ||
114 | - { | ||
115 | - label: '邮箱', | ||
116 | - field: 'email', | ||
117 | - component: 'Input', | ||
118 | - required: true, | ||
119 | - }, | ||
120 | - | ||
121 | - { | ||
122 | - label: '备注', | ||
123 | - field: 'remark', | ||
124 | - component: 'InputTextArea', | ||
125 | - }, | ||
126 | -]; |
src/views/demo/system/role/RoleDrawer.vue
@@ -8,7 +8,7 @@ | @@ -8,7 +8,7 @@ | ||
8 | @ok="handleSubmit" | 8 | @ok="handleSubmit" |
9 | > | 9 | > |
10 | <BasicForm @register="registerForm"> | 10 | <BasicForm @register="registerForm"> |
11 | - <template #menu="{ model, field }"> | 11 | + <!-- <template #menu="{ model, field }"> |
12 | <BasicTree | 12 | <BasicTree |
13 | v-model:value="model[field]" | 13 | v-model:value="model[field]" |
14 | :treeData="treeData" | 14 | :treeData="treeData" |
@@ -17,7 +17,7 @@ | @@ -17,7 +17,7 @@ | ||
17 | toolbar | 17 | toolbar |
18 | title="菜单分配" | 18 | title="菜单分配" |
19 | /> | 19 | /> |
20 | - </template> | 20 | + </template> --> |
21 | </BasicForm> | 21 | </BasicForm> |
22 | </BasicDrawer> | 22 | </BasicDrawer> |
23 | </template> | 23 | </template> |
src/views/demo/system/role/role.data.ts
@@ -7,60 +7,60 @@ import { useMessage } from '/@/hooks/web/useMessage'; | @@ -7,60 +7,60 @@ import { useMessage } from '/@/hooks/web/useMessage'; | ||
7 | export const columns: BasicColumn[] = [ | 7 | export const columns: BasicColumn[] = [ |
8 | { | 8 | { |
9 | title: '角色名称', | 9 | title: '角色名称', |
10 | - dataIndex: 'roleName', | 10 | + dataIndex: 'name', |
11 | width: 200, | 11 | width: 200, |
12 | }, | 12 | }, |
13 | - { | ||
14 | - title: '角色值', | ||
15 | - dataIndex: 'roleValue', | ||
16 | - width: 180, | ||
17 | - }, | ||
18 | - { | ||
19 | - title: '排序', | ||
20 | - dataIndex: 'orderNo', | ||
21 | - width: 50, | ||
22 | - }, | ||
23 | - { | ||
24 | - title: '状态', | ||
25 | - dataIndex: 'status', | ||
26 | - width: 120, | ||
27 | - customRender: ({ record }) => { | ||
28 | - if (!Reflect.has(record, 'pendingStatus')) { | ||
29 | - record.pendingStatus = false; | ||
30 | - } | ||
31 | - return h(Switch, { | ||
32 | - checked: record.status === '1', | ||
33 | - checkedChildren: '停用', | ||
34 | - unCheckedChildren: '启用', | ||
35 | - loading: record.pendingStatus, | ||
36 | - onChange(checked: boolean) { | ||
37 | - record.pendingStatus = true; | ||
38 | - const newStatus = checked ? '1' : '0'; | ||
39 | - const { createMessage } = useMessage(); | ||
40 | - setRoleStatus(record.id, newStatus) | ||
41 | - .then(() => { | ||
42 | - record.status = newStatus; | ||
43 | - createMessage.success(`已成功修改角色状态`); | ||
44 | - }) | ||
45 | - .catch(() => { | ||
46 | - createMessage.error('修改角色状态失败'); | ||
47 | - }) | ||
48 | - .finally(() => { | ||
49 | - record.pendingStatus = false; | ||
50 | - }); | ||
51 | - }, | ||
52 | - }); | ||
53 | - }, | ||
54 | - }, | 13 | + // { |
14 | + // title: '角色值', | ||
15 | + // dataIndex: 'roleValue', | ||
16 | + // width: 180, | ||
17 | + // }, | ||
18 | + // { | ||
19 | + // title: '排序', | ||
20 | + // dataIndex: 'orderNo', | ||
21 | + // width: 50, | ||
22 | + // }, | ||
23 | + // { | ||
24 | + // title: '状态', | ||
25 | + // dataIndex: 'status', | ||
26 | + // width: 120, | ||
27 | + // customRender: ({ record }) => { | ||
28 | + // if (!Reflect.has(record, 'pendingStatus')) { | ||
29 | + // record.pendingStatus = false; | ||
30 | + // } | ||
31 | + // return h(Switch, { | ||
32 | + // checked: record.status === '1', | ||
33 | + // checkedChildren: '停用', | ||
34 | + // unCheckedChildren: '启用', | ||
35 | + // loading: record.pendingStatus, | ||
36 | + // onChange(checked: boolean) { | ||
37 | + // record.pendingStatus = true; | ||
38 | + // const newStatus = checked ? '1' : '0'; | ||
39 | + // const { createMessage } = useMessage(); | ||
40 | + // setRoleStatus(record.id, newStatus) | ||
41 | + // .then(() => { | ||
42 | + // record.status = newStatus; | ||
43 | + // createMessage.success(`已成功修改角色状态`); | ||
44 | + // }) | ||
45 | + // .catch(() => { | ||
46 | + // createMessage.error('修改角色状态失败'); | ||
47 | + // }) | ||
48 | + // .finally(() => { | ||
49 | + // record.pendingStatus = false; | ||
50 | + // }); | ||
51 | + // }, | ||
52 | + // }); | ||
53 | + // }, | ||
54 | + // }, | ||
55 | { | 55 | { |
56 | title: '创建时间', | 56 | title: '创建时间', |
57 | dataIndex: 'createTime', | 57 | dataIndex: 'createTime', |
58 | width: 180, | 58 | width: 180, |
59 | }, | 59 | }, |
60 | - { | ||
61 | - title: '备注', | ||
62 | - dataIndex: 'remark', | ||
63 | - }, | 60 | + // { |
61 | + // title: '备注', | ||
62 | + // dataIndex: 'remark', | ||
63 | + // }, | ||
64 | ]; | 64 | ]; |
65 | 65 | ||
66 | export const searchFormSchema: FormSchema[] = [ | 66 | export const searchFormSchema: FormSchema[] = [ |
src/views/demo/system/account/AccountDetail.vue renamed to src/views/project/account/AccountDetail.vue
src/views/demo/system/account/AccountModal.vue renamed to src/views/project/account/AccountModal.vue
@@ -4,11 +4,10 @@ | @@ -4,11 +4,10 @@ | ||
4 | </BasicModal> | 4 | </BasicModal> |
5 | </template> | 5 | </template> |
6 | <script lang="ts"> | 6 | <script lang="ts"> |
7 | - import { defineComponent, ref, computed, unref } from 'vue'; | 7 | + import { defineComponent, ref, computed, unref, toRaw } from 'vue'; |
8 | import { BasicModal, useModalInner } from '/@/components/Modal'; | 8 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
9 | import { BasicForm, useForm } from '/@/components/Form/index'; | 9 | import { BasicForm, useForm } from '/@/components/Form/index'; |
10 | import { accountFormSchema } from './account.data'; | 10 | import { accountFormSchema } from './account.data'; |
11 | - import { getDeptList } from '/@/api/demo/system'; | ||
12 | 11 | ||
13 | export default defineComponent({ | 12 | export default defineComponent({ |
14 | name: 'AccountModal', | 13 | name: 'AccountModal', |
@@ -18,7 +17,7 @@ | @@ -18,7 +17,7 @@ | ||
18 | const isUpdate = ref(true); | 17 | const isUpdate = ref(true); |
19 | const rowId = ref(''); | 18 | const rowId = ref(''); |
20 | 19 | ||
21 | - const [registerForm, { setFieldsValue, updateSchema, resetFields, validate }] = useForm({ | 20 | + const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({ |
22 | labelWidth: 100, | 21 | labelWidth: 100, |
23 | baseColProps: { span: 24 }, | 22 | baseColProps: { span: 24 }, |
24 | schemas: accountFormSchema, | 23 | schemas: accountFormSchema, |
@@ -35,22 +34,11 @@ | @@ -35,22 +34,11 @@ | ||
35 | 34 | ||
36 | if (unref(isUpdate)) { | 35 | if (unref(isUpdate)) { |
37 | rowId.value = data.record.id; | 36 | rowId.value = data.record.id; |
37 | + | ||
38 | setFieldsValue({ | 38 | setFieldsValue({ |
39 | - ...data.record, | 39 | + ...toRaw(data.record), |
40 | }); | 40 | }); |
41 | } | 41 | } |
42 | - | ||
43 | - const treeData = await getDeptList(); | ||
44 | - updateSchema([ | ||
45 | - { | ||
46 | - field: 'pwd', | ||
47 | - show: !unref(isUpdate), | ||
48 | - }, | ||
49 | - { | ||
50 | - field: 'dept', | ||
51 | - componentProps: { treeData }, | ||
52 | - }, | ||
53 | - ]); | ||
54 | }); | 42 | }); |
55 | 43 | ||
56 | const getTitle = computed(() => (!unref(isUpdate) ? '新增账号' : '编辑账号')); | 44 | const getTitle = computed(() => (!unref(isUpdate) ? '新增账号' : '编辑账号')); |
@@ -59,8 +47,7 @@ | @@ -59,8 +47,7 @@ | ||
59 | try { | 47 | try { |
60 | const values = await validate(); | 48 | const values = await validate(); |
61 | setModalProps({ confirmLoading: true }); | 49 | setModalProps({ confirmLoading: true }); |
62 | - // TODO custom api | ||
63 | - console.log(values); | 50 | + |
64 | closeModal(); | 51 | closeModal(); |
65 | emit('success', { isUpdate: unref(isUpdate), values: { ...values, id: rowId.value } }); | 52 | emit('success', { isUpdate: unref(isUpdate), values: { ...values, id: rowId.value } }); |
66 | } finally { | 53 | } finally { |
src/views/demo/system/account/DeptTree.vue renamed to src/views/project/account/DeptTree.vue
src/views/project/account/account.data.ts
0 → 100644
1 | +import { getRoleList } from '/@/api/project/account'; | ||
2 | + | ||
3 | +export const columns: BasicColumn[] = [ | ||
4 | + { | ||
5 | + title: '手机号', | ||
6 | + dataIndex: 'phone', | ||
7 | + width: 120, | ||
8 | + }, | ||
9 | + { | ||
10 | + title: '昵称', | ||
11 | + dataIndex: 'nickName', | ||
12 | + width: 120, | ||
13 | + }, | ||
14 | + // { | ||
15 | + // title: '邮箱', | ||
16 | + // dataIndex: 'email', | ||
17 | + // width: 120, | ||
18 | + // }, | ||
19 | + // { | ||
20 | + // title: '创建时间', | ||
21 | + // dataIndex: 'createTime', | ||
22 | + // width: 180, | ||
23 | + // }, | ||
24 | + { | ||
25 | + title: '角色', | ||
26 | + dataIndex: 'roleName', | ||
27 | + width: 200, | ||
28 | + }, | ||
29 | + { | ||
30 | + title: '备注', | ||
31 | + dataIndex: 'remark', | ||
32 | + }, | ||
33 | +]; | ||
34 | + | ||
35 | +export const searchFormSchema: FormSchema[] = [ | ||
36 | + { | ||
37 | + field: 'phone', | ||
38 | + label: '手机号', | ||
39 | + component: 'Input', | ||
40 | + colProps: { span: 8 }, | ||
41 | + }, | ||
42 | + { | ||
43 | + field: 'nickName', | ||
44 | + label: '昵称', | ||
45 | + component: 'Input', | ||
46 | + colProps: { span: 8 }, | ||
47 | + }, | ||
48 | +]; | ||
49 | + | ||
50 | +export const accountFormSchema: FormSchema[] = [ | ||
51 | + { | ||
52 | + field: 'phone', | ||
53 | + label: '手机号', | ||
54 | + component: 'Input', | ||
55 | + // helpMessage: ['本字段演示异步验证', '不能输入带有admin的用户名'], | ||
56 | + rules: [ | ||
57 | + { | ||
58 | + required: true, | ||
59 | + message: '请输入用户名', | ||
60 | + }, | ||
61 | + // { | ||
62 | + // validator(_, value) { | ||
63 | + // return new Promise((resolve, reject) => { | ||
64 | + // isAccountExist(value) | ||
65 | + // .then(() => resolve()) | ||
66 | + // .catch((err) => { | ||
67 | + // reject(err.message || '验证失败'); | ||
68 | + // }); | ||
69 | + // }); | ||
70 | + // }, | ||
71 | + // }, | ||
72 | + ], | ||
73 | + }, | ||
74 | + // { | ||
75 | + // field: 'pwd', | ||
76 | + // label: '密码', | ||
77 | + // component: 'InputPassword', | ||
78 | + // required: true, | ||
79 | + // ifShow: false, | ||
80 | + // }, | ||
81 | + { | ||
82 | + label: '角色', | ||
83 | + field: 'roleName', | ||
84 | + component: 'ApiSelect', | ||
85 | + componentProps: { | ||
86 | + api: getRoleList, | ||
87 | + labelField: 'name', | ||
88 | + valueField: 'level', | ||
89 | + }, | ||
90 | + required: true, | ||
91 | + }, | ||
92 | + // { | ||
93 | + // field: 'dept', | ||
94 | + // label: '所属部门', | ||
95 | + // component: 'TreeSelect', | ||
96 | + // componentProps: { | ||
97 | + // fieldNames: { | ||
98 | + // label: 'deptName', | ||
99 | + // key: 'id', | ||
100 | + // value: 'id', | ||
101 | + // }, | ||
102 | + // getPopupContainer: () => document.body, | ||
103 | + // }, | ||
104 | + // required: true, | ||
105 | + // }, | ||
106 | + { | ||
107 | + field: 'nickName', | ||
108 | + label: '昵称', | ||
109 | + component: 'Input', | ||
110 | + required: true, | ||
111 | + }, | ||
112 | + | ||
113 | + // { | ||
114 | + // label: '邮箱', | ||
115 | + // field: 'email', | ||
116 | + // component: 'Input', | ||
117 | + // required: true, | ||
118 | + // }, | ||
119 | + | ||
120 | + { | ||
121 | + label: '备注', | ||
122 | + field: 'remark', | ||
123 | + component: 'InputTextArea', | ||
124 | + }, | ||
125 | +]; |
src/views/demo/system/account/index.vue renamed to src/views/project/account/index.vue
1 | <template> | 1 | <template> |
2 | <PageWrapper dense contentFullHeight fixedHeight contentClass="flex"> | 2 | <PageWrapper dense contentFullHeight fixedHeight contentClass="flex"> |
3 | - <DeptTree class="w-1/4 xl:w-1/5" @select="handleSelect" /> | ||
4 | - <BasicTable @register="registerTable" class="w-3/4 xl:w-4/5" :searchInfo="searchInfo"> | 3 | + <!-- <DeptTree class="w-1/4 xl:w-1/5" @select="handleSelect" /> --> |
4 | + <BasicTable @register="registerTable" :searchInfo="searchInfo"> | ||
5 | <template #toolbar> | 5 | <template #toolbar> |
6 | <a-button type="primary" @click="handleCreate">新增账号</a-button> | 6 | <a-button type="primary" @click="handleCreate">新增账号</a-button> |
7 | </template> | 7 | </template> |
@@ -9,11 +9,11 @@ | @@ -9,11 +9,11 @@ | ||
9 | <template v-if="column.key === 'action'"> | 9 | <template v-if="column.key === 'action'"> |
10 | <TableAction | 10 | <TableAction |
11 | :actions="[ | 11 | :actions="[ |
12 | - { | ||
13 | - icon: 'clarity:info-standard-line', | ||
14 | - tooltip: '查看用户详情', | ||
15 | - onClick: handleView.bind(null, record), | ||
16 | - }, | 12 | + // { |
13 | + // icon: 'clarity:info-standard-line', | ||
14 | + // tooltip: '查看用户详情', | ||
15 | + // onClick: handleView.bind(null, record), | ||
16 | + // }, | ||
17 | { | 17 | { |
18 | icon: 'clarity:note-edit-line', | 18 | icon: 'clarity:note-edit-line', |
19 | tooltip: '编辑用户资料', | 19 | tooltip: '编辑用户资料', |
@@ -41,7 +41,7 @@ | @@ -41,7 +41,7 @@ | ||
41 | import { defineComponent, reactive } from 'vue'; | 41 | import { defineComponent, reactive } from 'vue'; |
42 | 42 | ||
43 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; | 43 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
44 | - import { getAccountList } from '/@/api/demo/system'; | 44 | + import { getUserList, userAdd, userEdit } from '/@/api/project/account'; |
45 | import { PageWrapper } from '/@/components/Page'; | 45 | import { PageWrapper } from '/@/components/Page'; |
46 | import DeptTree from './DeptTree.vue'; | 46 | import DeptTree from './DeptTree.vue'; |
47 | 47 | ||
@@ -57,10 +57,10 @@ | @@ -57,10 +57,10 @@ | ||
57 | setup() { | 57 | setup() { |
58 | const go = useGo(); | 58 | const go = useGo(); |
59 | const [registerModal, { openModal }] = useModal(); | 59 | const [registerModal, { openModal }] = useModal(); |
60 | - const searchInfo = reactive<Recordable>({}); | 60 | + const searchInfo = reactive({}); |
61 | const [registerTable, { reload, updateTableDataRecord }] = useTable({ | 61 | const [registerTable, { reload, updateTableDataRecord }] = useTable({ |
62 | title: '账号列表', | 62 | title: '账号列表', |
63 | - api: getAccountList, | 63 | + api: getUserList, |
64 | rowKey: 'id', | 64 | rowKey: 'id', |
65 | columns, | 65 | columns, |
66 | formConfig: { | 66 | formConfig: { |
@@ -101,15 +101,14 @@ | @@ -101,15 +101,14 @@ | ||
101 | console.log(record); | 101 | console.log(record); |
102 | } | 102 | } |
103 | 103 | ||
104 | - function handleSuccess({ isUpdate, values }) { | 104 | + async function handleSuccess({ isUpdate, values }) { |
105 | if (isUpdate) { | 105 | if (isUpdate) { |
106 | - // 演示不刷新表格直接更新内部数据。 | ||
107 | - // 注意:updateTableDataRecord要求表格的rowKey属性为string并且存在于每一行的record的keys中 | ||
108 | - const result = updateTableDataRecord(values.id, values); | ||
109 | - console.log(result); | 106 | + await userEdit({ ...values }); |
110 | } else { | 107 | } else { |
111 | - reload(); | 108 | + await userAdd({ ...values }); |
112 | } | 109 | } |
110 | + | ||
111 | + reload(); | ||
113 | } | 112 | } |
114 | 113 | ||
115 | function handleSelect(deptId = '') { | 114 | function handleSelect(deptId = '') { |
src/views/project/approve/index.vue
0 → 100644
1 | +<template> | ||
2 | + <PageWrapper contentBackground> | ||
3 | + <template #footer> | ||
4 | + <a-tabs default-active-key="1" v-model:activeKey="currentKey"> | ||
5 | + <a-tab-pane key="1" tab="申请/待审核列表" | ||
6 | + ><BasicTable @register="registerTable1"> | ||
7 | + <template #form-custom> custom-slot </template> | ||
8 | + <template #bodyCell="{ column, record }"> | ||
9 | + <template v-if="column.key === 'action'"> | ||
10 | + <TableAction | ||
11 | + :actions="[ | ||
12 | + { | ||
13 | + label: '通过', | ||
14 | + // icon: 'ic:outline-delete-outline', | ||
15 | + onClick: handleTrue.bind(null, record), | ||
16 | + }, | ||
17 | + { | ||
18 | + label: '拒绝', | ||
19 | + // icon: 'ic:outline-delete-outline', | ||
20 | + onClick: handleFalse.bind(null, record), | ||
21 | + }, | ||
22 | + ]" | ||
23 | + /> | ||
24 | + </template> | ||
25 | + </template> </BasicTable | ||
26 | + ></a-tab-pane> | ||
27 | + <a-tab-pane key="2" tab="已审核列表"> | ||
28 | + <BasicTable @register="registerTable2" /> | ||
29 | + </a-tab-pane> | ||
30 | + </a-tabs> | ||
31 | + </template> | ||
32 | + </PageWrapper> | ||
33 | +</template> | ||
34 | +<script lang="ts"> | ||
35 | + import { defineComponent, ref } from 'vue'; | ||
36 | + import { BasicTable, useTable, TableAction } from '/@/components/Table'; | ||
37 | + import { Tabs } from 'ant-design-vue'; | ||
38 | + import { PageWrapper } from '/@/components/Page'; | ||
39 | + | ||
40 | + import { approveAuditApi, getWaitListApi, getApprovedListApi } from '/@/api/project/approve'; | ||
41 | + | ||
42 | + export default defineComponent({ | ||
43 | + components: { | ||
44 | + PageWrapper, | ||
45 | + BasicTable, | ||
46 | + TableAction, | ||
47 | + [Tabs.name]: Tabs, | ||
48 | + [Tabs.TabPane.name]: Tabs.TabPane, | ||
49 | + }, | ||
50 | + setup() { | ||
51 | + const checkedKeys = ref<Array<string | number>>([]); | ||
52 | + const currentKey = ref('1'); | ||
53 | + | ||
54 | + const [registerTable1, { reload }] = useTable({ | ||
55 | + api: getWaitListApi, | ||
56 | + columns: [ | ||
57 | + { | ||
58 | + title: '申请人', | ||
59 | + dataIndex: 'createBy', | ||
60 | + width: 150, | ||
61 | + }, | ||
62 | + { | ||
63 | + title: '申请字段', | ||
64 | + dataIndex: 'fields', | ||
65 | + width: 600, | ||
66 | + }, | ||
67 | + { | ||
68 | + title: '订单号', | ||
69 | + dataIndex: 'no6', | ||
70 | + }, | ||
71 | + { | ||
72 | + title: '订单字段1', | ||
73 | + dataIndex: 'no5', | ||
74 | + }, | ||
75 | + { | ||
76 | + title: '订单字段2', | ||
77 | + dataIndex: 'no4', | ||
78 | + }, | ||
79 | + { | ||
80 | + title: '订单字段3', | ||
81 | + dataIndex: 'no3', | ||
82 | + }, | ||
83 | + | ||
84 | + { | ||
85 | + title: '订单字段5', | ||
86 | + dataIndex: 'no1', | ||
87 | + }, | ||
88 | + ], | ||
89 | + // useSearchForm: true, | ||
90 | + // formConfig: getFormConfig(), | ||
91 | + rowKey: 'id', | ||
92 | + actionColumn: { | ||
93 | + width: 160, | ||
94 | + title: 'Action', | ||
95 | + dataIndex: 'action', | ||
96 | + // slots: { customRender: 'action' }, | ||
97 | + }, | ||
98 | + }); | ||
99 | + | ||
100 | + const [registerTable2] = useTable({ | ||
101 | + api: getApprovedListApi, | ||
102 | + columns: [ | ||
103 | + { | ||
104 | + title: '申请人', | ||
105 | + dataIndex: 'createBy', | ||
106 | + width: 150, | ||
107 | + }, | ||
108 | + { | ||
109 | + title: '申请字段', | ||
110 | + dataIndex: 'fields', | ||
111 | + width: 600, | ||
112 | + }, | ||
113 | + { | ||
114 | + title: '订单号', | ||
115 | + dataIndex: 'no6', | ||
116 | + }, | ||
117 | + { | ||
118 | + title: '订单字段1', | ||
119 | + dataIndex: 'no5', | ||
120 | + }, | ||
121 | + { | ||
122 | + title: '订单字段2', | ||
123 | + dataIndex: 'no4', | ||
124 | + }, | ||
125 | + { | ||
126 | + title: '订单字段3', | ||
127 | + dataIndex: 'no3', | ||
128 | + }, | ||
129 | + | ||
130 | + { | ||
131 | + title: '订单字段5', | ||
132 | + dataIndex: 'no1', | ||
133 | + }, | ||
134 | + ], | ||
135 | + rowKey: 'id', | ||
136 | + }); | ||
137 | + | ||
138 | + // function getFormValues() { | ||
139 | + // console.log(getForm1().getFieldsValue()); | ||
140 | + // } | ||
141 | + | ||
142 | + function onSelect(record, selected) { | ||
143 | + if (selected) { | ||
144 | + checkedKeys.value = [...checkedKeys.value, record.id]; | ||
145 | + } else { | ||
146 | + checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id); | ||
147 | + } | ||
148 | + } | ||
149 | + function onSelectAll(selected, selectedRows, changeRows) { | ||
150 | + const changeIds = changeRows.map((item) => item.id); | ||
151 | + if (selected) { | ||
152 | + checkedKeys.value = [...checkedKeys.value, ...changeIds]; | ||
153 | + } else { | ||
154 | + checkedKeys.value = checkedKeys.value.filter((id) => { | ||
155 | + return !changeIds.includes(id); | ||
156 | + }); | ||
157 | + } | ||
158 | + } | ||
159 | + function handleEdit(record, e) { | ||
160 | + e?.stopPropagation(); | ||
161 | + return false; | ||
162 | + } | ||
163 | + | ||
164 | + function handleProfitModal() {} | ||
165 | + | ||
166 | + async function handleTrue(record) { | ||
167 | + await approveAuditApi({ status: 10, id: record.id }); | ||
168 | + reload(); | ||
169 | + } | ||
170 | + | ||
171 | + async function handleFalse(record) { | ||
172 | + await approveAuditApi({ status: 20, id: record.id }); | ||
173 | + reload(); | ||
174 | + } | ||
175 | + | ||
176 | + return { | ||
177 | + handleProfitModal, | ||
178 | + registerTable1, | ||
179 | + registerTable2, | ||
180 | + checkedKeys, | ||
181 | + currentKey, | ||
182 | + onSelect, | ||
183 | + handleEdit, | ||
184 | + onSelectAll, | ||
185 | + handleTrue, | ||
186 | + handleFalse, | ||
187 | + }; | ||
188 | + }, | ||
189 | + }); | ||
190 | +</script> |
src/views/project/order/CheckDetail.vue
0 → 100644
1 | +<template> | ||
2 | + <BasicDrawer | ||
3 | + @register="register" | ||
4 | + v-bind="$attrs" | ||
5 | + showFooter | ||
6 | + title="字段编辑权限申请" | ||
7 | + width="60%" | ||
8 | + :isDetail="true" | ||
9 | + @ok="handleSubmit" | ||
10 | + :showDetailBack="false" | ||
11 | + okText="申请" | ||
12 | + ><input /> | ||
13 | + <div> | ||
14 | + <h3>基本信息</h3> | ||
15 | + <BasicForm @register="registerForm" /> | ||
16 | + <h3>利润分析</h3> | ||
17 | + <BasicForm @register="registerProfitForm" /> | ||
18 | + </div> | ||
19 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | ||
20 | + | ||
21 | + <template #appendFooter> | ||
22 | + <a-button type="primary" @click="onGoFormDetail"> 返回编辑</a-button> | ||
23 | + </template> | ||
24 | + </BasicDrawer> | ||
25 | +</template> | ||
26 | +<script lang="ts"> | ||
27 | + import { defineComponent, reactive, ref } from 'vue'; | ||
28 | + import { BasicForm, FormSchema, useForm } from '/@/components/Form/index'; | ||
29 | + import { orderAuth } from '/@/api/project/order'; | ||
30 | + | ||
31 | + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | ||
32 | + import { FIELDS_BASE_INFO, FIELDS_PROFIT_INFO } from './tableData'; | ||
33 | + import { cloneDeep, isEmpty, mapValues, mergeWith } from 'lodash-es'; | ||
34 | + | ||
35 | + const getSchema = (fields, base) => | ||
36 | + fields.map((item) => ({ | ||
37 | + field: `${base}.${item.field}`, | ||
38 | + dataIndex: `${base}.${item.field}`, | ||
39 | + label: item.label, | ||
40 | + component: 'Switch', | ||
41 | + colProps: { | ||
42 | + span: 6, | ||
43 | + }, | ||
44 | + })); | ||
45 | + | ||
46 | + export default defineComponent({ | ||
47 | + components: { BasicDrawer, BasicForm }, | ||
48 | + props: { | ||
49 | + onGoFormDetail: { | ||
50 | + type: Function, | ||
51 | + }, | ||
52 | + }, | ||
53 | + setup() { | ||
54 | + const id = ref(''); | ||
55 | + const schemas = getSchema(FIELDS_BASE_INFO, 'baseFields'); | ||
56 | + const profitSchemas = getSchema(FIELDS_PROFIT_INFO, 'profitAnalysisFields'); | ||
57 | + const [registerForm, { getFieldsValue }] = useForm({ | ||
58 | + labelWidth: 120, | ||
59 | + schemas, | ||
60 | + showActionButtonGroup: false, | ||
61 | + actionColOptions: { | ||
62 | + span: 24, | ||
63 | + }, | ||
64 | + }); | ||
65 | + const [registerProfitForm, { getFieldsValue: getProfitFieldsValue }] = useForm({ | ||
66 | + labelWidth: 120, | ||
67 | + schemas: profitSchemas, | ||
68 | + showActionButtonGroup: false, | ||
69 | + actionColOptions: { | ||
70 | + span: 24, | ||
71 | + }, | ||
72 | + }); | ||
73 | + const lockFields = reactive({}); | ||
74 | + const [register, { closeDrawer }] = useDrawerInner((data) => { | ||
75 | + Object.assign(lockFields, data.lockFields); | ||
76 | + id.value = data.id; | ||
77 | + }); | ||
78 | + | ||
79 | + function customizer(objValue, srcValue, key) { | ||
80 | + // 检查是否在 baseFields 内以及值是否为 true | ||
81 | + if (srcValue === true) { | ||
82 | + return 'UN_LOCKED'; | ||
83 | + } | ||
84 | + return objValue; // 如果不需要改变,返回原值 | ||
85 | + } | ||
86 | + const handleSubmit = async () => { | ||
87 | + const baseFieldValues = getFieldsValue(); | ||
88 | + const profitFieldValues = getProfitFieldsValue(); | ||
89 | + | ||
90 | + !isEmpty(baseFieldValues) && | ||
91 | + Object.keys(baseFieldValues.baseFields)?.map((key) => { | ||
92 | + baseFieldValues.baseFields[key] = baseFieldValues.baseFields[key] | ||
93 | + ? 'UN_LOCKED' | ||
94 | + : 'LOCKED'; | ||
95 | + }); | ||
96 | + | ||
97 | + !isEmpty(profitFieldValues) && | ||
98 | + Object.keys(profitFieldValues.profitAnalysisFields).map((key) => { | ||
99 | + profitFieldValues.profitAnalysisFields[key] = profitFieldValues.profitAnalysisFields[ | ||
100 | + key | ||
101 | + ] | ||
102 | + ? 'UN_LOCKED' | ||
103 | + : 'LOCKED'; | ||
104 | + }); | ||
105 | + | ||
106 | + const values = Object.assign({ orderId: id.value }, baseFieldValues, profitFieldValues); | ||
107 | + console.log('%c [ values ]-103', 'font-size:13px; background:pink; color:#bf2c9f;', values); | ||
108 | + await orderAuth(values); | ||
109 | + closeDrawer(); | ||
110 | + }; | ||
111 | + return { register, schemas, registerForm, registerProfitForm, handleSubmit }; | ||
112 | + }, | ||
113 | + }); | ||
114 | +</script> |
src/views/project/order/FieldDetail.vue
0 → 100644
1 | +<template> | ||
2 | + <BasicDrawer | ||
3 | + @register="register" | ||
4 | + v-bind="$attrs" | ||
5 | + title="title" | ||
6 | + width="60%" | ||
7 | + :isDetail="true" | ||
8 | + :showDetailBack="false" | ||
9 | + > | ||
10 | + <div> | ||
11 | + <BasicTable @register="registerTable" @edit-change="handleEditChange"> | ||
12 | + <template #bodyCell="{ column, record }"> | ||
13 | + <template v-if="column.key === 'action'"> | ||
14 | + <TableAction :actions="createActions(record, column)" /> | ||
15 | + </template> | ||
16 | + </template> | ||
17 | + </BasicTable> | ||
18 | + <a-button block class="mt-5" type="dashed" @click="handleAdd"> 新增选项 </a-button> | ||
19 | + </div> | ||
20 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | ||
21 | + </BasicDrawer> | ||
22 | +</template> | ||
23 | +<script lang="ts"> | ||
24 | + import { defineComponent, ref, toRaw } from 'vue'; | ||
25 | + import { | ||
26 | + BasicTable, | ||
27 | + useTable, | ||
28 | + TableAction, | ||
29 | + BasicColumn, | ||
30 | + ActionItem, | ||
31 | + EditRecordRow, | ||
32 | + } from '/@/components/Table'; | ||
33 | + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | ||
34 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | ||
35 | + import { dictCreate, dictDelete, dictList, dictUpdate } from '/@/api/project/order'; | ||
36 | + | ||
37 | + const orderStore = useOrderStoreWithOut(); | ||
38 | + | ||
39 | + const columns: BasicColumn[] = [ | ||
40 | + { | ||
41 | + title: '筛选项', | ||
42 | + dataIndex: 'dictValue', | ||
43 | + editRow: true, | ||
44 | + }, | ||
45 | + ]; | ||
46 | + | ||
47 | + export default defineComponent({ | ||
48 | + components: { BasicDrawer, BasicTable, TableAction }, | ||
49 | + props: { | ||
50 | + onGoFormDetail: { | ||
51 | + type: Function, | ||
52 | + }, | ||
53 | + }, | ||
54 | + setup() { | ||
55 | + const dataSource = ref([]); | ||
56 | + const key = ref(''); | ||
57 | + const title = ref(''); | ||
58 | + | ||
59 | + const [registerTable, { getDataSource, reload }] = useTable({ | ||
60 | + columns: columns, | ||
61 | + showIndexColumn: false, | ||
62 | + dataSource: toRaw(dataSource), | ||
63 | + actionColumn: { | ||
64 | + width: 160, | ||
65 | + title: '操作', | ||
66 | + dataIndex: 'action', | ||
67 | + // slots: { customRender: 'action' }, | ||
68 | + }, | ||
69 | + scroll: { y: '100%' }, | ||
70 | + pagination: false, | ||
71 | + }); | ||
72 | + | ||
73 | + const [register] = useDrawerInner((data) => { | ||
74 | + const { dataIndex, customTitle } = data; | ||
75 | + const dicts = orderStore.getDictInfo; | ||
76 | + const dict = dicts[dataIndex]; | ||
77 | + dataSource.value = dict; | ||
78 | + title.value = customTitle; | ||
79 | + key.value = dataIndex; | ||
80 | + }); | ||
81 | + | ||
82 | + function handleEdit(record: EditRecordRow) { | ||
83 | + record.onEdit?.(true); | ||
84 | + } | ||
85 | + | ||
86 | + function handleCancel(record: EditRecordRow) { | ||
87 | + record.onEdit?.(false); | ||
88 | + if (record.isNew) { | ||
89 | + const data = getDataSource(); | ||
90 | + const index = data.findIndex((item) => item.key === record.key); | ||
91 | + data.splice(index, 1); | ||
92 | + } | ||
93 | + } | ||
94 | + | ||
95 | + async function handleSave(record: EditRecordRow) { | ||
96 | + if (record.id) { | ||
97 | + await dictUpdate({ dictCode: key.value, dictValue: record.dictValue }); | ||
98 | + } else { | ||
99 | + await dictCreate({ | ||
100 | + dictName: title.value, | ||
101 | + dictCode: key.value, | ||
102 | + dictValue: record.dictValue, | ||
103 | + sort: dataSource.value.length + 1, | ||
104 | + }); | ||
105 | + } | ||
106 | + | ||
107 | + await orderStore.getDict(); | ||
108 | + | ||
109 | + setTimeout(async () => { | ||
110 | + const res = await dictList({ dictCode: key.value }); | ||
111 | + dataSource.value = res.records; | ||
112 | + reload(); | ||
113 | + }, 300); | ||
114 | + } | ||
115 | + | ||
116 | + async function handleDelete(record) { | ||
117 | + await dictDelete({ ids: [record.id] }); | ||
118 | + await orderStore.getDict(); | ||
119 | + record.onEdit?.(false, true); | ||
120 | + setTimeout(async () => { | ||
121 | + const res = await dictList({ dictCode: key.value }); | ||
122 | + dataSource.value = res.records; | ||
123 | + reload(); | ||
124 | + }, 300); | ||
125 | + } | ||
126 | + | ||
127 | + function handleEditChange(data) { | ||
128 | + console.log(data); | ||
129 | + } | ||
130 | + | ||
131 | + function handleAdd() { | ||
132 | + const data = getDataSource(); | ||
133 | + const addRow: EditRecordRow = { | ||
134 | + name: '', | ||
135 | + no: '', | ||
136 | + dept: '', | ||
137 | + editable: true, | ||
138 | + isNew: true, | ||
139 | + key: `${Date.now()}`, | ||
140 | + }; | ||
141 | + data.push(addRow); | ||
142 | + } | ||
143 | + | ||
144 | + function createActions(record: EditRecordRow, column: BasicColumn): ActionItem[] { | ||
145 | + if (!record.editable) { | ||
146 | + return [ | ||
147 | + { | ||
148 | + label: '编辑', | ||
149 | + onClick: handleEdit.bind(null, record), | ||
150 | + }, | ||
151 | + { | ||
152 | + label: '删除', | ||
153 | + onClick: handleDelete.bind(null, record), | ||
154 | + }, | ||
155 | + ]; | ||
156 | + } | ||
157 | + return [ | ||
158 | + { | ||
159 | + label: '保存', | ||
160 | + onClick: handleSave.bind(null, record, column), | ||
161 | + }, | ||
162 | + { | ||
163 | + label: '取消', | ||
164 | + popConfirm: { | ||
165 | + title: '是否取消编辑', | ||
166 | + confirm: handleCancel.bind(null, record, column), | ||
167 | + }, | ||
168 | + }, | ||
169 | + ]; | ||
170 | + } | ||
171 | + return { | ||
172 | + title, | ||
173 | + register, | ||
174 | + registerTable, | ||
175 | + handleEdit, | ||
176 | + createActions, | ||
177 | + handleAdd, | ||
178 | + getDataSource, | ||
179 | + handleEditChange, | ||
180 | + }; | ||
181 | + }, | ||
182 | + }); | ||
183 | +</script> |
src/views/project/order/FormDetail.vue
0 → 100644
1 | +<template> | ||
2 | + <BasicDrawer | ||
3 | + v-bind="$attrs" | ||
4 | + showFooter | ||
5 | + @register="register" | ||
6 | + @ok="handleSubmit" | ||
7 | + title="" | ||
8 | + width="28%" | ||
9 | + ref="formRef" | ||
10 | + :isDetail="true" | ||
11 | + :showDetailBack="false" | ||
12 | + okText="保存" | ||
13 | + :mask="false" | ||
14 | + class="z-20" | ||
15 | + > | ||
16 | + <Tabs v-model:activeKey="activeKey"> | ||
17 | + <TabPanel key="1" tab="基本信息" :forceRender="true"> | ||
18 | + <BasicForm @register="registerForm" /> | ||
19 | + </TabPanel> | ||
20 | + <TabPanel key="2" tab="利润分析" :forceRender="true"> | ||
21 | + <ProfitFormPanel ref="profitFormPanelRef" :id="id" /> | ||
22 | + </TabPanel> | ||
23 | + <TabPanel key="3" tab="项目报告书" :forceRender="true"> | ||
24 | + <ReportFormPanel ref="ReportFormPanelRef" /> | ||
25 | + </TabPanel> | ||
26 | + <TabPanel key="4" tab="跟单信息" :forceRender="true"> | ||
27 | + <TrackFormPanel ref="TrackFormPanelRef" /> | ||
28 | + </TabPanel> | ||
29 | + <TabPanel key="5" tab="质检信息" :forceRender="true"> | ||
30 | + <InspectionFormPanel ref="InspectionFormRef" /> | ||
31 | + </TabPanel> | ||
32 | + </Tabs> | ||
33 | + <!-- <BasicForm @register="registerForm" /> | ||
34 | + <BasicForm @register="registerForm" /> | ||
35 | + <BasicForm @register="registerForm" /> --> | ||
36 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | ||
37 | + | ||
38 | + <!-- <template #appendFooter> | ||
39 | + <a-button type="primary" @click="onGoCheckDetail"> 申请权限</a-button> | ||
40 | + </template> --> | ||
41 | + </BasicDrawer> | ||
42 | +</template> | ||
43 | +<script lang="ts"> | ||
44 | + import { computed, defineComponent, reactive, ref, toRaw, watch, watchEffect } from 'vue'; | ||
45 | + import { BasicForm, FormActionType, FormSchema, useForm } from '/@/components/Form/index'; | ||
46 | + import { orderCreate, orderUpdate, uploadImg } from '/@/api/project/order'; | ||
47 | + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | ||
48 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | ||
49 | + import { useOrderInfo } from '/@/hooks/component/order'; | ||
50 | + import { dateUtil } from '/@/utils/dateUtil'; | ||
51 | + import { FIELDS_REPORT_INFO } from './tableData'; | ||
52 | + import ProfitFormPanel from './component/ProfitFormPanel.vue'; | ||
53 | + import ReportFormPanel from './component/ReportFormPanel.vue'; | ||
54 | + import TrackFormPanel from './component/TrackFormPanel.vue'; | ||
55 | + import InspectionFormPanel from './component/InspectionFormPanel.vue'; | ||
56 | + | ||
57 | + import { Tabs } from 'ant-design-vue'; | ||
58 | + | ||
59 | + const TabPanel = Tabs.TabPane; | ||
60 | + | ||
61 | + export default defineComponent({ | ||
62 | + components: { | ||
63 | + BasicDrawer, | ||
64 | + BasicForm, | ||
65 | + Tabs, | ||
66 | + TabPanel, | ||
67 | + ProfitFormPanel, | ||
68 | + ReportFormPanel, | ||
69 | + TrackFormPanel, | ||
70 | + InspectionFormPanel, | ||
71 | + }, | ||
72 | + | ||
73 | + props: { | ||
74 | + detailData: { | ||
75 | + type: Object, | ||
76 | + }, | ||
77 | + onGoCheckDetail: { | ||
78 | + type: Function, | ||
79 | + }, | ||
80 | + }, | ||
81 | + emits: ['success'], | ||
82 | + setup(_, { emit }) { | ||
83 | + const orderStore = useOrderStoreWithOut(); | ||
84 | + const activeKey = ref('1'); | ||
85 | + const profitFormPanelRef = ref(null); | ||
86 | + const ReportFormPanelRef = ref(null); | ||
87 | + const TrackFormPanelRef = ref(null); | ||
88 | + const InspectionFormPanelRef = ref(null); | ||
89 | + | ||
90 | + const { | ||
91 | + customerCode, | ||
92 | + projectNo, | ||
93 | + productionDepartment, | ||
94 | + innerNo, | ||
95 | + poColor, | ||
96 | + cnColor, | ||
97 | + productStyle, | ||
98 | + outboundType, | ||
99 | + packetType, | ||
100 | + } = useOrderInfo(orderStore); | ||
101 | + | ||
102 | + const formRef = ref<FormActionType | null>(null); | ||
103 | + const id = ref(''); | ||
104 | + | ||
105 | + // const customerCode = computed(() => { | ||
106 | + // const dictInfo = orderStore.getDictInfo; | ||
107 | + // return map(dictInfo?.customerCode, transformDictInfo); | ||
108 | + // }); | ||
109 | + | ||
110 | + // const projectNo = computed(() => { | ||
111 | + // const dictInfo = orderStore.getDictInfo; | ||
112 | + // return map(dictInfo?.projectNo, transformDictInfo); | ||
113 | + // }); | ||
114 | + | ||
115 | + const picUrl = ref(''); | ||
116 | + let fields = reactive({ baseFields: {} }); | ||
117 | + const getDisable = (code) => { | ||
118 | + return code === 'LOCKED' && !!id.value; | ||
119 | + }; | ||
120 | + | ||
121 | + const schemas = computed(() => { | ||
122 | + return [ | ||
123 | + { | ||
124 | + field: 'baseInfo.customerCode', | ||
125 | + component: 'Select', | ||
126 | + label: '客户编码', | ||
127 | + rules: [{ required: true }], | ||
128 | + colProps: { | ||
129 | + span: 24, | ||
130 | + }, | ||
131 | + componentProps: { | ||
132 | + options: customerCode, | ||
133 | + disabled: getDisable(fields?.baseFields.customerCode), | ||
134 | + }, | ||
135 | + }, | ||
136 | + { | ||
137 | + field: 'baseInfo.projectNo', | ||
138 | + component: 'Select', | ||
139 | + componentProps: { | ||
140 | + options: projectNo, | ||
141 | + disabled: getDisable(fields?.baseFields?.projectNo), | ||
142 | + }, | ||
143 | + label: '项目号', | ||
144 | + rules: [{ required: true }], | ||
145 | + colProps: { | ||
146 | + span: 24, | ||
147 | + }, | ||
148 | + }, | ||
149 | + { | ||
150 | + field: 'baseInfo.productionDepartment', | ||
151 | + component: 'Select', | ||
152 | + label: '生产科', | ||
153 | + rules: [{ required: true }], | ||
154 | + colProps: { | ||
155 | + span: 24, | ||
156 | + }, | ||
157 | + componentProps: { | ||
158 | + options: productionDepartment, | ||
159 | + disabled: getDisable(fields?.baseFields?.productionDepartment), | ||
160 | + }, | ||
161 | + }, | ||
162 | + { | ||
163 | + field: 'baseInfo.innerNo', | ||
164 | + component: 'Select', | ||
165 | + label: '内部编号', | ||
166 | + rules: [{ required: true }], | ||
167 | + | ||
168 | + colProps: { | ||
169 | + span: 24, | ||
170 | + }, | ||
171 | + componentProps: { | ||
172 | + options: innerNo, | ||
173 | + disabled: getDisable(fields?.baseFields?.innerNo), | ||
174 | + }, | ||
175 | + }, | ||
176 | + { | ||
177 | + field: 'baseInfo.customerPo', | ||
178 | + component: 'Input', | ||
179 | + label: '客户po号', | ||
180 | + rules: [{ required: true }], | ||
181 | + componentProps: { | ||
182 | + disabled: getDisable(fields?.baseFields?.customerPo), | ||
183 | + }, | ||
184 | + colProps: { | ||
185 | + span: 24, | ||
186 | + }, | ||
187 | + }, | ||
188 | + { | ||
189 | + field: 'baseInfo.customerStyle', | ||
190 | + component: 'Input', | ||
191 | + label: '客户STYLE', | ||
192 | + rules: [{ required: true }], | ||
193 | + | ||
194 | + colProps: { | ||
195 | + span: 24, | ||
196 | + }, | ||
197 | + componentProps: { | ||
198 | + disabled: getDisable(fields?.baseFields?.customerStyle), | ||
199 | + }, | ||
200 | + }, | ||
201 | + { | ||
202 | + field: 'baseInfo.collection', | ||
203 | + component: 'Input', | ||
204 | + label: 'COLLECTION (style description)', | ||
205 | + rules: [{ required: true }], | ||
206 | + | ||
207 | + colProps: { | ||
208 | + span: 24, | ||
209 | + }, | ||
210 | + componentProps: { | ||
211 | + disabled: getDisable(fields?.baseFields?.collection), | ||
212 | + }, | ||
213 | + }, | ||
214 | + { | ||
215 | + field: 'baseInfo.poColor', | ||
216 | + component: 'Select', | ||
217 | + label: 'PO COLOR', | ||
218 | + rules: [{ required: true }], | ||
219 | + | ||
220 | + colProps: { | ||
221 | + span: 24, | ||
222 | + }, | ||
223 | + componentProps: { | ||
224 | + options: poColor, | ||
225 | + disabled: getDisable(fields?.baseFields?.poColor), | ||
226 | + }, | ||
227 | + }, | ||
228 | + { | ||
229 | + field: 'baseInfo.cnColor', | ||
230 | + component: 'Select', | ||
231 | + label: '颜色中文', | ||
232 | + rules: [{ required: true }], | ||
233 | + | ||
234 | + colProps: { | ||
235 | + span: 24, | ||
236 | + }, | ||
237 | + componentProps: { | ||
238 | + options: cnColor, | ||
239 | + disabled: getDisable(fields?.baseFields?.cnColor), | ||
240 | + }, | ||
241 | + }, | ||
242 | + { | ||
243 | + field: 'baseInfo.picUrl', | ||
244 | + component: 'FieldUpload', | ||
245 | + label: '图片', | ||
246 | + rules: [{ required: true }], | ||
247 | + colProps: { | ||
248 | + span: 24, | ||
249 | + }, | ||
250 | + componentProps: { | ||
251 | + imgUrl: picUrl, | ||
252 | + disabled: getDisable(fields?.baseFields?.picUrl), | ||
253 | + onChange: (res) => { | ||
254 | + if (res.file?.response?.data) picUrl.value = res.file?.response?.data; | ||
255 | + }, | ||
256 | + }, | ||
257 | + }, | ||
258 | + { | ||
259 | + field: 'baseInfo.productionComment', | ||
260 | + component: 'Input', | ||
261 | + rules: [{ required: true }], | ||
262 | + label: '生产要求', | ||
263 | + componentProps: { | ||
264 | + disabled: getDisable(fields?.baseFields?.productionComment), | ||
265 | + }, | ||
266 | + colProps: { | ||
267 | + span: 24, | ||
268 | + }, | ||
269 | + }, | ||
270 | + { | ||
271 | + field: 'baseInfo.orderCount', | ||
272 | + component: 'InputNumber', | ||
273 | + rules: [{ required: true }], | ||
274 | + label: '数量', | ||
275 | + colProps: { | ||
276 | + span: 24, | ||
277 | + }, | ||
278 | + componentProps: { | ||
279 | + disabled: getDisable(fields?.baseFields?.orderCount), | ||
280 | + }, | ||
281 | + }, | ||
282 | + { | ||
283 | + field: 'baseInfo.orderComposition', | ||
284 | + component: 'Input', | ||
285 | + rules: [{ required: true }], | ||
286 | + label: '订单成分', | ||
287 | + colProps: { | ||
288 | + span: 24, | ||
289 | + }, | ||
290 | + componentProps: { | ||
291 | + disabled: getDisable(fields?.baseFields?.orderComposition), | ||
292 | + }, | ||
293 | + }, | ||
294 | + { | ||
295 | + field: 'baseInfo.productStyle', | ||
296 | + component: 'Select', | ||
297 | + rules: [{ required: true }], | ||
298 | + label: '款式类型', | ||
299 | + colProps: { | ||
300 | + span: 24, | ||
301 | + }, | ||
302 | + componentProps: { | ||
303 | + options: productStyle, | ||
304 | + disabled: getDisable(fields?.baseFields?.productStyle), | ||
305 | + }, | ||
306 | + }, | ||
307 | + { | ||
308 | + field: 'baseInfo.productionDepartmentConsignTime', | ||
309 | + component: 'DatePicker', | ||
310 | + label: '生成科拖货时间', | ||
311 | + colProps: { | ||
312 | + span: 24, | ||
313 | + }, | ||
314 | + componentProps: { | ||
315 | + disabled: getDisable(fields?.baseFields?.productionDepartmentConsignTime), | ||
316 | + }, | ||
317 | + rules: [{ required: true }], | ||
318 | + }, | ||
319 | + { | ||
320 | + field: 'baseInfo.orderHodTime', | ||
321 | + component: 'DatePicker', | ||
322 | + label: '订单上HOD时间', | ||
323 | + colProps: { | ||
324 | + span: 24, | ||
325 | + }, | ||
326 | + componentProps: { | ||
327 | + disabled: getDisable(fields?.baseFields?.orderHodTime), | ||
328 | + }, | ||
329 | + rules: [{ required: true }], | ||
330 | + }, | ||
331 | + { | ||
332 | + field: 'baseInfo.outboundType', | ||
333 | + component: 'Select', | ||
334 | + label: '出库类型', | ||
335 | + colProps: { | ||
336 | + span: 24, | ||
337 | + }, | ||
338 | + rules: [{ required: true }], | ||
339 | + componentProps: { | ||
340 | + disabled: getDisable(fields?.baseFields?.outboundType), | ||
341 | + options: outboundType, | ||
342 | + }, | ||
343 | + }, | ||
344 | + { | ||
345 | + field: 'baseInfo.packetType', | ||
346 | + component: 'Select', | ||
347 | + label: '包装类型', | ||
348 | + colProps: { | ||
349 | + span: 24, | ||
350 | + }, | ||
351 | + rules: [{ required: true }], | ||
352 | + componentProps: { | ||
353 | + options: packetType, | ||
354 | + disabled: getDisable(fields?.baseFields?.packetType), | ||
355 | + }, | ||
356 | + }, | ||
357 | + ]; | ||
358 | + }); | ||
359 | + const reportSchemas = computed(() => { | ||
360 | + return FIELDS_REPORT_INFO.map((item) => { | ||
361 | + return { | ||
362 | + field: `reportInfo.${item.field}`, | ||
363 | + component: item.component, | ||
364 | + label: item.label, | ||
365 | + rules: [{ required: true }], | ||
366 | + colProps: { | ||
367 | + span: 24, | ||
368 | + }, | ||
369 | + componentProps: { | ||
370 | + disabled: getDisable(fields?.baseFields.customerCode), | ||
371 | + }, | ||
372 | + }; | ||
373 | + }); | ||
374 | + }); | ||
375 | + | ||
376 | + const [registerForm, { setFieldsValue, getFieldsValue, reload }] = useForm({ | ||
377 | + labelWidth: 120, | ||
378 | + schemas, | ||
379 | + showActionButtonGroup: false, | ||
380 | + actionColOptions: { | ||
381 | + span: 24, | ||
382 | + }, | ||
383 | + }); | ||
384 | + | ||
385 | + const [register, { closeDrawer }] = useDrawerInner((data) => { | ||
386 | + id.value = data.id; | ||
387 | + | ||
388 | + // 方式1 | ||
389 | + picUrl.value = data.picUrl; | ||
390 | + data.orderHodTime = data.orderHodTime ? dateUtil(data.orderHodTime) : null; | ||
391 | + data.productionDepartmentConsignTime = data.productionDepartmentConsignTime | ||
392 | + ? dateUtil(data.productionDepartmentConsignTime) | ||
393 | + : null; | ||
394 | + | ||
395 | + fields.baseFields = { | ||
396 | + ...fields.baseFields, | ||
397 | + ...data.lockFields.baseFields, | ||
398 | + }; | ||
399 | + | ||
400 | + if (id.value) { | ||
401 | + setFieldsValue({ | ||
402 | + baseInfo: { ...toRaw(data) }, | ||
403 | + }); | ||
404 | + | ||
405 | + profitFormPanelRef.value.fields.profitAnalysisInfo = | ||
406 | + { ...data.lockFields?.profitAnalysisFields } || {}; | ||
407 | + | ||
408 | + profitFormPanelRef?.value?.setFieldsValue({ | ||
409 | + ...toRaw(data.profitAnalysisInfo), | ||
410 | + profitAnalysisInfo: { ...toRaw(data.profitAnalysisInfo) }, | ||
411 | + }); | ||
412 | + } else { | ||
413 | + setFieldsValue({}); | ||
414 | + } | ||
415 | + }); | ||
416 | + | ||
417 | + const handleSubmit = async () => { | ||
418 | + const values = getFieldsValue() || {}; | ||
419 | + | ||
420 | + values.baseInfo = { | ||
421 | + ...values.baseInfo, | ||
422 | + picUrl: picUrl?.value || '', | ||
423 | + }; | ||
424 | + if (id.value) { | ||
425 | + values.orderId = id.value; | ||
426 | + | ||
427 | + await orderUpdate(values); | ||
428 | + } else { | ||
429 | + const v2 = profitFormPanelRef?.value?.getFieldsValue() || { profitAnalysisInfo: {} }; | ||
430 | + const v3 = ReportFormPanelRef?.value?.getFieldsValue() || { reportInfo: {} }; | ||
431 | + const v4 = TrackFormPanelRef?.value?.getFieldsValue() || { trackStageInfo: {} }; | ||
432 | + const v5 = InspectionFormPanelRef?.value?.getFieldsValue() || { inspectionStageInfo: {} }; | ||
433 | + | ||
434 | + values.profitAnalysisInfo = { ...v2.profitAnalysisInfo }; | ||
435 | + values.reportInfo = { ...v3.reportInfo }; | ||
436 | + values.trackStageInfo = { ...v4.trackStageInfo }; | ||
437 | + values.inspectionStageInfo = { ...v5.inspectionStageInfo }; | ||
438 | + await orderCreate(values); | ||
439 | + } | ||
440 | + closeDrawer(); | ||
441 | + emit('success', {}); | ||
442 | + }; | ||
443 | + return { | ||
444 | + id, | ||
445 | + profitFormPanelRef, | ||
446 | + ReportFormPanelRef, | ||
447 | + TrackFormPanelRef, | ||
448 | + InspectionFormPanelRef, | ||
449 | + activeKey, | ||
450 | + formRef, | ||
451 | + schemas, | ||
452 | + register, | ||
453 | + registerForm, | ||
454 | + handleSubmit, | ||
455 | + }; | ||
456 | + }, | ||
457 | + }); | ||
458 | +</script> | ||
459 | + | ||
460 | +<style> | ||
461 | + .ant-drawer { | ||
462 | + position: fixed; | ||
463 | + z-index: 9999; | ||
464 | + } | ||
465 | +</style> |
src/views/project/order/HistoryDetail.vue
0 → 100644
1 | +<template> | ||
2 | + <BasicDrawer | ||
3 | + v-bind="$attrs" | ||
4 | + title="操作记录" | ||
5 | + width="60%" | ||
6 | + :isDetail="true" | ||
7 | + :showDetailBack="false" | ||
8 | + okText="保存" | ||
9 | + > | ||
10 | + <Tabs animated> | ||
11 | + <template v-for="i in achieveList" :key="i.key"> | ||
12 | + <TabPane :tab="i.name" /> | ||
13 | + </template> | ||
14 | + </Tabs> | ||
15 | + <PageWrapper class="prefixCls"> | ||
16 | + <a-list :pagination="pagination" style="width: 100%"> | ||
17 | + <template v-for="item in list" :key="item.id"> | ||
18 | + <a-list-item class="list"> | ||
19 | + <a-list-item-meta> | ||
20 | + <template #avatar> | ||
21 | + <!-- <Icon class="icon" v-if="item.icon" :icon="item.icon" :color="item.color" /> --> | ||
22 | + </template> | ||
23 | + <template #title> | ||
24 | + <!-- <span>{{ item.title }}</span> --> | ||
25 | + <span>操作人</span> | ||
26 | + <!-- <div class="extra" v-if="item.extra"> | ||
27 | + {{ item.extra }} | ||
28 | + </div> --> | ||
29 | + </template> | ||
30 | + <template #description> | ||
31 | + <div class="description"> | ||
32 | + <!-- {{ item.description }} --> | ||
33 | + 干了什么 | ||
34 | + </div> | ||
35 | + <div class="info"> | ||
36 | + <div><span>操作时间</span>{{ item.datetime }}</div> | ||
37 | + </div> | ||
38 | + </template> | ||
39 | + </a-list-item-meta> | ||
40 | + </a-list-item> | ||
41 | + </template> | ||
42 | + </a-list> | ||
43 | + </PageWrapper> | ||
44 | + <!-- <template #titleToolbar> <a-button type="primary"> 申请编辑权限 </a-button></template> --> | ||
45 | + | ||
46 | + <template #appendFooter> | ||
47 | + <!-- <a-button type="primary" @click="onGoCheckDetail"> 申请权限</a-button> --> | ||
48 | + </template> | ||
49 | + </BasicDrawer> | ||
50 | +</template> | ||
51 | +<script lang="ts"> | ||
52 | + import { defineComponent } from 'vue'; | ||
53 | + import { Tabs, Progress, Row, Col, List } from 'ant-design-vue'; | ||
54 | + import { BasicForm, FormSchema, useForm } from '/@/components/Form/index'; | ||
55 | + import { cardList } from './data'; | ||
56 | + import { PageWrapper } from '/@/components/Page'; | ||
57 | + | ||
58 | + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | ||
59 | + | ||
60 | + const schemas: FormSchema[] = [ | ||
61 | + { | ||
62 | + field: '订单号', | ||
63 | + component: 'Input', | ||
64 | + label: '字段1', | ||
65 | + componentProps: { | ||
66 | + readonly: true, | ||
67 | + disabled: true, | ||
68 | + }, | ||
69 | + colProps: { | ||
70 | + span: 12, | ||
71 | + }, | ||
72 | + defaultValue: '111', | ||
73 | + }, | ||
74 | + { | ||
75 | + field: 'field2', | ||
76 | + component: 'Input', | ||
77 | + label: '字段2', | ||
78 | + colProps: { | ||
79 | + span: 12, | ||
80 | + }, | ||
81 | + }, | ||
82 | + ]; | ||
83 | + const achieveList = [ | ||
84 | + { | ||
85 | + key: '1', | ||
86 | + name: '编辑记录', | ||
87 | + }, | ||
88 | + { | ||
89 | + key: '2', | ||
90 | + name: '审批记录', | ||
91 | + }, | ||
92 | + ]; | ||
93 | + export default defineComponent({ | ||
94 | + components: { | ||
95 | + BasicDrawer, | ||
96 | + Tabs, | ||
97 | + [List.name]: List, | ||
98 | + [List.Item.name]: List.Item, | ||
99 | + AListItemMeta: List.Item.Meta, | ||
100 | + PageWrapper, | ||
101 | + }, | ||
102 | + props: { | ||
103 | + onGoCheckDetail: { | ||
104 | + type: Function, | ||
105 | + }, | ||
106 | + }, | ||
107 | + setup() { | ||
108 | + const [registerForm, { setFieldsValue }] = useForm({ | ||
109 | + labelWidth: 120, | ||
110 | + schemas, | ||
111 | + showActionButtonGroup: false, | ||
112 | + actionColOptions: { | ||
113 | + span: 24, | ||
114 | + }, | ||
115 | + }); | ||
116 | + const [register] = useDrawerInner((data) => { | ||
117 | + // 方式1 | ||
118 | + setFieldsValue({ | ||
119 | + field2: data.data, | ||
120 | + field1: data.info, | ||
121 | + }); | ||
122 | + }); | ||
123 | + return { | ||
124 | + register, | ||
125 | + schemas, | ||
126 | + registerForm, | ||
127 | + achieveList, | ||
128 | + list: cardList, | ||
129 | + prefixCls: 'account-center', | ||
130 | + | ||
131 | + pagination: { | ||
132 | + show: true, | ||
133 | + pageSize: 3, | ||
134 | + }, | ||
135 | + }; | ||
136 | + }, | ||
137 | + }); | ||
138 | +</script> | ||
139 | + | ||
140 | +<style lang="less" scoped> | ||
141 | + .account-center { | ||
142 | + &-bottom { | ||
143 | + margin: 0 16px 16px; | ||
144 | + padding: 10px; | ||
145 | + border-radius: 3px; | ||
146 | + background-color: @component-background; | ||
147 | + } | ||
148 | + } | ||
149 | +</style> |
src/views/project/order/ProfitAnalysis.vue
0 → 100644
1 | +<template> | ||
2 | + <BasicModal | ||
3 | + v-bind="$attrs" | ||
4 | + destroyOnClose | ||
5 | + @register="register" | ||
6 | + title="利润分析表" | ||
7 | + :helpMessage="['提示1', '提示2']" | ||
8 | + @visible-change="handleShow" | ||
9 | + :footer="null" | ||
10 | + > | ||
11 | + <!-- <template #insertFooter> | ||
12 | + <a-button type="primary" danger @click="setLines" :disabled="loading">点我更新内容</a-button> | ||
13 | + </template> --> | ||
14 | + <!-- <template v-if="loading"> | ||
15 | + <div class="empty-tips">加载中,稍等3秒……</div> | ||
16 | + </template> --> | ||
17 | + <Description | ||
18 | + class="mt-4" | ||
19 | + layout="vertical" | ||
20 | + :collapseOptions="{ canExpand: true, helpMessage: 'help me' }" | ||
21 | + :column="2" | ||
22 | + :data="mockData" | ||
23 | + :schema="schema" | ||
24 | + /> | ||
25 | + </BasicModal> | ||
26 | +</template> | ||
27 | +<script lang="ts"> | ||
28 | + import { defineComponent, ref, toRaw, watch } from 'vue'; | ||
29 | + import { BasicModal, useModalInner } from '/@/components/Modal'; | ||
30 | + import { Description, DescItem, useDescription } from '/@/components/Description/index'; | ||
31 | + import { orderAnalysis } from '/@/api/project/order'; | ||
32 | + | ||
33 | + export default defineComponent({ | ||
34 | + components: { BasicModal, Description }, | ||
35 | + setup() { | ||
36 | + const loading = ref(true); | ||
37 | + const lines = ref(10); | ||
38 | + const [register, { setModalProps, redoModalHeight }] = useModalInner(async (data) => { | ||
39 | + const orderIds = toRaw(data.data); | ||
40 | + const res = await orderAnalysis({ orderIds }); | ||
41 | + }); | ||
42 | + const mockData = { | ||
43 | + username: '100', | ||
44 | + nickName: '100', | ||
45 | + age: '123', | ||
46 | + phone: '1222', | ||
47 | + addr: '2332', | ||
48 | + }; | ||
49 | + | ||
50 | + const schema: DescItem[] = [ | ||
51 | + { | ||
52 | + field: 'username', | ||
53 | + label: '客户总金额', | ||
54 | + }, | ||
55 | + { | ||
56 | + field: 'nickName', | ||
57 | + label: '供应商总价', | ||
58 | + }, | ||
59 | + { | ||
60 | + field: 'phone', | ||
61 | + label: '包装费用', | ||
62 | + }, | ||
63 | + { | ||
64 | + field: 'addr', | ||
65 | + label: '总利润率', | ||
66 | + }, | ||
67 | + ]; | ||
68 | + | ||
69 | + watch( | ||
70 | + () => lines.value, | ||
71 | + () => { | ||
72 | + redoModalHeight(); | ||
73 | + }, | ||
74 | + ); | ||
75 | + | ||
76 | + function handleShow(visible: boolean) { | ||
77 | + if (visible) { | ||
78 | + loading.value = true; | ||
79 | + // setModalProps({ loading: true, confirmLoading: true }); | ||
80 | + setTimeout(() => { | ||
81 | + lines.value = Math.round(Math.random() * 30 + 5); | ||
82 | + loading.value = false; | ||
83 | + setModalProps({ loading: false, confirmLoading: false }); | ||
84 | + }, 3000); | ||
85 | + } | ||
86 | + } | ||
87 | + | ||
88 | + function setLines() { | ||
89 | + lines.value = Math.round(Math.random() * 20 + 10); | ||
90 | + } | ||
91 | + return { register, loading, handleShow, lines, setLines, mockData, schema }; | ||
92 | + }, | ||
93 | + }); | ||
94 | +</script> | ||
95 | +<style scoped> | ||
96 | + .empty-tips { | ||
97 | + height: 100px; | ||
98 | + line-height: 100px; | ||
99 | + text-align: center; | ||
100 | + } | ||
101 | +</style> |
src/views/project/order/component/InspectionFormPanel.vue
0 → 100644
1 | +<template> | ||
2 | + <BasicForm @register="registerForm" /> | ||
3 | +</template> | ||
4 | +<script lang="ts"> | ||
5 | + import { computed, defineComponent, reactive, ref, toRaw } from 'vue'; | ||
6 | + import { BasicForm, FormActionType, useForm } from '/@/components/Form/index'; | ||
7 | + import { useDrawerInner } from '/@/components/Drawer'; | ||
8 | + import { dateUtil } from '/@/utils/dateUtil'; | ||
9 | + import { FIELDS_INSPECTION_INFO } from '../tableData'; | ||
10 | + import { getDisable } from '/@/utils/project'; | ||
11 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | ||
12 | + | ||
13 | + import { useOrderInfo } from '/@/hooks/component/order'; | ||
14 | + | ||
15 | + export default defineComponent({ | ||
16 | + components: { BasicForm }, | ||
17 | + | ||
18 | + props: { | ||
19 | + detailData: { | ||
20 | + type: Object, | ||
21 | + }, | ||
22 | + onGoCheckDetail: { | ||
23 | + type: Function, | ||
24 | + }, | ||
25 | + }, | ||
26 | + emits: ['success'], | ||
27 | + setup(_, { emit }) { | ||
28 | + let fields = reactive({ baseFields: {}, profitAnalysisInfo: {} }); | ||
29 | + const orderStore = useOrderStoreWithOut(); | ||
30 | + | ||
31 | + const { midCheckResult, endCheckResult } = useOrderInfo(orderStore); | ||
32 | + | ||
33 | + const schemas = computed(() => { | ||
34 | + const options = { | ||
35 | + midCheckResult, | ||
36 | + endCheckResult, | ||
37 | + }; | ||
38 | + return FIELDS_INSPECTION_INFO.map((item) => ({ | ||
39 | + ...item, | ||
40 | + componentProps: { | ||
41 | + ...(item.component === 'Select' && { options: options[item.optionField] }), | ||
42 | + disabled: getDisable(`fields.${item.field}`), | ||
43 | + }, | ||
44 | + colProps: { | ||
45 | + span: 24, | ||
46 | + }, | ||
47 | + })); | ||
48 | + }); | ||
49 | + | ||
50 | + const [registerForm, { setFieldsValue, getFieldsValue, reload }] = useForm({ | ||
51 | + labelWidth: 120, | ||
52 | + schemas, | ||
53 | + showActionButtonGroup: false, | ||
54 | + actionColOptions: { | ||
55 | + span: 24, | ||
56 | + }, | ||
57 | + }); | ||
58 | + | ||
59 | + const [register, { closeDrawer }] = useDrawerInner((data) => { | ||
60 | + // 方式1 | ||
61 | + data.orderHodTime = data.orderHodTime ? dateUtil(data.orderHodTime) : null; | ||
62 | + data.productionDepartmentConsignTime = data.productionDepartmentConsignTime | ||
63 | + ? dateUtil(data.productionDepartmentConsignTime) | ||
64 | + : null; | ||
65 | + | ||
66 | + fields.baseFields = { | ||
67 | + ...fields.baseFields, | ||
68 | + ...data.lockFields.baseFields, | ||
69 | + }; | ||
70 | + | ||
71 | + if (id.value) { | ||
72 | + setFieldsValue({ | ||
73 | + ...toRaw(data), | ||
74 | + baseInfo: { ...toRaw(data) }, | ||
75 | + }); | ||
76 | + } else { | ||
77 | + setFieldsValue({}); | ||
78 | + } | ||
79 | + }); | ||
80 | + | ||
81 | + return { register, schemas, registerForm, getFieldsValue }; | ||
82 | + }, | ||
83 | + }); | ||
84 | +</script> |
src/views/project/order/component/ProfitFormPanel.vue
0 → 100644
1 | +<template> | ||
2 | + <BasicForm @register="registerForm" /> | ||
3 | +</template> | ||
4 | +<script lang="ts"> | ||
5 | + import { computed, defineComponent, reactive, ref, toRaw } from 'vue'; | ||
6 | + import { BasicForm, FormActionType, useForm } from '/@/components/Form/index'; | ||
7 | + import { orderCreate, orderUpdate } from '/@/api/project/order'; | ||
8 | + import { dateUtil } from '/@/utils/dateUtil'; | ||
9 | + import { FIELDS_PROFIT_INFO } from '../tableData'; | ||
10 | + import { getDisable } from '/@/utils/project'; | ||
11 | + import { get } from 'lodash-es'; | ||
12 | + | ||
13 | + export default defineComponent({ | ||
14 | + components: { BasicForm }, | ||
15 | + | ||
16 | + props: { | ||
17 | + detailData: { | ||
18 | + type: Object, | ||
19 | + }, | ||
20 | + onGoCheckDetail: { | ||
21 | + type: Function, | ||
22 | + }, | ||
23 | + id: { | ||
24 | + type: String, | ||
25 | + }, | ||
26 | + }, | ||
27 | + emits: ['success'], | ||
28 | + setup(props, { emit }) { | ||
29 | + console.log('%c [ props ]-29', 'font-size:13px; background:pink; color:#bf2c9f;', props); | ||
30 | + let fields = reactive({ profitAnalysisInfo: {} }); | ||
31 | + | ||
32 | + const schemas = computed(() => { | ||
33 | + return FIELDS_PROFIT_INFO.map((item) => { | ||
34 | + console.log( | ||
35 | + '%c [ ]-31', | ||
36 | + 'font-size:13px; background:pink; color:#bf2c9f;', | ||
37 | + get(fields, `${item.field}`), | ||
38 | + getDisable(get(fields, `${item.field}`), props.id), | ||
39 | + ); | ||
40 | + return { | ||
41 | + ...item, | ||
42 | + componentProps: { | ||
43 | + ...item.componentProps, | ||
44 | + disabled: getDisable(get(fields, `${item.field}`), props.id), | ||
45 | + }, | ||
46 | + colProps: { | ||
47 | + span: 24, | ||
48 | + }, | ||
49 | + }; | ||
50 | + }); | ||
51 | + }); | ||
52 | + | ||
53 | + const [registerForm, { setFieldsValue, getFieldsValue, reload }] = useForm({ | ||
54 | + labelWidth: 120, | ||
55 | + schemas, | ||
56 | + showActionButtonGroup: false, | ||
57 | + actionColOptions: { | ||
58 | + span: 24, | ||
59 | + }, | ||
60 | + }); | ||
61 | + return { fields, schemas, registerForm, getFieldsValue, setFieldsValue }; | ||
62 | + }, | ||
63 | + }); | ||
64 | +</script> |
src/views/project/order/component/ReportFormPanel.vue
0 → 100644
1 | +<template> | ||
2 | + <BasicForm @register="registerForm" /> | ||
3 | +</template> | ||
4 | +<script lang="ts"> | ||
5 | + import { computed, defineComponent, reactive, ref, toRaw } from 'vue'; | ||
6 | + import { BasicForm, FormActionType, useForm } from '/@/components/Form/index'; | ||
7 | + import { dateUtil } from '/@/utils/dateUtil'; | ||
8 | + import { FIELDS_REPORT_INFO } from '../tableData'; | ||
9 | + import { getDisable } from '/@/utils/project'; | ||
10 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | ||
11 | + import { useDrawerInner } from '/@/components/Drawer'; | ||
12 | + | ||
13 | + import { useOrderInfo } from '/@/hooks/component/order'; | ||
14 | + | ||
15 | + export default defineComponent({ | ||
16 | + components: { BasicForm }, | ||
17 | + | ||
18 | + props: { | ||
19 | + detailData: { | ||
20 | + type: Object, | ||
21 | + }, | ||
22 | + onGoCheckDetail: { | ||
23 | + type: Function, | ||
24 | + }, | ||
25 | + }, | ||
26 | + emits: ['success'], | ||
27 | + setup(_, { emit }) { | ||
28 | + let fields = reactive({ baseFields: {}, profitAnalysisInfo: {} }); | ||
29 | + const orderStore = useOrderStoreWithOut(); | ||
30 | + | ||
31 | + const { ideaSource, manualPreform } = useOrderInfo(orderStore); | ||
32 | + | ||
33 | + const schemas = computed(() => { | ||
34 | + const options = { | ||
35 | + ideaSource, | ||
36 | + manualPreform, | ||
37 | + }; | ||
38 | + return FIELDS_REPORT_INFO.map((item) => ({ | ||
39 | + ...item, | ||
40 | + componentProps: { | ||
41 | + ...(item.component === 'Select' && { options: options[item.optionField] }), | ||
42 | + disabled: getDisable(`fields.${item.field}`), | ||
43 | + }, | ||
44 | + colProps: { | ||
45 | + span: 24, | ||
46 | + }, | ||
47 | + })); | ||
48 | + }); | ||
49 | + | ||
50 | + const [registerForm, { setFieldsValue, getFieldsValue, reload }] = useForm({ | ||
51 | + labelWidth: 120, | ||
52 | + schemas, | ||
53 | + showActionButtonGroup: false, | ||
54 | + actionColOptions: { | ||
55 | + span: 24, | ||
56 | + }, | ||
57 | + }); | ||
58 | + | ||
59 | + const [register, { closeDrawer }] = useDrawerInner((data) => { | ||
60 | + // 方式1 | ||
61 | + data.orderHodTime = data.orderHodTime ? dateUtil(data.orderHodTime) : null; | ||
62 | + data.productionDepartmentConsignTime = data.productionDepartmentConsignTime | ||
63 | + ? dateUtil(data.productionDepartmentConsignTime) | ||
64 | + : null; | ||
65 | + | ||
66 | + fields.baseFields = { | ||
67 | + ...fields.baseFields, | ||
68 | + ...data.lockFields.baseFields, | ||
69 | + }; | ||
70 | + | ||
71 | + if (id.value) { | ||
72 | + setFieldsValue({ | ||
73 | + ...toRaw(data), | ||
74 | + baseInfo: { ...toRaw(data) }, | ||
75 | + }); | ||
76 | + } else { | ||
77 | + setFieldsValue({}); | ||
78 | + } | ||
79 | + }); | ||
80 | + | ||
81 | + return { register, schemas, registerForm, getFieldsValue }; | ||
82 | + }, | ||
83 | + }); | ||
84 | +</script> |
src/views/project/order/component/TrackFormPanel.vue
0 → 100644
1 | +<!-- 跟单信息 --> | ||
2 | +<template> | ||
3 | + <BasicForm @register="registerForm" /> | ||
4 | +</template> | ||
5 | +<script lang="ts"> | ||
6 | + import { computed, defineComponent, reactive, ref, toRaw } from 'vue'; | ||
7 | + import { BasicForm, FormActionType, useForm } from '/@/components/Form/index'; | ||
8 | + import { useDrawerInner } from '/@/components/Drawer'; | ||
9 | + import { dateUtil } from '/@/utils/dateUtil'; | ||
10 | + import { FIELDS_TRACK_STAGE_INFO } from '../tableData'; | ||
11 | + import { getDisable } from '/@/utils/project'; | ||
12 | + | ||
13 | + export default defineComponent({ | ||
14 | + components: { BasicForm }, | ||
15 | + | ||
16 | + props: { | ||
17 | + detailData: { | ||
18 | + type: Object, | ||
19 | + }, | ||
20 | + onGoCheckDetail: { | ||
21 | + type: Function, | ||
22 | + }, | ||
23 | + }, | ||
24 | + emits: ['success'], | ||
25 | + setup(_, { emit }) { | ||
26 | + let fields = reactive({ baseFields: {}, profitAnalysisInfo: {} }); | ||
27 | + | ||
28 | + const schemas = computed(() => { | ||
29 | + return FIELDS_TRACK_STAGE_INFO.map((item) => ({ | ||
30 | + ...item, | ||
31 | + componentProps: { | ||
32 | + ...item.componentProps, | ||
33 | + disabled: getDisable(`fields.${item.field}`), | ||
34 | + }, | ||
35 | + colProps: { | ||
36 | + span: 24, | ||
37 | + }, | ||
38 | + })); | ||
39 | + }); | ||
40 | + | ||
41 | + const [registerForm, { setFieldsValue, getFieldsValue, reload }] = useForm({ | ||
42 | + labelWidth: 120, | ||
43 | + schemas, | ||
44 | + showActionButtonGroup: false, | ||
45 | + actionColOptions: { | ||
46 | + span: 24, | ||
47 | + }, | ||
48 | + }); | ||
49 | + | ||
50 | + const [register, { closeDrawer }] = useDrawerInner((data) => { | ||
51 | + // 方式1 | ||
52 | + data.orderHodTime = data.orderHodTime ? dateUtil(data.orderHodTime) : null; | ||
53 | + data.productionDepartmentConsignTime = data.productionDepartmentConsignTime | ||
54 | + ? dateUtil(data.productionDepartmentConsignTime) | ||
55 | + : null; | ||
56 | + | ||
57 | + fields.baseFields = { | ||
58 | + ...fields.baseFields, | ||
59 | + ...data.lockFields.baseFields, | ||
60 | + }; | ||
61 | + | ||
62 | + if (id.value) { | ||
63 | + setFieldsValue({ | ||
64 | + ...toRaw(data), | ||
65 | + baseInfo: { ...toRaw(data) }, | ||
66 | + }); | ||
67 | + } else { | ||
68 | + setFieldsValue({}); | ||
69 | + } | ||
70 | + }); | ||
71 | + | ||
72 | + return { register, schemas, registerForm, getFieldsValue }; | ||
73 | + }, | ||
74 | + }); | ||
75 | +</script> |
src/views/project/order/data.tsx
0 → 100644
1 | +export const cardList = (() => { | ||
2 | + const result: any[] = []; | ||
3 | + for (let i = 0; i < 6; i++) { | ||
4 | + result.push({ | ||
5 | + id: i, | ||
6 | + title: 'Vben Admin', | ||
7 | + description: '基于Vue Next, TypeScript, Ant Design Vue实现的一套完整的企业级后台管理系统', | ||
8 | + datetime: '2020-11-26 17:39', | ||
9 | + extra: '编辑', | ||
10 | + icon: 'logos:vue', | ||
11 | + color: '#1890ff', | ||
12 | + author: 'Vben', | ||
13 | + percent: 20 * (i + 1), | ||
14 | + }); | ||
15 | + } | ||
16 | + return result; | ||
17 | +})(); |
src/views/project/order/index.vue
0 → 100644
1 | +<template> | ||
2 | + <div> | ||
3 | + <BasicTable @register="registerTable" bordered> | ||
4 | + <template #headerCell="{ column }"> | ||
5 | + <!-- <template v-if="column.key === 'address1'"> | ||
6 | + <span class="flex items-center justify-center"> 自定义字段列11 </span> | ||
7 | + </template> --> | ||
8 | + <template v-if="SELECT_FIELD_COLUMNS.includes(column.key)"> | ||
9 | + <span class="flex items-center justify-center"> | ||
10 | + {{ column.customTitle }} | ||
11 | + <FormOutlined class="ml-2 cursor-pointer" @click="handleFieldVisible(column)" /> | ||
12 | + </span> | ||
13 | + </template> | ||
14 | + <template v-else> | ||
15 | + <HeaderCell :column="column" /> | ||
16 | + </template> | ||
17 | + </template> | ||
18 | + <template #headerTop> | ||
19 | + <a-alert type="info" show-icon> | ||
20 | + <template #message> | ||
21 | + <template v-if="checkedKeys.length > 0"> | ||
22 | + <span>已选中{{ checkedKeys.length }}条记录(可跨页)</span> | ||
23 | + <a-button type="link" @click="checkedKeys = []" size="small">清空</a-button> | ||
24 | + </template> | ||
25 | + <template v-else> | ||
26 | + <span>未选中任何订单</span> | ||
27 | + </template> | ||
28 | + </template> | ||
29 | + </a-alert> | ||
30 | + </template> | ||
31 | + <template #bodyCell="{ column, record }"> | ||
32 | + <template v-if="column.key === 'action'"> | ||
33 | + <TableAction | ||
34 | + :actions="[ | ||
35 | + { | ||
36 | + label: '编辑', | ||
37 | + // icon: 'ic:outline-delete-outline', | ||
38 | + onClick: handleEdit.bind(null, record), | ||
39 | + }, | ||
40 | + { | ||
41 | + label: '申请权限', | ||
42 | + // icon: 'ic:outline-delete-outline', | ||
43 | + onClick: handleCheck.bind(null, record), | ||
44 | + }, | ||
45 | + ]" | ||
46 | + :dropDownActions="[ | ||
47 | + // { | ||
48 | + // label: '启用', | ||
49 | + // popConfirm: { | ||
50 | + // title: '是否启用?', | ||
51 | + // confirm: handleOpen.bind(null, record), | ||
52 | + // }, | ||
53 | + // }, | ||
54 | + { | ||
55 | + label: '历史记录', | ||
56 | + onClick: handleHistory.bind(null, record), | ||
57 | + }, | ||
58 | + ]" | ||
59 | + /> | ||
60 | + </template> | ||
61 | + <template v-if="column.key === 'picUrl'"> | ||
62 | + <img | ||
63 | + :width="100" | ||
64 | + :height="100" | ||
65 | + :src="record.picUrl" | ||
66 | + :key="record.picUrl" | ||
67 | + @click="handlePreview(record.picUrl)" | ||
68 | + /> | ||
69 | + </template> | ||
70 | + </template> | ||
71 | + | ||
72 | + <template #toolbar> | ||
73 | + <a-button type="primary" @click="handleExport">导出</a-button> | ||
74 | + <a-button type="primary" @click="handleProfitModal" :disabled="!checkedKeys.length" | ||
75 | + >分析利润</a-button | ||
76 | + > | ||
77 | + <a-button type="primary" @click="handleAdd">创建订单</a-button> | ||
78 | + </template> | ||
79 | + </BasicTable> | ||
80 | + <FormDetail | ||
81 | + @register="formDetailRegister" | ||
82 | + :onGoCheckDetail="handleGoCheckDetail" | ||
83 | + @success="handleFormSuccess" | ||
84 | + /> | ||
85 | + <ProfitAnalysis @register="profitModalRegister" /> | ||
86 | + <CheckDetail @register="checkModalRegister" :onGoFormDetail="handleGoFormDetail" /> | ||
87 | + <HistoryDetail @register="historyDetailRegister" /> | ||
88 | + <FieldDetail @register="fieldDetailRegister" /> | ||
89 | + </div> | ||
90 | +</template> | ||
91 | +<script lang="ts"> | ||
92 | + import { defineComponent, onMounted, ref, toRaw, toRefs, unref } from 'vue'; | ||
93 | + import { BasicTable, useTable, TableAction } from '/@/components/Table'; | ||
94 | + import { FormOutlined } from '@ant-design/icons-vue'; | ||
95 | + import HeaderCell from '/@/components/Table/src/components/HeaderCell.vue'; | ||
96 | + import { Alert } from 'ant-design-vue'; | ||
97 | + import { SELECT_FIELD_COLUMNS } from './selectData'; | ||
98 | + | ||
99 | + import { useDrawer } from '/@/components/Drawer'; | ||
100 | + import ProfitAnalysis from './ProfitAnalysis.vue'; | ||
101 | + import { useModal } from '/@/components/Modal'; | ||
102 | + | ||
103 | + import { getFormConfig, getOrderColumns } from './tableData'; | ||
104 | + import FormDetail from './FormDetail.vue'; | ||
105 | + import CheckDetail from './CheckDetail.vue'; | ||
106 | + import HistoryDetail from './HistoryDetail.vue'; | ||
107 | + import FieldDetail from './FieldDetail.vue'; | ||
108 | + import { createImgPreview } from '/@/components/Preview/index'; | ||
109 | + import { getOrderList, orderExport } from '/@/api/project/order'; | ||
110 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | ||
111 | + | ||
112 | + const orderStore = useOrderStoreWithOut(); | ||
113 | + | ||
114 | + export default defineComponent({ | ||
115 | + components: { | ||
116 | + HeaderCell, | ||
117 | + BasicTable, | ||
118 | + AAlert: Alert, | ||
119 | + TableAction, | ||
120 | + FormDetail, | ||
121 | + ProfitAnalysis, | ||
122 | + FormOutlined, | ||
123 | + CheckDetail, | ||
124 | + HistoryDetail, | ||
125 | + FieldDetail, | ||
126 | + }, | ||
127 | + setup() { | ||
128 | + const checkedKeys = ref<Array<string | number>>([]); | ||
129 | + const [profitModalRegister, { openModal: openProfitModal }] = useModal(); | ||
130 | + const tooltipVisible = ref(false); | ||
131 | + const [formDetailRegister, { openDrawer: openFormDetailDrawer }] = useDrawer(); | ||
132 | + const [historyDetailRegister, { openDrawer: openHistoryDetailDrawer }] = useDrawer(); | ||
133 | + const [fieldDetailRegister, { openDrawer: openFieldDetailDrawer }] = useDrawer(); | ||
134 | + | ||
135 | + const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); | ||
136 | + onMounted(async () => { | ||
137 | + await orderStore.getDict(); | ||
138 | + }); | ||
139 | + | ||
140 | + const [registerTable, { getForm, reload }] = useTable({ | ||
141 | + api: getOrderList, | ||
142 | + title: '订单列表', | ||
143 | + // api: () => { | ||
144 | + // const res = demoListApi(); | ||
145 | + // total.value = res.data.total; | ||
146 | + // return res; | ||
147 | + // // }, | ||
148 | + // pagination: { | ||
149 | + // total: 30, | ||
150 | + // }, | ||
151 | + pagination: { | ||
152 | + total: 60, | ||
153 | + }, | ||
154 | + columns: getOrderColumns(), | ||
155 | + useSearchForm: true, | ||
156 | + formConfig: getFormConfig(), | ||
157 | + showTableSetting: true, | ||
158 | + // tableSetting: { fullScreen: true }, | ||
159 | + showIndexColumn: false, | ||
160 | + rowKey: 'id', | ||
161 | + rowSelection: { | ||
162 | + type: 'checkbox', | ||
163 | + selectedRowKeys: checkedKeys, | ||
164 | + onSelect: onSelect, | ||
165 | + onSelectAll: onSelectAll, | ||
166 | + }, | ||
167 | + actionColumn: { | ||
168 | + width: 160, | ||
169 | + title: 'Action', | ||
170 | + dataIndex: 'action', | ||
171 | + // slots: { customRender: 'action' }, | ||
172 | + }, | ||
173 | + }); | ||
174 | + | ||
175 | + function getFormValues() { | ||
176 | + console.log(getForm().getFieldsValue()); | ||
177 | + } | ||
178 | + | ||
179 | + function onSelect(record, selected) { | ||
180 | + if (selected) { | ||
181 | + checkedKeys.value = [...checkedKeys.value, record.id]; | ||
182 | + } else { | ||
183 | + checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id); | ||
184 | + } | ||
185 | + } | ||
186 | + function onSelectAll(selected, selectedRows, changeRows) { | ||
187 | + const changeIds = changeRows.map((item) => item.id); | ||
188 | + if (selected) { | ||
189 | + checkedKeys.value = [...checkedKeys.value, ...changeIds]; | ||
190 | + } else { | ||
191 | + checkedKeys.value = checkedKeys.value.filter((id) => { | ||
192 | + return !changeIds.includes(id); | ||
193 | + }); | ||
194 | + } | ||
195 | + } | ||
196 | + | ||
197 | + function handleEdit(record, e) { | ||
198 | + openFormDetailDrawer(true, { ...toRaw(record) }); | ||
199 | + e?.stopPropagation(); | ||
200 | + return false; | ||
201 | + } | ||
202 | + | ||
203 | + function handleAdd() { | ||
204 | + openFormDetailDrawer(true); | ||
205 | + } | ||
206 | + | ||
207 | + function handleCheck(record, e) { | ||
208 | + openCheckDetailDrawer(true, record); | ||
209 | + e?.stopPropagation(); | ||
210 | + return false; | ||
211 | + } | ||
212 | + | ||
213 | + function handleHistory(record, e) { | ||
214 | + openHistoryDetailDrawer(true, record); | ||
215 | + e?.stopPropagation(); | ||
216 | + return false; | ||
217 | + } | ||
218 | + | ||
219 | + function handleOpen(record: Recordable) {} | ||
220 | + | ||
221 | + function handleProfitModal() { | ||
222 | + openProfitModal(true, { | ||
223 | + data: checkedKeys.value, | ||
224 | + }); | ||
225 | + } | ||
226 | + | ||
227 | + function handleFieldVisible(record) { | ||
228 | + openFieldDetailDrawer(true, record); | ||
229 | + } | ||
230 | + | ||
231 | + function handleGoCheckDetail() { | ||
232 | + openCheckDetailDrawer(true); | ||
233 | + openFormDetailDrawer(false); | ||
234 | + } | ||
235 | + | ||
236 | + function handleGoFormDetail() { | ||
237 | + openCheckDetailDrawer(false); | ||
238 | + openFormDetailDrawer(true); | ||
239 | + } | ||
240 | + | ||
241 | + function handlePreview(url, e) { | ||
242 | + createImgPreview({ imageList: [url], defaultWidth: 500 }); | ||
243 | + // e?.stopPropagation(); | ||
244 | + // e?.preventDefault(); | ||
245 | + return false; | ||
246 | + } | ||
247 | + | ||
248 | + async function handleExport() { | ||
249 | + await orderExport(); | ||
250 | + } | ||
251 | + | ||
252 | + const handleFormSuccess = () => { | ||
253 | + reload(); | ||
254 | + }; | ||
255 | + | ||
256 | + return { | ||
257 | + fieldDetailRegister, | ||
258 | + profitModalRegister, | ||
259 | + historyDetailRegister, | ||
260 | + formDetailRegister, | ||
261 | + handleProfitModal, | ||
262 | + registerTable, | ||
263 | + getFormValues, | ||
264 | + checkedKeys, | ||
265 | + onSelect, | ||
266 | + handleEdit, | ||
267 | + handleCheck, | ||
268 | + handleOpen, | ||
269 | + onSelectAll, | ||
270 | + tooltipVisible, | ||
271 | + handleFieldVisible, | ||
272 | + checkModalRegister, | ||
273 | + handleGoCheckDetail, | ||
274 | + handleGoFormDetail, | ||
275 | + handleHistory, | ||
276 | + handleAdd, | ||
277 | + SELECT_FIELD_COLUMNS, | ||
278 | + createImgPreview, | ||
279 | + handleExport, | ||
280 | + handlePreview, | ||
281 | + handleFormSuccess, | ||
282 | + }; | ||
283 | + }, | ||
284 | + }); | ||
285 | +</script> | ||
286 | + | ||
287 | +<style> | ||
288 | + .ant-table-thead th, | ||
289 | + .ant-table-tbody td { | ||
290 | + padding: 0; | ||
291 | + white-space: pre-wrap; | ||
292 | + } | ||
293 | + | ||
294 | + .ant-table-cell img { | ||
295 | + width: 100px; | ||
296 | + height: 100px; | ||
297 | + } | ||
298 | +</style> |
src/views/project/order/selectData.tsx
0 → 100644