Commit 4d629b54ee8411b4c6a68deef6491d732b5e12c9

Authored by boyang
1 parent 56cd3fcb

应收款与应付款前后端联调完成

Showing 38 changed files with 1939 additions and 322 deletions
src/api/project/approve.ts
@@ -30,7 +30,7 @@ export const getWaitListApi = async (params: DemoParams) => { @@ -30,7 +30,7 @@ export const getWaitListApi = async (params: DemoParams) => {
30 res.records = res.records.map((item) => { 30 res.records = res.records.map((item) => {
31 return item; 31 return item;
32 }); 32 });
33 - 33 + console.log(res.records, 5656565656);
34 return new Promise((resolve) => { 34 return new Promise((resolve) => {
35 resolve({ items: res.records, total: res.total }); 35 resolve({ items: res.records, total: res.total });
36 }); 36 });
src/api/project/invoice.ts
@@ -11,9 +11,21 @@ enum Api { @@ -11,9 +11,21 @@ enum Api {
11 UPDATE_AMOUNT = '/order/erp/invoice_bill/update_amount_info', //更新其他金额信息 11 UPDATE_AMOUNT = '/order/erp/invoice_bill/update_amount_info', //更新其他金额信息
12 INVOICE_DELETE = '/order/erp/invoice_bill/delete_by_id', //删除数据 12 INVOICE_DELETE = '/order/erp/invoice_bill/delete_by_id', //删除数据
13 COMMIT = '/order/erp/invoice_bill/commit_apply', //提交审核 13 COMMIT = '/order/erp/invoice_bill/commit_apply', //提交审核
  14 +
  15 + PRODUCT_CREATE = '/order/erp/check_bill/create', //创建生产科应付单据
  16 + PAYED_DATE = '/order/erp/check_bill/get_payed_date', //获取生产科应回款日期
  17 + UPDATE_DEDUCT_INFO = '/order/erp/check_bill/update_deduct_info', //更新扣款信息
  18 + UPDATE_AMOUNT_INFO = '/order/erp/check_bill/update_amount_info', //更新其他金额信息
  19 + UPDATE_INVOICE_INFO = '/order/erp/check_bill/update_invoice_info', //更新发票信息
  20 + CHECK_COMMIT = '/order/erp/check_bill/commit_apply', //提交审核
  21 + CHECK_DELETE = '/order/erp/check_bill/delete_by_id', //删除数据
  22 + CHECK_BILL = '/order/erp/check_bill/list_by_page', //分页查询列表
  23 + CHECK_DETAIL = '/order/erp/check_bill/list_base_order_info_by', //基础订单查询
  24 + CHECK_ANALYSIS = '/order/erp/check_bill/list_analysis_by', //分析列表
  25 + EXPORT_CHECK_ANALYSIS = '/order/erp/check_bill/export', //导出分析列表
14 } 26 }
15 27
16 -export const getRefundDate = async (params: any) => { 28 +export const getRefundDate = async (params: any, data?: any) => {
17 const res = await defHttp.post<any>({ 29 const res = await defHttp.post<any>({
18 url: Api.REFUND_DATE, 30 url: Api.REFUND_DATE,
19 params, 31 params,
@@ -33,7 +45,6 @@ export const getInvoice = async (params: any) =&gt; { @@ -33,7 +45,6 @@ export const getInvoice = async (params: any) =&gt; {
33 url: Api.INVOICE, 45 url: Api.INVOICE,
34 params, 46 params,
35 }); 47 });
36 - console.log(res, 5656);  
37 return res.records; 48 return res.records;
38 }; 49 };
39 export const getBaseInvoice = async (params: any) => { 50 export const getBaseInvoice = async (params: any) => {
@@ -55,13 +66,15 @@ export const exportAnalysis = async (params: any) =&gt; { @@ -55,13 +66,15 @@ export const exportAnalysis = async (params: any) =&gt; {
55 params, 66 params,
56 }); 67 });
57 }; 68 };
  69 +
58 export const updateDeduct = async (params: any) => { 70 export const updateDeduct = async (params: any) => {
59 return await defHttp.post<any>({ 71 return await defHttp.post<any>({
60 url: Api.UPDATE_DEDUCT, 72 url: Api.UPDATE_DEDUCT,
61 params, 73 params,
62 }); 74 });
63 }; 75 };
64 -export const updateAmount = async (params: any, p0?: { id: any; bgUrl: any }) => { 76 +// export const updateAmount = async (params: any, p0?: { id: any; bgUrl: any }) => {
  77 +export const updateAmount = async (params: any) => {
65 return await defHttp.post<any>({ 78 return await defHttp.post<any>({
66 url: Api.UPDATE_AMOUNT, 79 url: Api.UPDATE_AMOUNT,
67 params, 80 params,
@@ -79,3 +92,72 @@ export const commit = async (params: any) =&gt; { @@ -79,3 +92,72 @@ export const commit = async (params: any) =&gt; {
79 params, 92 params,
80 }); 93 });
81 }; 94 };
  95 +
  96 +export const checkCreate = async (params: any) => {
  97 + return await defHttp.post<any>({
  98 + url: Api.PRODUCT_CREATE,
  99 + params,
  100 + });
  101 +};
  102 +export const payDate = async (params: any) => {
  103 + return await defHttp.post<any>({
  104 + url: Api.PAYED_DATE,
  105 + params,
  106 + });
  107 +};
  108 +export const updateDeductInfo = async (params: any) => {
  109 + return await defHttp.post<any>({
  110 + url: Api.UPDATE_DEDUCT_INFO,
  111 + params,
  112 + });
  113 +};
  114 +export const updateAmountInfo = async (params: any) => {
  115 + return await defHttp.post<any>({
  116 + url: Api.UPDATE_AMOUNT_INFO,
  117 + params,
  118 + });
  119 +};
  120 +export const checkCommit = async (params: any) => {
  121 + return await defHttp.post<any>({
  122 + url: Api.CHECK_COMMIT,
  123 + params,
  124 + });
  125 +};
  126 +export const checkDelete = async (params: any, id?: string[]) => {
  127 + return await defHttp.post<any>({
  128 + url: Api.CHECK_DELETE,
  129 + params,
  130 + });
  131 +};
  132 +export const getCheck = async (params: any) => {
  133 + const res = await defHttp.post<any>({
  134 + url: Api.CHECK_BILL,
  135 + params,
  136 + });
  137 + console.log(res, '5656check');
  138 + return res.records;
  139 +};
  140 +export const checkDetail = async (params: any) => {
  141 + return await defHttp.post<any>({
  142 + url: Api.CHECK_DETAIL,
  143 + params,
  144 + });
  145 +};
  146 +export const checkAnalysis = async (params: any) => {
  147 + return await defHttp.post<any>({
  148 + url: Api.CHECK_ANALYSIS,
  149 + params,
  150 + });
  151 +};
  152 +export const updateInvoiceInfo = async (params: any) => {
  153 + return await defHttp.post<any>({
  154 + url: Api.UPDATE_INVOICE_INFO,
  155 + params,
  156 + });
  157 +};
  158 +export const exportCheckAnalysis = async (params: any) => {
  159 + return await defHttp.post<any>({
  160 + url: Api.EXPORT_CHECK_ANALYSIS,
  161 + params,
  162 + });
  163 +};
src/api/project/order.ts
@@ -33,6 +33,7 @@ enum Api { @@ -33,6 +33,7 @@ enum Api {
33 ORDER_FIELD_CHECK = '/order/erp/order/check', // 校验内部编号是否重复 33 ORDER_FIELD_CHECK = '/order/erp/order/check', // 校验内部编号是否重复
34 34
35 TRACK_HISTORY = '/order/erp/opinion/log/query_by_id', //跟单结果记录 35 TRACK_HISTORY = '/order/erp/opinion/log/query_by_id', //跟单结果记录
  36 + PASS_CALCULATE = '/order/erp/order/passRate', //一次性通过率
36 } 37 }
37 38
38 export const formatSearchData = (params) => { 39 export const formatSearchData = (params) => {
@@ -187,6 +188,7 @@ export const orderExport = async (data: any = {}) =&gt; { @@ -187,6 +188,7 @@ export const orderExport = async (data: any = {}) =&gt; {
187 a.download = `${strArr.join('_')} ${date}.xlsx`; // 你可以为文件命名 188 a.download = `${strArr.join('_')} ${date}.xlsx`; // 你可以为文件命名
188 document.body.appendChild(a); 189 document.body.appendChild(a);
189 a.click(); // 模拟点击操作来下载文件 190 a.click(); // 模拟点击操作来下载文件
  191 + console.log(a, '5656a');
190 URL.revokeObjectURL(downloadUrl); // 释放掉 blob 对象所占用的内存 192 URL.revokeObjectURL(downloadUrl); // 释放掉 blob 对象所占用的内存
191 document.body.removeChild(a); 193 document.body.removeChild(a);
192 194
@@ -305,3 +307,11 @@ export const trackHistory = async (data: any) =&gt; { @@ -305,3 +307,11 @@ export const trackHistory = async (data: any) =&gt; {
305 }); 307 });
306 return res; 308 return res;
307 }; 309 };
  310 +
  311 +export const passCalculate = async (data: any) => {
  312 + const res = await defHttp.post<any>({
  313 + url: Api.PASS_CALCULATE,
  314 + data: data,
  315 + });
  316 + return res;
  317 +};
src/api/sys/config.ts
@@ -91,6 +91,12 @@ export const getEmailList = async (params: any) =&gt; { @@ -91,6 +91,12 @@ export const getEmailList = async (params: any) =&gt; {
91 params, 91 params,
92 }); 92 });
93 const resAll = dealRecords(res.records); 93 const resAll = dealRecords(res.records);
  94 + resAll.sort((a, b) => {
  95 + if (a.enableFlag === b.enableFlag) {
  96 + return 0;
  97 + }
  98 + return a.enableFlag === 10 ? -1 : 1;
  99 + });
94 return resAll; 100 return resAll;
95 }; 101 };
96 102
src/components/Modal/src/hooks/useModal.ts
@@ -100,7 +100,7 @@ export function useModal(): UseModalReturnType { @@ -100,7 +100,7 @@ export function useModal(): UseModalReturnType {
100 return [register, methods]; 100 return [register, methods];
101 } 101 }
102 102
103 -export const useModalInner = (callbackFn?: Fn): UseModalInnerReturnType => { 103 +export const useModalInner = (callbackFn?: Fn, p0?: () => Promise<void>): UseModalInnerReturnType => {
104 const modalInstanceRef = ref<Nullable<ModalMethods>>(null); 104 const modalInstanceRef = ref<Nullable<ModalMethods>>(null);
105 const currentInstance = getCurrentInstance(); 105 const currentInstance = getCurrentInstance();
106 const uidRef = ref<string>(''); 106 const uidRef = ref<string>('');
src/router/routes/modules/project/approve.ts
1 import type { AppRouteModule } from '/@/router/types'; 1 import type { AppRouteModule } from '/@/router/types';
2 2
3 import { LAYOUT } from '/@/router/constant'; 3 import { LAYOUT } from '/@/router/constant';
  4 +import { RoleEnum } from '/@/enums/roleEnum';
4 5
5 const order: AppRouteModule = { 6 const order: AppRouteModule = {
6 path: '/approve', 7 path: '/approve',
@@ -10,7 +11,7 @@ const order: AppRouteModule = { @@ -10,7 +11,7 @@ const order: AppRouteModule = {
10 meta: { 11 meta: {
11 hideChildrenInMenu: true, 12 hideChildrenInMenu: true,
12 orderNo: 3, 13 orderNo: 3,
13 - // icon: 'ion:grid-outline', 14 + icon: 'ion:grid-outline',
14 title: '审批管理', 15 title: '审批管理',
15 }, 16 },
16 children: [ 17 children: [
src/views/project/approve/ReceivePanel.vue 0 → 100644
  1 +<template>
  2 + <BasicTable @register="registerTable" className="p-0">
  3 + <template #form-custom> custom-slot </template>
  4 + <template #bodyCell="{ column, record }">
  5 + <template v-if="column.key === 'picUrl'">
  6 + <img
  7 + :width="50"
  8 + :height="50"
  9 + :src="record?.orderBaseInfo?.smallPicUrl"
  10 + @click="handlePreview(record?.orderBaseInfo?.picUrl)"
  11 + />
  12 + </template>
  13 + <template v-if="column.key === 'action'">
  14 + <TableAction
  15 + :actions="[
  16 + {
  17 + label: '编辑',
  18 + // icon: 'ic:outline-delete-outline',
  19 + onClick: handleDetail.bind(null, record),
  20 + },
  21 + ]"
  22 + />
  23 + </template>
  24 + </template>
  25 + </BasicTable>
  26 + <BasicDrawer
  27 + :showFooter="!isApproved && role === ROLE.ADMIN"
  28 + @register="registerDrawer"
  29 + title="申请信息"
  30 + okText="通过"
  31 + @ok="handleTrue"
  32 + >
  33 + <BaseInfo :baseInfos="baseInfos" />
  34 + <h2>收款单信息</h2>
  35 + <div v-for="field in fieldInfos" :key="field">
  36 + <span className="w-[140px] inline-block text-right mr-3">{{ field.label }}:</span
  37 + ><span>{{ field.value }}</span>
  38 + </div>
  39 + <template #appendFooter>
  40 + <a-button @click="handleFalse"> 不通过</a-button>
  41 + </template>
  42 + </BasicDrawer>
  43 + <MsgModal v-if="msgVisible" @msg-modal-close="handleMsgModalClose" />
  44 +</template>
  45 +<script lang="ts">
  46 + import MsgModal from './MsgModal.vue';
  47 + import { computed, defineComponent, ref } from 'vue';
  48 + import { BasicTable, useTable, TableAction } from '/@/components/Table';
  49 + import { BasicDrawer, useDrawer } from '/@/components/Drawer';
  50 +
  51 + import { approveAuditApi, getApprovedListApi, getWaitListApi } from '/@/api/project/approve';
  52 + import { FIELDS_BASE_INFO, FIELDS_PROFIT_INFO, FIELDS_REPORT_INFO } from '../order/tableData';
  53 + import { ROLE } from '../order//type.d';
  54 + import { useUserStoreWithOut } from '/@/store/modules/user';
  55 + import BaseInfo from './BaseInfo.vue';
  56 + import { createImgPreview } from '/@/components/Preview';
  57 + import { getFormConfig } from './data';
  58 +
  59 + const userStore = useUserStoreWithOut();
  60 +
  61 + export default defineComponent({
  62 + components: {
  63 + BasicTable,
  64 + BasicDrawer,
  65 + TableAction,
  66 + BaseInfo,
  67 + MsgModal,
  68 + },
  69 + props: {
  70 + isApproved: { type: Boolean },
  71 + },
  72 + setup(props) {
  73 + // visible 用于msgModal显示隐藏
  74 + const msgVisible = ref(false);
  75 + const checkedKeys = ref<Array<string | number>>([]);
  76 + const currentKey = ref('1');
  77 + const [registerDrawer, { openDrawer, closeDrawer }] = useDrawer();
  78 + const fieldInfos = ref({});
  79 + const baseInfos = ref({});
  80 + const id = ref('');
  81 +
  82 + let columns = [
  83 + {
  84 + title: '申请人',
  85 + dataIndex: 'createBy',
  86 + width: 150,
  87 + },
  88 + {
  89 + title: 'INVOICE编号',
  90 + dataIndex: 'invoiceNo',
  91 + width: 150,
  92 + customRender: (column) => {
  93 + const { record } = column || {};
  94 + return record?.fieldInfos?.invoiceBillOrderDO?.invoiceNo;
  95 + },
  96 + },
  97 + // {
  98 + // title: '内部编号',
  99 + // dataIndex: 'innerNo',
  100 + // width: 150,
  101 + // customRender: (column) => {
  102 + // const { record } = column || {};
  103 + // return record?.fieldInfos?.invoiceBillOrderDO?.innerNo;
  104 + // },
  105 + // },
  106 + ];
  107 +
  108 + if (props.isApproved) {
  109 + columns = columns.concat([
  110 + {
  111 + title: '状态',
  112 + dataIndex: 'status',
  113 + width: 150,
  114 + customRender: (column) => {
  115 + const { record } = column || {};
  116 +
  117 + return record.status === 10 ? '通过' : '拒绝';
  118 + },
  119 + },
  120 + { title: '拒绝原因', dataIndex: 'refuseRemark', width: 250 },
  121 + ]);
  122 + }
  123 +
  124 + const [registerTable, { reload }] = useTable({
  125 + api: props.isApproved ? getApprovedListApi : getWaitListApi,
  126 + searchInfo: { type: 30 },
  127 + // scroll: {
  128 + // scrollToFirstRowOnChange: true,
  129 + // },
  130 + columns,
  131 + useSearchForm: true,
  132 + formConfig: getFormConfig(),
  133 + rowKey: 'id',
  134 + actionColumn: {
  135 + width: 160,
  136 + title: 'Action',
  137 + dataIndex: 'action',
  138 + // slots: { customRender: 'action' },
  139 + },
  140 + });
  141 +
  142 + function onSelect(record, selected) {
  143 + if (selected) {
  144 + checkedKeys.value = [...checkedKeys.value, record.id];
  145 + } else {
  146 + checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id);
  147 + }
  148 + }
  149 + function onSelectAll(selected, selectedRows, changeRows) {
  150 + const changeIds = changeRows.map((item) => item.id);
  151 + if (selected) {
  152 + checkedKeys.value = [...checkedKeys.value, ...changeIds];
  153 + } else {
  154 + checkedKeys.value = checkedKeys.value.filter((id) => {
  155 + return !changeIds.includes(id);
  156 + });
  157 + }
  158 + }
  159 + function handleEdit(record, e) {
  160 + e?.stopPropagation();
  161 + return false;
  162 + }
  163 +
  164 + function handleProfitModal() {}
  165 +
  166 + async function handleDetail(data) {}
  167 +
  168 + async function handleTrue() {
  169 + await approveAuditApi({ status: 10, id: id.value });
  170 + reload();
  171 + closeDrawer();
  172 + }
  173 +
  174 + async function handleFalse() {
  175 + msgVisible.value = true;
  176 + // await approveAuditApi({ status: 20, id: id.value });
  177 + // reload();
  178 + // closeDrawer();
  179 + }
  180 +
  181 + const role = computed(() => {
  182 + return userStore.getUserInfo?.roleSmallVO?.code;
  183 + });
  184 +
  185 + // 定义MsgModalClose的事件,方便子组件调用
  186 + const handleMsgModalClose = async (data) => {
  187 + if (data) {
  188 + await approveAuditApi({ status: 20, id: id.value, refuseRemark: data });
  189 + reload();
  190 + closeDrawer();
  191 + }
  192 + msgVisible.value = false;
  193 + };
  194 +
  195 + const handlePreview = (url) => {
  196 + createImgPreview({ imageList: [url], defaultWidth: 500 });
  197 + return false;
  198 + };
  199 +
  200 + return {
  201 + handleProfitModal,
  202 + registerTable,
  203 + checkedKeys,
  204 + currentKey,
  205 + onSelect,
  206 + handleEdit,
  207 + onSelectAll,
  208 + handleDetail,
  209 + registerDrawer,
  210 + fieldInfos,
  211 + baseInfos,
  212 + handleTrue,
  213 + handleFalse,
  214 + role,
  215 + ROLE,
  216 + msgVisible,
  217 + handleMsgModalClose,
  218 + handlePreview,
  219 + };
  220 + },
  221 + });
  222 +</script>
src/views/project/approve/index.vue
@@ -10,6 +10,9 @@ @@ -10,6 +10,9 @@
10 <a-tab-pane key="5" tab="项目报告书待审核"> 10 <a-tab-pane key="5" tab="项目报告书待审核">
11 <ReportPanel /> 11 <ReportPanel />
12 </a-tab-pane> 12 </a-tab-pane>
  13 + <a-tab-pane key="7" tab="应收款待审核">
  14 + <ReceivePanel />
  15 + </a-tab-pane>
13 <a-tab-pane key="2" tab="字段已审核"> 16 <a-tab-pane key="2" tab="字段已审核">
14 <FieldPanel isApproved /> 17 <FieldPanel isApproved />
15 </a-tab-pane> 18 </a-tab-pane>
@@ -19,6 +22,9 @@ @@ -19,6 +22,9 @@
19 <a-tab-pane key="6" tab="项目报告书已审核"> 22 <a-tab-pane key="6" tab="项目报告书已审核">
20 <ReportPanel isApproved /> 23 <ReportPanel isApproved />
21 </a-tab-pane> 24 </a-tab-pane>
  25 + <a-tab-pane key="8" tab="应收款已审核">
  26 + <ReceivePanel isApproved />
  27 + </a-tab-pane>
22 </a-tabs> 28 </a-tabs>
23 </div> 29 </div>
24 </template> 30 </template>
@@ -28,6 +34,7 @@ @@ -28,6 +34,7 @@
28 import ReportPanel from './ReportPanel.vue'; 34 import ReportPanel from './ReportPanel.vue';
29 import ProfitPanel from './ProfitPanel.vue'; 35 import ProfitPanel from './ProfitPanel.vue';
30 import FieldPanel from './FieldPanel.vue'; 36 import FieldPanel from './FieldPanel.vue';
  37 + import ReceivePanel from './ReceivePanel.vue';
31 import { useOrderStoreWithOut } from '/@/store/modules/order'; 38 import { useOrderStoreWithOut } from '/@/store/modules/order';
32 39
33 const orderStore = useOrderStoreWithOut(); 40 const orderStore = useOrderStoreWithOut();
@@ -39,6 +46,7 @@ @@ -39,6 +46,7 @@
39 ReportPanel, 46 ReportPanel,
40 FieldPanel, 47 FieldPanel,
41 ProfitPanel, 48 ProfitPanel,
  49 + ReceivePanel,
42 }, 50 },
43 setup() { 51 setup() {
44 const checkedKeys = ref<Array<string | number>>([]); 52 const checkedKeys = ref<Array<string | number>>([]);
src/views/project/config/CreateModal.vue
@@ -58,7 +58,7 @@ @@ -58,7 +58,7 @@
58 { 58 {
59 field: 'relationValue', 59 field: 'relationValue',
60 component: 'InputNumber', 60 component: 'InputNumber',
61 - label: props.column === 1 ? '利润率' : '包装费用', 61 + label: props.column === 1 ? '利润率' : props.column === 5 ? '回款时间' : '包装费用',
62 rules: [{ required: true }], 62 rules: [{ required: true }],
63 colProps: { 63 colProps: {
64 span: 24, 64 span: 24,
@@ -96,7 +96,14 @@ @@ -96,7 +96,14 @@
96 settingName: '客户编码', 96 settingName: '客户编码',
97 settingValue: values.settingValue, 97 settingValue: values.settingValue,
98 settingType: 1, 98 settingType: 1,
99 - relationCode: props.column === 1 ? 'profitRate' : 'packetPrice', 99 + // relationCode: props.column === 1 ? 'profitRate' : 'packetPrice',
  100 + relationCode:
  101 + props.column === 1
  102 + ? 'profitRate'
  103 + : props.column === 5
  104 + ? 'orderHodTime'
  105 + : 'packetPrice',
  106 +
100 relationName: '包装费用', 107 relationName: '包装费用',
101 relationValue: values.relationValue, 108 relationValue: values.relationValue,
102 }; 109 };
src/views/project/config/DrawerEdit.vue
@@ -50,7 +50,7 @@ @@ -50,7 +50,7 @@
50 colProps: { 50 colProps: {
51 span: 23, 51 span: 23,
52 }, 52 },
53 - label: '确认样品确认状态(填写邮箱)', 53 + label: '确认样品确认状态(填写邮箱,请用逗号隔开)',
54 rules: [{ required: true }], 54 rules: [{ required: true }],
55 }, 55 },
56 { 56 {
src/views/project/config/EmailPanel.vue
1 <template> 1 <template>
2 - <div class="p-4"> 2 + <div :style="{ marginLeft: '0px' }">
3 <BasicTable @register="registerTable"> 3 <BasicTable @register="registerTable">
4 <template #toolbar> 4 <template #toolbar>
5 <!-- <a-button type="primary" class="my-4" @click="handleCreate"> 新增 </a-button> --> 5 <!-- <a-button type="primary" class="my-4" @click="handleCreate"> 新增 </a-button> -->
src/views/project/config/TablePanel.vue
1 <template> 1 <template>
2 - <BasicTable @register="registerTable"> 2 + <BasicTable @register="registerTable" :bordered="true">
3 <template #toolbar> 3 <template #toolbar>
4 <a-button v-if="props.column !== 3" type="primary" @click="handleCreateModal">新建</a-button> 4 <a-button v-if="props.column !== 3" type="primary" @click="handleCreateModal">新建</a-button>
5 </template> 5 </template>
src/views/project/config/data.tsx
@@ -45,6 +45,20 @@ export const COLUMNS = { @@ -45,6 +45,20 @@ export const COLUMNS = {
45 editRow: true, 45 editRow: true,
46 }, 46 },
47 ], 47 ],
  48 + 5: [
  49 + {
  50 + title: '客户编码',
  51 + dataIndex: 'settingValue',
  52 + width: 150,
  53 + },
  54 + {
  55 + title: '最后汇款日期',
  56 + dataIndex: 'relationValue',
  57 + width: 150,
  58 + editComponent: 'InputNumber',
  59 + editRow: true,
  60 + },
  61 + ],
48 }; 62 };
49 63
50 export const columns: BasicColumn[] = [ 64 export const columns: BasicColumn[] = [
@@ -56,7 +70,7 @@ export const columns: BasicColumn[] = [ @@ -56,7 +70,7 @@ export const columns: BasicColumn[] = [
56 { 70 {
57 title: '状态', 71 title: '状态',
58 dataIndex: 'enableFlag', 72 dataIndex: 'enableFlag',
59 - width: 70, 73 + width: 100,
60 customRender: (column) => { 74 customRender: (column) => {
61 const { record } = column || {}; 75 const { record } = column || {};
62 return record.enableFlag === 10 ? <Tag color="green">启用</Tag> : <Tag color="red">禁用</Tag>; 76 return record.enableFlag === 10 ? <Tag color="green">启用</Tag> : <Tag color="red">禁用</Tag>;
src/views/project/config/index.vue
1 <template> 1 <template>
2 <PageWrapper contentBackground> 2 <PageWrapper contentBackground>
3 <div className="config-page"> 3 <div className="config-page">
4 - <Tabs v-model:selectedKey="currentKey" className="ml-2 mb-0"> 4 + <Tabs
  5 + v-model:selectedKey="currentKey"
  6 + className="ml-2 mb-0"
  7 + :style="{ marginLeft: '30px', marginRight: '5px' }"
  8 + >
5 <Tabs.TabPane key="1" tab="利润率配置"> 9 <Tabs.TabPane key="1" tab="利润率配置">
6 <TablePanel :searchInfo="{ relationCode: 'profitRate' }" :column="1" /> 10 <TablePanel :searchInfo="{ relationCode: 'profitRate' }" :column="1" />
7 </Tabs.TabPane> 11 </Tabs.TabPane>
@@ -12,6 +16,9 @@ @@ -12,6 +16,9 @@
12 <TablePanel :searchInfo="{ settingCode: 'exchangeRate' }" :column="3" 16 <TablePanel :searchInfo="{ settingCode: 'exchangeRate' }" :column="3"
13 /></Tabs.TabPane> 17 /></Tabs.TabPane>
14 <Tabs.TabPane key="4" tab="邮件发送配置"><EmailPanel /></Tabs.TabPane> 18 <Tabs.TabPane key="4" tab="邮件发送配置"><EmailPanel /></Tabs.TabPane>
  19 + <Tabs.TabPane key="5" tab="最后汇款日期">
  20 + <TablePanel :searchInfo="{ relationCode: 'orderHodTime' }" :column="5" />
  21 + </Tabs.TabPane>
15 </Tabs> 22 </Tabs>
16 </div> 23 </div>
17 </PageWrapper> 24 </PageWrapper>
src/views/project/finance/pay/CheckDetail.vue 0 → 100644
  1 +<template>
  2 + <template>
  3 + <BasicDrawer
  4 + @register="register"
  5 + v-bind="$attrs"
  6 + title="订单信息"
  7 + width="60%"
  8 + :isDetail="true"
  9 + :showDetailBack="false"
  10 + :destroyOnClose="true"
  11 + >
  12 + <div class="p-4">
  13 + <BasicTable @register="registerTable">
  14 + <template #bodyCell="{ column, record }">
  15 + <template v-if="column.key === 'action'"> </template>
  16 + <template v-if="column.key === 'picUrl'">
  17 + <img :z-index="100000" :width="50" :height="50" :src="record?.smallPicUrl" />
  18 + </template>
  19 + </template>
  20 + </BasicTable>
  21 + </div>
  22 + </BasicDrawer>
  23 + </template>
  24 +</template>
  25 +<script lang="ts" setup>
  26 + import { BasicDrawer, useDrawerInner } from '@/components/Drawer';
  27 + import { defineComponent, ref, computed, unref, toRaw, reactive } from 'vue';
  28 + import { BasicColumn, useTable, BasicTable, ColumnChangeParam } from '/@/components/Table';
  29 + import { checkDetail } from '/@/api/project/invoice';
  30 + import { useDesign } from '@/hooks/web/useDesign';
  31 +
  32 + // const handlePreview = (url) => {
  33 + // createImgPreview({ imageList: [url], defaultWidth: 500 });
  34 + // return false;
  35 + // };
  36 + const columns: BasicColumn[] = [
  37 + {
  38 + title: '客户编码',
  39 + dataIndex: 'customerCode',
  40 + width: 100,
  41 + },
  42 + {
  43 + title: '项目号',
  44 + dataIndex: 'projectNo',
  45 + width: 100,
  46 + },
  47 + {
  48 + title: '内部编码',
  49 + dataIndex: 'innerNo',
  50 + width: 100,
  51 + },
  52 + {
  53 + title: '客户po号',
  54 + dataIndex: 'customerPo',
  55 + width: 100,
  56 + },
  57 + {
  58 + title: '客户STYLE',
  59 + width: 150,
  60 + dataIndex: 'customerStyle',
  61 + },
  62 + {
  63 + title: 'Model(REFERENCE)',
  64 + width: 150,
  65 + dataIndex: 'modeleLo',
  66 + },
  67 + {
  68 + title: '订单图片',
  69 + width: 150,
  70 + dataIndex: 'picUrl',
  71 + },
  72 + {
  73 + title: '数量',
  74 + width: 150,
  75 + dataIndex: 'orderCount',
  76 + },
  77 + {
  78 + title: '生产科单价¥',
  79 + width: 150,
  80 + dataIndex: 'productionDepartmentPrice',
  81 + customRender: (column) => {
  82 + const { record } = column || {};
  83 + return record?.profitAnalysisInfo?.productionDepartmentPrice;
  84 + // ? `¥ ${record?.profitAnalysisInfo?.productionDepartmentPrice}`
  85 + // : '';
  86 + },
  87 + },
  88 + {
  89 + title: '生产科总价¥',
  90 + width: 150,
  91 + dataIndex: 'productionDepartmentTotalPrice',
  92 + customRender: (column) => {
  93 + const { record } = column || {};
  94 + return record?.profitAnalysisInfo?.productionDepartmentTotalPrice;
  95 + // ? `¥ ${record?.profitAnalysisInfo?.productionDepartmentTotalPrice}`
  96 + // : '';
  97 + },
  98 + },
  99 + ];
  100 + const checkNo = ref();
  101 +
  102 + const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => {
  103 + // 方式1
  104 + checkNo.value = data.data.checkNo;
  105 + console.log(data, '56562vvsdfv');
  106 + // checkDetail({ checkNo: checkNo.value });
  107 + });
  108 + const params = ref({
  109 + checkNo: checkNo.value,
  110 + });
  111 + const [registerTable] = useTable({
  112 + api: () => {
  113 + const res = checkDetail({ checkNo: checkNo.value });
  114 + console.log(res, 56565555);
  115 + return res;
  116 + },
  117 + columns: columns,
  118 + bordered: true,
  119 + });
  120 +</script>
src/views/project/finance/pay/CheckSum.vue 0 → 100644
  1 +<template>
  2 + <BasicModal
  3 + v-bind="$attrs"
  4 + @register="register"
  5 + title="收款单汇总"
  6 + width="80%"
  7 + :isDetail="true"
  8 + :showDetailBack="false"
  9 + @ok="handleOk"
  10 + @visible-change="handleShow"
  11 + >
  12 + <div class="p-4">
  13 + <BasicTable @register="registerTable">
  14 + <template #bodyCell="{ column, record }">
  15 + <template v-if="column.key === 'action'"> </template>
  16 + </template>
  17 + </BasicTable>
  18 + </div>
  19 + </BasicModal>
  20 +</template>
  21 +<script lang="ts" setup>
  22 + import { BasicModal, useModalInner } from '@/components/Modal';
  23 + import { computed, ref } from 'vue';
  24 + import { checkAnalysis, exportCheckAnalysis } from '@/api/project/invoice';
  25 + import { BasicColumn, useTable, BasicTable, ColumnChangeParam } from '/@/components/Table';
  26 + // 处理弹窗的确定按钮点击事件
  27 + import axios from 'axios';
  28 +
  29 + const columnsAnalysis: BasicColumn[] = [
  30 + {
  31 + title: '生产科名称',
  32 + dataIndex: 'productionDepartment',
  33 + width: 50,
  34 + customRender: (res) => {
  35 + // console.log(res, 56562);
  36 + return res.record.exportVOS[0].productionDepartment;
  37 + },
  38 + },
  39 + {
  40 + title: '生产科总价汇总',
  41 + dataIndex: 'productionDepartmentTotalPrice',
  42 + width: 50,
  43 + },
  44 + {
  45 + title: '生产科扣款金额汇总',
  46 + dataIndex: 'actualReceivableAmount',
  47 + width: 50,
  48 + },
  49 + {
  50 + title: '生产科实际应付金额',
  51 + dataIndex: 'calculateActualPayedAmount',
  52 + width: 50,
  53 + },
  54 + {
  55 + title: '实际付款金额汇总',
  56 + dataIndex: 'actualPayedAmount',
  57 + width: 50,
  58 + },
  59 + {
  60 + title: '未付金额',
  61 + dataIndex: 'unPayedAmount',
  62 + width: 50,
  63 + },
  64 + ];
  65 + // const ids = ref<number[]>([]);
  66 + const ids = ref();
  67 + // const res = ref();
  68 +
  69 + const [register, { closeModal }] = useModalInner(async (data) => {
  70 + ids.value = data.data;
  71 + setTimeout(() => {
  72 + reload();
  73 + }, 50);
  74 + });
  75 + const [registerTable, { reload }] = useTable({
  76 + // api: () => invoiceAnalysis({ ids: ids.value }),
  77 + api: async () => {
  78 + const res = await checkAnalysis({ ids: ids.value });
  79 + const arrayRes = ref([]);
  80 + arrayRes.value.push(res);
  81 + console.log(res, 56561);
  82 + return arrayRes.value;
  83 + },
  84 + columns: columnsAnalysis,
  85 + bordered: true,
  86 + });
  87 + function handleShow(visible: boolean) {
  88 + reload();
  89 + }
  90 + const searchData = ref({});
  91 + async function handleOk() {
  92 + // 构造符合 API 要求的参数
  93 + // const ids = [23];
  94 + // const requestData = {
  95 + // ids: ids.value,
  96 + // };
  97 + const idss = ids.value;
  98 + // await exportCheckAnalysis({ ids: ids });
  99 + axios
  100 + .post(
  101 + '/basic-api/order/erp/check_bill/export',
  102 + { ids: idss },
  103 + {
  104 + responseType: 'blob', // 设置响应类型为 'blob'
  105 + },
  106 + )
  107 + .then((response) => {
  108 + // 创建一个 Blob 对象来保存二进制数据
  109 + const blob = new Blob([response.data], { type: 'application/zip' });
  110 + const getFormattedDate = (): string => {
  111 + const date = new Date();
  112 +
  113 + const year = date.getFullYear();
  114 + const month = String(date.getMonth() + 1).padStart(2, '0');
  115 + const day = String(date.getDate()).padStart(2, '0');
  116 +
  117 + const hours = String(date.getHours()).padStart(2, '0');
  118 + const minutes = String(date.getMinutes()).padStart(2, '0');
  119 + const seconds = String(date.getSeconds()).padStart(2, '0');
  120 +
  121 + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  122 + };
  123 + const date = getFormattedDate();
  124 + // 创建一个链接元素用于下载
  125 + const link = document.createElement('a');
  126 + link.href = window.URL.createObjectURL(blob);
  127 + link.download = `应付款分析${date}.xlsx`; // 你可以为文件命名
  128 + document.body.appendChild(link);
  129 + link.click(); // 自动点击链接,触发下载
  130 + console.log(link, 5656);
  131 + document.body.removeChild(link); // 下载完成后移除链接
  132 + })
  133 + .catch((error) => {
  134 + console.error(error);
  135 + });
  136 + reload();
  137 + closeModal();
  138 + }
  139 +</script>
  140 +<style scoped>
  141 + .divAll {
  142 + display: flex;
  143 + justify-content: center;
  144 + align-items: center;
  145 + }
  146 +</style>
src/views/project/finance/pay/FinanceEdit.vue
@@ -28,11 +28,13 @@ @@ -28,11 +28,13 @@
28 import { BasicForm, FormSchema, useForm } from '@/components/Form'; 28 import { BasicForm, FormSchema, useForm } from '@/components/Form';
29 import { defineComponent, ref, computed, unref, toRaw, reactive } from 'vue'; 29 import { defineComponent, ref, computed, unref, toRaw, reactive } from 'vue';
30 import { getEmailList } from '/@/api/sys/config'; 30 import { getEmailList } from '/@/api/sys/config';
  31 + import { updateAmountInfo } from '@/api/project/invoice';
31 32
  33 + const emit = defineEmits(['success']);
32 const schemas: FormSchema[] = [ 34 const schemas: FormSchema[] = [
33 { 35 {
34 - field: 'configSample',  
35 - component: 'Input', 36 + field: 'actualPayedAmount',
  37 + component: 'InputNumber',
36 labelWidth: 250, 38 labelWidth: 250,
37 colProps: { 39 colProps: {
38 span: 23, 40 span: 23,
@@ -40,31 +42,31 @@ @@ -40,31 +42,31 @@
40 label: '生产科实际应付金额', 42 label: '生产科实际应付金额',
41 }, 43 },
42 { 44 {
43 - field: 'configSample',  
44 - component: 'Input', 45 + field: 'actualPayedAmount1',
  46 + component: 'InputNumber',
45 labelWidth: 250, 47 labelWidth: 250,
46 colProps: { 48 colProps: {
47 span: 23, 49 span: 23,
48 }, 50 },
49 - label: '实际应金额1', 51 + label: '实际应金额1',
50 }, 52 },
51 { 53 {
52 - field: 'configSample',  
53 - component: 'Input', 54 + field: 'actualPayedAmount2',
  55 + component: 'InputNumber',
54 labelWidth: 250, 56 labelWidth: 250,
55 colProps: { 57 colProps: {
56 span: 23, 58 span: 23,
57 }, 59 },
58 - label: '实际应金额2', 60 + label: '实际应金额2',
59 }, 61 },
60 { 62 {
61 - field: 'configSample',  
62 - component: 'Input', 63 + field: 'actualPayedAmount3',
  64 + component: 'InputNumber',
63 labelWidth: 250, 65 labelWidth: 250,
64 colProps: { 66 colProps: {
65 span: 23, 67 span: 23,
66 }, 68 },
67 - label: '实际应金额3', 69 + label: '实际应金额3',
68 }, 70 },
69 ]; 71 ];
70 const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({ 72 const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
@@ -76,23 +78,30 @@ @@ -76,23 +78,30 @@
76 span: 24, 78 span: 24,
77 }, 79 },
78 }); 80 });
  81 +
  82 + const update = ref();
79 const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { 83 const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => {
80 // 方式1 84 // 方式1
81 - console.log(data, 56561);  
82 resetFields(); 85 resetFields();
83 setDrawerProps({ confirmLoading: false }); 86 setDrawerProps({ confirmLoading: false });
84 setFieldsValue({ 87 setFieldsValue({
85 ...toRaw(data.data), 88 ...toRaw(data.data),
86 }); 89 });
  90 + update.value = data;
  91 + console.log(data, '5656data');
87 }); 92 });
88 - //获取现有的列表  
89 - async function getData() {  
90 - const emailAll = await getEmailList({});  
91 - return emailAll;  
92 - }  
93 //完成编辑 93 //完成编辑
94 async function handleSubmit() { 94 async function handleSubmit() {
95 const values = await validate(); 95 const values = await validate();
96 - console.log('5656handleSubmit'); 96 + const updatedValues = {
  97 + ...values,
  98 + id: update.value.data.id,
  99 + };
  100 + console.log(updatedValues, 56565);
  101 + await updateAmountInfo({
  102 + ...updatedValues,
  103 + });
  104 + emit('success');
  105 + closeDrawer();
97 } 106 }
98 </script> 107 </script>
src/views/project/finance/pay/InvoiceUpload.vue
@@ -4,13 +4,15 @@ @@ -4,13 +4,15 @@
4 @register="register" 4 @register="register"
5 title="发票上传" 5 title="发票上传"
6 width="500px" 6 width="500px"
7 - :bodyStyle="{ height: '200px' }" 7 + :bodyStyle="{ height: '240px' }"
8 @ok="handleOk" 8 @ok="handleOk"
9 ><a-upload-dragger 9 ><a-upload-dragger
10 v-model:fileList="fileList" 10 v-model:fileList="fileList"
11 name="file" 11 name="file"
  12 + :beforeUpload="beforeUpload"
  13 + :max-count="1"
12 :multiple="true" 14 :multiple="true"
13 - action="https://www.mocky.io/v2/5cc8019d300000980a055e76" 15 + :action="updateInvoiceUrl"
14 @change="handleChange" 16 @change="handleChange"
15 @drop="handleDrop" 17 @drop="handleDrop"
16 > 18 >
@@ -27,31 +29,43 @@ @@ -27,31 +29,43 @@
27 import type { UploadProps, UploadChangeParam } from 'ant-design-vue'; 29 import type { UploadProps, UploadChangeParam } from 'ant-design-vue';
28 import { InboxOutlined } from '@ant-design/icons-vue'; 30 import { InboxOutlined } from '@ant-design/icons-vue';
29 import { message } from 'ant-design-vue'; 31 import { message } from 'ant-design-vue';
  32 + import { updateInvoiceInfo } from '@/api/project/invoice';
30 33
31 - const handleChange = (info: UploadChangeParam) => {  
32 - const status = info.file.status;  
33 - if (status !== 'uploading') {  
34 - console.log(info.file, info.fileList);  
35 - }  
36 - if (status === 'done') {  
37 - message.success(`${info.file.name} file uploaded successfully.`);  
38 - } else if (status === 'error') {  
39 - message.error(`${info.file.name} file upload failed.`); 34 + const emit = defineEmits(['success']);
  35 + const uploadUrl = ref('http://47.104.8.35:18000/api/localStorage/upload_file_oss?name=');
  36 + const updateInvoiceUrl = ref('http://47.104.8.35:18000/api/localStorage/upload_file_oss?name=');
  37 + const invoiceUrl = ref();
  38 + const id = ref();
  39 +
  40 + const [register, { closeModal }] = useModalInner(async (data) => {
  41 + // fileList.value = [];
  42 + fileList.value = [];
  43 + invoiceUrl.value = data.data.invoiceUrl;
  44 + id.value = data.data.id;
  45 + });
  46 +
  47 + const handleChange = (info) => {
  48 + if (info.file.status == 'done') {
  49 + updateInvoiceUrl.value = info.file.response.data.fileUrl;
  50 + invoiceUrl.value = updateInvoiceUrl.value;
40 } 51 }
41 }; 52 };
  53 + function beforeUpload(info) {
  54 + updateInvoiceUrl.value = uploadUrl.value + info.name;
  55 + }
42 function handleDrop(e: DragEvent) { 56 function handleDrop(e: DragEvent) {
43 console.log(e); 57 console.log(e);
44 } 58 }
45 const fileList = ref<UploadProps['fileList']>([]); 59 const fileList = ref<UploadProps['fileList']>([]);
46 60
47 - const Input1 = ref('');  
48 - const Input2 = ref('123');  
49 -  
50 - const [register, { closeModal }] = useModalInner(async (data) => {  
51 - title.value = data.title;  
52 - });  
53 - const title = ref('');  
54 async function handleOk() { 61 async function handleOk() {
  62 + await updateInvoiceInfo({
  63 + id: id.value,
  64 + invoiceUrl: invoiceUrl.value,
  65 + });
  66 + // await updateDeduct(requestData);
  67 + fileList.value = [];
  68 + emit('success');
55 closeModal(); 69 closeModal();
56 } 70 }
57 </script> 71 </script>
src/views/project/finance/pay/TrackEdit.vue
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 <BasicDrawer 3 <BasicDrawer
4 @register="register" 4 @register="register"
5 v-bind="$attrs" 5 v-bind="$attrs"
6 - title="编辑" 6 + title="跟单编辑"
7 width="30%" 7 width="30%"
8 :isDetail="true" 8 :isDetail="true"
9 @ok="handleSubmit" 9 @ok="handleSubmit"
@@ -14,23 +14,22 @@ @@ -14,23 +14,22 @@
14 > 14 >
15 <div> 15 <div>
16 <div style="font-size: 15px">生产科扣款金额</div> 16 <div style="font-size: 15px">生产科扣款金额</div>
17 - <a-input v-model:value="Input1" placeholder="请输入" auto-size /> 17 + <a-input v-model:value="input1" placeholder="请输入" auto-size />
18 <div style="margin: 16px 0"></div> 18 <div style="margin: 16px 0"></div>
19 <div style="font-size: 15px">扣款责任部门</div> 19 <div style="font-size: 15px">扣款责任部门</div>
20 - <a-input v-model:value="Input2" placeholder="请输入" auto-size /> 20 + <a-input v-model:value="deductDept" placeholder="请输入" auto-size />
21 <div style="margin: 16px 0"></div> 21 <div style="margin: 16px 0"></div>
22 <div>上传扣款单</div 22 <div>上传扣款单</div
23 ><a-space direction="vertical" style="width: 100%" size="large"> 23 ><a-space direction="vertical" style="width: 100%" size="large">
24 <a-upload 24 <a-upload
25 v-model:file-list="fileList" 25 v-model:file-list="fileList"
  26 + :beforeUpload="beforeUpload"
26 list-type="picture" 27 list-type="picture"
27 :max-count="1" 28 :max-count="1"
28 - action="https://www.mocky.io/v2/5cc8019d300000980a055e76" 29 + :action="updateDeductUrl"
  30 + @change="handleChange"
29 > 31 >
30 - <a-button>  
31 - <!-- <upload-outlined></upload-outlined> -->  
32 - 上传报关单  
33 - </a-button> 32 + <a-button> 上传扣款单 </a-button>
34 </a-upload> 33 </a-upload>
35 </a-space> 34 </a-space>
36 </div> 35 </div>
@@ -47,22 +46,49 @@ @@ -47,22 +46,49 @@
47 import { getEmailList } from '/@/api/sys/config'; 46 import { getEmailList } from '/@/api/sys/config';
48 import { UploadOutlined } from '@ant-design/icons-vue'; 47 import { UploadOutlined } from '@ant-design/icons-vue';
49 import type { UploadProps } from 'ant-design-vue'; 48 import type { UploadProps } from 'ant-design-vue';
  49 + import { updateDeductInfo } from '@/api/project/invoice';
50 50
  51 + const emit = defineEmits(['success']);
51 const fileList = ref<UploadProps['fileList']>([]); 52 const fileList = ref<UploadProps['fileList']>([]);
52 53
53 - const Input1 = ref('');  
54 - const Input2 = ref('123'); 54 + const input1 = ref();
  55 + const deductUrl = ref();
  56 + const id = ref();
  57 + const checkNo = ref();
  58 + const deductDept = ref();
  59 + const uploadUrl = ref('http://47.104.8.35:18000/api/localStorage/upload_file_oss?name=');
  60 + const updateDeductUrl = ref('http://47.104.8.35:18000/api/localStorage/upload_file_oss?name=');
55 61
56 const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { 62 const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => {
57 - console.log(data, 56561); 63 + id.value = data.data.id;
  64 + checkNo.value = data.data.checkNo;
  65 + input1.value = data.data.deductAmount;
  66 + deductDept.value = data.data.deductDept;
  67 + deductUrl.value = data.data.deductUrl;
58 }); 68 });
59 - //获取现有的列表  
60 - async function getData() {  
61 - const emailAll = await getEmailList({});  
62 - return emailAll; 69 +
  70 + function handleChange(info) {
  71 + if (info.file.status == 'done') {
  72 + updateDeductUrl.value = info.file.response.data.fileUrl;
  73 + deductUrl.value = updateDeductUrl.value;
  74 + }
  75 + }
  76 + function beforeUpload(info) {
  77 + updateDeductUrl.value = uploadUrl.value + info.name;
63 } 78 }
  79 +
64 //完成编辑 80 //完成编辑
65 async function handleSubmit() { 81 async function handleSubmit() {
66 - console.log('5656handleSubmit'); 82 + await updateDeductInfo({
  83 + id: id.value,
  84 + checkNo: checkNo.value,
  85 + deductAmount: input1.value,
  86 + deductDept: deductDept.value,
  87 + deductUrl: deductUrl.value,
  88 + });
  89 + // await updateDeduct(requestData);
  90 + fileList.value = [];
  91 + emit('success');
  92 + closeDrawer();
67 } 93 }
68 </script> 94 </script>
src/views/project/finance/pay/index.vue
@@ -2,10 +2,12 @@ @@ -2,10 +2,12 @@
2 <div class="p-4"> 2 <div class="p-4">
3 <BasicTable @register="registerTable"> 3 <BasicTable @register="registerTable">
4 <template #toolbar> 4 <template #toolbar>
5 - <a-button type="primary">导出</a-button>  
6 - <FinanceEdit @register="registerFinanceEdit" />  
7 - <TrackEdit @register="registerTrackEdit" />  
8 - <InvoiceUpload @register="registerInvoiceUpload" /> 5 + <a-button type="primary" @click="handleCheckSum">应付款汇总</a-button>
  6 + <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" />
  7 + <TrackEdit @register="registerTrackEdit" @success="handleSuccess" />
  8 + <CheckSum @register="registerCheckSum" />
  9 + <InvoiceUpload @register="registerInvoiceUpload" @success="handleSuccess" />
  10 + <CheckDetail @register="registerInvoiceDetail" />
9 </template> 11 </template>
10 <template #bodyCell="{ column, record }"> 12 <template #bodyCell="{ column, record }">
11 <template v-if="column.key === 'action'"> 13 <template v-if="column.key === 'action'">
@@ -26,11 +28,15 @@ @@ -26,11 +28,15 @@
26 ]" 28 ]"
27 :dropDownActions="[ 29 :dropDownActions="[
28 { 30 {
29 - label: '应付款提交',  
30 - onClick: handleDelete.bind(null, record), 31 + label: '提交审核',
  32 + onClick: handleCommit.bind(null, record),
31 }, 33 },
32 { 34 {
33 label: '订单信息', 35 label: '订单信息',
  36 + onClick: handleDetail.bind(null, record),
  37 + },
  38 + {
  39 + label: '删除',
34 onClick: handleDelete.bind(null, record), 40 onClick: handleDelete.bind(null, record),
35 }, 41 },
36 ]" 42 ]"
@@ -41,28 +47,38 @@ @@ -41,28 +47,38 @@
41 </div> 47 </div>
42 </template> 48 </template>
43 <script lang="ts" setup> 49 <script lang="ts" setup>
44 - import { defineComponent } from 'vue'; 50 + import { defineComponent, ref } from 'vue';
45 import { BasicTable, useTable, BasicColumn, TableAction } from '/@/components/Table'; 51 import { BasicTable, useTable, BasicColumn, TableAction } from '/@/components/Table';
46 import { searchFormSchema, columns } from './pay.data'; 52 import { searchFormSchema, columns } from './pay.data';
47 - import { demoListApi } from '/@/api/demo/table';  
48 import TrackEdit from './TrackEdit.vue'; 53 import TrackEdit from './TrackEdit.vue';
49 import FinanceEdit from './FinanceEdit.vue'; 54 import FinanceEdit from './FinanceEdit.vue';
50 import InvoiceUpload from './InvoiceUpload.vue'; 55 import InvoiceUpload from './InvoiceUpload.vue';
  56 + import CheckDetail from './CheckDetail.vue';
  57 + import CheckSum from './CheckSum.vue';
51 import { useDrawer } from '/@/components/Drawer'; 58 import { useDrawer } from '/@/components/Drawer';
52 import { useModal } from '/@/components/Modal'; 59 import { useModal } from '/@/components/Modal';
  60 + import { getCheck, checkDelete, checkCommit, checkDetail } from '@/api/project/invoice';
  61 + import { useMessage } from '/@/hooks/web/useMessage';
53 62
  63 + const [registerCheckSum, { openModal: openCheckSum }] = useModal();
54 const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); 64 const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer();
55 const [registerTrackEdit, { openDrawer: openTrackEdit }] = useDrawer(); 65 const [registerTrackEdit, { openDrawer: openTrackEdit }] = useDrawer();
56 const [registerInvoiceUpload, { openModal: openInvoiceUpload }] = useModal(); 66 const [registerInvoiceUpload, { openModal: openInvoiceUpload }] = useModal();
  67 + const [registerInvoiceDetail, { openDrawer: openCheckDetail }] = useDrawer();
  68 + const checkedKeys = ref<Array<string | number>>([]);
57 69
58 - const [registerTable] = useTable({ 70 + const [registerTable, { reload }] = useTable({
59 title: '', 71 title: '',
60 - api: demoListApi, 72 + api: getCheck,
61 columns: columns, 73 columns: columns,
62 bordered: true, 74 bordered: true,
  75 + clickToRowSelect: false,
63 rowKey: 'id', 76 rowKey: 'id',
64 rowSelection: { 77 rowSelection: {
65 type: 'checkbox', 78 type: 'checkbox',
  79 + selectedRowKeys: checkedKeys,
  80 + onSelect,
  81 + onSelectAll,
66 }, 82 },
67 formConfig: { 83 formConfig: {
68 labelWidth: 120, 84 labelWidth: 120,
@@ -82,28 +98,314 @@ @@ -82,28 +98,314 @@
82 // slots: { customRender: 'action' }, 98 // slots: { customRender: 'action' },
83 }, 99 },
84 }); 100 });
  101 + //选择
  102 + // function onSelect(record, selected) {
  103 + // if (selected) {
  104 + // checkedKeys.value = [...checkedKeys.value, record.id];
  105 + // } else {
  106 + // checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id);
  107 + // }
  108 + // }
  109 + // function onSelectAll(selected, selectedRows, changeRows) {
  110 + // const changeIds = changeRows.map((item) => item.id);
  111 + // if (selected) {
  112 + // checkedKeys.value = [...checkedKeys.value, ...changeIds];
  113 + // } else {
  114 + // checkedKeys.value = checkedKeys.value.filter((id) => {
  115 + // return !changeIds.includes(id);
  116 + // });
  117 + // }
  118 + // }
  119 +
  120 + // type CustomerCodeEntry = [string, number]; // 定义二维数组类型 [customerCode, count]
  121 +
  122 + // const selectedCustomCodes = ref<CustomerCodeEntry[]>([]); // 创建一个二维数组的 ref
  123 +
  124 + // // 选择函数
  125 + // async function onSelect(record: any, selected: boolean) {
  126 + // if (selected) {
  127 + // const res = await checkDetail({ checkNo: record.checkNo });
  128 + // const customerCode = res[0].customerCode;
  129 +
  130 + // const index = selectedCustomCodes.value.findIndex(([code]) => code === customerCode);
  131 +
  132 + // if (index !== -1) {
  133 + // // 如果存在,增加计数
  134 + // selectedCustomCodes.value[index][1] += 1;
  135 + // } else {
  136 + // // 如果不存在,添加新项 [customerCode, 1]
  137 + // selectedCustomCodes.value.push([customerCode, 1]);
  138 + // }
  139 +
  140 + // checkedKeys.value = [...checkedKeys.value, record.id];
  141 + // } else {
  142 + // const res = await checkDetail({ checkNo: record.checkNo });
  143 + // const customerCode = res[0].customerCode;
  144 +
  145 + // const index = selectedCustomCodes.value.findIndex(([code]) => code === customerCode);
  146 +
  147 + // if (index !== -1) {
  148 + // if (selectedCustomCodes.value[index][1] > 1) {
  149 + // // 如果计数大于 1,减少计数
  150 + // selectedCustomCodes.value[index][1] -= 1;
  151 + // } else {
  152 + // // 如果计数为 1,移除该项
  153 + // selectedCustomCodes.value.splice(index, 1);
  154 + // }
  155 + // }
  156 +
  157 + // checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id);
  158 + // }
  159 + // console.log(selectedCustomCodes.value, 56561);
  160 + // console.log(checkedKeys.value, 56562);
  161 + // }
  162 +
  163 + // async function onSelectAll(selected: boolean, selectedRows: any[], changeRows: any[]) {
  164 + // const changeIds = changeRows.map((item) => item.id);
  165 + // const changeCustomerCodes = await Promise.all(
  166 + // changeRows.map(async (item) => {
  167 + // const res = await checkDetail({ checkNo: item.checkNo });
  168 + // return res[0].customerCode;
  169 + // }),
  170 + // );
  171 +
  172 + // if (selected) {
  173 + // // 添加到 checkedKeys
  174 + // checkedKeys.value = [...checkedKeys.value, ...changeIds];
  175 +
  176 + // // 处理每个 customerCode
  177 + // changeCustomerCodes.forEach((code) => {
  178 + // const index = selectedCustomCodes.value.findIndex(
  179 + // ([customerCode]) => customerCode === code,
  180 + // );
  181 + // if (index !== -1) {
  182 + // // 如果存在,增加计数
  183 + // selectedCustomCodes.value[index][1] += 1;
  184 + // } else {
  185 + // // 如果不存在,添加新项 [customerCode, 1]
  186 + // selectedCustomCodes.value.push([code, 1]);
  187 + // }
  188 + // });
  189 + // } else {
  190 + // // 从 checkedKeys 中移除
  191 + // checkedKeys.value = checkedKeys.value.filter((id) => !changeIds.includes(id));
  192 +
  193 + // // 处理每个 customerCode
  194 + // changeCustomerCodes.forEach((code) => {
  195 + // const index = selectedCustomCodes.value.findIndex(
  196 + // ([customerCode]) => customerCode === code,
  197 + // );
  198 + // if (index !== -1) {
  199 + // if (selectedCustomCodes.value[index][1] > 1) {
  200 + // // 如果计数大于 1,减少计数
  201 + // selectedCustomCodes.value[index][1] -= 1;
  202 + // } else {
  203 + // // 如果计数为 1,移除该项
  204 + // selectedCustomCodes.value.splice(index, 1);
  205 + // }
  206 + // }
  207 + // });
  208 + // }
  209 + // console.log(selectedCustomCodes.value, 56561);
  210 + // console.log(checkedKeys.value, 56562);
  211 + // }
  212 +
  213 + type CustomerCodeEntry = [string, number]; // 定义二维数组类型 [customerCode, count]
  214 + type ProductionDepartmentEntry = [string, number]; // 定义二维数组类型 [productionDepartment, count]
  215 +
  216 + const selectedCustomCodes = ref<CustomerCodeEntry[]>([]); // 创建一个二维数组的 ref
  217 + const selectedProductionDepartment = ref<ProductionDepartmentEntry[]>([]); // 创建一个二维数组的 ref
  218 + // const checkedKeys = ref<string[]>([]); // 选中的键值列表
  219 +
  220 + // 单选函数
  221 + async function onSelect(record, selected: boolean) {
  222 + const res = await checkDetail({ checkNo: record.checkNo });
  223 +
  224 + const customerCode = res[0].customerCode;
  225 + const productionDepartment = res[0].productionDepartment;
  226 +
  227 + const customerCodeIndex = selectedCustomCodes.value.findIndex(
  228 + ([code]) => code === customerCode,
  229 + );
  230 +
  231 + const productionDepartmentIndex = selectedProductionDepartment.value.findIndex(
  232 + ([department]) => department === productionDepartment,
  233 + );
  234 +
  235 + if (selected) {
  236 + checkedKeys.value = [...checkedKeys.value, record.id];
  237 +
  238 + // 更新 selectedCustomCodes
  239 + if (customerCodeIndex !== -1) {
  240 + selectedCustomCodes.value[customerCodeIndex][1] += 1;
  241 + } else {
  242 + selectedCustomCodes.value.push([customerCode, 1]);
  243 + }
  244 +
  245 + // 更新 selectedProductionDepartment
  246 + if (productionDepartmentIndex !== -1) {
  247 + selectedProductionDepartment.value[productionDepartmentIndex][1] += 1;
  248 + } else {
  249 + selectedProductionDepartment.value.push([productionDepartment, 1]);
  250 + }
  251 + } else {
  252 + checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id);
  253 +
  254 + // 更新 selectedCustomCodes
  255 + if (customerCodeIndex !== -1) {
  256 + if (selectedCustomCodes.value[customerCodeIndex][1] > 1) {
  257 + selectedCustomCodes.value[customerCodeIndex][1] -= 1;
  258 + } else {
  259 + selectedCustomCodes.value.splice(customerCodeIndex, 1);
  260 + }
  261 + }
  262 +
  263 + // 更新 selectedProductionDepartment
  264 + if (productionDepartmentIndex !== -1) {
  265 + if (selectedProductionDepartment.value[productionDepartmentIndex][1] > 1) {
  266 + selectedProductionDepartment.value[productionDepartmentIndex][1] -= 1;
  267 + } else {
  268 + selectedProductionDepartment.value.splice(productionDepartmentIndex, 1);
  269 + }
  270 + }
  271 + }
  272 + console.log(checkedKeys.value, 565666666); // 输出当前的 selectedCustomCodes 值
  273 + console.log(selectedCustomCodes.value, 565666666); // 输出当前的 selectedCustomCodes 值
  274 + console.log(selectedProductionDepartment.value, 565666666); // 输出当前的 selectedCustomCodes 值
  275 + }
  276 +
  277 + // 全选函数
  278 + async function onSelectAll(selected: boolean, selectedRows: any[], changeRows: any[]) {
  279 + const changeIds = changeRows.map((item) => item.id);
  280 + const changeCustomerCodes = await Promise.all(
  281 + changeRows.map(async (item) => {
  282 + const res = await checkDetail({ checkNo: item.checkNo });
  283 + return res[0].customerCode;
  284 + }),
  285 + );
  286 +
  287 + const changeProductionDepartments = await Promise.all(
  288 + changeRows.map(async (item) => {
  289 + const res = await checkDetail({ checkNo: item.checkNo });
  290 + return res[0].productionDepartment;
  291 + }),
  292 + );
  293 +
  294 + if (selected) {
  295 + checkedKeys.value = [...checkedKeys.value, ...changeIds];
  296 +
  297 + // 更新 selectedCustomCodes
  298 + changeCustomerCodes.forEach((code) => {
  299 + const index = selectedCustomCodes.value.findIndex(
  300 + ([customerCode]) => customerCode === code,
  301 + );
  302 + if (index !== -1) {
  303 + selectedCustomCodes.value[index][1] += 1;
  304 + } else {
  305 + selectedCustomCodes.value.push([code, 1]);
  306 + }
  307 + });
  308 +
  309 + // 更新 selectedProductionDepartment
  310 + changeProductionDepartments.forEach((department) => {
  311 + const index = selectedProductionDepartment.value.findIndex(
  312 + ([prodDepartment]) => prodDepartment === department,
  313 + );
  314 + if (index !== -1) {
  315 + selectedProductionDepartment.value[index][1] += 1;
  316 + } else {
  317 + selectedProductionDepartment.value.push([department, 1]);
  318 + }
  319 + });
  320 + } else {
  321 + checkedKeys.value = checkedKeys.value.filter((id) => !changeIds.includes(id));
  322 +
  323 + // 更新 selectedCustomCodes
  324 + changeCustomerCodes.forEach((code) => {
  325 + const index = selectedCustomCodes.value.findIndex(
  326 + ([customerCode]) => customerCode === code,
  327 + );
  328 + if (index !== -1) {
  329 + if (selectedCustomCodes.value[index][1] > 1) {
  330 + selectedCustomCodes.value[index][1] -= 1;
  331 + } else {
  332 + selectedCustomCodes.value.splice(index, 1);
  333 + }
  334 + }
  335 + });
  336 +
  337 + // 更新 selectedProductionDepartment
  338 + changeProductionDepartments.forEach((department) => {
  339 + const index = selectedProductionDepartment.value.findIndex(
  340 + ([prodDepartment]) => prodDepartment === department,
  341 + );
  342 + if (index !== -1) {
  343 + if (selectedProductionDepartment.value[index][1] > 1) {
  344 + selectedProductionDepartment.value[index][1] -= 1;
  345 + } else {
  346 + selectedProductionDepartment.value.splice(index, 1);
  347 + }
  348 + }
  349 + });
  350 + }
  351 +
  352 + console.log(checkedKeys.value, 565666666); // 输出当前的 selectedCustomCodes 值
  353 + console.log(selectedCustomCodes.value, 565666666); // 输出当前的 selectedCustomCodes 值
  354 + console.log(selectedProductionDepartment.value, 565666666); // 输出当前的 selectedCustomCodes 值
  355 + }
  356 +
85 function handleFinanceEdit(record) { 357 function handleFinanceEdit(record) {
86 - console.log('点击了编辑', record);  
87 openFinanceEdit(true, { 358 openFinanceEdit(true, {
88 data: record, 359 data: record,
89 }); 360 });
90 } 361 }
91 function handleTrackEdit(record) { 362 function handleTrackEdit(record) {
92 - console.log('点击了编辑', record);  
93 openTrackEdit(true, { 363 openTrackEdit(true, {
94 data: record, 364 data: record,
95 }); 365 });
96 } 366 }
97 function handleInvoiceUpload(record) { 367 function handleInvoiceUpload(record) {
98 - console.log('点击了编辑', record);  
99 openInvoiceUpload(true, { 368 openInvoiceUpload(true, {
100 data: record, 369 data: record,
101 }); 370 });
102 } 371 }
103 function handleDelete(record) { 372 function handleDelete(record) {
104 - console.log('点击了编辑', record);  
105 - openTrackEdit(true, { 373 + const id: string[] = Array.isArray(record.id) ? record.id : [record.id];
  374 + checkDelete({ ids: id });
  375 + setTimeout(() => {
  376 + reload();
  377 + }, 50);
  378 + }
  379 + function handleDetail(record) {
  380 + openCheckDetail(true, {
106 data: record, 381 data: record,
107 }); 382 });
108 } 383 }
  384 + function handleCommit(record) {
  385 + checkCommit({ id: record.id });
  386 + setTimeout(() => {
  387 + reload();
  388 + }, 50);
  389 + }
  390 +
  391 + const { createMessage } = useMessage();
  392 + const { error } = createMessage;
  393 + function handleCheckSum(record) {
  394 + if (checkedKeys.value.length == 0) {
  395 + error('请选择订单');
  396 + return;
  397 + }
  398 + if (selectedProductionDepartment.value.length > 1) {
  399 + error('勾选订单的生产科需一致');
  400 + return;
  401 + }
  402 + openCheckSum(true, {
  403 + data: checkedKeys.value,
  404 + });
  405 + }
  406 + function handleSuccess() {
  407 + setTimeout(() => {
  408 + reload();
  409 + }, 150);
  410 + }
109 </script> 411 </script>
src/views/project/finance/pay/pay.data.tsx
1 import { FormSchema } from '/@/components/Form'; 1 import { FormSchema } from '/@/components/Form';
2 import { BasicColumn } from '/@/components/Table'; 2 import { BasicColumn } from '/@/components/Table';
3 import { icon } from 'ant-design-vue'; 3 import { icon } from 'ant-design-vue';
4 -import { FolderAddOutlined } from '@ant-design/icons-vue'; 4 +import { FolderAddOutlined, FilePptOutlined } from '@ant-design/icons-vue';
5 import { size } from 'lodash-es'; 5 import { size } from 'lodash-es';
6 6
7 export const searchFormSchema: FormSchema[] = [ 7 export const searchFormSchema: FormSchema[] = [
8 { 8 {
9 - field: 'phone', 9 + field: 'checkNo',
10 label: '生产科对账单号', 10 label: '生产科对账单号',
11 component: 'Input', 11 component: 'Input',
12 colProps: { span: 8 }, 12 colProps: { span: 8 },
13 }, 13 },
14 { 14 {
15 - field: 'nickName',  
16 - label: '总经理审核', 15 + field: 'productionDepartment',
  16 + label: '生产科',
17 component: 'Input', 17 component: 'Input',
18 colProps: { span: 8 }, 18 colProps: { span: 8 },
19 }, 19 },
  20 + {
  21 + field: 'status',
  22 + label: '总经理审核',
  23 + component: 'Select',
  24 + colProps: { span: 8 },
  25 + componentProps: {
  26 + options: [
  27 + { label: '未提交审核', value: -1 },
  28 + { label: '待审核', value: 0 },
  29 + { label: '审核通过', value: 1 },
  30 + { label: '审核驳回', value: 2 },
  31 + ],
  32 + },
  33 + },
  34 + {
  35 + field: 'customerCode',
  36 + label: '客户编码',
  37 + component: 'Input',
  38 + colProps: {
  39 + span: 8,
  40 + },
  41 + },
20 ]; 42 ];
21 43
22 export const columns: BasicColumn[] = [ 44 export const columns: BasicColumn[] = [
23 { 45 {
24 title: '生产科对账单号', 46 title: '生产科对账单号',
25 - dataIndex: 'no', 47 + dataIndex: 'checkNo',
26 width: 120, 48 width: 120,
27 - customRender: (column) => {  
28 - return '5667';  
29 - },  
30 }, 49 },
31 { 50 {
32 title: '生产科应付款日期', 51 title: '生产科应付款日期',
33 - dataIndex: 'no', 52 + dataIndex: 'payedDate',
34 width: 140, 53 width: 140,
35 }, 54 },
36 { 55 {
37 title: '生产科扣款金额', 56 title: '生产科扣款金额',
38 - dataIndex: 'no', 57 + dataIndex: 'deductAmount',
39 width: 120, 58 width: 120,
40 }, 59 },
41 { 60 {
42 title: '扣款责任部门', 61 title: '扣款责任部门',
43 - dataIndex: 'no', 62 + dataIndex: 'deductDept',
44 width: 120, 63 width: 120,
45 }, 64 },
46 { 65 {
47 title: '上传扣款单', 66 title: '上传扣款单',
48 - dataIndex: 'no', 67 + dataIndex: 'deductUrl',
49 width: 120, 68 width: 120,
  69 + customRender: (column) => {
  70 + const deductUrl = column.record.deductUrl;
  71 + if (deductUrl == undefined) {
  72 + return;
  73 + }
  74 + return <FilePptOutlined style="font-size:25px" onClick={() => window.open(deductUrl)} />;
  75 + },
50 }, 76 },
51 { 77 {
52 title: '生产科实际应付金额', 78 title: '生产科实际应付金额',
53 - dataIndex: 'no', 79 + dataIndex: 'actualPayedAmount',
54 width: 120, 80 width: 120,
55 }, 81 },
56 { 82 {
57 title: '生产科发票上传', 83 title: '生产科发票上传',
58 - dataIndex: 'no', 84 + dataIndex: 'invoiceUrl',
59 width: 80, 85 width: 80,
60 customRender: (column) => { 86 customRender: (column) => {
61 - return <FolderAddOutlined style="font-size:25px" />; 87 + const deductUrl = column.record.invoiceUrl;
  88 + if (deductUrl == undefined) {
  89 + return;
  90 + }
  91 + return <FilePptOutlined style="font-size:25px" onClick={() => window.open(deductUrl)} />;
62 }, 92 },
63 }, 93 },
64 { 94 {
65 title: '实际付款金额1', 95 title: '实际付款金额1',
66 - dataIndex: 'no', 96 + dataIndex: 'actualPayedAmount1',
67 width: 120, 97 width: 120,
68 }, 98 },
69 { 99 {
70 title: '实际付款金额2', 100 title: '实际付款金额2',
71 - dataIndex: 'no', 101 + dataIndex: 'actualPayedAmount2',
72 width: 120, 102 width: 120,
73 }, 103 },
74 { 104 {
75 title: '实际付款金额3', 105 title: '实际付款金额3',
76 - dataIndex: 'no', 106 + dataIndex: 'actualPayedAmount3',
77 width: 120, 107 width: 120,
78 }, 108 },
79 { 109 {
80 title: '生产科发票', 110 title: '生产科发票',
81 - dataIndex: 'no', 111 + dataIndex: 'invoiceUrl',
82 width: 120, 112 width: 120,
  113 + customRender: (column) => {
  114 + const deductUrl = column.record.invoiceUrl;
  115 + if (deductUrl == undefined) {
  116 + return;
  117 + }
  118 + return <FilePptOutlined style="font-size:25px" onClick={() => window.open(deductUrl)} />;
  119 + },
83 }, 120 },
84 { 121 {
85 title: '总经理审核', 122 title: '总经理审核',
86 - dataIndex: 'no', 123 + dataIndex: 'status',
87 width: 120, 124 width: 120,
  125 + customRender: (column) => {
  126 + if (column.record.status == -1) {
  127 + return '未提交审核';
  128 + } else if (column.record.status == 0) {
  129 + return '待审核';
  130 + } else if (column.record.status == 1) {
  131 + return '审核通过';
  132 + } else if (column.record.status == 2) {
  133 + return '审核驳回';
  134 + }
  135 + },
88 }, 136 },
89 ]; 137 ];
src/views/project/finance/receive/FinanceEdit.vue
@@ -30,10 +30,11 @@ @@ -30,10 +30,11 @@
30 import { getEmailList } from '/@/api/sys/config'; 30 import { getEmailList } from '/@/api/sys/config';
31 import { updateAmount } from '@/api/project/invoice'; 31 import { updateAmount } from '@/api/project/invoice';
32 32
  33 + const emit = defineEmits(['success']);
33 const schemas: FormSchema[] = [ 34 const schemas: FormSchema[] = [
34 { 35 {
35 field: 'actualReceivableAmount', 36 field: 'actualReceivableAmount',
36 - component: 'Input', 37 + component: 'InputNumber',
37 labelWidth: 250, 38 labelWidth: 250,
38 colProps: { 39 colProps: {
39 span: 23, 40 span: 23,
@@ -42,7 +43,7 @@ @@ -42,7 +43,7 @@
42 }, 43 },
43 { 44 {
44 field: 'actualPayedAmount1', 45 field: 'actualPayedAmount1',
45 - component: 'Input', 46 + component: 'InputNumber',
46 labelWidth: 250, 47 labelWidth: 250,
47 colProps: { 48 colProps: {
48 span: 23, 49 span: 23,
@@ -51,7 +52,7 @@ @@ -51,7 +52,7 @@
51 }, 52 },
52 { 53 {
53 field: 'actualPayedAmount2', 54 field: 'actualPayedAmount2',
54 - component: 'Input', 55 + component: 'InputNumber',
55 labelWidth: 250, 56 labelWidth: 250,
56 colProps: { 57 colProps: {
57 span: 23, 58 span: 23,
@@ -60,7 +61,7 @@ @@ -60,7 +61,7 @@
60 }, 61 },
61 { 62 {
62 field: 'actualPayedAmount3', 63 field: 'actualPayedAmount3',
63 - component: 'Input', 64 + component: 'InputNumber',
64 labelWidth: 250, 65 labelWidth: 250,
65 colProps: { 66 colProps: {
66 span: 23, 67 span: 23,
@@ -69,7 +70,7 @@ @@ -69,7 +70,7 @@
69 }, 70 },
70 { 71 {
71 field: 'otherAmount', 72 field: 'otherAmount',
72 - component: 'Input', 73 + component: 'InputNumber',
73 labelWidth: 250, 74 labelWidth: 250,
74 colProps: { 75 colProps: {
75 span: 23, 76 span: 23,
@@ -108,5 +109,7 @@ @@ -108,5 +109,7 @@
108 await updateAmount({ 109 await updateAmount({
109 ...updatedValues, 110 ...updatedValues,
110 }); 111 });
  112 + emit('success');
  113 + closeDrawer();
111 } 114 }
112 </script> 115 </script>
src/views/project/finance/receive/InvoiceAnalysis.vue
@@ -3,51 +3,137 @@ @@ -3,51 +3,137 @@
3 v-bind="$attrs" 3 v-bind="$attrs"
4 @register="register" 4 @register="register"
5 title="收款单分析" 5 title="收款单分析"
6 - width="700px"  
7 - :bodyStyle="{ height: '400px' }" 6 + width="80%"
  7 + :isDetail="true"
  8 + :showDetailBack="false"
8 @ok="handleOk" 9 @ok="handleOk"
  10 + @visible-change="handleShow"
9 > 11 >
10 - <a-space direction="vertical">  
11 - <div style="margin: 16px 0"></div>  
12 - <div class="divAll">  
13 - <div  
14 - style="  
15 - margin-left: 22px;  
16 - margin-right: 5px;  
17 - width: 100px;  
18 - text-align: center;  
19 - line-height: 30px;  
20 - "  
21 - >生产科对账单号</div  
22 - ><a-input v-model:value="Input1" placeholder="请输入" style="width: 320px" />  
23 - </div>  
24 - <div class="divAll">  
25 - <div  
26 - style="  
27 - margin-left: 0px;  
28 - margin-right: 1px;  
29 - width: 180px;  
30 - text-align: center;  
31 - line-height: 30px;  
32 - "  
33 - >生产科应付款日期</div  
34 - ><a-input v-model:value="Input2" disabled />  
35 - </div> </a-space  
36 - ></BasicModal> 12 + <div class="p-4">
  13 + <BasicTable @register="registerTable">
  14 + <template #bodyCell="{ column, record }">
  15 + <template v-if="column.key === 'action'"> </template>
  16 + </template>
  17 + </BasicTable>
  18 + </div>
  19 + </BasicModal>
37 </template> 20 </template>
38 <script lang="ts" setup> 21 <script lang="ts" setup>
39 import { BasicModal, useModalInner } from '@/components/Modal'; 22 import { BasicModal, useModalInner } from '@/components/Modal';
40 import { computed, ref } from 'vue'; 23 import { computed, ref } from 'vue';
41 - import { getRefundDate } from '@/api/project/invoice'; 24 + import { invoiceAnalysis, exportAnalysis } from '@/api/project/invoice';
  25 + import { BasicColumn, useTable, BasicTable, ColumnChangeParam } from '/@/components/Table';
  26 + // 处理弹窗的确定按钮点击事件
  27 + import axios from 'axios';
42 28
43 - const Input1 = ref('');  
44 - const Input2 = ref(); 29 + const columnsAnalysis: BasicColumn[] = [
  30 + {
  31 + title: '客户编码',
  32 + dataIndex: 'actualPayedAmount',
  33 + width: 50,
  34 + customRender: (res) => {
  35 + // console.log(res, 56562);
  36 + return res.record.exportVOS[0].customerCode;
  37 + },
  38 + },
  39 + {
  40 + title: '实际应付金额总计',
  41 + dataIndex: 'actualPayedAmount',
  42 + width: 50,
  43 + },
  44 + {
  45 + title: '实际应收金额总计',
  46 + dataIndex: 'actualReceivableAmount',
  47 + width: 50,
  48 + },
  49 + {
  50 + title: '客户总价',
  51 + dataIndex: 'customerTotalPrice',
  52 + width: 50,
  53 + },
  54 + {
  55 + title: '发生扣款金额总计',
  56 + dataIndex: 'deductAmount',
  57 + width: 50,
  58 + },
  59 + {
  60 + title: '实际应收',
  61 + dataIndex: 'otherAmount',
  62 + width: 50,
  63 + },
  64 + {
  65 + title: '其他费用金额汇总',
  66 + dataIndex: 'otherTotalAmount',
  67 + width: 50,
  68 + },
  69 + ];
  70 + // const ids = ref<number[]>([]);
  71 + const ids = ref();
  72 + // const res = ref();
45 73
46 const [register, { closeModal }] = useModalInner(async (data) => { 74 const [register, { closeModal }] = useModalInner(async (data) => {
47 - Input2.value = getRefundDate(data.data);  
48 - console.log(Input2.value, 5656); 75 + ids.value = data.data;
  76 + setTimeout(() => {
  77 + reload();
  78 + }, 50);
49 }); 79 });
  80 + const [registerTable, { reload }] = useTable({
  81 + // api: () => invoiceAnalysis({ ids: ids.value }),
  82 + api: async () => {
  83 + const res = await invoiceAnalysis({ ids: ids.value });
  84 + const arrayRes = ref([]);
  85 + arrayRes.value.push(res);
  86 + console.log(res, 56561);
  87 + return arrayRes.value;
  88 + },
  89 + columns: columnsAnalysis,
  90 + bordered: true,
  91 + });
  92 + function handleShow(visible: boolean) {
  93 + reload();
  94 + }
  95 + const searchData = ref({});
50 async function handleOk() { 96 async function handleOk() {
  97 + // 构造符合 API 要求的参数
  98 + const idss = ids.value;
  99 + // await exportAnalysis({ ids: ids });
  100 + axios
  101 + .post(
  102 + '/basic-api/order/erp/invoice_bill/export',
  103 + { ids: idss },
  104 + {
  105 + responseType: 'blob', // 设置响应类型为 'blob'
  106 + },
  107 + )
  108 + .then((response) => {
  109 + // 创建一个 Blob 对象来保存二进制数据
  110 + const blob = new Blob([response.data], { type: 'application/zip' });
  111 + const getFormattedDate = (): string => {
  112 + const date = new Date();
  113 +
  114 + const year = date.getFullYear();
  115 + const month = String(date.getMonth() + 1).padStart(2, '0');
  116 + const day = String(date.getDate()).padStart(2, '0');
  117 +
  118 + const hours = String(date.getHours()).padStart(2, '0');
  119 + const minutes = String(date.getMinutes()).padStart(2, '0');
  120 + const seconds = String(date.getSeconds()).padStart(2, '0');
  121 +
  122 + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  123 + };
  124 + const date = getFormattedDate();
  125 + // 创建一个链接元素用于下载
  126 + const link = document.createElement('a');
  127 + link.href = window.URL.createObjectURL(blob);
  128 + link.download = `收款单分析${date}.xlsx`; // 你可以为文件命名
  129 + document.body.appendChild(link);
  130 + link.click(); // 自动点击链接,触发下载
  131 + console.log(link, 5656);
  132 + document.body.removeChild(link); // 下载完成后移除链接
  133 + })
  134 + .catch((error) => {
  135 + console.error(error);
  136 + });
51 closeModal(); 137 closeModal();
52 } 138 }
53 </script> 139 </script>
src/views/project/finance/receive/InvoiceDetail.vue
@@ -13,6 +13,9 @@ @@ -13,6 +13,9 @@
13 <BasicTable @register="registerTable"> 13 <BasicTable @register="registerTable">
14 <template #bodyCell="{ column, record }"> 14 <template #bodyCell="{ column, record }">
15 <template v-if="column.key === 'action'"> </template> 15 <template v-if="column.key === 'action'"> </template>
  16 + <template v-if="column.key === 'picUrl'">
  17 + <img :z-index="100000" :width="50" :height="50" :src="record?.smallPicUrl" />
  18 + </template>
16 </template> 19 </template>
17 </BasicTable> 20 </BasicTable>
18 </div> 21 </div>
@@ -31,22 +34,52 @@ @@ -31,22 +34,52 @@
31 { 34 {
32 title: '客户编码', 35 title: '客户编码',
33 dataIndex: 'customerCode', 36 dataIndex: 'customerCode',
34 - width: 50, 37 + width: 100,
35 }, 38 },
36 { 39 {
37 title: '项目号', 40 title: '项目号',
38 dataIndex: 'projectNo', 41 dataIndex: 'projectNo',
39 - width: 60, 42 + width: 100,
40 }, 43 },
41 { 44 {
42 title: '内部编码', 45 title: '内部编码',
43 dataIndex: 'innerNo', 46 dataIndex: 'innerNo',
44 - width: 60, 47 + width: 100,
45 }, 48 },
46 { 49 {
47 title: '客户po号', 50 title: '客户po号',
48 dataIndex: 'customerPo', 51 dataIndex: 'customerPo',
49 - width: 60, 52 + width: 100,
  53 + },
  54 + {
  55 + title: '客户STYLE',
  56 + width: 150,
  57 + dataIndex: 'customerStyle',
  58 + },
  59 + {
  60 + title: 'Model(REFERENCE)',
  61 + width: 150,
  62 + dataIndex: 'modeleLo',
  63 + },
  64 + {
  65 + title: '订单图片',
  66 + width: 150,
  67 + dataIndex: 'picUrl',
  68 + },
  69 + {
  70 + title: '数量',
  71 + width: 150,
  72 + dataIndex: 'orderCount',
  73 + },
  74 + {
  75 + title: '客户单价$',
  76 + width: 150,
  77 + dataIndex: 'orderCount',
  78 + },
  79 + {
  80 + title: '客户总价$',
  81 + width: 150,
  82 + dataIndex: 'orderCount',
50 }, 83 },
51 ]; 84 ];
52 const invoiceNo = ref(); 85 const invoiceNo = ref();
@@ -59,7 +92,10 @@ @@ -59,7 +92,10 @@
59 invoiceNo: invoiceNo.value, 92 invoiceNo: invoiceNo.value,
60 }); 93 });
61 const [registerTable] = useTable({ 94 const [registerTable] = useTable({
62 - api: () => getBaseInvoice({ invoiceNo: invoiceNo.value }), 95 + api: () => {
  96 + const res = getBaseInvoice({ invoiceNo: invoiceNo.value });
  97 + return res;
  98 + },
63 columns: columns, 99 columns: columns,
64 bordered: true, 100 bordered: true,
65 }); 101 });
src/views/project/finance/receive/TrackEdit.vue
@@ -26,10 +26,7 @@ @@ -26,10 +26,7 @@
26 :action="updateDeductUrl" 26 :action="updateDeductUrl"
27 @change="handleChange" 27 @change="handleChange"
28 > 28 >
29 - <a-button>  
30 - <!-- <upload-outlined></upload-outlined> -->  
31 - 上传扣款单  
32 - </a-button> 29 + <a-button> 上传扣款单 </a-button>
33 </a-upload> 30 </a-upload>
34 </a-space> 31 </a-space>
35 </div> 32 </div>
@@ -48,16 +45,17 @@ @@ -48,16 +45,17 @@
48 import type { UploadProps } from 'ant-design-vue'; 45 import type { UploadProps } from 'ant-design-vue';
49 import { updateDeduct } from '@/api/project/invoice'; 46 import { updateDeduct } from '@/api/project/invoice';
50 47
  48 + const emit = defineEmits(['success']);
51 const fileList = ref<UploadProps['fileList']>([]); 49 const fileList = ref<UploadProps['fileList']>([]);
52 50
53 - const input1 = ref(''); 51 + const input1 = ref();
54 const deductUrl = ref(); 52 const deductUrl = ref();
55 const id = ref(); 53 const id = ref();
56 const invoiceNo = ref(); 54 const invoiceNo = ref();
  55 + const uploadUrl = ref('http://47.104.8.35:18000/api/localStorage/upload_file_oss?name=');
57 const updateDeductUrl = ref('http://47.104.8.35:18000/api/localStorage/upload_file_oss?name='); 56 const updateDeductUrl = ref('http://47.104.8.35:18000/api/localStorage/upload_file_oss?name=');
58 57
59 const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => { 58 const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => {
60 - console.log(data, 56561);  
61 id.value = data.data.id; 59 id.value = data.data.id;
62 invoiceNo.value = data.data.invoiceNo; 60 invoiceNo.value = data.data.invoiceNo;
63 input1.value = data.data.deductAmount; 61 input1.value = data.data.deductAmount;
@@ -66,21 +64,31 @@ @@ -66,21 +64,31 @@
66 64
67 function handleChange(info) { 65 function handleChange(info) {
68 if (info.file.status == 'done') { 66 if (info.file.status == 'done') {
69 - updateDeductUrl.value = info.file.response.data.deductUrl; 67 + updateDeductUrl.value = info.file.response.data.fileUrl;
70 deductUrl.value = updateDeductUrl.value; 68 deductUrl.value = updateDeductUrl.value;
71 } 69 }
72 } 70 }
73 function beforeUpload(info) { 71 function beforeUpload(info) {
74 - updateDeductUrl.value += info.name; 72 + updateDeductUrl.value = uploadUrl.value + info.name;
75 } 73 }
76 74
77 //完成编辑 75 //完成编辑
78 async function handleSubmit() { 76 async function handleSubmit() {
  77 + const requestData = {
  78 + id: id.value,
  79 + invoiceNo: invoiceNo.value,
  80 + deductAmount: input1.value,
  81 + deductUrl: deductUrl.value,
  82 + };
79 await updateDeduct({ 83 await updateDeduct({
80 id: id.value, 84 id: id.value,
81 invoiceNo: invoiceNo.value, 85 invoiceNo: invoiceNo.value,
82 deductAmount: input1.value, 86 deductAmount: input1.value,
83 deductUrl: deductUrl.value, 87 deductUrl: deductUrl.value,
84 }); 88 });
  89 + // await updateDeduct(requestData);
  90 + fileList.value = [];
  91 + emit('success');
  92 + closeDrawer();
85 } 93 }
86 </script> 94 </script>
src/views/project/finance/receive/index.vue
@@ -3,9 +3,9 @@ @@ -3,9 +3,9 @@
3 <BasicTable @register="registerTable"> 3 <BasicTable @register="registerTable">
4 <template #toolbar> 4 <template #toolbar>
5 <a-button type="primary" @click="handleInvoiceAnalysis">收款单分析</a-button> 5 <a-button type="primary" @click="handleInvoiceAnalysis">收款单分析</a-button>
6 - <FinanceEdit @register="registerFinanceEdit" /> 6 + <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" />
7 <InvoiceAnalysis @register="registerInvoiceAnalysis" /> 7 <InvoiceAnalysis @register="registerInvoiceAnalysis" />
8 - <TrackEdit @register="registerTrackEdit" /> 8 + <TrackEdit @register="registerTrackEdit" @success="handleSuccess" />
9 <InvoiceDetail @register="registerInvoiceDetail" /> 9 <InvoiceDetail @register="registerInvoiceDetail" />
10 </template> 10 </template>
11 <template #bodyCell="{ column, record }"> 11 <template #bodyCell="{ column, record }">
@@ -42,7 +42,7 @@ @@ -42,7 +42,7 @@
42 </div> 42 </div>
43 </template> 43 </template>
44 <script lang="ts" setup> 44 <script lang="ts" setup>
45 - import { defineComponent } from 'vue'; 45 + import { computed, defineComponent, ref } from 'vue';
46 import { BasicTable, useTable, BasicColumn, TableAction } from '/@/components/Table'; 46 import { BasicTable, useTable, BasicColumn, TableAction } from '/@/components/Table';
47 import { searchFormSchema, columns } from './receive.data'; 47 import { searchFormSchema, columns } from './receive.data';
48 import FinanceEdit from './FinanceEdit.vue'; 48 import FinanceEdit from './FinanceEdit.vue';
@@ -50,25 +50,37 @@ @@ -50,25 +50,37 @@
50 import InvoiceAnalysis from './InvoiceAnalysis.vue'; 50 import InvoiceAnalysis from './InvoiceAnalysis.vue';
51 import InvoiceDetail from './InvoiceDetail.vue'; 51 import InvoiceDetail from './InvoiceDetail.vue';
52 import { useDrawer } from '/@/components/Drawer'; 52 import { useDrawer } from '/@/components/Drawer';
53 - import { getInvoice, deleteInvoice, commit } from '@/api/project/invoice'; 53 + import { getInvoice, deleteInvoice, commit, getBaseInvoice } from '@/api/project/invoice';
54 import { useModal } from '/@/components/Modal'; 54 import { useModal } from '/@/components/Modal';
55 import { FilePptOutlined } from '@ant-design/icons-vue'; 55 import { FilePptOutlined } from '@ant-design/icons-vue';
56 import { icon } from 'ant-design-vue'; 56 import { icon } from 'ant-design-vue';
  57 + import { ROLE } from './type.d';
  58 + import { useUserStoreWithOut } from '/@/store/modules/user';
  59 + import { useMessage } from '/@/hooks/web/useMessage';
57 60
58 const [registerInvoiceAnalysis, { openModal: openInvoiceAnalysis }] = useModal(); 61 const [registerInvoiceAnalysis, { openModal: openInvoiceAnalysis }] = useModal();
59 62
60 const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); 63 const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer();
61 const [registerTrackEdit, { openDrawer: openTrackEdit }] = useDrawer(); 64 const [registerTrackEdit, { openDrawer: openTrackEdit }] = useDrawer();
62 const [registerInvoiceDetail, { openDrawer: openInvoiceDetail }] = useDrawer(); 65 const [registerInvoiceDetail, { openDrawer: openInvoiceDetail }] = useDrawer();
63 -  
64 - const [registerTable] = useTable({ 66 + const checkedKeys = ref<Array<string | number>>([]);
  67 + const userStore = useUserStoreWithOut();
  68 + const user = userStore.getUserInfo;
  69 + const role = computed(() => {
  70 + return user?.roleSmallVO?.code;
  71 + });
  72 + const [registerTable, { reload }] = useTable({
65 title: '', 73 title: '',
66 api: getInvoice, 74 api: getInvoice,
67 columns: columns, 75 columns: columns,
68 bordered: true, 76 bordered: true,
  77 + clickToRowSelect: false,
69 rowKey: 'id', 78 rowKey: 'id',
70 rowSelection: { 79 rowSelection: {
71 type: 'checkbox', 80 type: 'checkbox',
  81 + selectedRowKeys: checkedKeys,
  82 + onSelect,
  83 + onSelectAll,
72 }, 84 },
73 formConfig: { 85 formConfig: {
74 labelWidth: 120, 86 labelWidth: 120,
@@ -88,6 +100,98 @@ @@ -88,6 +100,98 @@
88 // slots: { customRender: 'action' }, 100 // slots: { customRender: 'action' },
89 }, 101 },
90 }); 102 });
  103 +
  104 + type CustomerCodeEntry = [string, number]; // 定义二维数组类型 [customerCode, count]
  105 +
  106 + const selectedCustomCodes = ref<CustomerCodeEntry[]>([]); // 创建一个二维数组的 ref
  107 +
  108 + // 选择函数
  109 + async function onSelect(record: any, selected: boolean) {
  110 + if (selected) {
  111 + const res = await getBaseInvoice({ invoiceNo: record.invoiceNo });
  112 + const customerCode = res[0].customerCode;
  113 +
  114 + const index = selectedCustomCodes.value.findIndex(([code]) => code === customerCode);
  115 +
  116 + if (index !== -1) {
  117 + // 如果存在,增加计数
  118 + selectedCustomCodes.value[index][1] += 1;
  119 + } else {
  120 + // 如果不存在,添加新项 [customerCode, 1]
  121 + selectedCustomCodes.value.push([customerCode, 1]);
  122 + }
  123 +
  124 + checkedKeys.value = [...checkedKeys.value, record.id];
  125 + } else {
  126 + const res = await getBaseInvoice({ invoiceNo: record.invoiceNo });
  127 + const customerCode = res[0].customerCode;
  128 +
  129 + const index = selectedCustomCodes.value.findIndex(([code]) => code === customerCode);
  130 +
  131 + if (index !== -1) {
  132 + if (selectedCustomCodes.value[index][1] > 1) {
  133 + // 如果计数大于 1,减少计数
  134 + selectedCustomCodes.value[index][1] -= 1;
  135 + } else {
  136 + // 如果计数为 1,移除该项
  137 + selectedCustomCodes.value.splice(index, 1);
  138 + }
  139 + }
  140 +
  141 + checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id);
  142 + }
  143 + console.log(selectedCustomCodes.value, 56561);
  144 + console.log(checkedKeys.value, 56562);
  145 + }
  146 +
  147 + async function onSelectAll(selected: boolean, selectedRows: any[], changeRows: any[]) {
  148 + const changeIds = changeRows.map((item) => item.id);
  149 + const changeCustomerCodes = await Promise.all(
  150 + changeRows.map(async (item) => {
  151 + const res = await getBaseInvoice({ invoiceNo: item.invoiceNo });
  152 + return res[0].customerCode;
  153 + }),
  154 + );
  155 +
  156 + if (selected) {
  157 + // 添加到 checkedKeys
  158 + checkedKeys.value = [...checkedKeys.value, ...changeIds];
  159 +
  160 + // 处理每个 customerCode
  161 + changeCustomerCodes.forEach((code) => {
  162 + const index = selectedCustomCodes.value.findIndex(
  163 + ([customerCode]) => customerCode === code,
  164 + );
  165 + if (index !== -1) {
  166 + // 如果存在,增加计数
  167 + selectedCustomCodes.value[index][1] += 1;
  168 + } else {
  169 + // 如果不存在,添加新项 [customerCode, 1]
  170 + selectedCustomCodes.value.push([code, 1]);
  171 + }
  172 + });
  173 + } else {
  174 + // 从 checkedKeys 中移除
  175 + checkedKeys.value = checkedKeys.value.filter((id) => !changeIds.includes(id));
  176 +
  177 + // 处理每个 customerCode
  178 + changeCustomerCodes.forEach((code) => {
  179 + const index = selectedCustomCodes.value.findIndex(
  180 + ([customerCode]) => customerCode === code,
  181 + );
  182 + if (index !== -1) {
  183 + if (selectedCustomCodes.value[index][1] > 1) {
  184 + // 如果计数大于 1,减少计数
  185 + selectedCustomCodes.value[index][1] -= 1;
  186 + } else {
  187 + // 如果计数为 1,移除该项
  188 + selectedCustomCodes.value.splice(index, 1);
  189 + }
  190 + }
  191 + });
  192 + }
  193 + }
  194 +
91 function handleFinanceEdit(record) { 195 function handleFinanceEdit(record) {
92 openFinanceEdit(true, { 196 openFinanceEdit(true, {
93 data: record, 197 data: record,
@@ -101,18 +205,40 @@ @@ -101,18 +205,40 @@
101 function handleDelete(record) { 205 function handleDelete(record) {
102 const id: string[] = Array.isArray(record.id) ? record.id : [record.id]; 206 const id: string[] = Array.isArray(record.id) ? record.id : [record.id];
103 deleteInvoice({ ids: id }); 207 deleteInvoice({ ids: id });
  208 + setTimeout(() => {
  209 + reload();
  210 + }, 50);
104 } 211 }
105 function handleCommit(record) { 212 function handleCommit(record) {
106 commit({ id: record.id }); 213 commit({ id: record.id });
  214 + setTimeout(() => {
  215 + reload();
  216 + }, 50);
107 } 217 }
108 function handleInvoiceDetail(record) { 218 function handleInvoiceDetail(record) {
109 openInvoiceDetail(true, { 219 openInvoiceDetail(true, {
110 data: record, 220 data: record,
111 }); 221 });
112 } 222 }
  223 + const { createMessage } = useMessage();
  224 + const { error } = createMessage;
113 function handleInvoiceAnalysis(record) { 225 function handleInvoiceAnalysis(record) {
  226 + if (checkedKeys.value.length == 0) {
  227 + error('请选择订单');
  228 + return;
  229 + }
  230 + if (selectedCustomCodes.value.length > 1) {
  231 + error('勾选订单的客户编码需一致');
  232 + return;
  233 + }
114 openInvoiceAnalysis(true, { 234 openInvoiceAnalysis(true, {
115 - data: record, 235 + data: checkedKeys.value,
116 }); 236 });
117 } 237 }
  238 +
  239 + function handleSuccess() {
  240 + setTimeout(() => {
  241 + reload();
  242 + }, 50);
  243 + }
118 </script> 244 </script>
src/views/project/finance/receive/receive.data.tsx
@@ -7,16 +7,33 @@ import { ref } from &#39;vue&#39;; @@ -7,16 +7,33 @@ import { ref } from &#39;vue&#39;;
7 7
8 export const searchFormSchema: FormSchema[] = [ 8 export const searchFormSchema: FormSchema[] = [
9 { 9 {
10 - field: 'invoice', 10 + field: 'invoiceNo',
11 label: 'Invoice编号', 11 label: 'Invoice编号',
12 - component: 'Select',  
13 - colProps: { span: 8 }, 12 + component: 'Input',
  13 + colProps: { span: 6 },
14 }, 14 },
15 { 15 {
16 - field: 'nickName', 16 + field: 'status',
17 label: '总经理审核', 17 label: '总经理审核',
  18 + component: 'Select',
  19 + colProps: { span: 6 },
  20 + componentProps: {
  21 + options: [
  22 + { label: '未提交审核', value: -1 },
  23 + { label: '待审核', value: 0 },
  24 + { label: '审核通过', value: 1 },
  25 + { label: '审核驳回', value: 2 },
  26 + ],
  27 + },
  28 + },
  29 + {
  30 + field: 'customerCode',
  31 + label: '客户编码',
18 component: 'Input', 32 component: 'Input',
19 - colProps: { span: 8 }, 33 + colProps: {
  34 + span: 6,
  35 + },
  36 + // labelWidth: 140,
20 }, 37 },
21 ]; 38 ];
22 39
@@ -51,6 +68,9 @@ export const columns: BasicColumn[] = [ @@ -51,6 +68,9 @@ export const columns: BasicColumn[] = [
51 width: 80, 68 width: 80,
52 customRender: (column) => { 69 customRender: (column) => {
53 const deductUrl = column.record.deductUrl; 70 const deductUrl = column.record.deductUrl;
  71 + if (deductUrl == undefined) {
  72 + return;
  73 + }
54 return <FilePptOutlined style="font-size:25px" onClick={() => window.open(deductUrl)} />; 74 return <FilePptOutlined style="font-size:25px" onClick={() => window.open(deductUrl)} />;
55 }, 75 },
56 }, 76 },
@@ -96,3 +116,45 @@ export const columns: BasicColumn[] = [ @@ -96,3 +116,45 @@ export const columns: BasicColumn[] = [
96 }, 116 },
97 }, 117 },
98 ]; 118 ];
  119 +
  120 +export const columnsAnalysis: BasicColumn[] = [
  121 + {
  122 + title: '实际应付金额总计',
  123 + dataIndex: 'actualPayedAmount',
  124 + width: 50,
  125 + // customRender: (column) => {
  126 + // console.log(column, 5656666);
  127 + // return 1;
  128 + // },
  129 + },
  130 + {
  131 + title: '实际应收金额总计',
  132 + dataIndex: 'actualReceivableAmount',
  133 + width: 50,
  134 + },
  135 + {
  136 + title: '客户总价',
  137 + dataIndex: 'customerTotalPrice',
  138 + width: 50,
  139 + },
  140 + {
  141 + title: '发生扣款金额总计',
  142 + dataIndex: 'deductAmount',
  143 + width: 50,
  144 + },
  145 + {
  146 + title: '实际应收金额总计',
  147 + dataIndex: 'actualReceivableAmount',
  148 + width: 50,
  149 + },
  150 + {
  151 + title: '实际应收',
  152 + dataIndex: 'otherAmount',
  153 + width: 50,
  154 + },
  155 + {
  156 + title: '其他费用金额汇总',
  157 + dataIndex: 'otherTotalAmount',
  158 + width: 50,
  159 + },
  160 +];
src/views/project/finance/receive/type.d.ts 0 → 100644
  1 +export enum ROLE {
  2 + ADMIN = 'admin', // 超管
  3 + CUSTOM_ADMIN = 'custom_admin', // 客户管理员
  4 + DATA_REPORT_USER = 'data_report_user', //数据分析员
  5 + BUSINESS = 'business_user', // 业务员
  6 + TRACKER = 'tracker_user', // 跟单员
  7 + INSPECT = 'inspect_user', // 质检员
  8 + PRODUCE = 'produce_user', //生产科
  9 +}
src/views/project/order/ExportModal.vue
@@ -162,7 +162,6 @@ @@ -162,7 +162,6 @@
162 //导出选中的订单 162 //导出选中的订单
163 fieldVO.orderIds = props.ids; 163 fieldVO.orderIds = props.ids;
164 exportLoading.value = true; 164 exportLoading.value = true;
165 - console.log(fieldVO, 5656);  
166 await orderExport({ ...searchData.value, fieldVO }); 165 await orderExport({ ...searchData.value, fieldVO });
167 exportLoading.value = false; 166 exportLoading.value = false;
168 167
src/views/project/order/FormDetail/index.vue
@@ -324,10 +324,10 @@ @@ -324,10 +324,10 @@
324 trackFormPanelRef?.value?.setFieldsValue({ 324 trackFormPanelRef?.value?.setFieldsValue({
325 ...toRaw(data.trackStageInfo), 325 ...toRaw(data.trackStageInfo),
326 }); 326 });
327 - ppUpdate.value = data.trackStageInfo.ppConfirmResult;  
328 - shipUpdate.value = data.trackStageInfo.shippmentSampleConfirmTime;  
329 - altexUpdate.value = data.trackStageInfo.aitexTestFinishTime;  
330 - sgsUpdate.value = data.trackStageInfo.sgsTestFinishTime; 327 + ppUpdate.value = data?.trackStageInfo?.ppConfirmResult;
  328 + shipUpdate.value = data?.trackStageInfo?.shippmentSampleConfirmTime;
  329 + altexUpdate.value = data?.trackStageInfo?.aitexTestFinishTime;
  330 + sgsUpdate.value = data?.trackStageInfo?.sgsTestFinishTime;
331 } 331 }
332 332
333 if (inspectionFormPanelRef.value) { 333 if (inspectionFormPanelRef.value) {
@@ -408,19 +408,30 @@ @@ -408,19 +408,30 @@
408 forms.inspectionStageInfo = inspectionFormPanelRef?.value?.getFieldsValue() || {}; 408 forms.inspectionStageInfo = inspectionFormPanelRef?.value?.getFieldsValue() || {};
409 } 409 }
410 //跟单信息标记 410 //跟单信息标记
411 - if (forms.trackStageInfo.ppConfirmResult !== ppUpdate.value) { 411 + if (
  412 + forms.trackStageInfo?.ppConfirmResult !== undefined &&
  413 + forms.trackStageInfo?.ppConfirmResult !== ppUpdate.value
  414 + ) {
412 forms.trackStageInfo.ppConfirmTime = getFormattedDate(); 415 forms.trackStageInfo.ppConfirmTime = getFormattedDate();
413 } 416 }
414 - if (forms.trackStageInfo.shippmentSampleConfirmResult !== shipUpdate.value) { 417 + if (
  418 + forms.trackStageInfo?.shippmentSampleConfirmResult !== undefined &&
  419 + forms.trackStageInfo?.shippmentSampleConfirmResult !== shipUpdate.value
  420 + ) {
415 forms.trackStageInfo.shippmentSampleConfirmTime = getFormattedDate(); 421 forms.trackStageInfo.shippmentSampleConfirmTime = getFormattedDate();
416 } 422 }
417 - if (forms.trackStageInfo.aitexTestFinishResult !== altexUpdate.value) { 423 + if (
  424 + forms.trackStageInfo?.aitexTestFinishResult !== altexUpdate.value &&
  425 + forms.trackStageInfo?.aitexTestFinishResult !== undefined
  426 + ) {
418 forms.trackStageInfo.aitexTestFinishTime = getFormattedDate(); 427 forms.trackStageInfo.aitexTestFinishTime = getFormattedDate();
419 } 428 }
420 - if (forms.trackStageInfo.sgsTestFinishResult !== sgsUpdate.value) { 429 + if (
  430 + forms.trackStageInfo?.sgsTestFinishResult !== sgsUpdate.value &&
  431 + forms.trackStageInfo?.sgsTestFinishResult !== undefined
  432 + ) {
421 forms.trackStageInfo.sgsTestFinishTime = getFormattedDate(); 433 forms.trackStageInfo.sgsTestFinishTime = getFormattedDate();
422 } 434 }
423 - // console.log(forms.trackStageInfo, 5656);  
424 await orderUpdate(forms); 435 await orderUpdate(forms);
425 closeDrawer(); 436 closeDrawer();
426 emit('success', {}); 437 emit('success', {});
@@ -440,6 +451,9 @@ @@ -440,6 +451,9 @@
440 }; 451 };
441 await orderCreate(forms); 452 await orderCreate(forms);
442 closeDrawer(); 453 closeDrawer();
  454 + setTimeout(() => {
  455 + reload();
  456 + }, 50);
443 emit('success', {}); 457 emit('success', {});
444 } 458 }
445 } catch (error) { 459 } catch (error) {
src/views/project/order/InvoiceCreate.vue
@@ -32,7 +32,7 @@ @@ -32,7 +32,7 @@
32 import { BasicModal, useModalInner } from '@/components/Modal'; 32 import { BasicModal, useModalInner } from '@/components/Modal';
33 import { computed, ref } from 'vue'; 33 import { computed, ref } from 'vue';
34 import type { UploadProps } from 'ant-design-vue'; 34 import type { UploadProps } from 'ant-design-vue';
35 - import { getRefundDate, getInvoice } from '@/api/project/invoice'; 35 + import { getRefundDate, getInvoice, createInvoice } from '@/api/project/invoice';
36 36
37 const fileList = ref<UploadProps['fileList']>([]); 37 const fileList = ref<UploadProps['fileList']>([]);
38 38
@@ -43,13 +43,14 @@ @@ -43,13 +43,14 @@
43 const orderIds = ref(); 43 const orderIds = ref();
44 44
45 const [register, { closeModal }] = useModalInner(async (data) => { 45 const [register, { closeModal }] = useModalInner(async (data) => {
46 - const res = getRefundDate(data.data);  
47 - Input2.value = res.data; 46 + const ids = data.data;
  47 + const res = await getRefundDate({ orderIds: ids });
  48 + Input2.value = res;
48 orderIds.value = data.data; 49 orderIds.value = data.data;
49 }); 50 });
50 // const title = ref(''); 51 // const title = ref('');
51 async function handleOk() { 52 async function handleOk() {
52 - await getInvoice({ 53 + await createInvoice({
53 invoiceNo: Input1.value, 54 invoiceNo: Input1.value,
54 bgUrl: bgUrl.value, 55 bgUrl: bgUrl.value,
55 backRefundDate: Input2.value, 56 backRefundDate: Input2.value,
@@ -59,7 +60,7 @@ @@ -59,7 +60,7 @@
59 } 60 }
60 function handleChange(info) { 61 function handleChange(info) {
61 if (info.file.status == 'done') { 62 if (info.file.status == 'done') {
62 - bgUrl.value = info.file.response.data; 63 + bgUrl.value = info.file.response.data.fileUrl;
63 } 64 }
64 } 65 }
65 function beforeUpload(info) { 66 function beforeUpload(info) {
src/views/project/order/PassCalculate.vue
@@ -7,37 +7,32 @@ @@ -7,37 +7,32 @@
7 :bodyStyle="{ height: '100px' }" 7 :bodyStyle="{ height: '100px' }"
8 @ok="handleOk" 8 @ok="handleOk"
9 > 9 >
10 - <div style="margin-left: 10px; font-size: 16px">一次通过率:{{ result }}</div> 10 + <div style="margin-left: 10px; font-size: 16px">一次通过率:{{ num }}</div>
11 </BasicModal> 11 </BasicModal>
12 </template> 12 </template>
13 <script lang="ts" setup> 13 <script lang="ts" setup>
14 import { BasicModal, useModalInner } from '@/components/Modal'; 14 import { BasicModal, useModalInner } from '@/components/Modal';
15 import { computed, ref } from 'vue'; 15 import { computed, ref } from 'vue';
  16 + import { passCalculate } from '@/api/project/order';
16 17
17 const [register, { closeModal }] = useModalInner(async (data) => { 18 const [register, { closeModal }] = useModalInner(async (data) => {
18 - console.log(data, 56562);  
19 title.value = data.title; 19 title.value = data.title;
  20 + const id = data.check[0];
  21 + const opinionType = ref();
  22 + if (data.title == '确认意见') {
  23 + opinionType.value = 'pp样品确认意见';
  24 + } else if (data.title == '生产样品') {
  25 + opinionType.value = 'shipment sample确认意见';
  26 + } else if (data.title == '测试样品') {
  27 + opinionType.value = 'Altex测试结果';
  28 + }
  29 + num.value = await passCalculate({ orderId: id, opinionType: opinionType.value });
20 }); 30 });
21 const title = ref(''); 31 const title = ref('');
22 - const result = computed(() => {  
23 - const res = 1234;  
24 - return res;  
25 - });  
26 - // onMounted(async () => {  
27 - // // 获取包装费用和客户编码的关联关系  
28 - // const res = await getConfigList({  
29 - // page: 1,  
30 - // pageSize: 1000,  
31 - // // relationCode: 'packetPrice',  
32 - // });  
33 -  
34 - // configList.value = res?.items || [];  
35 -  
36 - // // 获取业务员  
37 - // const res1 = await getUserList({ page: 1, pageSize: 1000 });  
38 - // businessUsers.value = res1.items 32 + const num = ref();
39 33
40 async function handleOk() { 34 async function handleOk() {
41 closeModal(); 35 closeModal();
  36 + num.value = '';
42 } 37 }
43 </script> 38 </script>
src/views/project/order/ProductInvoice.vue
@@ -38,16 +38,22 @@ @@ -38,16 +38,22 @@
38 <script lang="ts" setup> 38 <script lang="ts" setup>
39 import { BasicModal, useModalInner } from '@/components/Modal'; 39 import { BasicModal, useModalInner } from '@/components/Modal';
40 import { computed, ref } from 'vue'; 40 import { computed, ref } from 'vue';
41 - import { getRefundDate } from '@/api/project/invoice'; 41 + import { payDate, checkCreate } from '@/api/project/invoice';
42 42
43 const Input1 = ref(''); 43 const Input1 = ref('');
44 const Input2 = ref(); 44 const Input2 = ref();
45 - 45 + const res = ref();
46 const [register, { closeModal }] = useModalInner(async (data) => { 46 const [register, { closeModal }] = useModalInner(async (data) => {
47 - Input2.value = getRefundDate(data.data);  
48 - console.log(Input2.value, 5656); 47 + res.value = data.data;
  48 + Input2.value = await payDate({ orderIds: res.value });
  49 + console.log(Input2.value, 565656);
49 }); 50 });
50 async function handleOk() { 51 async function handleOk() {
  52 + await checkCreate({
  53 + orderIds: res.value,
  54 + payedDate: Input2.value,
  55 + checkNo: Input1.value,
  56 + });
51 closeModal(); 57 closeModal();
52 } 58 }
53 </script> 59 </script>
src/views/project/order/ProductText.vue
@@ -50,7 +50,7 @@ @@ -50,7 +50,7 @@
50 </BasicModal> 50 </BasicModal>
51 </template> 51 </template>
52 <script lang="ts"> 52 <script lang="ts">
53 - import { defineComponent, ref, computed } from 'vue'; 53 + import { defineComponent, ref, computed, onMounted, onUpdated } from 'vue';
54 import { BasicModal, useModalInner } from '/@/components/Modal'; 54 import { BasicModal, useModalInner } from '/@/components/Modal';
55 import { RadioGroup } from 'ant-design-vue'; 55 import { RadioGroup } from 'ant-design-vue';
56 import { EyeOutlined, FilePptOutlined } from '@ant-design/icons-vue'; 56 import { EyeOutlined, FilePptOutlined } from '@ant-design/icons-vue';
@@ -74,7 +74,12 @@ @@ -74,7 +74,12 @@
74 const isShow1 = ref(true); //选择公司页面 74 const isShow1 = ref(true); //选择公司页面
75 const isShow2 = ref(false); //生成PDF页面 75 const isShow2 = ref(false); //生成PDF页面
76 const pdf = ref(['/pdf.png']); 76 const pdf = ref(['/pdf.png']);
77 - const [register, { setModalProps, closeModal }] = useModalInner(async (data) => {}); 77 + const [register, { setModalProps, closeModal }] = useModalInner(async (data) => {
  78 + // if (data.customers.length == 0) {
  79 + // error('请选择订单');
  80 + // closeModal();
  81 + // }
  82 + });
78 const options = computed(() => { 83 const options = computed(() => {
79 // 运营总监-基本信息,跟单,质检 84 // 运营总监-基本信息,跟单,质检
80 return [ 85 return [
@@ -114,27 +119,29 @@ @@ -114,27 +119,29 @@
114 isShow2.value = false; 119 isShow2.value = false;
115 } 120 }
116 } 121 }
117 - //判断选择公司与客户编码是否对应  
118 - function validateCustomerCodes(customerCodes: string[], chooseCompany: string): boolean {  
119 - for (const code of customerCodes) {  
120 - const expectedCompanyValue = customerCodeToCompanyMap[code];  
121 - if (expectedCompanyValue === undefined) {  
122 - // 如果代码不在映射中,不需要对应公司 122 + function validateCompany(selectedCodes: any, company: string): boolean {
  123 + for (const [customerCode] of selectedCodes) {
  124 + const mappedCompany = customerCodeToCompanyMap[customerCode];
  125 +
  126 + if (mappedCompany === undefined) {
  127 + // 如果 customerCode 不在 customerCodeToCompanyMap 中,跳过
  128 + console.warn(`Customer code ${customerCode} not found in the mapping, skipping.`);
123 continue; 129 continue;
124 } 130 }
125 - if (customerCodeToCompanyMap[code] !== chooseCompany) {  
126 - // 如果属于 customerCodes 的值与其公司不匹配,返回 false 131 +
  132 + if (mappedCompany !== company) {
  133 + // 如果有一个不匹配,返回 false
127 return false; 134 return false;
128 } 135 }
129 } 136 }
130 - return true; // 如果所有 customerCodes 内的代码正确匹配,返回 true 137 + // 如果所有匹配,返回 true
  138 + return true;
131 } 139 }
132 //生成pdf 140 //生成pdf
133 // const customerCodeList: string[] = props.customerCodes; 141 // const customerCodeList: string[] = props.customerCodes;
134 function handleProduct() { 142 function handleProduct() {
135 - const customerCodeList: string[] = props.customerCodes;  
136 - const areValid = validateCustomerCodes(customerCodeList, choose.value);  
137 - console.log(customerCodeList, 5656, props.customerCodes); 143 + const customerCodeList = props.customerCodes;
  144 + const areValid = validateCompany(customerCodeList, choose.value);
138 //如果选错了,弹出提示 145 //如果选错了,弹出提示
139 if (!areValid) { 146 if (!areValid) {
140 error('勾选订单与选择的公司不匹配'); 147 error('勾选订单与选择的公司不匹配');
src/views/project/order/TrackHistory.vue
@@ -21,10 +21,10 @@ @@ -21,10 +21,10 @@
21 </template> 21 </template>
22 <template #description> 22 <template #description>
23 <div class="description"> 23 <div class="description">
24 - {{ item.modifyTime }} 24 + {{ item.showOpinionType }}
25 </div> 25 </div>
26 <div class="info"> 26 <div class="info">
27 - <!-- <div><span>操作时间:</span>{{ formatToDateTime(item.createTime) }}</div> --> 27 + <div>操作时间:{{ item.modifyTime }}</div>
28 </div> 28 </div>
29 </template> 29 </template>
30 </a-list-item-meta> 30 </a-list-item-meta>
@@ -54,20 +54,43 @@ @@ -54,20 +54,43 @@
54 const orderId = ref(''); 54 const orderId = ref('');
55 // const activeKey = ref(1); 55 // const activeKey = ref(1);
56 56
  57 + function removeTFromTimestamp(timestamp: string): string {
  58 + // 使用 replace 方法将 "T" 替换为空字符串
  59 + return timestamp.replace('T', ' ');
  60 + }
  61 +
57 const getOrderOptLogFunc = async (data, page) => { 62 const getOrderOptLogFunc = async (data, page) => {
58 console.log('%c [ data ]-135', 'font-size:13px; background:pink; color:#bf2c9f;', data); 63 console.log('%c [ data ]-135', 'font-size:13px; background:pink; color:#bf2c9f;', data);
59 const res = await trackHistory({ orderId: data, page: page, pageSize: 20 }); 64 const res = await trackHistory({ orderId: data, page: page, pageSize: 20 });
60 list1.value = res; 65 list1.value = res;
61 - // total1.value = res.total;  
62 - // page1.value = page; 66 + for (const item of list1.value) {
  67 + item.modifyTime = removeTFromTimestamp(item.modifyTime);
  68 + item.showOpinionType = modifyConfirmResult(item.field, item.modifyTime);
  69 + }
63 }; 70 };
64 const [register] = useDrawerInner((data) => { 71 const [register] = useDrawerInner((data) => {
65 - console.log(data, 5656);  
66 orderId.value = data.id; 72 orderId.value = data.id;
67 // const res = await trackHistory({ orderId: data, page: page, pageSize: 20 }); 73 // const res = await trackHistory({ orderId: data, page: page, pageSize: 20 });
68 getOrderOptLogFunc(orderId.value, 1); 74 getOrderOptLogFunc(orderId.value, 1);
69 }); 75 });
  76 + function modifyConfirmResult(Result: string, Time: string): string {
  77 + // 获取 Time 的日期部分,去掉时间
  78 + let datePart = Time.split(' ')[0]; // 获取日期部分
  79 + datePart += ' ';
  80 + // 找到第一个"."的位置
  81 + const dotIndex = Result.indexOf('.');
70 82
  83 + // 如果找到了".",则进行拼接
  84 + if (dotIndex !== -1) {
  85 + // 生成新的结果
  86 + const modifiedResult = `${Result.slice(0, dotIndex + 1)}${datePart}${Result.slice(
  87 + dotIndex + 1,
  88 + )}`;
  89 + return modifiedResult;
  90 + }
  91 + // 如果没有找到".",直接返回原始字符串
  92 + return Result;
  93 + }
71 const pagination1 = computed(() => { 94 const pagination1 = computed(() => {
72 return { 95 return {
73 show: true, 96 show: true,
src/views/project/order/index.vue
@@ -31,32 +31,36 @@ @@ -31,32 +31,36 @@
31 <template #bodyCell="{ column, record }"> 31 <template #bodyCell="{ column, record }">
32 <template v-if="column.key === 'action'"> 32 <template v-if="column.key === 'action'">
33 <TableAction 33 <TableAction
34 - :actions="[  
35 - {  
36 - // 数据分析没有编辑权限  
37 - ...(role !== ROLE.DATA_REPORT_USER && {  
38 - label: '编辑',  
39 - // icon: 'ic:outline-delete-outline',  
40 - onClick: handleEdit.bind(null, record),  
41 - }),  
42 - },  
43 - {  
44 - ...(role !== ROLE.DATA_REPORT_USER && {  
45 - label: '申请权限',  
46 - // icon: 'ic:outline-delete-outline',  
47 - onClick: handleCheck.bind(null, record),  
48 - }),  
49 - },  
50 - // {  
51 - // ...(role !== ROLE.DATA_REPORT_USER && {  
52 - // label: '申请',  
53 - // // icon: 'ic:outline-delete-outline',  
54 - // onClick: handleCheck.bind(null, record),  
55 - // }),  
56 - // },  
57 - ]" 34 + :actions="
  35 + role !== ROLE.PRODUCE
  36 + ? [
  37 + {
  38 + // 数据分析没有编辑权限
  39 + ...(role !== ROLE.DATA_REPORT_USER && {
  40 + label: '编辑',
  41 + // icon: 'ic:outline-delete-outline',
  42 + onClick: handleEdit.bind(null, record),
  43 + }),
  44 + },
  45 + {
  46 + ...(role !== ROLE.DATA_REPORT_USER && {
  47 + label: '申请权限',
  48 + // icon: 'ic:outline-delete-outline',
  49 + onClick: handleCheck.bind(null, record),
  50 + }),
  51 + },
  52 + // {
  53 + // ...(role !== ROLE.DATA_REPORT_USER && {
  54 + // label: '申请',
  55 + // // icon: 'ic:outline-delete-outline',
  56 + // onClick: handleCheck.bind(null, record),
  57 + // }),
  58 + // },
  59 + ]
  60 + : []
  61 + "
58 :dropDownActions=" 62 :dropDownActions="
59 - role !== ROLE.DATA_REPORT_USER 63 + role !== ROLE.DATA_REPORT_USER && role !== ROLE.PRODUCE
60 ? [ 64 ? [
61 { 65 {
62 label: '历史记录', 66 label: '历史记录',
@@ -120,9 +124,10 @@ @@ -120,9 +124,10 @@
120 @change="handleChange" 124 @change="handleChange"
121 class="passCalculate" 125 class="passCalculate"
122 dropdown-class-name="dropdown-class" 126 dropdown-class-name="dropdown-class"
  127 + v-if="role === ROLE.ADMIN || role === ROLE.TRACKER || role === ROLE.BUSINESS"
123 > 128 >
124 - <a-select-option value1="confirm">一次通过率</a-select-option>  
125 - <a-select-option value="确认样品" @click="handlePassModal('确认样品')" 129 + <a-select-option value1="一次通过率">一次通过率</a-select-option>
  130 + <a-select-option value="确认样品" @click="handlePassModal('确认意见')"
126 >确认样品</a-select-option 131 >确认样品</a-select-option
127 > 132 >
128 <a-select-option value="生产样品" @click="handlePassModal('生产样品')" 133 <a-select-option value="生产样品" @click="handlePassModal('生产样品')"
@@ -142,7 +147,12 @@ @@ -142,7 +147,12 @@
142 >比重计算</a-button 147 >比重计算</a-button
143 > 148 >
144 <!-- 质检角色不能导出任何信息 --> 149 <!-- 质检角色不能导出任何信息 -->
145 - <a-button type="primary" @click="handleExportModal">导出</a-button> 150 + <a-button
  151 + type="primary"
  152 + @click="handleExportModal"
  153 + v-if="role === ROLE.ADMIN || role === ROLE.TRACKER || role === ROLE.BUSINESS"
  154 + >导出</a-button
  155 + >
146 <a-button 156 <a-button
147 type="primary" 157 type="primary"
148 @click="handleProfitModal" 158 @click="handleProfitModal"
@@ -208,6 +218,8 @@ @@ -208,6 +218,8 @@
208 import { useUserStoreWithOut } from '/@/store/modules/user'; 218 import { useUserStoreWithOut } from '/@/store/modules/user';
209 import { ROLE } from './type.d'; 219 import { ROLE } from './type.d';
210 import { getUserList } from '/@/api/project/account'; 220 import { getUserList } from '/@/api/project/account';
  221 + import { useMessage } from '/@/hooks/web/useMessage';
  222 + import { getBaseInvoice } from '/@/api/project/invoice';
211 223
212 const orderStore = useOrderStoreWithOut(); 224 const orderStore = useOrderStoreWithOut();
213 const userStore = useUserStoreWithOut(); 225 const userStore = useUserStoreWithOut();
@@ -234,7 +246,7 @@ @@ -234,7 +246,7 @@
234 }, 246 },
235 setup() { 247 setup() {
236 const checkedKeys = ref<Array<string | number>>([]); 248 const checkedKeys = ref<Array<string | number>>([]);
237 - const selectedCustomCodes = ref<Array<string>>([]); 249 + // const selectedCustomCodes = ref<Array<string>>([]);
238 const [profitModalRegister, { openModal: openProfitModal }] = useModal(); 250 const [profitModalRegister, { openModal: openProfitModal }] = useModal();
239 const [invoiceCreateModalRegister, { openModal: openInvoiceCreateModal }] = useModal(); 251 const [invoiceCreateModalRegister, { openModal: openInvoiceCreateModal }] = useModal();
240 const [productInvoiceModalRegister, { openModal: openProductInvoiceModal }] = useModal(); 252 const [productInvoiceModalRegister, { openModal: openProductInvoiceModal }] = useModal();
@@ -279,6 +291,7 @@ @@ -279,6 +291,7 @@
279 pagination: { 291 pagination: {
280 total: 60, 292 total: 60,
281 }, 293 },
  294 + clickToRowSelect: false,
282 columns: getOrderColumns(user?.roleSmallVO?.code), 295 columns: getOrderColumns(user?.roleSmallVO?.code),
283 useSearchForm: true, 296 useSearchForm: true,
284 formConfig: formConfig, 297 formConfig: formConfig,
@@ -292,47 +305,165 @@ @@ -292,47 +305,165 @@
292 onSelect, 305 onSelect,
293 onSelectAll, 306 onSelectAll,
294 }, 307 },
295 - actionColumn: {  
296 - width: 160,  
297 - title: 'Action',  
298 - dataIndex: 'action',  
299 - // slots: { customRender: 'action' },  
300 - }, 308 + // actionColumn: {
  309 + // width: 160,
  310 + // title: 'Action',
  311 + // dataIndex: 'action',
  312 + // // slots: { customRender: 'action' },
  313 + // },
  314 + actionColumn:
  315 + role.value !== ROLE.PRODUCE
  316 + ? {
  317 + width: 160,
  318 + title: 'Action',
  319 + dataIndex: 'action',
  320 + // slots: { customRender: 'action' },
  321 + }
  322 + : undefined,
301 }); 323 });
302 function getFormValues() { 324 function getFormValues() {
303 console.log(getForm().getFieldsValue()); 325 console.log(getForm().getFieldsValue());
304 } 326 }
305 - function onSelect(record, selected) { 327 +
  328 + type CustomerCodeEntry = [string, number]; // 定义二维数组类型 [customerCode, count]
  329 + type ProductionDepartmentEntry = [string, number]; // 定义二维数组类型 [productionDepartment, count]
  330 +
  331 + const selectedCustomCodes = ref<CustomerCodeEntry[]>([]); // 创建一个二维数组的 ref
  332 + const selectedProductionDepartment = ref<ProductionDepartmentEntry[]>([]); // 创建一个二维数组的 ref
  333 +
  334 + // 单选处理函数
  335 + function onSelect(
  336 + record: { customerCode: string; productionDepartment: string; id: string },
  337 + selected: boolean,
  338 + ) {
  339 + // 查找 customerCode 在 selectedCustomCodes 中的位置
  340 + const customerCodeIndex = selectedCustomCodes.value.findIndex(
  341 + ([customerCode]) => customerCode === record.customerCode,
  342 + );
  343 +
  344 + // 查找 productionDepartment 在 selectedProductionDepartment 中的位置
  345 + const productionDepartmentIndex = selectedProductionDepartment.value.findIndex(
  346 + ([department]) => department === record.productionDepartment,
  347 + );
  348 +
306 if (selected) { 349 if (selected) {
307 - if (!selectedCustomCodes.value.includes(record.customerCode)) {  
308 - // 如果不包含,则添加到 selectedCustomCodes  
309 - selectedCustomCodes.value = [...selectedCustomCodes.value, record.customerCode];  
310 - } 350 + // 添加到 checkedKeys
311 checkedKeys.value = [...checkedKeys.value, record.id]; 351 checkedKeys.value = [...checkedKeys.value, record.id];
  352 +
  353 + // 更新 selectedCustomCodes
  354 + if (customerCodeIndex !== -1) {
  355 + // 如果已存在,增加计数
  356 + selectedCustomCodes.value[customerCodeIndex][1] += 1;
  357 + } else {
  358 + // 如果不存在,添加新项 [customerCode, 1]
  359 + selectedCustomCodes.value.push([record.customerCode, 1]);
  360 + }
  361 +
  362 + // 更新 selectedProductionDepartment
  363 + if (productionDepartmentIndex !== -1) {
  364 + // 如果已存在,增加计数
  365 + selectedProductionDepartment.value[productionDepartmentIndex][1] += 1;
  366 + } else {
  367 + // 如果不存在,添加新项 [productionDepartment, 1]
  368 + selectedProductionDepartment.value.push([record.productionDepartment, 1]);
  369 + }
312 } else { 370 } else {
  371 + // 从 checkedKeys 中移除
313 checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id); 372 checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id);
314 - selectedCustomCodes.value = selectedCustomCodes.value.filter(  
315 - (customerCode) => customerCode !== record.customerCode,  
316 - ); 373 +
  374 + // 更新 selectedCustomCodes
  375 + if (customerCodeIndex !== -1) {
  376 + if (selectedCustomCodes.value[customerCodeIndex][1] > 1) {
  377 + selectedCustomCodes.value[customerCodeIndex][1] -= 1;
  378 + } else {
  379 + selectedCustomCodes.value.splice(customerCodeIndex, 1);
  380 + }
  381 + }
  382 +
  383 + // 更新 selectedProductionDepartment
  384 + if (productionDepartmentIndex !== -1) {
  385 + if (selectedProductionDepartment.value[productionDepartmentIndex][1] > 1) {
  386 + selectedProductionDepartment.value[productionDepartmentIndex][1] -= 1;
  387 + } else {
  388 + selectedProductionDepartment.value.splice(productionDepartmentIndex, 1);
  389 + }
  390 + }
317 } 391 }
  392 +
  393 + console.log('5656Checked Keys:', checkedKeys.value);
  394 + console.log('5656Selected Customer Codes:', selectedCustomCodes.value);
  395 + console.log('5656Selected Production Departments:', selectedProductionDepartment.value);
318 } 396 }
319 - function onSelectAll(selected, selectedRows, changeRows) { 397 +
  398 + // 全选处理函数
  399 + function onSelectAll(selected: boolean, selectedRows: any[], changeRows: any[]) {
320 const changeIds = changeRows.map((item) => item.id); 400 const changeIds = changeRows.map((item) => item.id);
321 const changeCustomerCodes = changeRows.map((item) => item.customerCode); 401 const changeCustomerCodes = changeRows.map((item) => item.customerCode);
  402 + const changeProductionDepartments = changeRows.map((item) => item.productionDepartment);
  403 +
322 if (selected) { 404 if (selected) {
  405 + // 添加到 checkedKeys
323 checkedKeys.value = [...checkedKeys.value, ...changeIds]; 406 checkedKeys.value = [...checkedKeys.value, ...changeIds];
324 - // 创建一个集合来去除重复的代码  
325 - const allCodes = new Set([...selectedCustomCodes.value, ...changeCustomerCodes]);  
326 - // 将集合转换回数组  
327 - selectedCustomCodes.value = Array.from(allCodes); 407 +
  408 + // 更新 selectedCustomCodes
  409 + changeCustomerCodes.forEach((code) => {
  410 + const index = selectedCustomCodes.value.findIndex(
  411 + ([customerCode]) => customerCode === code,
  412 + );
  413 + if (index !== -1) {
  414 + selectedCustomCodes.value[index][1] += 1;
  415 + } else {
  416 + selectedCustomCodes.value.push([code, 1]);
  417 + }
  418 + });
  419 +
  420 + // 更新 selectedProductionDepartment
  421 + changeProductionDepartments.forEach((department) => {
  422 + const index = selectedProductionDepartment.value.findIndex(
  423 + ([prodDepartment]) => prodDepartment === department,
  424 + );
  425 + if (index !== -1) {
  426 + selectedProductionDepartment.value[index][1] += 1;
  427 + } else {
  428 + selectedProductionDepartment.value.push([department, 1]);
  429 + }
  430 + });
328 } else { 431 } else {
329 - checkedKeys.value = checkedKeys.value.filter((id) => {  
330 - return !changeIds.includes(id); 432 + // 从 checkedKeys 中移除
  433 + checkedKeys.value = checkedKeys.value.filter((id) => !changeIds.includes(id));
  434 +
  435 + // 更新 selectedCustomCodes
  436 + changeCustomerCodes.forEach((code) => {
  437 + const index = selectedCustomCodes.value.findIndex(
  438 + ([customerCode]) => customerCode === code,
  439 + );
  440 + if (index !== -1) {
  441 + if (selectedCustomCodes.value[index][1] > 1) {
  442 + selectedCustomCodes.value[index][1] -= 1;
  443 + } else {
  444 + selectedCustomCodes.value.splice(index, 1);
  445 + }
  446 + }
331 }); 447 });
332 - selectedCustomCodes.value = selectedCustomCodes.value.filter((customerCode) => {  
333 - return !changeCustomerCodes.includes(customerCode); 448 +
  449 + // 更新 selectedProductionDepartment
  450 + changeProductionDepartments.forEach((department) => {
  451 + const index = selectedProductionDepartment.value.findIndex(
  452 + ([prodDepartment]) => prodDepartment === department,
  453 + );
  454 + if (index !== -1) {
  455 + if (selectedProductionDepartment.value[index][1] > 1) {
  456 + selectedProductionDepartment.value[index][1] -= 1;
  457 + } else {
  458 + selectedProductionDepartment.value.splice(index, 1);
  459 + }
  460 + }
334 }); 461 });
335 } 462 }
  463 +
  464 + console.log('5656Checked Keys:', checkedKeys.value);
  465 + console.log('5656Selected Customer Codes:', selectedCustomCodes.value);
  466 + console.log('5656Selected Production Departments:', selectedProductionDepartment.value);
336 } 467 }
337 468
338 function handleEdit(record, e) { 469 function handleEdit(record, e) {
@@ -377,10 +508,20 @@ @@ -377,10 +508,20 @@
377 }); 508 });
378 } 509 }
379 510
380 - function handleInvoiceCreateModal() { 511 + function handleInvoiceCreateModal(record) {
381 const form = getForm(); 512 const form = getForm();
382 const values = form.getFieldsValue(); 513 const values = form.getFieldsValue();
  514 + if (checkedKeys.value.length == 0) {
  515 + error('请选择订单');
  516 + return;
  517 + }
  518 + if (selectedCustomCodes.value.length > 1) {
  519 + error('勾选订单的客户编码需一致');
  520 + return;
  521 + }
383 openInvoiceCreateModal(true, { 522 openInvoiceCreateModal(true, {
  523 + record: record,
  524 + customersCodes: selectedCustomCodes.value,
384 data: checkedKeys.value, 525 data: checkedKeys.value,
385 searchData: values, 526 searchData: values,
386 }); 527 });
@@ -389,6 +530,14 @@ @@ -389,6 +530,14 @@
389 function handleProductInvoiceModal() { 530 function handleProductInvoiceModal() {
390 const form = getForm(); 531 const form = getForm();
391 const values = form.getFieldsValue(); 532 const values = form.getFieldsValue();
  533 + if (checkedKeys.value.length == 0) {
  534 + error('请选择订单');
  535 + return;
  536 + }
  537 + if (selectedProductionDepartment.value.length > 1) {
  538 + error('勾选订单的生产科需一致');
  539 + return;
  540 + }
392 openProductInvoiceModal(true, { 541 openProductInvoiceModal(true, {
393 data: checkedKeys.value, 542 data: checkedKeys.value,
394 searchData: values, 543 searchData: values,
@@ -401,35 +550,46 @@ @@ -401,35 +550,46 @@
401 function handlePassModal(title) { 550 function handlePassModal(title) {
402 const form = getForm(); 551 const form = getForm();
403 const values = form.getFieldsValue(); 552 const values = form.getFieldsValue();
404 - if (title == '确认样品') {  
405 - openPassModal(true, {  
406 - check: checkedKeys.value,  
407 - data: values,  
408 - title: title,  
409 - });  
410 - return false;  
411 - } else if (title == '生产样品') {  
412 - openPassModal(true, {  
413 - check: checkedKeys.value,  
414 - data: values,  
415 - title: title,  
416 - });  
417 - return false;  
418 - } else if (title == '测试样品') {  
419 - openPassModal(true, {  
420 - check: checkedKeys.value,  
421 - data: values,  
422 - title: title,  
423 - });  
424 - return false;  
425 - } 553 + openPassModal(true, {
  554 + check: checkedKeys.value,
  555 + title: title,
  556 + searchData: values,
  557 + });
426 } 558 }
427 - 559 + // const form = getForm();
  560 + // const values = form.getFieldsValue();
  561 + // if (title == '确认样品') {
  562 + // openPassModal(true, {
  563 + // check: checkedKeys.value,
  564 + // title: title,
  565 + // });
  566 + // return false;
  567 + // } else if (title == '生产样品') {
  568 + // openPassModal(true, {
  569 + // check: checkedKeys.value,
  570 + // title: title,
  571 + // });
  572 + // return false;
  573 + // } else if (title == '测试样品') {
  574 + // openPassModal(true, {
  575 + // check: checkedKeys.value,
  576 + // title: title,
  577 + // });
  578 + // return false;
  579 + // }
  580 + // }
  581 + const { createMessage } = useMessage();
  582 + const { error } = createMessage;
428 function handleProductModal() { 583 function handleProductModal() {
429 const form = getForm(); 584 const form = getForm();
430 const values = form.getFieldsValue(); 585 const values = form.getFieldsValue();
431 - 586 + console.log(selectedCustomCodes.value, 5656);
  587 + if (selectedCustomCodes.value.length == 0) {
  588 + error('请选择订单');
  589 + return;
  590 + }
432 openProductModal(true, { 591 openProductModal(true, {
  592 + customers: selectedCustomCodes.value,
433 data: values, 593 data: values,
434 }); 594 });
435 } 595 }
src/views/project/order/tableData.tsx
@@ -12,6 +12,8 @@ import { formatToDate } from &#39;/@/utils/dateUtil&#39;; @@ -12,6 +12,8 @@ import { formatToDate } from &#39;/@/utils/dateUtil&#39;;
12 12
13 const innerNoOptions = ref([]); 13 const innerNoOptions = ref([]);
14 const projectNoOptions = ref([]); 14 const projectNoOptions = ref([]);
  15 +const orderStore = useOrderStoreWithOut();
  16 +// const { productionDepartment: productionDepartmentOptions } = useOrderInfo(orderStore);
15 17
16 // 可选择的列 18 // 可选择的列
17 export const SELECT_FIELD_COLUMNS = [ 19 export const SELECT_FIELD_COLUMNS = [
@@ -353,6 +355,24 @@ export const ORDER_LIST_PROFIT_FIELDS = [ @@ -353,6 +355,24 @@ export const ORDER_LIST_PROFIT_FIELDS = [
353 }, 355 },
354 ]; 356 ];
355 357
  358 +function modifyConfirmResult(ppConfirmResult: string, ppConfirmTime: string): string {
  359 + // 获取 ppConfirmTime 的日期部分,去掉时间
  360 + let datePart = ppConfirmTime.split(' ')[0]; // 获取日期部分
  361 + datePart += ' ';
  362 + // 找到第一个"."的位置
  363 + const dotIndex = ppConfirmResult.indexOf('.');
  364 +
  365 + // 如果找到了".",则进行拼接
  366 + if (dotIndex !== -1) {
  367 + // 生成新的结果
  368 + const modifiedResult = `${ppConfirmResult.slice(0, dotIndex + 1)}${datePart}${ppConfirmResult.slice(dotIndex + 1)}`;
  369 + return modifiedResult;
  370 + }
  371 +
  372 + // 如果没有找到".",直接返回原始字符串
  373 + return ppConfirmResult;
  374 +}
  375 +
356 export const ORDER_LIST_TRACK_FIELDS = [ 376 export const ORDER_LIST_TRACK_FIELDS = [
357 { 377 {
358 title: '跟单信息', 378 title: '跟单信息',
@@ -370,13 +390,17 @@ export const ORDER_LIST_TRACK_FIELDS = [ @@ -370,13 +390,17 @@ export const ORDER_LIST_TRACK_FIELDS = [
370 }, 390 },
371 { 391 {
372 title: 'pp样品确认意见', 392 title: 'pp样品确认意见',
373 - width: 150, 393 + width: 180,
374 dataIndex: 'ppConfirmResult', 394 dataIndex: 'ppConfirmResult',
375 customRender: (column) => { 395 customRender: (column) => {
376 const { record } = column || {}; 396 const { record } = column || {};
377 - if (record?.trackStageInfo?.ppConfirmResult !== undefined) { 397 + if (
  398 + record?.trackStageInfo?.ppConfirmResult !== undefined &&
  399 + record?.trackStageInfo?.ppConfirmTime !== undefined
  400 + ) {
378 const ppUpdate = record?.trackStageInfo?.ppConfirmResult; 401 const ppUpdate = record?.trackStageInfo?.ppConfirmResult;
379 - const ppUpdate2 = ppUpdate + '123'; 402 + const ppUpdateTime = record?.trackStageInfo?.ppConfirmTime;
  403 + const ppUpdate2 = modifyConfirmResult(ppUpdate, ppUpdateTime);
380 return ppUpdate2; 404 return ppUpdate2;
381 } else { 405 } else {
382 return record?.trackStageInfo?.ppConfirmResult; 406 return record?.trackStageInfo?.ppConfirmResult;
@@ -407,7 +431,17 @@ export const ORDER_LIST_TRACK_FIELDS = [ @@ -407,7 +431,17 @@ export const ORDER_LIST_TRACK_FIELDS = [
407 dataIndex: 'shippmentSampleConfirmResult', 431 dataIndex: 'shippmentSampleConfirmResult',
408 customRender: (column) => { 432 customRender: (column) => {
409 const { record } = column || {}; 433 const { record } = column || {};
410 - return record?.trackStageInfo?.shippmentSampleConfirmResult; 434 + if (
  435 + record?.trackStageInfo?.shippmentSampleConfirmResult !== undefined &&
  436 + record?.trackStageInfo?.shippmentSampleConfirmTime !== undefined
  437 + ) {
  438 + const shipUpdate = record?.trackStageInfo?.shippmentSampleConfirmResult;
  439 + const shipUpdateTime = record?.trackStageInfo?.shippmentSampleConfirmTime;
  440 + const shipUpdate2 = modifyConfirmResult(shipUpdate, shipUpdateTime);
  441 + return shipUpdate2;
  442 + } else {
  443 + return record?.trackStageInfo?.shippmentSampleConfirmResult;
  444 + }
411 }, 445 },
412 }, 446 },
413 { 447 {
@@ -434,7 +468,17 @@ export const ORDER_LIST_TRACK_FIELDS = [ @@ -434,7 +468,17 @@ export const ORDER_LIST_TRACK_FIELDS = [
434 dataIndex: 'aitexTestFinishResult', 468 dataIndex: 'aitexTestFinishResult',
435 customRender: (column) => { 469 customRender: (column) => {
436 const { record } = column || {}; 470 const { record } = column || {};
437 - return record?.trackStageInfo?.aitexTestFinishResult; 471 + if (
  472 + record?.trackStageInfo?.aitexTestFinishResult !== undefined &&
  473 + record?.trackStageInfo?.aitexTestFinishTime !== undefined
  474 + ) {
  475 + const aitexUpdate = record?.trackStageInfo?.aitexTestFinishResult;
  476 + const aitexUpdateTime = record?.trackStageInfo?.aitexTestFinishTime;
  477 + const aitexUpdate2 = modifyConfirmResult(aitexUpdate, aitexUpdateTime);
  478 + return aitexUpdate2;
  479 + } else {
  480 + return record?.trackStageInfo?.aitexTestFinishResult;
  481 + }
438 }, 482 },
439 }, 483 },
440 { 484 {
@@ -452,7 +496,17 @@ export const ORDER_LIST_TRACK_FIELDS = [ @@ -452,7 +496,17 @@ export const ORDER_LIST_TRACK_FIELDS = [
452 dataIndex: 'sgsTestFinishResult', 496 dataIndex: 'sgsTestFinishResult',
453 customRender: (column) => { 497 customRender: (column) => {
454 const { record } = column || {}; 498 const { record } = column || {};
455 - return record?.trackStageInfo?.sgsTestFinishResult; 499 + if (
  500 + record?.trackStageInfo?.sgsTestFinishResult !== undefined &&
  501 + record?.trackStageInfo?.sgsTestFinishTime !== undefined
  502 + ) {
  503 + const sgsUpdate = record?.trackStageInfo?.sgsTestFinishResult;
  504 + const sgsUpdateTime = record?.trackStageInfo?.sgsTestFinishTime;
  505 + const sgsUpdate2 = modifyConfirmResult(sgsUpdate, sgsUpdateTime);
  506 + return sgsUpdate2;
  507 + } else {
  508 + return record?.trackStageInfo?.sgsTestFinishResult;
  509 + }
456 }, 510 },
457 }, 511 },
458 { 512 {
@@ -725,6 +779,9 @@ export const FIELDS_BASE_INFO = [ @@ -725,6 +779,9 @@ export const FIELDS_BASE_INFO = [
725 { 779 {
726 field: 'productionDepartment', 780 field: 'productionDepartment',
727 component: 'Select', 781 component: 'Select',
  782 + // componentProps: {
  783 + // options: productionDepartmentOptions,
  784 + // },
728 labelWidth: 150, 785 labelWidth: 150,
729 label: '生产科', 786 label: '生产科',
730 rules: [{ required: true }], 787 rules: [{ required: true }],
@@ -1122,29 +1179,29 @@ export const FIELDS_TRACK_STAGE_INFO = [ @@ -1122,29 +1179,29 @@ export const FIELDS_TRACK_STAGE_INFO = [
1122 }, 1179 },
1123 { 1180 {
1124 field: 'latestArrivalTime', 1181 field: 'latestArrivalTime',
1125 - component: 'Select',  
1126 - componentProps: {  
1127 - options: [  
1128 - {  
1129 - label: 'ok',  
1130 - value: 'ok',  
1131 - },  
1132 - ],  
1133 - }, 1182 + component: 'DatePicker',
  1183 + // componentProps: {
  1184 + // options: [
  1185 + // {
  1186 + // label: 'ok',
  1187 + // value: 'ok',
  1188 + // },
  1189 + // ],
  1190 + // },
1134 label: '最晚包材到货时间', 1191 label: '最晚包材到货时间',
1135 labelWidth: 250, 1192 labelWidth: 250,
1136 }, 1193 },
1137 { 1194 {
1138 field: 'latestBkTime', 1195 field: 'latestBkTime',
1139 - component: 'Select',  
1140 - componentProps: {  
1141 - options: [  
1142 - {  
1143 - label: 'ok',  
1144 - value: 'ok',  
1145 - },  
1146 - ],  
1147 - }, 1196 + component: 'DatePicker',
  1197 + // componentProps: {
  1198 + // options: [
  1199 + // {
  1200 + // label: 'ok',
  1201 + // value: 'ok',
  1202 + // },
  1203 + // ],
  1204 + // },
1148 label: '最晚订舱+报关资料时间', 1205 label: '最晚订舱+报关资料时间',
1149 labelWidth: 250, 1206 labelWidth: 250,
1150 }, 1207 },
vite.config.ts
@@ -21,6 +21,7 @@ export default defineApplicationConfig({ @@ -21,6 +21,7 @@ export default defineApplicationConfig({
21 proxy: { 21 proxy: {
22 '/basic-api/order': { 22 '/basic-api/order': {
23 target: 'http://47.104.8.35:18000', 23 target: 'http://47.104.8.35:18000',
  24 + // target: 'http://39.108.227.113:8000',
24 // target: 'http://localhost:8000', 25 // target: 'http://localhost:8000',
25 // target: 'http://39.108.227.113:3000/mock/35', 26 // target: 'http://39.108.227.113:3000/mock/35',
26 // http://39.108.227.113:8000/order/erp/captcha/get_img_captcha_code 27 // http://39.108.227.113:8000/order/erp/captcha/get_img_captcha_code
@@ -30,6 +31,8 @@ export default defineApplicationConfig({ @@ -30,6 +31,8 @@ export default defineApplicationConfig({
30 }, 31 },
31 '/api/localStorage/upload': { 32 '/api/localStorage/upload': {
32 target: 'http://47.104.8.35:18000', 33 target: 'http://47.104.8.35:18000',
  34 + // target: 'http://39.108.227.113:8000',
  35 + // target: '192.168.31.250:18000',
33 // target: 'http://localhost:8000', 36 // target: 'http://localhost:8000',
34 changeOrigin: true, 37 changeOrigin: true,
35 ws: true, 38 ws: true,