order_detail.vue 13 KB

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