Commit 4120cdccc84112b144885f0f424aa6cb76ff4838

Authored by
2 parents 4d1d2e7c 13928607

Merge branch 'zwl-develop' into 'develop'

Zwl develop



See merge request !7
src/views/project/config/index.vue
... ... @@ -18,19 +18,19 @@
18 18 <Tabs.TabPane key="4" tab="邮件发送配置" v-if="role !== ROLE.FINANCE"
19 19 ><EmailPanel
20 20 /></Tabs.TabPane>
21   - <Tabs.TabPane key="5" tab="最后汇款日期">
  21 + <Tabs.TabPane key="5" tab="最后汇款日期" v-if="role !== ROLE.FINANCE">
22 22 <TablePanel :searchInfo="{ relationCode: 'orderHodTime' }" :column="5" />
23 23 </Tabs.TabPane>
24   - <Tabs.TabPane key="6" tab="提成成本配置">
  24 + <Tabs.TabPane key="6" tab="提成成本配置" v-if="role !== ROLE.FINANCE">
25 25 <TablePanel :searchInfo="{ relationCode: 'costSettingItem', relationName: currentYear }" :column="6" />
26 26 </Tabs.TabPane>
27 27 <Tabs.TabPane key="7" tab="销售额配置" v-if="role !== ROLE.FINANCE">
28 28 <TablePanel :searchInfo="{ relationCode: 'salesAmount' }" :column="7" />
29 29 </Tabs.TabPane>
30   - <Tabs.TabPane key="8" tab="生产科应付日期">
  30 + <Tabs.TabPane key="8" tab="生产科应付日期" v-if="role !== ROLE.FINANCE">
31 31 <TablePanel :searchInfo="{ relationCode: 'produHodTime' }" :column="8" />
32 32 </Tabs.TabPane>
33   - <Tabs.TabPane key="9" tab="生产科固定成本">
  33 + <Tabs.TabPane key="9" tab="生产科固定成本" v-if="role !== ROLE.FINANCE">
34 34 <TablePanel :searchInfo="{ relationCode: 'ProduceSettingItem', relationName: currentYear }" :column="9" />
35 35 </Tabs.TabPane>
36 36 <Tabs.TabPane key="10" tab="客户公司" v-if="role !== ROLE.FINANCE">
... ...
src/views/project/finance/financeList/index.vue
... ... @@ -25,7 +25,7 @@
25 25 <a-button
26 26 type="primary"
27 27 danger
28   - v-if="role == ROLE.ADMIN || role == ROLE.FINANCE"
  28 + v-if="role == ROLE.ADMIN"
29 29 :style="{ borderRadius: '5px 5px 5px 5px' }"
30 30 >
31 31 设置为已完成
... ...
src/views/project/finance/financeProfit/ProductProfit/InnerData/data.tsx
... ... @@ -9,6 +9,8 @@ import { useOrderInfo } from &#39;/@/hooks/component/order&#39;;
9 9  
10 10 const innerNoOptions = ref([]);
11 11 const projectNoOptions = ref([]);
  12 +const allProjectNoOptions = ref([]);
  13 +export { allProjectNoOptions };
