x-orderManagement.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. <template>
  2. <view style="width: 100%;">
  3. <view class="card_ordermang" v-for="(item,index) in orderList" :key="index" @click="goOrderDetails(item)">
  4. <view class="head_ordermang space_between">
  5. <view class="waybill_title">运单号:<span>{{item.waybillNo}}</span></view>
  6. <span class="card_state" :style="{color:getState(item.status)}">{{orderStatus(item.status)}}</span>
  7. </view>
  8. <view class="title_ordermang"><span>订单号:</span>{{item.orderNo}}</view>
  9. <view class="title_ordermang"><span>收货人地址:</span>{{item.consigneeAddressDetails}}</view>
  10. <view class="title_ordermang"><span>收货人电话:</span>{{item.consigneeAddressPhone}}</view>
  11. <view class="title_ordermang"><span>下单时间:</span>{{item.orderTime}}</view>
  12. <view style="display: flex;margin-top: 15rpx;"
  13. v-if="item.status == 1 || item.status == 2 || item.status == 3">
  14. <!-- <view class="btn_printil markd10"
  15. @click.stop="modifyOrder(item)">
  16. <u-button size="small" type="warning" text="修改运单"></u-button>
  17. </view>
  18. <view class="btn_printil markd10" @click.stop="antiDismantle(item)">
  19. <u-button size="small" type="primary" text="防拆标签"></u-button>
  20. </view>
  21. <view class="btn_printil markd10" @click.stop="sendOrders(item)">
  22. <u-button size="small" type="success" text="派单"></u-button>
  23. </view> -->
  24. <view class="btn_printil markd10" @click.stop="toDeliver(item)">
  25. <u-button size="small" type="success" text="去配送"></u-button>
  26. </view>
  27. </view>
  28. <view style="display: flex;" v-if="item.status == 4 && !item.is_secondary_distribution">
  29. <view class="btn_printil markd10" @click.stop="rejection(item)">
  30. <u-button size="small" type="error" text="拒收"></u-button>
  31. </view>
  32. <view class="btn_printil markd10" @click.stop="signFor(item)">
  33. <u-button size="small" type="primary" text="签收"></u-button>
  34. </view>
  35. </view>
  36. <view style="display: flex;" v-else-if="item.status == 4 && item.is_secondary_distribution">
  37. <view class="btn_printil markd10" @click.stop="finished(item)">
  38. <u-button size="small" type="success" text="已完成"></u-button>
  39. </view>
  40. <view class="btn_printil markd10" @click.stop="distributionOrder(item)">
  41. <u-button size="small" type="primary" text="分配订单"></u-button>
  42. </view>
  43. </view>
  44. </view>
  45. <u-popup :show="signForShow" mode="center" round="6" closeable :closeOnClickOverlay="false" @close="close">
  46. <view class="center_in title_sign">{{signRejection}}</view>
  47. <view class="card_sign_for">
  48. <view class="img_sign_rejection">运单号: {{orderNumber}}</view>
  49. <view style="margin-bottom: 20rpx;" v-if="!rejectionFlag">
  50. <u-radio-group v-model="modePayment">
  51. <span style="font-size: 30rpx;margin: 0rpx 20rpx 15rpx 0rpx;">支付方式:</span>
  52. <u-radio style="margin: 0rpx 20rpx 15rpx 0rpx;" v-for="(item, index) in radiolist" :key="index"
  53. :label="item.name" :name="item.value"></u-radio>
  54. </u-radio-group>
  55. </view>
  56. <view style="margin-bottom: 20rpx;" v-if="!rejectionFlag">
  57. <u-radio-group v-model="statePayment">
  58. <span style="font-size: 30rpx;margin: 0rpx 20rpx 15rpx 0rpx;">支付状态:</span>
  59. <u-radio style="margin: 0rpx 20rpx 15rpx 0rpx;" v-for="(item, index) in stateList" :key="index"
  60. :label="item.name" :name="item.value"></u-radio>
  61. </u-radio-group>
  62. <view v-if="statePayment == 2">
  63. <u--input placeholder="请输入未结清备注" border="surround" v-model="remarksSettled"></u--input>
  64. </view>
  65. </view>
  66. <view class="card_image_sign">
  67. <view class="img_sign_rejection">{{signRejection}}图片</view>
  68. <u-upload :fileList="fileList1" name="1" multiple :maxCount="10" @afterRead="afterRead"
  69. @delete="deletePic"></u-upload>
  70. </view>
  71. <view class="card_image_sign">
  72. <view class="img_sign_rejection" @click="goSignature('client')">客户签字</view>
  73. <u-image :showLoading="true" :src="imageData" width="300rpx" height="155rpx"
  74. @click="goSignature('client')" mode="scaleToFill"></u-image>
  75. </view>
  76. <view class="rejection_card" v-if="rejectionFlag">
  77. <view class="img_sign_rejection">拒收原因</view>
  78. <u-textarea v-model="rejectionValue" placeholder="请输入拒收原因" autoHeight></u-textarea>
  79. </view>
  80. <u-button style="margin-top: 30rpx;" size="small" type="primary" text="确定"
  81. @click="confirm()"></u-button>
  82. </view>
  83. </u-popup>
  84. <u-popup :show="antiShow" mode="center" closeable :closeOnClickOverlay="false" round="6" @close="close">
  85. <view class="card_dismantle">
  86. <view class="headline_anti">防拆标签</view>
  87. <x-form ref="goods" :list="goodsList" :model="goodsModel" :rules="goodsRules"></x-form>
  88. <u-button style="margin-top: 10rpx;" size="small" type="primary" text="确定"
  89. @click="modifiedTamper()"></u-button>
  90. </view>
  91. </u-popup>
  92. <!-- 确定完成 -->
  93. <u-modal :show="logoutShow" showCancelButton :title="title" :content='content' @cancel="cancel"
  94. @confirm="definiteCompletion"></u-modal>
  95. </view>
  96. </template>
  97. <script>
  98. const ENV = require('@/.env.js')
  99. import {
  100. formRules,
  101. } from "./waybill.js";
  102. export default {
  103. name: 'xOrderManagement',
  104. props: {
  105. // 运单列表
  106. orderList: {
  107. type: Array,
  108. default: () => [],
  109. },
  110. userInfo: {
  111. type: Object,
  112. default: () => {},
  113. }
  114. },
  115. data() {
  116. return {
  117. signForShow: false,
  118. fileList1: [],
  119. rejectionValue: '',
  120. rejectionFlag: false,
  121. signRejection: '',
  122. orderNumber: '',
  123. imageUrl: '',
  124. antiShow: false,
  125. goodsList: formRules(),
  126. goodsModel: {
  127. tamperProofLabel: '',
  128. tamperProofLabelImg: '',
  129. },
  130. goodsRules: {
  131. tamperProofLabel: {
  132. required: true,
  133. message: '请输入防拆标签码',
  134. trigger: ['blur', 'change']
  135. },
  136. tamperProofLabelImg: {
  137. required: true,
  138. message: '请上传防拆标签图片',
  139. trigger: ['blur', 'change']
  140. },
  141. },
  142. antiList: {},
  143. imageData: '',
  144. radiolist: [{
  145. name: '现金',
  146. value: 1,
  147. }, {
  148. name: '线上支付',
  149. value: 2,
  150. }, {
  151. name: '银行卡',
  152. value: 3,
  153. }, {
  154. name: '医保',
  155. value: 4,
  156. }, {
  157. name: '其他',
  158. value: 5,
  159. }],
  160. stateList: [{
  161. name: '已结清',
  162. value: 1,
  163. }, {
  164. name: '未结清',
  165. value: 2,
  166. }],
  167. modePayment: null,
  168. statePayment: null,
  169. remarksSettled: '',
  170. logoutShow: false,
  171. title: '确定完成该订单?',
  172. content: '确定完成后将无法分配运单,重新下单后即可分配',
  173. orderId: null,
  174. }
  175. },
  176. mounted() {
  177. // console.log(this.userInfo, 26)
  178. },
  179. methods: {
  180. // 打印条码
  181. printBarCode(value) {
  182. this.$cache.setCache('commodity', JSON.stringify(value))
  183. uni.navigateTo({
  184. url: '/pages/order/quantum?waybillNo=' + value.waybillNo + '&printType=barCode'
  185. });
  186. },
  187. // 派单
  188. sendOrders(value) {
  189. this.$emit('sendOrders', value)
  190. },
  191. // 防拆标签
  192. antiDismantle(value) {
  193. this.antiList = value
  194. this.antiShow = true
  195. this.goodsModel.tamperProofLabel = value.tamperProofLabel
  196. this.goodsModel.tamperProofLabelImg = value.tamperProofLabelImg
  197. this.goodsModel.id = value.id
  198. if (value.tamperProofLabelImg) {
  199. let arrImg = value.tamperProofLabelImg.split(',')
  200. let arrImgList = []
  201. arrImg.forEach((item) => {
  202. const arr = {
  203. url: item,
  204. }
  205. arrImgList.push(arr)
  206. })
  207. this.$nextTick(() => {
  208. this.$refs.goods.fileList1 = arrImgList
  209. })
  210. }
  211. },
  212. // 去配送
  213. toDeliver(event) {
  214. uni.setStorageSync('incubatorValue', event.coolerBox)
  215. uni.setStorageSync('orderValue', JSON.stringify(event))
  216. uni.navigateTo({
  217. url: '/pages/order/dispatching'
  218. });
  219. },
  220. // 拒收
  221. rejection(value) {
  222. this.orderNumber = value.waybillNo
  223. this.signForShow = true
  224. this.rejectionFlag = true
  225. this.signRejection = '拒收'
  226. },
  227. // 签收
  228. signFor(value) {
  229. this.orderNumber = value.waybillNo
  230. this.signForShow = true
  231. this.rejectionFlag = false
  232. this.signRejection = '签收'
  233. },
  234. // 已完成
  235. finished(event) {
  236. this.orderId = event.id
  237. this.logoutShow = true
  238. },
  239. // 分配订单
  240. distributionOrder(event) {
  241. uni.navigateTo({
  242. url: '/pages/order/distributionOrder?flag=true&waybillNo=' + event.waybillNo
  243. });
  244. },
  245. // 确定签收/拒收
  246. confirm() {
  247. let params = {
  248. waybillNo: this.orderNumber,
  249. receiptImg: this.imageUrl,
  250. status: 5,
  251. rejectionReason: this.rejectionValue,
  252. receiptsign: this.imageData,
  253. paymentType: this.modePayment,
  254. paymentStatus: this.statePayment,
  255. paymentremark: this.remarksSettled,
  256. }
  257. let verify = false
  258. if (this.rejectionFlag) {
  259. params.status = 6
  260. verify = this.verification(params)
  261. } else {
  262. params.status = 5
  263. verify = this.verification(params)
  264. }
  265. if (verify) {
  266. this.$api.post('/api/waybill/receipt', params).then(res => {
  267. if (res.code == 200) {
  268. this.signForShow = false
  269. uni.$u.toast(res.msg)
  270. this.$emit('operateSuccessfully')
  271. } else {
  272. uni.$u.toast(res.msg)
  273. }
  274. })
  275. }
  276. },
  277. // 拒收签收验证
  278. verification(params) {
  279. let flag = false
  280. if (this.rejectionFlag) {
  281. if (params.receiptImg) {
  282. flag = true
  283. } else {
  284. uni.$u.toast('请上传' + this.signRejection + '图片')
  285. }
  286. } else {
  287. if (params.paymentType) {
  288. if (params.paymentStatus) {
  289. if (params.receiptImg) {
  290. flag = true
  291. } else {
  292. uni.$u.toast('请上传' + this.signRejection + '图片')
  293. }
  294. } else {
  295. uni.$u.toast('请选择支付状态')
  296. }
  297. } else {
  298. uni.$u.toast('请选择支付方式')
  299. }
  300. }
  301. return flag
  302. },
  303. // 修改防拆标签
  304. async modifiedTamper() {
  305. let flag2 = await this.$refs['goods'].validateForm();
  306. if (flag2) {
  307. let params = {
  308. senderAddressName: this.antiList.senderAddressName,
  309. senderAddressPhone: this.antiList.senderAddressPhone,
  310. senderAddressDetails: this.antiList.senderAddressDetails,
  311. consigneeAddressName: this.antiList.consigneeAddressName,
  312. consigneeAddressPhone: this.antiList.consigneeAddressPhone,
  313. consigneeAddressDetails: this.antiList.consigneeAddressDetails,
  314. deliveryName: this.antiList.deliveryName,
  315. deliveryPhone: this.antiList.deliveryPhone,
  316. ...this.goodsModel,
  317. }
  318. uni.showLoading();
  319. // 修改运单
  320. this.$api.put('/api/waybill', params).then(res => {
  321. if (res.code == 200) {
  322. this.antiShow = false
  323. uni.$u.toast(res.msg)
  324. this.$emit('proofRenewal')
  325. } else {
  326. uni.$u.toast('修改失败')
  327. }
  328. uni.hideLoading();
  329. }).catch(() => {
  330. uni.hideLoading();
  331. })
  332. }
  333. },
  334. // 打印温湿度记录
  335. humidityRecording(value) {
  336. this.$cache.setCache('commodity', JSON.stringify(value))
  337. uni.navigateTo({
  338. url: '/pages/order/quantum?waybillNo=' + value.waybillNo + '&printType=record'
  339. });
  340. },
  341. // 修改运单
  342. modifyOrder(value) {
  343. this.$cache.setCache('orderDetails', value)
  344. uni.redirectTo({
  345. url: '/pages/order/addWaybill?title=修改运单&type=2'
  346. });
  347. },
  348. // 运单详情
  349. goOrderDetails(value) {
  350. this.$cache.setCache('orderDetails', value)
  351. uni.navigateTo({
  352. url: '/pages/order/orderDetails?type=details'
  353. });
  354. },
  355. // 运单状态
  356. orderStatus(value) {
  357. if (value == 3) {
  358. return '待配送'
  359. } else if (value == 4) {
  360. return '配送中'
  361. } else if (value == 5) {
  362. return '已送达'
  363. } else if (value == 6) {
  364. return '已拒收'
  365. } else if (value == 8) {
  366. return '已取消'
  367. }
  368. },
  369. // 运单文字颜色
  370. getState(value) {
  371. if (value == 3) {
  372. return '#9ddd54'
  373. } else if (value == 4) {
  374. return '#4bc7fc'
  375. } else if (value == 5) {
  376. return '#1cc723'
  377. } else if (value == 6) {
  378. return '#fe880e'
  379. } else if (value == 8) {
  380. return '#fa3534'
  381. }
  382. },
  383. // 新增图片
  384. async afterRead(event) {
  385. // 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
  386. let lists = [].concat(event.file)
  387. let fileListLen = this[`fileList${event.name}`].length
  388. lists.map((item) => {
  389. this[`fileList${event.name}`].push({
  390. ...item,
  391. status: 'uploading',
  392. message: '上传中'
  393. })
  394. })
  395. uni.showLoading({
  396. title: '上传中',
  397. mask: true,
  398. })
  399. for (let i = 0; i < lists.length; i++) {
  400. const result = await this.uploadFilePromise(lists[i].url)
  401. let item = this[`fileList${event.name}`][fileListLen]
  402. this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
  403. status: 'success',
  404. message: '',
  405. url: result
  406. }))
  407. fileListLen++
  408. }
  409. var arr = []
  410. this.fileList1.forEach(item1 => {
  411. arr.push(item1.url)
  412. })
  413. uni.hideLoading();
  414. this.imageUrl = arr.join()
  415. },
  416. // 删除图片
  417. deletePic(event) {
  418. this[`fileList${event.name}`].splice(event.index, 1)
  419. var arr = []
  420. this.fileList1.forEach(item1 => {
  421. arr.push(item1.url)
  422. })
  423. this.imageUrl = arr.join()
  424. },
  425. // 签字
  426. goSignature(title) {
  427. uni.navigateTo({
  428. url: '/pages/order/signatureBoard'
  429. });
  430. },
  431. uploadFilePromise(url) {
  432. return new Promise((resolve, reject) => {
  433. let a = uni.uploadFile({
  434. url: ENV.APP_DEV_URL + '/api/upload', // 仅为示例,非真实的接口地址
  435. filePath: url,
  436. name: 'file',
  437. header: {
  438. 'Authorization': 'Bearer ' + uni.getStorageSync('access_token'),
  439. },
  440. success: (res) => {
  441. let state = JSON.parse(res.data)
  442. setTimeout(() => {
  443. if (state.code == 200) {
  444. resolve(state.data)
  445. }
  446. }, 100)
  447. }
  448. });
  449. })
  450. },
  451. // 确定完成订单
  452. definiteCompletion() {
  453. this.$api.put('/api/waybill/update-status', {
  454. id: [this.orderId],
  455. status: 5,
  456. }).then(res => {
  457. if (res.code == 200) {
  458. uni.$u.toast('操作成功')
  459. this.$emit('definiteCompletion')
  460. } else {
  461. uni.$u.toast(res.msg)
  462. }
  463. this.logoutShow = false
  464. })
  465. console.log('确定完成订单')
  466. },
  467. // 取消
  468. cancel() {
  469. this.logoutShow = false
  470. },
  471. close() {
  472. this.signForShow = false
  473. this.modePayment = null
  474. this.statePayment = null
  475. this.remarksSettled = ''
  476. this.fileList1 = []
  477. this.imageData = ''
  478. this.rejectionValue = ''
  479. this.antiShow = false
  480. },
  481. }
  482. }
  483. </script>
  484. <style lang="scss">
  485. .card_ordermang {
  486. background-color: #fff;
  487. padding: 20rpx;
  488. border-radius: 10rpx;
  489. margin: 20rpx;
  490. }
  491. .head_ordermang {
  492. margin-bottom: 10rpx;
  493. }
  494. .title_ordermang {
  495. margin-top: 10rpx;
  496. font-size: 26rpx;
  497. color: #909399;
  498. span {
  499. font-size: 26rpx;
  500. color: #909399;
  501. margin-right: 10rpx;
  502. }
  503. }
  504. .waybill_title {
  505. font-size: 30rpx;
  506. span {
  507. margin-left: 10rpx;
  508. }
  509. }
  510. .card_state {
  511. color: #606266;
  512. font-size: 28rpx;
  513. }
  514. .card_specification {
  515. display: flex;
  516. align-items: center;
  517. }
  518. .specification_title {
  519. margin-right: 20rpx;
  520. }
  521. .btn_printil {
  522. flex: 1;
  523. margin-top: 10px;
  524. }
  525. .markd10:nth-child(1) {
  526. margin: 10rpx 10rpx 0rpx 0rpx;
  527. }
  528. .markd10:nth-child(2) {
  529. margin: 10rpx 0rpx 0rpx 10rpx;
  530. }
  531. .markd10:nth-child(3) {
  532. margin: 10rpx 0rpx 0rpx 20rpx;
  533. }
  534. .title_sign {
  535. padding: 10rpx 0rpx;
  536. height: 60rpx;
  537. }
  538. .card_sign_for {
  539. width: 640rpx;
  540. padding: 10rpx 30rpx 30rpx 30rpx;
  541. }
  542. .rejection_card {
  543. margin-bottom: 20rpx;
  544. }
  545. .card_image_sign {
  546. display: flex;
  547. flex-direction: column;
  548. margin-bottom: 10rpx;
  549. }
  550. .img_sign_rejection {
  551. font-size: 30rpx;
  552. margin-bottom: 20rpx;
  553. }
  554. .card_dismantle {
  555. padding: 30rpx;
  556. }
  557. .headline_anti {
  558. font-size: 38rpx;
  559. font-weight: 600;
  560. display: flex;
  561. justify-content: center;
  562. border-bottom: 1rpx solid #e7e6e4;
  563. padding-bottom: 15rpx;
  564. margin-bottom: 15rpx;
  565. align-items: center;
  566. }
  567. ::v-deep .u-radio-group--row {
  568. flex-wrap: wrap;
  569. }
  570. </style>