index.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888
  1. <template>
  2. <view class="s-header-card">
  3. <zzx-icon name="location" size="14"></zzx-icon>
  4. <text>{{ timeList?.name }}</text>
  5. </view>
  6. <view class="content">
  7. <view class="s-selectdate-card">
  8. <view class="s-title">选择日期</view>
  9. <view class="select-card-list">
  10. <scroll-view class="scroll-view_H" scroll-x="true">
  11. <view :class="selIndex === index ? 'item-card-select' : 'item-card'"
  12. :style="{ backgroundColor: item.inventory < 1 ? '#fefefe' : '', color: item.inventory < 1 ? '#dddddd' : '' }"
  13. v-for="(item, index) in dateList" @click="open_calendar(item, index)">
  14. <view class="day">{{ item.namedDay }}</view>
  15. <view class="date">{{ item.day.slice(5) }}</view>
  16. </view>
  17. </scroll-view>
  18. <view class="more-date" @click="calendar.open()">
  19. 更多日期
  20. </view>
  21. </view>
  22. </view>
  23. <view class="s-selecttime-card">
  24. <view class="s-title">选择时段</view>
  25. <view class="select-card-list">
  26. <scroll-view class="scroll-view_H" scroll-x="true">
  27. <view class="item-card" :style="{
  28. background: `${check_index == index ? '#F0FFBB' : shouldGrayOut(item.endTime) ? '#E0E0E0' : '#F6F6F6'}`,
  29. opacity: shouldGrayOut(item.endTime) ? 0.6 : 1
  30. }" v-for="(item, index) in timeList?.timeSlot" @click="!shouldGrayOut(item.endTime) && check_item(item, index)">
  31. <view class="time">{{ item.name }}</view>
  32. <view class="allowance">余{{ item.inventory }}</view>
  33. <view class="price">¥{{ item.price || '0.00' }}</view>
  34. </view>
  35. </scroll-view>
  36. <view class="not-data" v-if="timeList?.timeSlot.length < 1">暂无可选时段</view>
  37. </view>
  38. </view>
  39. <view class="r-insurance" v-for="item in insureIdList" :key="item.id">
  40. <view class="r-insurance-infobox">
  41. <view class="r-image-box">
  42. <image :src="item.coverImg" mode=""></image>
  43. </view>
  44. <view class="r-insurance-title">
  45. <view class="r-insurance-name">
  46. <view class="r-name">{{ item.name }}</view>
  47. <view class="r-tags">不支持退款</view>
  48. </view>
  49. <view class="r-insurance-desc" v-for="(desc, index) in item.insuranceObvious" :key="index">
  50. <text v-for="([key, value], idx) in Object.entries(desc)" :key="key + idx">{{ key }}, {{
  51. value }};</text>
  52. </view>
  53. <view class="r-insurance-type">保险公司:{{ item.insuranceName_dictText }}</view>
  54. <view class="r-insurance-price">
  55. <view class="r-price">¥{{ insurePrice }}/天·人</view>
  56. <view class="r-insurance-btn" v-if="insureData.length < 1"
  57. @click="gotoInsuracePage(item, item.priceDataList)">去投保
  58. </view>
  59. </view>
  60. </view>
  61. </view>
  62. <view class="line" v-if="insureData.length > 0 && insureId == item.id"></view>
  63. <blcok v-if="insureData.length > 0 && insureId == item.id">
  64. <view class="r-insurance-adduser" v-for="(insureUser, index) in insureData" :key="index">
  65. <view class="r-adduser-btn">
  66. <view class="r-celar" @click="clearUser">清除</view>
  67. <view class="r-edit"
  68. @click="RouterUtils.to_page(`/pages/index/insure/index?priceDataList=${JSON.stringify(item.priceDataList)}`)">
  69. 修改</view>
  70. </view>
  71. <view class="r-userinfo-list">
  72. <view class="r-userinfo-item">
  73. <view class="r-item-title">被保人</view>
  74. <view class="r-item-info">{{ insureUser.userData.length }}人(<text
  75. v-for="user in insureUser.userData" :key="user.id">{{ user.fullName }},</text>)
  76. </view>
  77. </view>
  78. <view class="r-userinfo-item">
  79. <view class="r-item-title">生效时间</view>
  80. <view class="r-item-info">{{ insureUser.slectObj.insureDay }}天({{ insureUser.startDate }}-{{
  81. insureUser.endDate }})
  82. </view>
  83. </view>
  84. <view class="r-userinfo-item">
  85. <view class="r-item-title">保费总金额</view>
  86. <view class="r-item-info">¥{{ insureUser.totalPrice }}</view>
  87. </view>
  88. </view>
  89. </view>
  90. </blcok>
  91. </view>
  92. <view class="g-userinfo-card">
  93. <view class="r-user">
  94. <view class="user-title">用户信息</view>
  95. <view class="invite">
  96. <zzx-icon name="wechat" size="16"></zzx-icon>
  97. <view style="margin-bottom: 8rpx;">邀请微信好友</view>
  98. <zzx-icon name="ashRight" size="12"></zzx-icon>
  99. <button class="g-share-btn" open-type="share"></button>
  100. </view>
  101. </view>
  102. <!-- <view class="user-tags">张三</view> -->
  103. <view class="r-user-list" v-for="item in userData" :key="item.id">
  104. <view class="minus-user" @click="deleteUser(item)">-</view>
  105. <view class="r-list">
  106. <view class="name">{{ item.fullName }}</view>
  107. <view class="id-num">身份证 {{ idCardHide(item.identityCard) }}</view>
  108. </view>
  109. </view>
  110. <view class="g-adduser-btn" @click="toUserList">
  111. <view class="add-icon">+</view>
  112. <view class="add-text">添加用户</view>
  113. </view>
  114. </view>
  115. <view class="submit-btn" @click="submitBooking">免费 立即预约</view>
  116. </view>
  117. <uni-calendar ref="calendar" :insert="false" :date="selectInsurance" @confirm="confirm" />
  118. <uni-popup ref="insurePopup" type="center">
  119. <view class="r-center-popup" v-if="agreementContent">
  120. <view class="r-popup-title">{{ agreementContent.protocolName }}</view>
  121. <view class="r-popup-content">
  122. <rich-text :nodes="agreementContent.protocolContent"></rich-text>
  123. </view>
  124. <view class="r-popup-footer">
  125. <view class="r-popup-needbtn" @click="toNeed">我需要购买保险</view>
  126. <view class="r-popup-refusebtn" @click="toRefuse">我拒绝购买保险</view>
  127. <view class="r-popup-checkbox" @click="select_insurance = !select_insurance">
  128. <zzx-icon :name="select_insurance ? 'selected' : 'unchecked'" size="14"></zzx-icon>
  129. <text>我已认真阅读及确认</text>
  130. </view>
  131. </view>
  132. </view>
  133. </uni-popup>
  134. </template>
  135. <script lang="ts" setup>
  136. import { ref, onMounted } from 'vue';
  137. import { RouterUtils, TipsUtils, idCardHide, debounce } from '@/utils/util';
  138. import { onLoad, onShareAppMessage } from '@dcloudio/uni-app';
  139. import { http } from '@/utils/http'
  140. import { useCacheStore } from '@/stores/cache'
  141. const cache = useCacheStore()
  142. const calendar = ref();
  143. const check_index = ref(0);
  144. onLoad((option) => {
  145. placeId.value = option.id
  146. orderFormData.value.productIds = option.id
  147. })
  148. onShareAppMessage((res) => {
  149. if (res.from === 'button') {// 来自页面内分享按钮
  150. console.log(res.target)
  151. }
  152. return {
  153. title: '邀请您加入',
  154. path: `pages/index/userList/index?userId=${cache.get('USER_INFO').id}`
  155. }
  156. })
  157. onMounted(() => {
  158. get_previewTIme()
  159. get_userData()
  160. getInsureData()
  161. })
  162. const toUserList = () => {
  163. RouterUtils.to_page('/pages/index/userList/index')
  164. }
  165. const selIndex = ref(0)
  166. const selectInsurance = ref()
  167. const open_calendar = (e, i) => {
  168. if (e.inventory < 1) return TipsUtils.tips_toast('该天暂无库存')
  169. selectInsurance.value = e.day
  170. selIndex.value = i
  171. get_previewOrderPlaceSchool(e.day)
  172. }
  173. // 日历回调确认
  174. const confirm = (e) => {
  175. get_previewOrderPlaceSchool(e.fulldate)
  176. selIndex.value = -1
  177. }
  178. // 置灰处理
  179. const shouldGrayOut = (endTime: string) => {
  180. if (!endTime) return true; // 如果没有结束时间,默认为不可用
  181. // 只有当选中的日期是今天时才检查时间是否过期
  182. if (dateList.value && dateList.value[selIndex.value] && dateList.value[selIndex.value].namedDay === '今天') {
  183. return isTimeExpired(endTime);
  184. }
  185. return false;
  186. }
  187. const isTimeExpired = (endTime: string) => {
  188. if (!endTime) return false;
  189. const now = new Date();
  190. const currentTime = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;
  191. // 比较时间
  192. return currentTime > endTime;
  193. }
  194. const rulesId = ref()
  195. const check_item = (e, i) => {
  196. if (e.inventory < 1) return TipsUtils.tips_toast('余量不足,请选择其他时段')
  197. if (shouldGrayOut(e.endTime)) return TipsUtils.tips_toast('该时段已过期,请选择其他时段')
  198. console.log(e);
  199. check_index.value = i
  200. rulesId.value = e.id
  201. orderFormData.value.productIds = e.id
  202. }
  203. // 预览时间选项
  204. const dateList = ref()
  205. const get_previewTIme = () => {
  206. http.get('/order/previewOrderPlaceSchoolTime', { data: { placeId: placeId.value }, loading: true }).then((res) => {
  207. dateList.value = res.result
  208. get_previewOrderPlaceSchool(res.result[0].day)
  209. })
  210. }
  211. // 场地信息预览
  212. const placeId = ref()
  213. const timeList = ref()
  214. const insureIdList = ref([]) // 保险列表
  215. const insurePrice = ref() // 保险价格
  216. const inventory = ref() // 余量
  217. const get_previewOrderPlaceSchool = (startTime: string) => {
  218. http.get('/order/previewOrderPlaceSchool', { data: { placeId: placeId.value, startTime: startTime }, loading: true }).then((res) => {
  219. timeList.value = res.result
  220. // 重置选中索引
  221. check_index.value = -1
  222. if (res.result.timeSlot && res.result.timeSlot.length > 0) {
  223. // 找到第一个可用的时段(有库存且未过期)
  224. let defaultIndex = -1
  225. for (let i = 0; i < res.result.timeSlot.length; i++) {
  226. // 检查时段是否可用(有库存且未过期)
  227. if (res.result.timeSlot[i].inventory > 0 && !shouldGrayOut(res.result.timeSlot[i].endTime)) {
  228. defaultIndex = i
  229. break
  230. }
  231. }
  232. // 只有找到可用时段才设置选中状态
  233. if (defaultIndex !== -1) {
  234. check_index.value = defaultIndex
  235. rulesId.value = res.result.timeSlot[defaultIndex].id
  236. inventory.value = res.result.timeSlot[defaultIndex].inventory
  237. orderFormData.value.productIds = res.result.timeSlot[defaultIndex].id
  238. } else {
  239. // 如果没有可用时段,清空选中状态
  240. rulesId.value = null
  241. inventory.value = 0
  242. orderFormData.value.productIds = null
  243. TipsUtils.tips_toast('暂无可选时段')
  244. }
  245. }
  246. // 处理保险相关数据
  247. res.result.insureIdList.map((item: any) => {
  248. item.insuranceObvious = JSON.parse(item.insuranceObvious)
  249. item.insuranceObvious = [item.insuranceObvious]
  250. item.priceDataList.map((item2: any) => {
  251. if (item2.insureDay === 1) {
  252. insurePrice.value = item2.insurePrice
  253. }
  254. })
  255. })
  256. insureIdList.value = res.result.insureIdList
  257. })
  258. }
  259. const insureData = ref([])
  260. const getInsureData = () => {
  261. uni.$on('insureData', function (data) {
  262. insureData.value = data
  263. console.log(insureData.value, '投保人信息');
  264. orderFormData.value.insureOrderInfoForm.assertStartTime = insureData.value[0].startDate
  265. orderFormData.value.insureOrderInfoForm.assertEndTime = insureData.value[0].endDate
  266. orderFormData.value.insureOrderInfoForm.insurePriceId = insureData.value[0].slectObj.id
  267. if (data.length > 0) {
  268. let familyMembersIds = data[0].userData.map(item => item.id)
  269. orderFormData.value.insureOrderInfoForm.familyMembersIds = familyMembersIds.join(',')
  270. } else {
  271. orderFormData.value.insureOrderInfoForm.familyMembersIds = []
  272. }
  273. })
  274. }
  275. const clearUser = async () => {
  276. let res: any = await TipsUtils.tips_alert('确定清除投保人信息吗?', true)
  277. if (res.confirm) {
  278. insureData.value = []
  279. }
  280. }
  281. const priceDataListData = ref([])
  282. const insureId = ref()
  283. const gotoInsuracePage = (e1: any, e2: any) => {
  284. insureId.value = e1.id
  285. getFindByType(e1.insuranceName)
  286. priceDataListData.value = e2
  287. orderFormData.value.insureOrderInfoForm.insureId = e1.id
  288. }
  289. const agreementContent = ref()
  290. const insurePopup = ref()
  291. const getFindByType = (insuranceName: any) => {
  292. http.get('/my/feedback/findByType', { data: { insuranceName: insuranceName, protocolType: 0 }, loading: true }).then((res: any) => {
  293. agreementContent.value = res.result
  294. insurePopup.value.open()
  295. })
  296. }
  297. const select_insurance = ref(false)
  298. const toNeed = () => {
  299. if (!select_insurance.value) return TipsUtils.tips_toast('请先阅读并同意协议')
  300. RouterUtils.to_page(`/pages/index/insure/index?priceDataList=${JSON.stringify(priceDataListData.value)}&insureId=${insureId.value}`)
  301. insurePopup.value.close()
  302. }
  303. const toRefuse = () => {
  304. if (select_insurance.value) {
  305. insurePopup.value.close()
  306. } else {
  307. TipsUtils.tips_toast('请先阅读并同意协议')
  308. }
  309. }
  310. const userData = ref([])
  311. const get_userData = () => {
  312. uni.$on('userData', function (data) {
  313. console.log(data, '携带用户');
  314. userData.value = data
  315. if (data.length > 0) {
  316. let familyIds = data.map(item => item.id)
  317. orderFormData.value.familyIds = familyIds.join(',')
  318. } else {
  319. orderFormData.value.familyIds = []
  320. }
  321. })
  322. }
  323. const deleteUser = async (e) => {
  324. let res = await TipsUtils.tips_alert('确定删除该用户吗?', true)
  325. if (res.confirm) {
  326. userData.value = userData.value.filter(user => user.id !== e.id)
  327. }
  328. }
  329. let orderFormData = ref({
  330. amount: 1,
  331. type: 0,
  332. orderType: 0,
  333. productIds: null,
  334. familyIds: '',
  335. insureOrderInfoForm: {
  336. insureId: '',
  337. assertStartTime: '',
  338. assertEndTime: '',
  339. insurePriceId: '',
  340. familyMembersIds: '',
  341. }
  342. })
  343. const submitOrderImpl = () => {
  344. if (userData.value.length === 0) return TipsUtils.tips_toast('请添加成员')
  345. if (!rulesId.value) {
  346. return TipsUtils.tips_toast('请选择可用时段')
  347. }
  348. if (inventory.value === 0) return TipsUtils.tips_toast('余量不足,请选择其他时段')
  349. const selectedTimeSlot = timeList.value.timeSlot.find(item => item.id === rulesId.value)
  350. if (selectedTimeSlot && shouldGrayOut(selectedTimeSlot.endTime)) {
  351. return TipsUtils.tips_toast('所选时段已过期,请重新选择')
  352. }
  353. let data = { ...orderFormData.value };
  354. if (!insureData.value || insureData.value.length === 0) {
  355. delete data.insureOrderInfoForm;
  356. }
  357. http.post('/order/createOrder', data, { loading: true }).then((res) => {
  358. uni.requestSubscribeMessage({
  359. tmplIds: ['WSJjc9I24ijtr3EyNVXjEvTQm0gIECW9ABYVFcegOwM'],
  360. success(su) {
  361. TipsUtils.tips_toast('订阅成功')
  362. getOrderQuery(res.result.orderCode, res.result.orderId)
  363. },
  364. fail(err) {
  365. getOrderQuery(res.result.orderCode, res.result.orderId)
  366. console.log(err, '订阅消息失败')
  367. }
  368. })
  369. })
  370. }
  371. const submitBooking = debounce(submitOrderImpl, 500) //防抖
  372. // code编码 "100001支付成功";"100002查询失败"; "100003查询中 "; "100004支付失败"
  373. const getOrderQuery = (orderCode: string, orderId: string, retryCount = 0) => {
  374. http.get('/order/orderQuery', { data: { orderCode: orderCode }, loading: true }).then((res) => {
  375. if (res.result == '100001') {
  376. RouterUtils.to_page(`/pages/index/toBeUsed/index?orderId=${orderId}&orderType=${orderFormData.value.orderType}`)
  377. } else if (retryCount <= 3) {
  378. setTimeout(() => {
  379. getOrderQuery(orderCode, orderId, retryCount + 1)
  380. }, 1000)
  381. } else {
  382. if (res.result == '100003') {
  383. console.log('查询中,但已达到最大查询次数')
  384. } else if (res.result == '100002') {
  385. console.log('查询失败')
  386. } else if (res.result == '100004') {
  387. console.log('支付失败')
  388. TipsUtils.tips_toast('支付失败')
  389. }
  390. }
  391. }).catch((error) => {
  392. console.error('查询订单失败:', error)
  393. if (retryCount < 2) {
  394. setTimeout(() => {
  395. getOrderQuery(orderCode, orderId, retryCount + 1)
  396. }, 1000)
  397. }
  398. })
  399. }
  400. </script>
  401. <style lang="less" scoped>
  402. .s-header-card {
  403. background: #fff;
  404. padding: 20rpx;
  405. display: flex;
  406. align-items: center;
  407. gap: 10rpx;
  408. font-weight: bold;
  409. font-size: 28rpx;
  410. color: #222222;
  411. }
  412. .s-selectdate-card {
  413. margin-top: 20rpx;
  414. padding: 20rpx;
  415. background: linear-gradient(180deg, #FCFFF1 0%, #FFFFFF 100%);
  416. border-radius: 32rpx;
  417. .s-title {
  418. font-weight: bold;
  419. font-size: 28rpx;
  420. color: #222222;
  421. }
  422. .select-card-list {
  423. margin-top: 20rpx;
  424. display: flex;
  425. align-items: center;
  426. .scroll-view_H {
  427. white-space: nowrap;
  428. width: 90%;
  429. .item-card-select {
  430. margin-right: 16rpx;
  431. display: inline-block;
  432. width: 104rpx;
  433. height: 120rpx;
  434. background: #F0FFBB;
  435. border-radius: 16rpx;
  436. font-size: 24rpx;
  437. color: #222222;
  438. text-align: center;
  439. .day {
  440. padding-top: 20rpx;
  441. }
  442. .date {
  443. margin-top: 12rpx;
  444. }
  445. }
  446. .item-card {
  447. margin-right: 16rpx;
  448. display: inline-block;
  449. width: 104rpx;
  450. height: 120rpx;
  451. background: #F6F6F6;
  452. border-radius: 16rpx;
  453. font-size: 24rpx;
  454. color: #222222;
  455. text-align: center;
  456. .day {
  457. padding-top: 20rpx;
  458. }
  459. .date {
  460. margin-top: 12rpx;
  461. }
  462. }
  463. }
  464. .more-date {
  465. width: 200rpx;
  466. font-size: 24rpx;
  467. color: #FDD143;
  468. text-align: center;
  469. }
  470. }
  471. }
  472. .s-selecttime-card {
  473. margin-top: 20rpx;
  474. padding: 20rpx;
  475. background: linear-gradient(180deg, #FCFFF1 0%, #FFFFFF 100%);
  476. border-radius: 32rpx;
  477. .s-title {
  478. font-weight: bold;
  479. font-size: 28rpx;
  480. color: #222222;
  481. }
  482. .select-card-list {
  483. margin-top: 20rpx;
  484. .scroll-view_H {
  485. white-space: nowrap;
  486. width: 100%;
  487. .item-card {
  488. margin-right: 16rpx;
  489. display: inline-block;
  490. width: 220rpx;
  491. height: 172rpx;
  492. background: #F6F6F6;
  493. border-radius: 16rpx;
  494. text-align: center;
  495. .time {
  496. margin-top: 30rpx;
  497. font-size: 24rpx;
  498. color: #222222;
  499. }
  500. .allowance {
  501. margin-top: 12rpx;
  502. font-size: 24rpx;
  503. color: #222222;
  504. }
  505. .price {
  506. margin-top: 12rpx;
  507. font-weight: bold;
  508. font-size: 28rpx;
  509. color: #FB5B5B;
  510. }
  511. }
  512. }
  513. }
  514. }
  515. .r-insurance {
  516. margin-top: 20rpx;
  517. padding: 20rpx;
  518. background: #FFFFFF;
  519. border-radius: 32rpx;
  520. .r-insurance-infobox {
  521. display: flex;
  522. align-items: center;
  523. justify-content: space-between;
  524. gap: 20rpx;
  525. margin-bottom: 20rpx;
  526. .r-image-box {
  527. &>image {
  528. width: 200rpx;
  529. height: 200rpx;
  530. border-radius: 32rpx;
  531. }
  532. }
  533. .r-insurance-title {
  534. .r-insurance-name {
  535. display: flex;
  536. align-items: center;
  537. gap: 16rpx;
  538. .r-name {
  539. font-weight: 800;
  540. font-size: 28rpx;
  541. color: #222222;
  542. }
  543. .r-tags {
  544. width: 136rpx;
  545. height: 36rpx;
  546. background: #FDD143;
  547. border-radius: 8rpx;
  548. font-size: 22rpx;
  549. color: #222222;
  550. text-align: center;
  551. line-height: 36rpx;
  552. }
  553. }
  554. .r-insurance-desc {
  555. width: 440rpx;
  556. margin-top: 10rpx;
  557. font-size: 24rpx;
  558. color: #AAAAAA;
  559. }
  560. .r-insurance-type {
  561. margin-top: 10rpx;
  562. font-size: 24rpx;
  563. color: #AAAAAA;
  564. }
  565. .r-insurance-price {
  566. display: flex;
  567. align-items: center;
  568. justify-content: space-between;
  569. .r-price {
  570. font-weight: bold;
  571. font-size: 28rpx;
  572. color: #FB5B5B;
  573. }
  574. .r-insurance-btn {
  575. width: 200rpx;
  576. height: 68rpx;
  577. background: #C8FF0C;
  578. border-radius: 60rpx;
  579. font-weight: bold;
  580. font-size: 28rpx;
  581. color: #222222;
  582. text-align: center;
  583. line-height: 68rpx;
  584. }
  585. }
  586. }
  587. }
  588. .r-insurance-adduser {
  589. background: #F6F6F6;
  590. border-radius: 32rpx;
  591. padding: 20rpx;
  592. margin-top: 20rpx;
  593. .r-adduser-btn {
  594. display: flex;
  595. align-items: center;
  596. justify-content: flex-end;
  597. gap: 20rpx;
  598. .r-celar {
  599. width: 192rpx;
  600. height: 60rpx;
  601. background: #FFFFFF;
  602. border-radius: 60rpx;
  603. border: 2rpx solid #FB5B5B;
  604. font-weight: bold;
  605. font-size: 28rpx;
  606. color: #FB5B5B;
  607. text-align: center;
  608. line-height: 68rpx;
  609. }
  610. .r-edit {
  611. width: 200rpx;
  612. height: 68rpx;
  613. background: #C8FF0C;
  614. border-radius: 60rpx;
  615. font-weight: bold;
  616. font-size: 28rpx;
  617. color: #222222;
  618. text-align: center;
  619. line-height: 68rpx;
  620. }
  621. }
  622. .r-userinfo-list {
  623. .r-userinfo-item {
  624. display: flex;
  625. align-items: center;
  626. justify-content: space-between;
  627. margin-top: 20rpx;
  628. .r-item-title {
  629. font-size: 28rpx;
  630. color: #AAAAAA;
  631. }
  632. .r-item-info {
  633. font-size: 28rpx;
  634. color: #222222;
  635. }
  636. }
  637. }
  638. }
  639. }
  640. .g-userinfo-card {
  641. margin-top: 20rpx;
  642. padding: 20rpx;
  643. background: #FFFFFF;
  644. border-radius: 32rpx;
  645. .r-user {
  646. display: flex;
  647. align-items: center;
  648. justify-content: space-between;
  649. .user-title {
  650. font-weight: bold;
  651. font-size: 28rpx;
  652. color: #222222;
  653. }
  654. .invite {
  655. display: flex;
  656. align-items: center;
  657. gap: 8rpx;
  658. font-size: 24rpx;
  659. color: #AAAAAA;
  660. position: relative;
  661. .g-share-btn {
  662. position: absolute;
  663. width: 200rpx;
  664. height: 60rpx;
  665. opacity: 0;
  666. }
  667. }
  668. }
  669. .user-tags {
  670. margin-top: 20rpx;
  671. width: 112rpx;
  672. height: 40rpx;
  673. background: #FDD143;
  674. border-radius: 8rpx;
  675. line-height: 40rpx;
  676. font-weight: bold;
  677. font-size: 28rpx;
  678. color: #222222;
  679. text-align: center;
  680. font-size: 28rpx;
  681. color: #222222;
  682. }
  683. .r-user-list {
  684. margin-top: 20rpx;
  685. display: flex;
  686. align-items: center;
  687. gap: 20rpx;
  688. border-top: 1rpx solid #F0F0F0;
  689. height: 140rpx;
  690. .minus-user {
  691. width: 30rpx;
  692. height: 30rpx;
  693. border-radius: 50%;
  694. background: #FB5B5B;
  695. text-align: center;
  696. line-height: 20rpx;
  697. font-weight: 600;
  698. color: #fff;
  699. font-size: 40rpx;
  700. }
  701. .r-list {
  702. .name {
  703. font-weight: bold;
  704. font-size: 28rpx;
  705. color: #222222;
  706. }
  707. .id-num {
  708. font-size: 28rpx;
  709. color: #222222;
  710. }
  711. }
  712. }
  713. .g-adduser-btn {
  714. display: flex;
  715. height: 88rpx;
  716. align-items: center;
  717. justify-content: center;
  718. gap: 20rpx;
  719. border-top: 1rpx solid #F0F0F0;
  720. .add-icon {
  721. width: 30rpx;
  722. height: 30rpx;
  723. border-radius: 50%;
  724. background: #FDD143;
  725. font-size: 30rpx;
  726. font-weight: 600;
  727. color: #fff;
  728. text-align: center;
  729. line-height: 20rpx;
  730. }
  731. .add-text {
  732. font-size: 28rpx;
  733. color: #FDD143;
  734. }
  735. }
  736. }
  737. .submit-btn {
  738. margin-top: 20rpx;
  739. width: 100%;
  740. height: 100rpx;
  741. background: #C8FF0C;
  742. border-radius: 60rpx;
  743. font-weight: bold;
  744. font-size: 32rpx;
  745. color: #222222;
  746. text-align: center;
  747. line-height: 100rpx;
  748. }
  749. .r-center-popup {
  750. width: 646rpx;
  751. max-height: 1000rpx;
  752. background: #F6F6F6;
  753. border-radius: 32rpx;
  754. padding: 20rpx;
  755. .r-popup-title {
  756. font-weight: bold;
  757. font-size: 32rpx;
  758. color: #222222;
  759. text-align: center;
  760. }
  761. .r-popup-content {
  762. margin-top: 28rpx;
  763. font-size: 28rpx;
  764. color: #222222;
  765. max-height: 600rpx;
  766. overflow: auto;
  767. }
  768. .r-popup-footer {
  769. margin-top: 20rpx;
  770. .r-popup-needbtn {
  771. margin: auto;
  772. width: 598rpx;
  773. height: 100rpx;
  774. background: #C8FF0C;
  775. border-radius: 60rpx;
  776. font-weight: bold;
  777. font-size: 32rpx;
  778. color: #222222;
  779. text-align: center;
  780. line-height: 100rpx;
  781. }
  782. .r-popup-refusebtn {
  783. margin: auto;
  784. margin-top: 24rpx;
  785. width: 598rpx;
  786. height: 100rpx;
  787. background: #f0eeee;
  788. border-radius: 60rpx;
  789. font-weight: bold;
  790. font-size: 32rpx;
  791. color: #AAAAAA;
  792. text-align: center;
  793. line-height: 100rpx;
  794. }
  795. .r-popup-checkbox {
  796. margin-top: 20rpx;
  797. display: flex;
  798. align-items: center;
  799. justify-content: center;
  800. gap: 16rpx;
  801. font-size: 24rpx;
  802. color: #AAAAAA;
  803. &>text {
  804. margin-bottom: 8rpx;
  805. }
  806. }
  807. }
  808. }
  809. </style>