Commit 718c52c3faff473133d57d0e70922ac587e720ee
1 parent
eea414e0
feat: update
Showing
83 changed files
with
4267 additions
and
388 deletions
.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 | 20 | \ No newline at end of file | ... | ... |
mock/demo/table-demo.ts
... | ... | @@ -37,6 +37,14 @@ const demoList = (() => { |
37 | 37 | time: `@time('HH:mm')`, |
38 | 38 | 'no|100000-10000000': 100000, |
39 | 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 | 50 | return result; | ... | ... |
mock/sys/user.ts
package.json
... | ... | @@ -17,7 +17,7 @@ |
17 | 17 | }, |
18 | 18 | "scripts": { |
19 | 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 | 21 | "build:analyze": "cross-env NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build --mode analyze", |
22 | 22 | "build:docker": "vite build --mode docker", |
23 | 23 | "build:no-cache": "pnpm clean:cache && npm run build", |
... | ... | @@ -151,4 +151,4 @@ |
151 | 151 | "node": ">=16.15.1", |
152 | 152 | "pnpm": ">=8.1.0" |
153 | 153 | } |
154 | 154 | -} |
155 | +} | |
155 | 156 | \ No newline at end of file | ... | ... |
src/api/demo/system.ts
... | ... | @@ -13,17 +13,21 @@ import { |
13 | 13 | import { defHttp } from '/@/utils/http/axios'; |
14 | 14 | |
15 | 15 | enum Api { |
16 | - AccountList = '/system/getAccountList', | |
16 | + AccountList = '/order/erp/users/list_by_page', | |
17 | 17 | IsAccountExist = '/system/accountExist', |
18 | 18 | DeptList = '/system/getDeptList', |
19 | 19 | setRoleStatus = '/system/setRoleStatus', |
20 | 20 | MenuList = '/system/getMenuList', |
21 | - RolePageList = '/system/getRoleListByPage', | |
21 | + RolePageList = '/order/erp/roles/list_by_page', | |
22 | 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 | 32 | export const getDeptList = (params?: DeptListItem) => |
29 | 33 | defHttp.get<DeptListGetResultModel>({ url: Api.DeptList, params }); |
... | ... | @@ -31,8 +35,12 @@ export const getDeptList = (params?: DeptListItem) => |
31 | 35 | export const getMenuList = (params?: MenuParams) => |
32 | 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 | 45 | export const getAllRoleList = (params?: RoleParams) => |
38 | 46 | defHttp.get<RoleListGetResultModel>({ url: Api.GetAllRoleList, params }); | ... | ... |
src/api/demo/table.ts
1 | 1 | import { defHttp } from '/@/utils/http/axios'; |
2 | 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 | 6 | enum Api { |
5 | 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 | 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 | 21 | params, |
16 | 22 | headers: { |
17 | 23 | // @ts-ignore |
18 | 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
src/api/sys/user.ts
... | ... | @@ -4,7 +4,8 @@ import { LoginParams, LoginResultModel, GetUserInfoModel } from './model/userMod |
4 | 4 | import { ErrorMessageMode } from '/#/axios'; |
5 | 5 | |
6 | 6 | enum Api { |
7 | - Login = '/login', | |
7 | + // Login = '/login', | |
8 | + Login = '/order/erp/auth/login_by_pwd', | |
8 | 9 | Logout = '/logout', |
9 | 10 | GetUserInfo = '/getUserInfo', |
10 | 11 | GetPermCode = '/getPermCode', |
... | ... | @@ -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 | 117 | const getSchema = computed((): FormSchema[] => { |
118 | 118 | const schemas: FormSchema[] = unref(schemaRef) || (unref(getProps).schemas as any); |
119 | 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 | 126 | // handle date type |
122 | 127 | if (isHandleDateDefaultValue && defaultValue && dateItemType.includes(component)) { |
123 | - const valueFormat =componentProps ? componentProps['valueFormat'] : null; | |
128 | + const valueFormat = componentProps ? componentProps['valueFormat'] : null; | |
124 | 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 | 133 | } else { |
129 | 134 | const def: any[] = []; |
130 | 135 | defaultValue.forEach((item) => { | ... | ... |
src/components/Form/src/componentMap.ts
... | ... | @@ -29,6 +29,8 @@ import ApiTreeSelect from './components/ApiTreeSelect.vue'; |
29 | 29 | import ApiCascader from './components/ApiCascader.vue'; |
30 | 30 | import ApiTransfer from './components/ApiTransfer.vue'; |
31 | 31 | import { BasicUpload } from '/@/components/Upload'; |
32 | +import FieldUpload from '/@/components/FieldUpload'; | |
33 | + | |
32 | 34 | import { StrengthMeter } from '/@/components/StrengthMeter'; |
33 | 35 | import { IconPicker } from '/@/components/Icon'; |
34 | 36 | import { CountdownInput } from '/@/components/CountDown'; |
... | ... | @@ -71,6 +73,7 @@ componentMap.set('IconPicker', IconPicker); |
71 | 73 | componentMap.set('InputCountDown', CountdownInput); |
72 | 74 | |
73 | 75 | componentMap.set('Upload', BasicUpload); |
76 | +componentMap.set('FieldUpload', FieldUpload); | |
74 | 77 | componentMap.set('Divider', Divider); |
75 | 78 | |
76 | 79 | export function add(compName: ComponentType, component: Component) { | ... | ... |
src/components/Form/src/types/index.ts
src/components/Table/src/BasicTable.vue
src/components/Table/src/components/settings/ColumnSetting.vue
... | ... | @@ -12,7 +12,7 @@ |
12 | 12 | > |
13 | 13 | <template #title> |
14 | 14 | <div :class="`${prefixCls}__popover-title`"> |
15 | - <Checkbox | |
15 | + <!-- <Checkbox | |
16 | 16 | :indeterminate="indeterminate" |
17 | 17 | v-model:checked="checkAll" |
18 | 18 | @change="onCheckAllChange" |
... | ... | @@ -22,7 +22,7 @@ |
22 | 22 | |
23 | 23 | <Checkbox v-model:checked="checkIndex" @change="handleIndexCheckChange"> |
24 | 24 | {{ t('component.table.settingIndexColumnShow') }} |
25 | - </Checkbox> | |
25 | + </Checkbox> --> | |
26 | 26 | |
27 | 27 | <Checkbox |
28 | 28 | v-model:checked="checkSelect" |
... | ... | @@ -43,12 +43,12 @@ |
43 | 43 | <CheckboxGroup v-model:value="checkedList" @change="onChange" ref="columnListRef"> |
44 | 44 | <template v-for="item in plainOptions" :key="item.value"> |
45 | 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 | 47 | <Checkbox :value="item.value"> |
48 | 48 | {{ item.label }} |
49 | 49 | </Checkbox> |
50 | 50 | |
51 | - <Tooltip | |
51 | + <!-- <Tooltip | |
52 | 52 | placement="bottomLeft" |
53 | 53 | :mouseLeaveDelay="0.4" |
54 | 54 | :getPopupContainer="getPopupContainer" |
... | ... | @@ -88,7 +88,7 @@ |
88 | 88 | ]" |
89 | 89 | @click="handleColumnFixed(item, 'right')" |
90 | 90 | /> |
91 | - </Tooltip> | |
91 | + </Tooltip> --> | |
92 | 92 | </div> |
93 | 93 | </template> |
94 | 94 | </CheckboxGroup> |
... | ... | @@ -156,6 +156,7 @@ |
156 | 156 | setup(_, { emit, attrs }) { |
157 | 157 | const { t } = useI18n(); |
158 | 158 | const table = useTableContext(); |
159 | + const originColumns = getColumns(); // 配置的列 | |
159 | 160 | |
160 | 161 | const defaultRowSelection = omit(table.getRowSelection(), 'selectedRowKeys'); |
161 | 162 | let inited = false; |
... | ... | @@ -236,14 +237,37 @@ |
236 | 237 | const checkList = table |
237 | 238 | .getColumns({ ignoreAction: true, ignoreIndex: true }) |
238 | 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 | 255 | .filter(Boolean) as string[]; |
245 | - plainOptions.value = columns; | |
256 | + | |
257 | + // plainOptions.value = columns; | |
246 | 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 | 272 | table.setCacheColumns?.(columns); |
249 | 273 | !isReset && (cachePlainOptions.value = cloneDeep(columns)); |
... | ... | @@ -282,12 +306,22 @@ |
282 | 306 | const len = plainSortOptions.value.length; |
283 | 307 | state.checkAll = checkedList.length === len; |
284 | 308 | const sortList = unref(plainSortOptions).map((item) => item.value); |
309 | + | |
285 | 310 | checkedList.sort((prev, next) => { |
286 | 311 | return sortList.indexOf(prev) - sortList.indexOf(next); |
287 | 312 | }); |
288 | 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 | 325 | setColumns(checkedList); |
292 | 326 | } |
293 | 327 | |
... | ... | @@ -388,17 +422,63 @@ |
388 | 422 | function setColumns(columns: BasicColumn[] | string[]) { |
389 | 423 | isSetPropsFromThis = true; |
390 | 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 | 484 | function getPopupContainer() { |
... | ... | @@ -457,7 +537,7 @@ |
457 | 537 | display: flex; |
458 | 538 | align-items: center; |
459 | 539 | min-width: 100%; |
460 | - padding: 4px 16px 8px 0; | |
540 | + padding: 4px 16px 8px; | |
461 | 541 | |
462 | 542 | .ant-checkbox-wrapper { |
463 | 543 | width: 100%; | ... | ... |
src/components/Table/src/hooks/useDataSource.ts
... | ... | @@ -307,6 +307,7 @@ export function useDataSource( |
307 | 307 | const isArrayResult = Array.isArray(res); |
308 | 308 | |
309 | 309 | let resultItems: Recordable[] = isArrayResult ? res : get(res, listField); |
310 | + console.log('%c [ res ]-311', 'font-size:13px; background:pink; color:#bf2c9f;', res); | |
310 | 311 | const resultTotal: number = isArrayResult ? res.length : get(res, totalField); |
311 | 312 | |
312 | 313 | // 假如数据变少,导致总页数变少并小于当前选中页码,通过getPaginationRef获取到的页码是不正确的,需获取正确的页码再次执行 | ... | ... |
src/components/Upload/src/FileList.vue
... | ... | @@ -46,6 +46,12 @@ |
46 | 46 | </thead> |
47 | 47 | <tbody> |
48 | 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 | 55 | return ( |
50 | 56 | <tr class="file-table-tr" key={`${index + record.name || ''}`}> |
51 | 57 | {columnList.map((item) => { | ... | ... |
src/design/theme.less
src/enums/exceptionEnum.ts
src/enums/pageEnum.ts
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 | 11 | |
12 | 12 | <template #overlay> |
13 | 13 | <Menu @click="handleMenuClick"> |
14 | - <MenuItem | |
14 | + <!-- <MenuItem | |
15 | 15 | key="doc" |
16 | 16 | :text="t('layout.header.dropdownItemDoc')" |
17 | 17 | icon="ion:document-text-outline" |
... | ... | @@ -23,7 +23,7 @@ |
23 | 23 | key="lock" |
24 | 24 | :text="t('layout.header.tooltipLock')" |
25 | 25 | icon="ion:lock-closed-outline" |
26 | - /> | |
26 | + /> --> | |
27 | 27 | <MenuItem |
28 | 28 | key="logout" |
29 | 29 | :text="t('layout.header.dropdownItemLoginOut')" | ... | ... |
src/layouts/default/header/index.vue
... | ... | @@ -33,24 +33,24 @@ |
33 | 33 | |
34 | 34 | <!-- action --> |
35 | 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 | 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 | 42 | <FullScreen v-if="getShowFullScreen" :class="`${prefixCls}-action__item fullscreen-item`" /> |
43 | 43 | |
44 | - <AppLocalePicker | |
44 | + <!-- <AppLocalePicker | |
45 | 45 | v-if="getShowLocalePicker" |
46 | 46 | :reload="true" |
47 | 47 | :showText="false" |
48 | 48 | :class="`${prefixCls}-action__item`" |
49 | - /> | |
49 | + /> --> | |
50 | 50 | |
51 | 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 | 54 | </div> |
55 | 55 | </Header> |
56 | 56 | </template> | ... | ... |
src/layouts/default/index.vue
... | ... | @@ -3,9 +3,12 @@ |
3 | 3 | <LayoutFeatures /> |
4 | 4 | <LayoutHeader fixed v-if="getShowFullHeaderRef" /> |
5 | 5 | <Layout :class="[layoutClass]"> |
6 | + <!-- 左侧菜单 --> | |
6 | 7 | <LayoutSideBar v-if="getShowSidebar || getIsMobile" /> |
7 | 8 | <Layout :class="`${prefixCls}-main`"> |
9 | + <!-- 顶部header --> | |
8 | 10 | <LayoutMultipleHeader /> |
11 | + <!-- 内容区域 --> | |
9 | 12 | <LayoutContent /> |
10 | 13 | <LayoutFooter /> |
11 | 14 | </Layout> | ... | ... |
src/layouts/default/menu/index.vue
... | ... | @@ -140,7 +140,7 @@ |
140 | 140 | |
141 | 141 | function renderMenu() { |
142 | 142 | const { menus, ...menuProps } = unref(getCommonProps); |
143 | - // console.log(menus); | |
143 | + console.log(menus); | |
144 | 144 | if (!menus || !menus.length) return null; |
145 | 145 | return !props.isHorizontal ? ( |
146 | 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 | 67 | signUpFormTitle: '注册', |
68 | 68 | forgetFormTitle: '重置密码', |
69 | 69 | |
70 | - signInTitle: '开箱即用的中后台管理系统', | |
71 | - signInDesc: '输入您的个人详细信息开始使用!', | |
70 | + signInTitle: '订单管理系统', | |
71 | + signInDesc: '', | |
72 | 72 | policy: '我同意xxx隐私政策', |
73 | 73 | scanSign: `扫码后点击"确认",即可完成登录`, |
74 | 74 | ... | ... |
src/main.ts
src/router/guard/permissionGuard.ts
src/router/menus/index.ts
... | ... | @@ -63,10 +63,12 @@ async function getAsyncMenus() { |
63 | 63 | return show; |
64 | 64 | }); |
65 | 65 | }; |
66 | + | |
66 | 67 | if (isBackMode()) { |
67 | 68 | return menuFilter(permissionStore.getBackMenuList); |
68 | 69 | } |
69 | - if (isRouteMappingMode()) { | |
70 | + // if (isRouteMappingMode()) { | |
71 | + if (true) { | |
70 | 72 | return menuFilter(permissionStore.getFrontMenuList); |
71 | 73 | } |
72 | 74 | return staticMenus; | ... | ... |
src/router/routes/index.ts
... | ... | @@ -7,7 +7,7 @@ import { PageEnum } from '/@/enums/pageEnum'; |
7 | 7 | import { t } from '/@/hooks/web/useI18n'; |
8 | 8 | |
9 | 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 | 11 | const routeModuleList: AppRouteModule[] = []; |
12 | 12 | |
13 | 13 | // 加入到路由集合中 |
... | ... | @@ -40,6 +40,7 @@ export const LoginRoute: AppRouteRecordRaw = { |
40 | 40 | |
41 | 41 | // Basic routing without permission |
42 | 42 | // 未经许可的基本路由 |
43 | +// 没有权限要求,所有人都看得到 | |
43 | 44 | export const basicRoutes = [ |
44 | 45 | LoginRoute, |
45 | 46 | RootRoute, | ... | ... |
src/router/routes/modules/demo/system.ts
... | ... | @@ -21,7 +21,7 @@ const system: AppRouteModule = { |
21 | 21 | title: t('routes.demo.system.account'), |
22 | 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 | 27 | path: 'account_detail/:id', |
... | ... | @@ -33,7 +33,7 @@ const system: AppRouteModule = { |
33 | 33 | showMenu: false, |
34 | 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 | 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 | 4 | import { t } from '/@/hooks/web/useI18n'; |
5 | 5 | |
6 | 6 | const dashboard: AppRouteModule = { |
7 | - path: '/dashboard', | |
8 | - name: 'Dashboard', | |
7 | + path: '/home', | |
8 | + name: 'Analysis', | |
9 | 9 | component: LAYOUT, |
10 | - redirect: '/dashboard/analysis', | |
10 | + redirect: '/home', | |
11 | 11 | meta: { |
12 | - orderNo: 10, | |
12 | + hideChildrenInMenu: true, | |
13 | + orderNo: 1, | |
13 | 14 | icon: 'ion:grid-outline', |
14 | - title: t('routes.dashboard.dashboard'), | |
15 | + title: t('routes.dashboard.home'), | |
15 | 16 | }, |
16 | 17 | children: [ |
17 | 18 | { |
18 | - path: 'analysis', | |
19 | + path: '', | |
19 | 20 | name: 'Analysis', |
20 | 21 | component: () => import('/@/views/dashboard/analysis/index.vue'), |
21 | 22 | meta: { |
22 | 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 | 25 | settingButtonPosition: SettingButtonPositionEnum.AUTO, |
26 | 26 | |
27 | 27 | // Permission mode |
28 | + // permissionMode: PermissionModeEnum.ROLE, | |
28 | 29 | permissionMode: PermissionModeEnum.ROUTE_MAPPING, |
29 | 30 | |
30 | 31 | // Permission-related cache is stored in sessionStorage or localStorage | ... | ... |
src/store/modules/app.ts
... | ... | @@ -48,6 +48,11 @@ export const useAppStore = defineStore({ |
48 | 48 | }, |
49 | 49 | |
50 | 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 | 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 | 116 | |
117 | 117 | let routes: AppRouteRecordRaw[] = []; |
118 | 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 | 123 | // 路由过滤器 在 函数filter 作为回调传入遍历使用 |
122 | 124 | const routeFilter = (route: AppRouteRecordRaw) => { |
123 | 125 | const { meta } = route; |
... | ... | @@ -167,7 +169,6 @@ export const usePermissionStore = defineStore({ |
167 | 169 | } |
168 | 170 | return; |
169 | 171 | }; |
170 | - | |
171 | 172 | switch (permissionMode) { |
172 | 173 | // 角色权限 |
173 | 174 | case PermissionModeEnum.ROLE: |
... | ... | @@ -178,6 +179,8 @@ export const usePermissionStore = defineStore({ |
178 | 179 | // Convert multi-level routing to level 2 routing |
179 | 180 | // 将多级路由转换为 2 级路由 |
180 | 181 | routes = flatMultiLevelRoutes(routes); |
182 | + | |
183 | + routes = asyncRoutes; | |
181 | 184 | break; |
182 | 185 | |
183 | 186 | // 路由映射, 默认进入该case | ... | ... |
src/store/modules/user.ts
... | ... | @@ -7,7 +7,7 @@ import { PageEnum } from '/@/enums/pageEnum'; |
7 | 7 | import { ROLES_KEY, TOKEN_KEY, USER_INFO_KEY } from '/@/enums/cacheEnum'; |
8 | 8 | import { getAuthCache, setAuthCache } from '/@/utils/auth'; |
9 | 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 | 11 | import { useI18n } from '/@/hooks/web/useI18n'; |
12 | 12 | import { useMessage } from '/@/hooks/web/useMessage'; |
13 | 13 | import { router } from '/@/router'; |
... | ... | @@ -89,21 +89,24 @@ export const useUserStore = defineStore({ |
89 | 89 | }, |
90 | 90 | ): Promise<GetUserInfoModel | null> { |
91 | 91 | try { |
92 | - const { goHome = true, mode, ...loginParams } = params; | |
92 | + const { mode, ...loginParams } = params; | |
93 | 93 | const data = await loginApi(loginParams, mode); |
94 | - const { token } = data; | |
94 | + const { token, user } = data; | |
95 | 95 | |
96 | - // save token | |
97 | 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 | 102 | } catch (error) { |
100 | 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 | 107 | if (!this.getToken) return null; |
105 | 108 | // get user info |
106 | - const userInfo = await this.getUserInfoAction(); | |
109 | + // const userInfo = await this.getUserInfoAction(); | |
107 | 110 | |
108 | 111 | const sessionTimeout = this.sessionTimeout; |
109 | 112 | if (sessionTimeout) { |
... | ... | @@ -118,39 +121,40 @@ export const useUserStore = defineStore({ |
118 | 121 | router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw); |
119 | 122 | permissionStore.setDynamicAddedRoute(true); |
120 | 123 | } |
121 | - goHome && (await router.replace(userInfo?.homePath || PageEnum.BASE_HOME)); | |
124 | + await router.replace('home'); | |
122 | 125 | } |
123 | 126 | return userInfo; |
124 | 127 | }, |
125 | 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 | 144 | * @description: logout |
141 | 145 | */ |
142 | 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 | 154 | this.setToken(undefined); |
151 | 155 | this.setSessionTimeout(false); |
152 | 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 | 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 | 13 | import { isFunction } from '/@/utils/is'; |
14 | 14 | import { cloneDeep } from 'lodash-es'; |
15 | 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 | 20 | export * from './axiosTransform'; |
21 | +const { createMessage } = useMessage(); | |
18 | 22 | |
19 | 23 | /** |
20 | 24 | * @description: axios module |
... | ... | @@ -206,6 +210,7 @@ export class VAxios { |
206 | 210 | const transform = this.getTransform(); |
207 | 211 | |
208 | 212 | const { requestOptions } = this.options; |
213 | + const { message } = options || {}; | |
209 | 214 | |
210 | 215 | const opt: RequestOptions = Object.assign({}, requestOptions, options); |
211 | 216 | |
... | ... | @@ -218,9 +223,23 @@ export class VAxios { |
218 | 223 | conf = this.supportFormData(conf); |
219 | 224 | |
220 | 225 | return new Promise((resolve, reject) => { |
226 | + const userStore = useUserStoreWithOut(); | |
227 | + | |
221 | 228 | this.axiosInstance |
222 | 229 | .request<any, AxiosResponse<Result>>(conf) |
223 | 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 | 243 | if (transformResponseHook && isFunction(transformResponseHook)) { |
225 | 244 | try { |
226 | 245 | const ret = transformResponseHook(res, opt); |
... | ... | @@ -233,6 +252,7 @@ export class VAxios { |
233 | 252 | resolve(res as unknown as Promise<T>); |
234 | 253 | }) |
235 | 254 | .catch((e: Error | AxiosError) => { |
255 | + console.log('%c [ e ]-257', 'font-size:13px; background:pink; color:#bf2c9f;', e); | |
236 | 256 | if (requestCatchHook && isFunction(requestCatchHook)) { |
237 | 257 | reject(requestCatchHook(e, opt)); |
238 | 258 | return; | ... | ... |
src/utils/http/axios/index.ts
... | ... | @@ -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 | 50 | // return '[HTTP] Request has no return value'; |
51 | 51 | throw new Error(t('sys.api.apiRequestFailed')); |
52 | 52 | } |
53 | 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 | 58 | if (hasSuccess) { |
59 | 59 | let successMsg = message; |
60 | 60 | |
... | ... | @@ -67,13 +67,13 @@ const transform: AxiosTransform = { |
67 | 67 | } else if (options.successMessageMode === 'message') { |
68 | 68 | createMessage.success(successMsg); |
69 | 69 | } |
70 | - return result; | |
70 | + return data; | |
71 | 71 | } |
72 | 72 | |
73 | 73 | // 在此处根据自己项目的实际情况对不同的code执行不同的操作 |
74 | 74 | // 如果不希望中断当前请求,请return数据,否则直接抛出异常即可 |
75 | 75 | let timeoutMsg = ''; |
76 | - switch (code) { | |
76 | + switch (result) { | |
77 | 77 | case ResultEnum.TIMEOUT: |
78 | 78 | timeoutMsg = t('sys.api.timeoutMessage'); |
79 | 79 | const userStore = useUserStoreWithOut(); | ... | ... |
src/utils/project.ts
0 → 100644
src/views/dashboard/analysis/components/GrowCard.vue
... | ... | @@ -6,21 +6,21 @@ |
6 | 6 | :loading="loading" |
7 | 7 | :title="item.title" |
8 | 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 | 12 | <Tag :color="item.color">{{ item.action }}</Tag> |
13 | - </template> | |
13 | + </template> --> | |
14 | 14 | |
15 | 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 | 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 | 21 | <span>总{{ item.title }}</span> |
22 | 22 | <CountTo prefix="$" :startVal="1" :endVal="item.total" /> |
23 | - </div> | |
23 | + </div> --> | |
24 | 24 | </Card> |
25 | 25 | </template> |
26 | 26 | </div> |
... | ... | @@ -30,6 +30,56 @@ |
30 | 30 | import Icon from '@/components/Icon/Icon.vue'; |
31 | 31 | import { Tag, Card } from 'ant-design-vue'; |
32 | 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 | 84 | defineProps({ |
35 | 85 | loading: { | ... | ... |
src/views/dashboard/analysis/components/SiteAnalysis.vue
src/views/dashboard/analysis/components/VisitAnalysis.vue
1 | 1 | <template> |
2 | 2 | <div ref="chartRef" :style="{ height, width }"></div> |
3 | 3 | </template> |
4 | -<script lang="ts"> | |
5 | - import { basicProps } from './props'; | |
6 | -</script> | |
4 | + | |
7 | 5 | <script lang="ts" setup> |
8 | - import { onMounted, ref, Ref } from 'vue'; | |
6 | + import { ref, Ref, watchEffect } from 'vue'; | |
9 | 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 | 12 | defineProps({ |
12 | 13 | ...basicProps, |
13 | 14 | }); |
14 | 15 | const chartRef = ref<HTMLDivElement | null>(null); |
15 | 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 | 21 | setOptions({ |
19 | 22 | tooltip: { |
20 | 23 | trigger: 'axis', |
... | ... | @@ -28,7 +31,7 @@ |
28 | 31 | xAxis: { |
29 | 32 | type: 'category', |
30 | 33 | boundaryGap: false, |
31 | - data: [...new Array(18)].map((_item, index) => `${index + 6}:00`), | |
34 | + data: data?.x, | |
32 | 35 | splitLine: { |
33 | 36 | show: true, |
34 | 37 | lineStyle: { |
... | ... | @@ -44,7 +47,7 @@ |
44 | 47 | yAxis: [ |
45 | 48 | { |
46 | 49 | type: 'value', |
47 | - max: 80000, | |
50 | + max: maxY + 20, | |
48 | 51 | splitNumber: 4, |
49 | 52 | axisTick: { |
50 | 53 | show: false, |
... | ... | @@ -61,28 +64,25 @@ |
61 | 64 | series: [ |
62 | 65 | { |
63 | 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 | 68 | type: 'line', |
69 | 69 | areaStyle: {}, |
70 | 70 | itemStyle: { |
71 | 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 | 9 | |
10 | 10 | export const growCardList: GrowCardItem[] = [ |
11 | 11 | { |
12 | - title: '访问数', | |
12 | + title: '订单完成', | |
13 | 13 | icon: 'visit-count|svg', |
14 | 14 | value: 2000, |
15 | 15 | total: 120000, |
... | ... | @@ -17,7 +17,7 @@ export const growCardList: GrowCardItem[] = [ |
17 | 17 | action: '月', |
18 | 18 | }, |
19 | 19 | { |
20 | - title: '成交额', | |
20 | + title: '跟单和质检中', | |
21 | 21 | icon: 'total-sales|svg', |
22 | 22 | value: 20000, |
23 | 23 | total: 500000, |
... | ... | @@ -25,7 +25,7 @@ export const growCardList: GrowCardItem[] = [ |
25 | 25 | action: '月', |
26 | 26 | }, |
27 | 27 | { |
28 | - title: '下载数', | |
28 | + title: '利润分析表待审核', | |
29 | 29 | icon: 'download-count|svg', |
30 | 30 | value: 8000, |
31 | 31 | total: 120000, |
... | ... | @@ -33,7 +33,15 @@ export const growCardList: GrowCardItem[] = [ |
33 | 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 | 45 | icon: 'transaction|svg', |
38 | 46 | value: 5000, |
39 | 47 | total: 50000, | ... | ... |
src/views/dashboard/analysis/index.vue
... | ... | @@ -2,22 +2,26 @@ |
2 | 2 | <div class="p-4"> |
3 | 3 | <GrowCard :loading="loading" class="enter-y" /> |
4 | 4 | <SiteAnalysis class="!my-4 enter-y" :loading="loading" /> |
5 | - <div class="md:flex enter-y"> | |
5 | + <!-- <div class="md:flex enter-y"> | |
6 | 6 | <VisitRadar class="md:w-1/3 w-full" :loading="loading" /> |
7 | 7 | <VisitSource class="md:w-1/3 !md:mx-4 !md:my-0 !my-4 w-full" :loading="loading" /> |
8 | 8 | <SalesProductPie class="md:w-1/3 w-full" :loading="loading" /> |
9 | - </div> | |
9 | + </div> --> | |
10 | 10 | </div> |
11 | 11 | </template> |
12 | 12 | <script lang="ts" setup> |
13 | - import { ref } from 'vue'; | |
13 | + import { onMounted, ref } from 'vue'; | |
14 | 14 | import GrowCard from './components/GrowCard.vue'; |
15 | 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 | 18 | const loading = ref(true); |
19 | + const dataStore = useDataStoreWithOut(); | |
20 | + | |
21 | + onMounted(() => { | |
22 | + dataStore.getFetchData(); | |
23 | + dataStore.getFetchChartData(); | |
24 | + }); | |
21 | 25 | |
22 | 26 | setTimeout(() => { |
23 | 27 | loading.value = false; | ... | ... |
src/views/demo/permission/back/Btn.vue
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 | 8 | @ok="handleSubmit" |
9 | 9 | > |
10 | 10 | <BasicForm @register="registerForm"> |
11 | - <template #menu="{ model, field }"> | |
11 | + <!-- <template #menu="{ model, field }"> | |
12 | 12 | <BasicTree |
13 | 13 | v-model:value="model[field]" |
14 | 14 | :treeData="treeData" |
... | ... | @@ -17,7 +17,7 @@ |
17 | 17 | toolbar |
18 | 18 | title="菜单分配" |
19 | 19 | /> |
20 | - </template> | |
20 | + </template> --> | |
21 | 21 | </BasicForm> |
22 | 22 | </BasicDrawer> |
23 | 23 | </template> | ... | ... |
src/views/demo/system/role/role.data.ts
... | ... | @@ -7,60 +7,60 @@ import { useMessage } from '/@/hooks/web/useMessage'; |
7 | 7 | export const columns: BasicColumn[] = [ |
8 | 8 | { |
9 | 9 | title: '角色名称', |
10 | - dataIndex: 'roleName', | |
10 | + dataIndex: 'name', | |
11 | 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 | 56 | title: '创建时间', |
57 | 57 | dataIndex: 'createTime', |
58 | 58 | width: 180, |
59 | 59 | }, |
60 | - { | |
61 | - title: '备注', | |
62 | - dataIndex: 'remark', | |
63 | - }, | |
60 | + // { | |
61 | + // title: '备注', | |
62 | + // dataIndex: 'remark', | |
63 | + // }, | |
64 | 64 | ]; |
65 | 65 | |
66 | 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 | 4 | </BasicModal> |
5 | 5 | </template> |
6 | 6 | <script lang="ts"> |
7 | - import { defineComponent, ref, computed, unref } from 'vue'; | |
7 | + import { defineComponent, ref, computed, unref, toRaw } from 'vue'; | |
8 | 8 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
9 | 9 | import { BasicForm, useForm } from '/@/components/Form/index'; |
10 | 10 | import { accountFormSchema } from './account.data'; |
11 | - import { getDeptList } from '/@/api/demo/system'; | |
12 | 11 | |
13 | 12 | export default defineComponent({ |
14 | 13 | name: 'AccountModal', |
... | ... | @@ -18,7 +17,7 @@ |
18 | 17 | const isUpdate = ref(true); |
19 | 18 | const rowId = ref(''); |
20 | 19 | |
21 | - const [registerForm, { setFieldsValue, updateSchema, resetFields, validate }] = useForm({ | |
20 | + const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({ | |
22 | 21 | labelWidth: 100, |
23 | 22 | baseColProps: { span: 24 }, |
24 | 23 | schemas: accountFormSchema, |
... | ... | @@ -35,22 +34,11 @@ |
35 | 34 | |
36 | 35 | if (unref(isUpdate)) { |
37 | 36 | rowId.value = data.record.id; |
37 | + | |
38 | 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 | 44 | const getTitle = computed(() => (!unref(isUpdate) ? '新增账号' : '编辑账号')); |
... | ... | @@ -59,8 +47,7 @@ |
59 | 47 | try { |
60 | 48 | const values = await validate(); |
61 | 49 | setModalProps({ confirmLoading: true }); |
62 | - // TODO custom api | |
63 | - console.log(values); | |
50 | + | |
64 | 51 | closeModal(); |
65 | 52 | emit('success', { isUpdate: unref(isUpdate), values: { ...values, id: rowId.value } }); |
66 | 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 | 1 | <template> |
2 | 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 | 5 | <template #toolbar> |
6 | 6 | <a-button type="primary" @click="handleCreate">新增账号</a-button> |
7 | 7 | </template> |
... | ... | @@ -9,11 +9,11 @@ |
9 | 9 | <template v-if="column.key === 'action'"> |
10 | 10 | <TableAction |
11 | 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 | 18 | icon: 'clarity:note-edit-line', |
19 | 19 | tooltip: '编辑用户资料', |
... | ... | @@ -41,7 +41,7 @@ |
41 | 41 | import { defineComponent, reactive } from 'vue'; |
42 | 42 | |
43 | 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 | 45 | import { PageWrapper } from '/@/components/Page'; |
46 | 46 | import DeptTree from './DeptTree.vue'; |
47 | 47 | |
... | ... | @@ -57,10 +57,10 @@ |
57 | 57 | setup() { |
58 | 58 | const go = useGo(); |
59 | 59 | const [registerModal, { openModal }] = useModal(); |
60 | - const searchInfo = reactive<Recordable>({}); | |
60 | + const searchInfo = reactive({}); | |
61 | 61 | const [registerTable, { reload, updateTableDataRecord }] = useTable({ |
62 | 62 | title: '账号列表', |
63 | - api: getAccountList, | |
63 | + api: getUserList, | |
64 | 64 | rowKey: 'id', |
65 | 65 | columns, |
66 | 66 | formConfig: { |
... | ... | @@ -101,15 +101,14 @@ |
101 | 101 | console.log(record); |
102 | 102 | } |
103 | 103 | |
104 | - function handleSuccess({ isUpdate, values }) { | |
104 | + async function handleSuccess({ isUpdate, values }) { | |
105 | 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 | 107 | } else { |
111 | - reload(); | |
108 | + await userAdd({ ...values }); | |
112 | 109 | } |
110 | + | |
111 | + reload(); | |
113 | 112 | } |
114 | 113 | |
115 | 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
src/views/project/order/tableData.tsx
0 → 100644
1 | +import { useOrderInfo } from '/@/hooks/component/order'; | |
2 | +import { useOrderStoreWithOut } from '/@/store/modules/order'; | |
3 | + | |
4 | +export function getOrderColumns() { | |
5 | + return [ | |
6 | + { | |
7 | + title: '客户编码', | |
8 | + width: 150, | |
9 | + dataIndex: 'customerCode', | |
10 | + }, | |
11 | + { | |
12 | + title: '项目号', | |
13 | + width: 150, | |
14 | + dataIndex: 'projectNo', | |
15 | + }, | |
16 | + { | |
17 | + title: '生产科', | |
18 | + width: 150, | |
19 | + dataIndex: 'productionDepartment', | |
20 | + }, | |
21 | + { | |
22 | + title: '内部编号', | |
23 | + width: 150, | |
24 | + dataIndex: 'innerNo', | |
25 | + }, | |
26 | + { | |
27 | + title: '客户po号', | |
28 | + width: 150, | |
29 | + dataIndex: 'customerPo', | |
30 | + }, | |
31 | + | |
32 | + { | |
33 | + title: '客户STYLE', | |
34 | + width: 150, | |
35 | + dataIndex: 'customerStyle', | |
36 | + }, | |
37 | + | |
38 | + { | |
39 | + title: 'Modelo(REFERENCE)', | |
40 | + width: 150, | |
41 | + dataIndex: 'modeleLo', | |
42 | + }, | |
43 | + | |
44 | + { | |
45 | + title: 'COLLECTION (style description)', | |
46 | + width: 150, | |
47 | + dataIndex: 'collection', | |
48 | + }, | |
49 | + | |
50 | + { | |
51 | + title: 'PO COLOR', | |
52 | + width: 150, | |
53 | + dataIndex: 'poColor', | |
54 | + }, | |
55 | + { | |
56 | + title: '颜色中文', | |
57 | + width: 150, | |
58 | + dataIndex: 'cnColor', | |
59 | + }, | |
60 | + | |
61 | + { | |
62 | + title: '图片', | |
63 | + width: 150, | |
64 | + dataIndex: 'picUrl', | |
65 | + }, | |
66 | + { | |
67 | + title: '生产要求', | |
68 | + width: 150, | |
69 | + dataIndex: 'productionComment', | |
70 | + }, | |
71 | + { | |
72 | + title: '数量', | |
73 | + width: 150, | |
74 | + dataIndex: 'orderCount', | |
75 | + }, | |
76 | + { | |
77 | + title: '订单成分', | |
78 | + width: 150, | |
79 | + dataIndex: 'orderComposition', | |
80 | + }, | |
81 | + { | |
82 | + title: '款式类型', | |
83 | + width: 150, | |
84 | + dataIndex: 'productStyle', | |
85 | + }, | |
86 | + { | |
87 | + title: '生成科拖货时间', | |
88 | + width: 150, | |
89 | + dataIndex: 'productionDepartmentConsignTime', | |
90 | + }, | |
91 | + { | |
92 | + title: '订单上HOD时间', | |
93 | + width: 150, | |
94 | + dataIndex: 'orderHodTime', | |
95 | + }, | |
96 | + | |
97 | + { | |
98 | + title: '出库类型', | |
99 | + width: 150, | |
100 | + dataIndex: 'outboundType', | |
101 | + }, | |
102 | + { | |
103 | + title: '包装类型', | |
104 | + width: 150, | |
105 | + dataIndex: 'packetType', | |
106 | + }, | |
107 | + // { | |
108 | + // title: 'id', | |
109 | + // width: 150, | |
110 | + // dataIndex: 'id', | |
111 | + // }, | |
112 | + { | |
113 | + title: '项目完成报告信息', | |
114 | + width: 150, | |
115 | + children: [ | |
116 | + { | |
117 | + title: '想法来源', | |
118 | + width: 150, | |
119 | + dataIndex: 'ideaSource', | |
120 | + }, | |
121 | + { | |
122 | + title: '手工初型', | |
123 | + width: 150, | |
124 | + dataIndex: 'manualPreform', | |
125 | + }, | |
126 | + { | |
127 | + title: '想法和手工比例分配', | |
128 | + width: 150, | |
129 | + dataIndex: 'ideaManualRate', | |
130 | + }, | |
131 | + ], | |
132 | + }, | |
133 | + { | |
134 | + title: '利润分析信息', | |
135 | + width: 150, | |
136 | + dataIndex: 'profitAnalysisInfo', | |
137 | + children: [ | |
138 | + { | |
139 | + title: '客户单价', | |
140 | + width: 150, | |
141 | + dataIndex: 'profitAnalysisInfo.customerPrice', | |
142 | + customRender: (column) => { | |
143 | + const { record } = column || {}; | |
144 | + return record?.profitAnalysisInfo?.customerPrice; | |
145 | + }, | |
146 | + }, | |
147 | + { | |
148 | + title: '客户总价', | |
149 | + width: 150, | |
150 | + dataIndex: 'profitAnalysisInfo.customerTotalPrice', | |
151 | + customRender: (column) => { | |
152 | + const { record } = column || {}; | |
153 | + return record?.profitAnalysisInfo?.customerTotalPrice; | |
154 | + }, | |
155 | + }, | |
156 | + { | |
157 | + title: '生成科单价', | |
158 | + width: 150, | |
159 | + dataIndex: 'profitAnalysisInfo.productionDepartmentPrice', | |
160 | + customRender: (column) => { | |
161 | + const { record } = column || {}; | |
162 | + return record?.profitAnalysisInfo?.productionDepartmentPrice; | |
163 | + }, | |
164 | + }, | |
165 | + { | |
166 | + title: '包装费用', | |
167 | + width: 150, | |
168 | + dataIndex: 'profitAnalysisInfo.packetPrice', | |
169 | + customRender: (column) => { | |
170 | + const { record } = column || {}; | |
171 | + return record?.profitAnalysisInfo?.packetPrice; | |
172 | + }, | |
173 | + }, | |
174 | + { | |
175 | + title: '包装费用合计', | |
176 | + width: 150, | |
177 | + dataIndex: 'profitAnalysisInfo.packetTotalPrice', | |
178 | + customRender: (column) => { | |
179 | + const { record } = column || {}; | |
180 | + return record?.profitAnalysisInfo?.packetTotalPrice; | |
181 | + }, | |
182 | + }, | |
183 | + { | |
184 | + title: '汇率', | |
185 | + width: 150, | |
186 | + dataIndex: 'profitAnalysisInfo.exchangeRate', | |
187 | + customRender: (column) => { | |
188 | + const { record } = column || {}; | |
189 | + return record?.profitAnalysisInfo?.exchangeRate; | |
190 | + }, | |
191 | + }, | |
192 | + { | |
193 | + title: '利润率', | |
194 | + width: 150, | |
195 | + dataIndex: 'profitAnalysisInfo.profitRate', | |
196 | + customRender: (column) => { | |
197 | + const { record } = column || {}; | |
198 | + return record?.profitAnalysisInfo?.profitRate; | |
199 | + }, | |
200 | + }, | |
201 | + ], | |
202 | + }, | |
203 | + { | |
204 | + title: '跟单信息', | |
205 | + width: 150, | |
206 | + dataIndex: 'trackStageInfo', | |
207 | + children: [ | |
208 | + { | |
209 | + title: 'pp date', | |
210 | + width: 150, | |
211 | + dataIndex: 'ppTime', | |
212 | + }, | |
213 | + { | |
214 | + title: 'pp样品确认意见', | |
215 | + width: 150, | |
216 | + dataIndex: 'ppConfirmResult', | |
217 | + }, | |
218 | + { | |
219 | + title: 'EXTRA,SHOWROOM,ONLINE sample发送时间', | |
220 | + width: 250, | |
221 | + dataIndex: 'esoSampleSendTime', | |
222 | + }, | |
223 | + { | |
224 | + title: 'shippment sample 发送时间', | |
225 | + width: 150, | |
226 | + dataIndex: 'shippmentSampleSendTime', | |
227 | + }, | |
228 | + { | |
229 | + title: 'shipment sample确认意见', | |
230 | + width: 150, | |
231 | + dataIndex: 'shippmentSampleConfirmResult', | |
232 | + }, | |
233 | + { | |
234 | + title: '自测通过时间', | |
235 | + width: 150, | |
236 | + dataIndex: 'selfTestPassTime', | |
237 | + }, | |
238 | + { | |
239 | + title: 'Aitex测试发送时间', | |
240 | + width: 150, | |
241 | + dataIndex: 'aitexTestSendTime', | |
242 | + }, | |
243 | + { | |
244 | + title: 'Aitex测试结果', | |
245 | + width: 150, | |
246 | + dataIndex: 'aitexTestFinishResult', | |
247 | + }, | |
248 | + { | |
249 | + title: 'SGS测试发送时间', | |
250 | + width: 150, | |
251 | + dataIndex: 'sgsTestSendTime', | |
252 | + }, | |
253 | + { | |
254 | + title: 'SGS测试结果', | |
255 | + width: 150, | |
256 | + dataIndex: 'sgsTestFinishResult', | |
257 | + }, | |
258 | + | |
259 | + { | |
260 | + title: 'Barcode sticker arrival time', | |
261 | + width: 150, | |
262 | + dataIndex: 'barcodeStickerArrivalTime', | |
263 | + }, | |
264 | + { | |
265 | + title: '最晚包材到货时间', | |
266 | + width: 150, | |
267 | + dataIndex: 'latestArrivalTime', | |
268 | + }, | |
269 | + { | |
270 | + title: '最晚订舱+报关资料时间', | |
271 | + width: 150, | |
272 | + dataIndex: 'latestBkTime', | |
273 | + }, | |
274 | + ], | |
275 | + }, | |
276 | + { | |
277 | + title: '质检信息', | |
278 | + width: 150, | |
279 | + dataIndex: 'inspectionStageInfo', | |
280 | + children: [ | |
281 | + { | |
282 | + title: '中期验货申请时间', | |
283 | + width: 150, | |
284 | + dataIndex: 'endCheckApplyTime', | |
285 | + }, | |
286 | + { | |
287 | + title: '中期验货(功能性-拉力/跌落等、外观性-颜色/规格等、耐久性-烤厅等)', | |
288 | + width: 300, | |
289 | + dataIndex: 'midCheckComment', | |
290 | + }, | |
291 | + { | |
292 | + title: '中期验货结果PASS / FAIL', | |
293 | + width: 150, | |
294 | + dataIndex: 'midCheckResult', | |
295 | + }, | |
296 | + { | |
297 | + title: '尾期验货申请时间', | |
298 | + width: 150, | |
299 | + dataIndex: 'endCheckApplyTime', | |
300 | + }, | |
301 | + | |
302 | + { | |
303 | + title: 'midCheckApplyTime', | |
304 | + width: 150, | |
305 | + dataIndex: 'midCheckApplyTime', | |
306 | + }, | |
307 | + { | |
308 | + title: '长度/规格', | |
309 | + width: 150, | |
310 | + dataIndex: 'specification', | |
311 | + }, | |
312 | + { | |
313 | + title: '功能性不良', | |
314 | + width: 150, | |
315 | + dataIndex: 'functionality', | |
316 | + }, | |
317 | + { | |
318 | + title: '电镀不良', | |
319 | + width: 150, | |
320 | + dataIndex: 'electroplate', | |
321 | + }, | |
322 | + { | |
323 | + title: '不良1', | |
324 | + width: 150, | |
325 | + dataIndex: 'value1', | |
326 | + }, | |
327 | + | |
328 | + { | |
329 | + title: '不良2', | |
330 | + width: 150, | |
331 | + dataIndex: 'value2', | |
332 | + }, | |
333 | + { | |
334 | + title: '其他不良3', | |
335 | + width: 150, | |
336 | + dataIndex: 'value3', | |
337 | + }, | |
338 | + { | |
339 | + title: '包装:卡片、条码、箱贴,箱单 ', | |
340 | + width: 150, | |
341 | + dataIndex: 'boxPacket', | |
342 | + }, | |
343 | + { | |
344 | + title: '尾期验货结果PASS / FAIL', | |
345 | + width: 150, | |
346 | + dataIndex: 'endCheckResult', | |
347 | + }, | |
348 | + ], | |
349 | + }, | |
350 | + ]; | |
351 | +} | |
352 | +// 基本信息 | |
353 | +export const FIELDS_BASE_INFO = [ | |
354 | + { | |
355 | + field: 'customerCode', | |
356 | + component: 'Select', | |
357 | + label: '客户编码', | |
358 | + rules: [{ required: true }], | |
359 | + }, | |
360 | + { | |
361 | + field: 'projectNo', | |
362 | + component: 'Select', | |
363 | + label: '项目号', | |
364 | + rules: [{ required: true }], | |
365 | + }, | |
366 | + { | |
367 | + field: 'productionDepartment', | |
368 | + component: 'Select', | |
369 | + label: '生产科', | |
370 | + rules: [{ required: true }], | |
371 | + }, | |
372 | + { | |
373 | + field: 'innerNo', | |
374 | + component: 'Select', | |
375 | + label: '内部编号', | |
376 | + rules: [{ required: true }], | |
377 | + }, | |
378 | + { | |
379 | + field: 'customerPo', | |
380 | + component: 'Input', | |
381 | + label: '客户po号', | |
382 | + rules: [{ required: true }], | |
383 | + }, | |
384 | + { | |
385 | + field: 'customerStyle', | |
386 | + component: 'Input', | |
387 | + label: '客户STYLE', | |
388 | + rules: [{ required: true }], | |
389 | + }, | |
390 | + { | |
391 | + field: 'collection', | |
392 | + component: 'Input', | |
393 | + label: 'COLLECTION (style description)', | |
394 | + rules: [{ required: true }], | |
395 | + }, | |
396 | + { | |
397 | + field: 'poColor', | |
398 | + component: 'Select', | |
399 | + label: 'PO COLOR', | |
400 | + rules: [{ required: true }], | |
401 | + }, | |
402 | + { | |
403 | + field: 'cnColor', | |
404 | + component: 'Select', | |
405 | + label: '颜色中文', | |
406 | + rules: [{ required: true }], | |
407 | + }, | |
408 | + { | |
409 | + field: 'picUrl', | |
410 | + component: 'FieldUpload', | |
411 | + label: '图片', | |
412 | + rules: [{ required: true }], | |
413 | + }, | |
414 | + { | |
415 | + field: 'productionComment', | |
416 | + component: 'Input', | |
417 | + rules: [{ required: true }], | |
418 | + label: '生产要求', | |
419 | + }, | |
420 | + { | |
421 | + field: 'orderCount', | |
422 | + component: 'InputNumber', | |
423 | + rules: [{ required: true }], | |
424 | + label: '数量', | |
425 | + }, | |
426 | + { | |
427 | + field: 'orderComposition', | |
428 | + component: 'Input', | |
429 | + rules: [{ required: true }], | |
430 | + label: '订单成分', | |
431 | + }, | |
432 | + { | |
433 | + field: 'productStyle', | |
434 | + component: 'Select', | |
435 | + rules: [{ required: true }], | |
436 | + label: '款式类型', | |
437 | + }, | |
438 | + { | |
439 | + field: 'productionDepartmentConsignTime', | |
440 | + component: 'DatePicker', | |
441 | + label: '生成科拖货时间', | |
442 | + rules: [{ required: true }], | |
443 | + }, | |
444 | + { | |
445 | + field: 'orderHodTime', | |
446 | + component: 'DatePicker', | |
447 | + label: '订单上HOD时间', | |
448 | + | |
449 | + rules: [{ required: true }], | |
450 | + }, | |
451 | + { | |
452 | + field: 'outboundType', | |
453 | + component: 'Select', | |
454 | + label: '出库类型', | |
455 | + | |
456 | + rules: [{ required: true }], | |
457 | + }, | |
458 | + { | |
459 | + field: 'packetType', | |
460 | + component: 'Select', | |
461 | + label: '包装类型', | |
462 | + rules: [{ required: true }], | |
463 | + }, | |
464 | +]; | |
465 | + | |
466 | +//项目完成报告信息 | |
467 | +export const FIELDS_REPORT_INFO = [ | |
468 | + { | |
469 | + field: 'reportInfo.ideaSource', | |
470 | + component: 'Select', | |
471 | + optionField: 'ideaSource', | |
472 | + label: '想法来源', | |
473 | + rules: [{ required: true }], | |
474 | + }, | |
475 | + { | |
476 | + field: 'reportInfo.manualPreform', | |
477 | + component: 'Select', | |
478 | + optionField: 'manualPreform', | |
479 | + label: '手工初型', | |
480 | + rules: [{ required: true }], | |
481 | + }, | |
482 | + { | |
483 | + field: 'reportInfo.ideaManualRate', | |
484 | + component: 'Input', | |
485 | + label: '想法和手工比例分配', | |
486 | + rules: [{ required: true }], | |
487 | + }, | |
488 | +]; | |
489 | + | |
490 | +// 跟单信息 | |
491 | +export const FIELDS_TRACK_STAGE_INFO = [ | |
492 | + { | |
493 | + field: 'ppTime', | |
494 | + component: 'DatePicker', | |
495 | + label: 'pp date', | |
496 | + }, | |
497 | + { | |
498 | + field: 'ppConfirmResult', | |
499 | + component: 'Select', | |
500 | + componentProps: { | |
501 | + options: [ | |
502 | + { | |
503 | + label: 'ok', | |
504 | + value: 'ok', | |
505 | + }, | |
506 | + ], | |
507 | + }, | |
508 | + label: 'pp样品确认意见 ', | |
509 | + }, | |
510 | + { | |
511 | + field: 'esoSampleSendTime', | |
512 | + component: 'DatePicker', | |
513 | + label: 'EXTRA,SHOWROOM,ONLINE sample发送时间', | |
514 | + }, | |
515 | + { | |
516 | + field: 'shippmentSampleSendTime', | |
517 | + component: 'DatePicker', | |
518 | + label: 'shippment sample 发送时间', | |
519 | + }, | |
520 | + { | |
521 | + field: 'shippmentSampleConfirmResult', | |
522 | + component: 'Select', | |
523 | + componentProps: { | |
524 | + options: [ | |
525 | + { | |
526 | + label: 'ok', | |
527 | + value: 'ok', | |
528 | + }, | |
529 | + ], | |
530 | + }, | |
531 | + label: 'shipment sample确认意见', | |
532 | + }, | |
533 | + { | |
534 | + field: 'selfTestPassTime', | |
535 | + component: 'DatePicker', | |
536 | + label: '自测通过时间', | |
537 | + }, | |
538 | + { | |
539 | + field: 'aitexTestSendTime', | |
540 | + component: 'DatePicker', | |
541 | + label: 'Aitex测试发送时间', | |
542 | + }, | |
543 | + { | |
544 | + field: 'aitexTestFinishResult', | |
545 | + component: 'Select', | |
546 | + label: 'Aitex测试结果', | |
547 | + componentProps: { | |
548 | + options: [ | |
549 | + { | |
550 | + label: 'ok', | |
551 | + value: 'ok', | |
552 | + }, | |
553 | + ], | |
554 | + }, | |
555 | + }, | |
556 | + { | |
557 | + field: 'sgsTestSendTime', | |
558 | + component: 'DatePicker', | |
559 | + label: 'SGS测试发送时间', | |
560 | + }, | |
561 | + { | |
562 | + field: 'sgsTestFinishResult', | |
563 | + component: 'Select', | |
564 | + label: 'SGS测试结果', | |
565 | + componentProps: { | |
566 | + options: [ | |
567 | + { | |
568 | + label: 'ok', | |
569 | + value: 'ok', | |
570 | + }, | |
571 | + ], | |
572 | + }, | |
573 | + }, | |
574 | + { | |
575 | + field: 'barcodeStickerArrivalTime', | |
576 | + component: 'DatePicker', | |
577 | + label: 'Barcode sticker arrival time', | |
578 | + componentProps: { | |
579 | + options: [ | |
580 | + { | |
581 | + label: 'ok', | |
582 | + value: 'ok', | |
583 | + }, | |
584 | + ], | |
585 | + }, | |
586 | + }, | |
587 | + { | |
588 | + field: 'latestArrivalTime', | |
589 | + component: 'Select', | |
590 | + componentProps: { | |
591 | + options: [ | |
592 | + { | |
593 | + label: 'ok', | |
594 | + value: 'ok', | |
595 | + }, | |
596 | + ], | |
597 | + }, | |
598 | + label: '最晚包材到货时间', | |
599 | + }, | |
600 | + { | |
601 | + field: 'latestBkTime', | |
602 | + component: 'Select', | |
603 | + componentProps: { | |
604 | + options: [ | |
605 | + { | |
606 | + label: 'ok', | |
607 | + value: 'ok', | |
608 | + }, | |
609 | + ], | |
610 | + }, | |
611 | + label: '最晚订舱+报关资料时间', | |
612 | + }, | |
613 | +]; | |
614 | + | |
615 | +// 利润分析 | |
616 | +export const FIELDS_PROFIT_INFO = [ | |
617 | + { | |
618 | + field: 'profitAnalysisInfo.customerPrice', | |
619 | + component: 'InputNumber', | |
620 | + label: '客户单价', | |
621 | + rules: [{ required: true }], | |
622 | + }, | |
623 | + { | |
624 | + field: 'profitAnalysisInfo.customerCurrency', | |
625 | + component: 'Select', | |
626 | + label: '客户单价单位', | |
627 | + rules: [{ required: true }], | |
628 | + componentProps: { | |
629 | + options: [ | |
630 | + { label: '$', value: '$' }, | |
631 | + { label: '¥', value: '¥' }, | |
632 | + ], | |
633 | + }, | |
634 | + }, | |
635 | + { | |
636 | + field: 'profitAnalysisInfo.customerTotalPrice', | |
637 | + component: 'InputNumber', | |
638 | + label: '客户总价', | |
639 | + rules: [{ required: true }], | |
640 | + }, | |
641 | + { | |
642 | + field: 'profitAnalysisInfo.customerTotalCurrency', | |
643 | + component: 'Select', | |
644 | + label: '客户总价单位', | |
645 | + rules: [{ required: true }], | |
646 | + componentProps: { | |
647 | + options: [ | |
648 | + { label: '$', value: '$' }, | |
649 | + { label: '¥', value: '¥' }, | |
650 | + ], | |
651 | + }, | |
652 | + }, | |
653 | + { | |
654 | + field: 'profitAnalysisInfo.productionDepartmentPrice', | |
655 | + component: 'InputNumber', | |
656 | + label: '生成科单价¥', | |
657 | + rules: [{ required: true }], | |
658 | + }, | |
659 | + // { | |
660 | + // field: 'productionDepartmentPrice', | |
661 | + // component: 'InputNumber', | |
662 | + // label: '生成科总价¥', | |
663 | + // rules: [{ required: true }], | |
664 | + // }, | |
665 | + // { | |
666 | + // label: '包装费用$', | |
667 | + // component: 'InputNumber', | |
668 | + // field: 'packetPrice', | |
669 | + // rules: [{ required: true }], | |
670 | + // }, | |
671 | + { | |
672 | + label: '包装费用合计$', | |
673 | + component: 'InputNumber', | |
674 | + field: 'profitAnalysisInfo.packetTotalPrice', | |
675 | + rules: [{ required: true }], | |
676 | + }, | |
677 | + { | |
678 | + label: '包装费用合计单位', | |
679 | + component: 'Select', | |
680 | + field: 'profitAnalysisInfo.packetCurrency', | |
681 | + rules: [{ required: true }], | |
682 | + componentProps: { | |
683 | + options: [ | |
684 | + { label: '$', value: '$' }, | |
685 | + { label: '¥', value: '¥' }, | |
686 | + ], | |
687 | + }, | |
688 | + }, | |
689 | + { | |
690 | + label: '汇率', | |
691 | + component: 'InputNumber', | |
692 | + field: 'profitAnalysisInfo.exchangeRate', | |
693 | + rules: [{ required: true }], | |
694 | + }, | |
695 | + // { | |
696 | + // label: '利润率', | |
697 | + // component: 'Input', | |
698 | + // field: 'profitRate', | |
699 | + // rules: [{ required: true }], | |
700 | + // }, | |
701 | +]; | |
702 | + | |
703 | +//质量检测信息 | |
704 | +export const FIELDS_INSPECTION_INFO = [ | |
705 | + { | |
706 | + field: 'inspectionStageInfo.midCheckApplyTime', | |
707 | + component: 'DatePicker', | |
708 | + label: '中期验货申请时间', | |
709 | + rules: [{ required: true }], | |
710 | + }, | |
711 | + { | |
712 | + field: 'inspectionStageInfo.midCheckComment', | |
713 | + component: 'Input', | |
714 | + label: '中期验货(功能性-拉力/跌落等、外观性-颜色/规格等、耐久性-烤厅等)', | |
715 | + rules: [{ required: true }], | |
716 | + }, | |
717 | + { | |
718 | + field: 'inspectionStageInfo.midCheckResult', | |
719 | + component: 'Select', | |
720 | + optionField: 'midCheckResult', | |
721 | + | |
722 | + label: '中期验货结果PASS / FAIL', | |
723 | + rules: [{ required: true }], | |
724 | + }, | |
725 | + { | |
726 | + field: 'inspectionStageInfo.specification', | |
727 | + component: 'Input', | |
728 | + label: '长度/规格', | |
729 | + rules: [{ required: true }], | |
730 | + }, | |
731 | + { | |
732 | + field: 'inspectionStageInfo.functionality', | |
733 | + component: 'Input', | |
734 | + label: '功能性不良', | |
735 | + rules: [{ required: true }], | |
736 | + }, | |
737 | + { | |
738 | + field: 'inspectionStageInfo.electroplate', | |
739 | + component: 'Input', | |
740 | + label: '电镀不良', | |
741 | + rules: [{ required: true }], | |
742 | + }, | |
743 | + { | |
744 | + field: 'inspectionStageInfo.value1', | |
745 | + component: 'Input', | |
746 | + label: '不良1', | |
747 | + rules: [{ required: true }], | |
748 | + }, | |
749 | + { | |
750 | + field: 'inspectionStageInfo.value2', | |
751 | + component: 'Input', | |
752 | + label: '不良2', | |
753 | + rules: [{ required: true }], | |
754 | + }, | |
755 | + { | |
756 | + field: 'inspectionStageInfo.value3', | |
757 | + component: 'Input', | |
758 | + label: '其他不良3', | |
759 | + rules: [{ required: true }], | |
760 | + }, | |
761 | + { | |
762 | + field: 'inspectionStageInfo.boxPacket', | |
763 | + component: 'Input', | |
764 | + label: '包装:卡片、条码、箱贴,箱单', | |
765 | + rules: [{ required: true }], | |
766 | + }, | |
767 | + { | |
768 | + field: 'inspectionStageInfo.endCheckResult', | |
769 | + component: 'Select', | |
770 | + label: '尾期验货结果PASS / FAIL', | |
771 | + optionField: 'endCheckResult', | |
772 | + rules: [{ required: true }], | |
773 | + }, | |
774 | +]; | |
775 | + | |
776 | +export function getFormConfig(): Partial<FormProps> { | |
777 | + const orderStore = useOrderStoreWithOut(); | |
778 | + | |
779 | + const { | |
780 | + customerCode, | |
781 | + projectNo, | |
782 | + productionDepartment, | |
783 | + innerNo, | |
784 | + poColor, | |
785 | + cnColor, | |
786 | + productStyle, | |
787 | + outboundType, | |
788 | + packetType, | |
789 | + } = useOrderInfo(orderStore); | |
790 | + | |
791 | + return { | |
792 | + labelWidth: 100, | |
793 | + schemas: [ | |
794 | + { | |
795 | + field: `customerCode`, | |
796 | + label: `客户编码`, | |
797 | + component: 'Select', | |
798 | + colProps: { | |
799 | + xl: 12, | |
800 | + xxl: 8, | |
801 | + }, | |
802 | + componentProps: { | |
803 | + options: customerCode, | |
804 | + }, | |
805 | + }, | |
806 | + ], | |
807 | + }; | |
808 | +} | ... | ... |
src/views/sys/login/LoginForm.vue
... | ... | @@ -8,11 +8,12 @@ |
8 | 8 | v-show="getShow" |
9 | 9 | @keypress.enter="handleLogin" |
10 | 10 | > |
11 | - <FormItem name="account" class="enter-x"> | |
11 | + <FormItem name="userName" class="enter-x"> | |
12 | 12 | <Input |
13 | 13 | size="large" |
14 | - v-model:value="formData.account" | |
15 | - :placeholder="t('sys.login.userName')" | |
14 | + visibilityToggle | |
15 | + v-model:value="formData.userName" | |
16 | + placeholder="手机号" | |
16 | 17 | class="fix-auto-fill" |
17 | 18 | /> |
18 | 19 | </FormItem> |
... | ... | @@ -24,6 +25,17 @@ |
24 | 25 | :placeholder="t('sys.login.password')" |
25 | 26 | /> |
26 | 27 | </FormItem> |
28 | + <FormItem name="imgCaptchaCode" class="enter-x"> | |
29 | + <Input | |
30 | + size="large" | |
31 | + visibilityToggle | |
32 | + v-model:value="formData.imgCaptchaCode" | |
33 | + placeholder="请输入验证码" | |
34 | + /> | |
35 | + </FormItem> | |
36 | + <FormItem name="imgCaptchaCode" class="enter-x" label="验证码"> | |
37 | + <img :src="imgCaptcha" class="cursor-pointer" @click="getImgCaptcha" /> | |
38 | + </FormItem> | |
27 | 39 | |
28 | 40 | <ARow class="enter-x"> |
29 | 41 | <ACol :span="12"> |
... | ... | @@ -53,23 +65,23 @@ |
53 | 65 | </Button> --> |
54 | 66 | </FormItem> |
55 | 67 | <ARow class="enter-x"> |
56 | - <ACol :md="8" :xs="24"> | |
68 | + <!-- <ACol :md="8" :xs="24"> | |
57 | 69 | <Button block @click="setLoginState(LoginStateEnum.MOBILE)"> |
58 | 70 | {{ t('sys.login.mobileSignInFormTitle') }} |
59 | 71 | </Button> |
60 | - </ACol> | |
61 | - <ACol :md="8" :xs="24" class="!my-2 !md:my-0 xs:mx-0 md:mx-2"> | |
72 | + </ACol> --> | |
73 | + <!-- <ACol :md="8" :xs="24" class="!my-2 !md:my-0 xs:mx-0 md:mx-2"> | |
62 | 74 | <Button block @click="setLoginState(LoginStateEnum.QR_CODE)"> |
63 | 75 | {{ t('sys.login.qrSignInFormTitle') }} |
64 | 76 | </Button> |
65 | - </ACol> | |
66 | - <ACol :md="6" :xs="24"> | |
77 | + </ACol> --> | |
78 | + <!-- <ACol :md="6" :xs="24"> | |
67 | 79 | <Button block @click="setLoginState(LoginStateEnum.REGISTER)"> |
68 | 80 | {{ t('sys.login.registerButton') }} |
69 | 81 | </Button> |
70 | - </ACol> | |
82 | + </ACol> --> | |
71 | 83 | </ARow> |
72 | - | |
84 | + <!-- | |
73 | 85 | <Divider class="enter-x">{{ t('sys.login.otherSignIn') }}</Divider> |
74 | 86 | |
75 | 87 | <div class="flex justify-evenly enter-x" :class="`${prefixCls}-sign-in-way`"> |
... | ... | @@ -78,11 +90,11 @@ |
78 | 90 | <AlipayCircleFilled /> |
79 | 91 | <GoogleCircleFilled /> |
80 | 92 | <TwitterCircleFilled /> |
81 | - </div> | |
93 | + </div> --> | |
82 | 94 | </Form> |
83 | 95 | </template> |
84 | 96 | <script lang="ts" setup> |
85 | - import { reactive, ref, unref, computed } from 'vue'; | |
97 | + import { reactive, ref, unref, computed, onMounted } from 'vue'; | |
86 | 98 | |
87 | 99 | import { Checkbox, Form, Input, Row, Col, Button, Divider } from 'ant-design-vue'; |
88 | 100 | import { |
... | ... | @@ -117,14 +129,29 @@ |
117 | 129 | const formRef = ref(); |
118 | 130 | const loading = ref(false); |
119 | 131 | const rememberMe = ref(false); |
132 | + const imgCaptcha = ref(''); | |
133 | + const imgCaptchaUuid = ref(''); | |
120 | 134 | |
121 | 135 | const formData = reactive({ |
122 | - account: 'vben', | |
136 | + userName: 'admin', | |
123 | 137 | password: '123456', |
138 | + imgCaptchaCode: '', | |
139 | + imgCaptchaUuid: '', | |
124 | 140 | }); |
125 | 141 | |
126 | 142 | const { validForm } = useFormValid(formRef); |
127 | 143 | |
144 | + onMounted(async () => { | |
145 | + getImgCaptcha(); | |
146 | + }); | |
147 | + | |
148 | + const getImgCaptcha = async () => { | |
149 | + const data = await userStore.getImageCaptcha(); | |
150 | + console.log('%c [ data ]-151', 'font-size:13px; background:pink; color:#bf2c9f;', data); | |
151 | + imgCaptcha.value = data?.img; | |
152 | + imgCaptchaUuid.value = data?.uuid; | |
153 | + }; | |
154 | + | |
128 | 155 | //onKeyStroke('Enter', handleLogin); |
129 | 156 | |
130 | 157 | const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN); |
... | ... | @@ -136,7 +163,9 @@ |
136 | 163 | loading.value = true; |
137 | 164 | const userInfo = await userStore.login({ |
138 | 165 | password: data.password, |
139 | - username: data.account, | |
166 | + userName: data.userName, | |
167 | + imgCaptchaCode: data.imgCaptchaCode, | |
168 | + imgCaptchaUuid: imgCaptchaUuid.value, | |
140 | 169 | mode: 'none', //不要默认的错误提示 |
141 | 170 | }); |
142 | 171 | if (userInfo) { | ... | ... |
src/views/sys/login/RegisterForm.vue
... | ... | @@ -2,14 +2,14 @@ |
2 | 2 | <div v-if="getShow"> |
3 | 3 | <LoginFormTitle class="enter-x" /> |
4 | 4 | <Form class="p-4 enter-x" :model="formData" :rules="getFormRules" ref="formRef"> |
5 | - <FormItem name="account" class="enter-x"> | |
5 | + <!-- <FormItem name="account" class="enter-x"> | |
6 | 6 | <Input |
7 | 7 | class="fix-auto-fill" |
8 | 8 | size="large" |
9 | 9 | v-model:value="formData.account" |
10 | 10 | :placeholder="t('sys.login.userName')" |
11 | 11 | /> |
12 | - </FormItem> | |
12 | + </FormItem> --> | |
13 | 13 | <FormItem name="mobile" class="enter-x"> |
14 | 14 | <Input |
15 | 15 | size="large" | ... | ... |
src/views/sys/login/useLogin.ts
... | ... | @@ -84,7 +84,7 @@ export function useFormRules(formData?: Recordable) { |
84 | 84 | // register form rules |
85 | 85 | case LoginStateEnum.REGISTER: |
86 | 86 | return { |
87 | - account: accountFormRule, | |
87 | + userName: accountFormRule, | |
88 | 88 | password: passwordFormRule, |
89 | 89 | confirmPassword: [ |
90 | 90 | { validator: validateConfirmPassword(formData?.password), trigger: 'change' }, |
... | ... | @@ -96,7 +96,7 @@ export function useFormRules(formData?: Recordable) { |
96 | 96 | // reset password form rules |
97 | 97 | case LoginStateEnum.RESET_PASSWORD: |
98 | 98 | return { |
99 | - account: accountFormRule, | |
99 | + userName: accountFormRule, | |
100 | 100 | ...mobileRule, |
101 | 101 | }; |
102 | 102 | |
... | ... | @@ -107,7 +107,7 @@ export function useFormRules(formData?: Recordable) { |
107 | 107 | // login form rules |
108 | 108 | default: |
109 | 109 | return { |
110 | - account: accountFormRule, | |
110 | + userName: accountFormRule, | |
111 | 111 | password: passwordFormRule, |
112 | 112 | }; |
113 | 113 | } | ... | ... |
types/axios.d.ts
... | ... | @@ -36,10 +36,10 @@ export interface RetryRequest { |
36 | 36 | waitTime: number; |
37 | 37 | } |
38 | 38 | export interface Result<T = any> { |
39 | - code: number; | |
39 | + result: number; | |
40 | 40 | type: 'success' | 'error' | 'warning'; |
41 | 41 | message: string; |
42 | - result: T; | |
42 | + data: T; | |
43 | 43 | } |
44 | 44 | |
45 | 45 | // multipart/form-data: upload file | ... | ... |
vite.config.ts
... | ... | @@ -2,6 +2,9 @@ import { defineApplicationConfig } from '@vben/vite-config'; |
2 | 2 | |
3 | 3 | export default defineApplicationConfig({ |
4 | 4 | overrides: { |
5 | + // build: { | |
6 | + // sourcemap: 'inline', | |
7 | + // }, | |
5 | 8 | optimizeDeps: { |
6 | 9 | include: [ |
7 | 10 | 'echarts/core', |
... | ... | @@ -16,11 +19,22 @@ export default defineApplicationConfig({ |
16 | 19 | }, |
17 | 20 | server: { |
18 | 21 | proxy: { |
19 | - '/basic-api': { | |
20 | - target: 'http://localhost:3000', | |
22 | + '/basic-api/order': { | |
23 | + target: 'http://39.108.227.113:8010', | |
24 | + // target: 'http://39.108.227.113:3000/mock/35', | |
25 | + // http://39.108.227.113:8010/order/erp/captcha/get_img_captcha_code | |
21 | 26 | changeOrigin: true, |
22 | 27 | ws: true, |
23 | 28 | rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''), |
29 | + }, | |
30 | + '/api/localStorage/upload': { | |
31 | + target: 'http://39.108.227.113:8010', | |
32 | + changeOrigin: true, | |
33 | + ws: true, | |
34 | + // rewrite: (path) => { | |
35 | + // console.log('%c [ path ]-32', 'font-size:13px; background:pink; color:#bf2c9f;', path); | |
36 | + // return path.replace(new RegExp(`^/basic-api`), ''); | |
37 | + // }, | |
24 | 38 | // only https |
25 | 39 | // secure: false |
26 | 40 | }, | ... | ... |