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 30 res.records = res.records.map((item) => {
31 31 return item;
32 32 });
33   -
  33 + console.log(res.records, 5656565656);
34 34 return new Promise((resolve) => {
35 35 resolve({ items: res.records, total: res.total });
36 36 });
... ...
src/api/project/invoice.ts
... ... @@ -11,9 +11,21 @@ enum Api {
11 11 UPDATE_AMOUNT = '/order/erp/invoice_bill/update_amount_info', //更新其他金额信息
12 12 INVOICE_DELETE = '/order/erp/invoice_bill/delete_by_id', //删除数据
13 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 29 const res = await defHttp.post<any>({
18 30 url: Api.REFUND_DATE,
19 31 params,
... ... @@ -33,7 +45,6 @@ export const getInvoice = async (params: any) =&gt; {
33 45 url: Api.INVOICE,
34 46 params,
35 47 });
36   - console.log(res, 5656);
37 48 return res.records;
38 49 };
39 50 export const getBaseInvoice = async (params: any) => {
... ... @@ -55,13 +66,15 @@ export const exportAnalysis = async (params: any) =&gt; {
55 66 params,
56 67 });
57 68 };
  69 +
58 70 export const updateDeduct = async (params: any) => {
59 71 return await defHttp.post<any>({
60 72 url: Api.UPDATE_DEDUCT,
61 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 78 return await defHttp.post<any>({
66 79 url: Api.UPDATE_AMOUNT,
67 80 params,
... ... @@ -79,3 +92,72 @@ export const commit = async (params: any) =&gt; {
79 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 33 ORDER_FIELD_CHECK = '/order/erp/order/check', // 校验内部编号是否重复
34 34  
35 35 TRACK_HISTORY = '/order/erp/opinion/log/query_by_id', //跟单结果记录
  36 + PASS_CALCULATE = '/order/erp/order/passRate', //一次性通过率
36 37 }
37 38  
38 39 export const formatSearchData = (params) => {
... ... @@ -187,6 +188,7 @@ export const orderExport = async (data: any = {}) =&gt; {
187 188 a.download = `${strArr.join('_')} ${date}.xlsx`; // 你可以为文件命名
188 189 document.body.appendChild(a);
189 190 a.click(); // 模拟点击操作来下载文件
  191 + console.log(a, '5656a');
190 192 URL.revokeObjectURL(downloadUrl); // 释放掉 blob 对象所占用的内存
191 193 document.body.removeChild(a);
192 194  
... ... @@ -305,3 +307,11 @@ export const trackHistory = async (data: any) =&gt; {
305 307 });
306 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 91 params,
92 92 });
93 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 100 return resAll;
95 101 };
96 102  
... ...
src/components/Modal/src/hooks/useModal.ts
... ... @@ -100,7 +100,7 @@ export function useModal(): UseModalReturnType {
100 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 104 const modalInstanceRef = ref<Nullable<ModalMethods>>(null);
105 105 const currentInstance = getCurrentInstance();
106 106 const uidRef = ref<string>('');
... ...
src/router/routes/modules/project/approve.ts
1 1 import type { AppRouteModule } from '/@/router/types';
2 2  
3 3 import { LAYOUT } from '/@/router/constant';
  4 +import { RoleEnum } from '/@/enums/roleEnum';
4 5  
5 6 const order: AppRouteModule = {
6 7 path: '/approve',
... ... @@ -10,7 +11,7 @@ const order: AppRouteModule = {
10 11 meta: {
11 12 hideChildrenInMenu: true,
12 13 orderNo: 3,
13   - // icon: 'ion:grid-outline',
  14 + icon: 'ion:grid-outline',
14 15 title: '审批管理',
15 16 },
16 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 10 <a-tab-pane key="5" tab="项目报告书待审核">
11 11 <ReportPanel />
12 12 </a-tab-pane>
  13 + <a-tab-pane key="7" tab="应收款待审核">
  14 + <ReceivePanel />
  15 + </a-tab-pane>
13 16 <a-tab-pane key="2" tab="字段已审核">
14 17 <FieldPanel isApproved />
15 18 </a-tab-pane>
... ... @@ -19,6 +22,9 @@
19 22 <a-tab-pane key="6" tab="项目报告书已审核">
20 23 <ReportPanel isApproved />
21 24 </a-tab-pane>
  25 + <a-tab-pane key="8" tab="应收款已审核">
  26 + <ReceivePanel isApproved />
  27 + </a-tab-pane>
22 28 </a-tabs>
23 29 </div>
24 30 </template>
... ... @@ -28,6 +34,7 @@
28 34 import ReportPanel from './ReportPanel.vue';
29 35 import ProfitPanel from './ProfitPanel.vue';
30 36 import FieldPanel from './FieldPanel.vue';
  37 + import ReceivePanel from './ReceivePanel.vue';
31 38 import { useOrderStoreWithOut } from '/@/store/modules/order';
32 39  
33 40 const orderStore = useOrderStoreWithOut();
... ... @@ -39,6 +46,7 @@
39 46 ReportPanel,
40 47 FieldPanel,
41 48 ProfitPanel,
  49 + ReceivePanel,
42 50 },
43 51 setup() {
44 52 const checkedKeys = ref<Array<string | number>>([]);
... ...
src/views/project/config/CreateModal.vue
... ... @@ -58,7 +58,7 @@
58 58 {
59 59 field: 'relationValue',
60 60 component: 'InputNumber',
61   - label: props.column === 1 ? '利润率' : '包装费用',
  61 + label: props.column === 1 ? '利润率' : props.column === 5 ? '回款时间' : '包装费用',
62 62 rules: [{ required: true }],
63 63 colProps: {
64 64 span: 24,
... ... @@ -96,7 +96,14 @@
96 96 settingName: '客户编码',
97 97 settingValue: values.settingValue,
98 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 107 relationName: '包装费用',
101 108 relationValue: values.relationValue,
102 109 };
... ...
src/views/project/config/DrawerEdit.vue
... ... @@ -50,7 +50,7 @@
50 50 colProps: {
51 51 span: 23,
52 52 },
53   - label: '确认样品确认状态(填写邮箱)',
  53 + label: '确认样品确认状态(填写邮箱,请用逗号隔开)',
54 54 rules: [{ required: true }],
55 55 },
56 56 {
... ...
src/views/project/config/EmailPanel.vue
1 1 <template>
2   - <div class="p-4">
  2 + <div :style="{ marginLeft: '0px' }">
3 3 <BasicTable @register="registerTable">
4 4 <template #toolbar>
5 5 <!-- <a-button type="primary" class="my-4" @click="handleCreate"> 新增 </a-button> -->
... ...
src/views/project/config/TablePanel.vue
1 1 <template>
2   - <BasicTable @register="registerTable">
  2 + <BasicTable @register="registerTable" :bordered="true">
3 3 <template #toolbar>
4 4 <a-button v-if="props.column !== 3" type="primary" @click="handleCreateModal">新建</a-button>
5 5 </template>
... ...
src/views/project/config/data.tsx
... ... @@ -45,6 +45,20 @@ export const COLUMNS = {
45 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 64 export const columns: BasicColumn[] = [
... ... @@ -56,7 +70,7 @@ export const columns: BasicColumn[] = [
56 70 {
57 71 title: '状态',
58 72 dataIndex: 'enableFlag',
59   - width: 70,
  73 + width: 100,
60 74 customRender: (column) => {
61 75 const { record } = column || {};
62 76 return record.enableFlag === 10 ? <Tag color="green">启用</Tag> : <Tag color="red">禁用</Tag>;
... ...
src/views/project/config/index.vue
1 1 <template>
2 2 <PageWrapper contentBackground>
3 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 9 <Tabs.TabPane key="1" tab="利润率配置">
6 10 <TablePanel :searchInfo="{ relationCode: 'profitRate' }" :column="1" />
7 11 </Tabs.TabPane>
... ... @@ -12,6 +16,9 @@
12 16 <TablePanel :searchInfo="{ settingCode: 'exchangeRate' }" :column="3"
13 17 /></Tabs.TabPane>
14 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 22 </Tabs>
16 23 </div>
17 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 28 import { BasicForm, FormSchema, useForm } from '@/components/Form';
29 29 import { defineComponent, ref, computed, unref, toRaw, reactive } from 'vue';
30 30 import { getEmailList } from '/@/api/sys/config';
  31 + import { updateAmountInfo } from '@/api/project/invoice';
31 32  
  33 + const emit = defineEmits(['success']);
32 34 const schemas: FormSchema[] = [
33 35 {
34   - field: 'configSample',
35   - component: 'Input',
  36 + field: 'actualPayedAmount',
  37 + component: 'InputNumber',
36 38 labelWidth: 250,
37 39 colProps: {
38 40 span: 23,
... ... @@ -40,31 +42,31 @@
40 42 label: '生产科实际应付金额',
41 43 },
42 44 {
43   - field: 'configSample',
44   - component: 'Input',
  45 + field: 'actualPayedAmount1',
  46 + component: 'InputNumber',
45 47 labelWidth: 250,
46 48 colProps: {
47 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 56 labelWidth: 250,
55 57 colProps: {
56 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 65 labelWidth: 250,
64 66 colProps: {
65 67 span: 23,
66 68 },
67   - label: '实际应金额3',
  69 + label: '实际应金额3',
68 70 },
69 71 ];
70 72 const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
... ... @@ -76,23 +78,30 @@
76 78 span: 24,
77 79 },
78 80 });
  81 +
  82 + const update = ref();
79 83 const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => {
80 84 // 方式1
81   - console.log(data, 56561);
82 85 resetFields();
83 86 setDrawerProps({ confirmLoading: false });
84 87 setFieldsValue({
85 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 94 async function handleSubmit() {
95 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 107 </script>
... ...
src/views/project/finance/pay/InvoiceUpload.vue
... ... @@ -4,13 +4,15 @@
4 4 @register="register"
5 5 title="发票上传"
6 6 width="500px"
7   - :bodyStyle="{ height: '200px' }"
  7 + :bodyStyle="{ height: '240px' }"
8 8 @ok="handleOk"
9 9 ><a-upload-dragger
10 10 v-model:fileList="fileList"
11 11 name="file"
  12 + :beforeUpload="beforeUpload"
  13 + :max-count="1"
12 14 :multiple="true"
13   - action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
  15 + :action="updateInvoiceUrl"
14 16 @change="handleChange"
15 17 @drop="handleDrop"
16 18 >
... ... @@ -27,31 +29,43 @@
27 29 import type { UploadProps, UploadChangeParam } from 'ant-design-vue';
28 30 import { InboxOutlined } from '@ant-design/icons-vue';
29 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 56 function handleDrop(e: DragEvent) {
43 57 console.log(e);
44 58 }
45 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 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 69 closeModal();
56 70 }
57 71 </script>
... ...
src/views/project/finance/pay/TrackEdit.vue
... ... @@ -3,7 +3,7 @@
3 3 <BasicDrawer
4 4 @register="register"
5 5 v-bind="$attrs"
6   - title="编辑"
  6 + title="跟单编辑"
7 7 width="30%"
8 8 :isDetail="true"
9 9 @ok="handleSubmit"
... ... @@ -14,23 +14,22 @@
14 14 >
15 15 <div>
16 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 18 <div style="margin: 16px 0"></div>
19 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 21 <div style="margin: 16px 0"></div>
22 22 <div>上传扣款单</div
23 23 ><a-space direction="vertical" style="width: 100%" size="large">
24 24 <a-upload
25 25 v-model:file-list="fileList"
  26 + :beforeUpload="beforeUpload"
26 27 list-type="picture"
27 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 33 </a-upload>
35 34 </a-space>
36 35 </div>
... ... @@ -47,22 +46,49 @@
47 46 import { getEmailList } from '/@/api/sys/config';
48 47 import { UploadOutlined } from '@ant-design/icons-vue';
49 48 import type { UploadProps } from 'ant-design-vue';
  49 + import { updateDeductInfo } from '@/api/project/invoice';
50 50  
  51 + const emit = defineEmits(['success']);
51 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 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 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 94 </script>
... ...
src/views/project/finance/pay/index.vue
... ... @@ -2,10 +2,12 @@
2 2 <div class="p-4">
3 3 <BasicTable @register="registerTable">
4 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 11 </template>
10 12 <template #bodyCell="{ column, record }">
11 13 <template v-if="column.key === 'action'">
... ... @@ -26,11 +28,15 @@
26 28 ]"
27 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 35 label: '订单信息',
  36 + onClick: handleDetail.bind(null, record),
  37 + },
  38 + {
  39 + label: '删除',
34 40 onClick: handleDelete.bind(null, record),
35 41 },
36 42 ]"
... ... @@ -41,28 +47,38 @@
41 47 </div>
42 48 </template>
43 49 <script lang="ts" setup>
44   - import { defineComponent } from 'vue';
  50 + import { defineComponent, ref } from 'vue';
45 51 import { BasicTable, useTable, BasicColumn, TableAction } from '/@/components/Table';
46 52 import { searchFormSchema, columns } from './pay.data';
47   - import { demoListApi } from '/@/api/demo/table';
48 53 import TrackEdit from './TrackEdit.vue';
49 54 import FinanceEdit from './FinanceEdit.vue';
50 55 import InvoiceUpload from './InvoiceUpload.vue';
  56 + import CheckDetail from './CheckDetail.vue';
  57 + import CheckSum from './CheckSum.vue';
51 58 import { useDrawer } from '/@/components/Drawer';
52 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 64 const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer();
55 65 const [registerTrackEdit, { openDrawer: openTrackEdit }] = useDrawer();
56 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 71 title: '',
60   - api: demoListApi,
  72 + api: getCheck,
61 73 columns: columns,
62 74 bordered: true,
  75 + clickToRowSelect: false,
63 76 rowKey: 'id',
64 77 rowSelection: {
65 78 type: 'checkbox',
  79 + selectedRowKeys: checkedKeys,
  80 + onSelect,
  81 + onSelectAll,
66 82 },
67 83 formConfig: {
68 84 labelWidth: 120,
... ... @@ -82,28 +98,314 @@
82 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 357 function handleFinanceEdit(record) {
86   - console.log('点击了编辑', record);
87 358 openFinanceEdit(true, {
88 359 data: record,
89 360 });
90 361 }
91 362 function handleTrackEdit(record) {
92   - console.log('点击了编辑', record);
93 363 openTrackEdit(true, {
94 364 data: record,
95 365 });
96 366 }
97 367 function handleInvoiceUpload(record) {
98   - console.log('点击了编辑', record);
99 368 openInvoiceUpload(true, {
100 369 data: record,
101 370 });
102 371 }
103 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 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 411 </script>
... ...
src/views/project/finance/pay/pay.data.tsx
1 1 import { FormSchema } from '/@/components/Form';
2 2 import { BasicColumn } from '/@/components/Table';
3 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 5 import { size } from 'lodash-es';
6 6  
7 7 export const searchFormSchema: FormSchema[] = [
8 8 {
9   - field: 'phone',
  9 + field: 'checkNo',
10 10 label: '生产科对账单号',
11 11 component: 'Input',
12 12 colProps: { span: 8 },
13 13 },
14 14 {
15   - field: 'nickName',
16   - label: '总经理审核',
  15 + field: 'productionDepartment',
  16 + label: '生产科',
17 17 component: 'Input',
18 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 44 export const columns: BasicColumn[] = [
23 45 {
24 46 title: '生产科对账单号',
25   - dataIndex: 'no',
  47 + dataIndex: 'checkNo',
26 48 width: 120,
27   - customRender: (column) => {
28   - return '5667';
29   - },
30 49 },
31 50 {
32 51 title: '生产科应付款日期',
33   - dataIndex: 'no',
  52 + dataIndex: 'payedDate',
34 53 width: 140,
35 54 },
36 55 {
37 56 title: '生产科扣款金额',
38   - dataIndex: 'no',
  57 + dataIndex: 'deductAmount',
39 58 width: 120,
40 59 },
41 60 {
42 61 title: '扣款责任部门',
43   - dataIndex: 'no',
  62 + dataIndex: 'deductDept',
44 63 width: 120,
45 64 },
46 65 {
47 66 title: '上传扣款单',
48   - dataIndex: 'no',
  67 + dataIndex: 'deductUrl',
49 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 78 title: '生产科实际应付金额',
53   - dataIndex: 'no',
  79 + dataIndex: 'actualPayedAmount',
54 80 width: 120,
55 81 },
56 82 {
57 83 title: '生产科发票上传',
58   - dataIndex: 'no',
  84 + dataIndex: 'invoiceUrl',
59 85 width: 80,
60 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 95 title: '实际付款金额1',
66   - dataIndex: 'no',
  96 + dataIndex: 'actualPayedAmount1',
67 97 width: 120,
68 98 },
69 99 {
70 100 title: '实际付款金额2',
71   - dataIndex: 'no',
  101 + dataIndex: 'actualPayedAmount2',
72 102 width: 120,
73 103 },
74 104 {
75 105 title: '实际付款金额3',
76   - dataIndex: 'no',
  106 + dataIndex: 'actualPayedAmount3',
77 107 width: 120,
78 108 },
79 109 {
80 110 title: '生产科发票',
81   - dataIndex: 'no',
  111 + dataIndex: 'invoiceUrl',
82 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 122 title: '总经理审核',
86   - dataIndex: 'no',
  123 + dataIndex: 'status',
87 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 30 import { getEmailList } from '/@/api/sys/config';
31 31 import { updateAmount } from '@/api/project/invoice';
32 32  
  33 + const emit = defineEmits(['success']);
33 34 const schemas: FormSchema[] = [
34 35 {
35 36 field: 'actualReceivableAmount',
36   - component: 'Input',
  37 + component: 'InputNumber',
37 38 labelWidth: 250,
38 39 colProps: {
39 40 span: 23,
... ... @@ -42,7 +43,7 @@
42 43 },
43 44 {
44 45 field: 'actualPayedAmount1',
45   - component: 'Input',
  46 + component: 'InputNumber',
46 47 labelWidth: 250,
47 48 colProps: {
48 49 span: 23,
... ... @@ -51,7 +52,7 @@
51 52 },
52 53 {
53 54 field: 'actualPayedAmount2',
54   - component: 'Input',
  55 + component: 'InputNumber',
55 56 labelWidth: 250,
56 57 colProps: {
57 58 span: 23,
... ... @@ -60,7 +61,7 @@
60 61 },
61 62 {
62 63 field: 'actualPayedAmount3',
63   - component: 'Input',
  64 + component: 'InputNumber',
64 65 labelWidth: 250,
65 66 colProps: {
66 67 span: 23,
... ... @@ -69,7 +70,7 @@
69 70 },
70 71 {
71 72 field: 'otherAmount',
72   - component: 'Input',
  73 + component: 'InputNumber',
73 74 labelWidth: 250,
74 75 colProps: {
75 76 span: 23,
... ... @@ -108,5 +109,7 @@
108 109 await updateAmount({
109 110 ...updatedValues,
110 111 });
  112 + emit('success');
  113 + closeDrawer();
111 114 }
112 115 </script>
... ...
src/views/project/finance/receive/InvoiceAnalysis.vue
... ... @@ -3,51 +3,137 @@
3 3 v-bind="$attrs"
4 4 @register="register"
5 5 title="收款单分析"
6   - width="700px"
7   - :bodyStyle="{ height: '400px' }"
  6 + width="80%"
  7 + :isDetail="true"
  8 + :showDetailBack="false"
8 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 20 </template>
38 21 <script lang="ts" setup>
39 22 import { BasicModal, useModalInner } from '@/components/Modal';
40 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 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 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 137 closeModal();
52 138 }
53 139 </script>
... ...
src/views/project/finance/receive/InvoiceDetail.vue
... ... @@ -13,6 +13,9 @@
13 13 <BasicTable @register="registerTable">
14 14 <template #bodyCell="{ column, record }">
15 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 19 </template>
17 20 </BasicTable>
18 21 </div>
... ... @@ -31,22 +34,52 @@
31 34 {
32 35 title: '客户编码',
33 36 dataIndex: 'customerCode',
34   - width: 50,
  37 + width: 100,
35 38 },
36 39 {
37 40 title: '项目号',
38 41 dataIndex: 'projectNo',
39   - width: 60,
  42 + width: 100,
40 43 },
41 44 {
42 45 title: '内部编码',
43 46 dataIndex: 'innerNo',
44   - width: 60,
  47 + width: 100,
45 48 },
46 49 {
47 50 title: '客户po号',
48 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 85 const invoiceNo = ref();
... ... @@ -59,7 +92,10 @@
59 92 invoiceNo: invoiceNo.value,
60 93 });
61 94 const [registerTable] = useTable({
62   - api: () => getBaseInvoice({ invoiceNo: invoiceNo.value }),
  95 + api: () => {
  96 + const res = getBaseInvoice({ invoiceNo: invoiceNo.value });
  97 + return res;
  98 + },
63 99 columns: columns,
64 100 bordered: true,
65 101 });
... ...
src/views/project/finance/receive/TrackEdit.vue
... ... @@ -26,10 +26,7 @@
26 26 :action="updateDeductUrl"
27 27 @change="handleChange"
28 28 >
29   - <a-button>
30   - <!-- <upload-outlined></upload-outlined> -->
31   - 上传扣款单
32   - </a-button>
  29 + <a-button> 上传扣款单 </a-button>
33 30 </a-upload>
34 31 </a-space>
35 32 </div>
... ... @@ -48,16 +45,17 @@
48 45 import type { UploadProps } from 'ant-design-vue';
49 46 import { updateDeduct } from '@/api/project/invoice';
50 47  
  48 + const emit = defineEmits(['success']);
51 49 const fileList = ref<UploadProps['fileList']>([]);
52 50  
53   - const input1 = ref('');
  51 + const input1 = ref();
54 52 const deductUrl = ref();
55 53 const id = ref();
56 54 const invoiceNo = ref();
  55 + const uploadUrl = ref('http://47.104.8.35:18000/api/localStorage/upload_file_oss?name=');
57 56 const updateDeductUrl = ref('http://47.104.8.35:18000/api/localStorage/upload_file_oss?name=');
58 57  
59 58 const [register, { setDrawerProps, closeDrawer }] = useDrawerInner((data) => {
60   - console.log(data, 56561);
61 59 id.value = data.data.id;
62 60 invoiceNo.value = data.data.invoiceNo;
63 61 input1.value = data.data.deductAmount;
... ... @@ -66,21 +64,31 @@
66 64  
67 65 function handleChange(info) {
68 66 if (info.file.status == 'done') {
69   - updateDeductUrl.value = info.file.response.data.deductUrl;
  67 + updateDeductUrl.value = info.file.response.data.fileUrl;
70 68 deductUrl.value = updateDeductUrl.value;
71 69 }
72 70 }
73 71 function beforeUpload(info) {
74   - updateDeductUrl.value += info.name;
  72 + updateDeductUrl.value = uploadUrl.value + info.name;
75 73 }
76 74  
77 75 //完成编辑
78 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 83 await updateDeduct({
80 84 id: id.value,
81 85 invoiceNo: invoiceNo.value,
82 86 deductAmount: input1.value,
83 87 deductUrl: deductUrl.value,
84 88 });
  89 + // await updateDeduct(requestData);
  90 + fileList.value = [];
  91 + emit('success');
  92 + closeDrawer();
85 93 }
86 94 </script>
... ...
src/views/project/finance/receive/index.vue
... ... @@ -3,9 +3,9 @@
3 3 <BasicTable @register="registerTable">
4 4 <template #toolbar>
5 5 <a-button type="primary" @click="handleInvoiceAnalysis">收款单分析</a-button>
6   - <FinanceEdit @register="registerFinanceEdit" />
  6 + <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" />
7 7 <InvoiceAnalysis @register="registerInvoiceAnalysis" />
8   - <TrackEdit @register="registerTrackEdit" />
  8 + <TrackEdit @register="registerTrackEdit" @success="handleSuccess" />
9 9 <InvoiceDetail @register="registerInvoiceDetail" />
10 10 </template>
11 11 <template #bodyCell="{ column, record }">
... ... @@ -42,7 +42,7 @@
42 42 </div>
43 43 </template>
44 44 <script lang="ts" setup>
45   - import { defineComponent } from 'vue';
  45 + import { computed, defineComponent, ref } from 'vue';
46 46 import { BasicTable, useTable, BasicColumn, TableAction } from '/@/components/Table';
47 47 import { searchFormSchema, columns } from './receive.data';
48 48 import FinanceEdit from './FinanceEdit.vue';
... ... @@ -50,25 +50,37 @@
50 50 import InvoiceAnalysis from './InvoiceAnalysis.vue';
51 51 import InvoiceDetail from './InvoiceDetail.vue';
52 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 54 import { useModal } from '/@/components/Modal';
55 55 import { FilePptOutlined } from '@ant-design/icons-vue';
56 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 61 const [registerInvoiceAnalysis, { openModal: openInvoiceAnalysis }] = useModal();
59 62  
60 63 const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer();
61 64 const [registerTrackEdit, { openDrawer: openTrackEdit }] = useDrawer();
62 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 73 title: '',
66 74 api: getInvoice,
67 75 columns: columns,
68 76 bordered: true,
  77 + clickToRowSelect: false,
69 78 rowKey: 'id',
70 79 rowSelection: {
71 80 type: 'checkbox',
  81 + selectedRowKeys: checkedKeys,
  82 + onSelect,
  83 + onSelectAll,
72 84 },
73 85 formConfig: {
74 86 labelWidth: 120,
... ... @@ -88,6 +100,98 @@
88 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 195 function handleFinanceEdit(record) {
92 196 openFinanceEdit(true, {
93 197 data: record,
... ... @@ -101,18 +205,40 @@
101 205 function handleDelete(record) {
102 206 const id: string[] = Array.isArray(record.id) ? record.id : [record.id];
103 207 deleteInvoice({ ids: id });
  208 + setTimeout(() => {
  209 + reload();
  210 + }, 50);
104 211 }
105 212 function handleCommit(record) {
106 213 commit({ id: record.id });
  214 + setTimeout(() => {
  215 + reload();
  216 + }, 50);
107 217 }
108 218 function handleInvoiceDetail(record) {
109 219 openInvoiceDetail(true, {
110 220 data: record,
111 221 });
112 222 }
  223 + const { createMessage } = useMessage();
  224 + const { error } = createMessage;
113 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 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 244 </script>
... ...
src/views/project/finance/receive/receive.data.tsx
... ... @@ -7,16 +7,33 @@ import { ref } from &#39;vue&#39;;
7 7  
8 8 export const searchFormSchema: FormSchema[] = [
9 9 {
10   - field: 'invoice',
  10 + field: 'invoiceNo',
11 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 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 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 68 width: 80,
52 69 customRender: (column) => {
53 70 const deductUrl = column.record.deductUrl;
  71 + if (deductUrl == undefined) {
  72 + return;
  73 + }
54 74 return <FilePptOutlined style="font-size:25px" onClick={() => window.open(deductUrl)} />;
55 75 },
56 76 },
... ... @@ -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 162 //导出选中的订单
163 163 fieldVO.orderIds = props.ids;
164 164 exportLoading.value = true;
165   - console.log(fieldVO, 5656);
166 165 await orderExport({ ...searchData.value, fieldVO });
167 166 exportLoading.value = false;
168 167  
... ...
src/views/project/order/FormDetail/index.vue
... ... @@ -324,10 +324,10 @@
324 324 trackFormPanelRef?.value?.setFieldsValue({
325 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 333 if (inspectionFormPanelRef.value) {
... ... @@ -408,19 +408,30 @@
408 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 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 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 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 433 forms.trackStageInfo.sgsTestFinishTime = getFormattedDate();
422 434 }
423   - // console.log(forms.trackStageInfo, 5656);
424 435 await orderUpdate(forms);
425 436 closeDrawer();
426 437 emit('success', {});
... ... @@ -440,6 +451,9 @@
440 451 };
441 452 await orderCreate(forms);
442 453 closeDrawer();
  454 + setTimeout(() => {
  455 + reload();
  456 + }, 50);
443 457 emit('success', {});
444 458 }
445 459 } catch (error) {
... ...
src/views/project/order/InvoiceCreate.vue
... ... @@ -32,7 +32,7 @@
32 32 import { BasicModal, useModalInner } from '@/components/Modal';
33 33 import { computed, ref } from 'vue';
34 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 37 const fileList = ref<UploadProps['fileList']>([]);
38 38  
... ... @@ -43,13 +43,14 @@
43 43 const orderIds = ref();
44 44  
45 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 49 orderIds.value = data.data;
49 50 });
50 51 // const title = ref('');
51 52 async function handleOk() {
52   - await getInvoice({
  53 + await createInvoice({
53 54 invoiceNo: Input1.value,
54 55 bgUrl: bgUrl.value,
55 56 backRefundDate: Input2.value,
... ... @@ -59,7 +60,7 @@
59 60 }
60 61 function handleChange(info) {
61 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 66 function beforeUpload(info) {
... ...
src/views/project/order/PassCalculate.vue
... ... @@ -7,37 +7,32 @@
7 7 :bodyStyle="{ height: '100px' }"
8 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 11 </BasicModal>
12 12 </template>
13 13 <script lang="ts" setup>
14 14 import { BasicModal, useModalInner } from '@/components/Modal';
15 15 import { computed, ref } from 'vue';
  16 + import { passCalculate } from '@/api/project/order';
16 17  
17 18 const [register, { closeModal }] = useModalInner(async (data) => {
18   - console.log(data, 56562);
19 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 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 34 async function handleOk() {
41 35 closeModal();
  36 + num.value = '';
42 37 }
43 38 </script>
... ...
src/views/project/order/ProductInvoice.vue
... ... @@ -38,16 +38,22 @@
38 38 <script lang="ts" setup>
39 39 import { BasicModal, useModalInner } from '@/components/Modal';
40 40 import { computed, ref } from 'vue';
41   - import { getRefundDate } from '@/api/project/invoice';
  41 + import { payDate, checkCreate } from '@/api/project/invoice';
42 42  
43 43 const Input1 = ref('');
44 44 const Input2 = ref();
45   -
  45 + const res = ref();
46 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 51 async function handleOk() {
  52 + await checkCreate({
  53 + orderIds: res.value,
  54 + payedDate: Input2.value,
  55 + checkNo: Input1.value,
  56 + });
51 57 closeModal();
52 58 }
53 59 </script>
... ...
src/views/project/order/ProductText.vue
... ... @@ -50,7 +50,7 @@
50 50 </BasicModal>
51 51 </template>
52 52 <script lang="ts">
53   - import { defineComponent, ref, computed } from 'vue';
  53 + import { defineComponent, ref, computed, onMounted, onUpdated } from 'vue';
54 54 import { BasicModal, useModalInner } from '/@/components/Modal';
55 55 import { RadioGroup } from 'ant-design-vue';
56 56 import { EyeOutlined, FilePptOutlined } from '@ant-design/icons-vue';
... ... @@ -74,7 +74,12 @@
74 74 const isShow1 = ref(true); //选择公司页面
75 75 const isShow2 = ref(false); //生成PDF页面
76 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 83 const options = computed(() => {
79 84 // 运营总监-基本信息,跟单,质检
80 85 return [
... ... @@ -114,27 +119,29 @@
114 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 129 continue;
124 130 }
125   - if (customerCodeToCompanyMap[code] !== chooseCompany) {
126   - // 如果属于 customerCodes 的值与其公司不匹配,返回 false
  131 +
  132 + if (mappedCompany !== company) {
  133 + // 如果有一个不匹配,返回 false
127 134 return false;
128 135 }
129 136 }
130   - return true; // 如果所有 customerCodes 内的代码正确匹配,返回 true
  137 + // 如果所有匹配,返回 true
  138 + return true;
131 139 }
132 140 //生成pdf
133 141 // const customerCodeList: string[] = props.customerCodes;
134 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 146 if (!areValid) {
140 147 error('勾选订单与选择的公司不匹配');
... ...
src/views/project/order/TrackHistory.vue
... ... @@ -21,10 +21,10 @@
21 21 </template>
22 22 <template #description>
23 23 <div class="description">
24   - {{ item.modifyTime }}
  24 + {{ item.showOpinionType }}
25 25 </div>
26 26 <div class="info">
27   - <!-- <div><span>操作时间:</span>{{ formatToDateTime(item.createTime) }}</div> -->
  27 + <div>操作时间:{{ item.modifyTime }}</div>
28 28 </div>
29 29 </template>
30 30 </a-list-item-meta>
... ... @@ -54,20 +54,43 @@
54 54 const orderId = ref('');
55 55 // const activeKey = ref(1);
56 56  
  57 + function removeTFromTimestamp(timestamp: string): string {
  58 + // 使用 replace 方法将 "T" 替换为空字符串
  59 + return timestamp.replace('T', ' ');
  60 + }
  61 +
57 62 const getOrderOptLogFunc = async (data, page) => {
58 63 console.log('%c [ data ]-135', 'font-size:13px; background:pink; color:#bf2c9f;', data);
59 64 const res = await trackHistory({ orderId: data, page: page, pageSize: 20 });
60 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 71 const [register] = useDrawerInner((data) => {
65   - console.log(data, 5656);
66 72 orderId.value = data.id;
67 73 // const res = await trackHistory({ orderId: data, page: page, pageSize: 20 });
68 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 94 const pagination1 = computed(() => {
72 95 return {
73 96 show: true,
... ...
src/views/project/order/index.vue
... ... @@ -31,32 +31,36 @@
31 31 <template #bodyCell="{ column, record }">
32 32 <template v-if="column.key === 'action'">
33 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 62 :dropDownActions="
59   - role !== ROLE.DATA_REPORT_USER
  63 + role !== ROLE.DATA_REPORT_USER && role !== ROLE.PRODUCE
60 64 ? [
61 65 {
62 66 label: '历史记录',
... ... @@ -120,9 +124,10 @@
120 124 @change="handleChange"
121 125 class="passCalculate"
122 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 131 >确认样品</a-select-option
127 132 >
128 133 <a-select-option value="生产样品" @click="handlePassModal('生产样品')"
... ... @@ -142,7 +147,12 @@
142 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 156 <a-button
147 157 type="primary"
148 158 @click="handleProfitModal"
... ... @@ -208,6 +218,8 @@
208 218 import { useUserStoreWithOut } from '/@/store/modules/user';
209 219 import { ROLE } from './type.d';
210 220 import { getUserList } from '/@/api/project/account';
  221 + import { useMessage } from '/@/hooks/web/useMessage';
  222 + import { getBaseInvoice } from '/@/api/project/invoice';
211 223  
212 224 const orderStore = useOrderStoreWithOut();
213 225 const userStore = useUserStoreWithOut();
... ... @@ -234,7 +246,7 @@
234 246 },
235 247 setup() {
236 248 const checkedKeys = ref<Array<string | number>>([]);
237   - const selectedCustomCodes = ref<Array<string>>([]);
  249 + // const selectedCustomCodes = ref<Array<string>>([]);
238 250 const [profitModalRegister, { openModal: openProfitModal }] = useModal();
239 251 const [invoiceCreateModalRegister, { openModal: openInvoiceCreateModal }] = useModal();
240 252 const [productInvoiceModalRegister, { openModal: openProductInvoiceModal }] = useModal();
... ... @@ -279,6 +291,7 @@
279 291 pagination: {
280 292 total: 60,
281 293 },
  294 + clickToRowSelect: false,
282 295 columns: getOrderColumns(user?.roleSmallVO?.code),
283 296 useSearchForm: true,
284 297 formConfig: formConfig,
... ... @@ -292,47 +305,165 @@
292 305 onSelect,
293 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 324 function getFormValues() {
303 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 349 if (selected) {
307   - if (!selectedCustomCodes.value.includes(record.customerCode)) {
308   - // 如果不包含,则添加到 selectedCustomCodes
309   - selectedCustomCodes.value = [...selectedCustomCodes.value, record.customerCode];
310   - }
  350 + // 添加到 checkedKeys
311 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 370 } else {
  371 + // 从 checkedKeys 中移除
313 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 400 const changeIds = changeRows.map((item) => item.id);
321 401 const changeCustomerCodes = changeRows.map((item) => item.customerCode);
  402 + const changeProductionDepartments = changeRows.map((item) => item.productionDepartment);
  403 +
322 404 if (selected) {
  405 + // 添加到 checkedKeys
323 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 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 469 function handleEdit(record, e) {
... ... @@ -377,10 +508,20 @@
377 508 });
378 509 }
379 510  
380   - function handleInvoiceCreateModal() {
  511 + function handleInvoiceCreateModal(record) {
381 512 const form = getForm();
382 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 522 openInvoiceCreateModal(true, {
  523 + record: record,
  524 + customersCodes: selectedCustomCodes.value,
384 525 data: checkedKeys.value,
385 526 searchData: values,
386 527 });
... ... @@ -389,6 +530,14 @@
389 530 function handleProductInvoiceModal() {
390 531 const form = getForm();
391 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 541 openProductInvoiceModal(true, {
393 542 data: checkedKeys.value,
394 543 searchData: values,
... ... @@ -401,35 +550,46 @@
401 550 function handlePassModal(title) {
402 551 const form = getForm();
403 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 583 function handleProductModal() {
429 584 const form = getForm();
430 585 const values = form.getFieldsValue();
431   -
  586 + console.log(selectedCustomCodes.value, 5656);
  587 + if (selectedCustomCodes.value.length == 0) {
  588 + error('请选择订单');
  589 + return;
  590 + }
432 591 openProductModal(true, {
  592 + customers: selectedCustomCodes.value,
433 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 12  
13 13 const innerNoOptions = ref([]);
14 14 const projectNoOptions = ref([]);
  15 +const orderStore = useOrderStoreWithOut();
  16 +// const { productionDepartment: productionDepartmentOptions } = useOrderInfo(orderStore);
15 17  
16 18 // 可选择的列
17 19 export const SELECT_FIELD_COLUMNS = [
... ... @@ -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 376 export const ORDER_LIST_TRACK_FIELDS = [
357 377 {
358 378 title: '跟单信息',
... ... @@ -370,13 +390,17 @@ export const ORDER_LIST_TRACK_FIELDS = [
370 390 },
371 391 {
372 392 title: 'pp样品确认意见',
373   - width: 150,
  393 + width: 180,
374 394 dataIndex: 'ppConfirmResult',
375 395 customRender: (column) => {
376 396 const { record } = column || {};
377   - if (record?.trackStageInfo?.ppConfirmResult !== undefined) {
  397 + if (
  398 + record?.trackStageInfo?.ppConfirmResult !== undefined &&
  399 + record?.trackStageInfo?.ppConfirmTime !== undefined
  400 + ) {
378 401 const ppUpdate = record?.trackStageInfo?.ppConfirmResult;
379   - const ppUpdate2 = ppUpdate + '123';
  402 + const ppUpdateTime = record?.trackStageInfo?.ppConfirmTime;
  403 + const ppUpdate2 = modifyConfirmResult(ppUpdate, ppUpdateTime);
380 404 return ppUpdate2;
381 405 } else {
382 406 return record?.trackStageInfo?.ppConfirmResult;
... ... @@ -407,7 +431,17 @@ export const ORDER_LIST_TRACK_FIELDS = [
407 431 dataIndex: 'shippmentSampleConfirmResult',
408 432 customRender: (column) => {
409 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 468 dataIndex: 'aitexTestFinishResult',
435 469 customRender: (column) => {
436 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 496 dataIndex: 'sgsTestFinishResult',
453 497 customRender: (column) => {
454 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 779 {
726 780 field: 'productionDepartment',
727 781 component: 'Select',
  782 + // componentProps: {
  783 + // options: productionDepartmentOptions,
  784 + // },
728 785 labelWidth: 150,
729 786 label: '生产科',
730 787 rules: [{ required: true }],
... ... @@ -1122,29 +1179,29 @@ export const FIELDS_TRACK_STAGE_INFO = [
1122 1179 },
1123 1180 {
1124 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 1191 label: '最晚包材到货时间',
1135 1192 labelWidth: 250,
1136 1193 },
1137 1194 {
1138 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 1205 label: '最晚订舱+报关资料时间',
1149 1206 labelWidth: 250,
1150 1207 },
... ...
vite.config.ts
... ... @@ -21,6 +21,7 @@ export default defineApplicationConfig({
21 21 proxy: {
22 22 '/basic-api/order': {
23 23 target: 'http://47.104.8.35:18000',
  24 + // target: 'http://39.108.227.113:8000',
24 25 // target: 'http://localhost:8000',
25 26 // target: 'http://39.108.227.113:3000/mock/35',
26 27 // http://39.108.227.113:8000/order/erp/captcha/get_img_captcha_code
... ... @@ -30,6 +31,8 @@ export default defineApplicationConfig({
30 31 },
31 32 '/api/localStorage/upload': {
32 33 target: 'http://47.104.8.35:18000',
  34 + // target: 'http://39.108.227.113:8000',
  35 + // target: '192.168.31.250:18000',
33 36 // target: 'http://localhost:8000',
34 37 changeOrigin: true,
35 38 ws: true,
... ...