index.vue 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  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="orderStatus">
  11. <el-select v-model="queryParams.orderStatus" placeholder="请选择订单状态" clearable style="width: 200px">
  12. <el-option v-for="dict in order_status" :key="dict.value" :label="dict.label" :value="dict.value" />
  13. </el-select>
  14. </el-form-item>
  15. <el-form-item label="支付状态" prop="paymentStatus">
  16. <el-select v-model="queryParams.paymentStatus" placeholder="请选择支付状态" clearable style="width: 200px">
  17. <el-option v-for="dict in payment_status" :key="dict.value" :label="dict.label" :value="dict.value" />
  18. </el-select>
  19. </el-form-item>
  20. <el-form-item>
  21. <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
  22. <el-button icon="Refresh" @click="resetQuery">重置</el-button>
  23. </el-form-item>
  24. </el-form>
  25. </el-card>
  26. </div>
  27. </transition>
  28. <el-card shadow="never">
  29. <template #header>
  30. <el-row :gutter="10" class="mb8">
  31. <el-col :span="1.5">
  32. <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['order:zhongcheorder:add']">新增</el-button>
  33. </el-col>
  34. <el-col :span="1.5">
  35. <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['order:zhongcheorder:edit']">修改</el-button>
  36. </el-col>
  37. <el-col :span="1.5">
  38. <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['order:zhongcheorder:remove']">删除</el-button>
  39. </el-col>
  40. <el-col :span="1.5">
  41. <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['order:zhongcheorder:export']">导出</el-button>
  42. </el-col>
  43. <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
  44. </el-row>
  45. </template>
  46. <el-table v-loading="loading" border :data="zhongcheorderList" @selection-change="handleSelectionChange">
  47. <el-table-column type="selection" width="55" align="center" />
  48. <el-table-column type="index" label="序号" width="60" align="center" />
  49. <el-table-column label="订单编号" align="center" prop="orderNo" width="150" />
  50. <el-table-column label="订单类型" align="center" prop="preOrder" width="100">
  51. <template #default="scope">
  52. <dict-tag :options="order_type" :value="scope.row.preOrder" />
  53. </template>
  54. </el-table-column>
  55. <el-table-column label="下单人" align="center" prop="buyerName" />
  56. <el-table-column label="下单时间" align="center" prop="orderTime" width="180">
  57. <template #default="scope">
  58. <span>{{ parseTime(scope.row.orderTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
  59. </template>
  60. </el-table-column>
  61. <el-table-column label="确认时间" align="center" prop="confirmTime" width="180">
  62. <template #default="scope">
  63. <span>{{ parseTime(scope.row.confirmTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
  64. </template>
  65. </el-table-column>
  66. <el-table-column label="订单金额" align="center" prop="totalAmount" />
  67. <el-table-column label="支付状态" align="center" prop="paymentStatus">
  68. <template #default="scope">
  69. <dict-tag :options="payment_status" :value="scope.row.paymentStatus" />
  70. </template>
  71. </el-table-column>
  72. <el-table-column label="订单状态" align="center" prop="orderStatus">
  73. <template #default="scope">
  74. <dict-tag :options="order_status" :value="scope.row.orderStatus" />
  75. </template>
  76. </el-table-column>
  77. <el-table-column label="对账状态" align="center" prop="reconciliationStatus">
  78. <template #default="scope">
  79. <dict-tag :options="reconciliation_status" :value="scope.row.reconciliationStatus" />
  80. </template>
  81. </el-table-column>
  82. <el-table-column label="是否妥投" align="center" prop="isProperDelivery">
  83. <template #default="scope">
  84. <dict-tag :options="is_proper_delivery" :value="scope.row.isProperDelivery" />
  85. </template>
  86. </el-table-column>
  87. <el-table-column label="开票状态" align="center" prop="invoiceStatus">
  88. <template #default="scope">
  89. <dict-tag :options="invoice_issuance_status" :value="scope.row.invoiceStatus" />
  90. </template>
  91. </el-table-column>
  92. <el-table-column label="包裹数量" align="center" prop="packageCount" />
  93. <el-table-column label="结算状态" align="center" prop="settlementStatus" width="160">
  94. <template #default="scope">
  95. <dict-tag :options="settlement_status" :value="scope.row.settlementStatus" />
  96. <el-button
  97. v-if="String(scope.row.settlementStatus) !== '1'"
  98. link
  99. type="primary"
  100. @click="handleSettlement(scope.row)"
  101. >
  102. 结算
  103. </el-button>
  104. </template>
  105. </el-table-column>
  106. <el-table-column label="截止还款时间" align="center" prop="repaymentDeadline" width="180">
  107. <template #default="scope">
  108. <span>{{ parseTime(scope.row.repaymentDeadline, '{y}-{m}-{d}') }}</span>
  109. <el-button link type="primary" @click="handleOpenDeadline(scope.row)">录入</el-button>
  110. </template>
  111. </el-table-column>
  112. <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="300" fixed="right">
  113. <template #default="scope">
  114. <el-button
  115. v-if="String(scope.row.orderStatus) === '1'"
  116. link
  117. type="primary"
  118. @click="handleAccept(scope.row)"
  119. >
  120. 接单
  121. </el-button>
  122. <el-button
  123. v-if="String(scope.row.orderStatus) === '1'"
  124. link
  125. type="danger"
  126. @click="handleReject(scope.row)"
  127. >
  128. 拒单
  129. </el-button>
  130. <el-button v-if="String(scope.row.orderStatus) !== '1'" link type="primary" @click="handleViewLogistics(scope.row)">查看物流</el-button>
  131. <el-button link type="primary" @click="handleViewOrder(scope.row)">查看订单</el-button>
  132. <el-button v-if="String(scope.row.orderStatus) !== '1'" link type="primary" @click="handleOpenInvoice(scope.row)">上传发票</el-button>
  133. </template>
  134. </el-table-column>
  135. </el-table>
  136. <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
  137. </el-card>
  138. <!-- 添加或修改订单列表对话框 -->
  139. <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
  140. <el-form ref="zhongcheorderFormRef" :model="form" :rules="rules" label-width="80px">
  141. <el-form-item label="父订单id" prop="parentOrderId">
  142. <el-input v-model="form.parentOrderId" placeholder="请输入父订单id" />
  143. </el-form-item>
  144. <el-form-item label="订单编号" prop="orderNo">
  145. <el-input v-model="form.orderNo" placeholder="请输入订单编号" />
  146. </el-form-item>
  147. <el-form-item label="发货单号" prop="shipmentNo">
  148. <el-input v-model="form.shipmentNo" placeholder="请输入发货单号" />
  149. </el-form-item>
  150. <el-form-item label="子订单编号" prop="subOrderNo">
  151. <el-input v-model="form.subOrderNo" placeholder="请输入子订单编号" />
  152. </el-form-item>
  153. <el-form-item label="所属公司" prop="companyId">
  154. <el-input v-model="form.companyId" placeholder="请输入所属公司" />
  155. </el-form-item>
  156. <el-form-item label="客户编号" prop="customerCode">
  157. <el-input v-model="form.customerCode" placeholder="请输入客户编号" />
  158. </el-form-item>
  159. <el-form-item label="客户ID" prop="customerId">
  160. <el-input v-model="form.customerId" placeholder="请输入客户ID" />
  161. </el-form-item>
  162. <el-form-item label="用户ID" prop="userId">
  163. <el-input v-model="form.userId" placeholder="请输入用户ID" />
  164. </el-form-item>
  165. <el-form-item label="收货地址ID" prop="shippingAddressId">
  166. <el-input v-model="form.shippingAddressId" placeholder="请输入收货地址ID" />
  167. </el-form-item>
  168. <el-form-item label="采购事由" prop="purchaseReason">
  169. <el-input v-model="form.purchaseReason" placeholder="请输入采购事由" />
  170. </el-form-item>
  171. <el-form-item label="发货仓库" prop="warehouseId">
  172. <el-input v-model="form.warehouseId" placeholder="请输入发货仓库" />
  173. </el-form-item>
  174. <el-form-item label="信用额度" prop="creditLimit">
  175. <el-input v-model="form.creditLimit" placeholder="请输入信用额度" />
  176. </el-form-item>
  177. <el-form-item label="预计送达时间" prop="expectedDeliveryTime">
  178. <el-date-picker clearable
  179. v-model="form.expectedDeliveryTime"
  180. type="datetime"
  181. value-format="YYYY-MM-DD HH:mm:ss"
  182. placeholder="请选择预计送达时间">
  183. </el-date-picker>
  184. </el-form-item>
  185. <el-form-item label="业务员姓名/工号" prop="businessStaff">
  186. <el-input v-model="form.businessStaff" placeholder="请输入业务员姓名/工号" />
  187. </el-form-item>
  188. <el-form-item label="客服人员" prop="customerService">
  189. <el-input v-model="form.customerService" placeholder="请输入客服人员" />
  190. </el-form-item>
  191. <el-form-item label="业务部门" prop="businessDept">
  192. <el-input v-model="form.businessDept" placeholder="请输入业务部门" />
  193. </el-form-item>
  194. <el-form-item label="用户所属部门" prop="userDept">
  195. <el-input v-model="form.userDept" placeholder="请输入用户所属部门" />
  196. </el-form-item>
  197. <el-form-item label="商品总数量" prop="productQuantity">
  198. <el-input v-model="form.productQuantity" placeholder="请输入商品总数量" />
  199. </el-form-item>
  200. <el-form-item label="运费" prop="shippingFee">
  201. <el-input v-model="form.shippingFee" placeholder="请输入运费" />
  202. </el-form-item>
  203. <el-form-item label="订单总金额" prop="totalAmount">
  204. <el-input v-model="form.totalAmount" placeholder="请输入订单总金额" />
  205. </el-form-item>
  206. <el-form-item label="应付金额" prop="payableAmount">
  207. <el-input v-model="form.payableAmount" placeholder="请输入应付金额" />
  208. </el-form-item>
  209. <el-form-item label="订单来源" prop="orderSource">
  210. <el-input v-model="form.orderSource" placeholder="请输入订单来源" />
  211. </el-form-item>
  212. <el-form-item label="下单时间" prop="orderTime">
  213. <el-date-picker clearable
  214. v-model="form.orderTime"
  215. type="datetime"
  216. value-format="YYYY-MM-DD HH:mm:ss"
  217. placeholder="请选择下单时间">
  218. </el-date-picker>
  219. </el-form-item>
  220. <el-form-item label="确认时间" prop="confirmTime">
  221. <el-date-picker clearable
  222. v-model="form.confirmTime"
  223. type="datetime"
  224. value-format="YYYY-MM-DD HH:mm:ss"
  225. placeholder="请选择确认时间">
  226. </el-date-picker>
  227. </el-form-item>
  228. <el-form-item label="发货时间" prop="shippingTime">
  229. <el-date-picker clearable
  230. v-model="form.shippingTime"
  231. type="datetime"
  232. value-format="YYYY-MM-DD HH:mm:ss"
  233. placeholder="请选择发货时间">
  234. </el-date-picker>
  235. </el-form-item>
  236. <el-form-item label="收货时间" prop="receivingTime">
  237. <el-date-picker clearable
  238. v-model="form.receivingTime"
  239. type="datetime"
  240. value-format="YYYY-MM-DD HH:mm:ss"
  241. placeholder="请选择收货时间">
  242. </el-date-picker>
  243. </el-form-item>
  244. <el-form-item label="是否为拆分子单:0=是 (子订单), 1=否 (父订单)" prop="isSplitChild">
  245. <el-input v-model="form.isSplitChild" placeholder="请输入是否为拆分子单:0=是 (子订单), 1=否 (父订单)" />
  246. </el-form-item>
  247. <el-form-item label="包裹数量" prop="packageCount">
  248. <el-input v-model="form.packageCount" placeholder="请输入包裹数量" />
  249. </el-form-item>
  250. <el-form-item label="签收数量" prop="signedQuantity">
  251. <el-input v-model="form.signedQuantity" placeholder="请输入签收数量" />
  252. </el-form-item>
  253. <el-form-item label="已完成售后数量" prop="afterSaleCompleted">
  254. <el-input v-model="form.afterSaleCompleted" placeholder="请输入已完成售后数量" />
  255. </el-form-item>
  256. <el-form-item label="申请售后数量" prop="afterSalePending">
  257. <el-input v-model="form.afterSalePending" placeholder="请输入申请售后数量" />
  258. </el-form-item>
  259. <el-form-item label="配送时效描述" prop="deliveryDesc">
  260. <el-input v-model="form.deliveryDesc" placeholder="请输入配送时效描述" />
  261. </el-form-item>
  262. <el-form-item label="订单附件文件路径" prop="attachmentPath">
  263. <el-input v-model="form.attachmentPath" placeholder="请输入订单附件文件路径" />
  264. </el-form-item>
  265. <el-form-item label="创建类别" prop="orderCategory">
  266. <el-input v-model="form.orderCategory" placeholder="请输入创建类别" />
  267. </el-form-item>
  268. <el-form-item label="取消或异常原因" prop="cancelReason">
  269. <el-input v-model="form.cancelReason" placeholder="请输入取消或异常原因" />
  270. </el-form-item>
  271. <el-form-item label="用户编号" prop="userNo">
  272. <el-input v-model="form.userNo" placeholder="请输入用户编号" />
  273. </el-form-item>
  274. <el-form-item label="备注" prop="remark">
  275. <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
  276. </el-form-item>
  277. <el-form-item label="数据来源" prop="dataSource">
  278. <el-input v-model="form.dataSource" placeholder="请输入数据来源" />
  279. </el-form-item>
  280. <el-form-item label="分配对象ID" prop="assigneeId">
  281. <el-input v-model="form.assigneeId" placeholder="请输入分配对象ID" />
  282. </el-form-item>
  283. </el-form>
  284. <template #footer>
  285. <div class="dialog-footer">
  286. <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
  287. <el-button @click="cancel">取 消</el-button>
  288. </div>
  289. </template>
  290. </el-dialog>
  291. <el-dialog title="查看物流信息" v-model="logisticsDialog.visible" width="900px" append-to-body>
  292. <el-form :inline="true" label-width="80px" class="mb-[10px]">
  293. <el-form-item label="快递单号">
  294. <el-select v-model="logisticsDialog.selectedId" placeholder="请选择" style="width: 260px" @change="handleLogisticNoChange">
  295. <el-option v-for="item in logisticsDialog.options" :key="item.value" :label="item.label" :value="item.value" />
  296. </el-select>
  297. </el-form-item>
  298. <el-form-item label="快递公司">
  299. <el-input v-model="logisticsDialog.companyName" disabled style="width: 260px" />
  300. </el-form-item>
  301. <el-form-item>
  302. <el-button type="primary" :loading="logisticsDialog.trackLoading" :disabled="!logisticsDialog.selectedId" @click="handleQueryLogisticsTrack">查询</el-button>
  303. </el-form-item>
  304. </el-form>
  305. <div v-loading="logisticsDialog.trackLoading">
  306. <el-timeline v-if="logisticsDialog.traces && logisticsDialog.traces.length">
  307. <el-timeline-item v-for="(item, idx) in logisticsDialog.traces" :key="idx" :timestamp="item.ftime && item.time ? `${item.ftime}||${item.time}` : (item.ftime || item.time || '')" placement="top">
  308. <div>{{ item.context }}</div>
  309. </el-timeline-item>
  310. </el-timeline>
  311. <el-empty v-else description="暂无物流信息" />
  312. </div>
  313. <template #footer>
  314. <div class="dialog-footer">
  315. <el-button @click="logisticsDialog.visible = false">关 闭</el-button>
  316. </div>
  317. </template>
  318. </el-dialog>
  319. <el-dialog title="录入截止还款时间" v-model="deadlineDialog.visible" width="460px" append-to-body>
  320. <el-form label-width="110px">
  321. <el-form-item label="截止还款时间">
  322. <el-date-picker
  323. v-model="deadlineDialog.repaymentDeadline"
  324. type="datetime"
  325. value-format="YYYY-MM-DD HH:mm:ss"
  326. placeholder="请选择截止还款时间"
  327. style="width: 100%"
  328. />
  329. </el-form-item>
  330. </el-form>
  331. <template #footer>
  332. <div class="dialog-footer">
  333. <el-button :loading="deadlineDialog.loading" type="primary" @click="handleSubmitDeadline">确 定</el-button>
  334. <el-button :disabled="deadlineDialog.loading" @click="deadlineDialog.visible = false">取 消</el-button>
  335. </div>
  336. </template>
  337. </el-dialog>
  338. <el-dialog title="上传发票" v-model="invoiceDialog.visible" width="500px" append-to-body>
  339. <el-form label-width="80px">
  340. <el-form-item label="发票文件" required>
  341. <fileUpload v-model="invoiceDialog.invoice" :fileType="['doc', 'docx', 'pdf']" :limit="1" />
  342. </el-form-item>
  343. </el-form>
  344. <template #footer>
  345. <div class="dialog-footer">
  346. <el-button :loading="invoiceDialog.loading" type="primary" @click="handleSubmitInvoice">确 定</el-button>
  347. <el-button :disabled="invoiceDialog.loading" @click="invoiceDialog.visible = false">取 消</el-button>
  348. </div>
  349. </template>
  350. </el-dialog>
  351. <el-dialog title="订单商品明细" v-model="orderProductDialog.visible" width="1050px" append-to-body>
  352. <el-table v-loading="orderProductDialog.loading" :data="orderProductDialog.list" border>
  353. <el-table-column type="index" label="序号" width="60" align="center" />
  354. <el-table-column label="产品编号" align="center" prop="productNo" width="120" />
  355. <el-table-column label="产品名称" align="center" prop="productName" min-width="150" show-overflow-tooltip />
  356. <el-table-column label="品牌" align="center" prop="brandName" width="110" />
  357. <el-table-column label="单价" align="center" prop="orderPrice" width="110" />
  358. <el-table-column label="数量" align="center" prop="orderQuantity" width="90" />
  359. <el-table-column label="金额" align="center" prop="subtotal" width="110" />
  360. </el-table>
  361. <template #footer>
  362. <div class="dialog-footer">
  363. <el-button @click="orderProductDialog.visible = false">关 闭</el-button>
  364. </div>
  365. </template>
  366. </el-dialog>
  367. </div>
  368. </template>
  369. <script setup name="Zhongcheorder" lang="ts">
  370. import { listZhongcheorder, getZhongcheorder, delZhongcheorder, addZhongcheorder, updateZhongcheorder, acceptZhongcheorder, rejectZhongcheorder, getZhongcheorderLogistics, getZhongcheorderLogisticsTrack, settlementZhongcheorder, setZhongcheorderDeadline, uploadZhongcheorderInvoice } from '@/api/order/zhongcheorder/index';
  371. import { ZhongcheorderVO, ZhongcheorderQuery, ZhongcheorderForm } from '@/api/order/zhongcheorder/types';
  372. import { ElMessageBox } from 'element-plus';
  373. import { listByIds } from '@/api/system/oss';
  374. import { getZhongCheOrderProducts } from '@/api/order/orderProduct/index';
  375. const { proxy } = getCurrentInstance() as ComponentInternalInstance;
  376. const { order_status } = toRefs<any>(proxy?.useDict('order_status'));
  377. const { payment_status } = toRefs<any>(proxy?.useDict('payment_status'));
  378. const { order_type } = toRefs<any>(proxy?.useDict('order_type'));
  379. const { reconciliation_status } = toRefs<any>(proxy?.useDict('reconciliation_status'));
  380. const { is_proper_delivery } = toRefs<any>(proxy?.useDict('is_proper_delivery'));
  381. const { invoice_issuance_status } = toRefs<any>(proxy?.useDict('invoice_issuance_status'));
  382. const { settlement_status } = toRefs<any>(proxy?.useDict('settlement_status'));
  383. const zhongcheorderList = ref<ZhongcheorderVO[]>([]);
  384. const buttonLoading = ref(false);
  385. const loading = ref(true);
  386. const showSearch = ref(true);
  387. const ids = ref<Array<string | number>>([]);
  388. const single = ref(true);
  389. const multiple = ref(true);
  390. const total = ref(0);
  391. const queryFormRef = ref<ElFormInstance>();
  392. const zhongcheorderFormRef = ref<ElFormInstance>();
  393. const dialog = reactive<DialogOption>({
  394. visible: false,
  395. title: ''
  396. });
  397. const logisticsDialog = reactive<{
  398. visible: boolean;
  399. loading: boolean;
  400. trackLoading: boolean;
  401. packages: any[];
  402. options: Array<{ label: string; value: string }>;
  403. selectedId: string;
  404. companyName: string;
  405. traces: Array<{ time?: string; ftime?: string; context?: string }>;
  406. }>({
  407. visible: false,
  408. loading: false,
  409. trackLoading: false,
  410. packages: [],
  411. options: [],
  412. selectedId: '',
  413. companyName: '',
  414. traces: []
  415. });
  416. const deadlineDialog = reactive<{ visible: boolean; loading: boolean; id: string | number | undefined; repaymentDeadline: string }>({
  417. visible: false,
  418. loading: false,
  419. id: undefined,
  420. repaymentDeadline: ''
  421. });
  422. const invoiceDialog = reactive<{ visible: boolean; loading: boolean; id: string | number | undefined; invoice: string }>({
  423. visible: false,
  424. loading: false,
  425. id: undefined,
  426. invoice: ''
  427. });
  428. const orderProductDialog = reactive<{
  429. visible: boolean;
  430. loading: boolean;
  431. list: any[];
  432. }>({
  433. visible: false,
  434. loading: false,
  435. list: []
  436. });
  437. const initFormData: ZhongcheorderForm = {
  438. id: undefined,
  439. parentOrderId: undefined,
  440. orderNo: undefined,
  441. shipmentNo: undefined,
  442. subOrderNo: undefined,
  443. companyId: undefined,
  444. customerCode: undefined,
  445. customerId: undefined,
  446. userId: undefined,
  447. shippingAddressId: undefined,
  448. purchaseReason: undefined,
  449. invoiceType: undefined,
  450. payType: undefined,
  451. warehouseId: undefined,
  452. creditLimit: undefined,
  453. expectedDeliveryTime: undefined,
  454. businessStaff: undefined,
  455. customerService: undefined,
  456. businessDept: undefined,
  457. userDept: undefined,
  458. productQuantity: undefined,
  459. shippingFee: undefined,
  460. totalAmount: undefined,
  461. payableAmount: undefined,
  462. paymentStatus: undefined,
  463. orderSource: undefined,
  464. orderStatus: undefined,
  465. orderTime: undefined,
  466. confirmTime: undefined,
  467. shippingTime: undefined,
  468. receivingTime: undefined,
  469. splitStatus: undefined,
  470. isSplitChild: undefined,
  471. packageCount: undefined,
  472. signedQuantity: undefined,
  473. afterSaleCompleted: undefined,
  474. afterSalePending: undefined,
  475. deliveryDesc: undefined,
  476. pushStatus: undefined,
  477. attachmentPath: undefined,
  478. deliveryType: undefined,
  479. orderCategory: undefined,
  480. cancelReason: undefined,
  481. expenseType: undefined,
  482. userNo: undefined,
  483. remark: undefined,
  484. dataSource: undefined,
  485. checkStatus: undefined,
  486. assignmentStatus: undefined,
  487. assigneeId: undefined,
  488. assigneeType: undefined
  489. }
  490. const data = reactive<PageData<ZhongcheorderForm, ZhongcheorderQuery>>({
  491. form: {...initFormData},
  492. queryParams: {
  493. pageNum: 1,
  494. pageSize: 10,
  495. orderNo: undefined,
  496. paymentStatus: undefined,
  497. orderStatus: undefined,
  498. reconciliationStatus: undefined,
  499. isProperDelivery: undefined,
  500. settlementStatus: undefined,
  501. params: {
  502. }
  503. },
  504. rules: {
  505. }
  506. });
  507. const { queryParams, form, rules } = toRefs(data);
  508. /** 查询订单列表列表 */
  509. const getList = async () => {
  510. loading.value = true;
  511. const res = await listZhongcheorder(queryParams.value);
  512. zhongcheorderList.value = res.rows;
  513. total.value = res.total;
  514. loading.value = false;
  515. }
  516. /** 取消按钮 */
  517. const cancel = () => {
  518. reset();
  519. dialog.visible = false;
  520. }
  521. /** 表单重置 */
  522. const reset = () => {
  523. form.value = {...initFormData};
  524. zhongcheorderFormRef.value?.resetFields();
  525. }
  526. /** 搜索按钮操作 */
  527. const handleQuery = () => {
  528. queryParams.value.pageNum = 1;
  529. getList();
  530. }
  531. /** 重置按钮操作 */
  532. const resetQuery = () => {
  533. queryFormRef.value?.resetFields();
  534. handleQuery();
  535. }
  536. /** 多选框选中数据 */
  537. const handleSelectionChange = (selection: ZhongcheorderVO[]) => {
  538. ids.value = selection.map(item => item.id);
  539. single.value = selection.length != 1;
  540. multiple.value = !selection.length;
  541. }
  542. /** 新增按钮操作 */
  543. const handleAdd = () => {
  544. reset();
  545. dialog.visible = true;
  546. dialog.title = "添加订单列表";
  547. }
  548. /** 修改按钮操作 */
  549. const handleUpdate = async (row?: ZhongcheorderVO) => {
  550. reset();
  551. const _id = row?.id || ids.value[0]
  552. const res = await getZhongcheorder(_id);
  553. Object.assign(form.value, res.data);
  554. dialog.visible = true;
  555. dialog.title = "修改订单列表";
  556. }
  557. /** 提交按钮 */
  558. const submitForm = () => {
  559. zhongcheorderFormRef.value?.validate(async (valid: boolean) => {
  560. if (valid) {
  561. buttonLoading.value = true;
  562. if (form.value.id) {
  563. await updateZhongcheorder(form.value).finally(() => buttonLoading.value = false);
  564. } else {
  565. await addZhongcheorder(form.value).finally(() => buttonLoading.value = false);
  566. }
  567. proxy?.$modal.msgSuccess("操作成功");
  568. dialog.visible = false;
  569. await getList();
  570. }
  571. });
  572. }
  573. /** 删除按钮操作 */
  574. const handleDelete = async (row?: ZhongcheorderVO) => {
  575. const _ids = row?.id || ids.value;
  576. await proxy?.$modal.confirm('是否确认删除订单列表编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
  577. await delZhongcheorder(_ids);
  578. proxy?.$modal.msgSuccess("删除成功");
  579. await getList();
  580. }
  581. /** 导出按钮操作 */
  582. const handleExport = () => {
  583. proxy?.download('order/zhongcheorder/export', {
  584. ...queryParams.value
  585. }, `zhongcheorder_${new Date().getTime()}.xlsx`)
  586. }
  587. const handleAccept = async (row: ZhongcheorderVO) => {
  588. await proxy?.$modal.confirm('是否确认接单?');
  589. const res = await acceptZhongcheorder(row.id);
  590. proxy?.$modal.msgSuccess(res as any);
  591. await getList();
  592. }
  593. const handleReject = async (row: ZhongcheorderVO) => {
  594. try {
  595. const resPrompt = await ElMessageBox.prompt('请输入拒单理由', '系统提示', {
  596. confirmButtonText: '确定',
  597. cancelButtonText: '取消',
  598. type: 'warning',
  599. closeOnClickModal: false,
  600. inputValidator: (value) => {
  601. if (!String(value ?? '').trim()) {
  602. return '拒单理由不能为空';
  603. }
  604. return true;
  605. }
  606. });
  607. const reason = (resPrompt as any)?.value;
  608. const res = await rejectZhongcheorder(row.id, reason);
  609. proxy?.$modal.msgSuccess(res as any);
  610. await getList();
  611. } catch {
  612. // 用户取消
  613. }
  614. }
  615. const handleSettlement = async (row: ZhongcheorderVO) => {
  616. await proxy?.$modal.confirm('是否确认结算?');
  617. await settlementZhongcheorder(row.id);
  618. proxy?.$modal.msgSuccess('操作成功');
  619. await getList();
  620. }
  621. const handleOpenDeadline = (row: ZhongcheorderVO) => {
  622. deadlineDialog.visible = true;
  623. deadlineDialog.loading = false;
  624. deadlineDialog.id = row.id;
  625. deadlineDialog.repaymentDeadline = (row as any)?.repaymentDeadline ?? '';
  626. }
  627. const handleSubmitDeadline = async () => {
  628. const id = deadlineDialog.id;
  629. const repaymentDeadline = String(deadlineDialog.repaymentDeadline ?? '').trim();
  630. if (!id) return;
  631. if (!repaymentDeadline) {
  632. proxy?.$modal.msgError('请选择截止还款时间');
  633. return;
  634. }
  635. deadlineDialog.loading = true;
  636. try {
  637. await setZhongcheorderDeadline(id, repaymentDeadline);
  638. proxy?.$modal.msgSuccess('操作成功');
  639. deadlineDialog.visible = false;
  640. await getList();
  641. } finally {
  642. deadlineDialog.loading = false;
  643. }
  644. }
  645. const handleOpenInvoice = (row: ZhongcheorderVO) => {
  646. invoiceDialog.visible = true;
  647. invoiceDialog.loading = false;
  648. invoiceDialog.id = row.id;
  649. invoiceDialog.invoice = '';
  650. }
  651. const handleSubmitInvoice = async () => {
  652. const id = invoiceDialog.id;
  653. const invoiceId = String(invoiceDialog.invoice ?? '').trim();
  654. if (!id) return;
  655. if (!invoiceId) {
  656. proxy?.$modal.msgError('请先上传发票文件');
  657. return;
  658. }
  659. invoiceDialog.loading = true;
  660. try {
  661. const ossRes = await listByIds(invoiceId);
  662. let invoiceUrl = invoiceId;
  663. if (ossRes && (ossRes as any).data && (ossRes as any).data.length > 0) {
  664. invoiceUrl = (ossRes as any).data[0].url;
  665. }
  666. await uploadZhongcheorderInvoice(id, invoiceUrl);
  667. proxy?.$modal.msgSuccess('上传发票成功');
  668. invoiceDialog.visible = false;
  669. await getList();
  670. } finally {
  671. invoiceDialog.loading = false;
  672. }
  673. }
  674. const handleViewOrder = async (row: ZhongcheorderVO) => {
  675. orderProductDialog.visible = true;
  676. orderProductDialog.loading = true;
  677. orderProductDialog.list = [];
  678. try {
  679. const res = await getZhongCheOrderProducts(row.id);
  680. orderProductDialog.list = (res as any)?.data || (res as any)?.rows || res || [];
  681. } finally {
  682. orderProductDialog.loading = false;
  683. }
  684. }
  685. const handleViewLogistics = async (row: ZhongcheorderVO) => {
  686. logisticsDialog.visible = true;
  687. logisticsDialog.loading = true;
  688. logisticsDialog.trackLoading = false;
  689. logisticsDialog.packages = [];
  690. logisticsDialog.options = [];
  691. logisticsDialog.selectedId = '';
  692. logisticsDialog.companyName = '';
  693. logisticsDialog.traces = [];
  694. try {
  695. const res = await getZhongcheorderLogistics(row.id);
  696. const data = (res as any)?.data ?? res;
  697. const packages = (data?.list ?? data?.rows ?? data?.data ?? data) as any;
  698. if (Array.isArray(packages)) {
  699. logisticsDialog.packages = packages;
  700. logisticsDialog.options = packages
  701. .filter((p: any) => p?.id != null && !!p?.logisticNo)
  702. .map((p: any) => ({ label: String(p.logisticNo), value: String(p.id) }));
  703. const firstNo = logisticsDialog.options[0]?.value;
  704. if (firstNo) {
  705. logisticsDialog.selectedId = firstNo;
  706. handleLogisticNoChange(firstNo);
  707. }
  708. }
  709. } finally {
  710. logisticsDialog.loading = false;
  711. }
  712. }
  713. const handleLogisticNoChange = (no: any) => {
  714. const val = String(no ?? '');
  715. const pkg = logisticsDialog.packages.find((p: any) => String(p?.id ?? '') === val);
  716. logisticsDialog.companyName = pkg?.logisticsCompanyName ?? '';
  717. logisticsDialog.traces = [];
  718. }
  719. const handleQueryLogisticsTrack = async () => {
  720. const id = String(logisticsDialog.selectedId ?? '').trim();
  721. if (!id) return;
  722. logisticsDialog.trackLoading = true;
  723. logisticsDialog.traces = [];
  724. try {
  725. const res = await getZhongcheorderLogisticsTrack(id);
  726. const data = (res as any)?.data ?? res;
  727. const list = (data?.list ?? data?.rows ?? data?.data ?? data) as any;
  728. if (Array.isArray(list)) {
  729. logisticsDialog.traces = list.map((item: any) => ({
  730. time: item.time,
  731. ftime: item.ftime,
  732. context: item.context
  733. }));
  734. }
  735. } finally {
  736. logisticsDialog.trackLoading = false;
  737. }
  738. }
  739. onMounted(() => {
  740. getList();
  741. });
  742. </script>