12 14 const orderStore = useOrderStoreWithOut();
13 15 const {
14 16 customerCode,
... ... @@ -38,11 +40,10 @@ export const searchFormSchema = [
38 40 showSearch: true,
39 41 mode: 'multiple',
40 42 onSearch: async (value: any) => {
41   - projectNoOptions.value = await queryNoOptions('projectNo', value);
  43 + const result = await queryNoOptions('projectNo', value);
  44 + projectNoOptions.value = result;
  45 + allProjectNoOptions.value = result;
42 46 },
43   - // onSearch: async (value: any) => {
44   - // projectNoOptions.value = await queryNoOptions('projectNo', value);
45   - // },
46 47 },
47 48 },
48 49 {
... ...
src/views/project/finance/financeProfit/ProductProfit/InnerData/index.vue
1 1 <template>
2 2 <div>
3   - <BasicTable @register="registerTable" :bordered="true">
  3 + <BasicTable @register="registerTable" :bordered="true" @field-value-change="handleFieldValueChange">
4 4 <template #headerTop>
5 5 <a-alert type="info" show-icon>
6 6 <template #message>
... ... @@ -46,6 +46,11 @@
46 46 :style="{ borderRadius: '5px 5px 5px 5px' }"
47 47 >导出</a-button
48 48 >
  49 + <a-button
  50 + type="primary"
  51 + @click="handleAllProjectNoQuery"
  52 + style="margin-left: 8px;position: fixed;right: 29%;top: 107.5px;"
  53 + >全选</a-button>
49 54 </template>
50 55 </BasicTable>
51 56 <!-- <BasicModal
... ... @@ -68,7 +73,7 @@
68 73 <script setup lang="ts">
69 74 import { BasicTable, useTable, TableAction } from '/@/components/Table';
70 75 import { getInnerProfit, setInnerStatus } from '@/api/project/invoice';
71   - import { searchFormSchema, COLUMNS } from './data';
  76 + import { searchFormSchema, COLUMNS, allProjectNoOptions } from './data';
72 77 import { BasicModal, useModal } from '/@/components/Modal';
73 78 import { useMessage } from '/@/hooks/web/useMessage';
74 79 import { onMounted, ref, computed } from 'vue';
... ... @@ -111,11 +116,47 @@
111 116 message.value = '';
112 117 }
113 118 };
114   - const [registerTable, { reload, setSelectedRowKeys, getForm }] = useTable({
  119 + const [registerTable, { reload, getSelectRowKeys, getDataSource, setSelectedRowKeys, setProps, getForm }] = useTable({
  120 + title: '',
115 121 api: getInnerProfit,
116 122 bordered: true,
117 123 columns: COLUMNS,
118 124 rowKey: 'orderId',
  125 + formConfig: {
  126 + labelWidth: 120,
  127 + schemas: searchFormSchema,
  128 + autoSubmitOnEnter: true,
  129 + resetFunc: async () => {
  130 + localStorage.removeItem('isAllSelected');
  131 + },
  132 + },
  133 + // 处理查询参数,确保项目号数组正确传递
  134 + handleSearchInfoFn: (searchInfo) => {
  135 + // 获取表单实例
  136 + const formInstance = getForm();
  137 + if (formInstance) {
  138 + const formValues = formInstance.getFieldsValue();
  139 +
  140 + // 强制覆盖searchInfo,确保使用表单中的值
  141 + if (formValues.projectNo && formValues.projectNo.length > 0) {
  142 + // 确保传递的是数组而不是Proxy对象,并去重
  143 + const projectNoArray = [...new Set(formValues.projectNo)];
  144 + // 强制覆盖,不使用原始值
  145 + searchInfo = {
  146 + ...searchInfo,
  147 + projectNo: projectNoArray
  148 + };
  149 + } else {
  150 + // 如果表单中没有项目号,清空查询条件
  151 + searchInfo = {
  152 + ...searchInfo,
  153 + projectNo: []
  154 + };
  155 + }
  156 + }
  157 +
  158 + return searchInfo;
  159 + },
119 160 customRow: () => {
120 161 return {
121 162 onClick: (e) => {
... ... @@ -133,11 +174,6 @@
133 174 onSelectAll: onSelectAll,
134 175 checkStrictly: true,
135 176 },
136   - formConfig: {
137   - labelWidth: 120,
138   - schemas: searchFormSchema,
139   - autoSubmitOnEnter: true,
140   - },
141 177 useSearchForm: true,
142 178 showTableSetting: true,
143 179 showIndexColumn: false,
... ... @@ -485,5 +521,75 @@
485 521 }
486 522 setSelectedRowKeys(checkedKeys.value as any);
487 523 }
  524 +
  525 + function handleAllProjectNoQuery() {
  526 + // 检查是否有项目号选项
  527 + if (!allProjectNoOptions.value || allProjectNoOptions.value.length === 0) {
  528 + createMessage.warn('没有可查询的项目号!');
  529 + return;
  530 + }
  531 +
  532 + // 获取所有项目号的value值
  533 + const allProjectNos = allProjectNoOptions.value.map(item => {
  534 + // 处理不同的数据结构
  535 + if (typeof item === 'string') {
  536 + return item;
  537 + } else if (item && typeof item === 'object' && 'value' in item) {
  538 + return item.value;
  539 + } else if (item && typeof item === 'object' && 'label' in item) {
  540 + return item.label;
  541 + }
  542 + return item;
  543 + }).filter(Boolean); // 过滤掉空值
  544 +
  545 + if (allProjectNos.length === 0) {
  546 + createMessage.warn('没有有效的项目号!');
  547 + return;
  548 + }
  549 +
  550 + try {
  551 + // 提示用户全选成功
  552 + createMessage.success(`已全选 ${allProjectNos.length} 个项目号`);
  553 +
  554 + // 获取表单实例并设置表单值,将项目号填入搜索框
  555 + const formInstance = getForm();
  556 + if (formInstance && formInstance.setFieldsValue) {
  557 + formInstance.setFieldsValue({
  558 + projectNo: allProjectNos
  559 + });
  560 + }
  561 +
  562 + // 将allProjectNoOptions更新为已勾选的项目号数组,这样用户取消勾选时数组会同步更新
  563 + allProjectNoOptions.value = allProjectNos.map(projectNo => ({
  564 + label: projectNo,
  565 + value: projectNo
  566 + }));
  567 +
  568 + // 标记为全选状态
  569 + localStorage.setItem('isAllSelected', 'true');
  570 + } catch (error) {
  571 + console.error('全选失败:', error);
  572 + createMessage.error('全选失败,请检查网络连接!');
  573 + }
  574 + }
  575 +
  576 + // 监听表单字段变化
  577 + function handleFieldValueChange(field: string, value: any) {
  578 + // 如果是项目号字段变化且处于全选状态,同步更新查询条件
  579 + if (field === 'projectNo' && localStorage.getItem('isAllSelected') === 'true') {
  580 + // 确保value是数组格式,并去重
  581 + const projectNoArray = Array.isArray(value) ? [...new Set(value)] : [];
  582 +
  583 + // 强制重新加载表格,使用新的查询条件
  584 + reload({
  585 + searchInfo: {
  586 + projectNo: projectNoArray
  587 + }
  588 + });
  589 +
  590 + // 同时更新detailProjectNoKeys数组
  591 + detailProjectNoKeys.value = projectNoArray;
  592 + }
  593 + }
488 594 </script>
489 595 <style></style>
... ...
src/views/project/finance/financeProfit/ProductProfit/InnerProduce/data.tsx
... ... @@ -27,6 +27,8 @@ const userStore = useUserStoreWithOut();
27 27 // ];
28 28 const innerNoOptions = ref([]);
29 29 const projectNoOptions = ref([]);
  30 +const allProjectNoOptions = ref([]);
  31 +export { allProjectNoOptions };
30 32 const orderStore = useOrderStoreWithOut();
31 33 const {
32 34 customerCode,
... ... @@ -56,11 +58,10 @@ export const searchFormSchema = [
56 58 showSearch: true,
57 59 mode: 'multiple',
58 60 onSearch: async (value: any) => {
59   - projectNoOptions.value = await queryNoOptions('projectNo', value);
  61 + const result = await queryNoOptions('projectNo', value);
  62 + projectNoOptions.value = result;
  63 + allProjectNoOptions.value = result;
60 64 },
61   - // onSearch: async (value: any) => {
62   - // projectNoOptions.value = await queryNoOptions('projectNo', value);
63   - // },
64 65 },
65 66 },
66 67 {
... ...
src/views/project/finance/financeProfit/ProductProfit/InnerProduce/index.vue
1 1 <template>
2 2 <div>
3   - <BasicTable @register="registerTable" :bordered="true">
  3 + <BasicTable @register="registerTable" :bordered="true" @field-value-change="handleFieldValueChange">
4 4 <template #headerTop>
5 5 <a-alert type="info" show-icon>
6 6 <template #message>
... ... @@ -49,6 +49,11 @@
49 49 :style="{ borderRadius: '5px 5px 5px 5px' }"
50 50 >导出</a-button
51 51 >
  52 + <a-button
  53 + type="primary"
  54 + @click="handleAllProjectNoQuery"
  55 + style="margin-left: 8px;position: fixed;right: 29%;top: 107.5px;"
  56 + >全选</a-button>
52 57 </template>
53 58 </BasicTable>
54 59 <!-- <BasicModal
... ... @@ -71,7 +76,7 @@
71 76 <script setup lang="ts">
72 77 import { BasicTable, useTable, TableAction } from '/@/components/Table';
73 78 import { getInnerProduceProfit, setInnerProfitSetStatus } from '@/api/project/invoice';
74   - import { searchFormSchema, COLUMNS } from './data';
  79 + import { searchFormSchema, COLUMNS, allProjectNoOptions } from './data';
75 80 import { BasicModal, useModal } from '/@/components/Modal';
76 81 import { useMessage } from '/@/hooks/web/useMessage';
77 82 import { onMounted, ref, computed } from 'vue';
... ... @@ -110,11 +115,47 @@
110 115 message.value = '';
111 116 }
112 117 };
113   - const [registerTable, { reload, setSelectedRowKeys }] = useTable({
  118 + const [registerTable, { reload, getSelectRowKeys, getDataSource, setSelectedRowKeys, setProps, getForm }] = useTable({
  119 + title: '',
114 120 api: getInnerProduceProfit,
115 121 bordered: true,
116 122 columns: COLUMNS,
117 123 clickToRowSelect: false,
  124 + formConfig: {
  125 + labelWidth: 120,
  126 + schemas: searchFormSchema,
  127 + autoSubmitOnEnter: true,
  128 + resetFunc: async () => {
  129 + localStorage.removeItem('isAllSelected');
  130 + },
  131 + },
  132 + // 处理查询参数,确保项目号数组正确传递
  133 + handleSearchInfoFn: (searchInfo) => {
  134 + // 获取表单实例
  135 + const formInstance = getForm();
  136 + if (formInstance) {
  137 + const formValues = formInstance.getFieldsValue();
  138 +
  139 + // 强制覆盖searchInfo,确保使用表单中的值
  140 + if (formValues.projectNo && formValues.projectNo.length > 0) {
  141 + // 确保传递的是数组而不是Proxy对象,并去重
  142 + const projectNoArray = [...new Set(formValues.projectNo)];
  143 + // 强制覆盖,不使用原始值
  144 + searchInfo = {
  145 + ...searchInfo,
  146 + projectNo: projectNoArray
  147 + };
  148 + } else {
  149 + // 如果表单中没有项目号,清空查询条件
  150 + searchInfo = {
  151 + ...searchInfo,
  152 + projectNo: []
  153 + };
  154 + }
  155 + }
  156 +
  157 + return searchInfo;
  158 + },
118 159 rowKey: (record) => record.projectNoPrefix || record.id || record.serialNumber,
119 160 rowSelection: {
120 161 type: 'checkbox',
... ... @@ -122,11 +163,6 @@
122 163 onSelect: onSelect,
123 164 onSelectAll: onSelectAll,
124 165 },
125   - formConfig: {
126   - labelWidth: 120,
127   - schemas: searchFormSchema,
128   - autoSubmitOnEnter: true,
129   - },
130 166 useSearchForm: true,
131 167 showTableSetting: true,
132 168 showIndexColumn: false,
... ... @@ -408,5 +444,75 @@
408 444 handleClearChoose();
409 445 reload();
410 446 }
  447 +
  448 + function handleAllProjectNoQuery() {
  449 + // 检查是否有项目号选项
  450 + if (!allProjectNoOptions.value || allProjectNoOptions.value.length === 0) {
  451 + createMessage.warn('没有可查询的项目号!');
  452 + return;
  453 + }
  454 +
  455 + // 获取所有项目号的value值
  456 + const allProjectNos = allProjectNoOptions.value.map(item => {
  457 + // 处理不同的数据结构
  458 + if (typeof item === 'string') {
  459 + return item;
  460 + } else if (item && typeof item === 'object' && 'value' in item) {
  461 + return item.value;
  462 + } else if (item && typeof item === 'object' && 'label' in item) {
  463 + return item.label;
  464 + }
  465 + return item;
  466 + }).filter(Boolean); // 过滤掉空值
  467 +
  468 + if (allProjectNos.length === 0) {
  469 + createMessage.warn('没有有效的项目号!');
  470 + return;
  471 + }
  472 +
  473 + try {
  474 + // 提示用户全选成功
  475 + createMessage.success(`已全选 ${allProjectNos.length} 个项目号`);
  476 +
  477 + // 获取表单实例并设置表单值,将项目号填入搜索框
  478 + const formInstance = getForm();
  479 + if (formInstance && formInstance.setFieldsValue) {
  480 + formInstance.setFieldsValue({
  481 + projectNo: allProjectNos
  482 + });
  483 + }
  484 +
  485 + // 将allProjectNoOptions更新为已勾选的项目号数组,这样用户取消勾选时数组会同步更新
  486 + allProjectNoOptions.value = allProjectNos.map(projectNo => ({
  487 + label: projectNo,
  488 + value: projectNo
  489 + }));
  490 +
  491 + // 标记为全选状态
  492 + localStorage.setItem('isAllSelected', 'true');
  493 + } catch (error) {
  494 + console.error('全选失败:', error);
  495 + createMessage.error('全选失败,请检查网络连接!');
  496 + }
  497 + }
  498 +
  499 + // 监听表单字段变化
  500 + function handleFieldValueChange(field: string, value: any) {
  501 + // 如果是项目号字段变化且处于全选状态,同步更新查询条件
  502 + if (field === 'projectNo' && localStorage.getItem('isAllSelected') === 'true') {
  503 + // 确保value是数组格式,并去重
  504 + const projectNoArray = Array.isArray(value) ? [...new Set(value)] : [];
  505 +
  506 + // 强制重新加载表格,使用新的查询条件
  507 + reload({
  508 + searchInfo: {
  509 + projectNo: projectNoArray
  510 + }
  511 + });
  512 +
  513 + // 同时更新detailProjectNoKeys数组
  514 + detailProjectNoKeys.value = projectNoArray;
  515 + }
  516 + }
411 517 </script>
412 518 <style></style>
... ...
src/views/project/finance/financeProfit/ServiceProfit/PackageProfit/data.tsx
... ... @@ -9,6 +9,8 @@ import { useOrderInfo } from &#39;/@/hooks/component/order&#39;;
9 9  
10 10 const innerNoOptions = ref([]);
11 11 const projectNoOptions = ref([]);
  12 +const allProjectNoOptions = ref([]);
  13 +export { allProjectNoOptions };
12 14 const orderStore = useOrderStoreWithOut();
13 15 const {
14 16 customerCode,
... ... @@ -38,11 +40,10 @@ export const searchFormSchema = [
38 40 showSearch: true,
39 41 mode: 'multiple',
40 42 onSearch: async (value: any) => {
41   - projectNoOptions.value = await queryNoOptions('projectNo', value);
  43 + const result = await queryNoOptions('projectNo', value);
  44 + projectNoOptions.value = result;
  45 + allProjectNoOptions.value = result;
42 46 },
43   - // onSearch: async (value: any) => {
44   - // projectNoOptions.value = await queryNoOptions('projectNo', value);
45   - // },
46 47 },
47 48 },
48 49 {
... ...
src/views/project/finance/financeProfit/ServiceProfit/PackageProfit/index.vue
1 1 <template>
2 2 <div>
3   - <BasicTable @register="registerTable" :bordered="true">
  3 + <BasicTable @register="registerTable" :bordered="true" @field-value-change="handleFieldValueChange">
4 4 <template #headerTop>
5 5 <a-alert type="info" show-icon>
6 6 <template #message>
... ... @@ -49,6 +49,11 @@
49 49 :style="{ borderRadius: '5px 5px 5px 5px' }"
50 50 >导出</a-button
51 51 >
  52 + <a-button
  53 + type="primary"
  54 + @click="handleAllProjectNoQuery"
  55 + style="margin-left: 8px;position: fixed;right: 29%;top: 107.5px;"
  56 + >全选</a-button>
52 57 </template>
53 58 </BasicTable>
54 59 <!-- <BasicModal
... ... @@ -71,7 +76,7 @@
71 76 <script setup lang="ts">
72 77 import { BasicTable, useTable, TableAction } from '/@/components/Table';
73 78 import { getPackageProfit, setPackStatus } from '@/api/project/invoice';
74   - import { searchFormSchema, COLUMNS } from './data';
  79 + import { searchFormSchema, COLUMNS, allProjectNoOptions } from './data';
75 80 import { BasicModal, useModal } from '/@/components/Modal';
76 81 import { useMessage } from '/@/hooks/web/useMessage';
77 82 import { onMounted, ref, computed } from 'vue';
... ... @@ -115,16 +120,48 @@
115 120 message.value = '';
116 121 }
117 122 };
118   - const [registerTable, { reload, setSelectedRowKeys, getForm }] = useTable({
  123 + const [registerTable, { reload, getSelectRowKeys, getDataSource, setSelectedRowKeys, setProps, getForm }] = useTable({
  124 + title: '',
119 125 api: getPackageProfit,
120 126 bordered: true,
121 127 columns: COLUMNS,
122   - rowKey: (record) => record.orderId,
  128 + clickToRowSelect: false,
123 129 formConfig: {
124 130 labelWidth: 120,
125 131 schemas: searchFormSchema,
126 132 autoSubmitOnEnter: true,
  133 + resetFunc: async () => {
  134 + localStorage.removeItem('isAllSelected');
  135 + },
  136 + },
  137 + // 处理查询参数,确保项目号数组正确传递
  138 + handleSearchInfoFn: (searchInfo) => {
  139 + // 获取表单实例
  140 + const formInstance = getForm();
  141 + if (formInstance) {
  142 + const formValues = formInstance.getFieldsValue();
  143 +
  144 + // 强制覆盖searchInfo,确保使用表单中的值
  145 + if (formValues.projectNo && formValues.projectNo.length > 0) {
  146 + // 确保传递的是数组而不是Proxy对象,并去重
  147 + const projectNoArray = [...new Set(formValues.projectNo)];
  148 + // 强制覆盖,不使用原始值
  149 + searchInfo = {
  150 + ...searchInfo,
  151 + projectNo: projectNoArray
  152 + };
  153 + } else {
  154 + // 如果表单中没有项目号,清空查询条件
  155 + searchInfo = {
  156 + ...searchInfo,
  157 + projectNo: []
  158 + };
  159 + }
  160 + }
  161 +
  162 + return searchInfo;
127 163 },
  164 + rowKey: (record) => record.orderId,
128 165 // Add custom row props to prevent selection when clicking rows
129 166 customRow: () => {
130 167 return {
... ... @@ -479,5 +516,75 @@
479 516 }
480 517 setSelectedRowKeys(checkedKeys.value as any);
481 518 }
  519 +
  520 + function handleAllProjectNoQuery() {
  521 + // 检查是否有项目号选项
  522 + if (!allProjectNoOptions.value || allProjectNoOptions.value.length === 0) {
  523 + createMessage.warn('没有可查询的项目号!');
  524 + return;
  525 + }
  526 +
  527 + // 获取所有项目号的value值
  528 + const allProjectNos = allProjectNoOptions.value.map(item => {
  529 + // 处理不同的数据结构
  530 + if (typeof item === 'string') {
  531 + return item;
  532 + } else if (item && typeof item === 'object' && 'value' in item) {
  533 + return item.value;
  534 + } else if (item && typeof item === 'object' && 'label' in item) {
  535 + return item.label;
  536 + }
  537 + return item;
  538 + }).filter(Boolean); // 过滤掉空值
  539 +
  540 + if (allProjectNos.length === 0) {
  541 + createMessage.warn('没有有效的项目号!');
  542 + return;
  543 + }
  544 +
  545 + try {
  546 + // 提示用户全选成功
  547 + createMessage.success(`已全选 ${allProjectNos.length} 个项目号`);
  548 +
  549 + // 获取表单实例并设置表单值,将项目号填入搜索框
  550 + const formInstance = getForm();
  551 + if (formInstance && formInstance.setFieldsValue) {
  552 + formInstance.setFieldsValue({
  553 + projectNo: allProjectNos
  554 + });
  555 + }
  556 +
  557 + // 将allProjectNoOptions更新为已勾选的项目号数组,这样用户取消勾选时数组会同步更新
  558 + allProjectNoOptions.value = allProjectNos.map(projectNo => ({
  559 + label: projectNo,
  560 + value: projectNo
  561 + }));
  562 +
  563 + // 标记为全选状态
  564 + localStorage.setItem('isAllSelected', 'true');
  565 + } catch (error) {
  566 + console.error('全选失败:', error);
  567 + createMessage.error('全选失败,请检查网络连接!');
  568 + }
  569 + }
  570 +
  571 + // 监听表单字段变化
  572 + function handleFieldValueChange(field: string, value: any) {
  573 + // 如果是项目号字段变化且处于全选状态,同步更新查询条件
  574 + if (field === 'projectNo' && localStorage.getItem('isAllSelected') === 'true') {
  575 + // 确保value是数组格式,并去重
  576 + const projectNoArray = Array.isArray(value) ? [...new Set(value)] : [];
  577 +
  578 + // 强制重新加载表格,使用新的查询条件
  579 + reload({
  580 + searchInfo: {
  581 + projectNo: projectNoArray
  582 + }
  583 + });
  584 +
  585 + // 同时更新detailProjectNoKeys数组
  586 + detailProjectNoKeys.value = projectNoArray;
  587 + }
  588 + }
482 589 </script>
483 590 <style></style>
... ...
src/views/project/finance/financeProfit/ServiceProfit/ServiceProfit/FinanceEdit.vue
... ... @@ -25,10 +25,24 @@
25 25 />
26 26 <div style="margin: 16px 0"></div>
27 27 <div style="font-size: 15px">项目开始时间</div>
28   - <a-date-picker v-model:value="input3" :disabled="status3 === 'LOCKED'" auto-size />
  28 + <a-date-picker
  29 + v-model:value="input3"
  30 + :disabled="status3 === 'LOCKED'"
  31 + auto-size
  32 + placeholder="请选择项目开始时间"
  33 + format="YYYY-MM-DD"
  34 + value-format="YYYY-MM-DD"
  35 + />
29 36 <div style="margin: 16px 0"></div>
30 37 <div style="font-size: 15px">项目结束时间</div>
31   - <a-date-picker v-model:value="input4" :disabled="status4 === 'LOCKED'" auto-size />
  38 + <a-date-picker
  39 + v-model:value="input4"
  40 + :disabled="status4 === 'LOCKED'"
  41 + auto-size
  42 + placeholder="请选择项目结束时间"
  43 + format="YYYY-MM-DD"
  44 + value-format="YYYY-MM-DD"
  45 + />
32 46 <div style="margin: 16px 0"></div>
33 47 <div style="font-size: 15px">西班牙已发提成¥</div>
34 48 <a-input
... ... @@ -59,11 +73,14 @@
59 73 import { defineComponent, ref, computed, unref, toRaw, reactive } from 'vue';
60 74 import { getServiceEdit } from '@/api/project/invoice';
61 75 import { useMessage } from '/@/hooks/web/useMessage';
  76 + import { useUserStoreWithOut } from '/@/store/modules/user';
62 77 import { ROLE } from './type.d';
63 78 import type { Dayjs } from 'dayjs';
64 79 import dayjs from 'dayjs';
65 80  
66 81 const emit = defineEmits(['success']);
  82 + const userStore = useUserStoreWithOut();
  83 + const user = userStore.getUserInfo;
67 84 const role = computed(() => {
68 85 return user?.roleSmallVO?.code;
69 86 });
... ... @@ -141,8 +158,8 @@
141 158  
142 159 const input1 = ref();
143 160 const input2 = ref();
144   - const input3 = ref();
145   - const input4 = ref();
  161 + const input3 = ref<Dayjs | null>(null);
  162 + const input4 = ref<Dayjs | null>(null);
146 163  
147 164 const input5 = ref();
148 165 const id = ref();
... ... @@ -177,11 +194,23 @@
177 194 status5.value = data?.data?.lockFields?.paidRmbCommission;
178 195 }
179 196 id.value = data?.data?.projectNoPrefix;
180   - input1.value = data?.data?.developmentCopyRmbTotalPrice.toFixed(2);
181   - input2.value = data?.data?.spainPaidRmbCommission.toFixed(2);
182   - input3.value = dayjs(formatDateToDateOnly(data?.data?.projectStartTime));
183   - input4.value = dayjs(formatDateToDateOnly(data?.data?.projectEndTime));
184   - input5.value = data?.data?.paidRmbCommission.toFixed(2);
  197 + input1.value = data?.data?.developmentCopyRmbTotalPrice?.toFixed(2) || '';
  198 + input2.value = data?.data?.spainPaidRmbCommission?.toFixed(2) || '';
  199 +
  200 + // 确保日期值正确设置
  201 + if (data?.data?.projectStartTime) {
  202 + input3.value = dayjs(formatDateToDateOnly(data.data.projectStartTime));
  203 + } else {
  204 + input3.value = null;
  205 + }
  206 +
  207 + if (data?.data?.projectEndTime) {
  208 + input4.value = dayjs(formatDateToDateOnly(data.data.projectEndTime));
  209 + } else {
  210 + input4.value = null;
  211 + }
  212 +
  213 + input5.value = data?.data?.paidRmbCommission?.toFixed(2) || '';
185 214  
186 215 resetFields();
187 216 setDrawerProps({ confirmLoading: false });
... ... @@ -217,8 +246,8 @@
217 246 if (!visible) {
218 247 input1.value = '';
219 248 input2.value = '';
220   - input3.value = '';
221   - input4.value = '';
  249 + input3.value = null;
  250 + input4.value = null;
222 251 input5.value = '';
223 252 }
224 253 }
... ...
src/views/project/finance/financeProfit/ServiceProfit/ServiceProfit/data.tsx
... ... @@ -27,6 +27,8 @@ const userStore = useUserStoreWithOut();
27 27 // ];
28 28 const innerNoOptions = ref([]);
29 29 const projectNoOptions = ref([]);
  30 +const allProjectNoOptions = ref([]);
  31 +export { allProjectNoOptions };
30 32 const orderStore = useOrderStoreWithOut();
31 33 const {
32 34 customerCode,
... ... @@ -55,12 +57,17 @@ export const searchFormSchema = [
55 57 options: projectNoOptions,
56 58 showSearch: true,
57 59 mode: 'multiple',
58   - onSearch: async (value: any) => {
59   - projectNoOptions.value = await queryNoOptions('projectNo', value);
  60 + onSearch: async (value) => {
  61 + const result = await queryNoOptions('projectNo', value);
  62 + projectNoOptions.value = result;
  63 + allProjectNoOptions.value = projectNoOptions.value;
  64 + },
  65 + onChange: (value) => {
  66 + // 当项目号选择变化时,更新查询条件
  67 + if (localStorage.getItem('isAllSelected') === 'true') {
  68 +
  69 + }
60 70 },
61   - // onSearch: async (value: any) => {
62   - // projectNoOptions.value = await queryNoOptions('projectNo', value);
63   - // },
64 71 },
65 72 },
66 73 // {
... ... @@ -321,11 +328,13 @@ export const COLUMNS = [
321 328 axios
322 329 .post(
323 330 '/basic-api/project/businessProfit/export',
324   - {}, // 请求体为空
325 331 {
326   - params: {
327   - projectNoPrefix: column.record.projectNoPrefix, // 将参数放到查询字符串中
328   - },
  332 + ProjectNo:column.record.detailProjectNo
  333 + }, // 请求体为空
  334 + {
  335 + // params: {
  336 + // projectNoPrefix: column.record.projectNoPrefix, // 将参数放到查询字符串中
  337 + // },
329 338 headers: {
330 339 Authorization: `${token}`, // 去掉引号
331 340 },
... ...
src/views/project/finance/financeProfit/ServiceProfit/ServiceProfit/index.vue
1 1 <template>
2 2 <div>
3   - <BasicTable @register="registerTable" :bordered="true">
  3 + <BasicTable @register="registerTable" :bordered="true" @field-value-change="handleFieldValueChange">
4 4 <template #headerTop>
5 5 <a-alert type="info" show-icon>
6 6 <template #message>
... ... @@ -36,6 +36,11 @@
36 36 :style="{ borderRadius: '5px 5px 5px 5px' }"
37 37 >导出</a-button
38 38 >
  39 + <a-button
  40 + type="primary"
  41 + @click="handleAllProjectNoQuery"
  42 + style="margin-left: 8px;position: fixed;right: 29%;top: 107.5px;"
  43 + >全选</a-button>
39 44 </template>
40 45 </BasicTable>
41 46 <CheckDetail @register="checkModalRegister" :onGoFormDetail="handleGoFormDetail" />
... ... @@ -46,7 +51,8 @@
46 51 <script setup lang="ts">
47 52 import { BasicTable, useTable, TableAction } from '/@/components/Table';
48 53 import { getServiceProfit, setBusinessProfitSetStatus } from '@/api/project/invoice';
49   - import { searchFormSchema, COLUMNS } from './data';
  54 + import { saveConfig } from '@/api/sys/config';
  55 + import { searchFormSchema, COLUMNS, allProjectNoOptions } from './data';
50 56 import axios from 'axios';
51 57 import { useMessage } from '/@/hooks/web/useMessage';
52 58 import { onMounted, ref, computed, unref } from 'vue';
... ... @@ -73,7 +79,7 @@
73 79 const role = computed(() => {
74 80 return user?.roleSmallVO?.code;
75 81 });
76   - const [registerTable, { reload, getSelectRowKeys, getDataSource, setSelectedRowKeys }] = useTable({
  82 + const [registerTable, { reload, getSelectRowKeys, getDataSource, setSelectedRowKeys, setProps, getForm }] = useTable({
77 83 title: '',
78 84 api: getServiceProfit,
79 85 bordered: true,
... ... @@ -83,6 +89,49 @@
83 89 labelWidth: 120,
84 90 schemas: searchFormSchema,
85 91 autoSubmitOnEnter: true,
  92 + resetFunc: async () => {
  93 + localStorage.removeItem('isAllSelected');
  94 + setProps({
  95 + searchInfo: {
  96 + projectNo: []
  97 + }
  98 + });
  99 + },
  100 + },
  101 + handleSearchInfoFn: (searchInfo) => {
  102 + console.log('=== handleSearchInfoFn 开始 ===');
  103 + console.log('原始 searchInfo:', searchInfo);
  104 +
  105 + // 获取表单实例
  106 + const formInstance = getForm();
  107 + if (formInstance) {
  108 + const formValues = formInstance.getFieldsValue();
  109 + console.log('表单值:', formValues);
  110 +
  111 + // 强制覆盖searchInfo,确保使用表单中的值
  112 + if (formValues.projectNo && formValues.projectNo.length > 0) {
  113 + // 确保传递的是数组而不是Proxy对象,并去重
  114 + const projectNoArray = [...new Set(formValues.projectNo)];
  115 + // 强制覆盖,不使用原始值
  116 + searchInfo = {
  117 + ...searchInfo,
  118 + projectNo: projectNoArray
  119 + };
  120 + console.log('强制使用表单中的项目号:', projectNoArray);
  121 + } else {
  122 + // 如果表单中没有项目号,清空查询条件
  123 + searchInfo = {
  124 + ...searchInfo,
  125 + projectNo: []
  126 + };
  127 + console.log('清空项目号查询条件');
  128 + }
  129 + }
  130 +
  131 + console.log('处理后的 searchInfo:', searchInfo);
  132 + console.log('=== handleSearchInfoFn 结束 ===');
  133 +
  134 + return searchInfo;
86 135 },
87 136 rowKey: (record) => record.detailProjectNo || record.id || record.serialNumber,
88 137 rowSelection: {
... ... @@ -162,6 +211,34 @@
162 211 await orderStore.getDict();
163 212 });
164 213  
  214 + // 监听表单字段变化
  215 + function handleFieldValueChange(field: string, value: any) {
  216 + // 如果是项目号字段变化且处于全选状态,同步更新查询条件
  217 + if (field === 'projectNo' && localStorage.getItem('isAllSelected') === 'true') {
  218 + console.log('=== handleFieldValueChange 开始 ===');
  219 + console.log('field:', field);
  220 + console.log('value:', value);
  221 +
  222 + // 确保value是数组格式,并去重
  223 + const projectNoArray = Array.isArray(value) ? [...new Set(value)] : [];
  224 +
  225 + console.log('处理后的项目号数组:', projectNoArray);
  226 +
  227 + // 强制重新加载表格,使用新的查询条件
  228 + reload({
  229 + searchInfo: {
  230 + projectNo: projectNoArray
  231 + }
  232 + });
  233 +
  234 + // 同时更新detailProjectNoKeys数组
  235 + detailProjectNoKeys.value = projectNoArray;
  236 +
  237 + console.log('更新后的查询条件:', projectNoArray);
  238 + console.log('=== handleFieldValueChange 结束 ===');
  239 + }
  240 + }
  241 +
165 242 function handleFinanceEdit(record) {
166 243 openFinanceEdit(true, {
167 244 data: record,
... ... @@ -192,13 +269,23 @@
192 269  
193 270 async function handleStatus(record, status) {
194 271 try {
  272 + // 检查必要参数是否存在
  273 + if (!record.customerCode || !record.projectNoPrefix) {
  274 + createMessage.error('缺少必要的参数:客户编码或项目号');
  275 + return;
  276 + }
  277 +
195 278 await setBusinessProfitSetStatus({
196 279 customerCode: record.customerCode,
197 280 projectNo: record.projectNoPrefix,
  281 + status: status // 添加状态参数
198 282 });
  283 +
  284 + createMessage.success('状态更新成功!');
199 285 reload();
200 286 } catch (error) {
201 287 console.error('Error updating status:', error);
  288 + createMessage.error('状态更新失败:' + (error.message || '未知错误'));
202 289 }
203 290 }
204 291  
... ... @@ -365,5 +452,56 @@
365 452 }
366 453 setSelectedRowKeys(checkedKeys.value as any);
367 454 }
  455 + // 6/25未完成工作:全选查询
  456 + function handleAllProjectNoQuery() {
  457 + // 检查是否有项目号选项
  458 + if (!allProjectNoOptions.value || allProjectNoOptions.value.length === 0) {
  459 + createMessage.warn('没有可查询的项目号!');
  460 + return;
  461 + }
  462 +
  463 + // 获取所有项目号的value值
  464 + const allProjectNos = allProjectNoOptions.value.map(item => {
  465 + // 处理不同的数据结构
  466 + if (typeof item === 'string') {
  467 + return item;
  468 + } else if (item && typeof item === 'object' && 'value' in item) {
  469 + return item.value;
  470 + } else if (item && typeof item === 'object' && 'label' in item) {
  471 + return item.label;
  472 + }
  473 + return item;
  474 + }).filter(Boolean); // 过滤掉空值
  475 +
  476 + if (allProjectNos.length === 0) {
  477 + createMessage.warn('没有有效的项目号!');
  478 + return;
  479 + }
  480 +
  481 + try {
  482 + // 提示用户全选成功
  483 + createMessage.success(`已全选 ${allProjectNos.length} 个项目号`);
  484 +
  485 + // 获取表单实例并设置表单值,将项目号填入搜索框
  486 + const formInstance = getForm();
  487 + if (formInstance && formInstance.setFieldsValue) {
  488 + formInstance.setFieldsValue({
  489 + projectNo: allProjectNos
  490 + });
  491 + }
  492 +
  493 + // 将allProjectNoOptions更新为已勾选的项目号数组,这样用户取消勾选时数组会同步更新
  494 + allProjectNoOptions.value = allProjectNos.map(projectNo => ({
  495 + label: projectNo,
  496 + value: projectNo
  497 + }));
  498 +
  499 + // 标记为全选状态
  500 + localStorage.setItem('isAllSelected', 'true');
  501 + } catch (error) {
  502 + console.error('全选失败:', error);
  503 + createMessage.error('全选失败,请检查网络连接!');
  504 + }
  505 + }
368 506 </script>
369 507 <style></style>
... ...