Commit 4fa3b8872e8c8c9570a8ec9a814e0669d6ed2a02

Authored by zhongnanhuang
1 parent 1abb1273

feat: update 采购转发、下单

src/access.ts
@@ -6,5 +6,6 @@ export default (initialState: API.UserInfo) => { @@ -6,5 +6,6 @@ export default (initialState: API.UserInfo) => {
6 console.log(roleSmallVO?.code === 'admin'); 6 console.log(roleSmallVO?.code === 'admin');
7 return { 7 return {
8 canReadAdmin: roleSmallVO?.code === 'admin', 8 canReadAdmin: roleSmallVO?.code === 'admin',
  9 + canReadProcure: roleSmallVO?.code === 'procure',
9 }; 10 };
10 }; 11 };
src/app.ts
@@ -24,7 +24,7 @@ export const layout = () => { @@ -24,7 +24,7 @@ export const layout = () => {
24 // rightContentRender: () => <RightContent />, 24 // rightContentRender: () => <RightContent />,
25 // footerRender: () => <Footer />, 25 // footerRender: () => <Footer />,
26 }, 26 },
27 - // collapsed: true, 27 + collapsed: true,
28 }; 28 };
29 }; 29 };
30 30
src/pages/Order/components/CheckModal.tsx
1 import { RESPONSE_CODE } from '@/constants/enum'; 1 import { RESPONSE_CODE } from '@/constants/enum';
2 import { 2 import {
3 postServiceOrderCheckOrder, 3 postServiceOrderCheckOrder,
  4 + postServiceOrderFileProcess,
4 postServiceOrderFinanceCheckOrder, 5 postServiceOrderFinanceCheckOrder,
5 } from '@/services'; 6 } from '@/services';
6 import { ModalForm, ProFormTextArea } from '@ant-design/pro-components'; 7 import { ModalForm, ProFormTextArea } from '@ant-design/pro-components';
@@ -9,6 +10,7 @@ import Upload, { RcFile, UploadProps } from &#39;antd/es/upload&#39;; @@ -9,6 +10,7 @@ import Upload, { RcFile, UploadProps } from &#39;antd/es/upload&#39;;
9 import { useEffect, useRef, useState } from 'react'; 10 import { useEffect, useRef, useState } from 'react';
10 import { CHECK_TYPE, COMFIR_RECEIPT_IMAGES_NUMBER } from '../constant'; 11 import { CHECK_TYPE, COMFIR_RECEIPT_IMAGES_NUMBER } from '../constant';
11 // import { cloneDeep } from 'lodash'; 12 // import { cloneDeep } from 'lodash';
  13 +import { transImageFile } from '@/utils';
