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.

454 lines
17 KiB

  1. <template>
  2. <uv-popup ref="popup" :round="10">
  3. <view class="companion-popup" v-if="type == 0">
  4. <view class="popup-header">
  5. <text class="popup-title">是否指定之前服务过的伴宠师</text>
  6. <view class="popup-close" @click="close">
  7. <uni-icons type="close" size="20" color="#999"></uni-icons>
  8. </view>
  9. </view>
  10. <view class="popup-content">
  11. <view class="option-item" @click="selectOption('yes')">
  12. <text class="option-text"></text>
  13. <view class="option-circle" :class="{'selected': selectedOption === 'yes'}">
  14. <view class="option-inner" v-if="selectedOption === 'yes'"></view>
  15. </view>
  16. </view>
  17. <view class="option-item" @click="selectOption('no')">
  18. <text class="option-text"></text>
  19. <view class="option-circle" :class="{'selected': selectedOption === 'no'}">
  20. <view class="option-inner" v-if="selectedOption === 'no'"></view>
  21. </view>
  22. </view>
  23. </view>
  24. </view>
  25. <view class="companion-popup" v-else>
  26. <view class="popup-header">
  27. <text class="popup-title">请选择您喜欢的下单方式</text>
  28. <view class="popup-close" @click="close">
  29. <uni-icons type="close" size="20" color="#999"></uni-icons>
  30. </view>
  31. </view>
  32. <view class="popup-content">
  33. <view class="option-item" @click="selectOption('系统下单')">
  34. <text class="option-text">系统下单</text>
  35. <view class="option-circle" :class="{'selected': selectedOption === 'yes'}">
  36. <view class="option-inner" v-if="selectedOption === 'yes'"></view>
  37. </view>
  38. </view>
  39. <view class="option-item" @click="selectOption('指定伴宠师')">
  40. <text class="option-text">指定伴宠师</text>
  41. <view class="option-circle" :class="{'selected': selectedOption === 'no'}">
  42. <view class="option-inner" v-if="selectedOption === 'no'"></view>
  43. </view>
  44. </view>
  45. </view>
  46. </view>
  47. </uv-popup>
  48. </template>
  49. <script>
  50. import { getOrderDetail, getTeacherDetail } from '@/api/order/order.js'
  51. import { getAddressDetails } from '@/api/system/address.js'
  52. import { getOpenIdKey } from '@/utils/auth'
  53. import { mapState } from 'vuex'
  54. import positionMixin from '@/mixins/position'
  55. export default {
  56. mixins: [positionMixin],
  57. data() {
  58. return {
  59. selectedOption: '',
  60. type : 0,
  61. teacherId: null, // 技师ID(用于再来一单时传递)
  62. orderId: null, // 订单ID(用于再来一单时传递)
  63. originalOrderData: null, // 原始订单数据
  64. buyInfo: {
  65. teacher: null // 技师信息
  66. }
  67. }
  68. },
  69. computed: {
  70. ...mapState(['teacherLevelList']),
  71. },
  72. methods: {
  73. // 打开弹窗
  74. async open(teacherId = null, orderId = null) {
  75. this.selectedOption = '';
  76. this.type = 0;
  77. this.teacherId = teacherId;
  78. this.orderId = orderId;
  79. // 如果有订单ID,加载订单数据
  80. if (this.orderId) {
  81. await this.loadOrderData();
  82. }
  83. this.$refs.popup.open('bottom');
  84. },
  85. // 加载订单数据
  86. async loadOrderData() {
  87. if (!this.orderId) return;
  88. const params = {
  89. openId: getOpenIdKey(),
  90. orderId: this.orderId
  91. };
  92. try {
  93. const res = await getOrderDetail(params);
  94. if (res) {
  95. this.originalOrderData = res;
  96. console.log('获取订单详情成功:', res);
  97. } else {
  98. console.error('获取订单详情失败');
  99. }
  100. } catch (error) {
  101. console.error('获取订单数据失败', error);
  102. }
  103. },
  104. // 关闭弹窗
  105. close() {
  106. this.$refs.popup.close();
  107. },
  108. // async submit() {
  109. // // 如果有订单数据,处理订单数据
  110. // if (this.originalOrderData) {
  111. // await this.processOrderData();
  112. // }
  113. // uni.navigateTo({
  114. // url: `/pages/newOrder/serviceNew`
  115. // });
  116. // },
  117. // 处理订单数据,设置定位和位置信息
  118. async processOrderData() {
  119. if (!this.originalOrderData) return;
  120. uni.showLoading({
  121. title: '加载中...',
  122. mask: true
  123. })
  124. const order = this.originalOrderData;
  125. // 设置再来一单费用
  126. this.$globalData.newOrderData.originalOrderData = order;
  127. this.$globalData.newOrderData.moreOrderPrice = 10;
  128. // 验证地址是否存在并设置地址信息(包含定位)
  129. if (order.addressId) {
  130. try {
  131. const addressRes = await getAddressDetails(order.addressId);
  132. if (addressRes && addressRes.id) {
  133. // 地址存在,设置地址信息(包含定位信息)
  134. this.$globalData.newOrderData.currentAddress = {
  135. id: order.addressId,
  136. name: order.receiverName,
  137. phone: order.receiverPhone,
  138. province: order.receiverProvince,
  139. city: order.receiverCity,
  140. district: order.receiverDistrict,
  141. detailAddress: order.receiverDetailAddress,
  142. latitude: parseFloat(order.latitude) || 0,
  143. longitude: parseFloat(order.longitude) || 0,
  144. }
  145. console.log('设置地址信息成功,包含定位:', {
  146. latitude: order.latitude,
  147. longitude: order.longitude
  148. });
  149. } else {
  150. // 地址不存在,但仍然尝试从订单数据中获取定位信息
  151. console.log('地址不存在,addressId:', order.addressId);
  152. this.$globalData.newOrderData.currentAddress = {};
  153. }
  154. } catch (error) {
  155. // 验证失败时也不设置地址信息,但仍然尝试设置定位
  156. this.$globalData.newOrderData.currentAddress = {};
  157. }
  158. } else {
  159. // 没有地址ID,但仍然尝试从订单数据中获取定位信息
  160. this.$globalData.newOrderData.currentAddress = {};
  161. }
  162. // 处理技师信息
  163. // if (order.teacherId) {
  164. // try {
  165. // const teacherRes = await getTeacherDetail({
  166. // userId: order.teacherId
  167. // });
  168. // if (teacherRes) {
  169. // let companionInfo = teacherRes;
  170. // // 计算距离(需要当前位置信息)
  171. // if (teacherRes.appletAddresseList && this.$globalData.newOrderData.latitude && this.$globalData.newOrderData.longitude) {
  172. // companionInfo.distanceText = this.calculateDistanceAddress(teacherRes.appletAddresseList);
  173. // }
  174. // this.buyInfo.teacher = companionInfo;
  175. // // 将技师信息也设置到全局数据中
  176. // this.$globalData.newOrderData.selectedTeacher = companionInfo;
  177. // console.log('设置技师信息成功:', companionInfo);
  178. // }
  179. // } catch (error) {
  180. // console.error('获取技师详情失败:', error);
  181. // }
  182. // }
  183. // 处理伴宠师等级
  184. if (order.companionLevel) {
  185. this.$globalData.newOrderData.companionLevel =
  186. this.teacherLevelList.find(item => item.paramValueNum == order.companionLevel);
  187. }
  188. // 处理提前熟悉相关数据
  189. if (order.needPreFamiliarize) {
  190. this.$globalData.newOrderData.needPreFamiliarize = ['是否提前熟悉'];
  191. }
  192. // 组装宠物数据
  193. if (order.petVOList && order.petVOList.length > 0) {
  194. this.$globalData.newOrderData.currentPets = order.petVOList.map(pet => {
  195. // 获取该宠物的服务日期
  196. const petServices = order.orderServiceList.filter(service => service.petId === pet.id);
  197. const selectedDate = petServices.map(service => ({
  198. date: service.serviceDate,
  199. info: "预定"
  200. }));
  201. return {
  202. ...pet,
  203. checked: ['checked'], // 默认选中
  204. selectedDate,
  205. };
  206. });
  207. }
  208. uni.hideLoading();
  209. },
  210. // 选择选项
  211. async selectOption(option) {
  212. this.selectedOption = option;
  213. if(this.type == 1){
  214. if (option === '系统下单') {
  215. // 如果有订单数据,处理订单数据
  216. if (this.originalOrderData) {
  217. await this.processOrderData();
  218. }
  219. this.close();
  220. setTimeout(() => {
  221. uni.navigateTo({
  222. url: '/pages/newOrder/serviceNew'
  223. });
  224. }, 300);
  225. } else if (option === '指定伴宠师') {
  226. // 如果有订单数据,处理订单数据
  227. if (this.originalOrderData) {
  228. await this.processOrderData();
  229. }
  230. let locationInfo = this.$globalData.newOrderData.currentAddress;
  231. if(!locationInfo ||
  232. !locationInfo.latitude ||
  233. !locationInfo.longitude
  234. ){
  235. this.selectLocation();
  236. return
  237. }
  238. let address = locationInfo.province + locationInfo.city + locationInfo.district + locationInfo.detailAddress;
  239. // 构建位置信息对象
  240. const allInfo = {
  241. isCheckLocation: true,
  242. locationName: address,
  243. locationLongitude: locationInfo.longitude,
  244. locationLatitude: locationInfo.latitude,
  245. locationAddress: address,
  246. selectedDate: [],
  247. isCheckTime: false,
  248. selectedDateShowText: '',
  249. };
  250. this.$store.commit('setPosition', {
  251. address: address,
  252. longitude: locationInfo.longitude,
  253. latitude: locationInfo.latitude,
  254. date : [],
  255. })
  256. this.close();
  257. setTimeout(() => {
  258. uni.navigateTo({
  259. url: '/pages_order/companionPetList/companionPetList?info=' + encodeURIComponent(JSON.stringify(allInfo))
  260. });
  261. }, 300);
  262. }
  263. return
  264. }
  265. // 如果选择"是",跳转到伴宠师选择页面
  266. if (option === 'yes') {
  267. this.close();
  268. setTimeout(async () => {
  269. // 如果有订单数据,先处理订单数据并设置定位信息
  270. if (this.originalOrderData) {
  271. await this.processOrderData();
  272. }
  273. let url = '/pages_order/order/companionSelect';
  274. let params = [];
  275. // 如果有技师ID,添加到URL参数中
  276. if (this.teacherId) {
  277. params.push(`teacherId=${this.teacherId}`);
  278. }
  279. // 如果有订单ID,添加到URL参数中
  280. if (this.orderId) {
  281. params.push(`orderId=${this.orderId}`);
  282. }
  283. if (params.length > 0) {
  284. url += `?${params.join('&')}`;
  285. }
  286. uni.navigateTo({
  287. url: url
  288. });
  289. }, 300);
  290. } else if (option === 'no') {
  291. this.type = 1;
  292. this.selectedOption = '';
  293. }
  294. },
  295. // 选择定位
  296. selectLocation() {
  297. wx.chooseLocation({
  298. type: 'gcj02',
  299. success: (res) => {
  300. console.log('选择的位置:', res);
  301. // 构建位置信息对象
  302. const allInfo = {
  303. isCheckLocation: true,
  304. locationName: res.address,
  305. locationLongitude: res.longitude,
  306. locationLatitude: res.latitude,
  307. locationAddress: res.address,
  308. selectedDate: [],
  309. isCheckTime: false,
  310. selectedDateShowText: '',
  311. };
  312. this.$store.commit('setPosition', {
  313. address: res.address,
  314. longitude: res.longitude,
  315. latitude: res.latitude,
  316. date : [],
  317. })
  318. // 跳转到伴宠师列表页面,传递位置信息
  319. uni.navigateTo({
  320. url: `/pages_order/companionPetList/companionPetList?info=` + encodeURIComponent(JSON.stringify(allInfo))
  321. })
  322. },
  323. fail: (err) => {
  324. console.error('选择位置失败:', err);
  325. uni.showToast({
  326. title: '选择位置失败,请重试',
  327. icon: 'none',
  328. duration: 2000
  329. })
  330. }
  331. });
  332. },
  333. }
  334. }
  335. </script>
  336. <style lang="scss" scoped>
  337. .companion-popup {
  338. position: relative;
  339. background-color: #FFFFFF;
  340. border-radius: 20rpx;
  341. .popup-header {
  342. display: flex;
  343. align-items: center;
  344. justify-content: center;
  345. padding: 30rpx 20rpx;
  346. position: relative;
  347. .popup-title {
  348. font-size: 32rpx;
  349. font-weight: bold;
  350. color: #333;
  351. text-align: center;
  352. }
  353. .popup-close {
  354. position: absolute;
  355. right: 20rpx;
  356. top: 30rpx;
  357. }
  358. }
  359. .popup-content {
  360. padding: 20rpx 30rpx 50rpx;
  361. .option-item {
  362. display: flex;
  363. align-items: center;
  364. justify-content: space-between;
  365. height: 100rpx;
  366. border-radius: 10rpx;
  367. background-color: #F8F8F8;
  368. margin-bottom: 20rpx;
  369. padding: 0 30rpx;
  370. // &:first-child {
  371. // background-color: #FFF9E6;
  372. // .option-text {
  373. // color: #FFAA48;
  374. // }
  375. // }
  376. &:last-child {
  377. margin-bottom: 0;
  378. }
  379. .option-text {
  380. font-size: 28rpx;
  381. color: #333;
  382. }
  383. .option-circle {
  384. width: 36rpx;
  385. height: 36rpx;
  386. border-radius: 50%;
  387. border: 2rpx solid #DDDDDD;
  388. display: flex;
  389. align-items: center;
  390. justify-content: center;
  391. &.selected {
  392. border-color: #FFAA48;
  393. }
  394. .option-inner {
  395. width: 24rpx;
  396. height: 24rpx;
  397. border-radius: 50%;
  398. background-color: #FFAA48;
  399. }
  400. }
  401. }
  402. }
  403. }
  404. </style>