Commit 6953c5ab30b15edf472381f03d984f4cb42b7cf7
1 parent
20bd399f
feat: 开发完成
Showing
45 changed files
with
1652 additions
and
364 deletions
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/constant'; | |
5 | 3 | |
6 | 4 | enum Api { |
7 | 5 | DEMO_LIST = '/table/getDemoList', |
... | ... | @@ -39,8 +37,8 @@ export const demoApproveListApi = async (params: DemoParams) => { |
39 | 37 | item.fields = []; |
40 | 38 | Object.entries(item.fieldInfos.baseFields).map(([key, value]) => { |
41 | 39 | if (value === 'UN_LOCKED') { |
42 | - const obj = find(FIELDS_BASE_INFO, { field: key }); | |
43 | - item.fields.push(obj?.label); | |
40 | + // const obj = find(FIELDS_BASE_INFO, { field: key }); | |
41 | + // item.fields.push(obj?.label); | |
44 | 42 | } |
45 | 43 | }); |
46 | 44 | item.fields = item.fields.join(','); | ... | ... |
src/api/project/order.ts
... | ... | @@ -3,6 +3,7 @@ import { defHttp } from '/@/utils/http/axios'; |
3 | 3 | import { useUserStoreWithOut } from '/@/store/modules/user'; |
4 | 4 | import { useOrderStoreWithOut } from '/@/store/modules/order'; |
5 | 5 | import { formatToDate } from '/@/utils/dateUtil'; |
6 | +import message from '/@/views/form-design/utils/message'; | |
6 | 7 | |
7 | 8 | enum Api { |
8 | 9 | ORDER_CREATE = '/order/erp/order/add', |
... | ... | @@ -19,11 +20,37 @@ enum Api { |
19 | 20 | DICT_LIST = '/order/erp/dictionary/list_by_page', |
20 | 21 | |
21 | 22 | ANALYSIS = '/order/erp/profit/analysis', |
23 | + GRAVITY = '/order/erp/report/analysis', | |
22 | 24 | |
23 | 25 | OPT_LOG = '/order/erp/opt/log/list_by_page', // 操作日志 |
24 | 26 | AUDIT_LOG = '/order/erp/audit/log/list_by_page', //审批日志 |
25 | 27 | } |
26 | 28 | |
29 | +export const formatSearchData = (params) => { | |
30 | + params.createStartTime = params.createStartTime | |
31 | + ? formatToDate(params.createStartTime) | |
32 | + : undefined; | |
33 | + params.productionDepartmentConsignStartTime = params.productionDepartmentConsignStartTime | |
34 | + ? formatToDate(params.productionDepartmentConsignStartTime) | |
35 | + : undefined; | |
36 | + params.productionDepartmentConsignEndTime = params.productionDepartmentConsignEndTime | |
37 | + ? formatToDate(params.productionDepartmentConsignEndTime) | |
38 | + : undefined; | |
39 | + params.orderHodStartTime = params.orderHodStartTime | |
40 | + ? formatToDate(params.orderHodStartTime) | |
41 | + : undefined; | |
42 | + params.orderHodEndTime = params.orderHodEndTime | |
43 | + ? formatToDate(params.orderHodEndTime) | |
44 | + : undefined; | |
45 | + params.selfTestPassStartTime = params.selfTestPassStartTime | |
46 | + ? formatToDate(params.selfTestPassStartTime) | |
47 | + : undefined; | |
48 | + params.selfTestPassEndTime = params.selfTestPassEndTime | |
49 | + ? formatToDate(params.selfTestPassEndTime) | |
50 | + : undefined; | |
51 | + return params; | |
52 | +}; | |
53 | + | |
27 | 54 | export const orderCreate = async (data: any) => { |
28 | 55 | const res = await defHttp.post<any>({ url: Api.ORDER_CREATE, data }, { message: '保存成功' }); |
29 | 56 | return res; |
... | ... | @@ -50,6 +77,13 @@ export const orderAnalysis = async (data: any) => { |
50 | 77 | return res; |
51 | 78 | }; |
52 | 79 | |
80 | +export const orderGravity = async (data: any) => { | |
81 | + data = formatSearchData(data); | |
82 | + | |
83 | + const res = await defHttp.post<any>({ url: Api.GRAVITY, data }); | |
84 | + return res; | |
85 | +}; | |
86 | + | |
53 | 87 | export const orderExport = async (data: any = {}) => { |
54 | 88 | // const res = await defHttp.post<any>({ url: Api.EXPORT, data }); |
55 | 89 | const userStore = useUserStoreWithOut(); |
... | ... | @@ -60,7 +94,7 @@ export const orderExport = async (data: any = {}) => { |
60 | 94 | url: '/basic-api' + Api.EXPORT, |
61 | 95 | method: 'post', |
62 | 96 | responseType: 'blob', |
63 | - headers: { Authorization: `Bearer ${token}` }, | |
97 | + headers: { Authorization: `${token}` }, | |
64 | 98 | data, |
65 | 99 | }) |
66 | 100 | .then((response) => { |
... | ... | @@ -74,6 +108,8 @@ export const orderExport = async (data: any = {}) => { |
74 | 108 | a.click(); // 模拟点击操作来下载文件 |
75 | 109 | URL.revokeObjectURL(downloadUrl); // 释放掉 blob 对象所占用的内存 |
76 | 110 | document.body.removeChild(a); |
111 | + | |
112 | + message.success('导出成功'); | |
77 | 113 | }) |
78 | 114 | .catch((error) => { |
79 | 115 | // 处理错误 |
... | ... | @@ -104,28 +140,7 @@ export async function uploadImg(params, onUploadProgress: (progressEvent: Progre |
104 | 140 | } |
105 | 141 | |
106 | 142 | export const getOrderList = async (params: DemoParams) => { |
107 | - params.createStartTime = params.createStartTime | |
108 | - ? formatToDate(params.createStartTime) | |
109 | - : undefined; | |
110 | - params.productionDepartmentConsignStartTime = params.productionDepartmentConsignStartTime | |
111 | - ? formatToDate(params.productionDepartmentConsignStartTime) | |
112 | - : undefined; | |
113 | - params.productionDepartmentConsignEndTime = params.productionDepartmentConsignEndTime | |
114 | - ? formatToDate(params.productionDepartmentConsignEndTime) | |
115 | - : undefined; | |
116 | - params.orderHodStartTime = params.orderHodStartTime | |
117 | - ? formatToDate(params.orderHodStartTime) | |
118 | - : undefined; | |
119 | - params.orderHodEndTime = params.orderHodEndTime | |
120 | - ? formatToDate(params.orderHodEndTime) | |
121 | - : undefined; | |
122 | - params.selfTestPassStartTime = params.selfTestPassStartTime | |
123 | - ? formatToDate(params.selfTestPassStartTime) | |
124 | - : undefined; | |
125 | - params.selfTestPassEndTime = params.selfTestPassEndTime | |
126 | - ? formatToDate(params.selfTestPassEndTime) | |
127 | - : undefined; | |
128 | - | |
143 | + params = formatSearchData(params); | |
129 | 144 | const res = await defHttp.post<DemoListGetResultModel>({ |
130 | 145 | url: Api.ORDER, |
131 | 146 | params, | ... | ... |
src/api/sys/config.ts
0 → 100644
1 | +import { defHttp } from '/@/utils/http/axios'; | |
2 | +import { LoginParams, LoginResultModel } from './model/userModel'; | |
3 | + | |
4 | +import { ErrorMessageMode } from '/#/axios'; | |
5 | + | |
6 | +enum Api { | |
7 | + // Login = '/login', | |
8 | + LIST = '/order/erp/system_setting/query_list', | |
9 | + EDIT = '/order/erp/system_setting/edit', | |
10 | + ADD = '/order/erp/system_setting/add', | |
11 | + DELETE = '/order/erp/system_setting/delete_by_id', | |
12 | +} | |
13 | + | |
14 | +export function getList(params: LoginParams, mode: ErrorMessageMode = 'modal') { | |
15 | + return defHttp.post<LoginResultModel>( | |
16 | + { | |
17 | + url: Api.LIST, | |
18 | + params, | |
19 | + }, | |
20 | + { | |
21 | + errorMessageMode: mode, | |
22 | + }, | |
23 | + ); | |
24 | +} | |
25 | +export function saveConfig(params: LoginParams) { | |
26 | + return defHttp.post<LoginResultModel>( | |
27 | + { | |
28 | + url: Api.EDIT, | |
29 | + params, | |
30 | + }, | |
31 | + { | |
32 | + message: '保存成功', | |
33 | + }, | |
34 | + ); | |
35 | +} | |
36 | + | |
37 | +export function addConfig(params: LoginParams) { | |
38 | + return defHttp.post<LoginResultModel>( | |
39 | + { | |
40 | + url: Api.ADD, | |
41 | + params, | |
42 | + }, | |
43 | + { | |
44 | + message: '新建成功', | |
45 | + }, | |
46 | + ); | |
47 | +} | |
48 | + | |
49 | +export function deleteConfig(params: LoginParams) { | |
50 | + return defHttp.post<LoginResultModel>( | |
51 | + { | |
52 | + url: Api.DELETE, | |
53 | + params, | |
54 | + }, | |
55 | + { | |
56 | + message: '删除成功', | |
57 | + }, | |
58 | + ); | |
59 | +} | ... | ... |
src/api/sys/user.ts
... | ... | @@ -10,6 +10,11 @@ enum Api { |
10 | 10 | GetUserInfo = '/getUserInfo', |
11 | 11 | GetPermCode = '/getPermCode', |
12 | 12 | TestRetry = '/testRetry', |
13 | + MODIFY_PASSWORD = '/order/erp/users/update_pass', | |
14 | + FORGET_PASSWORD = '/order/erp/auth/password_modify', | |
15 | + RESET = '/order/erp/users/reset', | |
16 | + CAPTCHA = '/order/erp/captcha/get_img_captcha_code', | |
17 | + SMS = '/order/erp/captcha/send_captcha_code', | |
13 | 18 | } |
14 | 19 | |
15 | 20 | /** |
... | ... | @@ -27,6 +32,19 @@ export function loginApi(params: LoginParams, mode: ErrorMessageMode = 'modal') |
27 | 32 | ); |
28 | 33 | } |
29 | 34 | |
35 | +export function MODIFY_PASSWORD(params: LoginParams, mode: ErrorMessageMode = 'modal') { | |
36 | + return defHttp.post<LoginResultModel>( | |
37 | + { | |
38 | + url: Api.MODIFY_PASSWORD, | |
39 | + params, | |
40 | + }, | |
41 | + { | |
42 | + errorMessageMode: mode, | |
43 | + message: '修改成功', | |
44 | + }, | |
45 | + ); | |
46 | +} | |
47 | + | |
30 | 48 | /** |
31 | 49 | * @description: getUserInfo |
32 | 50 | */ |
... | ... | @@ -56,5 +74,18 @@ export function testRetry() { |
56 | 74 | } |
57 | 75 | |
58 | 76 | export function getImageCaptcha() { |
59 | - return defHttp.post({ url: '/order/erp/captcha/get_img_captcha_code' }); | |
77 | + return defHttp.post({ url: Api.CAPTCHA }); | |
78 | +} | |
79 | + | |
80 | +export function forgetPassword(params) { | |
81 | + return defHttp.post( | |
82 | + { url: Api.FORGET_PASSWORD, params }, | |
83 | + { | |
84 | + message: '修改成功', | |
85 | + }, | |
86 | + ); | |
87 | +} | |
88 | + | |
89 | +export function getSms(params) { | |
90 | + return defHttp.post({ url: Api.SMS, params }); | |
60 | 91 | } | ... | ... |
src/enums/pageEnum.ts
src/enums/roleEnum.ts
src/hooks/component/order.ts
... | ... | @@ -9,6 +9,11 @@ export function useOrderInfo(orderStore) { |
9 | 9 | value: item.dictValue, |
10 | 10 | }); |
11 | 11 | |
12 | + const exchangeRate = computed(() => { | |
13 | + const dictInfo = orderStore.getDictInfo; | |
14 | + return map(dictInfo?.exchangeRate, transformDictInfo); | |
15 | + }); | |
16 | + | |
12 | 17 | const customerCode = computed(() => { |
13 | 18 | const dictInfo = orderStore.getDictInfo; |
14 | 19 | |
... | ... | @@ -75,7 +80,11 @@ export function useOrderInfo(orderStore) { |
75 | 80 | return map(dictInfo?.midCheckResult, transformDictInfo); |
76 | 81 | }); |
77 | 82 | |
78 | - console.log('%c [ ]-78', 'font-size:13px; background:pink; color:#bf2c9f;', endCheckResult); | |
83 | + const businessPerson = computed(() => { | |
84 | + const dictInfo = orderStore.getDictInfo; | |
85 | + return map(dictInfo?.businessPerson, transformDictInfo); | |
86 | + }); | |
87 | + | |
79 | 88 | return { |
80 | 89 | customerCode, |
81 | 90 | projectNo, |
... | ... | @@ -90,5 +99,7 @@ export function useOrderInfo(orderStore) { |
90 | 99 | manualPreform, |
91 | 100 | midCheckResult, |
92 | 101 | endCheckResult, |
102 | + exchangeRate, | |
103 | + businessPerson, | |
93 | 104 | }; |
94 | 105 | } | ... | ... |
src/layouts/default/header/components/user-dropdown/index.vue
1 | 1 | <template> |
2 | 2 | <Dropdown placement="bottomLeft" :overlayClassName="`${prefixCls}-dropdown-overlay`"> |
3 | 3 | <span :class="[prefixCls, `${prefixCls}--${theme}`]" class="flex"> |
4 | - <img :class="`${prefixCls}__header`" :src="getUserInfo.avatar" /> | |
4 | + <!-- <img :class="`${prefixCls}__header`" :src="getUserInfo.avatar" /> --> | |
5 | 5 | <span :class="`${prefixCls}__info hidden md:block`"> |
6 | 6 | <span :class="`${prefixCls}__name `" class="truncate"> |
7 | - {{ getUserInfo.realName }} | |
7 | + {{ getUserInfo.nickName }} | |
8 | 8 | </span> |
9 | 9 | </span> |
10 | 10 | </span> |
... | ... | @@ -76,8 +76,13 @@ |
76 | 76 | const userStore = useUserStore(); |
77 | 77 | |
78 | 78 | const getUserInfo = computed(() => { |
79 | - const { realName = '', avatar, desc } = userStore.getUserInfo || {}; | |
80 | - return { realName, avatar: avatar || headerImg, desc }; | |
79 | + const { nickName = '', avatar, desc } = userStore.getUserInfo || {}; | |
80 | + console.log( | |
81 | + '%c [ userStore.getUserInfo ]-80', | |
82 | + 'font-size:13px; background:pink; color:#bf2c9f;', | |
83 | + userStore.getUserInfo, | |
84 | + ); | |
85 | + return { nickName, avatar: avatar || headerImg, desc }; | |
81 | 86 | }); |
82 | 87 | |
83 | 88 | const [register, { openModal }] = useModal(); | ... | ... |
src/layouts/default/header/index.less
src/layouts/default/header/index.vue
src/router/routes/modules/project/system.ts
... | ... | @@ -2,6 +2,7 @@ import type { AppRouteModule } from '/@/router/types'; |
2 | 2 | |
3 | 3 | import { LAYOUT } from '/@/router/constant'; |
4 | 4 | import { t } from '/@/hooks/web/useI18n'; |
5 | +import { RoleEnum } from '/@/enums/roleEnum'; | |
5 | 6 | |
6 | 7 | const system: AppRouteModule = { |
7 | 8 | path: '/system', |
... | ... | @@ -19,21 +20,41 @@ const system: AppRouteModule = { |
19 | 20 | name: 'AccountManagement', |
20 | 21 | meta: { |
21 | 22 | title: t('routes.demo.system.account'), |
23 | + roles: [RoleEnum.ADMIN], | |
22 | 24 | ignoreKeepAlive: false, |
23 | 25 | }, |
24 | 26 | component: () => import('/@/views/project/account/index.vue'), |
25 | 27 | }, |
28 | + // { | |
29 | + // path: 'account_detail/:id', | |
30 | + // name: 'AccountDetail', | |
31 | + // meta: { | |
32 | + // hideMenu: true, | |
33 | + // title: t('routes.demo.system.account_detail'), | |
34 | + // ignoreKeepAlive: true, | |
35 | + // showMenu: false, | |
36 | + // currentActiveMenu: '/system/account', | |
37 | + // }, | |
38 | + // component: () => import('/@/views/project/account/AccountDetail.vue'), | |
39 | + // }, | |
40 | + { | |
41 | + path: 'changePassword', | |
42 | + name: 'ChangePassword', | |
43 | + meta: { | |
44 | + title: t('routes.demo.system.password'), | |
45 | + ignoreKeepAlive: true, | |
46 | + }, | |
47 | + component: () => import('/@/views/demo/system/password/index.vue'), | |
48 | + }, | |
26 | 49 | { |
27 | - path: 'account_detail/:id', | |
28 | - name: 'AccountDetail', | |
50 | + path: 'config', | |
51 | + name: 'config', | |
29 | 52 | meta: { |
30 | - hideMenu: true, | |
31 | - title: t('routes.demo.system.account_detail'), | |
53 | + title: '系统配置', | |
32 | 54 | ignoreKeepAlive: true, |
33 | - showMenu: false, | |
34 | - currentActiveMenu: '/system/account', | |
55 | + roles: [RoleEnum.ADMIN], | |
35 | 56 | }, |
36 | - component: () => import('/@/views/project/account/AccountDetail.vue'), | |
57 | + component: () => import('/@/views/project/config/index.vue'), | |
37 | 58 | }, |
38 | 59 | // { |
39 | 60 | // path: 'role', | ... | ... |
src/store/modules/order.ts
... | ... | @@ -92,7 +92,7 @@ export const useOrderStore = defineStore({ |
92 | 92 | async getDict(): Promise<GetUserInfoModel | null> { |
93 | 93 | try { |
94 | 94 | const data = await getInitDictData(); |
95 | - console.log('%c [ data ]-95', 'font-size:13px; background:pink; color:#bf2c9f;', data); | |
95 | + | |
96 | 96 | this.dicts = groupBy(data, 'dictCode'); |
97 | 97 | } catch (error) { |
98 | 98 | return Promise.reject(error); | ... | ... |
src/store/modules/permission.ts
... | ... | @@ -112,6 +112,11 @@ export const usePermissionStore = defineStore({ |
112 | 112 | async buildRoutesAction(): Promise<AppRouteRecordRaw[]> { |
113 | 113 | const { t } = useI18n(); |
114 | 114 | const userStore = useUserStore(); |
115 | + console.log( | |
116 | + '%c [ userStore ]-115', | |
117 | + 'font-size:13px; background:pink; color:#bf2c9f;', | |
118 | + userStore, | |
119 | + ); | |
115 | 120 | const appStore = useAppStoreWithOut(); |
116 | 121 | |
117 | 122 | let routes: AppRouteRecordRaw[] = []; |
... | ... | @@ -127,7 +132,9 @@ export const usePermissionStore = defineStore({ |
127 | 132 | const { roles } = meta || {}; |
128 | 133 | if (!roles) return true; |
129 | 134 | // 进行角色权限判断 |
130 | - return roleList.some((role) => roles.includes(role)); | |
135 | + const user = userStore.getUserInfo; | |
136 | + return user?.roleSmallVO.code === 'admin'; | |
137 | + // return roleList.some((role) => roles.includes(role)); | |
131 | 138 | }; |
132 | 139 | |
133 | 140 | const routeRemoveIgnoreFilter = (route: AppRouteRecordRaw) => { |
... | ... | @@ -195,6 +202,7 @@ export const usePermissionStore = defineStore({ |
195 | 202 | routes = filter(routes, routeRemoveIgnoreFilter); |
196 | 203 | // 移除掉 ignoreRoute: true 的路由 一级路由; |
197 | 204 | routes = routes.filter(routeRemoveIgnoreFilter); |
205 | + | |
198 | 206 | // 对菜单进行排序 |
199 | 207 | menuList.sort((a, b) => { |
200 | 208 | return (a.meta?.orderNo || 0) - (b.meta?.orderNo || 0); | ... | ... |
src/utils/dateUtil.ts
... | ... | @@ -11,7 +11,7 @@ export function formatToDateTime(date?: dayjs.ConfigType, format = DATE_TIME_FOR |
11 | 11 | } |
12 | 12 | |
13 | 13 | export function formatToDate(date?: dayjs.ConfigType, format = DATE_FORMAT): string { |
14 | - return dayjs(date).format(format); | |
14 | + return date ? dayjs(date).format(format) : ''; | |
15 | 15 | } |
16 | 16 | |
17 | 17 | export const dateUtil = dayjs; | ... | ... |
src/utils/project.ts
1 | -export const getDisable = (code, id) => { | |
2 | - return code === 'LOCKED' && !!id; | |
1 | +export const getDisable = (code, id, value) => { | |
2 | + return code === 'LOCKED' && !!id && value; | |
3 | +}; | |
4 | + | |
5 | +// 利润分析的权限校验 | |
6 | +export const getProfitDisable = (field, code, id, value) => { | |
7 | + // 包装费用,汇率不允许修改 | |
8 | + if (['packetPrice', 'exchangeRate'].includes(field)) { | |
9 | + return true; | |
10 | + } | |
11 | + // code是lock,编辑并且value存在,才需要审核 | |
12 | + return code === 'LOCKED' && !!id && value; | |
13 | +}; | |
14 | + | |
15 | +// 基本信息的权限校验 客户编码、项目号、生产科、内部编号、业务员 才需要审核 | |
16 | +export const getBaseDisable = (field, code, id) => { | |
17 | + if ( | |
18 | + [ | |
19 | + 'customerCode', | |
20 | + 'projectNo', | |
21 | + 'productionDepartment', | |
22 | + 'innerNo', | |
23 | + 'orderCount', | |
24 | + 'businessPerson', | |
25 | + ].includes(field) | |
26 | + ) { | |
27 | + return code === 'LOCKED' && !!id; | |
28 | + } | |
29 | + return false; | |
3 | 30 | }; | ... | ... |
src/views/demo/system/password/index.vue
... | ... | @@ -13,13 +13,17 @@ |
13 | 13 | import { defineComponent } from 'vue'; |
14 | 14 | import { PageWrapper } from '/@/components/Page'; |
15 | 15 | import { BasicForm, useForm } from '/@/components/Form'; |
16 | + import { useUserStoreWithOut } from '/@/store/modules/user'; | |
16 | 17 | |
17 | 18 | import { formSchema } from './pwd.data'; |
19 | + import { forgetPassword } from '/@/api/sys/user'; | |
18 | 20 | |
19 | 21 | export default defineComponent({ |
20 | 22 | name: 'ChangePassword', |
21 | 23 | components: { BasicForm, PageWrapper }, |
22 | 24 | setup() { |
25 | + const userStore = useUserStoreWithOut(); | |
26 | + | |
23 | 27 | const [register, { validate, resetFields }] = useForm({ |
24 | 28 | size: 'large', |
25 | 29 | baseColProps: { span: 24 }, |
... | ... | @@ -31,12 +35,10 @@ |
31 | 35 | async function handleSubmit() { |
32 | 36 | try { |
33 | 37 | const values = await validate(); |
34 | - const { passwordOld, passwordNew } = values; | |
35 | 38 | |
36 | - // TODO custom api | |
37 | - console.log(passwordOld, passwordNew); | |
38 | - // const { router } = useRouter(); | |
39 | - // router.push(pageEnum.BASE_LOGIN); | |
39 | + const userInfo = userStore.getUserInfo; | |
40 | + | |
41 | + await forgetPassword({ ...values, userId: userInfo.id }); | |
40 | 42 | } catch (error) {} |
41 | 43 | } |
42 | 44 | ... | ... |
src/views/demo/system/password/pwd.data.ts
1 | 1 | import { FormSchema } from '/@/components/Form'; |
2 | 2 | |
3 | 3 | export const formSchema: FormSchema[] = [ |
4 | + // { | |
5 | + // field: 'passwordOld', | |
6 | + // label: '当前密码', | |
7 | + // component: 'InputPassword', | |
8 | + // required: true, | |
9 | + // }, | |
4 | 10 | { |
5 | - field: 'passwordOld', | |
6 | - label: '当前密码', | |
7 | - component: 'InputPassword', | |
8 | - required: true, | |
9 | - }, | |
10 | - { | |
11 | - field: 'passwordNew', | |
11 | + field: 'password', | |
12 | 12 | label: '新密码', |
13 | 13 | component: 'StrengthMeter', |
14 | 14 | componentProps: { |
... | ... | @@ -34,7 +34,7 @@ export const formSchema: FormSchema[] = [ |
34 | 34 | if (!value) { |
35 | 35 | return Promise.reject('密码不能为空'); |
36 | 36 | } |
37 | - if (value !== values.passwordNew) { | |
37 | + if (value !== values.password) { | |
38 | 38 | return Promise.reject('两次输入的密码不一致!'); |
39 | 39 | } |
40 | 40 | return Promise.resolve(); | ... | ... |
src/views/project/account/index.vue
src/views/project/approve/FieldPanel.vue
... | ... | @@ -51,14 +51,15 @@ |
51 | 51 | <a-button @click="handleFalse"> 不通过</a-button> |
52 | 52 | </template> |
53 | 53 | </BasicDrawer> |
54 | + <MsgModal v-if="msgVisible" @msg-modal-close="handleMsgModalClose" /> | |
54 | 55 | </PageWrapper> |
55 | 56 | </template> |
56 | 57 | <script lang="ts"> |
58 | + import MsgModal from './MsgModal.vue'; | |
57 | 59 | import { computed, defineComponent, ref } from 'vue'; |
58 | 60 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
59 | 61 | import { PageWrapper } from '/@/components/Page'; |
60 | 62 | import { BasicDrawer, useDrawer } from '/@/components/Drawer'; |
61 | - | |
62 | 63 | import { approveAuditApi, getApprovedListApi, getWaitListApi } from '/@/api/project/approve'; |
63 | 64 | import { |
64 | 65 | FIELDS_BASE_INFO, |
... | ... | @@ -81,11 +82,15 @@ |
81 | 82 | BasicDrawer, |
82 | 83 | TableAction, |
83 | 84 | BaseInfo, |
85 | + MsgModal, | |
84 | 86 | }, |
85 | 87 | props: { |
86 | 88 | isApproved: { type: Boolean }, |
87 | 89 | }, |
88 | 90 | setup(props) { |
91 | + // visible 用于msgModal显示隐藏 | |
92 | + const msgVisible = ref(false); | |
93 | + | |
89 | 94 | const checkedKeys = ref<Array<string | number>>([]); |
90 | 95 | const currentKey = ref('1'); |
91 | 96 | const [registerDrawer, { openDrawer, closeDrawer }] = useDrawer(); |
... | ... | @@ -99,17 +104,35 @@ |
99 | 104 | const baseInfos = ref({}); |
100 | 105 | const id = ref(''); |
101 | 106 | |
102 | - const [registerTable, { reload }] = useTable({ | |
103 | - api: props.isApproved ? getApprovedListApi : getWaitListApi, | |
104 | - searchInfo: { type: 0 }, | |
107 | + let columns = [ | |
108 | + { | |
109 | + title: '申请人', | |
110 | + dataIndex: 'createBy', | |
111 | + width: 150, | |
112 | + }, | |
113 | + ]; | |
105 | 114 | |
106 | - columns: [ | |
115 | + if (props.isApproved) { | |
116 | + columns = columns.concat([ | |
107 | 117 | { |
108 | - title: '申请人', | |
109 | - dataIndex: 'createBy', | |
118 | + title: '状态', | |
119 | + dataIndex: 'status', | |
110 | 120 | width: 150, |
121 | + customRender: (column) => { | |
122 | + const { record } = column || {}; | |
123 | + | |
124 | + return record.status === 10 ? '通过' : '拒绝'; | |
125 | + }, | |
111 | 126 | }, |
112 | - ], | |
127 | + { title: '拒绝原因', dataIndex: 'refuseRemark', width: 250 }, | |
128 | + ]); | |
129 | + } | |
130 | + | |
131 | + const [registerTable, { reload }] = useTable({ | |
132 | + api: props.isApproved ? getApprovedListApi : getWaitListApi, | |
133 | + searchInfo: { type: 0 }, | |
134 | + | |
135 | + columns, | |
113 | 136 | // useSearchForm: true, |
114 | 137 | // formConfig: getFormConfig(), |
115 | 138 | rowKey: 'id', |
... | ... | @@ -209,14 +232,23 @@ |
209 | 232 | } |
210 | 233 | |
211 | 234 | async function handleFalse() { |
212 | - await approveAuditApi({ status: 20, id: id.value }); | |
213 | - reload(); | |
214 | - closeDrawer(); | |
235 | + msgVisible.value = true; | |
215 | 236 | } |
216 | 237 | |
217 | 238 | const role = computed(() => { |
218 | 239 | return userStore.getUserInfo?.roleSmallVO?.code; |
219 | 240 | }); |
241 | + | |
242 | + // 定义MsgModalClose的事件,方便子组件调用 | |
243 | + const handleMsgModalClose = async (data) => { | |
244 | + if (data) { | |
245 | + await approveAuditApi({ status: 20, id: id.value, refuseRemark: data }); | |
246 | + reload(); | |
247 | + closeDrawer(); | |
248 | + } | |
249 | + msgVisible.value = false; | |
250 | + }; | |
251 | + | |
220 | 252 | return { |
221 | 253 | handleProfitModal, |
222 | 254 | registerTable, |
... | ... | @@ -233,8 +265,9 @@ |
233 | 265 | handleFalse, |
234 | 266 | ROLE, |
235 | 267 | role, |
268 | + msgVisible, | |
269 | + handleMsgModalClose, | |
236 | 270 | }; |
237 | 271 | }, |
238 | 272 | }); |
239 | 273 | </script> |
240 | -../order/constant | ... | ... |
src/views/project/approve/MsgModal.vue
0 → 100644
1 | +<!-- 通过vue的modal增加一个拒绝填写message --> | |
2 | +<template> | |
3 | + <!-- 一直显示 --> | |
4 | + <Modal title="拒绝原因" width="30%" @cancel="handleClose" @ok="handleOk" visible> | |
5 | + <div className="pa-5"> | |
6 | + <a-textarea :rows="5" placeholder="请输入拒绝原因" v-model:value="message" /> | |
7 | + </div> | |
8 | + </Modal> | |
9 | +</template> | |
10 | + | |
11 | +<script setup lang="ts"> | |
12 | + import { ref, defineEmits } from 'vue'; | |
13 | + import { Modal } from 'ant-design-vue'; | |
14 | + | |
15 | + const emit = defineEmits(['msg-modal-close']); | |
16 | + | |
17 | + const message = ref(''); | |
18 | + | |
19 | + const handleOk = () => { | |
20 | + // 修改父组件的状态 | |
21 | + emit('msg-modal-close', message.value); | |
22 | + }; | |
23 | + | |
24 | + const handleClose = () => { | |
25 | + // 修改父组件的状态 | |
26 | + emit('msg-modal-close'); | |
27 | + }; | |
28 | +</script> | ... | ... |
src/views/project/approve/ProfitPanel.vue
... | ... | @@ -33,9 +33,11 @@ |
33 | 33 | <a-button @click="handleFalse"> 不通过</a-button> |
34 | 34 | </template> |
35 | 35 | </BasicDrawer> |
36 | + <MsgModal v-if="msgVisible" @msg-modal-close="handleMsgModalClose" /> | |
36 | 37 | </PageWrapper> |
37 | 38 | </template> |
38 | 39 | <script lang="ts"> |
40 | + import MsgModal from './MsgModal.vue'; | |
39 | 41 | import { computed, defineComponent, ref } from 'vue'; |
40 | 42 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
41 | 43 | import { PageWrapper } from '/@/components/Page'; |
... | ... | @@ -56,11 +58,14 @@ |
56 | 58 | BasicDrawer, |
57 | 59 | TableAction, |
58 | 60 | BaseInfo, |
61 | + MsgModal, | |
59 | 62 | }, |
60 | 63 | props: { |
61 | 64 | isApproved: { type: Boolean }, |
62 | 65 | }, |
63 | 66 | setup(props) { |
67 | + // visible 用于msgModal显示隐藏 | |
68 | + const msgVisible = ref(false); | |
64 | 69 | const checkedKeys = ref<Array<string | number>>([]); |
65 | 70 | const currentKey = ref('1'); |
66 | 71 | const [registerDrawer, { openDrawer, closeDrawer }] = useDrawer(); |
... | ... | @@ -68,17 +73,35 @@ |
68 | 73 | const baseInfos = ref({}); |
69 | 74 | const id = ref(''); |
70 | 75 | |
71 | - const [registerTable, { reload }] = useTable({ | |
72 | - api: props.isApproved ? getApprovedListApi : getWaitListApi, | |
73 | - searchInfo: { type: 10 }, | |
76 | + let columns = [ | |
77 | + { | |
78 | + title: '申请人', | |
79 | + dataIndex: 'createBy', | |
80 | + width: 150, | |
81 | + }, | |
82 | + ]; | |
74 | 83 | |
75 | - columns: [ | |
84 | + if (props.isApproved) { | |
85 | + columns = columns.concat([ | |
76 | 86 | { |
77 | - title: '申请人', | |
78 | - dataIndex: 'createBy', | |
87 | + title: '状态', | |
88 | + dataIndex: 'status', | |
79 | 89 | width: 150, |
90 | + customRender: (column) => { | |
91 | + const { record } = column || {}; | |
92 | + | |
93 | + return record.status === 10 ? '通过' : '拒绝'; | |
94 | + }, | |
80 | 95 | }, |
81 | - ], | |
96 | + { title: '拒绝原因', dataIndex: 'refuseRemark', width: 250 }, | |
97 | + ]); | |
98 | + } | |
99 | + | |
100 | + const [registerTable, { reload }] = useTable({ | |
101 | + api: props.isApproved ? getApprovedListApi : getWaitListApi, | |
102 | + searchInfo: { type: 10 }, | |
103 | + | |
104 | + columns, | |
82 | 105 | // useSearchForm: true, |
83 | 106 | // formConfig: getFormConfig(), |
84 | 107 | rowKey: 'id', |
... | ... | @@ -118,6 +141,12 @@ |
118 | 141 | openDrawer(true, { data }); |
119 | 142 | id.value = data.id; |
120 | 143 | fieldInfos.value = FIELDS_PROFIT_INFO.map((field) => { |
144 | + if (field.field === 'profitType') { | |
145 | + return { | |
146 | + label: field.label, | |
147 | + value: data.fieldInfos.profitAnalysisFields[field.field] == 0 ? '方式1' : '方式2', | |
148 | + }; | |
149 | + } | |
121 | 150 | return { |
122 | 151 | label: field.label, |
123 | 152 | value: data.fieldInfos.profitAnalysisFields[field.field], |
... | ... | @@ -138,14 +167,25 @@ |
138 | 167 | } |
139 | 168 | |
140 | 169 | async function handleFalse() { |
141 | - await approveAuditApi({ status: 20, id: id.value }); | |
142 | - reload(); | |
143 | - closeDrawer(); | |
170 | + msgVisible.value = true; | |
171 | + // await approveAuditApi({ status: 20, id: id.value }); | |
172 | + // reload(); | |
173 | + // closeDrawer(); | |
144 | 174 | } |
145 | 175 | |
146 | 176 | const role = computed(() => { |
147 | 177 | return userStore.getUserInfo?.roleSmallVO?.code; |
148 | 178 | }); |
179 | + | |
180 | + // 定义MsgModalClose的事件,方便子组件调用 | |
181 | + const handleMsgModalClose = async (data) => { | |
182 | + if (data) { | |
183 | + await approveAuditApi({ status: 20, id: id.value, refuseRemark: data }); | |
184 | + reload(); | |
185 | + closeDrawer(); | |
186 | + } | |
187 | + msgVisible.value = false; | |
188 | + }; | |
149 | 189 | return { |
150 | 190 | handleProfitModal, |
151 | 191 | registerTable, |
... | ... | @@ -162,8 +202,9 @@ |
162 | 202 | handleFalse, |
163 | 203 | role, |
164 | 204 | ROLE, |
205 | + msgVisible, | |
206 | + handleMsgModalClose, | |
165 | 207 | }; |
166 | 208 | }, |
167 | 209 | }); |
168 | 210 | </script> |
169 | -../order/constant | ... | ... |
src/views/project/approve/ReportPanel.vue
... | ... | @@ -33,9 +33,11 @@ |
33 | 33 | <a-button @click="handleFalse"> 不通过</a-button> |
34 | 34 | </template> |
35 | 35 | </BasicDrawer> |
36 | + <MsgModal v-if="msgVisible" @msg-modal-close="handleMsgModalClose" /> | |
36 | 37 | </PageWrapper> |
37 | 38 | </template> |
38 | 39 | <script lang="ts"> |
40 | + import MsgModal from './MsgModal.vue'; | |
39 | 41 | import { computed, defineComponent, ref } from 'vue'; |
40 | 42 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
41 | 43 | import { PageWrapper } from '/@/components/Page'; |
... | ... | @@ -56,29 +58,49 @@ |
56 | 58 | BasicDrawer, |
57 | 59 | BaseInfo, |
58 | 60 | TableAction, |
61 | + MsgModal, | |
59 | 62 | }, |
60 | 63 | props: { |
61 | 64 | isApproved: { type: Boolean }, |
62 | 65 | }, |
63 | 66 | setup(props) { |
67 | + // visible 用于msgModal显示隐藏 | |
68 | + const msgVisible = ref(false); | |
64 | 69 | const checkedKeys = ref<Array<string | number>>([]); |
65 | 70 | const currentKey = ref('1'); |
66 | 71 | const [registerDrawer, { openDrawer, closeDrawer }] = useDrawer(); |
67 | 72 | const fieldInfos = ref({}); |
68 | 73 | const baseInfos = ref({}); |
69 | 74 | const id = ref(''); |
75 | + let columns = [ | |
76 | + { | |
77 | + title: '申请人', | |
78 | + dataIndex: 'createBy', | |
79 | + width: 150, | |
80 | + }, | |
81 | + ]; | |
82 | + | |
83 | + if (props.isApproved) { | |
84 | + columns = columns.concat([ | |
85 | + { | |
86 | + title: '状态', | |
87 | + dataIndex: 'status', | |
88 | + width: 150, | |
89 | + customRender: (column) => { | |
90 | + const { record } = column || {}; | |
91 | + | |
92 | + return record.status === 10 ? '通过' : '拒绝'; | |
93 | + }, | |
94 | + }, | |
95 | + { title: '拒绝原因', dataIndex: 'refuseRemark', width: 250 }, | |
96 | + ]); | |
97 | + } | |
70 | 98 | |
71 | 99 | const [registerTable, { reload }] = useTable({ |
72 | 100 | api: props.isApproved ? getApprovedListApi : getWaitListApi, |
73 | 101 | searchInfo: { type: 20 }, |
74 | 102 | |
75 | - columns: [ | |
76 | - { | |
77 | - title: '申请人', | |
78 | - dataIndex: 'createBy', | |
79 | - width: 150, | |
80 | - }, | |
81 | - ], | |
103 | + columns, | |
82 | 104 | // useSearchForm: true, |
83 | 105 | // formConfig: getFormConfig(), |
84 | 106 | rowKey: 'id', |
... | ... | @@ -138,11 +160,19 @@ |
138 | 160 | } |
139 | 161 | |
140 | 162 | async function handleFalse() { |
141 | - await approveAuditApi({ status: 20, id: id.value }); | |
142 | - reload(); | |
143 | - closeDrawer(); | |
163 | + msgVisible.value = true; | |
144 | 164 | } |
145 | 165 | |
166 | + // 定义MsgModalClose的事件,方便子组件调用 | |
167 | + const handleMsgModalClose = async (data) => { | |
168 | + if (data) { | |
169 | + await approveAuditApi({ status: 20, id: id.value, refuseRemark: data }); | |
170 | + reload(); | |
171 | + closeDrawer(); | |
172 | + } | |
173 | + msgVisible.value = false; | |
174 | + }; | |
175 | + | |
146 | 176 | const role = computed(() => { |
147 | 177 | return userStore.getUserInfo?.roleSmallVO?.code; |
148 | 178 | }); |
... | ... | @@ -162,8 +192,9 @@ |
162 | 192 | handleFalse, |
163 | 193 | role, |
164 | 194 | ROLE, |
195 | + msgVisible, | |
196 | + handleMsgModalClose, | |
165 | 197 | }; |
166 | 198 | }, |
167 | 199 | }); |
168 | 200 | </script> |
169 | -../order/constant | ... | ... |
src/views/project/approve/index.vue
... | ... | @@ -136,8 +136,6 @@ |
136 | 136 | return false; |
137 | 137 | } |
138 | 138 | |
139 | - function handleProfitModal() {} | |
140 | - | |
141 | 139 | async function handleTrue(record) { |
142 | 140 | await approveAuditApi({ status: 10, id: record.id }); |
143 | 141 | reload(); |
... | ... | @@ -149,7 +147,6 @@ |
149 | 147 | } |
150 | 148 | |
151 | 149 | return { |
152 | - handleProfitModal, | |
153 | 150 | registerTable1, |
154 | 151 | registerTable2, |
155 | 152 | checkedKeys, |
... | ... | @@ -163,3 +160,9 @@ |
163 | 160 | }, |
164 | 161 | }); |
165 | 162 | </script> |
163 | + | |
164 | +<style> | |
165 | + .ant-modal-wrap { | |
166 | + z-index: 99999999; | |
167 | + } | |
168 | +</style> | ... | ... |
src/views/project/config/CreateModal.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + destroyOnClose | |
5 | + @register="register" | |
6 | + title="创建配置" | |
7 | + width="600px" | |
8 | + @visible-change="handleShow" | |
9 | + @ok="handleOk" | |
10 | + > | |
11 | + <BasicForm @register="registerForm" /> | |
12 | + </BasicModal> | |
13 | +</template> | |
14 | +<script lang="ts"> | |
15 | + import { defineComponent, ref, defineEmits } from 'vue'; | |
16 | + import { BasicModal, useModalInner } from '/@/components/Modal'; | |
17 | + import { orderGravity } from '/@/api/project/order'; | |
18 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | |
19 | + import { useOrderInfo } from '/@/hooks/component/order'; | |
20 | + import { BasicForm, useForm } from '/@/components/Form/index'; | |
21 | + import { addConfig } from '/@/api/sys/config'; | |
22 | + | |
23 | + export default defineComponent({ | |
24 | + components: { BasicModal, BasicForm }, | |
25 | + props: { | |
26 | + column: { type: Number }, | |
27 | + }, | |
28 | + emits: ['modal-success'], | |
29 | + setup(props, { emit }) { | |
30 | + const orderStore = useOrderStoreWithOut(); | |
31 | + const { manualPreform, exchangeRate } = useOrderInfo(orderStore); | |
32 | + const loading = ref(true); | |
33 | + const activeUser = ref(); | |
34 | + const info = ref(); | |
35 | + const searchData = ref({}); | |
36 | + const [register, { setModalProps, closeModal }] = useModalInner(async (data) => { | |
37 | + searchData.value = data.data || {}; | |
38 | + activeUser.value = undefined; | |
39 | + info.value = ''; | |
40 | + }); | |
41 | + | |
42 | + const { customerCode: customerCodeOptions } = useOrderInfo(orderStore); | |
43 | + var [registerForm, { getFieldsValue, validate }] = useForm({ | |
44 | + labelWidth: 80, | |
45 | + schemas: [ | |
46 | + { | |
47 | + field: 'settingValue', | |
48 | + component: 'Select', | |
49 | + label: '客户编码', | |
50 | + rules: [{ required: true }], | |
51 | + componentProps: { | |
52 | + options: customerCodeOptions, | |
53 | + }, | |
54 | + colProps: { | |
55 | + span: 24, | |
56 | + }, | |
57 | + }, | |
58 | + { | |
59 | + field: 'relationValue', | |
60 | + component: 'InputNumber', | |
61 | + label: props.column === 1 ? '利润率' : '包装费用', | |
62 | + rules: [{ required: true }], | |
63 | + colProps: { | |
64 | + span: 24, | |
65 | + }, | |
66 | + }, | |
67 | + ], | |
68 | + showActionButtonGroup: false, | |
69 | + actionColOptions: { | |
70 | + span: 24, | |
71 | + }, | |
72 | + }); | |
73 | + | |
74 | + function handleShow(visible: boolean) { | |
75 | + if (visible) { | |
76 | + loading.value = true; | |
77 | + // setModalProps({ loading: true, confirmLoading: true }); | |
78 | + setModalProps({ loading: false, confirmLoading: false }); | |
79 | + } | |
80 | + } | |
81 | + | |
82 | + async function handleCalc() { | |
83 | + const res = await orderGravity({ | |
84 | + ...searchData.value, | |
85 | + designer: activeUser.value, | |
86 | + }); | |
87 | + info.value = res?.rate || 0; | |
88 | + } | |
89 | + | |
90 | + async function handleOk() { | |
91 | + try { | |
92 | + const values = getFieldsValue(); | |
93 | + await validate(); | |
94 | + const params = { | |
95 | + settingCode: 'customerCode', | |
96 | + settingName: '客户编码', | |
97 | + settingValue: values.settingValue, | |
98 | + settingType: 1, | |
99 | + relationCode: props.column === 1 ? 'profitRate' : 'packetPrice', | |
100 | + relationName: '包装费用', | |
101 | + relationValue: values.relationValue, | |
102 | + }; | |
103 | + | |
104 | + await addConfig(params); | |
105 | + emit('modal-success'); | |
106 | + closeModal(); | |
107 | + } catch (error) { | |
108 | + console.log('%c [ error ]-108', 'font-size:13px; background:pink; color:#bf2c9f;', error); | |
109 | + } | |
110 | + } | |
111 | + return { | |
112 | + register, | |
113 | + loading, | |
114 | + handleShow, | |
115 | + info, | |
116 | + manualPreform, | |
117 | + handleCalc, | |
118 | + activeUser, | |
119 | + exchangeRate, | |
120 | + registerForm, | |
121 | + handleOk, | |
122 | + }; | |
123 | + }, | |
124 | + }); | |
125 | +</script> | |
126 | +<style scoped> | |
127 | + .empty-tips { | |
128 | + height: 100px; | |
129 | + line-height: 100px; | |
130 | + text-align: center; | |
131 | + } | |
132 | +</style> | ... | ... |
src/views/project/config/TablePanel.vue
0 → 100644
1 | +<template> | |
2 | + <BasicTable @register="registerTable"> | |
3 | + <template #toolbar> | |
4 | + <a-button v-if="props.column !== 3" type="primary" @click="handleCreateModal">新建</a-button> | |
5 | + </template> | |
6 | + <template #bodyCell="{ column, record }"> | |
7 | + <template v-if="column.key === 'action'"> | |
8 | + <TableAction :actions="createActions(record)" /> | |
9 | + </template> | |
10 | + </template> | |
11 | + </BasicTable> | |
12 | + <CreateModal | |
13 | + @register="createModalRegister" | |
14 | + @modal-success="handleModalSuccess" | |
15 | + :column="props.column" | |
16 | + /> | |
17 | +</template> | |
18 | +<script setup lang="ts"> | |
19 | + import { BasicTable, useTable, TableAction } from '/@/components/Table'; | |
20 | + import CreateModal from './CreateModal.vue'; | |
21 | + import { deleteConfig, getList, saveConfig } from '/@/api/sys/config'; | |
22 | + import { COLUMNS } from './data'; | |
23 | + import { useModal } from '/@/components/Modal'; | |
24 | + | |
25 | + const props = defineProps({ | |
26 | + searchInfo: { | |
27 | + type: Object, | |
28 | + }, | |
29 | + column: { | |
30 | + type: Number, | |
31 | + }, | |
32 | + }); | |
33 | + const [createModalRegister, { openModal }] = useModal(); | |
34 | + | |
35 | + const [registerTable, { reload }] = useTable({ | |
36 | + api: getList, | |
37 | + searchInfo: props.searchInfo, | |
38 | + | |
39 | + columns: COLUMNS[props.column!], | |
40 | + rowKey: 'id', | |
41 | + actionColumn: { | |
42 | + width: 160, | |
43 | + title: 'Action', | |
44 | + dataIndex: 'action', | |
45 | + }, | |
46 | + }); | |
47 | + | |
48 | + function handleCreateModal() { | |
49 | + openModal(true); | |
50 | + } | |
51 | + | |
52 | + function createActions(record: any): any[] { | |
53 | + if (!record.editable) { | |
54 | + return [ | |
55 | + { | |
56 | + label: '编辑', | |
57 | + onClick: handleEdit.bind(null, record), | |
58 | + }, | |
59 | + { | |
60 | + ...(props.column !== 3 && { | |
61 | + label: '删除', | |
62 | + // onClick: handleDelete.bind(null, record), | |
63 | + popConfirm: { | |
64 | + title: '确认删除?', | |
65 | + confirm: handleDelete.bind(null, record), | |
66 | + }, | |
67 | + }), | |
68 | + }, | |
69 | + ]; | |
70 | + } | |
71 | + return [ | |
72 | + { | |
73 | + label: '保存', | |
74 | + onClick: handleSave.bind(null, record), | |
75 | + }, | |
76 | + { | |
77 | + label: '取消', | |
78 | + popConfirm: { | |
79 | + title: '是否取消编辑', | |
80 | + confirm: handleCancel.bind(null, record), | |
81 | + }, | |
82 | + }, | |
83 | + ]; | |
84 | + } | |
85 | + | |
86 | + async function handleSave(record) { | |
87 | + await saveConfig({ id: record.id, settingValue: record.settingValue }); | |
88 | + handleCancel(record); | |
89 | + reload(); | |
90 | + } | |
91 | + | |
92 | + function handleEdit(record: any) { | |
93 | + record.onEdit?.(true); | |
94 | + } | |
95 | + | |
96 | + function handleCancel(record) { | |
97 | + record.onEdit?.(false, false); | |
98 | + } | |
99 | + | |
100 | + function handleModalSuccess() { | |
101 | + reload(); | |
102 | + } | |
103 | + | |
104 | + async function handleDelete(record) { | |
105 | + await deleteConfig({ ids: [record.id] }); | |
106 | + reload(); | |
107 | + } | |
108 | +</script> | |
109 | +<style></style> | ... | ... |
src/views/project/config/data.ts
0 → 100644
1 | +export const COLUMNS = { | |
2 | + 1: [ | |
3 | + { | |
4 | + title: '客户编码', | |
5 | + dataIndex: 'settingValue', | |
6 | + width: 150, | |
7 | + }, | |
8 | + { | |
9 | + title: '利润率', | |
10 | + dataIndex: 'relationValue', | |
11 | + width: 150, | |
12 | + editComponent: 'InputNumber', | |
13 | + editRow: true, | |
14 | + }, | |
15 | + ], | |
16 | + 2: [ | |
17 | + { | |
18 | + title: '客户编码', | |
19 | + dataIndex: 'settingValue', | |
20 | + width: 150, | |
21 | + }, | |
22 | + { | |
23 | + title: '包装费用', | |
24 | + dataIndex: 'relationValue', | |
25 | + width: 150, | |
26 | + editComponent: 'InputNumber', | |
27 | + editRow: true, | |
28 | + }, | |
29 | + ], | |
30 | + 3: [ | |
31 | + { | |
32 | + title: '名称', | |
33 | + dataIndex: 'settingName', | |
34 | + width: 150, | |
35 | + }, | |
36 | + { | |
37 | + title: '值', | |
38 | + dataIndex: 'settingValue', | |
39 | + width: 150, | |
40 | + editComponent: 'InputNumber', | |
41 | + editRow: true, | |
42 | + }, | |
43 | + ], | |
44 | +}; | ... | ... |
src/views/project/config/index.vue
0 → 100644
1 | +<template> | |
2 | + <PageWrapper contentBackground> | |
3 | + <div className="config-page"> | |
4 | + <Tabs v-model:selectedKey="currentKey" className="ml-2 mb-0"> | |
5 | + <Tabs.TabPane key="1" tab="利润率配置"> | |
6 | + <TablePanel :searchInfo="{ relationCode: 'profitRate' }" :column="1" /> | |
7 | + </Tabs.TabPane> | |
8 | + <Tabs.TabPane key="2" tab="包装费用配置"> | |
9 | + <TablePanel :searchInfo="{ relationCode: 'packetPrice' }" :column="2" /> | |
10 | + </Tabs.TabPane> | |
11 | + <Tabs.TabPane key="3" tab="汇率配置"> | |
12 | + <TablePanel :searchInfo="{ settingCode: 'exchangeRate' }" :column="3" | |
13 | + /></Tabs.TabPane> | |
14 | + </Tabs> | |
15 | + </div> | |
16 | + </PageWrapper> | |
17 | +</template> | |
18 | + | |
19 | +<script setup lang="ts"> | |
20 | + import { Tabs } from 'ant-design-vue'; | |
21 | + import { PageWrapper } from '/@/components/Page'; | |
22 | + import TablePanel from './TablePanel.vue'; | |
23 | + import { onMounted } from 'vue'; | |
24 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | |
25 | + | |
26 | + let currentKey = '1'; | |
27 | + const orderStore = useOrderStoreWithOut(); | |
28 | + | |
29 | + onMounted(async () => { | |
30 | + await orderStore.getDict(); | |
31 | + }); | |
32 | +</script> | |
33 | + | |
34 | +<style> | |
35 | + .config-page .ant-tabs-nav-operations ant-tabs-nav-operations-hidden { | |
36 | + display: none; | |
37 | + } | |
38 | + | |
39 | + .config-page .ant-tabs-nav { | |
40 | + margin-bottom: 0; | |
41 | + } | |
42 | +</style> | ... | ... |
src/views/project/order/CheckDetail.vue
... | ... | @@ -12,8 +12,10 @@ |
12 | 12 | okText="申请" |
13 | 13 | ><input /> |
14 | 14 | <div> |
15 | - <h3>基本信息</h3> | |
16 | - <BasicForm @register="registerForm" /> | |
15 | + <template v-if="role === ROLE.ADMIN || role === ROLE.TRACKER"> | |
16 | + <h3>基本信息</h3> | |
17 | + <BasicForm @register="registerForm" /> | |
18 | + </template> | |
17 | 19 | <template v-if="role === ROLE.ADMIN || role === ROLE.BUSINESS"> |
18 | 20 | <h3>利润分析</h3> |
19 | 21 | <BasicForm @register="registerProfitForm" /> |
... | ... | @@ -56,19 +58,21 @@ |
56 | 58 | |
57 | 59 | const userStore = useUserStoreWithOut(); |
58 | 60 | const getSchema = (fields) => |
59 | - fields.map((item) => ({ | |
60 | - field: `${item.field}`, | |
61 | - dataIndex: `${item.field}`, | |
62 | - label: item.label, | |
63 | - component: 'Switch', | |
64 | - componentProps: { | |
65 | - checkedValue: 'UN_LOCKED', | |
66 | - unCheckedValue: 'LOCKED', | |
67 | - }, | |
68 | - colProps: { | |
69 | - span: 6, | |
70 | - }, | |
71 | - })); | |
61 | + fields | |
62 | + .map((item) => ({ | |
63 | + field: `${item.field}`, | |
64 | + dataIndex: `${item.field}`, | |
65 | + label: item.label, | |
66 | + component: 'Switch', | |
67 | + componentProps: { | |
68 | + checkedValue: 'UN_LOCKED', | |
69 | + unCheckedValue: 'LOCKED', | |
70 | + }, | |
71 | + colProps: { | |
72 | + span: 6, | |
73 | + }, | |
74 | + })) | |
75 | + .filter((item) => item.field !== 'packetPrice' && item.field !== 'exchangeRate'); | |
72 | 76 | |
73 | 77 | export default defineComponent({ |
74 | 78 | components: { BasicDrawer, BasicForm }, | ... | ... |
src/views/project/order/ExportModal.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + destroyOnClose | |
5 | + @register="register" | |
6 | + title="利润分析表" | |
7 | + width="500px" | |
8 | + :height="100" | |
9 | + wrapClassName="h-[260px]" | |
10 | + @visible-change="handleShow" | |
11 | + :footer="null" | |
12 | + > | |
13 | + <CheckboxGroup v-model:value="checkedList" :options="options" /> | |
14 | + <div className="mt-6"> | |
15 | + <a-button type="primary" @click="handleCalc" className="ml-4">导出</a-button> | |
16 | + </div> | |
17 | + </BasicModal> | |
18 | +</template> | |
19 | +<script lang="ts"> | |
20 | + import { defineComponent, ref, computed } from 'vue'; | |
21 | + import { BasicModal, useModalInner } from '/@/components/Modal'; | |
22 | + import { orderExport } from '/@/api/project/order'; | |
23 | + import { ROLE } from './type.d'; | |
24 | + import { CheckboxGroup } from 'ant-design-vue'; | |
25 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | |
26 | + import { useOrderInfo } from '/@/hooks/component/order'; | |
27 | + import { merge } from 'lodash-es'; | |
28 | + import { | |
29 | + ORDER_LIST_BASE_FIELDS, | |
30 | + ORDER_LIST_REPORT_FIELDS, | |
31 | + ORDER_LIST_PROFIT_FIELDS, | |
32 | + ORDER_LIST_INSPECT_FIELDS, | |
33 | + ORDER_LIST_TRACK_FIELDS, | |
34 | + } from './tableData'; | |
35 | + | |
36 | + export default defineComponent({ | |
37 | + components: { BasicModal, CheckboxGroup }, | |
38 | + props: { | |
39 | + role: { | |
40 | + type: String, | |
41 | + }, | |
42 | + }, | |
43 | + setup(props) { | |
44 | + const orderStore = useOrderStoreWithOut(); | |
45 | + const { manualPreform, exchangeRate } = useOrderInfo(orderStore); | |
46 | + const checkedList = ref([ | |
47 | + 'baseFields', | |
48 | + 'reportFields', | |
49 | + 'profitAnalysisFields', | |
50 | + 'trackStageFields', | |
51 | + 'inspectionStageFields', | |
52 | + ]); | |
53 | + const loading = ref(true); | |
54 | + const activeUser = ref(); | |
55 | + const info = ref(); | |
56 | + const searchData = ref({}); | |
57 | + const [register, { setModalProps, closeModal }] = useModalInner(async (data) => { | |
58 | + searchData.value = data.data || {}; | |
59 | + activeUser.value = undefined; | |
60 | + info.value = ''; | |
61 | + }); | |
62 | + | |
63 | + const options = computed(() => { | |
64 | + if (props.role === ROLE.TRACKER) { | |
65 | + return [ | |
66 | + { label: '基本信息', value: 'baseFields' }, | |
67 | + { label: '利润分析', value: 'profitAnalysisFields' }, | |
68 | + { label: '跟单信息', value: 'trackStageFields' }, | |
69 | + { label: '质检信息', value: 'inspectionStageFields' }, | |
70 | + ]; | |
71 | + } | |
72 | + if (props.role === ROLE.INSPECT) { | |
73 | + return [ | |
74 | + { label: '基本信息', value: 'baseFields' }, | |
75 | + { label: '跟单信息', value: 'trackStageFields' }, | |
76 | + { label: '质检信息', value: 'inspectionStageFields' }, | |
77 | + ]; | |
78 | + } | |
79 | + return [ | |
80 | + { label: '基本信息', value: 'baseFields' }, | |
81 | + { label: '项目报告', value: 'reportFields' }, | |
82 | + { label: '利润分析', value: 'profitAnalysisFields' }, | |
83 | + { label: '跟单信息', value: 'trackStageFields' }, | |
84 | + { label: '质检信息', value: 'inspectionStageFields' }, | |
85 | + ]; | |
86 | + }); | |
87 | + | |
88 | + function handleShow(visible: boolean) { | |
89 | + if (visible) { | |
90 | + loading.value = true; | |
91 | + setModalProps({ loading: false, confirmLoading: false }); | |
92 | + } | |
93 | + } | |
94 | + | |
95 | + async function handleCalc() { | |
96 | + const fieldVO: any = {}; | |
97 | + checkedList.value.forEach((item) => { | |
98 | + if (item === 'baseFields') { | |
99 | + fieldVO.baseFields = ORDER_LIST_BASE_FIELDS.map((item) => ({ | |
100 | + [item.dataIndex]: 'selected', | |
101 | + })); | |
102 | + fieldVO.baseFields = merge({}, ...fieldVO.baseFields); | |
103 | + } else if (item === 'reportFields') { | |
104 | + fieldVO.reportFields = ORDER_LIST_REPORT_FIELDS[0].children.map((item) => ({ | |
105 | + [item.dataIndex]: 'selected', | |
106 | + })); | |
107 | + fieldVO.reportFields = merge({}, ...fieldVO.reportFields); | |
108 | + } else if (item === 'profitAnalysisFields') { | |
109 | + if (props.role === ROLE.TRACKER) { | |
110 | + fieldVO.profitAnalysisFields = ORDER_LIST_PROFIT_FIELDS[0].children | |
111 | + .filter( | |
112 | + (k) => k.dataIndex === 'customerPrice' || k.dataIndex === 'customerTotalPrice', | |
113 | + ) | |
114 | + .map((item) => ({ | |
115 | + [item.dataIndex]: 'selected', | |
116 | + })); | |
117 | + } else { | |
118 | + fieldVO.profitAnalysisFields = ORDER_LIST_PROFIT_FIELDS[0].children.map((item) => ({ | |
119 | + [item.dataIndex]: 'selected', | |
120 | + })); | |
121 | + } | |
122 | + fieldVO.profitAnalysisFields = merge({}, ...fieldVO.profitAnalysisFields); | |
123 | + } else if (item === 'trackStageFields') { | |
124 | + fieldVO.trackStageFields = ORDER_LIST_TRACK_FIELDS[0].children.map((item) => ({ | |
125 | + [item.dataIndex]: 'selected', | |
126 | + })); | |
127 | + fieldVO.trackStageFields = merge({}, ...fieldVO.trackStageFields); | |
128 | + } else if (item === 'inspectionStageFields') { | |
129 | + fieldVO.inspectionStageFields = ORDER_LIST_INSPECT_FIELDS[0].children.map((item) => ({ | |
130 | + [item.dataIndex]: 'selected', | |
131 | + })); | |
132 | + fieldVO.inspectionStageFields = merge({}, ...fieldVO.inspectionStageFields); | |
133 | + } | |
134 | + }); | |
135 | + | |
136 | + await orderExport({ fieldVO }); | |
137 | + | |
138 | + closeModal(); | |
139 | + } | |
140 | + return { | |
141 | + register, | |
142 | + options, | |
143 | + loading, | |
144 | + handleShow, | |
145 | + info, | |
146 | + manualPreform, | |
147 | + handleCalc, | |
148 | + activeUser, | |
149 | + exchangeRate, | |
150 | + checkedList, | |
151 | + }; | |
152 | + }, | |
153 | + }); | |
154 | +</script> | ... | ... |
src/views/project/order/FieldDetail.vue
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | <BasicDrawer |
3 | 3 | @register="register" |
4 | 4 | v-bind="$attrs" |
5 | - title="title" | |
5 | + title="字段自定义" | |
6 | 6 | :destroyOnClose="true" |
7 | 7 | width="60%" |
8 | 8 | :isDetail="true" |
... | ... | @@ -55,7 +55,7 @@ |
55 | 55 | setup() { |
56 | 56 | const dataSource = ref([]); |
57 | 57 | const key = ref(''); |
58 | - const title = ref(''); | |
58 | + const title = ref('12'); | |
59 | 59 | |
60 | 60 | const [registerTable, { getDataSource, reload }] = useTable({ |
61 | 61 | columns: columns, |
... | ... | @@ -72,11 +72,18 @@ |
72 | 72 | }); |
73 | 73 | |
74 | 74 | const [register] = useDrawerInner((data) => { |
75 | - const { dataIndex, customTitle } = data; | |
75 | + let { dataIndex, customTitle } = data; | |
76 | + | |
77 | + // 如果dataIndex= 手工初型1或者2,则等于手工初型 | |
78 | + if (dataIndex === 'manualPreform1' || dataIndex == 'manualPreform2') { | |
79 | + dataIndex = 'manualPreform'; | |
80 | + } | |
76 | 81 | const dicts = orderStore.getDictInfo; |
77 | 82 | const dict = dicts[dataIndex]; |
78 | 83 | dataSource.value = dict; |
84 | + | |
79 | 85 | title.value = customTitle; |
86 | + | |
80 | 87 | key.value = dataIndex; |
81 | 88 | }); |
82 | 89 | |
... | ... | @@ -95,13 +102,13 @@ |
95 | 102 | |
96 | 103 | async function handleSave(record: EditRecordRow) { |
97 | 104 | if (record.id) { |
98 | - await dictUpdate({ dictCode: key.value, dictValue: record.dictValue }); | |
105 | + await dictUpdate({ id: record.id, dictCode: key.value, dictValue: record.dictValue }); | |
99 | 106 | } else { |
100 | 107 | await dictCreate({ |
101 | 108 | dictName: title.value, |
102 | 109 | dictCode: key.value, |
103 | 110 | dictValue: record.dictValue, |
104 | - sort: dataSource.value.length + 1, | |
111 | + sort: (dataSource.value?.length || 0) + 1, | |
105 | 112 | }); |
106 | 113 | } |
107 | 114 | ... | ... |
src/views/project/order/FormDetail/BaseFormPanel.vue
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | import { computed, defineComponent, ref } from 'vue'; |
6 | 6 | import { BasicForm, useForm } from '/@/components/Form/index'; |
7 | 7 | import { FIELDS_BASE_INFO } from '../tableData'; |
8 | - import { getDisable } from '/@/utils/project'; | |
8 | + import { getBaseDisable } from '/@/utils/project'; | |
9 | 9 | import { useOrderStoreWithOut } from '/@/store/modules/order'; |
10 | 10 | |
11 | 11 | import { useOrderInfo } from '/@/hooks/component/order'; |
... | ... | @@ -24,6 +24,9 @@ |
24 | 24 | id: { |
25 | 25 | type: String, |
26 | 26 | }, |
27 | + businessUsers: { | |
28 | + type: Array, | |
29 | + }, | |
27 | 30 | }, |
28 | 31 | emits: ['success'], |
29 | 32 | setup(props) { |
... | ... | @@ -42,7 +45,14 @@ |
42 | 45 | productStyle, |
43 | 46 | outboundType, |
44 | 47 | packetType, |
48 | + | |
49 | + // businessPerson, | |
45 | 50 | } = useOrderInfo(orderStore); |
51 | + console.log( | |
52 | + '%c [ productionDepartment ]-57', | |
53 | + 'font-size:13px; background:pink; color:#bf2c9f;', | |
54 | + productionDepartment, | |
55 | + ); | |
46 | 56 | |
47 | 57 | var schemas = computed(() => { |
48 | 58 | const options = { |
... | ... | @@ -55,14 +65,11 @@ |
55 | 65 | productStyle, |
56 | 66 | outboundType, |
57 | 67 | packetType, |
68 | + | |
69 | + businessPerson: props.businessUsers, | |
58 | 70 | }; |
59 | 71 | |
60 | 72 | const res = FIELDS_BASE_INFO.map((item) => { |
61 | - console.log( | |
62 | - '%c [ ]-62', | |
63 | - 'font-size:13px; background:pink; color:#bf2c9f;', | |
64 | - getDisable(fields.value?.baseFields?.picUrl, props.id), | |
65 | - ); | |
66 | 73 | if (item.field === 'picUrl') { |
67 | 74 | return { |
68 | 75 | field: 'picUrl', |
... | ... | @@ -74,7 +81,7 @@ |
74 | 81 | }, |
75 | 82 | componentProps: { |
76 | 83 | imgUrl: picUrl.value, |
77 | - disabled: getDisable(get(fields.value, 'picUrl'), props.id), | |
84 | + // disabled: getDisable(get(fields.value, 'picUrl'), props.id), | |
78 | 85 | onChange: (res) => { |
79 | 86 | if (res.file?.response?.data) { |
80 | 87 | picUrl.value = res.file?.response?.data?.picUrl; |
... | ... | @@ -87,12 +94,20 @@ |
87 | 94 | }, |
88 | 95 | }; |
89 | 96 | } |
97 | + | |
98 | + console.log( | |
99 | + '%c [ ]-98', | |
100 | + 'font-size:13px; background:pink; color:#bf2c9f;', | |
101 | + item.field, | |
102 | + options[item.field], | |
103 | + ); | |
104 | + | |
90 | 105 | return { |
91 | 106 | ...item, |
92 | 107 | field: `${item.field}`, |
93 | 108 | componentProps: { |
94 | 109 | ...(item.component === 'Select' && { options: options[item.field] }), |
95 | - disabled: getDisable(get(fields.value, `${item.field}`), props.id), | |
110 | + disabled: getBaseDisable(item.field, get(fields.value, `${item.field}`), props.id), | |
96 | 111 | }, |
97 | 112 | colProps: { |
98 | 113 | span: 24, | ... | ... |
src/views/project/order/FormDetail/InspectionFormPanel.vue
... | ... | @@ -2,10 +2,8 @@ |
2 | 2 | <BasicForm @register="registerForm" /> |
3 | 3 | </template> |
4 | 4 | <script lang="ts"> |
5 | - import { computed, defineComponent, ref, toRaw } from 'vue'; | |
5 | + import { computed, defineComponent, ref } from 'vue'; | |
6 | 6 | import { BasicForm, useForm } from '/@/components/Form/index'; |
7 | - import { useDrawerInner } from '/@/components/Drawer'; | |
8 | - import { dateUtil } from '/@/utils/dateUtil'; | |
9 | 7 | import { FIELDS_INSPECTION_INFO } from '../tableData'; |
10 | 8 | import { getDisable } from '/@/utils/project'; |
11 | 9 | import { useOrderStoreWithOut } from '/@/store/modules/order'; |
... | ... | @@ -19,6 +17,9 @@ |
19 | 17 | id: { |
20 | 18 | type: String, |
21 | 19 | }, |
20 | + inspectFormData: { | |
21 | + type: Object, | |
22 | + }, | |
22 | 23 | }, |
23 | 24 | emits: ['success'], |
24 | 25 | setup(props, { emit }) { |
... | ... | @@ -37,7 +38,11 @@ |
37 | 38 | ...item, |
38 | 39 | componentProps: { |
39 | 40 | ...(item.component === 'Select' && { options: options[item.field] }), |
40 | - disabled: getDisable(get(fields.value, item.field), props.id), | |
41 | + disabled: getDisable( | |
42 | + get(fields.value, item.field), | |
43 | + props.id, | |
44 | + get(props.inspectFormData, `${item.field}`), | |
45 | + ), | |
41 | 46 | }, |
42 | 47 | colProps: { |
43 | 48 | span: 24, | ... | ... |
src/views/project/order/FormDetail/ProfitFormPanel.vue
... | ... | @@ -4,37 +4,52 @@ |
4 | 4 | <script lang="ts"> |
5 | 5 | import { computed, defineComponent, reactive, ref, toRaw } from 'vue'; |
6 | 6 | import { BasicForm, useForm } from '/@/components/Form/index'; |
7 | - import { dateUtil } from '/@/utils/dateUtil'; | |
8 | 7 | import { FIELDS_PROFIT_INFO } from '../tableData'; |
9 | - import { getDisable } from '/@/utils/project'; | |
8 | + import { getProfitDisable } from '/@/utils/project'; | |
10 | 9 | import { get } from 'lodash-es'; |
10 | + import { useOrderInfo } from '/@/hooks/component/order'; | |
11 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | |
11 | 12 | |
12 | 13 | export default defineComponent({ |
13 | 14 | components: { BasicForm }, |
14 | 15 | |
15 | 16 | props: { |
16 | - detailData: { | |
17 | - type: Object, | |
18 | - }, | |
19 | 17 | onGoCheckDetail: { |
20 | 18 | type: Function, |
21 | 19 | }, |
22 | 20 | id: { |
23 | 21 | type: String, |
24 | 22 | }, |
23 | + profitFormData: { | |
24 | + type: Object, | |
25 | + }, | |
25 | 26 | }, |
26 | 27 | emits: ['success'], |
27 | 28 | setup(props, { emit }) { |
28 | 29 | let fields = ref({}); |
30 | + const orderStore = useOrderStoreWithOut(); | |
31 | + | |
32 | + const { exchangeRate } = useOrderInfo(orderStore); | |
29 | 33 | |
30 | 34 | const schemas = computed(() => { |
35 | + const options = { | |
36 | + exchangeRate, | |
37 | + }; | |
38 | + | |
31 | 39 | return FIELDS_PROFIT_INFO.map((item) => { |
32 | 40 | return { |
33 | 41 | ...item, |
34 | 42 | field: `${item.field}`, |
35 | 43 | componentProps: { |
36 | 44 | ...item.componentProps, |
37 | - disabled: getDisable(get(fields.value, `${item.field}`), props.id), | |
45 | + ...(item.component === 'Select' && | |
46 | + !item.componentProps?.options?.length && { options: options[item.field] }), | |
47 | + disabled: getProfitDisable( | |
48 | + item.field, | |
49 | + get(fields.value, `${item.field}`), | |
50 | + props.id, | |
51 | + get(props.profitFormData, `${item.field}`), | |
52 | + ), | |
38 | 53 | }, |
39 | 54 | colProps: { |
40 | 55 | span: 24, |
... | ... | @@ -43,7 +58,7 @@ |
43 | 58 | }); |
44 | 59 | }); |
45 | 60 | |
46 | - const [registerForm, { setFieldsValue, getFieldsValue, resetFields }] = useForm({ | |
61 | + const [registerForm, { setFieldsValue, getFieldsValue, resetFields, validate }] = useForm({ | |
47 | 62 | labelWidth: 120, |
48 | 63 | schemas, |
49 | 64 | layout: 'vertical', |
... | ... | @@ -52,7 +67,16 @@ |
52 | 67 | span: 24, |
53 | 68 | }, |
54 | 69 | }); |
55 | - return { fields, schemas, registerForm, getFieldsValue, setFieldsValue, resetFields }; | |
70 | + | |
71 | + return { | |
72 | + fields, | |
73 | + schemas, | |
74 | + validate, | |
75 | + registerForm, | |
76 | + getFieldsValue, | |
77 | + setFieldsValue, | |
78 | + resetFields, | |
79 | + }; | |
56 | 80 | }, |
57 | 81 | }); |
58 | 82 | </script> | ... | ... |
src/views/project/order/FormDetail/ReportFormPanel.vue
... | ... | @@ -24,6 +24,9 @@ |
24 | 24 | id: { |
25 | 25 | type: String, |
26 | 26 | }, |
27 | + reportFormData: { | |
28 | + type: Object, | |
29 | + }, | |
27 | 30 | }, |
28 | 31 | emits: ['success'], |
29 | 32 | setup(props) { |
... | ... | @@ -39,12 +42,20 @@ |
39 | 42 | }; |
40 | 43 | |
41 | 44 | const res = FIELDS_REPORT_INFO.map((item) => { |
45 | + let optionsField = item.field; | |
46 | + if (optionsField === 'manualPreform1' || optionsField === 'manualPreform2') { | |
47 | + optionsField = 'manualPreform'; | |
48 | + } | |
42 | 49 | return { |
43 | 50 | ...item, |
44 | 51 | field: `${item.field}`, |
45 | 52 | componentProps: { |
46 | - ...(item.component === 'Select' && { options: options[item.optionField] }), | |
47 | - disabled: getDisable(get(fields.value, `${item.field}`), props.id), | |
53 | + ...(item.component === 'Select' && { options: options[optionsField] }), | |
54 | + disabled: getDisable( | |
55 | + get(fields.value, `${item.field}`), | |
56 | + props.id, | |
57 | + get(props.reportFormData, `${item.field}`), | |
58 | + ), | |
48 | 59 | }, |
49 | 60 | colProps: { |
50 | 61 | span: 24, |
... | ... | @@ -54,7 +65,7 @@ |
54 | 65 | return res; |
55 | 66 | }); |
56 | 67 | |
57 | - const [registerForm, { setFieldsValue, getFieldsValue }] = useForm({ | |
68 | + const [registerForm, { setFieldsValue, getFieldsValue, resetFields, validate }] = useForm({ | |
58 | 69 | labelWidth: 120, |
59 | 70 | schemas, |
60 | 71 | layout: 'vertical', |
... | ... | @@ -64,7 +75,15 @@ |
64 | 75 | }, |
65 | 76 | }); |
66 | 77 | |
67 | - return { fields, schemas, registerForm, getFieldsValue, setFieldsValue }; | |
78 | + return { | |
79 | + fields, | |
80 | + schemas, | |
81 | + validate, | |
82 | + registerForm, | |
83 | + getFieldsValue, | |
84 | + setFieldsValue, | |
85 | + resetFields, | |
86 | + }; | |
68 | 87 | }, |
69 | 88 | }); |
70 | 89 | </script> | ... | ... |
src/views/project/order/FormDetail/TrackFormPanel.vue
... | ... | @@ -17,6 +17,9 @@ |
17 | 17 | id: { |
18 | 18 | type: String, |
19 | 19 | }, |
20 | + trackFormData: { | |
21 | + type: Object, | |
22 | + }, | |
20 | 23 | }, |
21 | 24 | emits: ['success'], |
22 | 25 | setup(props, { emit }) { |
... | ... | @@ -27,7 +30,11 @@ |
27 | 30 | ...item, |
28 | 31 | componentProps: { |
29 | 32 | ...item.componentProps, |
30 | - disabled: getDisable(get(fields.value, `${item.field}`), props.id), | |
33 | + disabled: getDisable( | |
34 | + get(fields.value, `${item.field}`), | |
35 | + props.id, | |
36 | + get(props.trackFormData, `${item.field}`), | |
37 | + ), | |
31 | 38 | }, |
32 | 39 | colProps: { |
33 | 40 | span: 24, | ... | ... |
src/views/project/order/FormDetail/index.vue
... | ... | @@ -14,10 +14,15 @@ |
14 | 14 | :mask="false" |
15 | 15 | class="z-20" |
16 | 16 | > |
17 | - <div className="mt-[-16px]"> | |
17 | + <div className="mt-[-16px] order-drawer-panel"> | |
18 | 18 | <Tabs v-model:activeKey="activeKey"> |
19 | - <TabPanel key="1" tab="基本信息" :forceRender="true" v-if="role !== ROLE.INSPECT"> | |
20 | - <BaseFormPanel ref="baseFormPanelRef" :id="id" /> | |
19 | + <TabPanel | |
20 | + key="1" | |
21 | + tab="基本信息" | |
22 | + :forceRender="true" | |
23 | + v-if="role === ROLE.ADMIN || role === ROLE.TRACKER" | |
24 | + > | |
25 | + <BaseFormPanel ref="baseFormPanelRef" :id="id" :businessUsers="businessUsers" /> | |
21 | 26 | </TabPanel> |
22 | 27 | <TabPanel |
23 | 28 | key="2" |
... | ... | @@ -25,7 +30,7 @@ |
25 | 30 | :forceRender="true" |
26 | 31 | v-if="!!id && (role === ROLE.ADMIN || role === ROLE.BUSINESS)" |
27 | 32 | > |
28 | - <ProfitFormPanel ref="profitFormPanelRef" :id="id" /> | |
33 | + <ProfitFormPanel ref="profitFormPanelRef" :id="id" :profitFormData="profitFormData" /> | |
29 | 34 | </TabPanel> |
30 | 35 | <TabPanel |
31 | 36 | key="3" |
... | ... | @@ -33,7 +38,7 @@ |
33 | 38 | :forceRender="true" |
34 | 39 | v-if="!!id && (role === ROLE.ADMIN || role === ROLE.BUSINESS)" |
35 | 40 | > |
36 | - <ReportFormPanel ref="reportFormPanelRef" :id="id" /> | |
41 | + <ReportFormPanel ref="reportFormPanelRef" :id="id" :reportFormData="reportFormData" /> | |
37 | 42 | </TabPanel> |
38 | 43 | <TabPanel |
39 | 44 | key="4" |
... | ... | @@ -41,7 +46,7 @@ |
41 | 46 | :forceRender="true" |
42 | 47 | v-if="!!id && (role === ROLE.ADMIN || role === ROLE.TRACKER)" |
43 | 48 | > |
44 | - <TrackFormPanel ref="trackFormPanelRef" :id="id" /> | |
49 | + <TrackFormPanel ref="trackFormPanelRef" :id="id" :trackFormData="trackFormData" /> | |
45 | 50 | </TabPanel> |
46 | 51 | <TabPanel |
47 | 52 | key="5" |
... | ... | @@ -49,7 +54,11 @@ |
49 | 54 | :forceRender="true" |
50 | 55 | v-if="!!id && (role === ROLE.ADMIN || role === ROLE.INSPECT)" |
51 | 56 | > |
52 | - <InspectionFormPanel ref="inspectionFormPanelRef" :id="id" /> | |
57 | + <InspectionFormPanel | |
58 | + ref="inspectionFormPanelRef" | |
59 | + :id="id" | |
60 | + :inspectFormData="inspectFormData" | |
61 | + /> | |
53 | 62 | </TabPanel> |
54 | 63 | </Tabs> |
55 | 64 | </div> |
... | ... | @@ -61,7 +70,7 @@ |
61 | 70 | </BasicDrawer> |
62 | 71 | </template> |
63 | 72 | <script lang="ts"> |
64 | - import { computed, defineComponent, reactive, ref, toRaw, watch, toRefs } from 'vue'; | |
73 | + import { computed, defineComponent, reactive, ref, toRaw, watch, toRefs, onMounted } from 'vue'; | |
65 | 74 | import { FormActionType, FormSchema, useForm } from '/@/components/Form/index'; |
66 | 75 | import { orderCreate, orderUpdate, uploadImg } from '/@/api/project/order'; |
67 | 76 | import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; |
... | ... | @@ -73,8 +82,12 @@ |
73 | 82 | import BaseFormPanel from './BaseFormPanel.vue'; |
74 | 83 | import { useUserStoreWithOut } from '/@/store/modules/user'; |
75 | 84 | import { ROLE } from '../type.d'; |
85 | + import { getList as getConfigList } from '/@/api/sys/config'; | |
76 | 86 | |
77 | 87 | import { Tabs } from 'ant-design-vue'; |
88 | + import { find } from 'lodash-es'; | |
89 | + import { getUserList } from '/@/api/project/account'; | |
90 | + import message from '/@/views/form-design/utils/message'; | |
78 | 91 | |
79 | 92 | const userStore = useUserStoreWithOut(); |
80 | 93 | |
... | ... | @@ -109,8 +122,33 @@ |
109 | 122 | const trackFormPanelRef = ref(); |
110 | 123 | const inspectionFormPanelRef = ref(); |
111 | 124 | |
125 | + // 编辑从接口获取的value | |
126 | + const baseFormData = ref(); | |
127 | + const profitFormData = ref(); | |
128 | + const reportFormData = ref(); | |
129 | + const trackFormData = ref(); | |
130 | + const inspectFormData = ref(); | |
131 | + | |
112 | 132 | const formRef = ref<FormActionType | null>(null); |
113 | 133 | const id = ref(''); |
134 | + const configList = ref([]); | |
135 | + const businessUsers = ref([]); | |
136 | + | |
137 | + onMounted(async () => { | |
138 | + // 获取包装费用和客户编码的关联关系 | |
139 | + const res = await getConfigList({ | |
140 | + page: 1, | |
141 | + pageSize: 1000, | |
142 | + // relationCode: 'packetPrice', | |
143 | + }); | |
144 | + configList.value = res || []; | |
145 | + | |
146 | + // 获取业务员 | |
147 | + const res1 = await getUserList({ page: 1, pageSize: 1000 }); | |
148 | + businessUsers.value = res1.items | |
149 | + .filter((item) => item.roleCode === ROLE.BUSINESS) | |
150 | + .map((item) => ({ value: item.userName, label: item.userName })); | |
151 | + }); | |
114 | 152 | |
115 | 153 | const role = computed(() => { |
116 | 154 | return userStore.getUserInfo?.roleSmallVO?.code; |
... | ... | @@ -120,6 +158,8 @@ |
120 | 158 | let fields = reactive({ baseFields: {} }); |
121 | 159 | |
122 | 160 | const [register, { closeDrawer }] = useDrawerInner((data) => { |
161 | + activeKey.value = | |
162 | + role.value === ROLE.INSPECT ? '5' : role.value === ROLE.BUSINESS ? '2' : '1'; | |
123 | 163 | if (!data.id) { |
124 | 164 | id.value = ''; |
125 | 165 | picUrl.value = ''; |
... | ... | @@ -133,6 +173,10 @@ |
133 | 173 | return; |
134 | 174 | } |
135 | 175 | id.value = data.id; |
176 | + profitFormData.value = data.profitAnalysisInfo; | |
177 | + inspectFormData.value = data.inspectionStageInfo; | |
178 | + reportFormData.value = data.reportInfo; | |
179 | + trackFormData.value = data.trackStageInfo; | |
136 | 180 | |
137 | 181 | // 方式1 |
138 | 182 | picUrl.value = data.picUrl; |
... | ... | @@ -159,10 +203,22 @@ |
159 | 203 | } |
160 | 204 | |
161 | 205 | if (profitFormPanelRef.value) { |
206 | + // 包装费用通过客户编码去查 | |
207 | + const packetPrice = find(configList.value, (item) => { | |
208 | + return ( | |
209 | + data.customerCode === item.settingValue && item.relationCode === 'packetPrice' | |
210 | + ); | |
211 | + }); | |
212 | + | |
213 | + const exchangeRate = find(configList.value, (item) => { | |
214 | + return item.settingCode === 'exchangeRate'; | |
215 | + }); | |
162 | 216 | // 利润分析 |
163 | 217 | profitFormPanelRef.value.fields = { ...data.lockFields?.profitAnalysisFields } || {}; |
164 | 218 | profitFormPanelRef?.value?.setFieldsValue({ |
165 | 219 | ...toRaw(data.profitAnalysisInfo), |
220 | + packetPrice: packetPrice?.relationValue || 0, | |
221 | + exchangeRate: exchangeRate?.settingValue, | |
166 | 222 | }); |
167 | 223 | } |
168 | 224 | |
... | ... | @@ -186,7 +242,7 @@ |
186 | 242 | inspectionFormPanelRef.value.fields = |
187 | 243 | { ...data.lockFields?.inspectionStageFields } || {}; |
188 | 244 | inspectionFormPanelRef?.value?.setFieldsValue({ |
189 | - ...toRaw(data.trackStageInfo), | |
245 | + ...toRaw(data.inspectionStageInfo), | |
190 | 246 | }); |
191 | 247 | } |
192 | 248 | }, 100); |
... | ... | @@ -196,10 +252,10 @@ |
196 | 252 | }); |
197 | 253 | |
198 | 254 | const handleSubmit = async () => { |
199 | - if (id.value) { | |
200 | - const forms = { orderId: id.value } as any; | |
201 | - if (activeKey.value === '1') { | |
202 | - try { | |
255 | + try { | |
256 | + if (id.value) { | |
257 | + const forms = { orderId: id.value } as any; | |
258 | + if (activeKey.value === '1') { | |
203 | 259 | await baseFormPanelRef?.value?.validate(); |
204 | 260 | |
205 | 261 | forms.baseInfo = baseFormPanelRef?.value?.getFieldsValue() || {}; |
... | ... | @@ -211,25 +267,36 @@ |
211 | 267 | await orderUpdate(forms); |
212 | 268 | closeDrawer(); |
213 | 269 | emit('success', {}); |
214 | - } catch (error) { | |
215 | - console.log(error); | |
270 | + } else { | |
271 | + if (activeKey.value === '2') { | |
272 | + await profitFormPanelRef?.value?.validate(); | |
273 | + forms.profitAnalysisInfo = profitFormPanelRef?.value?.getFieldsValue() || {}; | |
274 | + // 方式如果没有变化,默认方式1 | |
275 | + if (!forms.profitAnalysisInfo.profitType) { | |
276 | + forms.profitAnalysisInfo.profitType = '0'; | |
277 | + } | |
278 | + } else if (activeKey.value === '3') { | |
279 | + await reportFormPanelRef?.value?.validate(); | |
280 | + // 比重相加等于1 | |
281 | + const values = reportFormPanelRef?.value?.getFieldsValue() || {}; | |
282 | + if ( | |
283 | + values.ideaSourceRate + values.manualPreform1Rate + values.manualPreform2Rate !== | |
284 | + 1 | |
285 | + ) { | |
286 | + return message.error('占比相加不等于1'); | |
287 | + } | |
288 | + | |
289 | + forms.reportInfo = values; | |
290 | + } else if (activeKey.value === '4') { | |
291 | + forms.trackStageInfo = trackFormPanelRef?.value?.getFieldsValue() || {}; | |
292 | + } else if (activeKey.value === '5') { | |
293 | + forms.inspectionStageInfo = inspectionFormPanelRef?.value?.getFieldsValue() || {}; | |
294 | + } | |
295 | + await orderUpdate(forms); | |
296 | + closeDrawer(); | |
297 | + emit('success', {}); | |
216 | 298 | } |
217 | 299 | } else { |
218 | - if (activeKey.value === '2') { | |
219 | - forms.profitAnalysisInfo = profitFormPanelRef?.value?.getFieldsValue() || {}; | |
220 | - } else if (activeKey.value === '3') { | |
221 | - forms.reportInfo = reportFormPanelRef?.value?.getFieldsValue() || {}; | |
222 | - } else if (activeKey.value === '4') { | |
223 | - forms.trackStageInfo = trackFormPanelRef?.value?.getFieldsValue() || {}; | |
224 | - } else if (activeKey.value === '5') { | |
225 | - forms.inspectionStageInfo = inspectionFormPanelRef?.value?.getFieldsValue() || {}; | |
226 | - } | |
227 | - await orderUpdate(forms); | |
228 | - closeDrawer(); | |
229 | - emit('success', {}); | |
230 | - } | |
231 | - } else { | |
232 | - try { | |
233 | 300 | await baseFormPanelRef?.value?.validate(); |
234 | 301 | |
235 | 302 | // 新建只有基本信息 |
... | ... | @@ -245,9 +312,9 @@ |
245 | 312 | await orderCreate(forms); |
246 | 313 | closeDrawer(); |
247 | 314 | emit('success', {}); |
248 | - } catch (error) { | |
249 | - console.log(error); | |
250 | 315 | } |
316 | + } catch (error) { | |
317 | + console.log(error); | |
251 | 318 | } |
252 | 319 | }; |
253 | 320 | return { |
... | ... | @@ -261,16 +328,25 @@ |
261 | 328 | formRef, |
262 | 329 | ROLE, |
263 | 330 | role, |
331 | + profitFormData, | |
332 | + inspectFormData, | |
333 | + reportFormData, | |
334 | + trackFormData, | |
264 | 335 | register, |
265 | 336 | handleSubmit, |
337 | + businessUsers, | |
266 | 338 | }; |
267 | 339 | }, |
268 | 340 | }); |
269 | 341 | </script> |
270 | 342 | |
271 | -<style scoped> | |
343 | +<style> | |
272 | 344 | .ant-drawer { |
273 | 345 | position: fixed; |
274 | 346 | z-index: 9999; |
275 | 347 | } |
348 | + | |
349 | + .order-drawer-panel .ant-picker { | |
350 | + width: 100% !important; | |
351 | + } | |
276 | 352 | </style> | ... | ... |
src/views/project/order/ProfitAnalysis.vue
... | ... | @@ -4,9 +4,31 @@ |
4 | 4 | destroyOnClose |
5 | 5 | @register="register" |
6 | 6 | title="利润分析表" |
7 | + width="600px" | |
7 | 8 | @visible-change="handleShow" |
8 | 9 | :footer="null" |
9 | 10 | > |
11 | + <div className="mb-2"> | |
12 | + 公示: | |
13 | + <Select | |
14 | + className="w-[200px]" | |
15 | + :options="[ | |
16 | + { label: '公示1:1 -(LOCAL总金额 / 汇率 + 包装总金额)/客户总金额', value: '0' }, | |
17 | + { label: '公示2:1 -(LOCAL总金额/汇率 / (客户总金额-包装费用总金额)', value: '1' }, | |
18 | + ]" | |
19 | + v-model:value="profitType" | |
20 | + placeholder="请选择" | |
21 | + default-value="0" | |
22 | + /> | |
23 | + </div> | |
24 | + <Space> | |
25 | + <span> | |
26 | + 汇率: | |
27 | + {{ activeRate }} | |
28 | + </span> | |
29 | + <a-button type="primary" @click="handleCalc" className="ml-4">计算</a-button> | |
30 | + </Space> | |
31 | + <!-- <Button @click="handleCalc">计算</Button> --> | |
10 | 32 | <!-- :helpMessage="['提示1', '提示2']" --> |
11 | 33 | <!-- <template #insertFooter> |
12 | 34 | <a-button type="primary" danger @click="setLines" :disabled="loading">点我更新内容</a-button> |
... | ... | @@ -25,24 +47,34 @@ |
25 | 47 | </BasicModal> |
26 | 48 | </template> |
27 | 49 | <script lang="ts"> |
28 | - import { defineComponent, ref, toRaw, watch } from 'vue'; | |
50 | + import { computed, defineComponent, onMounted, ref, toRaw, watch } from 'vue'; | |
29 | 51 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
30 | 52 | import { Description, DescItem, useDescription } from '/@/components/Description/index'; |
31 | 53 | import { orderAnalysis } from '/@/api/project/order'; |
54 | + import { Select, Space } from 'ant-design-vue'; | |
55 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | |
56 | + import { getList } from '/@/api/sys/config'; | |
57 | + import { useOrderInfo } from '/@/hooks/component/order'; | |
32 | 58 | |
33 | 59 | export default defineComponent({ |
34 | - components: { BasicModal, Description }, | |
60 | + components: { BasicModal, Description, Select, Space }, | |
35 | 61 | setup() { |
62 | + const orderStore = useOrderStoreWithOut(); | |
63 | + const { exchangeRate } = useOrderInfo(orderStore); | |
64 | + const orderIds = ref([]); | |
36 | 65 | const loading = ref(true); |
37 | 66 | const lines = ref(10); |
67 | + const activeRate = ref(); | |
68 | + const profitType = ref('1'); | |
38 | 69 | const info = ref({}); |
39 | 70 | const [register, { setModalProps, redoModalHeight }] = useModalInner(async (data) => { |
40 | - const orderIds = toRaw(data.data); | |
41 | - const res = await orderAnalysis({ orderIds }); | |
71 | + orderIds.value = toRaw(data.data); | |
72 | + info.value = {}; | |
73 | + }); | |
42 | 74 | |
43 | - info.value = { | |
44 | - ...(res || {}), | |
45 | - }; | |
75 | + onMounted(async () => { | |
76 | + const res = await getList({ settingCode: 'exchangeRate', page: 1, pageSize: 10 }); | |
77 | + activeRate.value = res?.[0]?.settingValue; | |
46 | 78 | }); |
47 | 79 | |
48 | 80 | const schema: DescItem[] = [ |
... | ... | @@ -75,18 +107,37 @@ |
75 | 107 | if (visible) { |
76 | 108 | loading.value = true; |
77 | 109 | // setModalProps({ loading: true, confirmLoading: true }); |
78 | - setTimeout(() => { | |
79 | - lines.value = Math.round(Math.random() * 30 + 5); | |
80 | - loading.value = false; | |
81 | - setModalProps({ loading: false, confirmLoading: false }); | |
82 | - }, 3000); | |
110 | + setModalProps({ loading: false, confirmLoading: false }); | |
83 | 111 | } |
84 | 112 | } |
85 | 113 | |
86 | 114 | function setLines() { |
87 | 115 | lines.value = Math.round(Math.random() * 20 + 10); |
88 | 116 | } |
89 | - return { register, loading, handleShow, lines, setLines, info, schema }; | |
117 | + | |
118 | + async function handleCalc() { | |
119 | + const res = await orderAnalysis({ | |
120 | + orderIds: orderIds.value, | |
121 | + profitType: profitType.value, | |
122 | + exchangeRate: activeRate.value, | |
123 | + }); | |
124 | + info.value = { | |
125 | + ...(res || {}), | |
126 | + }; | |
127 | + } | |
128 | + return { | |
129 | + register, | |
130 | + loading, | |
131 | + handleShow, | |
132 | + lines, | |
133 | + setLines, | |
134 | + info, | |
135 | + schema, | |
136 | + exchangeRate, | |
137 | + handleCalc, | |
138 | + activeRate, | |
139 | + profitType, | |
140 | + }; | |
90 | 141 | }, |
91 | 142 | }); |
92 | 143 | </script> | ... | ... |
src/views/project/order/RateModal.vue
0 → 100644
1 | +<template> | |
2 | + <BasicModal | |
3 | + v-bind="$attrs" | |
4 | + destroyOnClose | |
5 | + @register="register" | |
6 | + title="利润分析表" | |
7 | + width="600px" | |
8 | + @visible-change="handleShow" | |
9 | + :footer="null" | |
10 | + > | |
11 | + <Space> | |
12 | + <span> | |
13 | + 设计师: | |
14 | + <Select :options="manualPreform" placeholder="请选择" v-model:value="activeUser" /> | |
15 | + </span> | |
16 | + <a-button type="primary" @click="handleCalc" className="ml-4">计算</a-button> | |
17 | + </Space> | |
18 | + <div className="mt-2">比重结果:{{ info }}</div> | |
19 | + </BasicModal> | |
20 | +</template> | |
21 | +<script lang="ts"> | |
22 | + import { defineComponent, ref } from 'vue'; | |
23 | + import { BasicModal, useModalInner } from '/@/components/Modal'; | |
24 | + import { orderGravity } from '/@/api/project/order'; | |
25 | + import { Select, Space } from 'ant-design-vue'; | |
26 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | |
27 | + import { useOrderInfo } from '/@/hooks/component/order'; | |
28 | + | |
29 | + export default defineComponent({ | |
30 | + components: { BasicModal, Select, Space }, | |
31 | + setup() { | |
32 | + const orderStore = useOrderStoreWithOut(); | |
33 | + const { manualPreform, exchangeRate } = useOrderInfo(orderStore); | |
34 | + | |
35 | + const loading = ref(true); | |
36 | + const activeUser = ref(); | |
37 | + const info = ref(); | |
38 | + const searchData = ref({}); | |
39 | + const [register, { setModalProps }] = useModalInner(async (data) => { | |
40 | + searchData.value = data.data || {}; | |
41 | + activeUser.value = undefined; | |
42 | + info.value = ''; | |
43 | + }); | |
44 | + | |
45 | + function handleShow(visible: boolean) { | |
46 | + if (visible) { | |
47 | + loading.value = true; | |
48 | + // setModalProps({ loading: true, confirmLoading: true }); | |
49 | + setModalProps({ loading: false, confirmLoading: false }); | |
50 | + } | |
51 | + } | |
52 | + | |
53 | + async function handleCalc() { | |
54 | + const res = await orderGravity({ | |
55 | + ...searchData.value, | |
56 | + designer: activeUser.value, | |
57 | + }); | |
58 | + info.value = res?.rate || 0; | |
59 | + } | |
60 | + return { | |
61 | + register, | |
62 | + loading, | |
63 | + handleShow, | |
64 | + info, | |
65 | + manualPreform, | |
66 | + handleCalc, | |
67 | + activeUser, | |
68 | + exchangeRate, | |
69 | + }; | |
70 | + }, | |
71 | + }); | |
72 | +</script> | |
73 | +<style scoped> | |
74 | + .empty-tips { | |
75 | + height: 100px; | |
76 | + line-height: 100px; | |
77 | + text-align: center; | |
78 | + } | |
79 | +</style> | ... | ... |
src/views/project/order/index.vue
... | ... | @@ -33,41 +33,56 @@ |
33 | 33 | <TableAction |
34 | 34 | :actions="[ |
35 | 35 | { |
36 | - label: '编辑', | |
37 | - // icon: 'ic:outline-delete-outline', | |
38 | - onClick: handleEdit.bind(null, record), | |
36 | + // 数据分析没有编辑权限 | |
37 | + ...(role !== ROLE.DATA_REPORT_USER && { | |
38 | + label: '编辑', | |
39 | + // icon: 'ic:outline-delete-outline', | |
40 | + onClick: handleEdit.bind(null, record), | |
41 | + }), | |
39 | 42 | }, |
40 | 43 | { |
41 | - label: '申请权限', | |
42 | - // icon: 'ic:outline-delete-outline', | |
43 | - onClick: handleCheck.bind(null, record), | |
44 | - }, | |
45 | - ]" | |
46 | - :dropDownActions="[ | |
47 | - { | |
48 | - label: '历史记录', | |
49 | - onClick: handleHistory.bind(null, record), | |
44 | + ...(role !== ROLE.DATA_REPORT_USER && { | |
45 | + label: '申请权限', | |
46 | + // icon: 'ic:outline-delete-outline', | |
47 | + onClick: handleCheck.bind(null, record), | |
48 | + }), | |
50 | 49 | }, |
51 | 50 | ]" |
51 | + :dropDownActions=" | |
52 | + role !== ROLE.DATA_REPORT_USER | |
53 | + ? [ | |
54 | + { | |
55 | + label: '历史记录', | |
56 | + onClick: handleHistory.bind(null, record), | |
57 | + }, | |
58 | + ] | |
59 | + : [] | |
60 | + " | |
52 | 61 | /> |
53 | 62 | </template> |
54 | 63 | <template v-if="column.key === 'picUrl'"> |
55 | 64 | <img |
56 | 65 | :width="100" |
57 | 66 | :height="100" |
58 | - :src="record.picUrl" | |
59 | - :key="record.picUrl" | |
67 | + :src="record.smallPicUrl" | |
68 | + :key="record.smallPicUrl" | |
60 | 69 | @click="handlePreview(record.picUrl)" |
61 | 70 | /> |
62 | 71 | </template> |
63 | 72 | </template> |
64 | 73 | |
65 | 74 | <template #toolbar> |
66 | - <a-button type="primary" @click="handleExport">导出</a-button> | |
75 | + <a-button type="primary" @click="handleRateModal">比重计算</a-button> | |
76 | + <a-button type="primary" @click="handleExportModal">导出</a-button> | |
67 | 77 | <a-button type="primary" @click="handleProfitModal" :disabled="!checkedKeys.length" |
68 | 78 | >分析利润</a-button |
69 | 79 | > |
70 | - <a-button type="primary" @click="handleAdd">创建订单</a-button> | |
80 | + <a-button | |
81 | + type="primary" | |
82 | + @click="handleAdd" | |
83 | + v-if="role !== ROLE.INSPECT && role !== ROLE.DATA_REPORT_USER" | |
84 | + >创建订单</a-button | |
85 | + > | |
71 | 86 | </template> |
72 | 87 | </BasicTable> |
73 | 88 | <FormDetail |
... | ... | @@ -76,13 +91,15 @@ |
76 | 91 | @success="handleFormSuccess" |
77 | 92 | /> |
78 | 93 | <ProfitAnalysis @register="profitModalRegister" /> |
94 | + <RateModal @register="rateModalRegister" /> | |
95 | + <ExportModal @register="exportModalRegister" :role="role" /> | |
79 | 96 | <CheckDetail @register="checkModalRegister" :onGoFormDetail="handleGoFormDetail" /> |
80 | 97 | <HistoryDetail @register="historyDetailRegister" /> |
81 | 98 | <FieldDetail @register="fieldDetailRegister" /> |
82 | 99 | </div> |
83 | 100 | </template> |
84 | 101 | <script lang="ts"> |
85 | - import { defineComponent, onMounted, ref, toRaw, toRefs, unref } from 'vue'; | |
102 | + import { defineComponent, onMounted, ref, toRaw, computed } from 'vue'; | |
86 | 103 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
87 | 104 | import { FormOutlined } from '@ant-design/icons-vue'; |
88 | 105 | import HeaderCell from '/@/components/Table/src/components/HeaderCell.vue'; |
... | ... | @@ -90,6 +107,8 @@ |
90 | 107 | |
91 | 108 | import { useDrawer } from '/@/components/Drawer'; |
92 | 109 | import ProfitAnalysis from './ProfitAnalysis.vue'; |
110 | + import RateModal from './RateModal.vue'; | |
111 | + import ExportModal from './ExportModal.vue'; | |
93 | 112 | import { useModal } from '/@/components/Modal'; |
94 | 113 | |
95 | 114 | import { getFormConfig, getOrderColumns, SELECT_FIELD_COLUMNS } from './tableData'; |
... | ... | @@ -98,10 +117,10 @@ |
98 | 117 | import HistoryDetail from './HistoryDetail.vue'; |
99 | 118 | import FieldDetail from './FieldDetail.vue'; |
100 | 119 | import { createImgPreview } from '/@/components/Preview/index'; |
101 | - import { getOrderList, orderExport } from '/@/api/project/order'; | |
120 | + import { getOrderList } from '/@/api/project/order'; | |
102 | 121 | import { useOrderStoreWithOut } from '/@/store/modules/order'; |
103 | - import { keyBy, reduce } from 'lodash-es'; | |
104 | 122 | import { useUserStoreWithOut } from '/@/store/modules/user'; |
123 | + import { ROLE } from './type.d'; | |
105 | 124 | |
106 | 125 | const orderStore = useOrderStoreWithOut(); |
107 | 126 | const userStore = useUserStoreWithOut(); |
... | ... | @@ -118,16 +137,24 @@ |
118 | 137 | CheckDetail, |
119 | 138 | HistoryDetail, |
120 | 139 | FieldDetail, |
140 | + RateModal, | |
141 | + ExportModal, | |
121 | 142 | }, |
122 | 143 | setup() { |
123 | 144 | const checkedKeys = ref<Array<string | number>>([]); |
124 | 145 | const [profitModalRegister, { openModal: openProfitModal }] = useModal(); |
146 | + const [rateModalRegister, { openModal: openRateModal }] = useModal(); | |
147 | + const [exportModalRegister, { openModal: openExportModal }] = useModal(); | |
148 | + | |
125 | 149 | const tooltipVisible = ref(false); |
126 | 150 | const [formDetailRegister, { openDrawer: openFormDetailDrawer }] = useDrawer(); |
127 | 151 | const [historyDetailRegister, { openDrawer: openHistoryDetailDrawer }] = useDrawer(); |
128 | 152 | const [fieldDetailRegister, { openDrawer: openFieldDetailDrawer }] = useDrawer(); |
129 | 153 | |
130 | 154 | const user = userStore.getUserInfo; |
155 | + const role = computed(() => { | |
156 | + return user?.roleSmallVO?.code; | |
157 | + }); | |
131 | 158 | |
132 | 159 | const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); |
133 | 160 | onMounted(async () => { |
... | ... | @@ -211,6 +238,15 @@ |
211 | 238 | }); |
212 | 239 | } |
213 | 240 | |
241 | + function handleRateModal() { | |
242 | + const form = getForm(); | |
243 | + const values = form.getFieldsValue(); | |
244 | + | |
245 | + openRateModal(true, { | |
246 | + data: values, | |
247 | + }); | |
248 | + } | |
249 | + | |
214 | 250 | function handleFieldVisible(record) { |
215 | 251 | openFieldDetailDrawer(true, record); |
216 | 252 | } |
... | ... | @@ -225,74 +261,15 @@ |
225 | 261 | openFormDetailDrawer(true); |
226 | 262 | } |
227 | 263 | |
228 | - function handlePreview(url, e) { | |
264 | + function handlePreview(url) { | |
229 | 265 | createImgPreview({ imageList: [url], defaultWidth: 500 }); |
230 | 266 | // e?.stopPropagation(); |
231 | 267 | // e?.preventDefault(); |
232 | 268 | return false; |
233 | 269 | } |
234 | 270 | |
235 | - async function handleExport() { | |
236 | - const columns = getColumns(); | |
237 | - const colObj = keyBy(columns, 'dataIndex'); | |
238 | - const { | |
239 | - trackStageInfo, | |
240 | - reportInfo, | |
241 | - profitAnalysisInfo, | |
242 | - inspectionStageInfo, | |
243 | - ...baseFields | |
244 | - } = colObj; | |
245 | - | |
246 | - for (const key in baseFields) { | |
247 | - baseFields[key] = 'selected'; | |
248 | - } | |
249 | - delete baseFields.action; | |
250 | - | |
251 | - const fieldVO = { | |
252 | - baseFields, | |
253 | - profitAnalysisFields: profitAnalysisInfo?.children?.length | |
254 | - ? reduce( | |
255 | - profitAnalysisInfo.children, | |
256 | - (result, item) => { | |
257 | - result[item.dataIndex] = 'selected'; | |
258 | - return result; | |
259 | - }, | |
260 | - {}, | |
261 | - ) | |
262 | - : {}, | |
263 | - reportFields: reportInfo?.children?.length | |
264 | - ? reduce( | |
265 | - reportInfo.children, | |
266 | - (result, item) => { | |
267 | - result[item.dataIndex] = 'selected'; | |
268 | - return result; | |
269 | - }, | |
270 | - {}, | |
271 | - ) | |
272 | - : {}, | |
273 | - trackStageFields: trackStageInfo?.children?.length | |
274 | - ? reduce( | |
275 | - trackStageInfo.children, | |
276 | - (result, item) => { | |
277 | - result[item.dataIndex] = 'selected'; | |
278 | - return result; | |
279 | - }, | |
280 | - {}, | |
281 | - ) | |
282 | - : {}, | |
283 | - inspectionStageFields: inspectionStageInfo?.children?.length | |
284 | - ? reduce( | |
285 | - inspectionStageInfo.children, | |
286 | - (result, item) => { | |
287 | - result[item.dataIndex] = 'selected'; | |
288 | - return result; | |
289 | - }, | |
290 | - {}, | |
291 | - ) | |
292 | - : {}, | |
293 | - }; | |
294 | - | |
295 | - await orderExport({ fieldVO }); | |
271 | + async function handleExportModal() { | |
272 | + openExportModal(true); | |
296 | 273 | } |
297 | 274 | |
298 | 275 | const handleFormSuccess = () => { |
... | ... | @@ -300,9 +277,12 @@ |
300 | 277 | }; |
301 | 278 | |
302 | 279 | return { |
280 | + user, | |
303 | 281 | SELECT_FIELD_COLUMNS, |
304 | 282 | fieldDetailRegister, |
305 | 283 | profitModalRegister, |
284 | + rateModalRegister, | |
285 | + exportModalRegister, | |
306 | 286 | historyDetailRegister, |
307 | 287 | formDetailRegister, |
308 | 288 | handleProfitModal, |
... | ... | @@ -321,9 +301,13 @@ |
321 | 301 | handleHistory, |
322 | 302 | handleAdd, |
323 | 303 | createImgPreview, |
324 | - handleExport, | |
304 | + handleExportModal, | |
325 | 305 | handlePreview, |
326 | 306 | handleFormSuccess, |
307 | + handleRateModal, | |
308 | + openExportModal, | |
309 | + role, | |
310 | + ROLE, | |
327 | 311 | }; |
328 | 312 | }, |
329 | 313 | }); |
... | ... | @@ -337,12 +321,17 @@ |
337 | 321 | } |
338 | 322 | |
339 | 323 | .ant-table-cell img { |
340 | - width: 100px; | |
341 | - height: 100px; | |
324 | + width: 40px; | |
325 | + height: 40px; | |
342 | 326 | } |
343 | 327 | |
344 | 328 | .order-page .vben-basic-table .ant-form-item .ant-picker { |
345 | 329 | width: 100%; |
346 | 330 | } |
331 | + | |
332 | + .order-page .ant-table.ant-table-middle .ant-table-tbody > tr > td { | |
333 | + padding-top: 0; | |
334 | + padding-bottom: 0; | |
335 | + } | |
347 | 336 | </style> |
348 | 337 | ./constant | ... | ... |
src/views/project/order/tableData.tsx
1 | 1 | import { ROLE } from './type.d'; |
2 | 2 | import { useOrderInfo } from '/@/hooks/component/order'; |
3 | 3 | import { useOrderStoreWithOut } from '/@/store/modules/order'; |
4 | +import { formatToDate } from '/@/utils/dateUtil'; | |
4 | 5 | |
5 | 6 | // 角色 |
6 | 7 | // 业务员- 查看all,编辑-利润分析,报告书 |
... | ... | @@ -11,21 +12,27 @@ import { useOrderStoreWithOut } from '/@/store/modules/order'; |
11 | 12 | export const SELECT_FIELD_COLUMNS = [ |
12 | 13 | 'projectNo', |
13 | 14 | 'customerCode', |
15 | + 'productionDepartment', | |
14 | 16 | 'innerNo', |
15 | 17 | 'poColor', |
16 | 18 | 'cnColor', |
17 | 19 | 'productStyle', |
18 | 20 | 'outboundType', |
19 | 21 | 'packetType', |
22 | + 'ideaSource', | |
23 | + 'manualPreform1', | |
24 | + 'manualPreform2', | |
20 | 25 | 'midCheckResult', |
21 | 26 | 'endCheckResult', |
27 | + // 'exchangeRate', | |
28 | + 'businessPerson', | |
22 | 29 | ]; |
23 | 30 | |
24 | 31 | /** |
25 | 32 | * |
26 | 33 | * @returns 订单列表数据 |
27 | 34 | */ |
28 | -const ORDER_LIST_BASE_FIELDS = [ | |
35 | +export const ORDER_LIST_BASE_FIELDS = [ | |
29 | 36 | { |
30 | 37 | title: '客户编码', |
31 | 38 | width: 150, |
... | ... | @@ -110,11 +117,19 @@ const ORDER_LIST_BASE_FIELDS = [ |
110 | 117 | title: '生成科拖货时间', |
111 | 118 | width: 150, |
112 | 119 | dataIndex: 'productionDepartmentConsignTime', |
120 | + customRender: (column) => { | |
121 | + const { record } = column || {}; | |
122 | + return formatToDate(record?.productionDepartmentConsignTime); | |
123 | + }, | |
113 | 124 | }, |
114 | 125 | { |
115 | 126 | title: '订单上HOD时间', |
116 | 127 | width: 150, |
117 | 128 | dataIndex: 'orderHodTime', |
129 | + customRender: (column) => { | |
130 | + const { record } = column || {}; | |
131 | + return formatToDate(record?.orderHodTime); | |
132 | + }, | |
118 | 133 | }, |
119 | 134 | { |
120 | 135 | title: '出库类型', |
... | ... | @@ -126,9 +141,14 @@ const ORDER_LIST_BASE_FIELDS = [ |
126 | 141 | width: 150, |
127 | 142 | dataIndex: 'packetType', |
128 | 143 | }, |
144 | + { | |
145 | + title: '业务员', | |
146 | + width: 150, | |
147 | + dataIndex: 'businessPerson', | |
148 | + }, | |
129 | 149 | ]; |
130 | 150 | |
131 | -const ORDER_LIST_REPORT_FIELDS = [ | |
151 | +export const ORDER_LIST_REPORT_FIELDS = [ | |
132 | 152 | { |
133 | 153 | title: '项目完成报告信息', |
134 | 154 | width: 150, |
... | ... | @@ -137,35 +157,62 @@ const ORDER_LIST_REPORT_FIELDS = [ |
137 | 157 | { |
138 | 158 | title: '想法来源', |
139 | 159 | width: 150, |
140 | - dataIndex: 'reportInfo.ideaSource', | |
160 | + dataIndex: 'ideaSource', | |
141 | 161 | customRender: (column) => { |
142 | 162 | const { record } = column || {}; |
143 | 163 | return record?.reportInfo?.ideaSource; |
144 | 164 | }, |
145 | 165 | }, |
146 | 166 | { |
147 | - title: '手工初型', | |
167 | + title: '想法来源占比', | |
168 | + width: 150, | |
169 | + dataIndex: 'ideaSourceRate', | |
170 | + customRender: (column) => { | |
171 | + const { record } = column || {}; | |
172 | + return record?.reportInfo?.ideaSourceRate; | |
173 | + }, | |
174 | + }, | |
175 | + { | |
176 | + title: '手工初型1', | |
177 | + width: 150, | |
178 | + dataIndex: 'manualPreform1', | |
179 | + customRender: (column) => { | |
180 | + const { record } = column || {}; | |
181 | + return record?.reportInfo?.manualPreform1; | |
182 | + }, | |
183 | + }, | |
184 | + { | |
185 | + title: '手工初型1占比', | |
186 | + width: 150, | |
187 | + dataIndex: 'manualPreform1Rate', | |
188 | + customRender: (column) => { | |
189 | + const { record } = column || {}; | |
190 | + return record?.reportInfo?.manualPreform1Rate; | |
191 | + }, | |
192 | + }, | |
193 | + { | |
194 | + title: '手工初型2', | |
148 | 195 | width: 150, |
149 | - dataIndex: 'reportInfo.manualPreform', | |
196 | + dataIndex: 'manualPreform2', | |
150 | 197 | customRender: (column) => { |
151 | 198 | const { record } = column || {}; |
152 | - return record?.reportInfo?.manualPreform; | |
199 | + return record?.reportInfo?.manualPreform2; | |
153 | 200 | }, |
154 | 201 | }, |
155 | 202 | { |
156 | - title: '想法和手工比例分配', | |
203 | + title: '手工初型2占比', | |
157 | 204 | width: 150, |
158 | - dataIndex: 'reportInfo.ideaManualRate', | |
205 | + dataIndex: 'manualPreform2Rate', | |
159 | 206 | customRender: (column) => { |
160 | 207 | const { record } = column || {}; |
161 | - return record?.reportInfo?.ideaManualRate; | |
208 | + return record?.reportInfo?.manualPreform2Rate; | |
162 | 209 | }, |
163 | 210 | }, |
164 | 211 | ], |
165 | 212 | }, |
166 | 213 | ]; |
167 | 214 | |
168 | -const ORDER_LIST_PROFIT_FIELDS = [ | |
215 | +export const ORDER_LIST_PROFIT_FIELDS = [ | |
169 | 216 | { |
170 | 217 | title: '利润分析信息', |
171 | 218 | width: 150, |
... | ... | @@ -177,7 +224,9 @@ const ORDER_LIST_PROFIT_FIELDS = [ |
177 | 224 | dataIndex: 'customerPrice', |
178 | 225 | customRender: (column) => { |
179 | 226 | const { record } = column || {}; |
180 | - return record?.profitAnalysisInfo?.customerPrice; | |
227 | + return `${record?.profitAnalysisInfo?.customerCurrency || ''} ${ | |
228 | + record?.profitAnalysisInfo?.customerPrice || '' | |
229 | + }`; | |
181 | 230 | }, |
182 | 231 | }, |
183 | 232 | { |
... | ... | @@ -195,7 +244,18 @@ const ORDER_LIST_PROFIT_FIELDS = [ |
195 | 244 | dataIndex: 'productionDepartmentPrice', |
196 | 245 | customRender: (column) => { |
197 | 246 | const { record } = column || {}; |
198 | - return record?.profitAnalysisInfo?.productionDepartmentPrice; | |
247 | + return `${record?.profitAnalysisInfo?.productionDepartmentCurrency || ''} ${ | |
248 | + record?.profitAnalysisInfo?.productionDepartmentPrice || '' | |
249 | + }`; | |
250 | + }, | |
251 | + }, | |
252 | + { | |
253 | + title: '生成科总价', | |
254 | + width: 150, | |
255 | + dataIndex: 'productionDepartmentTotalPrice', | |
256 | + customRender: (column) => { | |
257 | + const { record } = column || {}; | |
258 | + return record?.profitAnalysisInfo?.productionDepartmentTotalPrice; | |
199 | 259 | }, |
200 | 260 | }, |
201 | 261 | { |
... | ... | @@ -204,7 +264,9 @@ const ORDER_LIST_PROFIT_FIELDS = [ |
204 | 264 | dataIndex: 'packetPrice', |
205 | 265 | customRender: (column) => { |
206 | 266 | const { record } = column || {}; |
207 | - return record?.profitAnalysisInfo?.packetPrice; | |
267 | + return `${record?.profitAnalysisInfo?.packetCurrency || ''} ${ | |
268 | + record?.profitAnalysisInfo?.packetPrice || '' | |
269 | + }`; | |
208 | 270 | }, |
209 | 271 | }, |
210 | 272 | { |
... | ... | @@ -234,11 +296,24 @@ const ORDER_LIST_PROFIT_FIELDS = [ |
234 | 296 | return record?.profitAnalysisInfo?.profitRate; |
235 | 297 | }, |
236 | 298 | }, |
299 | + { | |
300 | + title: '利润率计算方式', | |
301 | + width: 150, | |
302 | + dataIndex: 'profitRate', | |
303 | + customRender: (column) => { | |
304 | + const { record } = column || {}; | |
305 | + return record?.profitAnalysisInfo?.profitType === '0' | |
306 | + ? '方式1' | |
307 | + : record?.profitAnalysisInfo?.profitType === '1' | |
308 | + ? '方式2' | |
309 | + : ''; | |
310 | + }, | |
311 | + }, | |
237 | 312 | ], |
238 | 313 | }, |
239 | 314 | ]; |
240 | 315 | |
241 | -const ORDER_LIST_TRACK_FIELDS = [ | |
316 | +export const ORDER_LIST_TRACK_FIELDS = [ | |
242 | 317 | { |
243 | 318 | title: '跟单信息', |
244 | 319 | width: 150, |
... | ... | @@ -250,7 +325,7 @@ const ORDER_LIST_TRACK_FIELDS = [ |
250 | 325 | dataIndex: 'ppTime', |
251 | 326 | customRender: (column) => { |
252 | 327 | const { record } = column || {}; |
253 | - return record?.trackStageInfo?.ppTime; | |
328 | + return formatToDate(record?.trackStageInfo?.ppTime); | |
254 | 329 | }, |
255 | 330 | }, |
256 | 331 | { |
... | ... | @@ -268,7 +343,7 @@ const ORDER_LIST_TRACK_FIELDS = [ |
268 | 343 | dataIndex: 'esoSampleSendTime', |
269 | 344 | customRender: (column) => { |
270 | 345 | const { record } = column || {}; |
271 | - return record?.trackStageInfo?.esoSampleSendTime; | |
346 | + return formatToDate(record?.trackStageInfo?.esoSampleSendTime); | |
272 | 347 | }, |
273 | 348 | }, |
274 | 349 | { |
... | ... | @@ -277,7 +352,7 @@ const ORDER_LIST_TRACK_FIELDS = [ |
277 | 352 | dataIndex: 'shippmentSampleSendTime', |
278 | 353 | customRender: (column) => { |
279 | 354 | const { record } = column || {}; |
280 | - return record?.trackStageInfo?.shippmentSampleSendTime; | |
355 | + return formatToDate(record?.trackStageInfo?.shippmentSampleSendTime); | |
281 | 356 | }, |
282 | 357 | }, |
283 | 358 | { |
... | ... | @@ -295,7 +370,7 @@ const ORDER_LIST_TRACK_FIELDS = [ |
295 | 370 | dataIndex: 'selfTestPassTime', |
296 | 371 | customRender: (column) => { |
297 | 372 | const { record } = column || {}; |
298 | - return record?.trackStageInfo?.selfTestPassTime; | |
373 | + return formatToDate(record?.trackStageInfo?.selfTestPassTime); | |
299 | 374 | }, |
300 | 375 | }, |
301 | 376 | { |
... | ... | @@ -304,7 +379,7 @@ const ORDER_LIST_TRACK_FIELDS = [ |
304 | 379 | dataIndex: 'aitexTestSendTime', |
305 | 380 | customRender: (column) => { |
306 | 381 | const { record } = column || {}; |
307 | - return record?.trackStageInfo?.aitexTestSendTime; | |
382 | + return formatToDate(record?.trackStageInfo?.aitexTestSendTime); | |
308 | 383 | }, |
309 | 384 | }, |
310 | 385 | { |
... | ... | @@ -322,7 +397,7 @@ const ORDER_LIST_TRACK_FIELDS = [ |
322 | 397 | dataIndex: 'sgsTestSendTime', |
323 | 398 | customRender: (column) => { |
324 | 399 | const { record } = column || {}; |
325 | - return record?.trackStageInfo?.sgsTestSendTime; | |
400 | + return formatToDate(record?.trackStageInfo?.sgsTestSendTime); | |
326 | 401 | }, |
327 | 402 | }, |
328 | 403 | { |
... | ... | @@ -349,7 +424,7 @@ const ORDER_LIST_TRACK_FIELDS = [ |
349 | 424 | dataIndex: 'latestArrivalTime', |
350 | 425 | customRender: (column) => { |
351 | 426 | const { record } = column || {}; |
352 | - return record?.trackStageInfo?.latestArrivalTime; | |
427 | + return formatToDate(record?.trackStageInfo?.latestArrivalTime); | |
353 | 428 | }, |
354 | 429 | }, |
355 | 430 | { |
... | ... | @@ -358,14 +433,14 @@ const ORDER_LIST_TRACK_FIELDS = [ |
358 | 433 | dataIndex: 'latestBkTime', |
359 | 434 | customRender: (column) => { |
360 | 435 | const { record } = column || {}; |
361 | - return record?.trackStageInfo?.latestBkTime; | |
436 | + return formatToDate(record?.trackStageInfo?.latestBkTime); | |
362 | 437 | }, |
363 | 438 | }, |
364 | 439 | ], |
365 | 440 | }, |
366 | 441 | ]; |
367 | 442 | |
368 | -const ORDER_LIST_INSPECT_FIELDS = [ | |
443 | +export const ORDER_LIST_INSPECT_FIELDS = [ | |
369 | 444 | { |
370 | 445 | title: '质检信息', |
371 | 446 | width: 150, |
... | ... | @@ -378,7 +453,7 @@ const ORDER_LIST_INSPECT_FIELDS = [ |
378 | 453 | dataIndex: 'midCheckApplyTime', |
379 | 454 | customRender: (column) => { |
380 | 455 | const { record } = column || {}; |
381 | - return record?.inspectionStageInfo?.midCheckApplyTime; | |
456 | + return formatToDate(record?.inspectionStageInfo?.midCheckApplyTime); | |
382 | 457 | }, |
383 | 458 | }, |
384 | 459 | { |
... | ... | @@ -405,7 +480,7 @@ const ORDER_LIST_INSPECT_FIELDS = [ |
405 | 480 | dataIndex: 'endCheckApplyTime', |
406 | 481 | customRender: (column) => { |
407 | 482 | const { record } = column || {}; |
408 | - return record?.inspectionStageInfo?.endCheckApplyTime; | |
483 | + return formatToDate(record?.inspectionStageInfo?.endCheckApplyTime); | |
409 | 484 | }, |
410 | 485 | }, |
411 | 486 | { |
... | ... | @@ -493,7 +568,9 @@ const ORDER_LIST_SCHEDULE = [ |
493 | 568 | }, |
494 | 569 | ]; |
495 | 570 | |
571 | +// 订单列表,也就是读权限 | |
496 | 572 | export function getOrderColumns(role: ROLE) { |
573 | + // 管理员/业务员看到所有列 | |
497 | 574 | if (role === ROLE.ADMIN || role === ROLE.BUSINESS) { |
498 | 575 | return [ |
499 | 576 | ...ORDER_LIST_BASE_FIELDS, |
... | ... | @@ -504,15 +581,16 @@ export function getOrderColumns(role: ROLE) { |
504 | 581 | ...ORDER_LIST_SCHEDULE, |
505 | 582 | ]; |
506 | 583 | } |
507 | - | |
584 | + // 跟单 -基本信息-利润分析(单价,总价),跟单,质检 | |
508 | 585 | if (role === ROLE.TRACKER) { |
509 | 586 | return [ |
510 | 587 | ...ORDER_LIST_BASE_FIELDS, |
511 | 588 | ...ORDER_LIST_PROFIT_FIELDS.map((item) => { |
512 | 589 | const children = item.children.filter( |
513 | - (k) => k.dataIndex !== 'exchangeRate' && k.dataIndex !== 'profitRate', | |
590 | + (k) => k.dataIndex === 'customerPrice' || k.dataIndex === 'customerTotalPrice', | |
514 | 591 | ); |
515 | 592 | item.children = children; |
593 | + | |
516 | 594 | return item; |
517 | 595 | }), |
518 | 596 | ...ORDER_LIST_TRACK_FIELDS, |
... | ... | @@ -521,7 +599,8 @@ export function getOrderColumns(role: ROLE) { |
521 | 599 | ]; |
522 | 600 | } |
523 | 601 | |
524 | - if (role === ROLE.INSPECT) { | |
602 | + // 质检-基本,跟单,质检 | |
603 | + if (role === ROLE.INSPECT || role === ROLE.DATA_REPORT_USER) { | |
525 | 604 | return [ |
526 | 605 | ...ORDER_LIST_BASE_FIELDS, |
527 | 606 | ...ORDER_LIST_TRACK_FIELDS, |
... | ... | @@ -532,7 +611,9 @@ export function getOrderColumns(role: ROLE) { |
532 | 611 | |
533 | 612 | return []; |
534 | 613 | } |
535 | - | |
614 | +/** | |
615 | + * drawer面板的字段 | |
616 | + */ | |
536 | 617 | // 基本信息 |
537 | 618 | export const FIELDS_BASE_INFO = [ |
538 | 619 | { |
... | ... | @@ -670,6 +751,13 @@ export const FIELDS_BASE_INFO = [ |
670 | 751 | label: '包装类型', |
671 | 752 | rules: [{ required: true }], |
672 | 753 | }, |
754 | + { | |
755 | + field: 'businessPerson', | |
756 | + component: 'Select', | |
757 | + labelWidth: 150, | |
758 | + label: '业务员', | |
759 | + rules: [{ required: true }], | |
760 | + }, | |
673 | 761 | ]; |
674 | 762 | |
675 | 763 | //项目完成报告信息 |
... | ... | @@ -680,22 +768,44 @@ export const FIELDS_REPORT_INFO = [ |
680 | 768 | optionField: 'ideaSource', |
681 | 769 | labelWidth: 150, |
682 | 770 | label: '想法来源', |
683 | - // rules: [{ required: true }], | |
771 | + rules: [{ required: true }], | |
772 | + }, | |
773 | + { | |
774 | + field: 'ideaSourceRate', | |
775 | + component: 'InputNumber', | |
776 | + optionField: 'ideaSourceRate', | |
777 | + labelWidth: 150, | |
778 | + label: '想法来源占比', | |
779 | + rules: [{ required: true }], | |
684 | 780 | }, |
685 | 781 | { |
686 | - field: 'manualPreform', | |
782 | + field: 'manualPreform1', | |
687 | 783 | component: 'Select', |
688 | - optionField: 'manualPreform', | |
784 | + optionField: 'manualPreform1', | |
689 | 785 | labelWidth: 150, |
690 | - label: '手工初型', | |
691 | - // rules: [{ required: true }], | |
786 | + label: '手工初型1', | |
787 | + rules: [{ required: true }], | |
692 | 788 | }, |
693 | 789 | { |
694 | - field: 'ideaManualRate', | |
695 | - component: 'Input', | |
790 | + field: 'manualPreform1Rate', | |
791 | + component: 'InputNumber', | |
696 | 792 | labelWidth: 150, |
697 | - label: '想法和手工比例分配', | |
698 | - // rules: [{ required: true }], | |
793 | + label: '手工初型1占比', | |
794 | + rules: [{ required: true }], | |
795 | + }, | |
796 | + { | |
797 | + field: 'manualPreform2', | |
798 | + component: 'Select', | |
799 | + labelWidth: 150, | |
800 | + label: '手工初型2', | |
801 | + rules: [{ required: true }], | |
802 | + }, | |
803 | + { | |
804 | + field: 'manualPreform2Rate', | |
805 | + component: 'InputNumber', | |
806 | + labelWidth: 150, | |
807 | + label: '手工初型2占比', | |
808 | + rules: [{ required: true }], | |
699 | 809 | }, |
700 | 810 | ]; |
701 | 811 | |
... | ... | @@ -836,7 +946,7 @@ export const FIELDS_PROFIT_INFO = [ |
836 | 946 | field: 'customerPrice', |
837 | 947 | component: 'InputNumber', |
838 | 948 | label: '客户单价', |
839 | - // rules: [{ required: true }], | |
949 | + rules: [{ required: true }], | |
840 | 950 | }, |
841 | 951 | // { |
842 | 952 | // field: 'customerTotalPrice', |
... | ... | @@ -848,7 +958,8 @@ export const FIELDS_PROFIT_INFO = [ |
848 | 958 | field: 'customerCurrency', |
849 | 959 | component: 'Select', |
850 | 960 | label: '客户单价货币单位', |
851 | - // rules: [{ required: true }], | |
961 | + labelWidth: 400, | |
962 | + rules: [{ required: true }], | |
852 | 963 | componentProps: { |
853 | 964 | options: [ |
854 | 965 | { label: '$', value: '$' }, |
... | ... | @@ -860,13 +971,13 @@ export const FIELDS_PROFIT_INFO = [ |
860 | 971 | field: 'productionDepartmentPrice', |
861 | 972 | component: 'InputNumber', |
862 | 973 | label: '生成科单价', |
863 | - // rules: [{ required: true }], | |
974 | + rules: [{ required: true }], | |
864 | 975 | }, |
865 | 976 | { |
866 | 977 | field: 'productionDepartmentCurrency', |
867 | 978 | component: 'Select', |
868 | 979 | label: '生成科货币单位', |
869 | - // rules: [{ required: true }], | |
980 | + rules: [{ required: true }], | |
870 | 981 | componentProps: { |
871 | 982 | options: [ |
872 | 983 | { label: '$', value: '$' }, |
... | ... | @@ -884,6 +995,14 @@ export const FIELDS_PROFIT_INFO = [ |
884 | 995 | label: '包装费用', |
885 | 996 | component: 'InputNumber', |
886 | 997 | field: 'packetPrice', |
998 | + fieldComponent: { disabled: true }, | |
999 | + // rules: [{ required: true }], | |
1000 | + }, | |
1001 | + { | |
1002 | + label: '汇率', | |
1003 | + component: 'InputNumber', | |
1004 | + field: 'exchangeRate', | |
1005 | + fieldComponent: { disabled: true }, | |
887 | 1006 | // rules: [{ required: true }], |
888 | 1007 | }, |
889 | 1008 | // { |
... | ... | @@ -892,30 +1011,39 @@ export const FIELDS_PROFIT_INFO = [ |
892 | 1011 | // field: 'packetTotalPrice', |
893 | 1012 | // rules: [{ required: true }], |
894 | 1013 | // }, |
1014 | + // { | |
1015 | + // label: '包装费用货币单位', | |
1016 | + // component: 'Input', | |
1017 | + // field: 'packetCurrency', | |
1018 | + // value: '$', | |
1019 | + // // rules: [{ required: true }], | |
1020 | + // componentProps: { | |
1021 | + // disblaed: true, | |
1022 | + // // options: [ | |
1023 | + // // { label: '$', value: '$' }, | |
1024 | + // // { label: '¥', value: '¥' }, | |
1025 | + // // ], | |
1026 | + // }, | |
1027 | + // }, | |
1028 | + // { | |
1029 | + // label: '汇率', | |
1030 | + // component: 'Select', | |
1031 | + // field: 'exchangeRate', | |
1032 | + // // rules: [{ required: true }], | |
1033 | + // }, | |
895 | 1034 | { |
896 | - label: '包装费用货币单位', | |
1035 | + label: '计算利润方式', | |
897 | 1036 | component: 'Select', |
898 | - field: 'packetCurrency', | |
899 | - // rules: [{ required: true }], | |
1037 | + field: 'profitType', | |
900 | 1038 | componentProps: { |
1039 | + defaultValue: '0', | |
901 | 1040 | options: [ |
902 | - { label: '$', value: '$' }, | |
903 | - { label: '¥', value: '¥' }, | |
1041 | + { label: '方式一: 1 -(LOCAL单价 / 汇率 + 包装费用)/ 客户单价', value: '0' }, | |
1042 | + { label: '方式二: 1 -(LOCAL单价/汇率 / (客户单价-包装费用)', value: '1' }, | |
904 | 1043 | ], |
905 | 1044 | }, |
906 | - }, | |
907 | - { | |
908 | - label: '汇率', | |
909 | - component: 'InputNumber', | |
910 | - field: 'exchangeRate', | |
911 | 1045 | // rules: [{ required: true }], |
912 | 1046 | }, |
913 | - // { | |
914 | - // label: '利润率', | |
915 | - // component: 'Input', | |
916 | - // field: 'profitRate', | |
917 | - // rules: [{ required: true }], | |
918 | - // }, | |
919 | 1047 | ]; |
920 | 1048 | |
921 | 1049 | //质量检测信息 |
... | ... | @@ -1196,14 +1324,25 @@ export function getFormConfig(): Partial<FormProps> { |
1196 | 1324 | }, |
1197 | 1325 | }, |
1198 | 1326 | { |
1199 | - field: `manualPreform`, | |
1200 | - label: `手工初型`, | |
1327 | + field: `manualPreform1`, | |
1328 | + label: `手工初型1`, | |
1329 | + component: 'Select', | |
1330 | + colProps: { | |
1331 | + span: 6, | |
1332 | + }, | |
1333 | + labelWidth: 150, | |
1334 | + componentProps: { | |
1335 | + options: manualPreform, | |
1336 | + }, | |
1337 | + }, | |
1338 | + { | |
1339 | + field: `manualPreform2`, | |
1340 | + label: `手工初型2`, | |
1201 | 1341 | component: 'Select', |
1202 | 1342 | colProps: { |
1203 | 1343 | span: 6, |
1204 | 1344 | }, |
1205 | 1345 | labelWidth: 150, |
1206 | - | |
1207 | 1346 | componentProps: { |
1208 | 1347 | options: manualPreform, |
1209 | 1348 | }, | ... | ... |
src/views/project/order/type.d.ts
src/views/sys/login/ForgetPasswordForm.vue
... | ... | @@ -2,21 +2,49 @@ |
2 | 2 | <template 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 | size="large" |
8 | 8 | v-model:value="formData.account" |
9 | 9 | :placeholder="t('sys.login.userName')" |
10 | 10 | /> |
11 | + </FormItem> --> | |
12 | + <FormItem name="phone" class="enter-x"> | |
13 | + <Input size="large" v-model:value="formData.phone" :placeholder="t('sys.login.mobile')" /> | |
14 | + </FormItem> | |
15 | + <FormItem name="password" class="enter-x"> | |
16 | + <Input | |
17 | + size="large" | |
18 | + visibilityToggle | |
19 | + v-model:value="formData.password" | |
20 | + placeholder="请输入密码" | |
21 | + /> | |
22 | + </FormItem> | |
23 | + <FormItem name="confirmPassword" class="enter-x"> | |
24 | + <Input | |
25 | + size="large" | |
26 | + visibilityToggle | |
27 | + v-model:value="formData.confirmPassword" | |
28 | + placeholder="请输入确认密码" | |
29 | + /> | |
11 | 30 | </FormItem> |
12 | 31 | |
13 | - <FormItem name="mobile" class="enter-x"> | |
14 | - <Input size="large" v-model:value="formData.mobile" :placeholder="t('sys.login.mobile')" /> | |
32 | + <FormItem name="imgCaptchaCode" class="enter-x"> | |
33 | + <div className="flex"> | |
34 | + <img :src="imgCaptcha" class="cursor-pointer" @click="getImgCaptcha" /> | |
35 | + <Input | |
36 | + size="large" | |
37 | + visibilityToggle | |
38 | + v-model:value="imgCaptchaCode" | |
39 | + placeholder="请输入图片验证码" | |
40 | + /> | |
41 | + </div> | |
15 | 42 | </FormItem> |
16 | - <FormItem name="sms" class="enter-x"> | |
43 | + <FormItem name="smsCaptchaCode" class="enter-x"> | |
17 | 44 | <CountdownInput |
18 | 45 | size="large" |
19 | - v-model:value="formData.sms" | |
46 | + v-model:value="formData.smsCaptchaCode" | |
47 | + :sendCodeApi="handleSendMsg" | |
20 | 48 | :placeholder="t('sys.login.smsCode')" |
21 | 49 | /> |
22 | 50 | </FormItem> |
... | ... | @@ -33,12 +61,14 @@ |
33 | 61 | </template> |
34 | 62 | </template> |
35 | 63 | <script lang="ts" setup> |
36 | - import { reactive, ref, computed, unref } from 'vue'; | |
64 | + import { reactive, ref, computed, unref, onMounted } from 'vue'; | |
37 | 65 | import LoginFormTitle from './LoginFormTitle.vue'; |
38 | - import { Form, Input, Button } from 'ant-design-vue'; | |
66 | + import { Form, Input, Button, message } from 'ant-design-vue'; | |
39 | 67 | import { CountdownInput } from '/@/components/CountDown'; |
40 | 68 | import { useI18n } from '/@/hooks/web/useI18n'; |
41 | 69 | import { useLoginState, useFormRules, LoginStateEnum } from './useLogin'; |
70 | + import { forgetPassword, getSms } from '/@/api/sys/user'; | |
71 | + import { useUserStore } from '/@/store/modules/user'; | |
42 | 72 | |
43 | 73 | const FormItem = Form.Item; |
44 | 74 | const { t } = useI18n(); |
... | ... | @@ -49,16 +79,56 @@ |
49 | 79 | const loading = ref(false); |
50 | 80 | |
51 | 81 | const formData = reactive({ |
52 | - account: '', | |
53 | - mobile: '', | |
54 | - sms: '', | |
82 | + phone: '', | |
83 | + smsCaptchaCode: '', | |
84 | + password: '', | |
85 | + confirmPassword: '', | |
86 | + }); | |
87 | + | |
88 | + const imgCaptchaCode = ref(''); | |
89 | + const imgCaptcha = ref(''); | |
90 | + const imgCaptchaUuid = ref(''); | |
91 | + const userStore = useUserStore(); | |
92 | + | |
93 | + onMounted(async () => { | |
94 | + getImgCaptcha(); | |
55 | 95 | }); |
56 | 96 | |
97 | + const getImgCaptcha = async () => { | |
98 | + const data = await userStore.getImageCaptcha(); | |
99 | + imgCaptcha.value = data?.img; | |
100 | + imgCaptchaUuid.value = data?.uuid; | |
101 | + }; | |
102 | + | |
103 | + const handleSendMsg = async () => { | |
104 | + if (!formData.phone) { | |
105 | + message.error('请输入手机号'); | |
106 | + return false; | |
107 | + } | |
108 | + if (!imgCaptchaCode.value) { | |
109 | + message.error('请输入验证码'); | |
110 | + return false; | |
111 | + } | |
112 | + if (formData.password !== formData.confirmPassword) { | |
113 | + message.error('密码和确认密码不一样'); | |
114 | + return false; | |
115 | + } | |
116 | + return await getSms({ | |
117 | + phone: formData.phone, | |
118 | + imgCaptchaCode: imgCaptchaCode.value, | |
119 | + imgCaptchaUuid: imgCaptchaUuid.value, | |
120 | + }); | |
121 | + }; | |
122 | + | |
57 | 123 | const getShow = computed(() => unref(getLoginState) === LoginStateEnum.RESET_PASSWORD); |
58 | 124 | |
59 | 125 | async function handleReset() { |
60 | - const form = unref(formRef); | |
61 | - if (!form) return; | |
62 | - await form.resetFields(); | |
126 | + try { | |
127 | + await formRef.value.validate(); | |
128 | + const form = unref(formRef); | |
129 | + if (!form) return; | |
130 | + await forgetPassword({ ...formData }); | |
131 | + handleBackLogin(); | |
132 | + } catch (error) {} | |
63 | 133 | } |
64 | 134 | </script> | ... | ... |
src/views/sys/login/LoginForm.vue
... | ... | @@ -34,13 +34,15 @@ |
34 | 34 | /> |
35 | 35 | </FormItem> |
36 | 36 | <FormItem name="imgCaptchaCode" class="enter-x" label="验证码"> |
37 | - <img :src="imgCaptcha" class="cursor-pointer" @click="getImgCaptcha" /> | |
37 | + <img :src="imgCaptcha" class="cursor-pointer mr-40" @click="getImgCaptcha" /> | |
38 | + <Button type="link" size="small" @click="setLoginState(LoginStateEnum.RESET_PASSWORD)"> | |
39 | + {{ t('sys.login.forgetPassword') }} | |
40 | + </Button> | |
38 | 41 | </FormItem> |
39 | 42 | |
40 | - <ARow class="enter-x"> | |
43 | + <!-- <ARow class="enter-x"> | |
41 | 44 | <ACol :span="12"> |
42 | 45 | <FormItem> |
43 | - <!-- No logic, you need to deal with it yourself --> | |
44 | 46 | <Checkbox v-model:checked="rememberMe" size="small"> |
45 | 47 | {{ t('sys.login.rememberMe') }} |
46 | 48 | </Checkbox> |
... | ... | @@ -48,13 +50,12 @@ |
48 | 50 | </ACol> |
49 | 51 | <ACol :span="12"> |
50 | 52 | <FormItem :style="{ 'text-align': 'right' }"> |
51 | - <!-- No logic, you need to deal with it yourself --> | |
52 | 53 | <Button type="link" size="small" @click="setLoginState(LoginStateEnum.RESET_PASSWORD)"> |
53 | 54 | {{ t('sys.login.forgetPassword') }} |
54 | 55 | </Button> |
55 | 56 | </FormItem> |
56 | 57 | </ACol> |
57 | - </ARow> | |
58 | + </ARow> --> | |
58 | 59 | |
59 | 60 | <FormItem class="enter-x"> |
60 | 61 | <Button type="primary" size="large" block @click="handleLogin" :loading="loading"> |
... | ... | @@ -64,23 +65,23 @@ |
64 | 65 | {{ t('sys.login.registerButton') }} |
65 | 66 | </Button> --> |
66 | 67 | </FormItem> |
67 | - <ARow class="enter-x"> | |
68 | - <!-- <ACol :md="8" :xs="24"> | |
68 | + <!-- <ARow class="enter-x"> --> | |
69 | + <!-- <ACol :md="8" :xs="24"> | |
69 | 70 | <Button block @click="setLoginState(LoginStateEnum.MOBILE)"> |
70 | 71 | {{ t('sys.login.mobileSignInFormTitle') }} |
71 | 72 | </Button> |
72 | 73 | </ACol> --> |
73 | - <!-- <ACol :md="8" :xs="24" class="!my-2 !md:my-0 xs:mx-0 md:mx-2"> | |
74 | + <!-- <ACol :md="8" :xs="24" class="!my-2 !md:my-0 xs:mx-0 md:mx-2"> | |
74 | 75 | <Button block @click="setLoginState(LoginStateEnum.QR_CODE)"> |
75 | 76 | {{ t('sys.login.qrSignInFormTitle') }} |
76 | 77 | </Button> |
77 | 78 | </ACol> --> |
78 | - <!-- <ACol :md="6" :xs="24"> | |
79 | + <!-- <ACol :md="6" :xs="24"> | |
79 | 80 | <Button block @click="setLoginState(LoginStateEnum.REGISTER)"> |
80 | 81 | {{ t('sys.login.registerButton') }} |
81 | 82 | </Button> |
82 | 83 | </ACol> --> |
83 | - </ARow> | |
84 | + <!-- </ARow> --> | |
84 | 85 | <!-- |
85 | 86 | <Divider class="enter-x">{{ t('sys.login.otherSignIn') }}</Divider> |
86 | 87 | |
... | ... | @@ -133,8 +134,8 @@ |
133 | 134 | const imgCaptchaUuid = ref(''); |
134 | 135 | |
135 | 136 | const formData = reactive({ |
136 | - userName: 'admin', | |
137 | - password: '123456', | |
137 | + userName: '', | |
138 | + password: '', | |
138 | 139 | imgCaptchaCode: '', |
139 | 140 | imgCaptchaUuid: '', |
140 | 141 | }); | ... | ... |
src/views/sys/login/useLogin.ts
... | ... | @@ -53,6 +53,7 @@ export function useFormRules(formData?: Recordable) { |
53 | 53 | const getPasswordFormRule = computed(() => createRule(t('sys.login.passwordPlaceholder'))); |
54 | 54 | const getSmsFormRule = computed(() => createRule(t('sys.login.smsPlaceholder'))); |
55 | 55 | const getMobileFormRule = computed(() => createRule(t('sys.login.mobilePlaceholder'))); |
56 | + const getConfirmPasswordFormRule = computed(() => createRule(t('请输入确认密码'))); | |
56 | 57 | |
57 | 58 | const validatePolicy = async (_: RuleObject, value: boolean) => { |
58 | 59 | return !value ? Promise.reject(t('sys.login.policyPlaceholder')) : Promise.resolve(); |
... | ... | @@ -75,10 +76,11 @@ export function useFormRules(formData?: Recordable) { |
75 | 76 | const passwordFormRule = unref(getPasswordFormRule); |
76 | 77 | const smsFormRule = unref(getSmsFormRule); |
77 | 78 | const mobileFormRule = unref(getMobileFormRule); |
79 | + const confirmPasswordFormRule = unref(getConfirmPasswordFormRule); | |
78 | 80 | |
79 | 81 | const mobileRule = { |
80 | 82 | sms: smsFormRule, |
81 | - mobile: mobileFormRule, | |
83 | + phone: mobileFormRule, | |
82 | 84 | }; |
83 | 85 | switch (unref(currentState)) { |
84 | 86 | // register form rules |
... | ... | @@ -97,6 +99,8 @@ export function useFormRules(formData?: Recordable) { |
97 | 99 | case LoginStateEnum.RESET_PASSWORD: |
98 | 100 | return { |
99 | 101 | userName: accountFormRule, |
102 | + password: passwordFormRule, | |
103 | + confirmPassword: confirmPasswordFormRule, | |
100 | 104 | ...mobileRule, |
101 | 105 | }; |
102 | 106 | ... | ... |
vite.config.ts
... | ... | @@ -20,15 +20,15 @@ export default defineApplicationConfig({ |
20 | 20 | server: { |
21 | 21 | proxy: { |
22 | 22 | '/basic-api/order': { |
23 | - target: 'http://39.108.227.113:8010', | |
23 | + target: 'http://39.108.227.113:8000', | |
24 | 24 | // target: 'http://39.108.227.113:3000/mock/35', |
25 | - // http://39.108.227.113:8010/order/erp/captcha/get_img_captcha_code | |
25 | + // http://39.108.227.113:8000/order/erp/captcha/get_img_captcha_code | |
26 | 26 | changeOrigin: true, |
27 | 27 | ws: true, |
28 | 28 | rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''), |
29 | 29 | }, |
30 | 30 | '/api/localStorage/upload': { |
31 | - target: 'http://39.108.227.113:8010', | |
31 | + target: 'http://39.108.227.113:8000', | |
32 | 32 | changeOrigin: true, |
33 | 33 | ws: true, |
34 | 34 | // rewrite: (path) => { | ... | ... |