猫妈狗爸伴宠师小程序前端代码
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.

357 lines
8.9 KiB

3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
  1. <template>
  2. <view>
  3. <view class="header-buts flex flex-center">
  4. <view class="flex buts-box">
  5. <view class="buts" :class="{'buts-active':activeIndex===1}" @click="handleClickTab(1)">总订单</view>
  6. <view class="buts" :class="{'buts-active':activeIndex===2}" @click="handleClickTab(2)">日订单</view>
  7. </view>
  8. </view>
  9. <up-sticky bgColor="#fff" v-if="activeIndex == 1">
  10. <view class="container-tabs">
  11. <up-tabs @click="handleClassifyClickTab" :list="tabList1" lineWidth="68rpx" :activeStyle="{
  12. color: '#FFFFFF',
  13. fontWeight: 'bold',
  14. transform: 'scale(1.05)'
  15. }" :inactiveStyle="{
  16. color: '#FFFFFF',
  17. transform: 'scale(1)'
  18. }" :itemStyle="{height:'88rpx',width : '33%'}"
  19. lineColor="#FFFFFF"></up-tabs>
  20. </view>
  21. </up-sticky>
  22. <up-sticky bgColor="#fff" v-else>
  23. <view class="container-tabs">
  24. <up-tabs :list="tabList2" lineWidth="68rpx" :activeStyle="{
  25. color: '#FFFFFF',
  26. fontWeight: 'bold',
  27. transform: 'scale(1.05)'
  28. }" :inactiveStyle="{
  29. color: '#FFFFFF',
  30. transform: 'scale(1)'
  31. }" :itemStyle="{height:'88rpx',padding:'0 52rpx', width : '400rpx'}"
  32. @click="handleClassifyClickTab"
  33. lineColor="#FFFFFF"></up-tabs>
  34. </view>
  35. </up-sticky>
  36. <view class="container">
  37. <!-- 未登录提示 -->
  38. <view v-if="!isLogin" class="login-tip-container">
  39. <view class="login-tip-content">
  40. <up-image class="login-image" width="120rpx" height="120rpx"
  41. src="https://image.hhlm1688.com/img/work/log/headImage.png" shape="circle"></up-image>
  42. <view class="login-tip">请先登录查看订单数据</view>
  43. <up-button @click="goToLogin" type="primary" text="立即登录"
  44. shape="circle" color="#FFBF60" class="login-btn"></up-button>
  45. </view>
  46. </view>
  47. <!-- 已登录但加载中状态 -->
  48. <view v-else-if="loading" class="loading-container">
  49. <up-loading-icon size="36" mode="circle" color="#FFAA48"></up-loading-icon>
  50. <text class="loading-text">加载中...</text>
  51. </view>
  52. <!-- 总订单内容 -->
  53. <systemOrder :list="list" :current="current" v-else-if="activeIndex == 1" />
  54. <!-- 日订单内容 -->
  55. <view v-else>
  56. <view v-if="dateOrderList && dateOrderList.length > 0">
  57. <timelineService
  58. v-for="(item,index) in dateOrderList"
  59. :key="index"
  60. :date="item.date"
  61. :status="current == 0"
  62. :list="item.list"
  63. :current="current"
  64. />
  65. </view>
  66. <view v-else class="empty-state">
  67. <image src="/static/images/ydd/empty.png" mode="aspectFit" class="empty-image"></image>
  68. <text class="empty-text">暂无订单数据</text>
  69. </view>
  70. </view>
  71. </view>
  72. </view>
  73. </template>
  74. <script setup>
  75. import {
  76. computed,
  77. reactive,
  78. ref
  79. } from "vue";
  80. import systemOrder from "./components/systemOrder.vue";
  81. import orderListByData from "./components/orderListByData.vue";
  82. import timelineService from "./components/timelineService.vue";
  83. import {
  84. onShow,
  85. onLoad,
  86. } from "@dcloudio/uni-app"
  87. import {
  88. getLoginStatus
  89. } from "@/utils/useMixin.js"
  90. import {
  91. getIsLogin,
  92. getToken
  93. } from "@/utils/auth";
  94. import {
  95. myList
  96. } from "@/api/receivingHall/index.js"
  97. import {
  98. getOrderDateList,
  99. } from "@/api/order/order.js"
  100. import {
  101. appletOrderDateFrequencyList,
  102. } from "@/api/order/frequency.js"
  103. import {
  104. useStore
  105. } from "vuex"
  106. import { getOrderServiceText, getProductNameText } from '@/utils/serviceTime.js'
  107. onLoad(() => {
  108. requestId.value = 0;
  109. activeIndex.value = 1;
  110. })
  111. onShow(() => {
  112. checkLoginStatus();
  113. if (isLogin.value) {
  114. getList();
  115. }
  116. })
  117. const current = ref(0)
  118. const activeIndex = ref(1)
  119. const list = ref([])
  120. const dateOrderList = ref([])
  121. const loading = ref(false) // 添加loading状态
  122. const requestId = ref(0) // 添加请求序列号
  123. const isLogin = ref(false) // 添加登录状态
  124. const store = useStore();
  125. const userInfo = computed(() => {
  126. return store.getters.userInfo;
  127. })
  128. const tabList1 = reactive([{
  129. name: '待服务',
  130. badge: {
  131. value: 0,
  132. }
  133. },
  134. {
  135. name: '进行中',
  136. badge: {
  137. value: 0,
  138. }
  139. },
  140. {
  141. name: '已完成',
  142. badge: {
  143. value: 0,
  144. }
  145. },
  146. ])
  147. const tabList2 = reactive([{
  148. name: '待上门',
  149. badge: {
  150. value: 0,
  151. }
  152. },
  153. {
  154. name: '已完成',
  155. badge: {
  156. value: 0,
  157. }
  158. },
  159. ])
  160. // 检查登录状态
  161. const checkLoginStatus = () => {
  162. if (getIsLogin() && getToken()) {
  163. isLogin.value = true
  164. } else {
  165. isLogin.value = false
  166. }
  167. }
  168. // 跳转登录页面
  169. const goToLogin = () => {
  170. uni.navigateTo({
  171. url: "/pages/login/index"
  172. })
  173. }
  174. // 检查登录状态,未登录则跳转登录
  175. const checkLoginAndRedirect = () => {
  176. if (!isLogin.value) {
  177. goToLogin()
  178. return false
  179. }
  180. return true
  181. }
  182. function getList() {
  183. if (!isLogin.value) return;
  184. loading.value = true; // 开始加载
  185. requestId.value++; // 递增请求序列号
  186. const currentRequestId = requestId.value; // 保存当前请求的ID
  187. let index = current.value;
  188. if (activeIndex.value == 1) {
  189. myList({
  190. orderStatus: index,
  191. userId: userInfo.value.userId
  192. })
  193. .then(res => {
  194. // 检查请求是否是最新的
  195. if (currentRequestId !== requestId.value) {
  196. return; // 如果不是最新请求,忽略响应
  197. }
  198. if (res.code == 200) {
  199. list.value = res.data.rows
  200. tabList1[index].badge.value = res.data.total
  201. list.value.forEach(item => {
  202. item.h5OrderVO.petVOList.forEach(pet => {
  203. pet.orderServiceText = getOrderServiceText(pet.id, item.h5OrderVO.orderServiceList)
  204. pet.productNameText = getProductNameText(pet.id, item.h5OrderVO.orderItemList, item.h5OrderVO.orderServiceList)
  205. })
  206. })
  207. }
  208. })
  209. .finally(() => {
  210. // 只有最新请求才能关闭loading
  211. if(activeIndex.value == 1 && currentRequestId === requestId.value){
  212. loading.value = false; // 结束加载
  213. }
  214. })
  215. }else{
  216. dateOrderList.value = []
  217. appletOrderDateFrequencyList({
  218. status: index == 0 ? '0,1' : '2',
  219. masterId: userInfo.value.userId
  220. })
  221. .then(res => {
  222. // 检查请求是否是最新的
  223. if (currentRequestId !== requestId.value) {
  224. return; // 如果不是最新请求,忽略响应
  225. }
  226. if (res.code == 200) {
  227. dateOrderList.value = res.data
  228. // 更新标签数量显示
  229. let totalOrders = 0;
  230. dateOrderList.value.forEach(item => {
  231. totalOrders += item.list.length || 0;
  232. item.list.forEach(n => {
  233. n.pets.forEach(pet => {
  234. pet.orderItemList.reverse()
  235. })
  236. })
  237. });
  238. tabList2[index].badge.value = totalOrders;
  239. }
  240. })
  241. .finally(() => {
  242. // 只有最新请求才能关闭loading
  243. if(activeIndex.value == 2 && currentRequestId === requestId.value){
  244. loading.value = false; // 结束加载
  245. }
  246. })
  247. }
  248. }
  249. function handleClickTab(index) {
  250. current.value = 0;
  251. activeIndex.value = index;
  252. if (checkLoginAndRedirect()) {
  253. getList();
  254. }
  255. }
  256. const handleClassifyClickTab = (item) => {
  257. current.value = item.index;
  258. if (checkLoginAndRedirect()) {
  259. getList();
  260. }
  261. }
  262. </script>
  263. <style scoped lang="scss">
  264. @import "index.scss";
  265. .loading-container {
  266. display: flex;
  267. flex-direction: column;
  268. align-items: center;
  269. justify-content: center;
  270. padding: 40rpx;
  271. .loading-text {
  272. margin-top: 20rpx;
  273. color: #999;
  274. font-size: 28rpx;
  275. }
  276. }
  277. .empty-state {
  278. display: flex;
  279. flex-direction: column;
  280. align-items: center;
  281. justify-content: center;
  282. padding: 80rpx 40rpx;
  283. .empty-image {
  284. width: 200rpx;
  285. height: 200rpx;
  286. margin-bottom: 20rpx;
  287. }
  288. .empty-text {
  289. color: #999;
  290. font-size: 28rpx;
  291. }
  292. }
  293. .login-tip-container {
  294. display: flex;
  295. align-items: center;
  296. justify-content: center;
  297. padding: 80rpx 40rpx;
  298. .login-tip-content {
  299. display: flex;
  300. flex-direction: column;
  301. align-items: center;
  302. padding: 60rpx;
  303. border-radius: 20rpx;
  304. .login-image {
  305. margin-bottom: 30rpx;
  306. }
  307. .login-tip {
  308. font-size: 28rpx;
  309. color: #666;
  310. margin-bottom: 30rpx;
  311. }
  312. .login-btn {
  313. width: 240rpx;
  314. }
  315. }
  316. }
  317. </style>