Commit 6953c5ab30b15edf472381f03d984f4cb42b7cf7
1 parent
20bd399f
feat: 开发完成
Showing
45 changed files
with
1652 additions
and
364 deletions
src/api/demo/table.ts
1 | import { defHttp } from '/@/utils/http/axios'; | 1 | import { defHttp } from '/@/utils/http/axios'; |
2 | import { DemoParams, DemoListGetResultModel } from './model/tableModel'; | 2 | import { DemoParams, DemoListGetResultModel } from './model/tableModel'; |
3 | -import { find } from 'lodash-es'; | ||
4 | -import { FIELDS_BASE_INFO } from '../../views/project/order/constant'; | ||
5 | 3 | ||
6 | enum Api { | 4 | enum Api { |
7 | DEMO_LIST = '/table/getDemoList', | 5 | DEMO_LIST = '/table/getDemoList', |
@@ -39,8 +37,8 @@ export const demoApproveListApi = async (params: DemoParams) => { | @@ -39,8 +37,8 @@ export const demoApproveListApi = async (params: DemoParams) => { | ||
39 | item.fields = []; | 37 | item.fields = []; |
40 | Object.entries(item.fieldInfos.baseFields).map(([key, value]) => { | 38 | Object.entries(item.fieldInfos.baseFields).map(([key, value]) => { |
41 | if (value === 'UN_LOCKED') { | 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 | item.fields = item.fields.join(','); | 44 | item.fields = item.fields.join(','); |
src/api/project/order.ts
@@ -3,6 +3,7 @@ import { defHttp } from '/@/utils/http/axios'; | @@ -3,6 +3,7 @@ import { defHttp } from '/@/utils/http/axios'; | ||
3 | import { useUserStoreWithOut } from '/@/store/modules/user'; | 3 | import { useUserStoreWithOut } from '/@/store/modules/user'; |
4 | import { useOrderStoreWithOut } from '/@/store/modules/order'; | 4 | import { useOrderStoreWithOut } from '/@/store/modules/order'; |
5 | import { formatToDate } from '/@/utils/dateUtil'; | 5 | import { formatToDate } from '/@/utils/dateUtil'; |
6 | +import message from '/@/views/form-design/utils/message'; | ||
6 | 7 | ||
7 | enum Api { | 8 | enum Api { |
8 | ORDER_CREATE = '/order/erp/order/add', | 9 | ORDER_CREATE = '/order/erp/order/add', |
@@ -19,11 +20,37 @@ enum Api { | @@ -19,11 +20,37 @@ enum Api { | ||
19 | DICT_LIST = '/order/erp/dictionary/list_by_page', | 20 | DICT_LIST = '/order/erp/dictionary/list_by_page', |
20 | 21 | ||
21 | ANALYSIS = '/order/erp/profit/analysis', | 22 | ANALYSIS = '/order/erp/profit/analysis', |
23 | + GRAVITY = '/order/erp/report/analysis', | ||
22 | 24 | ||
23 | OPT_LOG = '/order/erp/opt/log/list_by_page', // 操作日志 | 25 | OPT_LOG = '/order/erp/opt/log/list_by_page', // 操作日志 |
24 | AUDIT_LOG = '/order/erp/audit/log/list_by_page', //审批日志 | 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 | export const orderCreate = async (data: any) => { | 54 | export const orderCreate = async (data: any) => { |
28 | const res = await defHttp.post<any>({ url: Api.ORDER_CREATE, data }, { message: '保存成功' }); | 55 | const res = await defHttp.post<any>({ url: Api.ORDER_CREATE, data }, { message: '保存成功' }); |
29 | return res; | 56 | return res; |
@@ -50,6 +77,13 @@ export const orderAnalysis = async (data: any) => { | @@ -50,6 +77,13 @@ export const orderAnalysis = async (data: any) => { | ||
50 | return res; | 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 | export const orderExport = async (data: any = {}) => { | 87 | export const orderExport = async (data: any = {}) => { |
54 | // const res = await defHttp.post<any>({ url: Api.EXPORT, data }); | 88 | // const res = await defHttp.post<any>({ url: Api.EXPORT, data }); |
55 | const userStore = useUserStoreWithOut(); | 89 | const userStore = useUserStoreWithOut(); |
@@ -60,7 +94,7 @@ export const orderExport = async (data: any = {}) => { | @@ -60,7 +94,7 @@ export const orderExport = async (data: any = {}) => { | ||
60 | url: '/basic-api' + Api.EXPORT, | 94 | url: '/basic-api' + Api.EXPORT, |
61 | method: 'post', | 95 | method: 'post', |
62 | responseType: 'blob', | 96 | responseType: 'blob', |
63 | - headers: { Authorization: `Bearer ${token}` }, | 97 | + headers: { Authorization: `${token}` }, |
64 | data, | 98 | data, |
65 | }) | 99 | }) |
66 | .then((response) => { | 100 | .then((response) => { |
@@ -74,6 +108,8 @@ export const orderExport = async (data: any = {}) => { | @@ -74,6 +108,8 @@ export const orderExport = async (data: any = {}) => { | ||
74 | a.click(); // 模拟点击操作来下载文件 | 108 | a.click(); // 模拟点击操作来下载文件 |
75 | URL.revokeObjectURL(downloadUrl); // 释放掉 blob 对象所占用的内存 | 109 | URL.revokeObjectURL(downloadUrl); // 释放掉 blob 对象所占用的内存 |
76 | document.body.removeChild(a); | 110 | document.body.removeChild(a); |
111 | + | ||
112 | + message.success('导出成功'); | ||
77 | }) | 113 | }) |
78 | .catch((error) => { | 114 | .catch((error) => { |
79 | // 处理错误 | 115 | // 处理错误 |
@@ -104,28 +140,7 @@ export async function uploadImg(params, onUploadProgress: (progressEvent: Progre | @@ -104,28 +140,7 @@ export async function uploadImg(params, onUploadProgress: (progressEvent: Progre | ||
104 | } | 140 | } |
105 | 141 | ||
106 | export const getOrderList = async (params: DemoParams) => { | 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 | const res = await defHttp.post<DemoListGetResultModel>({ | 144 | const res = await defHttp.post<DemoListGetResultModel>({ |
130 | url: Api.ORDER, | 145 | url: Api.ORDER, |
131 | params, | 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,6 +10,11 @@ enum Api { | ||
10 | GetUserInfo = '/getUserInfo', | 10 | GetUserInfo = '/getUserInfo', |
11 | GetPermCode = '/getPermCode', | 11 | GetPermCode = '/getPermCode', |
12 | TestRetry = '/testRetry', | 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,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 | * @description: getUserInfo | 49 | * @description: getUserInfo |
32 | */ | 50 | */ |
@@ -56,5 +74,18 @@ export function testRetry() { | @@ -56,5 +74,18 @@ export function testRetry() { | ||
56 | } | 74 | } |
57 | 75 | ||
58 | export function getImageCaptcha() { | 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
@@ -2,7 +2,7 @@ export enum PageEnum { | @@ -2,7 +2,7 @@ export enum PageEnum { | ||
2 | // basic login path | 2 | // basic login path |
3 | BASE_LOGIN = '/login', | 3 | BASE_LOGIN = '/login', |
4 | // basic home path | 4 | // basic home path |
5 | - BASE_HOME = '/', | 5 | + BASE_HOME = '/home', |
6 | // error page path | 6 | // error page path |
7 | ERROR_PAGE = '/exception', | 7 | ERROR_PAGE = '/exception', |
8 | // error log page path | 8 | // error log page path |
src/enums/roleEnum.ts
src/hooks/component/order.ts
@@ -9,6 +9,11 @@ export function useOrderInfo(orderStore) { | @@ -9,6 +9,11 @@ export function useOrderInfo(orderStore) { | ||
9 | value: item.dictValue, | 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 | const customerCode = computed(() => { | 17 | const customerCode = computed(() => { |
13 | const dictInfo = orderStore.getDictInfo; | 18 | const dictInfo = orderStore.getDictInfo; |
14 | 19 | ||
@@ -75,7 +80,11 @@ export function useOrderInfo(orderStore) { | @@ -75,7 +80,11 @@ export function useOrderInfo(orderStore) { | ||
75 | return map(dictInfo?.midCheckResult, transformDictInfo); | 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 | return { | 88 | return { |
80 | customerCode, | 89 | customerCode, |
81 | projectNo, | 90 | projectNo, |
@@ -90,5 +99,7 @@ export function useOrderInfo(orderStore) { | @@ -90,5 +99,7 @@ export function useOrderInfo(orderStore) { | ||
90 | manualPreform, | 99 | manualPreform, |
91 | midCheckResult, | 100 | midCheckResult, |
92 | endCheckResult, | 101 | endCheckResult, |
102 | + exchangeRate, | ||
103 | + businessPerson, | ||
93 | }; | 104 | }; |
94 | } | 105 | } |
src/layouts/default/header/components/user-dropdown/index.vue
1 | <template> | 1 | <template> |
2 | <Dropdown placement="bottomLeft" :overlayClassName="`${prefixCls}-dropdown-overlay`"> | 2 | <Dropdown placement="bottomLeft" :overlayClassName="`${prefixCls}-dropdown-overlay`"> |
3 | <span :class="[prefixCls, `${prefixCls}--${theme}`]" class="flex"> | 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 | <span :class="`${prefixCls}__info hidden md:block`"> | 5 | <span :class="`${prefixCls}__info hidden md:block`"> |
6 | <span :class="`${prefixCls}__name `" class="truncate"> | 6 | <span :class="`${prefixCls}__name `" class="truncate"> |
7 | - {{ getUserInfo.realName }} | 7 | + {{ getUserInfo.nickName }} |
8 | </span> | 8 | </span> |
9 | </span> | 9 | </span> |
10 | </span> | 10 | </span> |
@@ -76,8 +76,13 @@ | @@ -76,8 +76,13 @@ | ||
76 | const userStore = useUserStore(); | 76 | const userStore = useUserStore(); |
77 | 77 | ||
78 | const getUserInfo = computed(() => { | 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 | const [register, { openModal }] = useModal(); | 88 | const [register, { openModal }] = useModal(); |
src/layouts/default/header/index.less
@@ -104,7 +104,7 @@ | @@ -104,7 +104,7 @@ | ||
104 | display: flex; | 104 | display: flex; |
105 | // padding-right: 12px; | 105 | // padding-right: 12px; |
106 | align-items: center; | 106 | align-items: center; |
107 | - min-width: 180px; | 107 | + min-width: 120px; |
108 | 108 | ||
109 | &__item { | 109 | &__item { |
110 | display: flex !important; | 110 | display: flex !important; |
src/layouts/default/header/index.vue
@@ -49,7 +49,6 @@ | @@ -49,7 +49,6 @@ | ||
49 | /> --> | 49 | /> --> |
50 | 50 | ||
51 | <UserDropDown :theme="getHeaderTheme" /> | 51 | <UserDropDown :theme="getHeaderTheme" /> |
52 | - <span className="text-gray-900">{{ nickName }}</span> | ||
53 | <!-- <SettingDrawer v-if="getShowSetting" :class="`${prefixCls}-action__item`" /> --> | 52 | <!-- <SettingDrawer v-if="getShowSetting" :class="`${prefixCls}-action__item`" /> --> |
54 | </div> | 53 | </div> |
55 | </Header> | 54 | </Header> |
src/router/routes/modules/project/system.ts
@@ -2,6 +2,7 @@ import type { AppRouteModule } from '/@/router/types'; | @@ -2,6 +2,7 @@ import type { AppRouteModule } from '/@/router/types'; | ||
2 | 2 | ||
3 | import { LAYOUT } from '/@/router/constant'; | 3 | import { LAYOUT } from '/@/router/constant'; |
4 | import { t } from '/@/hooks/web/useI18n'; | 4 | import { t } from '/@/hooks/web/useI18n'; |
5 | +import { RoleEnum } from '/@/enums/roleEnum'; | ||
5 | 6 | ||
6 | const system: AppRouteModule = { | 7 | const system: AppRouteModule = { |
7 | path: '/system', | 8 | path: '/system', |
@@ -19,21 +20,41 @@ const system: AppRouteModule = { | @@ -19,21 +20,41 @@ const system: AppRouteModule = { | ||
19 | name: 'AccountManagement', | 20 | name: 'AccountManagement', |
20 | meta: { | 21 | meta: { |
21 | title: t('routes.demo.system.account'), | 22 | title: t('routes.demo.system.account'), |
23 | + roles: [RoleEnum.ADMIN], | ||
22 | ignoreKeepAlive: false, | 24 | ignoreKeepAlive: false, |
23 | }, | 25 | }, |
24 | component: () => import('/@/views/project/account/index.vue'), | 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 | meta: { | 52 | meta: { |
30 | - hideMenu: true, | ||
31 | - title: t('routes.demo.system.account_detail'), | 53 | + title: '系统配置', |
32 | ignoreKeepAlive: true, | 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 | // path: 'role', | 60 | // path: 'role', |
src/store/modules/order.ts
@@ -92,7 +92,7 @@ export const useOrderStore = defineStore({ | @@ -92,7 +92,7 @@ export const useOrderStore = defineStore({ | ||
92 | async getDict(): Promise<GetUserInfoModel | null> { | 92 | async getDict(): Promise<GetUserInfoModel | null> { |
93 | try { | 93 | try { |
94 | const data = await getInitDictData(); | 94 | const data = await getInitDictData(); |
95 | - console.log('%c [ data ]-95', 'font-size:13px; background:pink; color:#bf2c9f;', data); | 95 | + |
96 | this.dicts = groupBy(data, 'dictCode'); | 96 | this.dicts = groupBy(data, 'dictCode'); |
97 | } catch (error) { | 97 | } catch (error) { |
98 | return Promise.reject(error); | 98 | return Promise.reject(error); |
src/store/modules/permission.ts
@@ -112,6 +112,11 @@ export const usePermissionStore = defineStore({ | @@ -112,6 +112,11 @@ export const usePermissionStore = defineStore({ | ||
112 | async buildRoutesAction(): Promise<AppRouteRecordRaw[]> { | 112 | async buildRoutesAction(): Promise<AppRouteRecordRaw[]> { |
113 | const { t } = useI18n(); | 113 | const { t } = useI18n(); |
114 | const userStore = useUserStore(); | 114 | const userStore = useUserStore(); |
115 | + console.log( | ||
116 | + '%c [ userStore ]-115', | ||
117 | + 'font-size:13px; background:pink; color:#bf2c9f;', | ||
118 | + userStore, | ||
119 | + ); | ||
115 | const appStore = useAppStoreWithOut(); | 120 | const appStore = useAppStoreWithOut(); |
116 | 121 | ||
117 | let routes: AppRouteRecordRaw[] = []; | 122 | let routes: AppRouteRecordRaw[] = []; |
@@ -127,7 +132,9 @@ export const usePermissionStore = defineStore({ | @@ -127,7 +132,9 @@ export const usePermissionStore = defineStore({ | ||
127 | const { roles } = meta || {}; | 132 | const { roles } = meta || {}; |
128 | if (!roles) return true; | 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 | const routeRemoveIgnoreFilter = (route: AppRouteRecordRaw) => { | 140 | const routeRemoveIgnoreFilter = (route: AppRouteRecordRaw) => { |
@@ -195,6 +202,7 @@ export const usePermissionStore = defineStore({ | @@ -195,6 +202,7 @@ export const usePermissionStore = defineStore({ | ||
195 | routes = filter(routes, routeRemoveIgnoreFilter); | 202 | routes = filter(routes, routeRemoveIgnoreFilter); |
196 | // 移除掉 ignoreRoute: true 的路由 一级路由; | 203 | // 移除掉 ignoreRoute: true 的路由 一级路由; |
197 | routes = routes.filter(routeRemoveIgnoreFilter); | 204 | routes = routes.filter(routeRemoveIgnoreFilter); |
205 | + | ||
198 | // 对菜单进行排序 | 206 | // 对菜单进行排序 |
199 | menuList.sort((a, b) => { | 207 | menuList.sort((a, b) => { |
200 | return (a.meta?.orderNo || 0) - (b.meta?.orderNo || 0); | 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,7 +11,7 @@ export function formatToDateTime(date?: dayjs.ConfigType, format = DATE_TIME_FOR | ||
11 | } | 11 | } |
12 | 12 | ||
13 | export function formatToDate(date?: dayjs.ConfigType, format = DATE_FORMAT): string { | 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 | export const dateUtil = dayjs; | 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 +13,17 @@ | ||
13 | import { defineComponent } from 'vue'; | 13 | import { defineComponent } from 'vue'; |
14 | import { PageWrapper } from '/@/components/Page'; | 14 | import { PageWrapper } from '/@/components/Page'; |
15 | import { BasicForm, useForm } from '/@/components/Form'; | 15 | import { BasicForm, useForm } from '/@/components/Form'; |
16 | + import { useUserStoreWithOut } from '/@/store/modules/user'; | ||
16 | 17 | ||
17 | import { formSchema } from './pwd.data'; | 18 | import { formSchema } from './pwd.data'; |
19 | + import { forgetPassword } from '/@/api/sys/user'; | ||
18 | 20 | ||
19 | export default defineComponent({ | 21 | export default defineComponent({ |
20 | name: 'ChangePassword', | 22 | name: 'ChangePassword', |
21 | components: { BasicForm, PageWrapper }, | 23 | components: { BasicForm, PageWrapper }, |
22 | setup() { | 24 | setup() { |
25 | + const userStore = useUserStoreWithOut(); | ||
26 | + | ||
23 | const [register, { validate, resetFields }] = useForm({ | 27 | const [register, { validate, resetFields }] = useForm({ |
24 | size: 'large', | 28 | size: 'large', |
25 | baseColProps: { span: 24 }, | 29 | baseColProps: { span: 24 }, |
@@ -31,12 +35,10 @@ | @@ -31,12 +35,10 @@ | ||
31 | async function handleSubmit() { | 35 | async function handleSubmit() { |
32 | try { | 36 | try { |
33 | const values = await validate(); | 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 | } catch (error) {} | 42 | } catch (error) {} |
41 | } | 43 | } |
42 | 44 |
src/views/demo/system/password/pwd.data.ts
1 | import { FormSchema } from '/@/components/Form'; | 1 | import { FormSchema } from '/@/components/Form'; |
2 | 2 | ||
3 | export const formSchema: FormSchema[] = [ | 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 | label: '新密码', | 12 | label: '新密码', |
13 | component: 'StrengthMeter', | 13 | component: 'StrengthMeter', |
14 | componentProps: { | 14 | componentProps: { |
@@ -34,7 +34,7 @@ export const formSchema: FormSchema[] = [ | @@ -34,7 +34,7 @@ export const formSchema: FormSchema[] = [ | ||
34 | if (!value) { | 34 | if (!value) { |
35 | return Promise.reject('密码不能为空'); | 35 | return Promise.reject('密码不能为空'); |
36 | } | 36 | } |
37 | - if (value !== values.passwordNew) { | 37 | + if (value !== values.password) { |
38 | return Promise.reject('两次输入的密码不一致!'); | 38 | return Promise.reject('两次输入的密码不一致!'); |
39 | } | 39 | } |
40 | return Promise.resolve(); | 40 | return Promise.resolve(); |
src/views/project/account/index.vue
@@ -70,6 +70,9 @@ | @@ -70,6 +70,9 @@ | ||
70 | }, | 70 | }, |
71 | useSearchForm: true, | 71 | useSearchForm: true, |
72 | showTableSetting: true, | 72 | showTableSetting: true, |
73 | + tableSetting: { | ||
74 | + setting: false, | ||
75 | + }, | ||
73 | bordered: true, | 76 | bordered: true, |
74 | handleSearchInfoFn(info) { | 77 | handleSearchInfoFn(info) { |
75 | console.log('handleSearchInfoFn', info); | 78 | console.log('handleSearchInfoFn', info); |
src/views/project/approve/FieldPanel.vue
@@ -51,14 +51,15 @@ | @@ -51,14 +51,15 @@ | ||
51 | <a-button @click="handleFalse"> 不通过</a-button> | 51 | <a-button @click="handleFalse"> 不通过</a-button> |
52 | </template> | 52 | </template> |
53 | </BasicDrawer> | 53 | </BasicDrawer> |
54 | + <MsgModal v-if="msgVisible" @msg-modal-close="handleMsgModalClose" /> | ||
54 | </PageWrapper> | 55 | </PageWrapper> |
55 | </template> | 56 | </template> |
56 | <script lang="ts"> | 57 | <script lang="ts"> |
58 | + import MsgModal from './MsgModal.vue'; | ||
57 | import { computed, defineComponent, ref } from 'vue'; | 59 | import { computed, defineComponent, ref } from 'vue'; |
58 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; | 60 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
59 | import { PageWrapper } from '/@/components/Page'; | 61 | import { PageWrapper } from '/@/components/Page'; |
60 | import { BasicDrawer, useDrawer } from '/@/components/Drawer'; | 62 | import { BasicDrawer, useDrawer } from '/@/components/Drawer'; |
61 | - | ||
62 | import { approveAuditApi, getApprovedListApi, getWaitListApi } from '/@/api/project/approve'; | 63 | import { approveAuditApi, getApprovedListApi, getWaitListApi } from '/@/api/project/approve'; |
63 | import { | 64 | import { |
64 | FIELDS_BASE_INFO, | 65 | FIELDS_BASE_INFO, |
@@ -81,11 +82,15 @@ | @@ -81,11 +82,15 @@ | ||
81 | BasicDrawer, | 82 | BasicDrawer, |
82 | TableAction, | 83 | TableAction, |
83 | BaseInfo, | 84 | BaseInfo, |
85 | + MsgModal, | ||
84 | }, | 86 | }, |
85 | props: { | 87 | props: { |
86 | isApproved: { type: Boolean }, | 88 | isApproved: { type: Boolean }, |
87 | }, | 89 | }, |
88 | setup(props) { | 90 | setup(props) { |
91 | + // visible 用于msgModal显示隐藏 | ||
92 | + const msgVisible = ref(false); | ||
93 | + | ||
89 | const checkedKeys = ref<Array<string | number>>([]); | 94 | const checkedKeys = ref<Array<string | number>>([]); |
90 | const currentKey = ref('1'); | 95 | const currentKey = ref('1'); |
91 | const [registerDrawer, { openDrawer, closeDrawer }] = useDrawer(); | 96 | const [registerDrawer, { openDrawer, closeDrawer }] = useDrawer(); |
@@ -99,17 +104,35 @@ | @@ -99,17 +104,35 @@ | ||
99 | const baseInfos = ref({}); | 104 | const baseInfos = ref({}); |
100 | const id = ref(''); | 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 | width: 150, | 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 | // useSearchForm: true, | 136 | // useSearchForm: true, |
114 | // formConfig: getFormConfig(), | 137 | // formConfig: getFormConfig(), |
115 | rowKey: 'id', | 138 | rowKey: 'id', |
@@ -209,14 +232,23 @@ | @@ -209,14 +232,23 @@ | ||
209 | } | 232 | } |
210 | 233 | ||
211 | async function handleFalse() { | 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 | const role = computed(() => { | 238 | const role = computed(() => { |
218 | return userStore.getUserInfo?.roleSmallVO?.code; | 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 | return { | 252 | return { |
221 | handleProfitModal, | 253 | handleProfitModal, |
222 | registerTable, | 254 | registerTable, |
@@ -233,8 +265,9 @@ | @@ -233,8 +265,9 @@ | ||
233 | handleFalse, | 265 | handleFalse, |
234 | ROLE, | 266 | ROLE, |
235 | role, | 267 | role, |
268 | + msgVisible, | ||
269 | + handleMsgModalClose, | ||
236 | }; | 270 | }; |
237 | }, | 271 | }, |
238 | }); | 272 | }); |
239 | </script> | 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,9 +33,11 @@ | ||
33 | <a-button @click="handleFalse"> 不通过</a-button> | 33 | <a-button @click="handleFalse"> 不通过</a-button> |
34 | </template> | 34 | </template> |
35 | </BasicDrawer> | 35 | </BasicDrawer> |
36 | + <MsgModal v-if="msgVisible" @msg-modal-close="handleMsgModalClose" /> | ||
36 | </PageWrapper> | 37 | </PageWrapper> |
37 | </template> | 38 | </template> |
38 | <script lang="ts"> | 39 | <script lang="ts"> |
40 | + import MsgModal from './MsgModal.vue'; | ||
39 | import { computed, defineComponent, ref } from 'vue'; | 41 | import { computed, defineComponent, ref } from 'vue'; |
40 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; | 42 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
41 | import { PageWrapper } from '/@/components/Page'; | 43 | import { PageWrapper } from '/@/components/Page'; |
@@ -56,11 +58,14 @@ | @@ -56,11 +58,14 @@ | ||
56 | BasicDrawer, | 58 | BasicDrawer, |
57 | TableAction, | 59 | TableAction, |
58 | BaseInfo, | 60 | BaseInfo, |
61 | + MsgModal, | ||
59 | }, | 62 | }, |
60 | props: { | 63 | props: { |
61 | isApproved: { type: Boolean }, | 64 | isApproved: { type: Boolean }, |
62 | }, | 65 | }, |
63 | setup(props) { | 66 | setup(props) { |
67 | + // visible 用于msgModal显示隐藏 | ||
68 | + const msgVisible = ref(false); | ||
64 | const checkedKeys = ref<Array<string | number>>([]); | 69 | const checkedKeys = ref<Array<string | number>>([]); |
65 | const currentKey = ref('1'); | 70 | const currentKey = ref('1'); |
66 | const [registerDrawer, { openDrawer, closeDrawer }] = useDrawer(); | 71 | const [registerDrawer, { openDrawer, closeDrawer }] = useDrawer(); |
@@ -68,17 +73,35 @@ | @@ -68,17 +73,35 @@ | ||
68 | const baseInfos = ref({}); | 73 | const baseInfos = ref({}); |
69 | const id = ref(''); | 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 | width: 150, | 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 | // useSearchForm: true, | 105 | // useSearchForm: true, |
83 | // formConfig: getFormConfig(), | 106 | // formConfig: getFormConfig(), |
84 | rowKey: 'id', | 107 | rowKey: 'id', |
@@ -118,6 +141,12 @@ | @@ -118,6 +141,12 @@ | ||
118 | openDrawer(true, { data }); | 141 | openDrawer(true, { data }); |
119 | id.value = data.id; | 142 | id.value = data.id; |
120 | fieldInfos.value = FIELDS_PROFIT_INFO.map((field) => { | 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 | return { | 150 | return { |
122 | label: field.label, | 151 | label: field.label, |
123 | value: data.fieldInfos.profitAnalysisFields[field.field], | 152 | value: data.fieldInfos.profitAnalysisFields[field.field], |
@@ -138,14 +167,25 @@ | @@ -138,14 +167,25 @@ | ||
138 | } | 167 | } |
139 | 168 | ||
140 | async function handleFalse() { | 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 | const role = computed(() => { | 176 | const role = computed(() => { |
147 | return userStore.getUserInfo?.roleSmallVO?.code; | 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 | return { | 189 | return { |
150 | handleProfitModal, | 190 | handleProfitModal, |
151 | registerTable, | 191 | registerTable, |
@@ -162,8 +202,9 @@ | @@ -162,8 +202,9 @@ | ||
162 | handleFalse, | 202 | handleFalse, |
163 | role, | 203 | role, |
164 | ROLE, | 204 | ROLE, |
205 | + msgVisible, | ||
206 | + handleMsgModalClose, | ||
165 | }; | 207 | }; |
166 | }, | 208 | }, |
167 | }); | 209 | }); |
168 | </script> | 210 | </script> |
169 | -../order/constant |
src/views/project/approve/ReportPanel.vue
@@ -33,9 +33,11 @@ | @@ -33,9 +33,11 @@ | ||
33 | <a-button @click="handleFalse"> 不通过</a-button> | 33 | <a-button @click="handleFalse"> 不通过</a-button> |
34 | </template> | 34 | </template> |
35 | </BasicDrawer> | 35 | </BasicDrawer> |
36 | + <MsgModal v-if="msgVisible" @msg-modal-close="handleMsgModalClose" /> | ||
36 | </PageWrapper> | 37 | </PageWrapper> |
37 | </template> | 38 | </template> |
38 | <script lang="ts"> | 39 | <script lang="ts"> |
40 | + import MsgModal from './MsgModal.vue'; | ||
39 | import { computed, defineComponent, ref } from 'vue'; | 41 | import { computed, defineComponent, ref } from 'vue'; |
40 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; | 42 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
41 | import { PageWrapper } from '/@/components/Page'; | 43 | import { PageWrapper } from '/@/components/Page'; |
@@ -56,29 +58,49 @@ | @@ -56,29 +58,49 @@ | ||
56 | BasicDrawer, | 58 | BasicDrawer, |
57 | BaseInfo, | 59 | BaseInfo, |
58 | TableAction, | 60 | TableAction, |
61 | + MsgModal, | ||
59 | }, | 62 | }, |
60 | props: { | 63 | props: { |
61 | isApproved: { type: Boolean }, | 64 | isApproved: { type: Boolean }, |
62 | }, | 65 | }, |
63 | setup(props) { | 66 | setup(props) { |
67 | + // visible 用于msgModal显示隐藏 | ||
68 | + const msgVisible = ref(false); | ||
64 | const checkedKeys = ref<Array<string | number>>([]); | 69 | const checkedKeys = ref<Array<string | number>>([]); |
65 | const currentKey = ref('1'); | 70 | const currentKey = ref('1'); |
66 | const [registerDrawer, { openDrawer, closeDrawer }] = useDrawer(); | 71 | const [registerDrawer, { openDrawer, closeDrawer }] = useDrawer(); |
67 | const fieldInfos = ref({}); | 72 | const fieldInfos = ref({}); |
68 | const baseInfos = ref({}); | 73 | const baseInfos = ref({}); |
69 | const id = ref(''); | 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 | const [registerTable, { reload }] = useTable({ | 99 | const [registerTable, { reload }] = useTable({ |
72 | api: props.isApproved ? getApprovedListApi : getWaitListApi, | 100 | api: props.isApproved ? getApprovedListApi : getWaitListApi, |
73 | searchInfo: { type: 20 }, | 101 | searchInfo: { type: 20 }, |
74 | 102 | ||
75 | - columns: [ | ||
76 | - { | ||
77 | - title: '申请人', | ||
78 | - dataIndex: 'createBy', | ||
79 | - width: 150, | ||
80 | - }, | ||
81 | - ], | 103 | + columns, |
82 | // useSearchForm: true, | 104 | // useSearchForm: true, |
83 | // formConfig: getFormConfig(), | 105 | // formConfig: getFormConfig(), |
84 | rowKey: 'id', | 106 | rowKey: 'id', |
@@ -138,11 +160,19 @@ | @@ -138,11 +160,19 @@ | ||
138 | } | 160 | } |
139 | 161 | ||
140 | async function handleFalse() { | 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 | const role = computed(() => { | 176 | const role = computed(() => { |
147 | return userStore.getUserInfo?.roleSmallVO?.code; | 177 | return userStore.getUserInfo?.roleSmallVO?.code; |
148 | }); | 178 | }); |
@@ -162,8 +192,9 @@ | @@ -162,8 +192,9 @@ | ||
162 | handleFalse, | 192 | handleFalse, |
163 | role, | 193 | role, |
164 | ROLE, | 194 | ROLE, |
195 | + msgVisible, | ||
196 | + handleMsgModalClose, | ||
165 | }; | 197 | }; |
166 | }, | 198 | }, |
167 | }); | 199 | }); |
168 | </script> | 200 | </script> |
169 | -../order/constant |
src/views/project/approve/index.vue
@@ -136,8 +136,6 @@ | @@ -136,8 +136,6 @@ | ||
136 | return false; | 136 | return false; |
137 | } | 137 | } |
138 | 138 | ||
139 | - function handleProfitModal() {} | ||
140 | - | ||
141 | async function handleTrue(record) { | 139 | async function handleTrue(record) { |
142 | await approveAuditApi({ status: 10, id: record.id }); | 140 | await approveAuditApi({ status: 10, id: record.id }); |
143 | reload(); | 141 | reload(); |
@@ -149,7 +147,6 @@ | @@ -149,7 +147,6 @@ | ||
149 | } | 147 | } |
150 | 148 | ||
151 | return { | 149 | return { |
152 | - handleProfitModal, | ||
153 | registerTable1, | 150 | registerTable1, |
154 | registerTable2, | 151 | registerTable2, |
155 | checkedKeys, | 152 | checkedKeys, |
@@ -163,3 +160,9 @@ | @@ -163,3 +160,9 @@ | ||
163 | }, | 160 | }, |
164 | }); | 161 | }); |
165 | </script> | 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,8 +12,10 @@ | ||
12 | okText="申请" | 12 | okText="申请" |
13 | ><input /> | 13 | ><input /> |
14 | <div> | 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 | <template v-if="role === ROLE.ADMIN || role === ROLE.BUSINESS"> | 19 | <template v-if="role === ROLE.ADMIN || role === ROLE.BUSINESS"> |
18 | <h3>利润分析</h3> | 20 | <h3>利润分析</h3> |
19 | <BasicForm @register="registerProfitForm" /> | 21 | <BasicForm @register="registerProfitForm" /> |
@@ -56,19 +58,21 @@ | @@ -56,19 +58,21 @@ | ||
56 | 58 | ||
57 | const userStore = useUserStoreWithOut(); | 59 | const userStore = useUserStoreWithOut(); |
58 | const getSchema = (fields) => | 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 | export default defineComponent({ | 77 | export default defineComponent({ |
74 | components: { BasicDrawer, BasicForm }, | 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,7 +2,7 @@ | ||
2 | <BasicDrawer | 2 | <BasicDrawer |
3 | @register="register" | 3 | @register="register" |
4 | v-bind="$attrs" | 4 | v-bind="$attrs" |
5 | - title="title" | 5 | + title="字段自定义" |
6 | :destroyOnClose="true" | 6 | :destroyOnClose="true" |
7 | width="60%" | 7 | width="60%" |
8 | :isDetail="true" | 8 | :isDetail="true" |
@@ -55,7 +55,7 @@ | @@ -55,7 +55,7 @@ | ||
55 | setup() { | 55 | setup() { |
56 | const dataSource = ref([]); | 56 | const dataSource = ref([]); |
57 | const key = ref(''); | 57 | const key = ref(''); |
58 | - const title = ref(''); | 58 | + const title = ref('12'); |
59 | 59 | ||
60 | const [registerTable, { getDataSource, reload }] = useTable({ | 60 | const [registerTable, { getDataSource, reload }] = useTable({ |
61 | columns: columns, | 61 | columns: columns, |
@@ -72,11 +72,18 @@ | @@ -72,11 +72,18 @@ | ||
72 | }); | 72 | }); |
73 | 73 | ||
74 | const [register] = useDrawerInner((data) => { | 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 | const dicts = orderStore.getDictInfo; | 81 | const dicts = orderStore.getDictInfo; |
77 | const dict = dicts[dataIndex]; | 82 | const dict = dicts[dataIndex]; |
78 | dataSource.value = dict; | 83 | dataSource.value = dict; |
84 | + | ||
79 | title.value = customTitle; | 85 | title.value = customTitle; |
86 | + | ||
80 | key.value = dataIndex; | 87 | key.value = dataIndex; |
81 | }); | 88 | }); |
82 | 89 | ||
@@ -95,13 +102,13 @@ | @@ -95,13 +102,13 @@ | ||
95 | 102 | ||
96 | async function handleSave(record: EditRecordRow) { | 103 | async function handleSave(record: EditRecordRow) { |
97 | if (record.id) { | 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 | } else { | 106 | } else { |
100 | await dictCreate({ | 107 | await dictCreate({ |
101 | dictName: title.value, | 108 | dictName: title.value, |
102 | dictCode: key.value, | 109 | dictCode: key.value, |
103 | dictValue: record.dictValue, | 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,7 +5,7 @@ | ||
5 | import { computed, defineComponent, ref } from 'vue'; | 5 | import { computed, defineComponent, ref } from 'vue'; |
6 | import { BasicForm, useForm } from '/@/components/Form/index'; | 6 | import { BasicForm, useForm } from '/@/components/Form/index'; |
7 | import { FIELDS_BASE_INFO } from '../tableData'; | 7 | import { FIELDS_BASE_INFO } from '../tableData'; |
8 | - import { getDisable } from '/@/utils/project'; | 8 | + import { getBaseDisable } from '/@/utils/project'; |
9 | import { useOrderStoreWithOut } from '/@/store/modules/order'; | 9 | import { useOrderStoreWithOut } from '/@/store/modules/order'; |
10 | 10 | ||
11 | import { useOrderInfo } from '/@/hooks/component/order'; | 11 | import { useOrderInfo } from '/@/hooks/component/order'; |
@@ -24,6 +24,9 @@ | @@ -24,6 +24,9 @@ | ||
24 | id: { | 24 | id: { |
25 | type: String, | 25 | type: String, |
26 | }, | 26 | }, |
27 | + businessUsers: { | ||
28 | + type: Array, | ||
29 | + }, | ||
27 | }, | 30 | }, |
28 | emits: ['success'], | 31 | emits: ['success'], |
29 | setup(props) { | 32 | setup(props) { |
@@ -42,7 +45,14 @@ | @@ -42,7 +45,14 @@ | ||
42 | productStyle, | 45 | productStyle, |
43 | outboundType, | 46 | outboundType, |
44 | packetType, | 47 | packetType, |
48 | + | ||
49 | + // businessPerson, | ||
45 | } = useOrderInfo(orderStore); | 50 | } = useOrderInfo(orderStore); |
51 | + console.log( | ||
52 | + '%c [ productionDepartment ]-57', | ||
53 | + 'font-size:13px; background:pink; color:#bf2c9f;', | ||
54 | + productionDepartment, | ||
55 | + ); | ||
46 | 56 | ||
47 | var schemas = computed(() => { | 57 | var schemas = computed(() => { |
48 | const options = { | 58 | const options = { |
@@ -55,14 +65,11 @@ | @@ -55,14 +65,11 @@ | ||
55 | productStyle, | 65 | productStyle, |
56 | outboundType, | 66 | outboundType, |
57 | packetType, | 67 | packetType, |
68 | + | ||
69 | + businessPerson: props.businessUsers, | ||
58 | }; | 70 | }; |
59 | 71 | ||
60 | const res = FIELDS_BASE_INFO.map((item) => { | 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 | if (item.field === 'picUrl') { | 73 | if (item.field === 'picUrl') { |
67 | return { | 74 | return { |
68 | field: 'picUrl', | 75 | field: 'picUrl', |
@@ -74,7 +81,7 @@ | @@ -74,7 +81,7 @@ | ||
74 | }, | 81 | }, |
75 | componentProps: { | 82 | componentProps: { |
76 | imgUrl: picUrl.value, | 83 | imgUrl: picUrl.value, |
77 | - disabled: getDisable(get(fields.value, 'picUrl'), props.id), | 84 | + // disabled: getDisable(get(fields.value, 'picUrl'), props.id), |
78 | onChange: (res) => { | 85 | onChange: (res) => { |
79 | if (res.file?.response?.data) { | 86 | if (res.file?.response?.data) { |
80 | picUrl.value = res.file?.response?.data?.picUrl; | 87 | picUrl.value = res.file?.response?.data?.picUrl; |
@@ -87,12 +94,20 @@ | @@ -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 | return { | 105 | return { |
91 | ...item, | 106 | ...item, |
92 | field: `${item.field}`, | 107 | field: `${item.field}`, |
93 | componentProps: { | 108 | componentProps: { |
94 | ...(item.component === 'Select' && { options: options[item.field] }), | 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 | colProps: { | 112 | colProps: { |
98 | span: 24, | 113 | span: 24, |
src/views/project/order/FormDetail/InspectionFormPanel.vue
@@ -2,10 +2,8 @@ | @@ -2,10 +2,8 @@ | ||
2 | <BasicForm @register="registerForm" /> | 2 | <BasicForm @register="registerForm" /> |
3 | </template> | 3 | </template> |
4 | <script lang="ts"> | 4 | <script lang="ts"> |
5 | - import { computed, defineComponent, ref, toRaw } from 'vue'; | 5 | + import { computed, defineComponent, ref } from 'vue'; |
6 | import { BasicForm, useForm } from '/@/components/Form/index'; | 6 | import { BasicForm, useForm } from '/@/components/Form/index'; |
7 | - import { useDrawerInner } from '/@/components/Drawer'; | ||
8 | - import { dateUtil } from '/@/utils/dateUtil'; | ||
9 | import { FIELDS_INSPECTION_INFO } from '../tableData'; | 7 | import { FIELDS_INSPECTION_INFO } from '../tableData'; |
10 | import { getDisable } from '/@/utils/project'; | 8 | import { getDisable } from '/@/utils/project'; |
11 | import { useOrderStoreWithOut } from '/@/store/modules/order'; | 9 | import { useOrderStoreWithOut } from '/@/store/modules/order'; |
@@ -19,6 +17,9 @@ | @@ -19,6 +17,9 @@ | ||
19 | id: { | 17 | id: { |
20 | type: String, | 18 | type: String, |
21 | }, | 19 | }, |
20 | + inspectFormData: { | ||
21 | + type: Object, | ||
22 | + }, | ||
22 | }, | 23 | }, |
23 | emits: ['success'], | 24 | emits: ['success'], |
24 | setup(props, { emit }) { | 25 | setup(props, { emit }) { |
@@ -37,7 +38,11 @@ | @@ -37,7 +38,11 @@ | ||
37 | ...item, | 38 | ...item, |
38 | componentProps: { | 39 | componentProps: { |
39 | ...(item.component === 'Select' && { options: options[item.field] }), | 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 | colProps: { | 47 | colProps: { |
43 | span: 24, | 48 | span: 24, |
src/views/project/order/FormDetail/ProfitFormPanel.vue
@@ -4,37 +4,52 @@ | @@ -4,37 +4,52 @@ | ||
4 | <script lang="ts"> | 4 | <script lang="ts"> |
5 | import { computed, defineComponent, reactive, ref, toRaw } from 'vue'; | 5 | import { computed, defineComponent, reactive, ref, toRaw } from 'vue'; |
6 | import { BasicForm, useForm } from '/@/components/Form/index'; | 6 | import { BasicForm, useForm } from '/@/components/Form/index'; |
7 | - import { dateUtil } from '/@/utils/dateUtil'; | ||
8 | import { FIELDS_PROFIT_INFO } from '../tableData'; | 7 | import { FIELDS_PROFIT_INFO } from '../tableData'; |
9 | - import { getDisable } from '/@/utils/project'; | 8 | + import { getProfitDisable } from '/@/utils/project'; |
10 | import { get } from 'lodash-es'; | 9 | import { get } from 'lodash-es'; |
10 | + import { useOrderInfo } from '/@/hooks/component/order'; | ||
11 | + import { useOrderStoreWithOut } from '/@/store/modules/order'; | ||
11 | 12 | ||
12 | export default defineComponent({ | 13 | export default defineComponent({ |
13 | components: { BasicForm }, | 14 | components: { BasicForm }, |
14 | 15 | ||
15 | props: { | 16 | props: { |
16 | - detailData: { | ||
17 | - type: Object, | ||
18 | - }, | ||
19 | onGoCheckDetail: { | 17 | onGoCheckDetail: { |
20 | type: Function, | 18 | type: Function, |
21 | }, | 19 | }, |
22 | id: { | 20 | id: { |
23 | type: String, | 21 | type: String, |
24 | }, | 22 | }, |
23 | + profitFormData: { | ||
24 | + type: Object, | ||
25 | + }, | ||
25 | }, | 26 | }, |
26 | emits: ['success'], | 27 | emits: ['success'], |
27 | setup(props, { emit }) { | 28 | setup(props, { emit }) { |
28 | let fields = ref({}); | 29 | let fields = ref({}); |
30 | + const orderStore = useOrderStoreWithOut(); | ||
31 | + | ||
32 | + const { exchangeRate } = useOrderInfo(orderStore); | ||
29 | 33 | ||
30 | const schemas = computed(() => { | 34 | const schemas = computed(() => { |
35 | + const options = { | ||
36 | + exchangeRate, | ||
37 | + }; | ||
38 | + | ||
31 | return FIELDS_PROFIT_INFO.map((item) => { | 39 | return FIELDS_PROFIT_INFO.map((item) => { |
32 | return { | 40 | return { |
33 | ...item, | 41 | ...item, |
34 | field: `${item.field}`, | 42 | field: `${item.field}`, |
35 | componentProps: { | 43 | componentProps: { |
36 | ...item.componentProps, | 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 | colProps: { | 54 | colProps: { |
40 | span: 24, | 55 | span: 24, |
@@ -43,7 +58,7 @@ | @@ -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 | labelWidth: 120, | 62 | labelWidth: 120, |
48 | schemas, | 63 | schemas, |
49 | layout: 'vertical', | 64 | layout: 'vertical', |
@@ -52,7 +67,16 @@ | @@ -52,7 +67,16 @@ | ||
52 | span: 24, | 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 | </script> | 82 | </script> |
src/views/project/order/FormDetail/ReportFormPanel.vue
@@ -24,6 +24,9 @@ | @@ -24,6 +24,9 @@ | ||
24 | id: { | 24 | id: { |
25 | type: String, | 25 | type: String, |
26 | }, | 26 | }, |
27 | + reportFormData: { | ||
28 | + type: Object, | ||
29 | + }, | ||
27 | }, | 30 | }, |
28 | emits: ['success'], | 31 | emits: ['success'], |
29 | setup(props) { | 32 | setup(props) { |
@@ -39,12 +42,20 @@ | @@ -39,12 +42,20 @@ | ||
39 | }; | 42 | }; |
40 | 43 | ||
41 | const res = FIELDS_REPORT_INFO.map((item) => { | 44 | const res = FIELDS_REPORT_INFO.map((item) => { |
45 | + let optionsField = item.field; | ||
46 | + if (optionsField === 'manualPreform1' || optionsField === 'manualPreform2') { | ||
47 | + optionsField = 'manualPreform'; | ||
48 | + } | ||
42 | return { | 49 | return { |
43 | ...item, | 50 | ...item, |
44 | field: `${item.field}`, | 51 | field: `${item.field}`, |
45 | componentProps: { | 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 | colProps: { | 60 | colProps: { |
50 | span: 24, | 61 | span: 24, |
@@ -54,7 +65,7 @@ | @@ -54,7 +65,7 @@ | ||
54 | return res; | 65 | return res; |
55 | }); | 66 | }); |
56 | 67 | ||
57 | - const [registerForm, { setFieldsValue, getFieldsValue }] = useForm({ | 68 | + const [registerForm, { setFieldsValue, getFieldsValue, resetFields, validate }] = useForm({ |
58 | labelWidth: 120, | 69 | labelWidth: 120, |
59 | schemas, | 70 | schemas, |
60 | layout: 'vertical', | 71 | layout: 'vertical', |
@@ -64,7 +75,15 @@ | @@ -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 | </script> | 89 | </script> |
src/views/project/order/FormDetail/TrackFormPanel.vue
@@ -17,6 +17,9 @@ | @@ -17,6 +17,9 @@ | ||
17 | id: { | 17 | id: { |
18 | type: String, | 18 | type: String, |
19 | }, | 19 | }, |
20 | + trackFormData: { | ||
21 | + type: Object, | ||
22 | + }, | ||
20 | }, | 23 | }, |
21 | emits: ['success'], | 24 | emits: ['success'], |
22 | setup(props, { emit }) { | 25 | setup(props, { emit }) { |
@@ -27,7 +30,11 @@ | @@ -27,7 +30,11 @@ | ||
27 | ...item, | 30 | ...item, |
28 | componentProps: { | 31 | componentProps: { |
29 | ...item.componentProps, | 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 | colProps: { | 39 | colProps: { |
33 | span: 24, | 40 | span: 24, |
src/views/project/order/FormDetail/index.vue
@@ -14,10 +14,15 @@ | @@ -14,10 +14,15 @@ | ||
14 | :mask="false" | 14 | :mask="false" |
15 | class="z-20" | 15 | class="z-20" |
16 | > | 16 | > |
17 | - <div className="mt-[-16px]"> | 17 | + <div className="mt-[-16px] order-drawer-panel"> |
18 | <Tabs v-model:activeKey="activeKey"> | 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 | </TabPanel> | 26 | </TabPanel> |
22 | <TabPanel | 27 | <TabPanel |
23 | key="2" | 28 | key="2" |
@@ -25,7 +30,7 @@ | @@ -25,7 +30,7 @@ | ||
25 | :forceRender="true" | 30 | :forceRender="true" |
26 | v-if="!!id && (role === ROLE.ADMIN || role === ROLE.BUSINESS)" | 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 | </TabPanel> | 34 | </TabPanel> |
30 | <TabPanel | 35 | <TabPanel |
31 | key="3" | 36 | key="3" |
@@ -33,7 +38,7 @@ | @@ -33,7 +38,7 @@ | ||
33 | :forceRender="true" | 38 | :forceRender="true" |
34 | v-if="!!id && (role === ROLE.ADMIN || role === ROLE.BUSINESS)" | 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 | </TabPanel> | 42 | </TabPanel> |
38 | <TabPanel | 43 | <TabPanel |
39 | key="4" | 44 | key="4" |
@@ -41,7 +46,7 @@ | @@ -41,7 +46,7 @@ | ||
41 | :forceRender="true" | 46 | :forceRender="true" |
42 | v-if="!!id && (role === ROLE.ADMIN || role === ROLE.TRACKER)" | 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 | </TabPanel> | 50 | </TabPanel> |
46 | <TabPanel | 51 | <TabPanel |
47 | key="5" | 52 | key="5" |
@@ -49,7 +54,11 @@ | @@ -49,7 +54,11 @@ | ||
49 | :forceRender="true" | 54 | :forceRender="true" |
50 | v-if="!!id && (role === ROLE.ADMIN || role === ROLE.INSPECT)" | 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 | </TabPanel> | 62 | </TabPanel> |
54 | </Tabs> | 63 | </Tabs> |
55 | </div> | 64 | </div> |
@@ -61,7 +70,7 @@ | @@ -61,7 +70,7 @@ | ||
61 | </BasicDrawer> | 70 | </BasicDrawer> |
62 | </template> | 71 | </template> |
63 | <script lang="ts"> | 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 | import { FormActionType, FormSchema, useForm } from '/@/components/Form/index'; | 74 | import { FormActionType, FormSchema, useForm } from '/@/components/Form/index'; |
66 | import { orderCreate, orderUpdate, uploadImg } from '/@/api/project/order'; | 75 | import { orderCreate, orderUpdate, uploadImg } from '/@/api/project/order'; |
67 | import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | 76 | import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; |
@@ -73,8 +82,12 @@ | @@ -73,8 +82,12 @@ | ||
73 | import BaseFormPanel from './BaseFormPanel.vue'; | 82 | import BaseFormPanel from './BaseFormPanel.vue'; |
74 | import { useUserStoreWithOut } from '/@/store/modules/user'; | 83 | import { useUserStoreWithOut } from '/@/store/modules/user'; |
75 | import { ROLE } from '../type.d'; | 84 | import { ROLE } from '../type.d'; |
85 | + import { getList as getConfigList } from '/@/api/sys/config'; | ||
76 | 86 | ||
77 | import { Tabs } from 'ant-design-vue'; | 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 | const userStore = useUserStoreWithOut(); | 92 | const userStore = useUserStoreWithOut(); |
80 | 93 | ||
@@ -109,8 +122,33 @@ | @@ -109,8 +122,33 @@ | ||
109 | const trackFormPanelRef = ref(); | 122 | const trackFormPanelRef = ref(); |
110 | const inspectionFormPanelRef = ref(); | 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 | const formRef = ref<FormActionType | null>(null); | 132 | const formRef = ref<FormActionType | null>(null); |
113 | const id = ref(''); | 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 | const role = computed(() => { | 153 | const role = computed(() => { |
116 | return userStore.getUserInfo?.roleSmallVO?.code; | 154 | return userStore.getUserInfo?.roleSmallVO?.code; |
@@ -120,6 +158,8 @@ | @@ -120,6 +158,8 @@ | ||
120 | let fields = reactive({ baseFields: {} }); | 158 | let fields = reactive({ baseFields: {} }); |
121 | 159 | ||
122 | const [register, { closeDrawer }] = useDrawerInner((data) => { | 160 | const [register, { closeDrawer }] = useDrawerInner((data) => { |
161 | + activeKey.value = | ||
162 | + role.value === ROLE.INSPECT ? '5' : role.value === ROLE.BUSINESS ? '2' : '1'; | ||
123 | if (!data.id) { | 163 | if (!data.id) { |
124 | id.value = ''; | 164 | id.value = ''; |
125 | picUrl.value = ''; | 165 | picUrl.value = ''; |
@@ -133,6 +173,10 @@ | @@ -133,6 +173,10 @@ | ||
133 | return; | 173 | return; |
134 | } | 174 | } |
135 | id.value = data.id; | 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 | // 方式1 | 181 | // 方式1 |
138 | picUrl.value = data.picUrl; | 182 | picUrl.value = data.picUrl; |
@@ -159,10 +203,22 @@ | @@ -159,10 +203,22 @@ | ||
159 | } | 203 | } |
160 | 204 | ||
161 | if (profitFormPanelRef.value) { | 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 | profitFormPanelRef.value.fields = { ...data.lockFields?.profitAnalysisFields } || {}; | 217 | profitFormPanelRef.value.fields = { ...data.lockFields?.profitAnalysisFields } || {}; |
164 | profitFormPanelRef?.value?.setFieldsValue({ | 218 | profitFormPanelRef?.value?.setFieldsValue({ |
165 | ...toRaw(data.profitAnalysisInfo), | 219 | ...toRaw(data.profitAnalysisInfo), |
220 | + packetPrice: packetPrice?.relationValue || 0, | ||
221 | + exchangeRate: exchangeRate?.settingValue, | ||
166 | }); | 222 | }); |
167 | } | 223 | } |
168 | 224 | ||
@@ -186,7 +242,7 @@ | @@ -186,7 +242,7 @@ | ||
186 | inspectionFormPanelRef.value.fields = | 242 | inspectionFormPanelRef.value.fields = |
187 | { ...data.lockFields?.inspectionStageFields } || {}; | 243 | { ...data.lockFields?.inspectionStageFields } || {}; |
188 | inspectionFormPanelRef?.value?.setFieldsValue({ | 244 | inspectionFormPanelRef?.value?.setFieldsValue({ |
189 | - ...toRaw(data.trackStageInfo), | 245 | + ...toRaw(data.inspectionStageInfo), |
190 | }); | 246 | }); |
191 | } | 247 | } |
192 | }, 100); | 248 | }, 100); |
@@ -196,10 +252,10 @@ | @@ -196,10 +252,10 @@ | ||
196 | }); | 252 | }); |
197 | 253 | ||
198 | const handleSubmit = async () => { | 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 | await baseFormPanelRef?.value?.validate(); | 259 | await baseFormPanelRef?.value?.validate(); |
204 | 260 | ||
205 | forms.baseInfo = baseFormPanelRef?.value?.getFieldsValue() || {}; | 261 | forms.baseInfo = baseFormPanelRef?.value?.getFieldsValue() || {}; |
@@ -211,25 +267,36 @@ | @@ -211,25 +267,36 @@ | ||
211 | await orderUpdate(forms); | 267 | await orderUpdate(forms); |
212 | closeDrawer(); | 268 | closeDrawer(); |
213 | emit('success', {}); | 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 | } else { | 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 | await baseFormPanelRef?.value?.validate(); | 300 | await baseFormPanelRef?.value?.validate(); |
234 | 301 | ||
235 | // 新建只有基本信息 | 302 | // 新建只有基本信息 |
@@ -245,9 +312,9 @@ | @@ -245,9 +312,9 @@ | ||
245 | await orderCreate(forms); | 312 | await orderCreate(forms); |
246 | closeDrawer(); | 313 | closeDrawer(); |
247 | emit('success', {}); | 314 | emit('success', {}); |
248 | - } catch (error) { | ||
249 | - console.log(error); | ||
250 | } | 315 | } |
316 | + } catch (error) { | ||
317 | + console.log(error); | ||
251 | } | 318 | } |
252 | }; | 319 | }; |
253 | return { | 320 | return { |
@@ -261,16 +328,25 @@ | @@ -261,16 +328,25 @@ | ||
261 | formRef, | 328 | formRef, |
262 | ROLE, | 329 | ROLE, |
263 | role, | 330 | role, |
331 | + profitFormData, | ||
332 | + inspectFormData, | ||
333 | + reportFormData, | ||
334 | + trackFormData, | ||
264 | register, | 335 | register, |
265 | handleSubmit, | 336 | handleSubmit, |
337 | + businessUsers, | ||
266 | }; | 338 | }; |
267 | }, | 339 | }, |
268 | }); | 340 | }); |
269 | </script> | 341 | </script> |
270 | 342 | ||
271 | -<style scoped> | 343 | +<style> |
272 | .ant-drawer { | 344 | .ant-drawer { |
273 | position: fixed; | 345 | position: fixed; |
274 | z-index: 9999; | 346 | z-index: 9999; |
275 | } | 347 | } |
348 | + | ||
349 | + .order-drawer-panel .ant-picker { | ||
350 | + width: 100% !important; | ||
351 | + } | ||
276 | </style> | 352 | </style> |
src/views/project/order/ProfitAnalysis.vue
@@ -4,9 +4,31 @@ | @@ -4,9 +4,31 @@ | ||
4 | destroyOnClose | 4 | destroyOnClose |
5 | @register="register" | 5 | @register="register" |
6 | title="利润分析表" | 6 | title="利润分析表" |
7 | + width="600px" | ||
7 | @visible-change="handleShow" | 8 | @visible-change="handleShow" |
8 | :footer="null" | 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 | <!-- :helpMessage="['提示1', '提示2']" --> | 32 | <!-- :helpMessage="['提示1', '提示2']" --> |
11 | <!-- <template #insertFooter> | 33 | <!-- <template #insertFooter> |
12 | <a-button type="primary" danger @click="setLines" :disabled="loading">点我更新内容</a-button> | 34 | <a-button type="primary" danger @click="setLines" :disabled="loading">点我更新内容</a-button> |
@@ -25,24 +47,34 @@ | @@ -25,24 +47,34 @@ | ||
25 | </BasicModal> | 47 | </BasicModal> |
26 | </template> | 48 | </template> |
27 | <script lang="ts"> | 49 | <script lang="ts"> |
28 | - import { defineComponent, ref, toRaw, watch } from 'vue'; | 50 | + import { computed, defineComponent, onMounted, ref, toRaw, watch } from 'vue'; |
29 | import { BasicModal, useModalInner } from '/@/components/Modal'; | 51 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
30 | import { Description, DescItem, useDescription } from '/@/components/Description/index'; | 52 | import { Description, DescItem, useDescription } from '/@/components/Description/index'; |
31 | import { orderAnalysis } from '/@/api/project/order'; | 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 | export default defineComponent({ | 59 | export default defineComponent({ |
34 | - components: { BasicModal, Description }, | 60 | + components: { BasicModal, Description, Select, Space }, |
35 | setup() { | 61 | setup() { |
62 | + const orderStore = useOrderStoreWithOut(); | ||
63 | + const { exchangeRate } = useOrderInfo(orderStore); | ||
64 | + const orderIds = ref([]); | ||
36 | const loading = ref(true); | 65 | const loading = ref(true); |
37 | const lines = ref(10); | 66 | const lines = ref(10); |
67 | + const activeRate = ref(); | ||
68 | + const profitType = ref('1'); | ||
38 | const info = ref({}); | 69 | const info = ref({}); |
39 | const [register, { setModalProps, redoModalHeight }] = useModalInner(async (data) => { | 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 | const schema: DescItem[] = [ | 80 | const schema: DescItem[] = [ |
@@ -75,18 +107,37 @@ | @@ -75,18 +107,37 @@ | ||
75 | if (visible) { | 107 | if (visible) { |
76 | loading.value = true; | 108 | loading.value = true; |
77 | // setModalProps({ loading: true, confirmLoading: true }); | 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 | function setLines() { | 114 | function setLines() { |
87 | lines.value = Math.round(Math.random() * 20 + 10); | 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 | </script> | 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,41 +33,56 @@ | ||
33 | <TableAction | 33 | <TableAction |
34 | :actions="[ | 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 | </template> | 62 | </template> |
54 | <template v-if="column.key === 'picUrl'"> | 63 | <template v-if="column.key === 'picUrl'"> |
55 | <img | 64 | <img |
56 | :width="100" | 65 | :width="100" |
57 | :height="100" | 66 | :height="100" |
58 | - :src="record.picUrl" | ||
59 | - :key="record.picUrl" | 67 | + :src="record.smallPicUrl" |
68 | + :key="record.smallPicUrl" | ||
60 | @click="handlePreview(record.picUrl)" | 69 | @click="handlePreview(record.picUrl)" |
61 | /> | 70 | /> |
62 | </template> | 71 | </template> |
63 | </template> | 72 | </template> |
64 | 73 | ||
65 | <template #toolbar> | 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 | <a-button type="primary" @click="handleProfitModal" :disabled="!checkedKeys.length" | 77 | <a-button type="primary" @click="handleProfitModal" :disabled="!checkedKeys.length" |
68 | >分析利润</a-button | 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 | </template> | 86 | </template> |
72 | </BasicTable> | 87 | </BasicTable> |
73 | <FormDetail | 88 | <FormDetail |
@@ -76,13 +91,15 @@ | @@ -76,13 +91,15 @@ | ||
76 | @success="handleFormSuccess" | 91 | @success="handleFormSuccess" |
77 | /> | 92 | /> |
78 | <ProfitAnalysis @register="profitModalRegister" /> | 93 | <ProfitAnalysis @register="profitModalRegister" /> |
94 | + <RateModal @register="rateModalRegister" /> | ||
95 | + <ExportModal @register="exportModalRegister" :role="role" /> | ||
79 | <CheckDetail @register="checkModalRegister" :onGoFormDetail="handleGoFormDetail" /> | 96 | <CheckDetail @register="checkModalRegister" :onGoFormDetail="handleGoFormDetail" /> |
80 | <HistoryDetail @register="historyDetailRegister" /> | 97 | <HistoryDetail @register="historyDetailRegister" /> |
81 | <FieldDetail @register="fieldDetailRegister" /> | 98 | <FieldDetail @register="fieldDetailRegister" /> |
82 | </div> | 99 | </div> |
83 | </template> | 100 | </template> |
84 | <script lang="ts"> | 101 | <script lang="ts"> |
85 | - import { defineComponent, onMounted, ref, toRaw, toRefs, unref } from 'vue'; | 102 | + import { defineComponent, onMounted, ref, toRaw, computed } from 'vue'; |
86 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; | 103 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
87 | import { FormOutlined } from '@ant-design/icons-vue'; | 104 | import { FormOutlined } from '@ant-design/icons-vue'; |
88 | import HeaderCell from '/@/components/Table/src/components/HeaderCell.vue'; | 105 | import HeaderCell from '/@/components/Table/src/components/HeaderCell.vue'; |
@@ -90,6 +107,8 @@ | @@ -90,6 +107,8 @@ | ||
90 | 107 | ||
91 | import { useDrawer } from '/@/components/Drawer'; | 108 | import { useDrawer } from '/@/components/Drawer'; |
92 | import ProfitAnalysis from './ProfitAnalysis.vue'; | 109 | import ProfitAnalysis from './ProfitAnalysis.vue'; |
110 | + import RateModal from './RateModal.vue'; | ||
111 | + import ExportModal from './ExportModal.vue'; | ||
93 | import { useModal } from '/@/components/Modal'; | 112 | import { useModal } from '/@/components/Modal'; |
94 | 113 | ||
95 | import { getFormConfig, getOrderColumns, SELECT_FIELD_COLUMNS } from './tableData'; | 114 | import { getFormConfig, getOrderColumns, SELECT_FIELD_COLUMNS } from './tableData'; |
@@ -98,10 +117,10 @@ | @@ -98,10 +117,10 @@ | ||
98 | import HistoryDetail from './HistoryDetail.vue'; | 117 | import HistoryDetail from './HistoryDetail.vue'; |
99 | import FieldDetail from './FieldDetail.vue'; | 118 | import FieldDetail from './FieldDetail.vue'; |
100 | import { createImgPreview } from '/@/components/Preview/index'; | 119 | import { createImgPreview } from '/@/components/Preview/index'; |
101 | - import { getOrderList, orderExport } from '/@/api/project/order'; | 120 | + import { getOrderList } from '/@/api/project/order'; |
102 | import { useOrderStoreWithOut } from '/@/store/modules/order'; | 121 | import { useOrderStoreWithOut } from '/@/store/modules/order'; |
103 | - import { keyBy, reduce } from 'lodash-es'; | ||
104 | import { useUserStoreWithOut } from '/@/store/modules/user'; | 122 | import { useUserStoreWithOut } from '/@/store/modules/user'; |
123 | + import { ROLE } from './type.d'; | ||
105 | 124 | ||
106 | const orderStore = useOrderStoreWithOut(); | 125 | const orderStore = useOrderStoreWithOut(); |
107 | const userStore = useUserStoreWithOut(); | 126 | const userStore = useUserStoreWithOut(); |
@@ -118,16 +137,24 @@ | @@ -118,16 +137,24 @@ | ||
118 | CheckDetail, | 137 | CheckDetail, |
119 | HistoryDetail, | 138 | HistoryDetail, |
120 | FieldDetail, | 139 | FieldDetail, |
140 | + RateModal, | ||
141 | + ExportModal, | ||
121 | }, | 142 | }, |
122 | setup() { | 143 | setup() { |
123 | const checkedKeys = ref<Array<string | number>>([]); | 144 | const checkedKeys = ref<Array<string | number>>([]); |
124 | const [profitModalRegister, { openModal: openProfitModal }] = useModal(); | 145 | const [profitModalRegister, { openModal: openProfitModal }] = useModal(); |
146 | + const [rateModalRegister, { openModal: openRateModal }] = useModal(); | ||
147 | + const [exportModalRegister, { openModal: openExportModal }] = useModal(); | ||
148 | + | ||
125 | const tooltipVisible = ref(false); | 149 | const tooltipVisible = ref(false); |
126 | const [formDetailRegister, { openDrawer: openFormDetailDrawer }] = useDrawer(); | 150 | const [formDetailRegister, { openDrawer: openFormDetailDrawer }] = useDrawer(); |
127 | const [historyDetailRegister, { openDrawer: openHistoryDetailDrawer }] = useDrawer(); | 151 | const [historyDetailRegister, { openDrawer: openHistoryDetailDrawer }] = useDrawer(); |
128 | const [fieldDetailRegister, { openDrawer: openFieldDetailDrawer }] = useDrawer(); | 152 | const [fieldDetailRegister, { openDrawer: openFieldDetailDrawer }] = useDrawer(); |
129 | 153 | ||
130 | const user = userStore.getUserInfo; | 154 | const user = userStore.getUserInfo; |
155 | + const role = computed(() => { | ||
156 | + return user?.roleSmallVO?.code; | ||
157 | + }); | ||
131 | 158 | ||
132 | const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); | 159 | const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); |
133 | onMounted(async () => { | 160 | onMounted(async () => { |
@@ -211,6 +238,15 @@ | @@ -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 | function handleFieldVisible(record) { | 250 | function handleFieldVisible(record) { |
215 | openFieldDetailDrawer(true, record); | 251 | openFieldDetailDrawer(true, record); |
216 | } | 252 | } |
@@ -225,74 +261,15 @@ | @@ -225,74 +261,15 @@ | ||
225 | openFormDetailDrawer(true); | 261 | openFormDetailDrawer(true); |
226 | } | 262 | } |
227 | 263 | ||
228 | - function handlePreview(url, e) { | 264 | + function handlePreview(url) { |
229 | createImgPreview({ imageList: [url], defaultWidth: 500 }); | 265 | createImgPreview({ imageList: [url], defaultWidth: 500 }); |
230 | // e?.stopPropagation(); | 266 | // e?.stopPropagation(); |
231 | // e?.preventDefault(); | 267 | // e?.preventDefault(); |
232 | return false; | 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 | const handleFormSuccess = () => { | 275 | const handleFormSuccess = () => { |
@@ -300,9 +277,12 @@ | @@ -300,9 +277,12 @@ | ||
300 | }; | 277 | }; |
301 | 278 | ||
302 | return { | 279 | return { |
280 | + user, | ||
303 | SELECT_FIELD_COLUMNS, | 281 | SELECT_FIELD_COLUMNS, |
304 | fieldDetailRegister, | 282 | fieldDetailRegister, |
305 | profitModalRegister, | 283 | profitModalRegister, |
284 | + rateModalRegister, | ||
285 | + exportModalRegister, | ||
306 | historyDetailRegister, | 286 | historyDetailRegister, |
307 | formDetailRegister, | 287 | formDetailRegister, |
308 | handleProfitModal, | 288 | handleProfitModal, |
@@ -321,9 +301,13 @@ | @@ -321,9 +301,13 @@ | ||
321 | handleHistory, | 301 | handleHistory, |
322 | handleAdd, | 302 | handleAdd, |
323 | createImgPreview, | 303 | createImgPreview, |
324 | - handleExport, | 304 | + handleExportModal, |
325 | handlePreview, | 305 | handlePreview, |
326 | handleFormSuccess, | 306 | handleFormSuccess, |
307 | + handleRateModal, | ||
308 | + openExportModal, | ||
309 | + role, | ||
310 | + ROLE, | ||
327 | }; | 311 | }; |
328 | }, | 312 | }, |
329 | }); | 313 | }); |
@@ -337,12 +321,17 @@ | @@ -337,12 +321,17 @@ | ||
337 | } | 321 | } |
338 | 322 | ||
339 | .ant-table-cell img { | 323 | .ant-table-cell img { |
340 | - width: 100px; | ||
341 | - height: 100px; | 324 | + width: 40px; |
325 | + height: 40px; | ||
342 | } | 326 | } |
343 | 327 | ||
344 | .order-page .vben-basic-table .ant-form-item .ant-picker { | 328 | .order-page .vben-basic-table .ant-form-item .ant-picker { |
345 | width: 100%; | 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 | </style> | 336 | </style> |
348 | ./constant | 337 | ./constant |
src/views/project/order/tableData.tsx
1 | import { ROLE } from './type.d'; | 1 | import { ROLE } from './type.d'; |
2 | import { useOrderInfo } from '/@/hooks/component/order'; | 2 | import { useOrderInfo } from '/@/hooks/component/order'; |
3 | import { useOrderStoreWithOut } from '/@/store/modules/order'; | 3 | import { useOrderStoreWithOut } from '/@/store/modules/order'; |
4 | +import { formatToDate } from '/@/utils/dateUtil'; | ||
4 | 5 | ||
5 | // 角色 | 6 | // 角色 |
6 | // 业务员- 查看all,编辑-利润分析,报告书 | 7 | // 业务员- 查看all,编辑-利润分析,报告书 |
@@ -11,21 +12,27 @@ import { useOrderStoreWithOut } from '/@/store/modules/order'; | @@ -11,21 +12,27 @@ import { useOrderStoreWithOut } from '/@/store/modules/order'; | ||
11 | export const SELECT_FIELD_COLUMNS = [ | 12 | export const SELECT_FIELD_COLUMNS = [ |
12 | 'projectNo', | 13 | 'projectNo', |
13 | 'customerCode', | 14 | 'customerCode', |
15 | + 'productionDepartment', | ||
14 | 'innerNo', | 16 | 'innerNo', |
15 | 'poColor', | 17 | 'poColor', |
16 | 'cnColor', | 18 | 'cnColor', |
17 | 'productStyle', | 19 | 'productStyle', |
18 | 'outboundType', | 20 | 'outboundType', |
19 | 'packetType', | 21 | 'packetType', |
22 | + 'ideaSource', | ||
23 | + 'manualPreform1', | ||
24 | + 'manualPreform2', | ||
20 | 'midCheckResult', | 25 | 'midCheckResult', |
21 | 'endCheckResult', | 26 | 'endCheckResult', |
27 | + // 'exchangeRate', | ||
28 | + 'businessPerson', | ||
22 | ]; | 29 | ]; |
23 | 30 | ||
24 | /** | 31 | /** |
25 | * | 32 | * |
26 | * @returns 订单列表数据 | 33 | * @returns 订单列表数据 |
27 | */ | 34 | */ |
28 | -const ORDER_LIST_BASE_FIELDS = [ | 35 | +export const ORDER_LIST_BASE_FIELDS = [ |
29 | { | 36 | { |
30 | title: '客户编码', | 37 | title: '客户编码', |
31 | width: 150, | 38 | width: 150, |
@@ -110,11 +117,19 @@ const ORDER_LIST_BASE_FIELDS = [ | @@ -110,11 +117,19 @@ const ORDER_LIST_BASE_FIELDS = [ | ||
110 | title: '生成科拖货时间', | 117 | title: '生成科拖货时间', |
111 | width: 150, | 118 | width: 150, |
112 | dataIndex: 'productionDepartmentConsignTime', | 119 | dataIndex: 'productionDepartmentConsignTime', |
120 | + customRender: (column) => { | ||
121 | + const { record } = column || {}; | ||
122 | + return formatToDate(record?.productionDepartmentConsignTime); | ||
123 | + }, | ||
113 | }, | 124 | }, |
114 | { | 125 | { |
115 | title: '订单上HOD时间', | 126 | title: '订单上HOD时间', |
116 | width: 150, | 127 | width: 150, |
117 | dataIndex: 'orderHodTime', | 128 | dataIndex: 'orderHodTime', |
129 | + customRender: (column) => { | ||
130 | + const { record } = column || {}; | ||
131 | + return formatToDate(record?.orderHodTime); | ||
132 | + }, | ||
118 | }, | 133 | }, |
119 | { | 134 | { |
120 | title: '出库类型', | 135 | title: '出库类型', |
@@ -126,9 +141,14 @@ const ORDER_LIST_BASE_FIELDS = [ | @@ -126,9 +141,14 @@ const ORDER_LIST_BASE_FIELDS = [ | ||
126 | width: 150, | 141 | width: 150, |
127 | dataIndex: 'packetType', | 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 | title: '项目完成报告信息', | 153 | title: '项目完成报告信息', |
134 | width: 150, | 154 | width: 150, |
@@ -137,35 +157,62 @@ const ORDER_LIST_REPORT_FIELDS = [ | @@ -137,35 +157,62 @@ const ORDER_LIST_REPORT_FIELDS = [ | ||
137 | { | 157 | { |
138 | title: '想法来源', | 158 | title: '想法来源', |
139 | width: 150, | 159 | width: 150, |
140 | - dataIndex: 'reportInfo.ideaSource', | 160 | + dataIndex: 'ideaSource', |
141 | customRender: (column) => { | 161 | customRender: (column) => { |
142 | const { record } = column || {}; | 162 | const { record } = column || {}; |
143 | return record?.reportInfo?.ideaSource; | 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 | width: 150, | 195 | width: 150, |
149 | - dataIndex: 'reportInfo.manualPreform', | 196 | + dataIndex: 'manualPreform2', |
150 | customRender: (column) => { | 197 | customRender: (column) => { |
151 | const { record } = column || {}; | 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 | width: 150, | 204 | width: 150, |
158 | - dataIndex: 'reportInfo.ideaManualRate', | 205 | + dataIndex: 'manualPreform2Rate', |
159 | customRender: (column) => { | 206 | customRender: (column) => { |
160 | const { record } = column || {}; | 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 | title: '利润分析信息', | 217 | title: '利润分析信息', |
171 | width: 150, | 218 | width: 150, |
@@ -177,7 +224,9 @@ const ORDER_LIST_PROFIT_FIELDS = [ | @@ -177,7 +224,9 @@ const ORDER_LIST_PROFIT_FIELDS = [ | ||
177 | dataIndex: 'customerPrice', | 224 | dataIndex: 'customerPrice', |
178 | customRender: (column) => { | 225 | customRender: (column) => { |
179 | const { record } = column || {}; | 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,7 +244,18 @@ const ORDER_LIST_PROFIT_FIELDS = [ | ||
195 | dataIndex: 'productionDepartmentPrice', | 244 | dataIndex: 'productionDepartmentPrice', |
196 | customRender: (column) => { | 245 | customRender: (column) => { |
197 | const { record } = column || {}; | 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,7 +264,9 @@ const ORDER_LIST_PROFIT_FIELDS = [ | ||
204 | dataIndex: 'packetPrice', | 264 | dataIndex: 'packetPrice', |
205 | customRender: (column) => { | 265 | customRender: (column) => { |
206 | const { record } = column || {}; | 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,11 +296,24 @@ const ORDER_LIST_PROFIT_FIELDS = [ | ||
234 | return record?.profitAnalysisInfo?.profitRate; | 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 | title: '跟单信息', | 318 | title: '跟单信息', |
244 | width: 150, | 319 | width: 150, |
@@ -250,7 +325,7 @@ const ORDER_LIST_TRACK_FIELDS = [ | @@ -250,7 +325,7 @@ const ORDER_LIST_TRACK_FIELDS = [ | ||
250 | dataIndex: 'ppTime', | 325 | dataIndex: 'ppTime', |
251 | customRender: (column) => { | 326 | customRender: (column) => { |
252 | const { record } = column || {}; | 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,7 +343,7 @@ const ORDER_LIST_TRACK_FIELDS = [ | ||
268 | dataIndex: 'esoSampleSendTime', | 343 | dataIndex: 'esoSampleSendTime', |
269 | customRender: (column) => { | 344 | customRender: (column) => { |
270 | const { record } = column || {}; | 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,7 +352,7 @@ const ORDER_LIST_TRACK_FIELDS = [ | ||
277 | dataIndex: 'shippmentSampleSendTime', | 352 | dataIndex: 'shippmentSampleSendTime', |
278 | customRender: (column) => { | 353 | customRender: (column) => { |
279 | const { record } = column || {}; | 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,7 +370,7 @@ const ORDER_LIST_TRACK_FIELDS = [ | ||
295 | dataIndex: 'selfTestPassTime', | 370 | dataIndex: 'selfTestPassTime', |
296 | customRender: (column) => { | 371 | customRender: (column) => { |
297 | const { record } = column || {}; | 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,7 +379,7 @@ const ORDER_LIST_TRACK_FIELDS = [ | ||
304 | dataIndex: 'aitexTestSendTime', | 379 | dataIndex: 'aitexTestSendTime', |
305 | customRender: (column) => { | 380 | customRender: (column) => { |
306 | const { record } = column || {}; | 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,7 +397,7 @@ const ORDER_LIST_TRACK_FIELDS = [ | ||
322 | dataIndex: 'sgsTestSendTime', | 397 | dataIndex: 'sgsTestSendTime', |
323 | customRender: (column) => { | 398 | customRender: (column) => { |
324 | const { record } = column || {}; | 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,7 +424,7 @@ const ORDER_LIST_TRACK_FIELDS = [ | ||
349 | dataIndex: 'latestArrivalTime', | 424 | dataIndex: 'latestArrivalTime', |
350 | customRender: (column) => { | 425 | customRender: (column) => { |
351 | const { record } = column || {}; | 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,14 +433,14 @@ const ORDER_LIST_TRACK_FIELDS = [ | ||
358 | dataIndex: 'latestBkTime', | 433 | dataIndex: 'latestBkTime', |
359 | customRender: (column) => { | 434 | customRender: (column) => { |
360 | const { record } = column || {}; | 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 | title: '质检信息', | 445 | title: '质检信息', |
371 | width: 150, | 446 | width: 150, |
@@ -378,7 +453,7 @@ const ORDER_LIST_INSPECT_FIELDS = [ | @@ -378,7 +453,7 @@ const ORDER_LIST_INSPECT_FIELDS = [ | ||
378 | dataIndex: 'midCheckApplyTime', | 453 | dataIndex: 'midCheckApplyTime', |
379 | customRender: (column) => { | 454 | customRender: (column) => { |
380 | const { record } = column || {}; | 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,7 +480,7 @@ const ORDER_LIST_INSPECT_FIELDS = [ | ||
405 | dataIndex: 'endCheckApplyTime', | 480 | dataIndex: 'endCheckApplyTime', |
406 | customRender: (column) => { | 481 | customRender: (column) => { |
407 | const { record } = column || {}; | 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,7 +568,9 @@ const ORDER_LIST_SCHEDULE = [ | ||
493 | }, | 568 | }, |
494 | ]; | 569 | ]; |
495 | 570 | ||
571 | +// 订单列表,也就是读权限 | ||
496 | export function getOrderColumns(role: ROLE) { | 572 | export function getOrderColumns(role: ROLE) { |
573 | + // 管理员/业务员看到所有列 | ||
497 | if (role === ROLE.ADMIN || role === ROLE.BUSINESS) { | 574 | if (role === ROLE.ADMIN || role === ROLE.BUSINESS) { |
498 | return [ | 575 | return [ |
499 | ...ORDER_LIST_BASE_FIELDS, | 576 | ...ORDER_LIST_BASE_FIELDS, |
@@ -504,15 +581,16 @@ export function getOrderColumns(role: ROLE) { | @@ -504,15 +581,16 @@ export function getOrderColumns(role: ROLE) { | ||
504 | ...ORDER_LIST_SCHEDULE, | 581 | ...ORDER_LIST_SCHEDULE, |
505 | ]; | 582 | ]; |
506 | } | 583 | } |
507 | - | 584 | + // 跟单 -基本信息-利润分析(单价,总价),跟单,质检 |
508 | if (role === ROLE.TRACKER) { | 585 | if (role === ROLE.TRACKER) { |
509 | return [ | 586 | return [ |
510 | ...ORDER_LIST_BASE_FIELDS, | 587 | ...ORDER_LIST_BASE_FIELDS, |
511 | ...ORDER_LIST_PROFIT_FIELDS.map((item) => { | 588 | ...ORDER_LIST_PROFIT_FIELDS.map((item) => { |
512 | const children = item.children.filter( | 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 | item.children = children; | 592 | item.children = children; |
593 | + | ||
516 | return item; | 594 | return item; |
517 | }), | 595 | }), |
518 | ...ORDER_LIST_TRACK_FIELDS, | 596 | ...ORDER_LIST_TRACK_FIELDS, |
@@ -521,7 +599,8 @@ export function getOrderColumns(role: ROLE) { | @@ -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 | return [ | 604 | return [ |
526 | ...ORDER_LIST_BASE_FIELDS, | 605 | ...ORDER_LIST_BASE_FIELDS, |
527 | ...ORDER_LIST_TRACK_FIELDS, | 606 | ...ORDER_LIST_TRACK_FIELDS, |
@@ -532,7 +611,9 @@ export function getOrderColumns(role: ROLE) { | @@ -532,7 +611,9 @@ export function getOrderColumns(role: ROLE) { | ||
532 | 611 | ||
533 | return []; | 612 | return []; |
534 | } | 613 | } |
535 | - | 614 | +/** |
615 | + * drawer面板的字段 | ||
616 | + */ | ||
536 | // 基本信息 | 617 | // 基本信息 |
537 | export const FIELDS_BASE_INFO = [ | 618 | export const FIELDS_BASE_INFO = [ |
538 | { | 619 | { |
@@ -670,6 +751,13 @@ export const FIELDS_BASE_INFO = [ | @@ -670,6 +751,13 @@ export const FIELDS_BASE_INFO = [ | ||
670 | label: '包装类型', | 751 | label: '包装类型', |
671 | rules: [{ required: true }], | 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,22 +768,44 @@ export const FIELDS_REPORT_INFO = [ | ||
680 | optionField: 'ideaSource', | 768 | optionField: 'ideaSource', |
681 | labelWidth: 150, | 769 | labelWidth: 150, |
682 | label: '想法来源', | 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 | component: 'Select', | 783 | component: 'Select', |
688 | - optionField: 'manualPreform', | 784 | + optionField: 'manualPreform1', |
689 | labelWidth: 150, | 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 | labelWidth: 150, | 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,7 +946,7 @@ export const FIELDS_PROFIT_INFO = [ | ||
836 | field: 'customerPrice', | 946 | field: 'customerPrice', |
837 | component: 'InputNumber', | 947 | component: 'InputNumber', |
838 | label: '客户单价', | 948 | label: '客户单价', |
839 | - // rules: [{ required: true }], | 949 | + rules: [{ required: true }], |
840 | }, | 950 | }, |
841 | // { | 951 | // { |
842 | // field: 'customerTotalPrice', | 952 | // field: 'customerTotalPrice', |
@@ -848,7 +958,8 @@ export const FIELDS_PROFIT_INFO = [ | @@ -848,7 +958,8 @@ export const FIELDS_PROFIT_INFO = [ | ||
848 | field: 'customerCurrency', | 958 | field: 'customerCurrency', |
849 | component: 'Select', | 959 | component: 'Select', |
850 | label: '客户单价货币单位', | 960 | label: '客户单价货币单位', |
851 | - // rules: [{ required: true }], | 961 | + labelWidth: 400, |
962 | + rules: [{ required: true }], | ||
852 | componentProps: { | 963 | componentProps: { |
853 | options: [ | 964 | options: [ |
854 | { label: '$', value: '$' }, | 965 | { label: '$', value: '$' }, |
@@ -860,13 +971,13 @@ export const FIELDS_PROFIT_INFO = [ | @@ -860,13 +971,13 @@ export const FIELDS_PROFIT_INFO = [ | ||
860 | field: 'productionDepartmentPrice', | 971 | field: 'productionDepartmentPrice', |
861 | component: 'InputNumber', | 972 | component: 'InputNumber', |
862 | label: '生成科单价', | 973 | label: '生成科单价', |
863 | - // rules: [{ required: true }], | 974 | + rules: [{ required: true }], |
864 | }, | 975 | }, |
865 | { | 976 | { |
866 | field: 'productionDepartmentCurrency', | 977 | field: 'productionDepartmentCurrency', |
867 | component: 'Select', | 978 | component: 'Select', |
868 | label: '生成科货币单位', | 979 | label: '生成科货币单位', |
869 | - // rules: [{ required: true }], | 980 | + rules: [{ required: true }], |
870 | componentProps: { | 981 | componentProps: { |
871 | options: [ | 982 | options: [ |
872 | { label: '$', value: '$' }, | 983 | { label: '$', value: '$' }, |
@@ -884,6 +995,14 @@ export const FIELDS_PROFIT_INFO = [ | @@ -884,6 +995,14 @@ export const FIELDS_PROFIT_INFO = [ | ||
884 | label: '包装费用', | 995 | label: '包装费用', |
885 | component: 'InputNumber', | 996 | component: 'InputNumber', |
886 | field: 'packetPrice', | 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 | // rules: [{ required: true }], | 1006 | // rules: [{ required: true }], |
888 | }, | 1007 | }, |
889 | // { | 1008 | // { |
@@ -892,30 +1011,39 @@ export const FIELDS_PROFIT_INFO = [ | @@ -892,30 +1011,39 @@ export const FIELDS_PROFIT_INFO = [ | ||
892 | // field: 'packetTotalPrice', | 1011 | // field: 'packetTotalPrice', |
893 | // rules: [{ required: true }], | 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 | component: 'Select', | 1036 | component: 'Select', |
898 | - field: 'packetCurrency', | ||
899 | - // rules: [{ required: true }], | 1037 | + field: 'profitType', |
900 | componentProps: { | 1038 | componentProps: { |
1039 | + defaultValue: '0', | ||
901 | options: [ | 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 | // rules: [{ required: true }], | 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,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 | component: 'Select', | 1341 | component: 'Select', |
1202 | colProps: { | 1342 | colProps: { |
1203 | span: 6, | 1343 | span: 6, |
1204 | }, | 1344 | }, |
1205 | labelWidth: 150, | 1345 | labelWidth: 150, |
1206 | - | ||
1207 | componentProps: { | 1346 | componentProps: { |
1208 | options: manualPreform, | 1347 | options: manualPreform, |
1209 | }, | 1348 | }, |
src/views/project/order/type.d.ts
1 | export enum ROLE { | 1 | export enum ROLE { |
2 | ADMIN = 'admin', // 超管 | 2 | ADMIN = 'admin', // 超管 |
3 | + CUSTOM_ADMIN = 'custom_admin', // 客户管理员 | ||
4 | + DATA_REPORT_USER = 'data_report_user', //数据分析员 | ||
3 | BUSINESS = 'business_user', // 业务员 | 5 | BUSINESS = 'business_user', // 业务员 |
4 | TRACKER = 'tracker_user', // 跟单员 | 6 | TRACKER = 'tracker_user', // 跟单员 |
5 | INSPECT = 'inspect_user', // 质检员 | 7 | INSPECT = 'inspect_user', // 质检员 |
src/views/sys/login/ForgetPasswordForm.vue
@@ -2,21 +2,49 @@ | @@ -2,21 +2,49 @@ | ||
2 | <template v-if="getShow"> | 2 | <template v-if="getShow"> |
3 | <LoginFormTitle class="enter-x" /> | 3 | <LoginFormTitle class="enter-x" /> |
4 | <Form class="p-4 enter-x" :model="formData" :rules="getFormRules" ref="formRef"> | 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 | <Input | 6 | <Input |
7 | size="large" | 7 | size="large" |
8 | v-model:value="formData.account" | 8 | v-model:value="formData.account" |
9 | :placeholder="t('sys.login.userName')" | 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 | </FormItem> | 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 | </FormItem> | 42 | </FormItem> |
16 | - <FormItem name="sms" class="enter-x"> | 43 | + <FormItem name="smsCaptchaCode" class="enter-x"> |
17 | <CountdownInput | 44 | <CountdownInput |
18 | size="large" | 45 | size="large" |
19 | - v-model:value="formData.sms" | 46 | + v-model:value="formData.smsCaptchaCode" |
47 | + :sendCodeApi="handleSendMsg" | ||
20 | :placeholder="t('sys.login.smsCode')" | 48 | :placeholder="t('sys.login.smsCode')" |
21 | /> | 49 | /> |
22 | </FormItem> | 50 | </FormItem> |
@@ -33,12 +61,14 @@ | @@ -33,12 +61,14 @@ | ||
33 | </template> | 61 | </template> |
34 | </template> | 62 | </template> |
35 | <script lang="ts" setup> | 63 | <script lang="ts" setup> |
36 | - import { reactive, ref, computed, unref } from 'vue'; | 64 | + import { reactive, ref, computed, unref, onMounted } from 'vue'; |
37 | import LoginFormTitle from './LoginFormTitle.vue'; | 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 | import { CountdownInput } from '/@/components/CountDown'; | 67 | import { CountdownInput } from '/@/components/CountDown'; |
40 | import { useI18n } from '/@/hooks/web/useI18n'; | 68 | import { useI18n } from '/@/hooks/web/useI18n'; |
41 | import { useLoginState, useFormRules, LoginStateEnum } from './useLogin'; | 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 | const FormItem = Form.Item; | 73 | const FormItem = Form.Item; |
44 | const { t } = useI18n(); | 74 | const { t } = useI18n(); |
@@ -49,16 +79,56 @@ | @@ -49,16 +79,56 @@ | ||
49 | const loading = ref(false); | 79 | const loading = ref(false); |
50 | 80 | ||
51 | const formData = reactive({ | 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 | const getShow = computed(() => unref(getLoginState) === LoginStateEnum.RESET_PASSWORD); | 123 | const getShow = computed(() => unref(getLoginState) === LoginStateEnum.RESET_PASSWORD); |
58 | 124 | ||
59 | async function handleReset() { | 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 | </script> | 134 | </script> |
src/views/sys/login/LoginForm.vue
@@ -34,13 +34,15 @@ | @@ -34,13 +34,15 @@ | ||
34 | /> | 34 | /> |
35 | </FormItem> | 35 | </FormItem> |
36 | <FormItem name="imgCaptchaCode" class="enter-x" label="验证码"> | 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 | </FormItem> | 41 | </FormItem> |
39 | 42 | ||
40 | - <ARow class="enter-x"> | 43 | + <!-- <ARow class="enter-x"> |
41 | <ACol :span="12"> | 44 | <ACol :span="12"> |
42 | <FormItem> | 45 | <FormItem> |
43 | - <!-- No logic, you need to deal with it yourself --> | ||
44 | <Checkbox v-model:checked="rememberMe" size="small"> | 46 | <Checkbox v-model:checked="rememberMe" size="small"> |
45 | {{ t('sys.login.rememberMe') }} | 47 | {{ t('sys.login.rememberMe') }} |
46 | </Checkbox> | 48 | </Checkbox> |
@@ -48,13 +50,12 @@ | @@ -48,13 +50,12 @@ | ||
48 | </ACol> | 50 | </ACol> |
49 | <ACol :span="12"> | 51 | <ACol :span="12"> |
50 | <FormItem :style="{ 'text-align': 'right' }"> | 52 | <FormItem :style="{ 'text-align': 'right' }"> |
51 | - <!-- No logic, you need to deal with it yourself --> | ||
52 | <Button type="link" size="small" @click="setLoginState(LoginStateEnum.RESET_PASSWORD)"> | 53 | <Button type="link" size="small" @click="setLoginState(LoginStateEnum.RESET_PASSWORD)"> |
53 | {{ t('sys.login.forgetPassword') }} | 54 | {{ t('sys.login.forgetPassword') }} |
54 | </Button> | 55 | </Button> |
55 | </FormItem> | 56 | </FormItem> |
56 | </ACol> | 57 | </ACol> |
57 | - </ARow> | 58 | + </ARow> --> |
58 | 59 | ||
59 | <FormItem class="enter-x"> | 60 | <FormItem class="enter-x"> |
60 | <Button type="primary" size="large" block @click="handleLogin" :loading="loading"> | 61 | <Button type="primary" size="large" block @click="handleLogin" :loading="loading"> |
@@ -64,23 +65,23 @@ | @@ -64,23 +65,23 @@ | ||
64 | {{ t('sys.login.registerButton') }} | 65 | {{ t('sys.login.registerButton') }} |
65 | </Button> --> | 66 | </Button> --> |
66 | </FormItem> | 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 | <Button block @click="setLoginState(LoginStateEnum.MOBILE)"> | 70 | <Button block @click="setLoginState(LoginStateEnum.MOBILE)"> |
70 | {{ t('sys.login.mobileSignInFormTitle') }} | 71 | {{ t('sys.login.mobileSignInFormTitle') }} |
71 | </Button> | 72 | </Button> |
72 | </ACol> --> | 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 | <Button block @click="setLoginState(LoginStateEnum.QR_CODE)"> | 75 | <Button block @click="setLoginState(LoginStateEnum.QR_CODE)"> |
75 | {{ t('sys.login.qrSignInFormTitle') }} | 76 | {{ t('sys.login.qrSignInFormTitle') }} |
76 | </Button> | 77 | </Button> |
77 | </ACol> --> | 78 | </ACol> --> |
78 | - <!-- <ACol :md="6" :xs="24"> | 79 | + <!-- <ACol :md="6" :xs="24"> |
79 | <Button block @click="setLoginState(LoginStateEnum.REGISTER)"> | 80 | <Button block @click="setLoginState(LoginStateEnum.REGISTER)"> |
80 | {{ t('sys.login.registerButton') }} | 81 | {{ t('sys.login.registerButton') }} |
81 | </Button> | 82 | </Button> |
82 | </ACol> --> | 83 | </ACol> --> |
83 | - </ARow> | 84 | + <!-- </ARow> --> |
84 | <!-- | 85 | <!-- |
85 | <Divider class="enter-x">{{ t('sys.login.otherSignIn') }}</Divider> | 86 | <Divider class="enter-x">{{ t('sys.login.otherSignIn') }}</Divider> |
86 | 87 | ||
@@ -133,8 +134,8 @@ | @@ -133,8 +134,8 @@ | ||
133 | const imgCaptchaUuid = ref(''); | 134 | const imgCaptchaUuid = ref(''); |
134 | 135 | ||
135 | const formData = reactive({ | 136 | const formData = reactive({ |
136 | - userName: 'admin', | ||
137 | - password: '123456', | 137 | + userName: '', |
138 | + password: '', | ||
138 | imgCaptchaCode: '', | 139 | imgCaptchaCode: '', |
139 | imgCaptchaUuid: '', | 140 | imgCaptchaUuid: '', |
140 | }); | 141 | }); |
src/views/sys/login/useLogin.ts
@@ -53,6 +53,7 @@ export function useFormRules(formData?: Recordable) { | @@ -53,6 +53,7 @@ export function useFormRules(formData?: Recordable) { | ||
53 | const getPasswordFormRule = computed(() => createRule(t('sys.login.passwordPlaceholder'))); | 53 | const getPasswordFormRule = computed(() => createRule(t('sys.login.passwordPlaceholder'))); |
54 | const getSmsFormRule = computed(() => createRule(t('sys.login.smsPlaceholder'))); | 54 | const getSmsFormRule = computed(() => createRule(t('sys.login.smsPlaceholder'))); |
55 | const getMobileFormRule = computed(() => createRule(t('sys.login.mobilePlaceholder'))); | 55 | const getMobileFormRule = computed(() => createRule(t('sys.login.mobilePlaceholder'))); |
56 | + const getConfirmPasswordFormRule = computed(() => createRule(t('请输入确认密码'))); | ||
56 | 57 | ||
57 | const validatePolicy = async (_: RuleObject, value: boolean) => { | 58 | const validatePolicy = async (_: RuleObject, value: boolean) => { |
58 | return !value ? Promise.reject(t('sys.login.policyPlaceholder')) : Promise.resolve(); | 59 | return !value ? Promise.reject(t('sys.login.policyPlaceholder')) : Promise.resolve(); |
@@ -75,10 +76,11 @@ export function useFormRules(formData?: Recordable) { | @@ -75,10 +76,11 @@ export function useFormRules(formData?: Recordable) { | ||
75 | const passwordFormRule = unref(getPasswordFormRule); | 76 | const passwordFormRule = unref(getPasswordFormRule); |
76 | const smsFormRule = unref(getSmsFormRule); | 77 | const smsFormRule = unref(getSmsFormRule); |
77 | const mobileFormRule = unref(getMobileFormRule); | 78 | const mobileFormRule = unref(getMobileFormRule); |
79 | + const confirmPasswordFormRule = unref(getConfirmPasswordFormRule); | ||
78 | 80 | ||
79 | const mobileRule = { | 81 | const mobileRule = { |
80 | sms: smsFormRule, | 82 | sms: smsFormRule, |
81 | - mobile: mobileFormRule, | 83 | + phone: mobileFormRule, |
82 | }; | 84 | }; |
83 | switch (unref(currentState)) { | 85 | switch (unref(currentState)) { |
84 | // register form rules | 86 | // register form rules |
@@ -97,6 +99,8 @@ export function useFormRules(formData?: Recordable) { | @@ -97,6 +99,8 @@ export function useFormRules(formData?: Recordable) { | ||
97 | case LoginStateEnum.RESET_PASSWORD: | 99 | case LoginStateEnum.RESET_PASSWORD: |
98 | return { | 100 | return { |
99 | userName: accountFormRule, | 101 | userName: accountFormRule, |
102 | + password: passwordFormRule, | ||
103 | + confirmPassword: confirmPasswordFormRule, | ||
100 | ...mobileRule, | 104 | ...mobileRule, |
101 | }; | 105 | }; |
102 | 106 |
vite.config.ts
@@ -20,15 +20,15 @@ export default defineApplicationConfig({ | @@ -20,15 +20,15 @@ export default defineApplicationConfig({ | ||
20 | server: { | 20 | server: { |
21 | proxy: { | 21 | proxy: { |
22 | '/basic-api/order': { | 22 | '/basic-api/order': { |
23 | - target: 'http://39.108.227.113:8010', | 23 | + target: 'http://39.108.227.113:8000', |
24 | // target: 'http://39.108.227.113:3000/mock/35', | 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 | changeOrigin: true, | 26 | changeOrigin: true, |
27 | ws: true, | 27 | ws: true, |
28 | rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''), | 28 | rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''), |
29 | }, | 29 | }, |
30 | '/api/localStorage/upload': { | 30 | '/api/localStorage/upload': { |
31 | - target: 'http://39.108.227.113:8010', | 31 | + target: 'http://39.108.227.113:8000', |
32 | changeOrigin: true, | 32 | changeOrigin: true, |
33 | ws: true, | 33 | ws: true, |
34 | // rewrite: (path) => { | 34 | // rewrite: (path) => { |