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.

1332 lines
42 KiB

6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
  1. <template>
  2. <view class="service-new container">
  3. <view class="service-new-address">
  4. <uni-card padding=0 :is-shadow="false">
  5. <view class="service-new-title" slot="title">
  6. <view class="service-new-title-left">
  7. <view class="service-new-flag"></view>
  8. <view>服务地址</view>
  9. </view>
  10. </view>
  11. <view class="split-line"></view>
  12. <view class="service-new-address-content">
  13. <view class="service-new-address-selected">
  14. <view class="personal-address-info">
  15. <view class="personal-address-text">
  16. {{currentAddress.province}} {{currentAddress.city}} {{currentAddress.detailAddress}}
  17. </view>
  18. <view class="personal-address-people">
  19. <view>
  20. {{currentAddress.name}}
  21. </view>
  22. <view style="border: solid #7D8196 1px; margin: 0 10px; height: 12px;"> </view>
  23. <view>
  24. {{currentAddress.phone}}
  25. </view>
  26. </view>
  27. </view>
  28. </view>
  29. </view>
  30. </uni-card>
  31. </view>
  32. <view class="service-new-pet">
  33. <uni-card padding=0 :is-shadow="false">
  34. <view class="service-new-title" slot="title">
  35. <view class="service-new-title-left">
  36. <view class="service-new-flag">
  37. </view>
  38. <view class="service-new-title-text">
  39. 服务宠物
  40. </view>
  41. </view>
  42. </view>
  43. <view class="split-line"></view>
  44. <view class="service-new-pet-content">
  45. <view class="personal-pet-list">
  46. <view v-for="(item,index) in showPets" :key="index">
  47. <view class="personal-pet-list-item">
  48. <view class="personal-pet-info">
  49. <!-- 左侧头像 -->
  50. <view class="pet-avatar">
  51. <u-avatar :src="item.photo?item.photo:defaultPhoto" size="60"
  52. shape="circle"></u-avatar>
  53. </view>
  54. <!-- 中间内容 -->
  55. <view class="pet-info" style="flex: 1; margin: 0 20rpx; max-width: 50%;">
  56. <view class="pet-name-gender" style="display: flex; align-items: center;">
  57. <view>{{item.name}}</view>
  58. <view class="pet-gender"
  59. style="margin-left: 10rpx; display: flex;align-items: center;">
  60. <img :src="item.gender=='男生'?'../../static/images/details/boy.svg':'../../static/images/details/girl.svg'"
  61. alt="sex" style="width: 16px;height: 16px;" />
  62. </view>
  63. </view>
  64. <view class="pet-dates ellipsis">
  65. {{ item.pets.map(e=>e.serviceDate).join(';') }}
  66. </view>
  67. </view>
  68. <!-- 右侧天数统计 -->
  69. <view class="date-total" style="margin-left: auto;width: 140rpx;text-align: end;">
  70. {{item.pets.length}}
  71. </view>
  72. </view>
  73. </view>
  74. </view>
  75. </view>
  76. </view>
  77. </uni-card>
  78. </view>
  79. <view class="service-new-pet">
  80. <uni-card padding=0 :is-shadow="false">
  81. <view class="service-new-title" slot="title">
  82. <view class="service-new-title-left">
  83. <view class="service-new-flag">
  84. </view>
  85. <view class="service-new-title-text">
  86. 服务信息及费用
  87. </view>
  88. </view>
  89. </view>
  90. <view class="split-line"></view>
  91. <view class="service-new-pet-content">
  92. <view class="personal-pet-list">
  93. <view v-for="item in dailyShowData" :key="item.date" class="service-new-address">
  94. <view class="service-summary">
  95. <view style="display: flex; align-items: center;">
  96. <view style="padding-right: 10rpx;color: #7D8196;">{{ getDateText(item.date) }}</view>
  97. <!-- <view style="padding-right: 10rpx;color: #7D8196;">{{ item.date }}</view> -->
  98. <view
  99. style="margin: 0 10rpx; width: 2px; height: 20rpx; background-color: #7D8196;">
  100. </view>
  101. <view style="color: #333333; margin-left: 10rpx;">{{baseProduct}}
  102. {{item.customServicesTotalCnt? ' + 定制服务' + item.customServicesTotalCnt + '项' : '' }}
  103. </view>
  104. </view>
  105. <view style="display: flex; align-items: center;">
  106. <view style="color: #333333;margin-right: 10rpx;">¥{{ item.totalCost }}</view>
  107. <view>
  108. <u-icon @click="toggleExpand( item.date )"
  109. :name="expandedIndexs.includes( item.date ) ? 'arrow-up' : 'arrow-down'"
  110. color="#FFBF60" size="14"></u-icon>
  111. </view>
  112. </view>
  113. </view>
  114. <view v-if="!expandedIndexs.includes(item.date)" class="split-line"></view>
  115. <view v-show="expandedIndexs.includes(item.date)" class="service-details">
  116. <!-- 基础服务 上门次数 额外费用 -->
  117. <view>基础服务</view>
  118. <view v-for="(priceItem, priceIndex) in item.priceDetails" :key="priceIndex"
  119. class="price-details-item">
  120. <view style="display: flex;" v-for="(item2, index) in priceItem.item" :key="index">
  121. <view v-if="item2.quantity" class="service-item">
  122. <view v-if="item2.itemName != item.name"
  123. class="price-details-item-price-total-item">- {{ item2.itemName }}
  124. </view>
  125. <view class="price-details-item-price-total-item">¥{{ parseFloat(item2.price) }} ×
  126. {{ item2.quantity }} {{ item2.unit }}</view>
  127. </view>
  128. </view>
  129. </view>
  130. <view v-if="item.customServicesTotalCnt>0" style="margin-top: 20rpx;">定制服务</view>
  131. <view v-for="(pet, petIndex) in item.pets" :key="petIndex">
  132. <view
  133. v-if="pet.customServices &&pet.customServices.filter(e=>e.quantity>0).length>0"
  134. style="display: flex; align-items: center; justify-content: flex-start; margin-top: 20rpx;">
  135. <view class="pet-avatar">
  136. <u-avatar :src="pet.photo?pet.photo:defaultPhoto" size="34"
  137. shape="circle"></u-avatar>
  138. </view>
  139. <view style="margin-left: 20rpx;">{{ pet.name}}</view>
  140. </view>
  141. <!-- 定制服务 -->
  142. <view v-for="(customItem, customIndex) in pet.customServices" :key="customIndex">
  143. <view v-if="customItem.quantity" class="service-item">
  144. <view>- {{ customItem.name }}</view>
  145. <view>¥{{ parseFloat(customItem.price).toFixed(2) }} × {{ customItem.quantity }} </view>
  146. </view>
  147. </view>
  148. </view>
  149. </view>
  150. </view>
  151. <view class="service-new-address">
  152. <view v-if="needPreFamiliarize.length>0" class="total-cost">
  153. <view>提前熟悉 </view>
  154. <view>¥{{ price_config.preFamiliarize.price }}</view>
  155. </view>
  156. <view v-if="companionLevelPrice()>0" class="total-cost">
  157. <view> {{ buyInfo.teacher ? buyInfo.teacher.userName : companionLevelTitle }} </view>
  158. <view>¥{{ companionLevelPrice() }}</view>
  159. </view>
  160. <view class="total-cost">
  161. <view>费用总计 </view>
  162. <view>¥{{ parseFloat(originalTotalPrice).toFixed(2) }}</view>
  163. </view>
  164. <view class="total-cost" @click="selectCoupon">
  165. <view>平台优惠</view>
  166. <view style="color: #FF530A;">
  167. {{ selectedCoupon ? selectedCoupon.stockName : '未使用优惠券' }}
  168. <uni-icons type="right" size="28rpx" color="#AAA"></uni-icons>
  169. </view>
  170. </view>
  171. <view class="total-cost" v-if="discountMemberText">
  172. <view>会员折扣</view>
  173. <view style="display: flex; align-items: center;">
  174. <view style="color: #999999;">{{ currentMember.itemType }}{{ discountMemberText }}折优惠</view>
  175. <view style="border: solid #7D8196 1px; margin: 0 10rpx; height: 12px;"> </view>
  176. <view style="color: #FF530A;">-¥{{ parseFloat(memberDiscount).toFixed(2) }}</view>
  177. </view>
  178. </view>
  179. <view class="total-cost">
  180. <view>应付费用</view>
  181. <view style="font-weight: 500;font-size: 32rpx;">¥{{ parseFloat(finalPrice).toFixed(2) }}</view>
  182. </view>
  183. </view>
  184. </view>
  185. </view>
  186. </uni-card>
  187. </view>
  188. <view class="service-new-pet">
  189. <uni-card padding=0 :is-shadow="false">
  190. <view class="service-new-title" slot="title">
  191. <view class="service-new-title-left">
  192. <view class="service-new-flag">
  193. </view>
  194. <view class="service-new-title-text">
  195. 服务细则
  196. </view>
  197. </view>
  198. </view>
  199. <view class="split-line"></view>
  200. <view class="service-new-details-content">
  201. <view style="margin: 30rpx 0;">
  202. <u-checkbox-group @change="changePreFamiliarize" :value="needPreFamiliarize"
  203. iconPlacement="right" placement="column">
  204. <u-checkbox activeColor="#FFBF60" label="是否提前熟悉" name="是否提前熟悉" shape="circle"></u-checkbox>
  205. </u-checkbox-group>
  206. </view>
  207. <view class="split-line"></view>
  208. <view class="service-new-details-desc">
  209. <view style="display: flex;">
  210. <text style="width: 20rpx;">*</text>
  211. <text style="flex: 1;">价格{{ price_config.preFamiliarize.price }}/</text>
  212. </view>
  213. <view style="display: flex; margin: 20rpx 0;">
  214. <text style="width: 20rpx;">*</text>
  215. <text style="flex: 1;">服务内容: 购买此服务后伴宠师将在您离家前按照约定日期提前上门沟通熟悉喂养要求及宠物</text>
  216. </view>
  217. <view style="display: flex;">
  218. <text style="width: 20rpx;">*</text>
  219. <text style="flex: 1;">服务保障: 购买此服务后平台支持在提前熟悉后上门服务第一天前无理由免费更换伴宠师1次</text>
  220. </view>
  221. </view>
  222. </view>
  223. </uni-card>
  224. </view>
  225. <view class="details-subscribe">
  226. <view class="details-radio" style="width: 100%;padding-bottom: 20rpx;">
  227. <view>
  228. <u-checkbox-group v-model="isAgree" size="16" labelSize="14" labelColor="#999999">
  229. <u-checkbox activeColor="#FFBF60" label="我同意" name="我同意" labelSize="14" size="14"
  230. shape="circle"></u-checkbox>
  231. </u-checkbox-group>
  232. </view>
  233. <text style="color: #FFBF60;font-size: 28rpx;" @click="checkAgreement">猫妈狗爸用户服务协议和隐私协议</text>
  234. </view>
  235. <view style="display: flex;justify-content: space-between; align-items: center;">
  236. <view style="height: 80rpx; display: flex; align-items: center;">
  237. <text style="color: #333333;">订单总价: </text>
  238. <text style="color: #FF530A; font-size: 40rpx;">¥{{ parseFloat(finalPrice).toFixed(2) }} <text
  239. style="font-size: 32rpx;"></text></text>
  240. </view>
  241. <view style="display: flex;">
  242. <u-button color="#FFF4E4" customStyle="width: 200rpx; color: #FFAA48; margin-right: 20rpx;"
  243. text="上一步" @click="goBack"></u-button>
  244. <u-button color="#FFBF60" customStyle="width: 200rpx; color: #FFF;" text="支付"
  245. @click="goNext"></u-button>
  246. </view>
  247. </view>
  248. </view>
  249. <view v-if="showCoupon" class="calendar-popup">
  250. <view class="calendar-mask"></view>
  251. <view class="calendar-content">
  252. <view class="price-details">
  253. <view class="price-details-header">
  254. <text
  255. style="text-align: center; width: 100%; font-size: 32rpx; font-weight: 500; color: #333333;">优惠券</text>
  256. <u-icon name="close" @click="togglePriceDetails"></u-icon>
  257. </view>
  258. <view class="split-line"></view>
  259. <scroll-view class="price-details-body" scroll-y v-if="showCouponList">
  260. <view v-for="(item,index) in couponList" style="padding-bottom:14px;" :key="index">
  261. <view class="coupon-card" :class="{
  262. 'auto-selected': item.checked && item.checked.length > 0 && item.isAutoSelected,
  263. 'manual-selected': item.checked && item.checked.length > 0 && !item.isAutoSelected
  264. }">
  265. <view class="card-left"><text
  266. style="font-size: 40rpx; margin-left: 5rpx;">{{ getCouponAmountOrDiscount(item) }}</text>
  267. </view>
  268. <view class="card-right">
  269. <view class="card-content">
  270. <view class="card-info">
  271. {{item.stockName}}
  272. <text v-if="item.checked && item.checked.length > 0 && item.isAutoSelected" style="color: #FF530A; font-size: 24rpx; margin-left: 10rpx;">(自动选择)</text>
  273. <text v-if="item.checked && item.checked.length > 0 && !item.isAutoSelected" style="color: #FF530A; font-size: 24rpx; margin-left: 10rpx;">(手动选择)</text>
  274. </view>
  275. <view class="card-time">有效期限: {{item.expireTime.slice(0, 10)}}截止</view>
  276. </view>
  277. <view style="width: 20%;">
  278. <u-checkbox-group :value="item.checked" @change="changeCoupon">
  279. <u-checkbox :disabled="item.transactionMinimum > originalTotalPrice"
  280. shape="circle" :name="item.id" activeColor="#ffbf60"></u-checkbox>
  281. </u-checkbox-group>
  282. </view>
  283. </view>
  284. </view>
  285. </view>
  286. </scroll-view>
  287. </view>
  288. <u-button color="#FFBF60" type="primary" @click="confirmCoupon">确定</u-button>
  289. </view>
  290. </view>
  291. </view>
  292. </template>
  293. <script>
  294. import {
  295. getPersonalInfo,
  296. getCouponList,
  297. getCouponListForOrder
  298. } from "@/api/system/personal.js"
  299. import {
  300. getToken,
  301. getOpenIdKey
  302. } from '@/utils/auth'
  303. import {
  304. createOrderNew
  305. } from '@/api/system/user.js'
  306. import dayjs from '@/utils/lib/dayjs.min.js'
  307. export default {
  308. data() {
  309. return {
  310. isPaying: false,
  311. currentAddress: {},
  312. currentPetsByDay: [],
  313. showPets: [],
  314. expandedIndexs: [],
  315. isAgree: false,
  316. needPreFamiliarize: [],
  317. dailyShowData: [],
  318. originalTotalPrice: 0,
  319. totalPrice: 0, // 总费用
  320. discount: 0, // 平台优惠
  321. memberDiscount: 0, // 会员折扣
  322. finalPrice: 0, // 应付费用
  323. defaultPhoto: 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/pet/catdog.png',
  324. currentMember: {},
  325. memberDiscountList: [{
  326. itemType: "新晋家长",
  327. },
  328. {
  329. itemType: "普卡会员",
  330. },
  331. {
  332. itemType: "银卡会员",
  333. },
  334. {
  335. itemType: "金卡会员",
  336. }
  337. ],
  338. couponList: [],
  339. showCoupon: false,
  340. selectedCoupon: null,
  341. showCouponList: true,
  342. couponId: null,
  343. basePrice: 0,
  344. baseProduct: '',
  345. // 节假日价格配置
  346. holidayPrice: 75,
  347. normalPrice: 75,
  348. holidayDate: [],
  349. //折扣
  350. discountMemberText : '',
  351. companionLevelTitle : '',
  352. }
  353. },
  354. onLoad() {
  355. if (getToken() && getOpenIdKey()) {
  356. this.getPersonalInfo()
  357. }
  358. this.originalTotalPrice = this.$globalData.newOrderData.totalPrice
  359. if (this.originalTotalPrice) {
  360. this.basePrice = this.$globalData.mainSku[0].price
  361. this.baseProduct = this.$globalData.mainSku[0].name
  362. this.currentAddress = this.$globalData.newOrderData.currentAddress
  363. this.currentPetsByDay = this.$globalData.newOrderData.currentPetsByDay
  364. this.needPreFamiliarize = this.$globalData.newOrderData.needPreFamiliarize
  365. } else {
  366. // 返回首页
  367. uni.reLaunch({
  368. url: '/pages/index'
  369. });
  370. }
  371. this.initPriceConfig()
  372. this.getShowPets()
  373. this.groupPetsByDate()
  374. this.getCouponList()
  375. // this.totalPrice = this.$globalData.newOrderData.totalPrice
  376. this.companionLevelTitle = this.$globalData.newOrderData.companionLevel.paramValue
  377. },
  378. methods: {
  379. companionLevelPrice(){
  380. let companionLevel = this.$globalData.newOrderData.companionLevel
  381. let price = Number(companionLevel.paramValueText) * this.isAddPrice()
  382. return price * this.$store.state.memberRate
  383. },
  384. //判断当前选中的地址是否加价
  385. isAddPrice(){
  386. let currentAddress = this.$globalData.newOrderData.currentAddress || {}
  387. let defaultPrice = 1
  388. try{
  389. defaultPrice = this.price_config.cityConfig.priceRates.default
  390. }catch(e){
  391. defaultPrice = 1
  392. }
  393. if(!this.price_config.cityConfig || !currentAddress.province || !currentAddress.city){
  394. return defaultPrice
  395. }
  396. let addressList = this.price_config.cityConfig.priceRates || []
  397. for(let key in addressList){
  398. if((currentAddress.province + currentAddress.city).includes(key)){
  399. return addressList[key]
  400. }
  401. }
  402. return defaultPrice
  403. },
  404. getDateText(date){
  405. return dayjs(date).format('MM-DD')
  406. },
  407. // 将currentPets转换为showPets
  408. getShowPets() {
  409. const showPets = []
  410. // 将 currentPetsByDay 通过petId分组
  411. const groupedPets = this.currentPetsByDay.reduce((acc, pet) => {
  412. pet.index = pet.petId + '-' + pet.serviceDate
  413. if (!acc[pet.petId]) {
  414. acc[pet.petId] = []; // 如果不存在,则初始化一个空数组
  415. }
  416. acc[pet.petId].push(pet); // 将当前宠物添加到对应的 petId 数组中
  417. return acc;
  418. }, {});
  419. console.log(groupedPets)
  420. // 循环将pets转换为showPets
  421. for (let petId in groupedPets) {
  422. const showPet = {
  423. petId: petId,
  424. name: groupedPets[petId][0].name,
  425. gender: groupedPets[petId][0].gender,
  426. petType: groupedPets[petId][0].petType,
  427. bodyType: groupedPets[petId][0].bodyType,
  428. photo: groupedPets[petId][0].photo,
  429. pets: groupedPets[petId]
  430. }
  431. showPets.push(showPet)
  432. }
  433. this.showPets = showPets
  434. console.log(this.showPets)
  435. },
  436. // 将宠物按天分组
  437. groupPetsByDate() {
  438. const dailyShowData = []
  439. const dailyPets = [];
  440. // 按日期分组宠物
  441. this.currentPetsByDay.forEach(pet => {
  442. const serviceDate = pet.serviceDate;
  443. if (!dailyPets[serviceDate]) {
  444. dailyPets[serviceDate] = [];
  445. }
  446. dailyPets[serviceDate].push(pet);
  447. });
  448. // 计算每日费用
  449. for (const date in dailyPets) {
  450. const pets = dailyPets[date];
  451. const priceDetails = []
  452. // 基础服务 - 根据是否为节假日设置价格
  453. const baseServiceCost = Number(this.isHoliday(date) ? this.holidayPrice : this.normalPrice)
  454. const largeDogCount = pets.filter(pet => pet.petType === 'dog' && pet.bodyType.includes('大型')).length;
  455. let mediumDogCount = pets.filter(pet => pet.petType === 'dog' && pet.bodyType.includes('中型')).length;
  456. let smallDogCount = pets.filter(pet => pet.petType === 'dog' && pet.bodyType.includes('小型')).length;
  457. let catCount = pets.filter(pet => pet.petType === 'cat').length;
  458. const additionalCostItem = []
  459. let additionalCost = 0
  460. // 单天总宠物费用
  461. let totalPetCost = pets.reduce((acc, pet) => {
  462. return acc + this.calculatePetCost(pet);
  463. }, 0);
  464. //免费规则
  465. // 如果总宠物费用>30
  466. const freeQuota = this.price_config.freeQuota
  467. if (totalPetCost > Number(freeQuota.threshold)) {
  468. freeQuota.rules.forEach(rule => {
  469. if (rule.type === 'cat' && catCount >= rule.count) {
  470. additionalCost = totalPetCost - Number(rule.freeAmount)
  471. catCount = catCount - rule.count
  472. }else if(rule.type === 'smallDog' && smallDogCount >= rule.count){
  473. additionalCost = totalPetCost - Number(rule.freeAmount)
  474. smallDogCount = smallDogCount - rule.count
  475. }else if(rule.type === 'mediumDog' && mediumDogCount >= rule.count){
  476. additionalCost = totalPetCost - Number(rule.freeAmount)
  477. mediumDogCount = mediumDogCount - rule.count
  478. }else{
  479. additionalCost = totalPetCost - Number(rule.freeAmount)
  480. }
  481. })
  482. if (mediumDogCount > 0) {
  483. additionalCostItem.push({
  484. itemName: '中型犬',
  485. price: this.calculatePetCost({
  486. petType: 'dog',
  487. bodyType: '中型',
  488. }),
  489. quantity: mediumDogCount,
  490. unit: '只'
  491. })
  492. }
  493. if (smallDogCount > 0) {
  494. additionalCostItem.push({
  495. itemName: '小型犬',
  496. price: this.calculatePetCost({
  497. petType: 'dog',
  498. bodyType: '小型',
  499. }),
  500. quantity: smallDogCount,
  501. unit: '只'
  502. })
  503. }
  504. if (catCount > 0) {
  505. additionalCostItem.push({
  506. itemName: '猫猫',
  507. price: this.calculatePetCost({
  508. petType: 'cat',
  509. }),
  510. quantity: catCount,
  511. unit: '只'
  512. })
  513. }
  514. }
  515. // 如果有大型犬,额外费用为40元/只
  516. if (largeDogCount > 0) {
  517. additionalCost += (this.calculatePetCost({
  518. petType: 'dog',
  519. bodyType: '大型',
  520. }) * largeDogCount)
  521. additionalCostItem.push({
  522. itemName: '大型犬',
  523. price: this.calculatePetCost({
  524. petType: 'dog',
  525. bodyType: '大型',
  526. }),
  527. quantity: largeDogCount,
  528. unit: '只'
  529. })
  530. }
  531. // 当日多次服务次数
  532. let multServicesTotalCost = 0
  533. const maxFeedCount = Math.max(...pets.map(pet => pet.feedCount));
  534. if (maxFeedCount === 2) {
  535. multServicesTotalCost += this.price_config.multiService.two.price; // 1天2次
  536. } else if (maxFeedCount === 3) {
  537. multServicesTotalCost += this.price_config.multiService.three.price; // 1天3次
  538. }
  539. priceDetails.push({
  540. name: '专业喂养',
  541. item: [{
  542. itemName: this.isHoliday(date) ? '节假日' : '非节假日',
  543. price: baseServiceCost,
  544. quantity: 1,
  545. unit: '天'
  546. }, ]
  547. })
  548. priceDetails.push({
  549. name: '上门次数',
  550. item: [{
  551. itemName: '1天2次',
  552. price: this.price_config.multiService.two.price,
  553. quantity: maxFeedCount === 2 ? 1 : 0,
  554. unit: '天'
  555. },
  556. {
  557. itemName: '1天3次',
  558. price: this.price_config.multiService.three.price,
  559. quantity: maxFeedCount === 3 ? 1 : 0,
  560. unit: '天'
  561. },
  562. ]
  563. })
  564. if (additionalCostItem.length > 0) {
  565. priceDetails.push({
  566. name: '额外宠物费用',
  567. item: additionalCostItem
  568. })
  569. }
  570. // 所有宠物定制服务费用
  571. const customServiceCost = pets.reduce((acc, pet) => acc + this.calculatePetCustomServiceCost(pet), 0)
  572. console.log(baseServiceCost + additionalCost + multServicesTotalCost + customServiceCost);
  573. console.log(baseServiceCost , additionalCost , multServicesTotalCost , customServiceCost);
  574. const totalCost = parseFloat((baseServiceCost + additionalCost + multServicesTotalCost + Number(customServiceCost))).toFixed(2)
  575. // 所有宠物定制服务总项数,每个类型的服务只算一次
  576. const acc = []
  577. pets.map(pet => {
  578. pet.customServices.forEach(service => {
  579. if (!acc.includes(service.skuId) && service.quantity > 0) {
  580. acc.push(service.skuId)
  581. }
  582. })
  583. })
  584. const customServicesTotalCnt = acc.length
  585. dailyShowData.push({
  586. date,
  587. pets,
  588. priceDetails,
  589. totalCost,
  590. customServicesTotalCnt
  591. })
  592. }
  593. // 将dailyShowData按日期排序
  594. this.dailyShowData = dailyShowData.sort((a, b) => new Date(a.date) - new Date(b.date))
  595. this.getShowTotalPrice()
  596. },
  597. calculatePetCost(pet) {
  598. // 宠物额外费用 不计算大型犬
  599. let petExtra = this.price_config.petExtra
  600. let petCost = 0;
  601. if (pet.petType === 'cat') {
  602. petCost += Number(petExtra.cat); // 猫额外费用
  603. } else if (pet.petType === 'dog' && pet.bodyType.includes('小型')) {
  604. petCost += Number(petExtra.smallDog); // 小型犬额外费用
  605. } else if (pet.petType === 'dog' && pet.bodyType.includes('中型')) {
  606. petCost += Number(petExtra.mediumDog); // 中型犬额外费用
  607. }
  608. return petCost;
  609. },
  610. // 计算宠物定制服务费用
  611. calculatePetCustomServiceCost(pet) {
  612. console.log('pet.customServices',pet.customServices)
  613. const customServiceCost = pet.customServices.reduce((acc, item) => acc + Number(item.price) * item.quantity, 0)
  614. console.log('customServiceCost',customServiceCost)
  615. return parseFloat(customServiceCost).toFixed(2)
  616. },
  617. // 展开或收起服务详情
  618. toggleExpand(index) {
  619. console.log(index)
  620. this.expandedIndexs = this.expandedIndexs.includes(index) ? this.expandedIndexs.filter(i => i !== index) :
  621. [...this.expandedIndexs, index];
  622. // this.expandedIndexs.push(index)
  623. console.log(this.expandedIndexs)
  624. },
  625. goBack() {
  626. let len = getCurrentPages().length;
  627. if (len >= 2) {
  628. uni.navigateBack();
  629. } else {
  630. uni.redirectTo({
  631. url: '/pages/newOrder/serviceNew2'
  632. });
  633. }
  634. },
  635. changeAgree() {
  636. this.isAgree = !this.isAgree
  637. },
  638. checkAgreement() {
  639. uni.navigateTo({
  640. url: '/pages/details/agreement'
  641. });
  642. },
  643. // 初始化价格配置
  644. initPriceConfig() {
  645. let priceConfig = this.$store.state.price_config
  646. console.log('价格配置:', priceConfig)
  647. if(priceConfig.basePrice && priceConfig.basePrice.holiday){
  648. this.holidayPrice = Number(priceConfig.basePrice.holiday * this.$store.state.memberRate).toFixed(2)
  649. }
  650. if(priceConfig.basePrice && priceConfig.basePrice.normal){
  651. this.normalPrice = Number(priceConfig.basePrice.normal * this.$store.state.memberRate).toFixed(2)
  652. }
  653. if(priceConfig.holidays && priceConfig.holidays.length > 0){
  654. this.holidayDate = priceConfig.holidays
  655. }else{
  656. this.holidayDate = []
  657. }
  658. this.discountMemberText = (this.$store.state.memberRate * 10)
  659. },
  660. // 判断是否为节假日
  661. isHoliday(date) {
  662. return this.holidayDate.includes(date)
  663. },
  664. // 节流
  665. throttle(func, delay) {
  666. let lastCall = 0;
  667. return function(...args) {
  668. const now = new Date().getTime();
  669. if (now - lastCall < delay) {
  670. return;
  671. }
  672. lastCall = now;
  673. func(...args);
  674. }
  675. },
  676. getPersonalInfo() {
  677. getPersonalInfo().then(res => {
  678. if (res && (res.id || res.id === 0)) {
  679. let userLevel = res.level
  680. this.currentMember = this.memberDiscountList.find(item => {
  681. if (item.itemType.includes(userLevel)) {
  682. return item
  683. }
  684. })
  685. this.getShowTotalPrice()
  686. // 重新计算最优惠的优惠券
  687. if (this.couponList.length > 0) {
  688. this.autoSelectBestCoupon()
  689. }
  690. }
  691. })
  692. },
  693. // 获取优惠券列表
  694. getCouponList() {
  695. getCouponListForOrder().then(res => {
  696. let rows = res.rows
  697. console.log(rows)
  698. this.couponList = rows.filter(item => item.couponState == "SENDED")
  699. this.couponList.forEach(item => {
  700. item.checked = []
  701. item.couponAmount = 20
  702. item.isAutoSelected = false
  703. })
  704. // 自动选择最优惠的优惠券
  705. this.autoSelectBestCoupon()
  706. })
  707. },
  708. selectCoupon() {
  709. this.showCoupon = true
  710. },
  711. changeCoupon(item) {
  712. this.showCouponList = false
  713. const selectedCouponId = item[0]
  714. const selectedCoupon = this.couponList.find(coupon => coupon.id === selectedCouponId)
  715. // 清空所有优惠券的选中状态和自动选择标记
  716. this.couponList.forEach(coupon => {
  717. coupon.checked = null
  718. coupon.isAutoSelected = false
  719. })
  720. // 如果选择了优惠券,检查是否有相同 couponState 的优惠券已被使用
  721. if (selectedCoupon) {
  722. // 检查是否有相同 couponState 的优惠券已被使用
  723. const hasSameStateUsed = this.couponList.some(coupon =>
  724. coupon.id !== selectedCouponId &&
  725. coupon.couponState === selectedCoupon.couponState &&
  726. coupon.checked &&
  727. coupon.checked.length > 0
  728. )
  729. if (hasSameStateUsed) {
  730. uni.showToast({
  731. title: '相同类型的优惠券不可重复使用',
  732. icon: 'none'
  733. })
  734. this.showCouponList = true
  735. return
  736. }
  737. // 设置选中状态,标记为用户手动选择
  738. selectedCoupon.checked = item
  739. selectedCoupon.isAutoSelected = false
  740. }
  741. this.showCouponList = true
  742. },
  743. confirmCoupon() {
  744. this.selectedCoupon = this.couponList.find(coupon => coupon.checked && coupon.checked.length > 0)
  745. if (!this.selectedCoupon) {
  746. this.couponId = null
  747. this.discount = 0
  748. } else {
  749. this.couponId = this.selectedCoupon?.id
  750. // 如果优惠券是折扣
  751. if (this.selectedCoupon?.stockType == "PDISCOUNT" && this.selectedCoupon?.discountPercent > 0) {
  752. //保留两位小数
  753. this.discount = (this.originalTotalPrice * (1 - this.selectedCoupon.discountPercent / 100))
  754. .toFixed(2)
  755. } else {
  756. this.discount = this.selectedCoupon?.discountAmount
  757. }
  758. }
  759. this.getShowTotalPrice()
  760. this.showCoupon = false
  761. },
  762. togglePriceDetails() {
  763. this.showCoupon = !this.showCoupon
  764. },
  765. // 构造订单
  766. constructOrder() {
  767. const order = {
  768. openId: getOpenIdKey(),
  769. addressId: this.currentAddress.id,
  770. totalPrice: this.finalPrice,//应付费用
  771. needPreFamiliarize: this.needPreFamiliarize.length > 0,
  772. couponId: this.couponId,
  773. petOrderServices: this.getPetOrderServices(this.currentPetsByDay),
  774. //费用明细
  775. //dailyShowData : JSON.stringify(this.dailyShowData),
  776. //优惠券优惠
  777. couponDiscount: this.discount,
  778. //会员折扣
  779. memberDiscount: this.memberDiscount,
  780. //费用总计
  781. oldPrice : this.originalTotalPrice,
  782. //提前熟悉的费用
  783. preFamiliarizePrice: this.price_config.preFamiliarize.price,
  784. //伴宠师等级名称
  785. companionLevelTitle : this.companionLevelTitle,
  786. //伴宠师等级加价
  787. companionLevelPrice: this.companionLevelPrice(),
  788. }
  789. if(this.buyInfo.teacher){
  790. order.teacherId = this.buyInfo.teacher.userId
  791. }
  792. if(this.$globalData.newOrderData.companionLevel){
  793. //打印
  794. console.log(this.$globalData.newOrderData.companionLevel);
  795. order.companionLevel = this.$globalData.newOrderData.companionLevel.paramValueNum
  796. // order.companionLevel = ['', 'junior', 'senior'].indexOf(this.$globalData.newOrderData.companionLevel)
  797. }
  798. if(this.$globalData.newOrderData.orderId){
  799. order.orderId = this.$globalData.newOrderData.orderId
  800. }
  801. console.log(order)
  802. return order
  803. },
  804. getSkuList(customServices, feedCount, price) {
  805. console.log('customServices', JSON.parse(JSON.stringify(customServices)));
  806. const skuList = customServices.filter(service => service.quantity > 0).map(service2 => {
  807. return {
  808. skuId: service2.skuId,
  809. quantity: service2.quantity,
  810. isMainProduct: service2.isMainProduct,
  811. price: service2.price
  812. }
  813. })
  814. skuList.push({
  815. skuId: this.$globalData.mainSku[0].skuId,
  816. quantity: feedCount,
  817. isMainProduct: true,
  818. price
  819. })
  820. return skuList
  821. },
  822. getPetOrderServices(currentPetsByDay) {
  823. console.log('currentPetsByDay', JSON.parse(JSON.stringify(currentPetsByDay)));
  824. const petOrderServices = currentPetsByDay.map(pet => {
  825. let price = this.isHoliday(pet.serviceDate) ? this.holidayPrice : this.normalPrice
  826. // 当日多次服务次数
  827. let feedCountPrice = 0;
  828. if (pet.feedCount == 2) {
  829. feedCountPrice += this.price_config.multiService.two.price; // 1天2次
  830. } else if (pet.feedCount == 3) {
  831. feedCountPrice += this.price_config.multiService.three.price; // 1天3次
  832. }
  833. return {
  834. petId: pet.petId,
  835. serviceDate: pet.serviceDate,
  836. feedCount: pet.feedCount,
  837. selectedTimeSlots: pet.selectedTimeSlots.join(','),
  838. skuList: this.getSkuList(pet.customServices, pet.feedCount, price),
  839. feedCountPrice,//当日多次服务加价
  840. }
  841. })
  842. return petOrderServices
  843. },
  844. pay(params) {
  845. if (this.isPaying) {
  846. return;
  847. }
  848. this.isPaying = true
  849. uni.requestPayment({
  850. provider: 'wxpay',
  851. timeStamp: params.timeStamp,
  852. nonceStr: params.nonceStr,
  853. package: params.package_,
  854. signType: params.signType,
  855. paySign: params.paySign,
  856. success: (res) => {
  857. this.$modal.showToast('支付成功')
  858. this.$globalData.newOrderData = {
  859. currentAddress: {},
  860. currentPets: [],
  861. totalPrice: 0,
  862. needPreFamiliarize: []
  863. }
  864. uni.reLaunch({
  865. url: '/pages_order/order/payOrderSuccessful'
  866. // url: '/pages/details/successful'
  867. });
  868. },
  869. fail: (err) => {
  870. this.loading = false
  871. console.log('支付失败', err)
  872. this.$modal.showToast('支付失败')
  873. },
  874. complete: () => {
  875. this.loading = false
  876. this.isPaying = false
  877. }
  878. })
  879. },
  880. changePreFamiliarize(name) {
  881. if (name && name.length > 0) {
  882. this.needPreFamiliarize = name
  883. this.originalTotalPrice = this.originalTotalPrice + this.price_config.preFamiliarize.price
  884. } else {
  885. this.needPreFamiliarize = []
  886. this.originalTotalPrice = this.originalTotalPrice - this.price_config.preFamiliarize.price
  887. }
  888. // 重新计算最优惠的优惠券
  889. this.autoSelectBestCoupon()
  890. this.getShowTotalPrice()
  891. },
  892. getShowTotalPrice() {
  893. // 会员折扣已经在上一个页面减去了,这里需要根据originalTotalPrice反推会员减去了多少
  894. // originalTotalPrice: 已经应用会员折扣后的价格
  895. // memberRate: 会员折扣率(如0.9表示9折)
  896. // 反推原价:originalTotalPrice / memberRate
  897. // 会员折扣金额:原价 - originalTotalPrice
  898. const originalPriceBeforeMemberDiscount = this.originalTotalPrice / this.$store.state.memberRate
  899. this.memberDiscount = (originalPriceBeforeMemberDiscount - this.originalTotalPrice).toFixed(2)
  900. // 计算最终支付价格
  901. // finalPrice: 最终支付价格 = 已应用会员折扣的价格 - 优惠券优惠
  902. this.finalPrice = (this.originalTotalPrice - this.discount).toFixed(2)
  903. },
  904. getCouponAmountOrDiscount(item) {
  905. if (item.stockType == "PDISCOUNT") {
  906. return item.discountPercent / 10 + '折'
  907. } else {
  908. return '¥' + item.discountAmount
  909. }
  910. },
  911. // 自动选择最优惠的优惠券
  912. autoSelectBestCoupon() {
  913. // 清空所有优惠券的选中状态和自动选择标记
  914. this.couponList.forEach(coupon => {
  915. coupon.checked = null
  916. coupon.isAutoSelected = false
  917. })
  918. // 过滤出可用的优惠券(满足最低消费要求)
  919. const availableCoupons = this.couponList.filter(coupon =>
  920. this.originalTotalPrice >= coupon.transactionMinimum
  921. )
  922. if (availableCoupons.length === 0) {
  923. this.selectedCoupon = null
  924. this.couponId = null
  925. this.discount = 0
  926. return
  927. }
  928. // 计算每个优惠券的实际优惠金额
  929. const couponsWithDiscount = availableCoupons.map(coupon => {
  930. let discountAmount = 0
  931. if (coupon.stockType === "PDISCOUNT" && coupon.discountPercent > 0) {
  932. // 折扣券:计算折扣后的优惠金额
  933. discountAmount = this.originalTotalPrice * (coupon.discountPercent / 100)
  934. } else {
  935. // 满减券:直接使用优惠金额
  936. discountAmount = coupon.discountAmount
  937. }
  938. return {
  939. ...coupon,
  940. calculatedDiscount: discountAmount
  941. }
  942. })
  943. // 按优惠金额从高到低排序,选择最优惠的
  944. couponsWithDiscount.sort((a, b) => b.calculatedDiscount - a.calculatedDiscount)
  945. // 选择最优惠的优惠券
  946. const bestCoupon = couponsWithDiscount[0]
  947. // 在原始的 couponList 中找到对应的优惠券并设置选中状态
  948. const originalCoupon = this.couponList.find(coupon => coupon.id === bestCoupon.id)
  949. if (originalCoupon) {
  950. originalCoupon.checked = [originalCoupon.id]
  951. originalCoupon.isAutoSelected = true // 标记为自动选择
  952. this.selectedCoupon = originalCoupon
  953. this.couponId = originalCoupon.id
  954. // 计算优惠金额
  955. if (originalCoupon.stockType === "PDISCOUNT" && originalCoupon.discountPercent > 0) {
  956. this.discount = (this.originalTotalPrice * (1 - originalCoupon.discountPercent / 100)).toFixed(2)
  957. } else {
  958. this.discount = originalCoupon.discountAmount
  959. }
  960. console.log('自动选择最优惠优惠券:', originalCoupon.stockName, '优惠金额:', this.discount)
  961. }
  962. // 重新计算总价
  963. this.getShowTotalPrice()
  964. },
  965. goNext() {
  966. if (!this.isAgree) {
  967. uni.showToast({
  968. title: '请先同意用户协议',
  969. icon: 'none'
  970. })
  971. return
  972. }
  973. const order = this.constructOrder()
  974. createOrderNew(order).then(res => {
  975. if (res.code == 200) {
  976. this.pay(res.data)
  977. } else {
  978. this.$modal.showToast('创建订单失败,请重试');
  979. this.loading = false
  980. }
  981. })
  982. }
  983. }
  984. }
  985. </script>
  986. <style scoped lang="scss">
  987. .container {
  988. position: relative;
  989. height: 100%;
  990. padding-bottom: 200rpx;
  991. .details-subscribe {
  992. background-color: #FFFFFF;
  993. padding: 10px;
  994. width: 100%;
  995. height: 200rpx;
  996. position: fixed;
  997. bottom: 0;
  998. z-index: 100;
  999. .details-btn {
  1000. width: 100%;
  1001. border-radius: 6px;
  1002. background: #FFB13F;
  1003. font-size: 16px;
  1004. color: #FFFFFF;
  1005. }
  1006. .details-radio {
  1007. display: flex;
  1008. align-items: center;
  1009. justify-content: center;
  1010. }
  1011. }
  1012. }
  1013. .service-new {
  1014. .service-new-flag {
  1015. width: 8rpx;
  1016. height: 32rpx;
  1017. background: #FFBF60;
  1018. border-radius: 30rpx 30rpx 30rpx 30rpx;
  1019. margin-right: 10rpx;
  1020. }
  1021. .split-line {
  1022. width: 100%;
  1023. height: 1rpx;
  1024. background: #EFEFEF;
  1025. }
  1026. .service-new-title {
  1027. display: flex;
  1028. font-weight: 500;
  1029. font-size: 28rpx;
  1030. color: #333333;
  1031. line-height: 33rpx;
  1032. margin: 42rpx 0 30rpx;
  1033. justify-content: space-between;
  1034. .service-new-title-left {
  1035. display: flex;
  1036. align-items: center;
  1037. }
  1038. }
  1039. .service-new-details-desc {
  1040. font-weight: 400;
  1041. font-size: 24rpx;
  1042. color: #A94F20;
  1043. line-height: 28rpx;
  1044. text-align: left;
  1045. padding: 26rpx 0;
  1046. }
  1047. .personal-address-info {
  1048. display: flex;
  1049. align-items: center;
  1050. justify-content: flex-start;
  1051. flex-wrap: wrap;
  1052. margin: 32rpx 0;
  1053. width: 80%;
  1054. .personal-address-text {
  1055. color: #333;
  1056. font-size: 28rpx;
  1057. font-weight: bold;
  1058. width: 100%;
  1059. }
  1060. .personal-address-people {
  1061. color: #7D8196;
  1062. font-size: 28rpx;
  1063. font-weight: 400;
  1064. display: flex;
  1065. justify-content: flex-start;
  1066. align-items: center;
  1067. }
  1068. }
  1069. .service-new-address-selected {
  1070. display: flex;
  1071. justify-content: space-between;
  1072. align-items: center;
  1073. }
  1074. }
  1075. .personal-pet-list {
  1076. margin-top: 20rpx;
  1077. .personal-pet-list-item {
  1078. margin-bottom: 20rpx;
  1079. background-color: #F9F9F9;
  1080. height: 172rpx;
  1081. border-radius: 8rpx;
  1082. .personal-pet-info {
  1083. height: 100%;
  1084. display: flex;
  1085. align-items: center;
  1086. padding: 0 20rpx;
  1087. }
  1088. }
  1089. }
  1090. .service-new-address {
  1091. .service-summary {
  1092. height: 90rpx;
  1093. display: flex;
  1094. justify-content: space-between;
  1095. align-items: center;
  1096. padding: 15rpx;
  1097. cursor: pointer;
  1098. transition: background-color 0.3s;
  1099. }
  1100. .service-details {
  1101. padding: 10rpx 15rpx;
  1102. background-color: #F9F9F9;
  1103. margin-bottom: 10rpx;
  1104. .pet-info {
  1105. display: flex;
  1106. justify-content: space-between;
  1107. margin: 5rpx 0;
  1108. font-size: 24rpx;
  1109. color: #333;
  1110. }
  1111. .service-item {
  1112. display: flex;
  1113. justify-content: space-between;
  1114. width: 100%;
  1115. color: #999999;
  1116. font-size: 28rpx;
  1117. }
  1118. }
  1119. .total-cost {
  1120. padding: 10rpx 15rpx;
  1121. font-size: 28rpx;
  1122. color: #333;
  1123. display: flex;
  1124. justify-content: space-between;
  1125. }
  1126. }
  1127. .calendar-popup {
  1128. position: fixed;
  1129. bottom: 0;
  1130. left: 0;
  1131. right: 0;
  1132. z-index: 999;
  1133. .calendar-content {
  1134. background: #F5F5F7;
  1135. border-radius: 16rpx 16rpx 0 0;
  1136. padding: 0 20rpx 40rpx;
  1137. }
  1138. }
  1139. .calendar-mask {
  1140. position: fixed;
  1141. top: 0;
  1142. left: 0;
  1143. right: 0;
  1144. bottom: 0;
  1145. background: rgba(0, 0, 0, 0.5);
  1146. /* 半透明黑色 */
  1147. z-index: 998;
  1148. /* 确保在内容下方 */
  1149. pointer-events: none;
  1150. /* 使遮罩层不阻止点击事件 */
  1151. }
  1152. .calendar-content {
  1153. position: relative;
  1154. /* 确保内容在遮罩层之上 */
  1155. z-index: 999;
  1156. /* 确保内容在遮罩层之上 */
  1157. }
  1158. .price-details {
  1159. background: #F5F5F7;
  1160. /* 背景颜色 */
  1161. padding: 10px 10px 0 10px;
  1162. /* 内边距 */
  1163. z-index: 1000;
  1164. /* 确保在其他元素之上 */
  1165. min-height: 600rpx;
  1166. /* 固定高度 */
  1167. overflow: hidden;
  1168. /* 隐藏超出部分 */
  1169. }
  1170. .price-details-header {
  1171. display: flex;
  1172. justify-content: space-between;
  1173. align-items: center;
  1174. padding-bottom: 20rpx;
  1175. }
  1176. .price-details-body {
  1177. margin-top: 20rpx;
  1178. max-height: 450rpx;
  1179. /* 留出头部空间 */
  1180. overflow-y: auto;
  1181. /* 允许上下滚动 */
  1182. }
  1183. .coupon-card {
  1184. display: flex;
  1185. align-items: center;
  1186. width: 100%;
  1187. padding: 10px 0;
  1188. background: #fff;
  1189. border-radius: 8px;
  1190. -webkit-mask-image: radial-gradient(circle at 88px 4px, transparent 4px, #d8d8d8 4.5px), radial-gradient(closest-side circle at 50%, #d8d8d8 99%, transparent 100%);
  1191. -webkit-mask-size: 100%, 2px 4px;
  1192. -webkit-mask-repeat: repeat, repeat-y;
  1193. -webkit-mask-position: 0 -4px, 87px;
  1194. -webkit-mask-composite: source-out;
  1195. mask-composite: subtract;
  1196. // background: linear-gradient(45deg, orange, red);
  1197. // &.auto-selected {
  1198. // border: 2px solid #FF530A;
  1199. // background: linear-gradient(135deg, #fff 0%, #FFF4E4 100%);
  1200. // }
  1201. // &.manual-selected {
  1202. // border: 2px solid #4CAF50;
  1203. // background: linear-gradient(135deg, #fff 0%, #E8F5E8 100%);
  1204. // }
  1205. }
  1206. .card-left {
  1207. width: 88px;
  1208. text-align: center;
  1209. font-size: 28rpx;
  1210. color: #FF530A;
  1211. }
  1212. .card-right {
  1213. padding: 0px 12px;
  1214. display: flex;
  1215. flex: 1;
  1216. /* flex-direction: column; */
  1217. justify-content: space-between;
  1218. align-items: center;
  1219. height: 60px;
  1220. s .card-content {
  1221. width: 80%;
  1222. }
  1223. .card-icon {
  1224. position: relative;
  1225. right: -10px;
  1226. top: -10px;
  1227. }
  1228. }
  1229. .card-info {
  1230. margin: 0;
  1231. font-size: 14px;
  1232. line-height: 20px;
  1233. color: #333333;
  1234. }
  1235. .card-time {
  1236. font-size: 12px;
  1237. line-height: 16px;
  1238. font-weight: normal;
  1239. color: #aaaaaa;
  1240. margin-top: 4px;
  1241. }
  1242. </style>