index.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. <template>
  2. <div class="p-2">
  3. <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
  4. <div v-show="showSearch" class="mb-[10px]">
  5. <el-card shadow="hover">
  6. <el-form ref="queryFormRef" :model="queryParams" :inline="true">
  7. <el-form-item label="订单编号" prop="orderNo">
  8. <el-input v-model="queryParams.orderNo" placeholder="请输入订单编号" clearable @keyup.enter="handleQuery" />
  9. </el-form-item>
  10. <el-form-item label="客户编号" prop="customerCode">
  11. <el-input v-model="queryParams.customerCode" placeholder="请输入客户编号" clearable @keyup.enter="handleQuery" />
  12. </el-form-item>
  13. <el-form-item label="客户名称" prop="customerName">
  14. <el-input v-model="queryParams.customerName" placeholder="请输入客户名称" clearable @keyup.enter="handleQuery" />
  15. </el-form-item>
  16. <el-form-item label="订单来源" prop="orderSource">
  17. <el-select v-model="queryParams.orderSource" placeholder="请选择订单来源" clearable>
  18. <el-option v-for="dict in order_source" :key="dict.value" :label="dict.label" :value="dict.value" />
  19. </el-select>
  20. </el-form-item>
  21. <el-form-item label="订单状态" prop="orderStatus">
  22. <el-select v-model="queryParams.orderStatus" placeholder="请选择订单状态" clearable>
  23. <el-option v-for="dict in order_status" :key="dict.value" :label="dict.label" :value="dict.value" />
  24. </el-select>
  25. </el-form-item>
  26. <el-form-item label="提交时间" prop="orderTime">
  27. <el-date-picker
  28. v-model="dateRange"
  29. type="daterange"
  30. range-separator="至"
  31. start-placeholder="开始时间"
  32. end-placeholder="结束时间"
  33. value-format="YYYY-MM-DD"
  34. />
  35. </el-form-item>
  36. <el-form-item>
  37. <el-button type="primary" icon="Search" @click="handleQuery()">搜索</el-button>
  38. <el-button icon="Refresh" @click="resetQuery">重置</el-button>
  39. </el-form-item>
  40. </el-form>
  41. </el-card>
  42. </div>
  43. </transition>
  44. <el-card shadow="never">
  45. <template #header>
  46. <el-row :gutter="10" class="mb8" type="flex" justify="space-between" align="middle">
  47. <!-- 左侧标题 -->
  48. <span style="font-size: 16px; font-weight: 500">销售订单信息列表</span>
  49. <div style="display: flex; flex-wrap: nowrap; gap: 10px">
  50. <el-button type="primary" @click="handleCloseOrder()" :disabled="!ids.length" plain>关闭订单</el-button>
  51. <el-button type="primary" @click="handleDelete()" :disabled="!ids.length" plain>删除订单</el-button>
  52. <el-button type="primary" :disabled="!ids.length" plain>导出订单</el-button>
  53. <el-button type="primary" :disabled="!ids.length" @click="handleOpenReturnStatusDialog" plain> 修改回款状态 </el-button>
  54. <el-button
  55. :type="queryParams.orderStatus === undefined ? 'primary' : ''"
  56. :plain="queryParams.orderStatus !== undefined"
  57. @click="handleQuery()"
  58. >全部订单{{ orderStatusStats.totalCount }}</el-button
  59. >
  60. <el-button :type="queryParams.orderStatus === '0' ? 'primary' : ''" :plain="queryParams.orderStatus !== '0'" @click="handleQuery('0')"
  61. >待付款{{ orderStatusStats.pendingPaymentCount }}</el-button
  62. >
  63. <el-button :type="queryParams.orderStatus === '2' ? 'primary' : ''" :plain="queryParams.orderStatus !== '2'" @click="handleQuery('2')"
  64. >待发货{{ orderStatusStats.pendingShipmentCount }}</el-button
  65. >
  66. <el-button :type="queryParams.orderStatus === '4' ? 'primary' : ''" :plain="queryParams.orderStatus !== '4'" @click="handleQuery('4')"
  67. >已发货{{ orderStatusStats.shippedCount }}</el-button
  68. >
  69. <el-button :type="queryParams.orderStatus === '5' ? 'primary' : ''" :plain="queryParams.orderStatus !== '5'" @click="handleQuery('5')"
  70. >已完成{{ orderStatusStats.completedCount }}</el-button
  71. >
  72. <el-button :type="queryParams.orderStatus === '6' ? 'primary' : ''" :plain="queryParams.orderStatus !== '6'" @click="handleQuery('6')"
  73. >已关闭{{ orderStatusStats.closedCount }}</el-button
  74. >
  75. </div>
  76. </el-row>
  77. </template>
  78. <el-table v-loading="loading" border :data="orderMainList" @selection-change="handleSelectionChange">
  79. <el-table-column type="selection" width="55" align="center" />
  80. <el-table-column label="订单时间" align="center" prop="orderTime" />
  81. <el-table-column label="订单编号" align="center" prop="orderNo" />
  82. <el-table-column label="平台\项目订单号" align="center" prop="projectOrderNo" />
  83. <el-table-column label="客户编号" align="center" prop="customerCode" />
  84. <el-table-column label="订单总金额" align="center" prop="totalAmount" />
  85. <el-table-column label="支付方式" align="center" prop="payType">
  86. <template #default="scope">
  87. <dict-tag :options="pay_method" :value="scope.row.payType" />
  88. </template>
  89. </el-table-column>
  90. <el-table-column label="业务员" align="center" prop="businessStaff" />
  91. <el-table-column label="客服" align="center" prop="customerService" />
  92. <el-table-column label="归属部门" align="center" prop="businessDept" />
  93. <el-table-column label="订单来源" align="center" prop="orderSource">
  94. <template #default="scope">
  95. <dict-tag :options="order_source" :value="scope.row.orderSource" />
  96. </template>
  97. </el-table-column>
  98. <!-- <el-table-column label="审核状态" align="center" prop="checkStatus">
  99. <template #default="scope">
  100. <dict-tag :options="order_check_status" :value="scope.row.checkStatus" />
  101. </template>
  102. </el-table-column> -->
  103. <el-table-column label="订单状态" align="center" prop="orderStatus">
  104. <template #default="scope">
  105. <dict-tag :options="order_status" :value="scope.row.orderStatus" />
  106. </template>
  107. </el-table-column>
  108. <el-table-column label="回款状态" align="center" prop="returnedStatus">
  109. <template #default="scope">
  110. <span>{{ scope.row.returnedStatus == '0' ? '未回款' : scope.row.returnedStatus == '1' ? '部分回款' : '全部回款' }}</span>
  111. </template>
  112. </el-table-column>
  113. <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  114. <template #default="scope">
  115. <template v-for="btn in getActionButtons(scope.row)" :key="btn.label">
  116. <el-button link type="primary" @click="btn.handler(scope.row)">{{ btn.label }}</el-button>
  117. </template>
  118. </template>
  119. </el-table-column>
  120. </el-table>
  121. <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
  122. </el-card>
  123. <!-- 发货对话框 -->
  124. <DeliverDialog v-model="showDeliverDialog" :order-id="currentOrderId" :order-no="currentOrderNo" @success="handleDeliverSuccess" />
  125. <!-- 物流详情对话框 -->
  126. <LogisticsDetail v-model="showLogisticsDialog" :order-id="logisticsOrderId" />
  127. <el-dialog v-model="returnStatusDialogVisible" title="选择回款状态" width="300px">
  128. <el-form>
  129. <el-form-item label="回款状态">
  130. <el-select v-model="selectedReturnStatus" placeholder="请选择" style="width: 100%">
  131. <el-option label="未回款" value="0" />
  132. <el-option label="部分回款" value="1" />
  133. <el-option label="全部回款" value="2" />
  134. </el-select>
  135. </el-form-item>
  136. </el-form>
  137. <template #footer>
  138. <el-button @click="returnStatusDialogVisible = false">取消</el-button>
  139. <el-button type="primary" @click="handleChangeReturn">确定</el-button>
  140. </template>
  141. </el-dialog>
  142. </div>
  143. </template>
  144. <script setup name="OrderMain" lang="ts">
  145. import {
  146. listOrderMain,
  147. getOrderMain,
  148. delOrderMain,
  149. addOrderMain,
  150. updateOrderMain,
  151. closeOrderMain,
  152. queryOrderStatusStats,
  153. changeStatus,
  154. changeCheckStatus,
  155. changeReturnedStatus
  156. } from '@/api/order/orderMain';
  157. import { OrderMainVO, OrderMainQuery, OrderMainForm } from '@/api/order/orderMain/types';
  158. import DeliverDialog from './deliverDialog.vue';
  159. import LogisticsDetail from './logisticsDetail.vue';
  160. const { proxy } = getCurrentInstance() as ComponentInternalInstance;
  161. const { order_status, order_check_status, pay_method, order_source } = toRefs<any>(
  162. proxy?.useDict('order_status', 'order_check_status', 'pay_method', 'order_source')
  163. );
  164. const orderMainList = ref<OrderMainVO[]>([]);
  165. const buttonLoading = ref(false);
  166. const loading = ref(true);
  167. const showSearch = ref(true);
  168. const ids = ref<Array<string | number>>([]);
  169. const single = ref(true);
  170. const multiple = ref(true);
  171. const total = ref(0);
  172. const router = useRouter();
  173. const queryFormRef = ref<ElFormInstance>();
  174. const orderMainFormRef = ref<ElFormInstance>();
  175. const checkStatusValue = ref('1'); // 审核状态选择值
  176. // 发货对话框
  177. const showDeliverDialog = ref(false);
  178. const currentOrderId = ref<string | number>();
  179. const currentOrderNo = ref<string>();
  180. const dateRange = ref<[DateModelType, DateModelType]>(['', '']);
  181. const showLogisticsDialog = ref(false);
  182. const logisticsOrderId = ref<string | number>();
  183. // 1. 定义响应式数据
  184. const returnStatusDialogVisible = ref(false); // 控制对话框显示
  185. const selectedReturnStatus = ref(''); // 存储用户选择的回款状态
  186. const dialog = reactive<DialogOption>({
  187. visible: false,
  188. title: ''
  189. });
  190. const orderStatusStats = ref({
  191. pendingPaymentCount: 0, // 待支付
  192. pendingShipmentCount: 0, // 待发货
  193. shippedCount: 0, // 已发货(发货完成)
  194. completedCount: 0, // 已完成
  195. closedCount: 0, // 已关闭
  196. totalCount: 0 // 全部订单
  197. });
  198. const initFormData: OrderMainForm = {
  199. id: undefined,
  200. orderNo: undefined,
  201. shipmentNo: undefined,
  202. subOrderNo: undefined,
  203. companyId: undefined,
  204. customerId: undefined,
  205. customerCode: undefined,
  206. isSplitChild: undefined,
  207. userId: undefined,
  208. shippingAddressId: undefined,
  209. purchaseReason: undefined,
  210. invoiceType: undefined,
  211. payType: undefined,
  212. warehouseId: undefined,
  213. creditLimit: undefined,
  214. expectedDeliveryTime: undefined,
  215. businessStaff: undefined,
  216. customerService: undefined,
  217. businessDept: undefined,
  218. userDept: undefined,
  219. productQuantity: undefined,
  220. shippingFee: undefined,
  221. totalAmount: undefined,
  222. payableAmount: undefined,
  223. paymentStatus: undefined,
  224. orderSource: undefined,
  225. orderStatus: undefined,
  226. orderTime: undefined,
  227. confirmTime: undefined,
  228. shippingTime: undefined,
  229. receivingTime: undefined,
  230. shippedQuantity: undefined,
  231. unshippedQuantity: undefined,
  232. packageCount: undefined,
  233. signedQuantity: undefined,
  234. afterSaleCompleted: undefined,
  235. afterSalePending: undefined,
  236. deliveryDesc: undefined,
  237. pushStatus: undefined,
  238. attachmentPath: undefined,
  239. deliveryType: undefined,
  240. orderCategory: undefined,
  241. productCode: undefined,
  242. cancelReason: undefined,
  243. expenseType: undefined,
  244. userNo: undefined,
  245. status: undefined,
  246. remark: undefined,
  247. orderProductBos: [],
  248. customerSalesInfoVo: {}
  249. };
  250. const data = reactive<PageData<OrderMainForm, OrderMainQuery>>({
  251. form: { ...initFormData },
  252. queryParams: {
  253. pageNum: 1,
  254. pageSize: 10,
  255. orderNo: undefined,
  256. shipmentNo: undefined,
  257. subOrderNo: undefined,
  258. companyId: undefined,
  259. customerCode: undefined,
  260. customerId: undefined,
  261. userId: undefined,
  262. shippingAddressId: undefined,
  263. purchaseReason: undefined,
  264. invoiceType: undefined,
  265. payType: undefined,
  266. warehouseId: undefined,
  267. creditLimit: undefined,
  268. expectedDeliveryTime: undefined,
  269. businessStaff: undefined,
  270. customerService: undefined,
  271. businessDept: undefined,
  272. userDept: undefined,
  273. productQuantity: undefined,
  274. shippingFee: undefined,
  275. totalAmount: undefined,
  276. payableAmount: undefined,
  277. paymentStatus: undefined,
  278. orderSource: undefined,
  279. orderStatus: undefined,
  280. orderTime: undefined,
  281. confirmTime: undefined,
  282. shippingTime: undefined,
  283. receivingTime: undefined,
  284. shippedQuantity: undefined,
  285. unshippedQuantity: undefined,
  286. packageCount: undefined,
  287. signedQuantity: undefined,
  288. afterSaleCompleted: undefined,
  289. afterSalePending: undefined,
  290. deliveryDesc: undefined,
  291. pushStatus: undefined,
  292. attachmentPath: undefined,
  293. deliveryType: undefined,
  294. orderCategory: undefined,
  295. productCode: undefined,
  296. cancelReason: undefined,
  297. expenseType: undefined,
  298. status: undefined,
  299. checkStatus: '1',
  300. platformCode: undefined,
  301. params: {}
  302. },
  303. rules: {
  304. customerId: [{ required: true, message: '客户ID不能为空', trigger: 'blur' }],
  305. payType: [{ required: true, message: '支付方式不能为空', trigger: 'change' }],
  306. warehouseId: [{ required: true, message: '发货仓库不能为空', trigger: 'change' }],
  307. expectedDeliveryTime: [{ required: true, message: '预计送达时间不能为空', trigger: 'blur' }],
  308. shippingFee: [{ required: true, message: '运费不能为空', trigger: 'blur' }],
  309. confirmTime: [{ required: true, message: '确认时间不能为空', trigger: 'blur' }],
  310. shippingTime: [{ required: true, message: '发货时间不能为空', trigger: 'blur' }],
  311. receivingTime: [{ required: true, message: '收货时间不能为空', trigger: 'blur' }],
  312. cancelReason: [{ required: true, message: '取消或异常原因不能为空', trigger: 'blur' }],
  313. expenseType: [{ required: true, message: '费用类型不能为空', trigger: 'change' }]
  314. }
  315. });
  316. const { queryParams, form, rules } = toRefs(data);
  317. /** 查询订单主信息列表 */
  318. const getList = async () => {
  319. loading.value = true;
  320. const res = await listOrderMain(proxy?.addDateRange(queryParams.value, dateRange.value));
  321. orderMainList.value = res.rows;
  322. total.value = res.total;
  323. loading.value = false;
  324. queryOrderStatusStatsMethod();
  325. };
  326. const queryOrderStatusStatsMethod = async () => {
  327. const res = await queryOrderStatusStats();
  328. orderStatusStats.value = res as any;
  329. };
  330. /** 取消按钮 */
  331. const cancel = () => {
  332. reset();
  333. dialog.visible = false;
  334. };
  335. /** 表单重置 */
  336. const reset = () => {
  337. form.value = { ...initFormData };
  338. orderMainFormRef.value?.resetFields();
  339. };
  340. /** 搜索按钮操作 */
  341. const handleQuery = (orderStatus?: string) => {
  342. if (orderStatus) {
  343. queryParams.value.orderStatus = orderStatus;
  344. } else {
  345. queryParams.value.orderStatus = undefined;
  346. }
  347. queryParams.value.pageNum = 1;
  348. getList();
  349. };
  350. /** 重置按钮操作 */
  351. const resetQuery = () => {
  352. dateRange.value = ['', ''];
  353. queryFormRef.value?.resetFields();
  354. handleQuery();
  355. };
  356. /** 多选框选中数据 */
  357. const handleSelectionChange = (selection: OrderMainVO[]) => {
  358. ids.value = selection.map((item) => item.id);
  359. single.value = selection.length != 1;
  360. multiple.value = !selection.length;
  361. };
  362. /** 查看物流按钮操作 */
  363. const handleViewLogistics = (row?: OrderMainVO) => {
  364. if (!row?.id) {
  365. proxy?.$modal.msgWarning('订单ID不能为空');
  366. return;
  367. }
  368. logisticsOrderId.value = row.id;
  369. showLogisticsDialog.value = true;
  370. };
  371. const handleReview = (row?: OrderMainVO) => {
  372. router.push({
  373. path: '/order-manage/order-sendDetail',
  374. query: { id: row.id }
  375. });
  376. };
  377. const handleAffirm = (row?: OrderMainVO) => {
  378. router.push({
  379. path: '/order-manage/order-affirm',
  380. query: { id: row.id }
  381. });
  382. };
  383. /** 审核按钮操作 */
  384. const handleCheck = async (row?: OrderMainVO) => {
  385. const oldValue = row.checkStatus; // 保存旧值
  386. // 弹出审核选择对话框
  387. try {
  388. await ElMessageBox({
  389. title: '审核',
  390. message: h('div', { style: 'padding: 10px 0' }, [
  391. h('p', { style: 'margin-bottom: 15px; font-size: 14px' }, '请选择审核结果:'),
  392. h('div', { style: 'display: flex; flex-direction: column; gap: 12px' }, [
  393. h(
  394. 'label',
  395. {
  396. style: 'display: flex; align-items: center; cursor: pointer; font-size: 14px',
  397. onClick: () => {
  398. checkStatusValue.value = '1';
  399. const radio = document.querySelector('input[name="checkStatus"][value="1"]') as HTMLInputElement;
  400. if (radio) radio.checked = true;
  401. }
  402. },
  403. [
  404. h('input', {
  405. type: 'radio',
  406. name: 'checkStatus',
  407. value: '1',
  408. checked: true,
  409. style: 'margin-right: 8px; cursor: pointer',
  410. onChange: () => {
  411. checkStatusValue.value = '1';
  412. }
  413. }),
  414. h('span', null, '审核通过')
  415. ]
  416. ),
  417. h(
  418. 'label',
  419. {
  420. style: 'display: flex; align-items: center; cursor: pointer; font-size: 14px',
  421. onClick: () => {
  422. checkStatusValue.value = '2';
  423. const radio = document.querySelector('input[name="checkStatus"][value="2"]') as HTMLInputElement;
  424. if (radio) radio.checked = true;
  425. }
  426. },
  427. [
  428. h('input', {
  429. type: 'radio',
  430. name: 'checkStatus',
  431. value: '2',
  432. style: 'margin-right: 8px; cursor: pointer',
  433. onChange: () => {
  434. checkStatusValue.value = '2';
  435. }
  436. }),
  437. h('span', null, '驳回')
  438. ]
  439. )
  440. ])
  441. ]),
  442. showCancelButton: true,
  443. confirmButtonText: '确定',
  444. cancelButtonText: '取消',
  445. beforeClose: (action, instance, done) => {
  446. if (action === 'confirm') {
  447. done();
  448. } else {
  449. done();
  450. }
  451. }
  452. });
  453. // 调用接口,传入用户选择的值
  454. await changeCheckStatus(row.id, checkStatusValue.value);
  455. getList();
  456. proxy?.$modal.msgSuccess('操作成功');
  457. } catch (error) {
  458. // 用户取消或操作失败
  459. if (error !== 'cancel' && error !== 'close') {
  460. row.checkStatus = oldValue; // 失败回滚
  461. proxy?.$modal.msgError('操作失败,请重试');
  462. }
  463. }
  464. };
  465. /** 审核按钮操作 */
  466. const handleCancel = async (row?: OrderMainVO) => {
  467. const oldValue = row.checkStatus; // 保存旧值
  468. // 弹出审核选择对话框
  469. try {
  470. // 调用接口,传入用户选择的值
  471. await changeStatus(row.id, '7');
  472. getList();
  473. proxy?.$modal.msgSuccess('操作成功');
  474. } catch (error) {
  475. // 用户取消或操作失败
  476. if (error !== 'cancel' && error !== 'close') {
  477. row.checkStatus = oldValue; // 失败回滚
  478. proxy?.$modal.msgError('操作失败,请重试');
  479. }
  480. }
  481. };
  482. /** 2. 修改按钮点击事件:只负责打开对话框 */
  483. const handleOpenReturnStatusDialog = () => {
  484. selectedReturnStatus.value = ''; // 打开时重置选择
  485. returnStatusDialogVisible.value = true;
  486. };
  487. /** 3. 完善操作函数:在对话框中点击“确定”后调用 */
  488. const handleChangeReturn = async () => {
  489. // 校验是否选择了状态
  490. if (!selectedReturnStatus.value) {
  491. proxy?.$modal.msgWarning('请选择回款状态');
  492. return;
  493. }
  494. try {
  495. // 调用接口,传入 ids 和用户选择的状态值
  496. await changeReturnedStatus(ids.value, selectedReturnStatus.value);
  497. returnStatusDialogVisible.value = false; // 操作成功后关闭对话框
  498. getList(); // 刷新列表
  499. proxy?.$modal.msgSuccess('操作成功');
  500. } catch (error) {
  501. // 用户取消或操作失败
  502. if (error !== 'cancel' && error !== 'close') {
  503. proxy?.$modal.msgError('操作失败,请重试');
  504. }
  505. }
  506. };
  507. /** 发货按钮操作 */
  508. const handleDeliver = (row?: OrderMainVO) => {
  509. if (!row?.id) {
  510. proxy?.$modal.msgWarning('订单ID不能为空');
  511. return;
  512. }
  513. currentOrderId.value = row.id;
  514. currentOrderNo.value = row.orderNo;
  515. showDeliverDialog.value = true;
  516. };
  517. /** 发货成功回调 */
  518. const handleDeliverSuccess = () => {
  519. getList();
  520. };
  521. /** 修改按钮操作 */
  522. const handleUpdate = async (row?: OrderMainVO) => {
  523. reset();
  524. const _id = row?.id || ids.value[0];
  525. const res = await getOrderMain(_id);
  526. Object.assign(form.value, res.data);
  527. dialog.visible = true;
  528. dialog.title = '修改订单主信息';
  529. };
  530. /** 提交按钮 */
  531. const submitForm = () => {
  532. orderMainFormRef.value?.validate(async (valid: boolean) => {
  533. if (valid) {
  534. buttonLoading.value = true;
  535. if (form.value.id) {
  536. await updateOrderMain(form.value).finally(() => (buttonLoading.value = false));
  537. } else {
  538. await addOrderMain(form.value).finally(() => (buttonLoading.value = false));
  539. }
  540. proxy?.$modal.msgSuccess('操作成功');
  541. dialog.visible = false;
  542. await getList();
  543. }
  544. });
  545. };
  546. /** 删除按钮操作 */
  547. const handleDelete = async (row?: OrderMainVO) => {
  548. const _ids = row?.id || ids.value;
  549. await proxy?.$modal.confirm('是否确认删除订单主信息编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
  550. await delOrderMain(_ids);
  551. proxy?.$modal.msgSuccess('删除成功');
  552. await getList();
  553. };
  554. /** 关闭订单操作 */
  555. const handleCloseOrder = async (row?: OrderMainVO) => {
  556. const _ids = row?.id || ids.value;
  557. await proxy?.$modal.confirm('是否确认关闭订单主信息编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
  558. await closeOrderMain(_ids);
  559. proxy?.$modal.msgSuccess('关闭成功');
  560. await getList();
  561. };
  562. // 订单状态枚举
  563. enum OrderStatus {
  564. PENDING_PAYMENT = '0', // 待支付
  565. PENDING_CONFIRM = '1', // 待确认
  566. PENDING_SHIPMENT = '2', // 待发货
  567. PARTIAL_SHIPMENT = '3', // 部分发货
  568. SHIPMENT_COMPLETED = '4', // 发货完成
  569. COMPLETED = '5', // 已完成
  570. CLOSED = '6', // 已关闭
  571. CANCELLED = '7' // 已取消
  572. }
  573. // 审核状态枚举
  574. enum CheckStatus {
  575. PENDING = '0', // 待审核
  576. APPROVED = '1', // 审核通过
  577. REJECTED = '2' // 已驳回
  578. }
  579. // 按钮配置类型
  580. interface ActionButton {
  581. label: string;
  582. handler: (row: OrderMainVO) => void;
  583. }
  584. // 按钮配置映射:根据订单状态和审核状态返回可用按钮
  585. const getButtonsByStatus = (orderStatus: string, checkStatus: string): ActionButton[] => {
  586. const buttons: ActionButton[] = [];
  587. // 待支付状态:显示查看按钮
  588. if (orderStatus === OrderStatus.PENDING_PAYMENT) {
  589. buttons.push({ label: '查看', handler: handleReview });
  590. buttons.push({ label: '确认订单', handler: handleAffirm });
  591. }
  592. // 待确认状态:显示确认订单按钮
  593. if (orderStatus === OrderStatus.PENDING_CONFIRM) {
  594. buttons.push({ label: '查看', handler: handleReview });
  595. buttons.push({ label: '确认订单', handler: handleAffirm });
  596. }
  597. // 待审核:显示审核按钮
  598. // if (checkStatus === CheckStatus.PENDING) {
  599. // buttons.push({ label: '审核', handler: handleCheck });
  600. // }
  601. // 待发货或部分发货:显示发货按钮
  602. if (orderStatus === OrderStatus.PENDING_SHIPMENT || orderStatus === OrderStatus.PARTIAL_SHIPMENT) {
  603. buttons.push({ label: '发货', handler: handleDeliver });
  604. }
  605. // 待发货、部分发货、发货完成、已完成:显示查看订单信息按钮
  606. if (
  607. [OrderStatus.PENDING_SHIPMENT, OrderStatus.PARTIAL_SHIPMENT, OrderStatus.SHIPMENT_COMPLETED, OrderStatus.COMPLETED].includes(
  608. orderStatus as OrderStatus
  609. )
  610. ) {
  611. buttons.push({ label: '查看订单信息', handler: handleReview });
  612. }
  613. // 发货完成或已完成:显示查看物流按钮
  614. if (orderStatus === OrderStatus.PARTIAL_SHIPMENT || orderStatus === OrderStatus.SHIPMENT_COMPLETED || orderStatus === OrderStatus.COMPLETED) {
  615. buttons.push({ label: '查看物流', handler: handleViewLogistics });
  616. }
  617. // 非已取消和已关闭状态:显示取消订单按钮
  618. if (orderStatus !== OrderStatus.CANCELLED && orderStatus !== OrderStatus.CLOSED && orderStatus !== OrderStatus.SHIPMENT_COMPLETED) {
  619. buttons.push({ label: '取消订单', handler: handleCancel });
  620. }
  621. return buttons;
  622. };
  623. // 根据订单状态获取可用的操作按钮
  624. const getActionButtons = (row: OrderMainVO): ActionButton[] => {
  625. return getButtonsByStatus(row.orderStatus, row.checkStatus);
  626. };
  627. /** 导出按钮操作 */
  628. const handleExport = () => {
  629. proxy?.download(
  630. 'system/orderMain/export',
  631. {
  632. ...queryParams.value
  633. },
  634. `orderMain_${new Date().getTime()}.xlsx`
  635. );
  636. };
  637. onMounted(() => {
  638. getList();
  639. });
  640. onActivated(() => {
  641. getList();
  642. });
  643. </script>