logic.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. import { getMyProfile, getPendingOrders, acceptOrder, getOrderCount } from '@/api/fulfiller'
  2. import { getServiceList } from '@/api/service'
  3. import { isLoggedIn } from '@/utils/auth'
  4. export default {
  5. data() {
  6. return {
  7. taskList: [],
  8. currentFilter: 'default', // default, distance, time
  9. filterCondition: '筛选条件',
  10. sortDistance: 'asc', // asc, desc
  11. sortTime: 'asc',
  12. scrollTop: 0, // Track scroll position
  13. isFilterShow: false,
  14. tempFilter: {
  15. service: null,
  16. distance: '全部',
  17. amount: '全部'
  18. },
  19. activeFilter: {
  20. service: null,
  21. distance: '全部',
  22. amount: '全部'
  23. },
  24. workStatus: 'working', // working | resting
  25. showConfirmModal: false,
  26. showPetModal: false,
  27. currentPetInfo: {},
  28. showRejectModal: false,
  29. rejectReason: '',
  30. currentOrder: null,
  31. showAcceptConfirmModal: false,
  32. showNavModal: false,
  33. navTargetItem: null,
  34. navTargetPointType: '',
  35. profile: null,
  36. profileLoading: false,
  37. serviceList: [],
  38. orderStats: {
  39. total: 0,
  40. reject: 0,
  41. award: 0,
  42. punishment: 0
  43. }
  44. }
  45. },
  46. onPageScroll(e) {
  47. this.scrollTop = e.scrollTop;
  48. },
  49. onLoad() {
  50. // Initial load
  51. this.checkWorkStatus();
  52. this.loadServiceList();
  53. this.loadTaskList();
  54. },
  55. onShow() {
  56. this.checkWorkStatus();
  57. if (isLoggedIn()) {
  58. this.loadProfile()
  59. this.loadOrderStats()
  60. }
  61. },
  62. methods: {
  63. async loadProfile() {
  64. if (this.profileLoading) return
  65. this.profileLoading = true
  66. try {
  67. const res = await getMyProfile()
  68. this.profile = res.data || null
  69. } catch (err) {
  70. console.error('获取个人信息失败:', err)
  71. } finally {
  72. this.profileLoading = false
  73. }
  74. },
  75. async loadServiceList() {
  76. try {
  77. const res = await getServiceList()
  78. this.serviceList = res.data || []
  79. } catch (err) {
  80. console.error('获取服务类型失败:', err)
  81. }
  82. },
  83. async loadOrderStats() {
  84. try {
  85. const res = await getOrderCount()
  86. this.orderStats = res.data || { total: 0, reject: 0, award: 0, punishment: 0 }
  87. } catch (err) {
  88. console.error('获取订单统计失败:', err)
  89. }
  90. },
  91. checkWorkStatus() {
  92. const status = uni.getStorageSync('workStatus');
  93. if (status) {
  94. this.workStatus = status;
  95. } else {
  96. // Default to working if not set
  97. this.workStatus = 'working';
  98. uni.setStorageSync('workStatus', 'working');
  99. }
  100. },
  101. toggleFilter() {
  102. if (this.workStatus === 'resting') return; // Disable filter when resting? Or keep it? User didn't specify, but usually disabled. Let's keep it enabled for now as they might look at filters before working.
  103. this.isFilterShow = !this.isFilterShow;
  104. },
  105. goToWorkStatus() {
  106. uni.navigateTo({
  107. url: '/pages/home/work-status'
  108. });
  109. },
  110. startWork() {
  111. this.showConfirmModal = true;
  112. },
  113. confirmStartWork() {
  114. this.workStatus = 'working';
  115. uni.setStorageSync('workStatus', 'working');
  116. this.loadTaskList();
  117. this.showConfirmModal = false;
  118. uni.showToast({ title: '已开始接单', icon: 'success' });
  119. },
  120. closeConfirmModal() {
  121. this.showConfirmModal = false;
  122. },
  123. showPetProfile(item) {
  124. this.currentPetInfo = item;
  125. this.showPetModal = true;
  126. },
  127. closePetProfile() {
  128. this.showPetModal = false;
  129. },
  130. openRejectModal(item) {
  131. this.currentOrder = item;
  132. this.rejectReason = '';
  133. this.showRejectModal = true;
  134. },
  135. closeRejectModal() {
  136. this.showRejectModal = false;
  137. this.currentOrder = null;
  138. },
  139. confirmReject() {
  140. if (!this.rejectReason.trim()) {
  141. uni.showToast({ title: '请输入拒绝理由', icon: 'none' });
  142. return;
  143. }
  144. // Add actual API call here
  145. uni.showToast({ title: '已拒绝接单', icon: 'success' });
  146. this.showRejectModal = false;
  147. },
  148. openAcceptModal(item) {
  149. this.currentOrder = item;
  150. this.showAcceptConfirmModal = true;
  151. },
  152. closeAcceptModal() {
  153. this.showAcceptConfirmModal = false;
  154. this.currentOrder = null;
  155. },
  156. async confirmAccept() {
  157. if (!this.currentOrder?.id) return
  158. try {
  159. await acceptOrder(this.currentOrder.id)
  160. uni.showToast({ title: '接单成功', icon: 'success' })
  161. this.showAcceptConfirmModal = false
  162. this.currentOrder = null
  163. this.loadTaskList()
  164. this.loadProfile()
  165. } catch (err) {
  166. console.error('接单失败:', err)
  167. uni.showToast({ title: '接单失败', icon: 'none' })
  168. }
  169. },
  170. openNavigation(item, pointType) {
  171. this.navTargetItem = item;
  172. this.navTargetPointType = pointType;
  173. this.showNavModal = true;
  174. },
  175. closeNavModal() {
  176. this.showNavModal = false;
  177. },
  178. chooseMap(mapType) {
  179. let item = this.navTargetItem;
  180. let pointType = this.navTargetPointType;
  181. let name = pointType === 'start' ? item.startLocation : item.endLocation;
  182. let address = pointType === 'start' ? item.startAddress : item.endAddress;
  183. this.showNavModal = false;
  184. uni.openLocation({
  185. latitude: 30.52, // Mock lat
  186. longitude: 114.31, // Mock lng
  187. name: name || '目的地',
  188. address: address || '默认地址',
  189. success: function () {
  190. console.log('打开导航成功: ' + mapType);
  191. }
  192. });
  193. },
  194. selectService(type) {
  195. this.tempFilter.service = type;
  196. },
  197. selectDistance(type) {
  198. this.tempFilter.distance = type;
  199. },
  200. selectAmount(type) {
  201. this.tempFilter.amount = type;
  202. },
  203. resetFilter() {
  204. this.tempFilter = {
  205. service: null,
  206. distance: '全部',
  207. amount: '全部'
  208. };
  209. },
  210. confirmFilter() {
  211. this.activeFilter = { ...this.tempFilter };
  212. this.isFilterShow = false;
  213. uni.showToast({ title: '筛选已生效', icon: 'none' });
  214. // Add filtering logic here if needed
  215. },
  216. closeFilter() {
  217. this.isFilterShow = false;
  218. },
  219. goToDetail(item) {
  220. console.log('Go to detail', item);
  221. },
  222. async loadTaskList() {
  223. try {
  224. const params = {
  225. service: this.activeFilter.service,
  226. minPrice: this.getMinPrice(),
  227. maxPrice: this.getMaxPrice(),
  228. pageNum: 1,
  229. pageSize: 20
  230. }
  231. const res = await getPendingOrders(params)
  232. this.taskList = (res.rows || []).map(item => this.transformOrder(item))
  233. } catch (err) {
  234. console.error('获取订单列表失败:', err)
  235. uni.showToast({ title: '加载失败', icon: 'none' })
  236. this.taskList = []
  237. }
  238. },
  239. getMinPrice() {
  240. const amount = this.activeFilter.amount
  241. if (amount === '100以下') return 0
  242. if (amount === '100-200') return 10000
  243. if (amount === '200-500') return 20000
  244. if (amount === '500以上') return 50000
  245. return undefined
  246. },
  247. getMaxPrice() {
  248. const amount = this.activeFilter.amount
  249. if (amount === '100以下') return 10000
  250. if (amount === '100-200') return 20000
  251. if (amount === '200-500') return 50000
  252. return undefined
  253. },
  254. transformOrder(item) {
  255. const service = this.serviceList.find(s => s.id === item.service)
  256. const serviceText = service?.name || '未知'
  257. const serviceIcon = service?.icon || ''
  258. const mode = service?.mode || 0
  259. const isRoundTrip = mode === 1
  260. return {
  261. id: item.id,
  262. type: isRoundTrip ? 1 : item.service,
  263. typeText: serviceText,
  264. typeIcon: serviceIcon,
  265. price: (item.price / 100).toFixed(2),
  266. timeLabel: isRoundTrip ? '取货时间' : '服务时间',
  267. time: item.serviceTime,
  268. petAvatar: '/static/dog.png',
  269. petName: item.petName,
  270. petBreed: item.breed,
  271. petGender: 'M',
  272. petAge: '',
  273. petWeight: '',
  274. petPersonality: '',
  275. petHobby: '',
  276. petRemark: '',
  277. petTags: [],
  278. petLogs: [],
  279. startLocation: isRoundTrip ? item.fromAddress : '',
  280. startAddress: isRoundTrip ? item.fromAddress : '',
  281. startDistance: '0km',
  282. endLocation: item.customerName + ' ' + item.customerPhone,
  283. endAddress: item.toAddress,
  284. endDistance: '0km',
  285. serviceContent: '',
  286. remark: item.remark || ''
  287. }
  288. },
  289. setFilter(type) {
  290. this.currentFilter = type;
  291. if (type === 'distance') {
  292. this.sortDistance = this.sortDistance === 'asc' ? 'desc' : 'asc';
  293. uni.showToast({ title: `按距离${this.sortDistance === 'asc' ? '升序' : '降序'}`, icon: 'none' });
  294. } else if (type === 'time') {
  295. this.sortTime = this.sortTime === 'asc' ? 'desc' : 'asc';
  296. uni.showToast({ title: `按时间${this.sortTime === 'asc' ? '升序' : '降序'}`, icon: 'none' });
  297. }
  298. },
  299. showFilterDropdown() {
  300. this.toggleFilter();
  301. }
  302. }
  303. }