order_detail.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. <template>
  2. <view class="verification-container">
  3. <!-- 内容区域 -->
  4. <view class="content">
  5. <!-- 用户信息卡片 -->
  6. <view class="info-card1">
  7. <view class="address-item">
  8. <view class="img-status-text">
  9. <image src="/static/img/icon-send.png" mode="" class="img"></image>
  10. <!-- <view class="status-text">{{getStatusText}}</view> -->
  11. </view>
  12. <view class="user-info">
  13. <AddressInfo :address="addressSend" />
  14. </view>
  15. </view>
  16. <view class="address-item">
  17. <view class="img-status-text">
  18. <image src="/static/img/icon-receive.png" mode="" class="img"></image>
  19. <!-- <view class="status-text">{{getStatusText}}</view> -->
  20. </view>
  21. <view class="user-info">
  22. <AddressInfo :address="addressReceive" />
  23. </view>
  24. </view>
  25. </view>
  26. <view class="action-title">运单信息</view>
  27. <OrderInfo :order-detail="orderInfo"></OrderInfo>
  28. <view class="action-title">费用信息</view>
  29. <OrderFeesInfo v-if="details?.feeList?.length" :order-detail="details.feeList" />
  30. </view>
  31. </view>
  32. </template>
  33. <script setup>
  34. import {
  35. ref,
  36. computed
  37. } from 'vue'
  38. import {
  39. onLoad,
  40. onShow
  41. } from '@dcloudio/uni-app'
  42. import OrderInfo from './components/OrderInfo.vue'
  43. import OrderFeesInfo from './components/OrderFeesInfo.vue'
  44. import AddressInfo from '@/components/AddressInfo.vue'
  45. import {
  46. getOrderDetail,
  47. getCostDetails
  48. } from '@/api/order.js'
  49. import {
  50. useAppStore
  51. } from '@/stores/app'
  52. const appStore = useAppStore()
  53. const shopOrderId = ref('')
  54. const addressSend = ref({})
  55. const addressReceive = ref({})
  56. const orderInfo = ref({})
  57. const details = ref({})
  58. const showOrderCofirmBtn = ref(false)
  59. const showOrderDispatchBtn = ref(false)
  60. const showOrderRefundBtn = ref(false)
  61. const showCallUserBtn = ref(true)
  62. onLoad((option) => {
  63. shopOrderId.value = option.waybillId;
  64. getOrderInfo()
  65. })
  66. const getOrderInfo = async () => {
  67. getOrderDetail(shopOrderId.value).then(res => {
  68. if (res.code == 200) {
  69. console.log('getOrderInfoApi=========', res)
  70. orderInfo.value = res.data;
  71. addressSend.value = {
  72. contactName: res.data.senderName,
  73. contactPhone: res.data.senderPhone,
  74. provinceName: res.data.senderProvince,
  75. cityName: res.data.senderCity,
  76. countyName: res.data.senderCounty,
  77. detailedAddress: res.data.senderAddress
  78. }
  79. addressReceive.value = {
  80. contactName: res.data.receiverName,
  81. contactPhone: res.data.receiverPhone,
  82. provinceName: res.data.receiverProvince,
  83. cityName: res.data.receiverCity,
  84. countyName: res.data.receiverCounty,
  85. detailedAddress: res.data.receiverAddress
  86. }
  87. }
  88. })
  89. let result = await getCostDetails({
  90. waybillId: shopOrderId.value
  91. })
  92. if (result.code == 200) {
  93. details.value = result.data;
  94. }
  95. console.log(result, '222')
  96. }
  97. // 返回按钮点击事件
  98. const handleBack = () => {
  99. uni.navigateBack()
  100. }
  101. // 确认核销按钮点击事件
  102. const handleVerification = () => {
  103. uni.showModal({
  104. title: '确认核销',
  105. content: '确定要核销此订单吗?',
  106. success: (res) => {
  107. if (res.confirm) {
  108. uni.showToast({
  109. title: '核销成功',
  110. icon: 'success'
  111. })
  112. // 这里可以添加核销成功的后续逻辑
  113. }
  114. }
  115. })
  116. }
  117. const makePhoneCall = (phoneNum) => {
  118. // 这里以拨打10086为例,实际使用时可以替换为动态获取的电话号码
  119. uni.makePhoneCall({
  120. phoneNumber: phoneNum, // 电话号码
  121. success: () => {
  122. console.log('拨打电话成功')
  123. },
  124. fail: (err) => {
  125. console.log('拨打电话失败:', err)
  126. }
  127. })
  128. }
  129. //确认订单是去派单状态
  130. const updateOrderDispatch = () => {
  131. if (!appStore.userInfo.orderDispatch) {
  132. uni.showToast({
  133. title: "当前会员不能使用此功,请升级为SVIP会员",
  134. icon: "none"
  135. })
  136. return
  137. }
  138. uni.showModal({
  139. title: '去派单',
  140. content: '是否确认去派单?',
  141. success: (res) => {
  142. if (res.confirm) {
  143. const params = {
  144. shopOrderId: orderInfo.value.shopOrderId,
  145. dispatchVerifyStatus: "0"
  146. }
  147. updateOrderDispatchApi(params).then(res => {
  148. if (res.code == 200) {
  149. uni.showToast({
  150. title: '操作成功',
  151. icon: 'success'
  152. })
  153. uni.navigateBack()
  154. }
  155. })
  156. }
  157. }
  158. })
  159. }
  160. //直接核销订单
  161. const updateOrderVerify = () => {
  162. const params = {
  163. shopOrderId: orderInfo.value.shopOrderId
  164. }
  165. updateOrderVerifyApi(params).then(res => {
  166. if (res.code == 200) {
  167. uni.showToast({
  168. title: '操作成功',
  169. icon: 'success'
  170. })
  171. uni.navigateBack()
  172. }
  173. })
  174. }
  175. //0 待服务 1 服务中 2 服务完成 3 待接单
  176. const startServe = () => {
  177. // 在实际UniApp项目中,使用以下代码:
  178. uni.scanCode({
  179. success: (res) => {
  180. console.log(res, '=============scanCode==startServe=')
  181. if (res.result == orderInfo.value.shopOrderId) {
  182. //这里判断 grabId 是否相同 相同的话直接更新
  183. updateOrderVerify()
  184. } else {
  185. uni.showModal({
  186. content: "服务订单与扫码订单不一致",
  187. confirmText: "确认",
  188. showCancel: false
  189. })
  190. }
  191. },
  192. fail: (err) => {
  193. uni.showToast({
  194. title: '扫码失败',
  195. icon: 'none'
  196. })
  197. }
  198. })
  199. }
  200. const handleOrderRefund = (status) => {
  201. if (status == '2') {
  202. uni.showModal({
  203. title: '拒绝退款',
  204. content: '是否确认拒绝退款?',
  205. success: (res) => {
  206. if (res.confirm) {
  207. updateOrderRefund(status)
  208. }
  209. }
  210. })
  211. return
  212. }
  213. uni.showModal({
  214. title: '确认退款',
  215. content: '是否确认退款?',
  216. success: (res) => {
  217. if (res.confirm) {
  218. updateOrderRefundSure(status)
  219. }
  220. }
  221. })
  222. }
  223. //处理退款订单 0 待审核 1 审核通过 2 审核拒绝
  224. const updateOrderRefundSure = (status) => {
  225. const params = {
  226. shopOrderId: orderInfo.value.shopOrderId
  227. }
  228. updateOrderRefundSureApi(params).then(res => {
  229. if (res.code == 200) {
  230. uni.showToast({
  231. title: '操作成功',
  232. icon: 'success'
  233. })
  234. uni.navigateBack()
  235. // emit('success');
  236. }
  237. })
  238. }
  239. //处理退款订单 0 待审核 1 审核通过 2 审核拒绝
  240. const updateOrderRefund = (status) => {
  241. const params = {
  242. shopOrderId: orderInfo.value.shopOrderId,
  243. reviewResult: status
  244. }
  245. updateOrderRefundApi(params).then(res => {
  246. if (res.code == 200) {
  247. uni.showToast({
  248. title: '操作成功',
  249. icon: 'success'
  250. })
  251. uni.navigateBack()
  252. }
  253. })
  254. }
  255. // 发布抢单
  256. const publishOrder = () => {
  257. uni.navigateTo({
  258. url: '/pages/dispatchOrders/publishOrder?id=' + orderInfo.value.shopOrderId
  259. })
  260. }
  261. // 直接派单
  262. const assignOrder = () => {
  263. uni.navigateTo({
  264. url: '/pages/dispatchOrders/dispatch?id=' + orderInfo.value.shopOrderId
  265. })
  266. }
  267. const reSetBtnStatus = () => {
  268. showOrderCofirmBtn.value = false
  269. showOrderDispatchBtn.value = false
  270. showOrderRefundBtn.value = false
  271. showCallUserBtn.value = false
  272. }
  273. //orderType: 订单类型(1-全部订单, 2-待确认, 3-待核销, 4-已完成, 5-申请退款, 6-服务中)
  274. const getStatusText = computed(() => {
  275. // shop_order_status 商品订单状态(0 待支付 1 待使用 2 退款中 3 退款成功 4 退款失败 5 服务完成)
  276. // shop_evaluate_status 评价状态(0 待评价 1 已评价)
  277. // shop_refund_review_status 订单退款审核状态(0 待审核 1 审核通过 2 审核拒绝)
  278. // shop_service_status 服务状态:0=待服务,1=正在服务中,2=服务完成
  279. // shop_confirm_status 确认状态:0=待确认,1=已确认
  280. // shop_dispatch_verify_status 派单核销状态:0=待派单,1=待核销,2=已派单,3=已核销
  281. //dispatchInfo.shopOrderServiceStatus 0 待派单 1 已派单 2 待抢单 3 已抢单
  282. reSetBtnStatus()
  283. if (orderInfo.value.shopOrderStatus == '2') {
  284. showOrderRefundBtn.value = true
  285. return '申请退款'
  286. }
  287. if (orderInfo.value.shopOrderStatus == '3') {
  288. showCallUserBtn.value = true
  289. return '退款成功'
  290. }
  291. if (orderInfo.value.shopOrderStatus == '4') {
  292. showCallUserBtn.value = true
  293. return '退款失败'
  294. }
  295. if (orderInfo.value.shopOrderStatus == '0') {
  296. showCallUserBtn.value = true
  297. return '待支付'
  298. }
  299. if (orderInfo.value.shopConfirmStatus == '0') {
  300. showOrderCofirmBtn.value = true
  301. return '待确认'
  302. }
  303. if (orderInfo.value.shopOrderStatus == '5') {
  304. if (orderInfo.value.shopEvaluateStatus == '0') {
  305. showCallUserBtn.value = true
  306. return '待评价'
  307. }
  308. if (orderInfo.value.shopEvaluateStatus == '1') {
  309. showCallUserBtn.value = true
  310. return '已评价'
  311. }
  312. return '服务完成'
  313. }
  314. //orderDetail.shopConfirmStatus == '1' 的时候才会有下边的状态值
  315. if (orderInfo.value.shopOrderStatus == '1' && orderInfo.value.shopConfirmStatus == '1') {
  316. if (orderInfo.value.dispatchInfo && orderInfo.value.dispatchInfo.shopOrderServiceStatus == '2') {
  317. showCallUserBtn.value = true
  318. return '待抢单'
  319. }
  320. if (orderInfo.value.dispatchInfo && orderInfo.value.dispatchInfo.shopOrderServiceStatus == '3') {
  321. showCallUserBtn.value = true
  322. return '已抢单'
  323. }
  324. switch (orderInfo.value.shopDispatchVerifyStatus) {
  325. case '0':
  326. //这里需要看下是否是有会员 派单权限
  327. showOrderDispatchBtn.value = true
  328. return '待派单' // 待派单
  329. case '1':
  330. showCallUserBtn.value = true
  331. return '待核销' // 待核销
  332. case '2':
  333. showCallUserBtn.value = true
  334. return '已派单' // 已派单
  335. case '3':
  336. showCallUserBtn.value = true
  337. return '已核销' // 已核销
  338. }
  339. return '待使用'
  340. }
  341. })
  342. </script>
  343. <style lang="scss" scoped>
  344. .verification-container {
  345. min-height: 100vh;
  346. background-color: #F5F7FA;
  347. position: relative;
  348. padding-bottom: 140rpx;
  349. /* 为底部固定按钮预留空间 */
  350. .content {
  351. padding: 20rpx;
  352. }
  353. .verification-status {
  354. height: 72rpx;
  355. background: #FFF7EC;
  356. border-radius: 16rpx 16rpx 16rpx 16rpx;
  357. align-items: center;
  358. display: flex;
  359. padding-left: 16rpx;
  360. image {
  361. width: 28rpx;
  362. height: 28rpx;
  363. }
  364. .status-text {
  365. margin-left: 8rpx;
  366. height: 40rpx;
  367. font-weight: 400;
  368. font-size: 24rpx;
  369. color: #FFAF41;
  370. line-height: 40rpx;
  371. }
  372. }
  373. .action-title {
  374. height: 48rpx;
  375. font-weight: bold;
  376. font-size: 32rpx;
  377. color: #333333;
  378. line-height: 48rpx;
  379. margin: 20rpx 0rpx;
  380. }
  381. .info-card1 {
  382. background: #fff;
  383. border-radius: 32rpx;
  384. padding: 20rpx;
  385. margin-bottom: 16rpx;
  386. // F1F3F8
  387. .address-item {
  388. display: flex;
  389. &:first-child {
  390. border-bottom: 2rpx solid #F1F3F8;
  391. padding-bottom: 20rpx;
  392. }
  393. &:last-child {
  394. padding-top: 20rpx;
  395. }
  396. }
  397. .user-info {
  398. flex: 1;
  399. margin-left: 26rpx;
  400. }
  401. .img-status-text {
  402. align-self: center;
  403. text-align: center;
  404. flex-shrink: 0;
  405. .img {
  406. width: 56rpx;
  407. height: 56rpx;
  408. }
  409. .status-text {
  410. font-size: 24rpx;
  411. color: #0089FF;
  412. font-size: 500;
  413. }
  414. }
  415. }
  416. .info-card {
  417. background-color: #ffffff;
  418. border-radius: 16rpx;
  419. overflow: hidden;
  420. padding: 16rpx;
  421. margin-top: 16rpx;
  422. .card-header {
  423. display: flex;
  424. align-items: center;
  425. image {
  426. width: 35rpx;
  427. height: 35rpx;
  428. }
  429. .card-title {
  430. height: 48rpx;
  431. line-height: 48rpx;
  432. font-weight: 400;
  433. font-size: 32rpx;
  434. font-weight: bold;
  435. color: #333;
  436. margin-left: 10rpx;
  437. }
  438. }
  439. }
  440. .verification-card-body {
  441. display: flex;
  442. flex-direction: column;
  443. align-items: center;
  444. justify-content: center;
  445. image {
  446. margin-top: 16rpx;
  447. width: 320rpx;
  448. height: 320rpx;
  449. }
  450. }
  451. .verification-code {
  452. padding: 20rpx 0;
  453. display: flex;
  454. align-items: center;
  455. .code-label {
  456. font-size: 28rpx;
  457. color: #666;
  458. }
  459. .code-value {
  460. font-size: 32rpx;
  461. color: #333;
  462. font-weight: bold;
  463. }
  464. }
  465. .fixed-footer {
  466. position: fixed;
  467. bottom: 0;
  468. left: 0;
  469. right: 0;
  470. background-color: #ffffff;
  471. box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.1);
  472. .footer-buttons {
  473. display: flex;
  474. justify-content: center;
  475. padding: 22rpx;
  476. .back {
  477. width: 238rpx;
  478. height: 88rpx;
  479. background: rgba(0, 137, 255, 0.1);
  480. border-radius: 8rpx 8rpx 8rpx 8rpx;
  481. font-family: PingFang SC, PingFang SC;
  482. font-weight: 400;
  483. font-size: 32rpx;
  484. color: #0089FF;
  485. line-height: 88rpx;
  486. text-align: center;
  487. }
  488. .confirm {
  489. width: 416rpx;
  490. height: 88rpx;
  491. margin-left: 32rpx;
  492. align-items: center;
  493. background: #0089FF;
  494. border-radius: 16rpx 16rpx 16rpx 16rpx;
  495. font-family: PingFang SC Bold, PingFang SC Bold;
  496. font-weight: 400;
  497. font-size: 32rpx;
  498. color: #FFFFFF;
  499. line-height: 88rpx;
  500. text-align: center;
  501. }
  502. .call {
  503. width: 327rpx;
  504. height: 88rpx;
  505. border-radius: 16rpx 16rpx 16rpx 16rpx;
  506. font-family: PingFang SC, PingFang SC;
  507. font-weight: 400;
  508. font-size: 32rpx;
  509. line-height: 88rpx;
  510. text-align: center;
  511. }
  512. .call-user {
  513. width: 100%;
  514. height: 88rpx;
  515. border-radius: 16rpx 16rpx 16rpx 16rpx;
  516. font-family: PingFang SC, PingFang SC;
  517. font-weight: 400;
  518. font-size: 32rpx;
  519. line-height: 88rpx;
  520. text-align: center;
  521. background: #0089FF;
  522. color: #FFFFFF;
  523. margin: 0rpx 32rpx;
  524. }
  525. .shop {
  526. background: rgba(0, 137, 255, 0.1);
  527. color: #0089FF;
  528. }
  529. .user {
  530. margin-left: 32rpx;
  531. background: #0089FF;
  532. color: #FFFFFF;
  533. }
  534. }
  535. }
  536. }
  537. </style>