12 import { PlusOutlined } from '@ant-design/icons'; 14 import { PlusOutlined } from '@ant-design/icons';
13 import { cloneDeep } from 'lodash'; 15 import { cloneDeep } from 'lodash';
14 export default ({ 16 export default ({
@@ -32,6 +34,7 @@ export default ({ @@ -32,6 +34,7 @@ export default ({
32 const [fileList, setFileList] = useState<UploadFile[]>([]); 34 const [fileList, setFileList] = useState<UploadFile[]>([]);
33 const [uploading, setUploading] = useState(false); 35 const [uploading, setUploading] = useState(false);
34 const handleCancel = () => setPreviewOpen(false); 36 const handleCancel = () => setPreviewOpen(false);
  37 + const [messageApi, contextHolder] = message.useMessage();
35 console.log(uploading); 38 console.log(uploading);
36 const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => { 39 const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {
37 //fileListObj得在change里变化,change的参数是已经处理过的file数组 40 //fileListObj得在change里变化,change的参数是已经处理过的file数组
@@ -121,7 +124,7 @@ export default ({ @@ -121,7 +124,7 @@ export default ({
121 124
122 const handleBeforeUpload = (file: any) => { 125 const handleBeforeUpload = (file: any) => {
123 setFileList([...fileList, file]); 126 setFileList([...fileList, file]);
124 - return true; 127 + return false;
125 }; 128 };
126 129
127 const props: UploadProps = { 130 const props: UploadProps = {
@@ -137,7 +140,7 @@ export default ({ @@ -137,7 +140,7 @@ export default ({
137 fileList, 140 fileList,
138 onChange: handleChange, 141 onChange: handleChange,
139 accept: 'image/png, image/jpeg, image/png', 142 accept: 'image/png, image/jpeg, image/png',
140 - action: '/api/service/order/fileProcess', 143 + // action: '/api/service/order/fileProcess',
141 name: 'files', 144 name: 'files',
142 headers: { Authorization: localStorage.getItem('token') }, 145 headers: { Authorization: localStorage.getItem('token') },
143 }; 146 };
@@ -165,7 +168,64 @@ export default ({ @@ -165,7 +168,64 @@ export default ({
165 * 168 *
166 * @param body 财务审核 169 * @param body 财务审核
167 */ 170 */
168 - async function doFinancailCheck(body: object) { 171 + async function doFinancailCheck(values: any, isAgree: boolean) {
  172 + messageApi.open({
  173 + type: 'loading',
  174 + content: '正在上传图片...',
  175 + duration: 0,
  176 + });
  177 + //附件处理
  178 + let formData = new FormData();
  179 + //附件处理
  180 + for (let file of fileList) {
  181 + //有url的话取url(源文件),没url取thumbUrl。有url的时候thumbUrl是略缩图
  182 + if (file?.url === undefined || file?.url === null) {
  183 + formData.append(
  184 + 'files',
  185 + transImageFile(file?.thumbUrl),
  186 + file?.originFileObj?.name,
  187 + );
  188 + } else {
  189 + formData.append(
  190 + 'files',
  191 + transImageFile(file?.url),
  192 + file?.originFileObj?.name,
  193 + );
  194 + }
  195 + }
  196 + let res = await postServiceOrderFileProcess({
  197 + data: formData,
  198 + });
  199 + messageApi.destroy();
  200 + if (res.result === RESPONSE_CODE.SUCCESS) {
  201 + message.success('上传成功!');
  202 +
  203 + let fileUrls = res?.data?.map((item) => {
  204 + return { url: item };
  205 + });
  206 + //财务审核
  207 + const data = await postServiceOrderFinanceCheckOrder({
  208 + data: {
  209 + checkNotes: values.name,
  210 + ids: subOrderIds,
  211 + checkPassOrReject: isAgree,
  212 + invoicingCheckAnnex: fileUrls,
  213 + },
  214 + });
  215 + if (data.result === RESPONSE_CODE.SUCCESS) {
  216 + message.success(data.message);
  217 + onClose();
  218 + }
  219 + } else {
  220 + message.success('上传失败');
  221 + }
  222 + }
  223 +
  224 + /**
  225 + *
  226 + * @param body 售后审核
  227 + */
  228 + async function doAfterSalesCheck(body: object) {
169 const data = await postServiceOrderFinanceCheckOrder({ 229 const data = await postServiceOrderFinanceCheckOrder({
170 data: body, 230 data: body,
171 }); 231 });
@@ -210,7 +270,7 @@ export default ({ @@ -210,7 +270,7 @@ export default ({
210 myDoms.push( 270 myDoms.push(
211 <Button 271 <Button
212 key="驳回" 272 key="驳回"
213 - onClick={() => { 273 + onClick={async () => {
214 if (checkType(CHECK_TYPE.NORMAL)) { 274 if (checkType(CHECK_TYPE.NORMAL)) {
215 doCheck({ 275 doCheck({
216 flag: false, 276 flag: false,
@@ -221,18 +281,20 @@ export default ({ @@ -221,18 +281,20 @@ export default ({
221 return; 281 return;
222 } 282 }
223 283
224 - //附件处理  
225 - console.log(fileList);  
226 - let fileUrls = fileList?.map((file) => {  
227 - return { url: file.response?.data[0] };  
228 - });  
229 - //财务审核  
230 - doFinancailCheck({  
231 - checkNotes: form.getFieldValue('name'),  
232 - ids: subOrderIds,  
233 - checkPassOrReject: false,  
234 - invoicingCheckAnnex: fileUrls,  
235 - }); 284 + if (checkType(CHECK_TYPE.AFTER_SALES)) {
  285 + doAfterSalesCheck({
  286 + flag: false,
  287 + ids: subOrderIds,
  288 + externalProcurement: 0,
  289 + checkNotes: form.getFieldValue('name'),
  290 + });
  291 + return;
  292 + }
  293 +
  294 + if (checkType(CHECK_TYPE.FINALCIAL)) {
  295 + let values = { name: form.getFieldValue('name') };
  296 + doFinancailCheck(values, false);
  297 + }
236 setUploading(false); 298 setUploading(false);
237 }} 299 }}
238 > 300 >
@@ -240,7 +302,7 @@ export default ({ @@ -240,7 +302,7 @@ export default ({
240 </Button>, 302 </Button>,
241 ); 303 );
242 304
243 - //如果不是财务审核,那么显示这个外部采购 305 + //如果是仓库审核,那么显示这个外部采购
244 if (checkType(CHECK_TYPE.NORMAL)) { 306 if (checkType(CHECK_TYPE.NORMAL)) {
245 myDoms.push( 307 myDoms.push(
246 <Button 308 <Button
@@ -276,16 +338,19 @@ export default ({ @@ -276,16 +338,19 @@ export default ({
276 }); 338 });
277 } 339 }
278 340
279 - //附件处理  
280 - console.log(fileList); 341 + if (checkType(CHECK_TYPE.AFTER_SALES)) {
  342 + //审核通过
  343 + return doAfterSalesCheck({
  344 + flag: true,
  345 + ids: subOrderIds,
  346 + externalProcurement: 0,
  347 + checkNotes: values.name,
  348 + });
  349 + }
281 350
282 - //财务审核  
283 - // return doFinancailCheck({  
284 - // checkNotes: values.name,  
285 - // ids: subOrderIds,  
286 - // checkPassOrReject: true,  
287 - // invoicingCheckAnnex: fileUrls,  
288 - // }); 351 + if (checkType(CHECK_TYPE.FINALCIAL)) {
  352 + doFinancailCheck(values, true);
  353 + }
289 }} 354 }}
290 onOpenChange={setCheckVisible} 355 onOpenChange={setCheckVisible}
291 > 356 >
@@ -317,6 +382,8 @@ export default ({ @@ -317,6 +382,8 @@ export default ({
317 > 382 >
318 <img alt="图片预览" style={{ width: '100%' }} src={previewImage} /> 383 <img alt="图片预览" style={{ width: '100%' }} src={previewImage} />
319 </Modal> 384 </Modal>
  385 +
  386 + {contextHolder}
320 </> 387 </>
321 ); 388 );
322 }; 389 };
src/pages/Order/components/FinancialDrawer.tsx
@@ -65,6 +65,9 @@ export default ({ @@ -65,6 +65,9 @@ export default ({
65 invoicingStatus: form.getFieldValue('invoicingStatus'), 65 invoicingStatus: form.getFieldValue('invoicingStatus'),
66 mainorderOrSubOrderInvoicing: isMainOrder, 66 mainorderOrSubOrderInvoicing: isMainOrder,
67 afterInvoicingStatus: form.getFieldValue('afterInvoicingStatus'), 67 afterInvoicingStatus: form.getFieldValue('afterInvoicingStatus'),
  68 + financialReceiptIssuanceTime: form.getFieldValue(
  69 + 'financialReceiptIssuanceTime',
  70 + ),
68 }; 71 };
69 if (isEdit) { 72 if (isEdit) {
70 res = await postServiceOrderEditOrder({ data: body }); 73 res = await postServiceOrderEditOrder({ data: body });
@@ -132,6 +135,13 @@ export default ({ @@ -132,6 +135,13 @@ export default ({
132 initialValue={subOrders[0]?.invoicingTime} 135 initialValue={subOrders[0]?.invoicingTime}
133 />, 136 />,
134 <ProFormDatePicker 137 <ProFormDatePicker
  138 + key="financialReceiptIssuanceTime"
  139 + width="lg"
  140 + name="financialReceiptIssuanceTime"
  141 + label="开收据时间"
  142 + initialValue={subOrders[0]?.financialReceiptIssuanceTime}
  143 + />,
  144 + <ProFormDatePicker
135 key="collectMoneyTime" 145 key="collectMoneyTime"
136 width="lg" 146 width="lg"
137 name="collectMoneyTime" 147 name="collectMoneyTime"
src/pages/Order/components/FinancialEditDrawer.tsx 0 → 100644
  1 +// import { PlusOutlined } from '@ant-design/icons';
  2 +import { RESPONSE_CODE } from '@/constants/enum';
  3 +import { postServiceOrderNoNeedInvoicingEdit } from '@/services';
  4 +import { DrawerForm, ProFormDatePicker } from '@ant-design/pro-components';
  5 +import { Form, message } from 'antd';
  6 +
  7 +export default ({ subOrders, setVisible, onClose }) => {
  8 + const subOrderIds = subOrders?.map((subOrder) => {
  9 + return subOrder?.id;
  10 + });
  11 + const [form] = Form.useForm<{ collectMoneyTime: string; subIds: [] }>();
  12 + return (
  13 + <DrawerForm<{
  14 + collectMoneyTime: string;
  15 + subIds: [];
  16 + }>
  17 + open
  18 + title="收款时间"
  19 + resize={{
  20 + onResize() {
  21 + console.log('resize!');
  22 + },
  23 + maxWidth: window.innerWidth * 0.8,
  24 + minWidth: 400,
  25 + }}
  26 + initialValues={subOrders[0]}
  27 + form={form}
  28 + autoFocusFirstInput
  29 + drawerProps={{
  30 + destroyOnClose: true,
  31 + }}
  32 + submitTimeout={2000}
  33 + onFinish={async () => {
  34 + let res = await postServiceOrderNoNeedInvoicingEdit({
  35 + data: {
  36 + subIds: subOrderIds,
  37 + collectMoneyTime: form.getFieldValue('collectMoneyTime'),
  38 + },
  39 + });
  40 + if (res.result === RESPONSE_CODE.SUCCESS) {
  41 + message.success(res.message);
  42 + onClose();
  43 + }
  44 + }}
  45 + onOpenChange={(val) => {
  46 + return !val && setVisible(val);
  47 + }}
  48 + >
  49 + <ProFormDatePicker
  50 + key="collectMoneyTime"
  51 + width="lg"
  52 + name="collectMoneyTime"
  53 + label="收款时间"
  54 + />
  55 + </DrawerForm>
  56 + );
  57 +};
src/pages/Order/components/OrderDrawer.tsx
@@ -50,7 +50,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -50,7 +50,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
50 * @returns 获取开票选项 50 * @returns 获取开票选项
51 */ 51 */
52 function getInvoicingSelect() { 52 function getInvoicingSelect() {
53 - if (optType('edit') || optType('copy')) { 53 + if (optType('edit')) {
54 return enumToSelect(INVOCING_STATUS_OPTIONS_OLD); 54 return enumToSelect(INVOCING_STATUS_OPTIONS_OLD);
55 } 55 }
56 return enumToSelect(INVOCING_STATUS_OPTIONS); 56 return enumToSelect(INVOCING_STATUS_OPTIONS);
@@ -66,6 +66,12 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -66,6 +66,12 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
66 }, [data]); 66 }, [data]);
67 // let mainInfoDisbled = optType('edit'); 67 // let mainInfoDisbled = optType('edit');
68 if (optType('edit') || optType('copy')) { 68 if (optType('edit') || optType('copy')) {
  69 + //如果是复制,需要开票,不回显是否需要开票字段
  70 + if (optType('copy')) {
  71 + if (data.invoicingStatus === 'INVOICED') {
  72 + data.invoicingStatus = undefined;
  73 + }
  74 + }
69 //订单修改和新增的子订单列表命名是list 75 //订单修改和新增的子订单列表命名是list
70 data.list = data.subOrderInformationLists; 76 data.list = data.subOrderInformationLists;
71 //主订单事业部默认显示子订单第一条的事业部 77 //主订单事业部默认显示子订单第一条的事业部
@@ -350,7 +356,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -350,7 +356,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
350 {' | '} 356 {' | '}
351 <span style={{ color: '#666666' }}> 357 <span style={{ color: '#666666' }}>
352 {item.institutionContactName === undefined 358 {item.institutionContactName === undefined
353 - ? '无单位联系人' 359 + ? '无课题组'
354 : item.institutionContactName} 360 : item.institutionContactName}
355 </span> 361 </span>
356 {' | '} 362 {' | '}
@@ -411,9 +417,9 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -411,9 +417,9 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
411 width="lg" 417 width="lg"
412 key="institutionContactName" 418 key="institutionContactName"
413 name="institutionContactName" 419 name="institutionContactName"
414 - label="单位联系人"  
415 - placeholder="请输入单位联系人"  
416 - rules={[{ required: true, message: '单位联系人必填' }]} 420 + label="课题组"
  421 + placeholder="请输入课题组"
  422 + rules={[{ required: true, message: '课题组必填' }]}
417 // disabled={mainInfoDisbled} 423 // disabled={mainInfoDisbled}
418 /> 424 />
419 <ProFormTextArea 425 <ProFormTextArea
@@ -690,7 +696,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -690,7 +696,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
690 label={ 696 label={
691 <> 697 <>
692 <span>商品编码</span> 698 <span>商品编码</span>
693 - <span className="text-gray-400 text-xs pl-2"> 699 + <span className="pl-2 text-xs text-gray-400">
694 新增商品时,商品编码由系统自动生成 700 新增商品时,商品编码由系统自动生成
695 </span> 701 </span>
696 </> 702 </>
src/pages/Order/components/ProcureConvertModal.tsx 0 → 100644
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import {
  3 + postServiceOrderProcureConvertProcure,
  4 + postServiceOrderProvideProcurementRoles,
  5 +} from '@/services';
  6 +import {
  7 + ModalForm,
  8 + ProFormSelect,
  9 + ProFormTextArea,
  10 +} from '@ant-design/pro-components';
  11 +import { Form, message } from 'antd';
  12 +export default ({ setVisible, subOrders, onClose }) => {
  13 + const [form] = Form.useForm<{
  14 + procureName: string;
  15 + procureConvertNotes: string;
  16 + }>();
  17 +
  18 + // const [checkNotes, setCheckNotes] = useState<string>('');
  19 +
  20 + let subOrderIds: any[] = [];
  21 + //是单条子订单审核
  22 + if (subOrders === undefined) {
  23 + subOrderIds = [data.id];
  24 + } else {
  25 + subOrderIds = subOrders.map((subOrder) => subOrder.id);
  26 + }
  27 +
  28 + return (
  29 + <ModalForm<{
  30 + procureName: string;
  31 + procureConvertNotes: string;
  32 + }>
  33 + width={500}
  34 + open
  35 + title="采购转发"
  36 + form={form}
  37 + autoFocusFirstInput
  38 + modalProps={{
  39 + okText: '确认',
  40 + cancelText: '取消',
  41 + destroyOnClose: true,
  42 + onCancel: () => {
  43 + setVisible(false);
  44 + },
  45 + }}
  46 + submitter={{
  47 + render: (props, defaultDoms) => {
  48 + return defaultDoms;
  49 + },
  50 + }}
  51 + submitTimeout={2000}
  52 + onFinish={async (values) => {
  53 + const data = await postServiceOrderProcureConvertProcure({
  54 + data: {
  55 + procureName: values.procureName,
  56 + procureConvertNotes: values.procureConvertNotes,
  57 + subIds: subOrderIds,
  58 + },
  59 + });
  60 + if (data.result === RESPONSE_CODE.SUCCESS) {
  61 + message.success(data.message);
  62 + onClose();
  63 + }
  64 + }}
  65 + onOpenChange={setVisible}
  66 + >
  67 + <ProFormSelect
  68 + key="key"
  69 + label="采购名称"
  70 + width="lg"
  71 + name="procureName"
  72 + // options={options}
  73 + placeholder="请选择采购"
  74 + rules={[{ required: true, message: '采购必填' }]}
  75 + request={async () => {
  76 + const res = await postServiceOrderProvideProcurementRoles();
  77 + return res.data?.map((item) => {
  78 + return { label: item, value: item };
  79 + });
  80 + }}
  81 + />
  82 +
  83 + <ProFormTextArea
  84 + key="key"
  85 + label="转发备注"
  86 + width="lg"
  87 + name="procureConvertNotes"
  88 + // options={options}
  89 + placeholder="请填写转发备注"
  90 + />
  91 + </ModalForm>
  92 + );
  93 +};
src/pages/Order/constant.ts
@@ -24,6 +24,7 @@ export const PRODUCT_BELONG_DEPARTMENT_OPTIONS = { @@ -24,6 +24,7 @@ export const PRODUCT_BELONG_DEPARTMENT_OPTIONS = {
24 CUSTOMIZATION: '定制化事业部门', 24 CUSTOMIZATION: '定制化事业部门',
25 EXPERIMENTAL_EQUIPMENT: '实验设备事业部门', 25 EXPERIMENTAL_EQUIPMENT: '实验设备事业部门',
26 EXPERIMENTAL_CONSUMABLES: '实验耗材事业部门', 26 EXPERIMENTAL_CONSUMABLES: '实验耗材事业部门',
  27 + CLAMPING_APPARATUS: '工夹具事业部',
27 }; 28 };
28 29
29 export const INVOCING_STATUS_OPTIONS_OLD = { 30 export const INVOCING_STATUS_OPTIONS_OLD = {
@@ -33,6 +34,11 @@ export const INVOCING_STATUS_OPTIONS_OLD = { @@ -33,6 +34,11 @@ export const INVOCING_STATUS_OPTIONS_OLD = {
33 INVOICED: '需要开票', 34 INVOICED: '需要开票',
34 }; 35 };
35 36
  37 +export const PROCURE_ORDER_STATUS = {
  38 + PROCUREMENT_HAS_BEEN_ORDERED: '已下单',
  39 + PROCURE_NOT_ORDERED: '未下单',
  40 +};
  41 +
36 export const INVOCING_STATUS_OPTIONS = { 42 export const INVOCING_STATUS_OPTIONS = {
37 UN_INVOICE: '不需开票', 43 UN_INVOICE: '不需开票',
38 SPECIALLY_INVOICED: '专票', 44 SPECIALLY_INVOICED: '专票',
@@ -56,6 +62,7 @@ export const CHECK_TYPE = { @@ -56,6 +62,7 @@ export const CHECK_TYPE = {
56 FINALCIAL: 'FINALCIAL', 62 FINALCIAL: 'FINALCIAL',
57 PROCURE: 'PROCURE', 63 PROCURE: 'PROCURE',
58 SUPPLIER: 'SUPPLIER', 64 SUPPLIER: 'SUPPLIER',
  65 + AFTER_SALES: 'AFTER_SALES',
59 }; 66 };
60 67
61 /** 68 /**
@@ -159,53 +166,93 @@ export const TAGS_COLOR = new Map&lt;string, string&gt;([ @@ -159,53 +166,93 @@ export const TAGS_COLOR = new Map&lt;string, string&gt;([
159 ['NO_NEED_SEND', 'success'], 166 ['NO_NEED_SEND', 'success'],
160 ['PROCURE_CONVERT_WAREHOUSE_KEEPER', 'processing'], 167 ['PROCURE_CONVERT_WAREHOUSE_KEEPER', 'processing'],
161 ]); 168 ]);
162 -  
163 export const SALES_CODE_OPTIONS = [ 169 export const SALES_CODE_OPTIONS = [
164 - { label: 'HQ_Linda', value: 'HQ_Linda' },  
165 - { label: 'HQ-1_Rita', value: 'HQ-1_Rita' },  
166 - { label: 'HQ-2_Lisa', value: 'HQ-2_Lisa' },  
167 - { label: 'HQ-3_iris', value: 'HQ-3_iris' },  
168 - { label: 'HQ-4_Lynn', value: 'HQ-4_Lynn' },  
169 - { label: 'HQ-5_Jessica', value: 'HQ-5_Jessica' },  
170 - { label: 'HQ-6_smile', value: 'HQ-6_smile' },  
171 - { label: 'HQ-7_Yvonne', value: 'HQ-7_Yvonne' },  
172 - { label: 'HQ-8_Daniel', value: 'HQ-8_Daniel' },  
173 - { label: 'HQ-9_Wendy', value: 'HQ-9_Wendy' },  
174 - { label: 'W_strong', value: 'W_strong' },  
175 - { label: 'W-1_Alice', value: 'W-1_Alice' },  
176 - { label: 'W-2_Demi', value: 'W-2_Demi' },  
177 - { label: 'W-3_Nico', value: 'W-3_Nico' },  
178 - { label: 'W-4_kk', value: 'W-4_kk' },  
179 - { label: 'W-5_Alma', value: 'W-5_Alma' },  
180 - { label: 'W-6_Dream', value: 'W-6_Dream' },  
181 - { label: 'W-7_Aimee', value: 'W-7_Aimee' },  
182 - { label: 'XX_Tina', value: 'XX_Tina' },  
183 - { label: 'XX-2_Vivi', value: 'XX-2_Vivi' },  
184 - { label: 'XX-A1_Ada', value: 'XX-A1_Ada' },  
185 - { label: 'XX-A2_Amy', value: 'XX-A2_Amy' },  
186 - { label: 'XX-N1_Nancy', value: 'XX-N1_Nancy' },  
187 - { label: 'XX-N2_Sara', value: 'XX-N2_Sara' },  
188 - { label: 'XX-C_CC', value: 'XX-C_CC' },  
189 - { label: 'XX-L1_Lucy', value: 'XX-L1_Lucy' },  
190 - { label: 'XX-L2_Lulu', value: 'XX-L2_Lulu' },  
191 - { label: 'XX-P', value: 'XX-P' }, 170 + { label: 'D-Linda', value: 'D-Linda' },
  171 + { label: 'G-Rita', value: 'G-Rita' },
  172 + { label: 'G-Iris', value: 'G-Iris' },
  173 + { label: 'X-Jessica', value: 'X-Jessica' },
  174 + { label: 'G-Daniel', value: 'G-Daniel' },
  175 + { label: 'D-Strong', value: 'D-Strong' },
  176 + { label: 'T-Alice', value: 'T-Alice' },
  177 + { label: 'X-Demi', value: 'X-Demi' },
  178 + { label: 'T-Nico', value: 'T-Nico' },
  179 + { label: 'T-kk', value: 'T-kk' },
  180 + { label: 'T-Alma', value: 'T-Alma' },
  181 + { label: 'T-Dream', value: 'T-Dream' },
  182 + { label: 'T-Aimee', value: 'T-Aimee' },
  183 + { label: 'D-Tina', value: 'D-Tina' },
  184 + { label: 'D-Vivi', value: 'D-Vivi' },
  185 + { label: 'X-Ada', value: 'X-Ada' },
  186 + { label: 'X-Amy', value: 'X-Amy' },
  187 + { label: 'G-Nancy', value: 'G-Nancy' },
  188 + { label: 'X-Sara', value: 'X-Sara' },
  189 + { label: 'X-CC', value: 'X-CC' },
  190 + { label: 'X-Lucy', value: 'X-Lucy' },
  191 + { label: 'X-Lulu', value: 'X-Lulu' },
  192 + { label: 'X-P', value: 'X-P' },
192 { label: 'TB', value: 'TB' }, 193 { label: 'TB', value: 'TB' },
193 { label: 'HCTB', value: 'HCTB' }, 194 { label: 'HCTB', value: 'HCTB' },
194 { label: 'TBC', value: 'TBC' }, 195 { label: 'TBC', value: 'TBC' },
195 - { label: 'GW-3_iris', value: 'GW-3_iris' },  
196 - { label: 'GW-4_Lynn', value: 'GW-4_Lynn' },  
197 - { label: 'GW-6_smile', value: 'GW-6_smile' },  
198 - { label: 'GW-7_Yvonne', value: 'GW-7_Yvonne' },  
199 - { label: 'GW-9_Wendy', value: 'GW-9_Wendy' },  
200 - { label: 'W-9_Jack', value: 'W-9_Jack' },  
201 - { label: 'W-8_Andy', value: 'W-8_Andy' }, 196 + { label: 'G-Lisa', value: 'G-Lisa' },
  197 + { label: 'G-Lynn', value: 'G-Lynn' },
  198 + { label: 'G-Smile', value: 'G-Smile' },
  199 + { label: 'G-Yvonne', value: 'G-Yvonne' },
  200 + { label: 'G-Wendy', value: 'G-Wendy' },
  201 + { label: 'T-Andy', value: 'T-Andy' },
202 { label: 'CQ_Peter', value: 'CQ_Peter' }, 202 { label: 'CQ_Peter', value: 'CQ_Peter' },
203 { label: 'MA_A_Mao', value: 'MA_A_Mao' }, 203 { label: 'MA_A_Mao', value: 'MA_A_Mao' },
204 { label: 'CQ-2', value: 'CQ-2' }, 204 { label: 'CQ-2', value: 'CQ-2' },
205 { label: 'JJ', value: 'JJ' }, 205 { label: 'JJ', value: 'JJ' },
206 { label: 'CQ-3', value: 'CQ-3' }, 206 { label: 'CQ-3', value: 'CQ-3' },
  207 + { label: 'GW', value: 'GW' },
207 ]; 208 ];
208 209
  210 +// export const SALES_CODE_OPTIONS = [
  211 +// { label: 'HQ_Linda', value: 'HQ_Linda' },
  212 +// { label: 'HQ-1_Rita', value: 'HQ-1_Rita' },
  213 +// { label: 'HQ-2_Lisa', value: 'HQ-2_Lisa' },
  214 +// { label: 'HQ-3_iris', value: 'HQ-3_iris' },
  215 +// { label: 'HQ-4_Lynn', value: 'HQ-4_Lynn' },
  216 +// { label: 'HQ-5_Jessica', value: 'HQ-5_Jessica' },
  217 +// { label: 'HQ-6_smile', value: 'HQ-6_smile' },
  218 +// { label: 'HQ-7_Yvonne', value: 'HQ-7_Yvonne' },
  219 +// { label: 'HQ-8_Daniel', value: 'HQ-8_Daniel' },
  220 +// { label: 'HQ-9_Wendy', value: 'HQ-9_Wendy' },
  221 +// { label: 'W_strong', value: 'W_strong' },
  222 +// { label: 'W-1_Alice', value: 'W-1_Alice' },
  223 +// { label: 'W-2_Demi', value: 'W-2_Demi' },
  224 +// { label: 'W-3_Nico', value: 'W-3_Nico' },
  225 +// { label: 'W-4_kk', value: 'W-4_kk' },
  226 +// { label: 'W-5_Alma', value: 'W-5_Alma' },
  227 +// { label: 'W-6_Dream', value: 'W-6_Dream' },
  228 +// { label: 'W-7_Aimee', value: 'W-7_Aimee' },
  229 +// { label: 'XX_Tina', value: 'XX_Tina' },
  230 +// { label: 'XX-2_Vivi', value: 'XX-2_Vivi' },
  231 +// { label: 'XX-A1_Ada', value: 'XX-A1_Ada' },
  232 +// { label: 'XX-A2_Amy', value: 'XX-A2_Amy' },
  233 +// { label: 'XX-N1_Nancy', value: 'XX-N1_Nancy' },
  234 +// { label: 'XX-N2_Sara', value: 'XX-N2_Sara' },
  235 +// { label: 'XX-C_CC', value: 'XX-C_CC' },
  236 +// { label: 'XX-L1_Lucy', value: 'XX-L1_Lucy' },
  237 +// { label: 'XX-L2_Lulu', value: 'XX-L2_Lulu' },
  238 +// { label: 'XX-P', value: 'XX-P' },
  239 +// { label: 'TB', value: 'TB' },
  240 +// { label: 'HCTB', value: 'HCTB' },
  241 +// { label: 'TBC', value: 'TBC' },
  242 +// { label: 'GW-3_iris', value: 'GW-3_iris' },
  243 +// { label: 'GW-4_Lynn', value: 'GW-4_Lynn' },
  244 +// { label: 'GW-6_smile', value: 'GW-6_smile' },
  245 +// { label: 'GW-7_Yvonne', value: 'GW-7_Yvonne' },
  246 +// { label: 'GW-9_Wendy', value: 'GW-9_Wendy' },
  247 +// { label: 'W-9_Jack', value: 'W-9_Jack' },
  248 +// { label: 'W-8_Andy', value: 'W-8_Andy' },
  249 +// { label: 'CQ_Peter', value: 'CQ_Peter' },
  250 +// { label: 'MA_A_Mao', value: 'MA_A_Mao' },
  251 +// { label: 'CQ-2', value: 'CQ-2' },
  252 +// { label: 'JJ', value: 'JJ' },
  253 +// { label: 'CQ-3', value: 'CQ-3' },
  254 +// ];
  255 +
209 export const HISTORY_OPT_TYPE = new Map<string, string>([ 256 export const HISTORY_OPT_TYPE = new Map<string, string>([
210 ['DELETE', '作废'], 257 ['DELETE', '作废'],
211 ['UPDATE', '编辑'], 258 ['UPDATE', '编辑'],
src/pages/Order/index.tsx
@@ -4,11 +4,17 @@ import { @@ -4,11 +4,17 @@ import {
4 postServiceOrderAfterSalesCompletion, 4 postServiceOrderAfterSalesCompletion,
5 postServiceOrderNoNeedSend, 5 postServiceOrderNoNeedSend,
6 postServiceOrderOrderCancel, 6 postServiceOrderOrderCancel,
  7 + postServiceOrderProcureOrder,
7 postServiceOrderProcurePrint, 8 postServiceOrderProcurePrint,
8 postServiceOrderQueryServiceOrder, 9 postServiceOrderQueryServiceOrder,
9 } from '@/services'; 10 } from '@/services';
10 import { orderExport } from '@/services/order'; 11 import { orderExport } from '@/services/order';
11 -import { enumValueToLabel, formatDateTime } from '@/utils'; 12 +import {
  13 + copyToClipboard,
  14 + enumToProTableEnumValue,
  15 + enumValueToLabel,
  16 + formatDateTime,
  17 +} from '@/utils';
12 import { getUserInfo } from '@/utils/user'; 18 import { getUserInfo } from '@/utils/user';
13 import { 19 import {
14 ClockCircleTwoTone, 20 ClockCircleTwoTone,
@@ -50,11 +56,13 @@ import ConfirmReceiptModal from &#39;./components/ConfirmReceiptModal&#39;; @@ -50,11 +56,13 @@ import ConfirmReceiptModal from &#39;./components/ConfirmReceiptModal&#39;;
50 import DeliverInfoDrawer from './components/DeliverInfoDrawer'; 56 import DeliverInfoDrawer from './components/DeliverInfoDrawer';
51 import DeliverModal from './components/DeliverModal'; 57 import DeliverModal from './components/DeliverModal';
52 import FinancialDrawer from './components/FinancialDrawer'; 58 import FinancialDrawer from './components/FinancialDrawer';
  59 +import FinancialEditDrawer from './components/FinancialEditDrawer';
53 import HistoryModal from './components/HistoryModal'; 60 import HistoryModal from './components/HistoryModal';
54 import ImportModal from './components/ImportModal'; 61 import ImportModal from './components/ImportModal';
55 import OrderDrawer from './components/OrderDrawer'; 62 import OrderDrawer from './components/OrderDrawer';
56 import OrderNotesEditModal from './components/OrderNotesEditModal'; 63 import OrderNotesEditModal from './components/OrderNotesEditModal';
57 import ProcureCheckModal from './components/ProcureCheckModal'; 64 import ProcureCheckModal from './components/ProcureCheckModal';
  65 +import ProcureConvertModal from './components/ProcureConvertModal';
58 import SubOrderComfirmReceiptImagesModal from './components/SubOrderComfirmReceiptImagesModal'; 66 import SubOrderComfirmReceiptImagesModal from './components/SubOrderComfirmReceiptImagesModal';
59 import { 67 import {
60 AFTER_INVOICING_STATUS, 68 AFTER_INVOICING_STATUS,
@@ -65,6 +73,7 @@ import { @@ -65,6 +73,7 @@ import {
65 ORDER_STATUS_OPTIONS, 73 ORDER_STATUS_OPTIONS,
66 PAYMENT_CHANNEL_OPTIONS, 74 PAYMENT_CHANNEL_OPTIONS,
67 PAYMENT_METHOD_OPTIONS, 75 PAYMENT_METHOD_OPTIONS,
  76 + PROCURE_ORDER_STATUS,
68 PRODUCT_BELONG_DEPARTMENT_OPTIONS, 77 PRODUCT_BELONG_DEPARTMENT_OPTIONS,
69 TAGS_COLOR, 78 TAGS_COLOR,
70 getInvoicingType, 79 getInvoicingType,
@@ -85,6 +94,8 @@ const OrderPage = () =&gt; { @@ -85,6 +94,8 @@ const OrderPage = () =&gt; {
85 const [attachmentModalVisible, setAttachmentModalVisible] = 94 const [attachmentModalVisible, setAttachmentModalVisible] =
86 useState<boolean>(false); 95 useState<boolean>(false);
87 const [financialVisible, setFinancialVisible] = useState<boolean>(false); 96 const [financialVisible, setFinancialVisible] = useState<boolean>(false);
  97 + const [financialEditVisible, setFinancialEditVisible] =
  98 + useState<boolean>(false);
88 const [afterSalesDrawerVisible, setAfterSalesDrawerVisible] = 99 const [afterSalesDrawerVisible, setAfterSalesDrawerVisible] =
89 useState<boolean>(false); 100 useState<boolean>(false);
90 const [historyModalVisible, setHistoryModalVisible] = 101 const [historyModalVisible, setHistoryModalVisible] =
@@ -97,6 +108,8 @@ const OrderPage = () =&gt; { @@ -97,6 +108,8 @@ const OrderPage = () =&gt; {
97 useState<boolean>(false); 108 useState<boolean>(false);
98 const [procureCheckModalVisible, setProcureCheckModalVisible] = 109 const [procureCheckModalVisible, setProcureCheckModalVisible] =
99 useState<boolean>(false); 110 useState<boolean>(false);
  111 + const [procureConvertModalVisible, setProcureConvertModalVisible] =
  112 + useState<boolean>(false);
100 const [confirmReceiptVisible, setConfirmReceiptVisible] = 113 const [confirmReceiptVisible, setConfirmReceiptVisible] =
101 useState<boolean>(false); 114 useState<boolean>(false);
102 const [deliverVisible, setDeliverVisible] = useState<boolean>(false); 115 const [deliverVisible, setDeliverVisible] = useState<boolean>(false);
@@ -173,6 +186,30 @@ const OrderPage = () =&gt; { @@ -173,6 +186,30 @@ const OrderPage = () =&gt; {
173 refreshTable(); 186 refreshTable();
174 } 187 }
175 188
  189 + /**
  190 + * 复制订单到剪贴板
  191 + * @param record
  192 + */
  193 + function copyOrderToClipboard(record: any) {
  194 + let text = '';
  195 + text += record?.id;
  196 + text += ',' + record?.customerName;
  197 + text += ',' + record?.customerContactNumber;
  198 + text += ',' + record?.customerShippingAddress;
  199 + record?.subOrderInformationLists?.forEach((item) => {
  200 + text += '\n';
  201 + text += item?.productName;
  202 + text += ' ' + item?.parameters;
  203 + text += ' ' + item?.quantity;
  204 + text += ' ' + item?.unit;
  205 + });
  206 + if (copyToClipboard(text)) {
  207 + message.info('已复制到剪贴板');
  208 + } else {
  209 + message.info('无法复制到剪贴板');
  210 + }
  211 + }
  212 +
176 // const resize = () => { 213 // const resize = () => {
177 // // 计算元素底部到视口顶部的距离 214 // // 计算元素底部到视口顶部的距离
178 // let bottomDistance = document 215 // let bottomDistance = document
@@ -573,6 +610,21 @@ const OrderPage = () =&gt; { @@ -573,6 +610,21 @@ const OrderPage = () =&gt; {
573 {getOrderStatusTag(optRecord)} 610 {getOrderStatusTag(optRecord)}
574 </div> 611 </div>
575 612
  613 + {/**采购是否已下单状态 */}
  614 + {optRecord.procureOrderStatus !== null &&
  615 + optRecord.procureOrderStatus !== undefined ? (
  616 + <div className="overflow-hidden whitespace-no-wrap overflow-ellipsis">
  617 + <Tag color="success">
  618 + {enumValueToLabel(
  619 + optRecord.procureOrderStatus,
  620 + PROCURE_ORDER_STATUS,
  621 + )}
  622 + </Tag>
  623 + </div>
  624 + ) : (
  625 + ''
  626 + )}
  627 +
576 {/* 物流信息 */} 628 {/* 物流信息 */}
577 <div className="overflow-hidden whitespace-no-wrap overflow-ellipsis"> 629 <div className="overflow-hidden whitespace-no-wrap overflow-ellipsis">
578 {optRecord.orderStatus === 'CONFIRM_RECEIPT' || 630 {optRecord.orderStatus === 'CONFIRM_RECEIPT' ||
@@ -602,6 +654,21 @@ const OrderPage = () =&gt; { @@ -602,6 +654,21 @@ const OrderPage = () =&gt; {
602 </div> 654 </div>
603 </Flex> 655 </Flex>
604 <Flex className="w-[18%]" wrap="wrap" gap="small"> 656 <Flex className="w-[18%]" wrap="wrap" gap="small">
  657 + {optRecord.subPath?.includes('noNeedInvoicingEdit') ? (
  658 + <Button
  659 + className="p-0"
  660 + type="link"
  661 + onClick={() => {
  662 + setFinancialEditVisible(true);
  663 + setSelectedRows([optRecord]);
  664 + setIsMainOrder(false);
  665 + }}
  666 + >
  667 + 收款时间
  668 + </Button>
  669 + ) : (
  670 + ''
  671 + )}
605 {optRecord.subPath?.includes('sendProduct') ? ( 672 {optRecord.subPath?.includes('sendProduct') ? (
606 <Button 673 <Button
607 className="p-0" 674 className="p-0"
@@ -859,6 +926,22 @@ const OrderPage = () =&gt; { @@ -859,6 +926,22 @@ const OrderPage = () =&gt; {
859 '' 926 ''
860 )} 927 )}
861 928
  929 + {optRecord.subPath?.includes('procureConvertProcure') ? (
  930 + <Button
  931 + className="p-0"
  932 + type="link"
  933 + onClick={() => {
  934 + setSelectedRows([optRecord]);
  935 + setOrderCheckType(CHECK_TYPE.PROCURE);
  936 + setProcureConvertModalVisible(true);
  937 + }}
  938 + >
  939 + 转发
  940 + </Button>
  941 + ) : (
  942 + ''
  943 + )}
  944 +
862 {optRecord.subPath?.includes('rePrintOrder') ? ( 945 {optRecord.subPath?.includes('rePrintOrder') ? (
863 <Button 946 <Button
864 className="p-0" 947 className="p-0"
@@ -927,6 +1010,26 @@ const OrderPage = () =&gt; { @@ -927,6 +1010,26 @@ const OrderPage = () =&gt; {
927 '' 1010 ''
928 )} 1011 )}
929 1012
  1013 + {optRecord.subPath?.includes('procureOrder') ? (
  1014 + <ButtonConfirm
  1015 + className="p-0"
  1016 + title="是否已下单?"
  1017 + text="下单"
  1018 + onConfirm={async () => {
  1019 + let res = await postServiceOrderProcureOrder({
  1020 + data: { subIds: [optRecord.id] },
  1021 + });
  1022 + if (res.result === RESPONSE_CODE.SUCCESS) {
  1023 + message.success(res.message);
  1024 + refreshTable();
  1025 + return true;
  1026 + }
  1027 + }}
  1028 + />
  1029 + ) : (
  1030 + ''
  1031 + )}
  1032 +
930 {optRecord.subPath?.includes('noNeedSend') ? ( 1033 {optRecord.subPath?.includes('noNeedSend') ? (
931 <ButtonConfirm 1034 <ButtonConfirm
932 className="p-0" 1035 className="p-0"
@@ -1183,6 +1286,7 @@ const OrderPage = () =&gt; { @@ -1183,6 +1286,7 @@ const OrderPage = () =&gt; {
1183 <CopyTwoTone 1286 <CopyTwoTone
1184 className="hover:cursor-pointer" 1287 className="hover:cursor-pointer"
1185 onClick={() => { 1288 onClick={() => {
  1289 + copyOrderToClipboard(record);
1186 setOrderOptType('copy'); 1290 setOrderOptType('copy');
1187 setOrderDrawerVisible(true); 1291 setOrderDrawerVisible(true);
1188 let copy = cloneDeep(record); 1292 let copy = cloneDeep(record);
@@ -1195,7 +1299,14 @@ const OrderPage = () =&gt; { @@ -1195,7 +1299,14 @@ const OrderPage = () =&gt; {
1195 /> 1299 />
1196 </Tooltip> 1300 </Tooltip>
1197 ) : ( 1301 ) : (
1198 - '' 1302 + <Tooltip title="复制文本">
  1303 + <CopyTwoTone
  1304 + className="hover:cursor-pointer"
  1305 + onClick={() => {
  1306 + copyOrderToClipboard(record);
  1307 + }}
  1308 + />
  1309 + </Tooltip>
1199 )} 1310 )}
1200 1311
1201 <Tooltip title="历史"> 1312 <Tooltip title="历史">
@@ -1506,6 +1617,33 @@ const OrderPage = () =&gt; { @@ -1506,6 +1617,33 @@ const OrderPage = () =&gt; {
1506 '' 1617 ''
1507 )} 1618 )}
1508 1619
  1620 + {record.mainPath?.includes('') ? (
  1621 + <Button
  1622 + className="p-0"
  1623 + type="link"
  1624 + onClick={() => {
  1625 + let selectedSubOrders = selectedRowObj[record.id];
  1626 + setSelectedRows(selectedSubOrders);
  1627 + if (selectedSubOrders === undefined) {
  1628 + setSelectedRows(record.subOrderInformationLists);
  1629 + }
  1630 + for (let i = 0; i < selectedRows.length; i++) {
  1631 + if (selectedRows[i].orderStatus !== 'UNAUDITED') {
  1632 + message.error('请选择未审核的子订单进行审核');
  1633 + return;
  1634 + }
  1635 + }
  1636 + setOrderRow(record);
  1637 + setCheckVisible(true);
  1638 + setOrderCheckType(CHECK_TYPE.AFTER_SALES);
  1639 + }}
  1640 + >
  1641 + 售后审核
  1642 + </Button>
  1643 + ) : (
  1644 + ''
  1645 + )}
  1646 +
1509 {record.mainPath?.includes('noNeedSend') ? ( 1647 {record.mainPath?.includes('noNeedSend') ? (
1510 <ButtonConfirm 1648 <ButtonConfirm
1511 className="p-0" 1649 className="p-0"
@@ -1803,6 +1941,18 @@ const OrderPage = () =&gt; { @@ -1803,6 +1941,18 @@ const OrderPage = () =&gt; {
1803 }, 1941 },
1804 ); 1942 );
1805 1943
  1944 + //判断是否是采购,是的话新增一个筛选条件
  1945 + console.log(userInfo?.roleSmallVO?.code === 'procure');
  1946 + if (userInfo?.roleSmallVO?.code === 'procure') {
  1947 + mainOrdersColumns.push({
  1948 + title: '采购下单状态',
  1949 + dataIndex: 'procureOrderStatus',
  1950 + valueType: 'select',
  1951 + hideInTable: true,
  1952 + valueEnum: enumToProTableEnumValue(PROCURE_ORDER_STATUS),
  1953 + });
  1954 + }
  1955 +
1806 function toolBarRender() { 1956 function toolBarRender() {
1807 let roleCode = userInfo?.roleSmallVO?.code; 1957 let roleCode = userInfo?.roleSmallVO?.code;
1808 let toolBtns = []; 1958 let toolBtns = [];
@@ -2173,6 +2323,21 @@ const OrderPage = () =&gt; { @@ -2173,6 +2323,21 @@ const OrderPage = () =&gt; {
2173 /> 2323 />
2174 )} 2324 )}
2175 2325
  2326 + {financialEditVisible && (
  2327 + <FinancialEditDrawer
  2328 + subOrders={selectedRows}
  2329 + setVisible={() => {
  2330 + setFinancialEditVisible(false);
  2331 + setIsMainOrder(false);
  2332 + }}
  2333 + onClose={() => {
  2334 + setFinancialEditVisible(false);
  2335 + refreshTable();
  2336 + setIsMainOrder(false);
  2337 + }}
  2338 + />
  2339 + )}
  2340 +
2176 {orderPrintVisible && ( 2341 {orderPrintVisible && (
2177 <OrderPrintModal 2342 <OrderPrintModal
2178 mainOrder={orderRow} 2343 mainOrder={orderRow}
@@ -2290,6 +2455,18 @@ const OrderPage = () =&gt; { @@ -2290,6 +2455,18 @@ const OrderPage = () =&gt; {
2290 /> 2455 />
2291 )} 2456 )}
2292 2457
  2458 + {procureConvertModalVisible && (
  2459 + <ProcureConvertModal
  2460 + setVisible={setProcureConvertModalVisible}
  2461 + subOrders={selectedRows}
  2462 + onClose={() => {
  2463 + setProcureConvertModalVisible(false);
  2464 + setSelectedRows({});
  2465 + refreshTable();
  2466 + }}
  2467 + />
  2468 + )}
  2469 +
2293 {contextHolder} 2470 {contextHolder}
2294 </PageContainer> 2471 </PageContainer>
2295 ); 2472 );
src/services/definition.ts
@@ -709,6 +709,19 @@ export interface ProcureCheckOrderDto { @@ -709,6 +709,19 @@ export interface ProcureCheckOrderDto {
709 supplier?: string; 709 supplier?: string;
710 } 710 }
711 711
  712 +export interface ProcureConvertProcureDto {
  713 + /**
  714 + * @description
  715 + * 采购人名称
  716 + */
  717 + procureName?: string;
  718 + /**
  719 + * @description
  720 + * 子订单id集合
  721 + */
  722 + subIds?: Array<number>;
  723 +}
  724 +
712 export interface ProcureConvertWarehouseKeeperDto { 725 export interface ProcureConvertWarehouseKeeperDto {
713 /** 726 /**
714 * @description 727 * @description
@@ -722,6 +735,14 @@ export interface ProcureConvertWarehouseKeeperDto { @@ -722,6 +735,14 @@ export interface ProcureConvertWarehouseKeeperDto {
722 subIds?: Array<number>; 735 subIds?: Array<number>;
723 } 736 }
724 737
  738 +export interface ProcureOrderDto {
  739 + /**
  740 + * @description
  741 + * 子订单id集合
  742 + */
  743 + subIds?: Array<number>;
  744 +}
  745 +
725 export interface ProcurePrintDto { 746 export interface ProcurePrintDto {
726 /** 747 /**
727 * @description 748 * @description
@@ -876,6 +897,12 @@ export interface Dto { @@ -876,6 +897,12 @@ export interface Dto {
876 collectMoneyTime?: string; 897 collectMoneyTime?: string;
877 /** 898 /**
878 * @description 899 * @description
  900 + * 采购开收据时间
  901 + * @format date-time
  902 + */
  903 + financialReceiptIssuanceTime?: string;
  904 + /**
  905 + * @description
879 * 财务备注 906 * 财务备注
880 */ 907 */
881 invoicingNotes?: string; 908 invoicingNotes?: string;
src/services/request.ts
@@ -36,7 +36,9 @@ import type { @@ -36,7 +36,9 @@ import type {
36 OrderUnlockFieldApplyVO, 36 OrderUnlockFieldApplyVO,
37 OrderUpdateVO, 37 OrderUpdateVO,
38 ProcureCheckOrderDto, 38 ProcureCheckOrderDto,
  39 + ProcureConvertProcureDto,
39 ProcureConvertWarehouseKeeperDto, 40 ProcureConvertWarehouseKeeperDto,
  41 + ProcureOrderDto,
40 ProcurePrintDto, 42 ProcurePrintDto,
41 ProductInformationDto, 43 ProductInformationDto,
42 QueryAnnexDto, 44 QueryAnnexDto,
@@ -5838,6 +5840,77 @@ export const postServiceOrderInvoicing = /* #__PURE__ */ (() =&gt; { @@ -5838,6 +5840,77 @@ export const postServiceOrderInvoicing = /* #__PURE__ */ (() =&gt; {
5838 return request; 5840 return request;
5839 })(); 5841 })();
5840 5842
  5843 +/** @description request parameter type for postServiceOrderNoNeedInvoicingEdit */
  5844 +export interface PostServiceOrderNoNeedInvoicingEditOption {
  5845 + /**
  5846 + * @description
  5847 + * dto
  5848 + */
  5849 + body: {
  5850 + /**
  5851 + @description
  5852 + dto */
  5853 + dto: Dto;
  5854 + };
  5855 +}
  5856 +
  5857 +/** @description response type for postServiceOrderNoNeedInvoicingEdit */
  5858 +export interface PostServiceOrderNoNeedInvoicingEditResponse {
  5859 + /**
  5860 + * @description
  5861 + * OK
  5862 + */
  5863 + 200: ServerResult;
  5864 + /**
  5865 + * @description
  5866 + * Created
  5867 + */
  5868 + 201: any;
  5869 + /**
  5870 + * @description
  5871 + * Unauthorized
  5872 + */
  5873 + 401: any;
  5874 + /**
  5875 + * @description
  5876 + * Forbidden
  5877 + */
  5878 + 403: any;
  5879 + /**
  5880 + * @description
  5881 + * Not Found
  5882 + */
  5883 + 404: any;
  5884 +}
  5885 +
  5886 +export type PostServiceOrderNoNeedInvoicingEditResponseSuccess =
  5887 + PostServiceOrderNoNeedInvoicingEditResponse[200];
  5888 +/**
  5889 + * @description
  5890 + * 财务无需开票的编辑按钮
  5891 + * @tags 内部订单
  5892 + * @produces *
  5893 + * @consumes application/json
  5894 + */
  5895 +export const postServiceOrderNoNeedInvoicingEdit = /* #__PURE__ */ (() => {
  5896 + const method = 'post';
  5897 + const url = '/service/order/noNeedInvoicingEdit';
  5898 + function request(
  5899 + option: PostServiceOrderNoNeedInvoicingEditOption,
  5900 + ): Promise<PostServiceOrderNoNeedInvoicingEditResponseSuccess> {
  5901 + return requester(request.url, {
  5902 + method: request.method,
  5903 + ...option,
  5904 + }) as unknown as Promise<PostServiceOrderNoNeedInvoicingEditResponseSuccess>;
  5905 + }
  5906 +
  5907 + /** http method */
  5908 + request.method = method;
  5909 + /** request url */
  5910 + request.url = url;
  5911 + return request;
  5912 +})();
  5913 +
5841 /** @description request parameter type for postServiceOrderNoNeedSend */ 5914 /** @description request parameter type for postServiceOrderNoNeedSend */
5842 export interface PostServiceOrderNoNeedSendOption { 5915 export interface PostServiceOrderNoNeedSendOption {
5843 /** 5916 /**
@@ -6122,6 +6195,77 @@ export const postServiceOrderProcureCheckOrder = /* #__PURE__ */ (() =&gt; { @@ -6122,6 +6195,77 @@ export const postServiceOrderProcureCheckOrder = /* #__PURE__ */ (() =&gt; {
6122 return request; 6195 return request;
6123 })(); 6196 })();
6124 6197
  6198 +/** @description request parameter type for postServiceOrderProcureConvertProcure */
  6199 +export interface PostServiceOrderProcureConvertProcureOption {
  6200 + /**
  6201 + * @description
  6202 + * dto
  6203 + */
  6204 + body: {
  6205 + /**
  6206 + @description
  6207 + dto */
  6208 + dto: ProcureConvertProcureDto;
  6209 + };
  6210 +}
  6211 +
  6212 +/** @description response type for postServiceOrderProcureConvertProcure */
  6213 +export interface PostServiceOrderProcureConvertProcureResponse {
  6214 + /**
  6215 + * @description
  6216 + * OK
  6217 + */
  6218 + 200: ServerResult;
  6219 + /**
  6220 + * @description
  6221 + * Created
  6222 + */
  6223 + 201: any;
  6224 + /**
  6225 + * @description
  6226 + * Unauthorized
  6227 + */
  6228 + 401: any;
  6229 + /**
  6230 + * @description
  6231 + * Forbidden
  6232 + */
  6233 + 403: any;
  6234 + /**
  6235 + * @description
  6236 + * Not Found
  6237 + */
  6238 + 404: any;
  6239 +}
  6240 +
  6241 +export type PostServiceOrderProcureConvertProcureResponseSuccess =
  6242 + PostServiceOrderProcureConvertProcureResponse[200];
  6243 +/**
  6244 + * @description
  6245 + * 采购转给采购
  6246 + * @tags 内部订单
  6247 + * @produces *
  6248 + * @consumes application/json
  6249 + */
  6250 +export const postServiceOrderProcureConvertProcure = /* #__PURE__ */ (() => {
  6251 + const method = 'post';
  6252 + const url = '/service/order/procureConvertProcure';
  6253 + function request(
  6254 + option: PostServiceOrderProcureConvertProcureOption,
  6255 + ): Promise<PostServiceOrderProcureConvertProcureResponseSuccess> {
  6256 + return requester(request.url, {
  6257 + method: request.method,
  6258 + ...option,
  6259 + }) as unknown as Promise<PostServiceOrderProcureConvertProcureResponseSuccess>;
  6260 + }
  6261 +
  6262 + /** http method */
  6263 + request.method = method;
  6264 + /** request url */
  6265 + request.url = url;
  6266 + return request;
  6267 +})();
  6268 +
6125 /** @description request parameter type for postServiceOrderProcureConvertWarehouseKeeper */ 6269 /** @description request parameter type for postServiceOrderProcureConvertWarehouseKeeper */
6126 export interface PostServiceOrderProcureConvertWarehouseKeeperOption { 6270 export interface PostServiceOrderProcureConvertWarehouseKeeperOption {
6127 /** 6271 /**
@@ -6194,6 +6338,77 @@ export const postServiceOrderProcureConvertWarehouseKeeper = @@ -6194,6 +6338,77 @@ export const postServiceOrderProcureConvertWarehouseKeeper =
6194 return request; 6338 return request;
6195 })(); 6339 })();
6196 6340
  6341 +/** @description request parameter type for postServiceOrderProcureOrder */
  6342 +export interface PostServiceOrderProcureOrderOption {
  6343 + /**
  6344 + * @description
  6345 + * dto
  6346 + */
  6347 + body: {
  6348 + /**
  6349 + @description
  6350 + dto */
  6351 + dto: ProcureOrderDto;
  6352 + };
  6353 +}
  6354 +
  6355 +/** @description response type for postServiceOrderProcureOrder */
  6356 +export interface PostServiceOrderProcureOrderResponse {
  6357 + /**
  6358 + * @description
  6359 + * OK
  6360 + */
  6361 + 200: ServerResult;
  6362 + /**
  6363 + * @description
  6364 + * Created
  6365 + */
  6366 + 201: any;
  6367 + /**
  6368 + * @description
  6369 + * Unauthorized
  6370 + */
  6371 + 401: any;
  6372 + /**
  6373 + * @description
  6374 + * Forbidden
  6375 + */
  6376 + 403: any;
  6377 + /**
  6378 + * @description
  6379 + * Not Found
  6380 + */
  6381 + 404: any;
  6382 +}
  6383 +
  6384 +export type PostServiceOrderProcureOrderResponseSuccess =
  6385 + PostServiceOrderProcureOrderResponse[200];
  6386 +/**
  6387 + * @description
  6388 + * 采购下单按钮
  6389 + * @tags 内部订单
  6390 + * @produces *
  6391 + * @consumes application/json
  6392 + */
  6393 +export const postServiceOrderProcureOrder = /* #__PURE__ */ (() => {
  6394 + const method = 'post';
  6395 + const url = '/service/order/procureOrder';
  6396 + function request(
  6397 + option: PostServiceOrderProcureOrderOption,
  6398 + ): Promise<PostServiceOrderProcureOrderResponseSuccess> {
  6399 + return requester(request.url, {
  6400 + method: request.method,
  6401 + ...option,
  6402 + }) as unknown as Promise<PostServiceOrderProcureOrderResponseSuccess>;
  6403 + }
  6404 +
  6405 + /** http method */
  6406 + request.method = method;
  6407 + /** request url */
  6408 + request.url = url;
  6409 + return request;
  6410 +})();
  6411 +
6197 /** @description request parameter type for postServiceOrderProcurePrint */ 6412 /** @description request parameter type for postServiceOrderProcurePrint */
6198 export interface PostServiceOrderProcurePrintOption { 6413 export interface PostServiceOrderProcurePrintOption {
6199 /** 6414 /**
@@ -6576,6 +6791,60 @@ export const getServiceOrderProvidePaymentMethod = /* #__PURE__ */ (() =&gt; { @@ -6576,6 +6791,60 @@ export const getServiceOrderProvidePaymentMethod = /* #__PURE__ */ (() =&gt; {
6576 return request; 6791 return request;
6577 })(); 6792 })();
6578 6793
  6794 +/** @description response type for postServiceOrderProvideProcurementRoles */
  6795 +export interface PostServiceOrderProvideProcurementRolesResponse {
  6796 + /**
  6797 + * @description
  6798 + * OK
  6799 + */
  6800 + 200: ServerResult;
  6801 + /**
  6802 + * @description
  6803 + * Created
  6804 + */
  6805 + 201: any;
  6806 + /**
  6807 + * @description
  6808 + * Unauthorized
  6809 + */
  6810 + 401: any;
  6811 + /**
  6812 + * @description
  6813 + * Forbidden
  6814 + */
  6815 + 403: any;
  6816 + /**
  6817 + * @description
  6818 + * Not Found
  6819 + */
  6820 + 404: any;
  6821 +}
  6822 +
  6823 +export type PostServiceOrderProvideProcurementRolesResponseSuccess =
  6824 + PostServiceOrderProvideProcurementRolesResponse[200];
  6825 +/**
  6826 + * @description
  6827 + * 提供采购角色
  6828 + * @tags 内部订单
  6829 + * @produces *
  6830 + * @consumes application/json
  6831 + */
  6832 +export const postServiceOrderProvideProcurementRoles = /* #__PURE__ */ (() => {
  6833 + const method = 'post';
  6834 + const url = '/service/order/provideProcurementRoles';
  6835 + function request(): Promise<PostServiceOrderProvideProcurementRolesResponseSuccess> {
  6836 + return requester(request.url, {
  6837 + method: request.method,
  6838 + }) as unknown as Promise<PostServiceOrderProvideProcurementRolesResponseSuccess>;
  6839 + }
  6840 +
  6841 + /** http method */
  6842 + request.method = method;
  6843 + /** request url */
  6844 + request.url = url;
  6845 + return request;
  6846 +})();
  6847 +
6579 /** @description response type for getServiceOrderProvideProductBelongDepartment */ 6848 /** @description response type for getServiceOrderProvideProductBelongDepartment */
6580 export interface GetServiceOrderProvideProductBelongDepartmentResponse { 6849 export interface GetServiceOrderProvideProductBelongDepartmentResponse {
6581 /** 6850 /**
src/utils/index.ts
@@ -145,9 +145,53 @@ function getAliYunOSSFileNameFromUrl(url: string) { @@ -145,9 +145,53 @@ function getAliYunOSSFileNameFromUrl(url: string) {
145 return url; 145 return url;
146 } 146 }
147 } 147 }
  148 +
  149 +function transImageFile(base64Image: any) {
  150 + // 将Base64字符串解码为二进制数据
  151 + const binaryData = atob(base64Image.split(',')[1]);
  152 +
  153 + // 创建一个Uint8Array来存储二进制数据
  154 + const arrayBuffer = new ArrayBuffer(binaryData.length);
  155 + const uint8Array = new Uint8Array(arrayBuffer);
  156 + for (let i = 0; i < binaryData.length; i++) {
  157 + uint8Array[i] = binaryData.charCodeAt(i);
  158 + }
  159 +
  160 + // 创建Blob对象
  161 + return new Blob([uint8Array], { type: 'image/png' });
  162 +}
  163 +
  164 +/**
  165 + * 复制文本到剪贴板
  166 + * @param text
  167 + */
  168 +function copyToClipboard(text: string) {
  169 + // 创建一个临时的textarea元素
  170 + const textarea = document.createElement('textarea');
  171 + textarea.value = text;
  172 +
  173 + // 将textarea元素添加到DOM中
  174 + document.body.appendChild(textarea);
  175 +
  176 + // 选中textarea中的文本
  177 + textarea.select();
  178 +
  179 + try {
  180 + // 尝试执行复制命令
  181 + document.execCommand('copy');
  182 + return true;
  183 + } catch (err) {
  184 + return false;
  185 + } finally {
  186 + // 移除临时的textarea元素
  187 + document.body.removeChild(textarea);
  188 + }
  189 +}
  190 +
148 export { 191 export {
149 appendFormData, 192 appendFormData,
150 blobToFile, 193 blobToFile,
  194 + copyToClipboard,
151 customMessage, 195 customMessage,
152 dataURItoBlob, 196 dataURItoBlob,
153 enumToProTableEnumValue, 197 enumToProTableEnumValue,
@@ -158,4 +202,5 @@ export { @@ -158,4 +202,5 @@ export {
158 formatdate, 202 formatdate,
159 getAliYunOSSFileNameFromUrl, 203 getAliYunOSSFileNameFromUrl,
160 getUserInfo, 204 getUserInfo,
  205 + transImageFile,
161 }; 206 };