You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

464 lines
11 KiB

8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
  1. <template>
  2. <view class="content">
  3. <view style="width: 710rpx; margin: 40rpx auto 20rpx;">
  4. <view class="flex rr" style="align-items: center;">
  5. <uni-icons type="sound" size="50rpx" color="#FBA54F"></uni-icons>
  6. <view class="xx" v-html="notice">
  7. </view>
  8. <!-- 长沙市刘师傅在服务过程中客户投诉服务过程中有不文明的行为,扣信用分5分罚款500元公布三日望引以为戒 -->
  9. </view>
  10. <view
  11. style="width: 670rpx;height: 80rpx;background-color: #fff; border-radius: 16rpx;padding: 15rpx 20rpx;">
  12. <view class="flex-sb" style="line-height: 40rpx; font-size: 28rpx;">
  13. <view :class="{'sb-w8' : true, select : item == selectDate}" @click="onSelectDate(item)"
  14. v-for="(item, index) in dateList">
  15. <view class="">
  16. {{ item.format('dddd')[2] }}
  17. </view>
  18. <view class="">
  19. {{ index == 0 ? '今' : index == 1 ? '明' : item.format('DD') }}
  20. </view>
  21. </view>
  22. <!-- <view class="sb-w8" style="border-left: 1rpx solid #999;"><uni-icons type="list" size="34rpx"/></view> -->
  23. </view>
  24. <!-- <view class="flex-sb" style="line-height: 48rpx;">
  25. <view class="sb-w8" v-for="(item, index) in dateList">
  26. {{ index == 0 ? '今' : index == 1 ? '明' : item.format('DD') }}
  27. </view> -->
  28. <!-- <view class="sb-w8" style="border-left: 1rpx solid #999;"><uni-icons type="down" size="34rpx"/></view> -->
  29. <!-- </view> -->
  30. </view>
  31. <view class="flex-sb" style="margin-top: 20rpx;">
  32. <view :class="{'status-card' : true, select : queryParams.state == 0}" @click="selectTenState(0)">
  33. <view>
  34. <view class="num">{{ completedQuantity }}</view>
  35. <view>已完成</view>
  36. </view>
  37. </view>
  38. <view :class="{'status-card' : true, select : queryParams.state == 1}" @click="selectTenState(1)">
  39. <view>
  40. <view class="num">{{ confirmedQuantity }}</view>
  41. <view>待确认</view>
  42. </view>
  43. </view>
  44. <view :class="{'status-card' : true, select : queryParams.state == 2}" @click="selectTenState(2)">
  45. <view>
  46. <view class="num">{{ numberOfVisits }}</view>
  47. <view>待上门</view>
  48. </view>
  49. </view>
  50. </view>
  51. <view class="mt20">
  52. <van-list v-if="orderList.length > 0" v-model:loading="loading" :finished="finished" @load="onLoad">
  53. <view class="item" v-for="(item, index) in orderList"
  54. @click="toOrderDetail(item.id)">
  55. <view class="top">
  56. <view class="service">
  57. <text>{{item.projectId_dictText}}</text>
  58. <uni-icons type="right" size="15"></uni-icons>
  59. <text>{{item.type_dictText}}</text>
  60. </view>
  61. <view class="status">
  62. <text> {{item.tenState_dictText}}</text>
  63. </view>
  64. </view>
  65. <view class="content">
  66. <view class="left">
  67. <image mode="aspectFill" :src="item.image"></image>
  68. <view class="tag">
  69. {{item.technicianId_dictText}}
  70. </view>
  71. </view>
  72. <view class="right">
  73. <view class="text-hidden-1">
  74. 客户姓名{{item.name}}
  75. </view>
  76. <view class="text-hidden-1">
  77. 下单时间{{item.createTime}}
  78. </view>
  79. <view class="text-hidden-1">
  80. 下单地址{{item.addressId_dictText}}
  81. </view>
  82. <view class="text-hidden-1">
  83. 总计时间{{item.useTime}}分钟
  84. </view>
  85. <view class="price">
  86. 总价格<text class="num">{{item.money}}</text>
  87. </view>
  88. </view>
  89. </view>
  90. <view v-if="item.state !=4" class="bottom">
  91. <view class="b2" v-if="item.tenState == 0"
  92. @click.stop="confirmVipOrder(item, getOrderList)">
  93. 确认订单
  94. </view>
  95. <view class="b2" v-if="item.tenState == 1" @click.stop="startVipOrder(item, getOrderList)">
  96. 技师出发
  97. </view>
  98. <view class="b2" v-if="item.tenState == 2" @click.stop="arriveVipOrder(item, getOrderList)">
  99. 到达打卡
  100. </view>
  101. <view class="b2" v-if="item.tenState == 3"
  102. @click.stop="startVipService(item, startServiceCallback)">
  103. 开始服务
  104. </view>
  105. <view class="b1" v-if="item.tenState == 4 && !item.isTimeout"
  106. @click.stop="toCountdown(item)">
  107. 服务时间
  108. </view>
  109. <view class="b2" v-if="item.tenState == 4"
  110. @click.stop="endVipService(item, toEvaluate, item.id, item.projectId,item.technicianId)">
  111. 结束服务
  112. </view>
  113. <!-- <view class="b1" @click.stop="toEvaluate()" v-if="item.tenState == 5">
  114. 投诉举报
  115. </view> -->
  116. <view class="b2" @click.stop="toEvaluate(item.id,item.projectId,item.technicianId)"
  117. v-if="item.tenState == 5">
  118. 立即评价
  119. </view>
  120. </view>
  121. <view v-else class="bottom">
  122. <view @click.stop="()=>{}" class="b3">
  123. 用户取消
  124. </view>
  125. </view>
  126. </view>
  127. </van-list>
  128. <van-empty v-else image="/static/empty/order.png" image-size="400rpx" :description="getStatus()" />
  129. </view>
  130. </view>
  131. </view>
  132. </template>
  133. <script>
  134. import orderMixins from '@/mixins/order.js'
  135. export default {
  136. mixins: [orderMixins],
  137. data() {
  138. return {
  139. dateList: [],
  140. active: 0,
  141. queryParams: {
  142. state: 1,
  143. pageNo: 1,
  144. pageSize: 10
  145. },
  146. orderList: [], //订单列表数据
  147. loading: false,
  148. finished: false,
  149. tenState: 0,
  150. selectDate: null,
  151. config: [],
  152. notice: '',
  153. completedQuantity: 0,
  154. confirmedQuantity: 0,
  155. numberOfVisits: 0,
  156. countdownOrder: uni.getStorageSync('countdownOrder') ? JSON.parse(uni.getStorageSync('countdownOrder')) :
  157. {}
  158. }
  159. },
  160. onShow() {
  161. this.getOrderList(this.queryParams.state)
  162. this.getConfig()
  163. this.dateList = []
  164. let today = this.dayjs()
  165. this.selectDate = today;
  166. this.dateList.push(today)
  167. for (let i = 1; i < 7; i++) {
  168. this.dateList.push(today.add(i, 'day'))
  169. }
  170. },
  171. methods: {
  172. onLoad() {
  173. this.queryParams.pageSize += 10
  174. this.getOrderList()
  175. },
  176. //获取订单列表
  177. getOrderList(state, order) {
  178. let params = {
  179. ...this.queryParams,
  180. }
  181. if (this.selectDate) {
  182. params.serviceDate = this.selectDate.format('YYYY-MM-DD')
  183. }
  184. this.$api('getTenOrderPageList', params, res => {
  185. if (res.code == 200) {
  186. res.result.records.forEach(item => {
  187. item.isTimeout = true; //是否服务时间已过
  188. if (item && item.startServiceTime) { //有开始服务时间说明技师已开始服务
  189. let isTimeout = new Date(item.startServiceTime).valueOf() + item.useTime *
  190. 1000 * 60
  191. if (Date.now() <= isTimeout) {
  192. item.isTimeout = false
  193. }
  194. }
  195. })
  196. this.orderList = res.result.records;
  197. //统计各种状态订单数量
  198. let titles = ['completedQuantity', 'confirmedQuantity', 'numberOfVisits']
  199. let current = titles[state]
  200. this[current] = res.result.total
  201. //打开倒计时页面
  202. if (order && order.id) {
  203. this.orderList.forEach(item => {
  204. if (item.id == order.id) {
  205. this.toCountdown(item)
  206. }
  207. })
  208. }
  209. if (this.queryParams.pageSize > this.orderList.length) {
  210. this.finished = true
  211. }
  212. } else {
  213. this.finished = true
  214. }
  215. this.loading = false
  216. })
  217. },
  218. selectTenState(state) {
  219. this.queryParams.pageSize = 10
  220. this.queryParams.state = state;
  221. this.getOrderList(state)
  222. },
  223. onSelectDate(selectDate) {
  224. if (this.selectDate == selectDate) {
  225. this.selectDate = null
  226. } else {
  227. this.selectDate = selectDate
  228. }
  229. this.queryParams.pageSize = 10
  230. this.queryParams.serviceTime = this.dayjs(selectDate).format('YYYY-MM-DD')
  231. this.getOrderList(this.queryParams.state)
  232. },
  233. toEvaluate(id, projectId, terId) {
  234. uni.navigateTo({
  235. url : `/pages/order/evaluate?id=${id}&projectId=${projectId}&terId=${terId}`
  236. })
  237. },
  238. toOrderDetail(id) {
  239. uni.navigateTo({
  240. url: '/pages/order/orderDetail?id=' + id
  241. })
  242. },
  243. getConfig() {
  244. this.vid = uni.getStorageSync("ivcode");
  245. this.$api('getConfig', {}, res => {
  246. if (res.code == 200) {
  247. res.result.forEach(n => {
  248. if (n.keyValue == 'notice') {
  249. this.notice = n.content
  250. }
  251. })
  252. this.config = res.result
  253. }
  254. })
  255. },
  256. //获取当前查询订单状态
  257. getStatus() {
  258. let titles = ['暂无已完成订单', '暂无待确认订单', '暂无待上门']
  259. return titles[this.queryParams.state]
  260. },
  261. //跳转倒计时
  262. toCountdown(order) {
  263. let {
  264. useTime,
  265. startServiceTime
  266. } = order
  267. let isTimeout = new Date(startServiceTime).valueOf() + useTime * 1000 * 60
  268. if (Date.now() >= isTimeout) {
  269. return uni.showToast({
  270. title: '服务时间已过',
  271. icon: 'none'
  272. })
  273. }
  274. uni.navigateTo({
  275. url: `/pages/mine/countdown?time=${useTime}&startTime=${startServiceTime}`
  276. })
  277. },
  278. //开始服务回调
  279. startServiceCallback(order) {
  280. this.getOrderList(this.queryParams.state, order)
  281. }
  282. }
  283. }
  284. </script>
  285. <style scoped lang="scss">
  286. body {
  287. background-color: #f3f3f3;
  288. font-family: PingFang SC;
  289. }
  290. .rr {
  291. height: 52rpx;
  292. background: #fbecdd;
  293. border-radius: 16rpx;
  294. width: calc(710rpx - 40rpx);
  295. padding: 20rpx;
  296. margin: 20rpx 0;
  297. }
  298. .xx {
  299. width: 602rpx;
  300. height: 56rpx;
  301. font-size: 20rpx;
  302. font-family: PingFang SC, PingFang SC-Regular;
  303. font-weight: 400;
  304. text-align: left;
  305. color: #323232;
  306. display: flex;
  307. align-items: center;
  308. }
  309. .status-card {
  310. width: 132rpx;
  311. height: 92rpx;
  312. background-color: #fff;
  313. border-radius: 16rpx;
  314. padding: 40rpx;
  315. text-align: center;
  316. color: #ccc;
  317. .num {
  318. color: #0d0d0d;
  319. font-size: 42rpx;
  320. }
  321. }
  322. .status-card.select {
  323. background-color: var(--van-primary-color);
  324. color: #eee;
  325. .num {
  326. color: #fff;
  327. }
  328. }
  329. .select {
  330. color: var(--van-primary-color);
  331. font-weight: 900;
  332. }
  333. .item {
  334. width: calc(100% - 40rpx);
  335. background-color: #fff;
  336. margin: 20rpx;
  337. box-sizing: border-box;
  338. border-radius: 16rpx;
  339. padding: 30rpx;
  340. .top {
  341. display: flex;
  342. justify-content: space-between;
  343. align-items: center;
  344. font-size: 30rpx;
  345. .service {}
  346. .status {
  347. color: var(--van-primary-color);
  348. font-size: 26rpx;
  349. font-weight: 600;
  350. }
  351. }
  352. .content {
  353. display: flex;
  354. margin: 10rpx 0;
  355. .left {
  356. width: 150rpx;
  357. height: 150rpx;
  358. overflow: hidden;
  359. border-radius: 10rpx;
  360. image {
  361. width: 150rpx;
  362. height: 150rpx;
  363. }
  364. .tag {
  365. color: var(--van-primary-color);
  366. font-size: 24rpx;
  367. text-align: center;
  368. width: 100%;
  369. background-color: #e7fdf7;
  370. border: 1px solid var(--van-primary-color);
  371. border-radius: 8rpx;
  372. padding: 2rpx 0;
  373. }
  374. }
  375. .right {
  376. width: calc(100% - 160rpx);
  377. color: #777;
  378. font-size: 24rpx;
  379. padding-left: 20rpx;
  380. line-height: 40rpx;
  381. .price {
  382. font-weight: 900;
  383. text-align: right;
  384. text {
  385. color: #ff780099;
  386. font-size: 30rpx;
  387. }
  388. }
  389. }
  390. }
  391. .bottom {
  392. display: flex;
  393. justify-content: flex-end;
  394. font-size: 25rpx;
  395. .b1,
  396. .b3 {
  397. border: 1px solid #777;
  398. color: #777;
  399. box-sizing: border-box;
  400. }
  401. .b2 {
  402. background: linear-gradient(178deg, #4FD3BC, #60C285);
  403. color: #fff;
  404. }
  405. .b3 {
  406. background: transparent;
  407. }
  408. view {
  409. margin: 12rpx;
  410. border-radius: 28rpx;
  411. padding: 8rpx 28rpx;
  412. margin-bottom: 0;
  413. }
  414. }
  415. }
  416. </style>