PageThree.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  1. <template>
  2. <view class="page-three-container">
  3. <!-- 支付信息卡片 -->
  4. <view class="info-card">
  5. <view class="info-card-title">支付信息</view>
  6. <u-row class="info-row" justify="space-between">
  7. <u-col span="5.8">
  8. <view class="info-label">开户人</view>
  9. <u-input v-model="paymentInfo.customName" placeholder="请输入开户人姓名" class="info-input"
  10. @blur="handleCustomNameInput" />
  11. </u-col>
  12. <u-col span="5.8">
  13. <view class="info-label">银行名称</view>
  14. <u-input v-model="paymentInfo.bankName" placeholder="请输入银行名称" class="info-input"
  15. @blur="handleBankNameInput" />
  16. </u-col>
  17. </u-row>
  18. <u-row class="info-row">
  19. <u-col span="12">
  20. <view class="info-label">银行账号</view>
  21. <u-input v-model="paymentInfo.bankAccount" placeholder="请输入银行账号" class="info-input" type="number"
  22. @input="handleBankAccountInput" />
  23. </u-col>
  24. </u-row>
  25. <u-row class="info-row">
  26. <u-col span="12">
  27. <view class="info-label">身份证号</view>
  28. <u-input v-model="paymentInfo.idNumber" placeholder="请输入身份证号" class="info-input" type="number"
  29. @input="handleIdNumberInput" />
  30. </u-col>
  31. </u-row>
  32. <u-row class="info-row">
  33. <u-col span="12">
  34. <view class="info-label">支付方式选择</view>
  35. <u-radio-group iconPlacement="left" v-model="paymentMethodRadio" placement="row"
  36. @change="handlePaymentMethodRadioChange">
  37. <u-radio shape="circle" label="小葫芦线上支付" name="online" />
  38. <u-radio shape="circle" label="线下支付" name="offline" />
  39. </u-radio-group>
  40. </u-col>
  41. </u-row>
  42. <u-row class="info-row">
  43. <u-col span="12">
  44. <view class="info-label">支付方式</view>
  45. <u-input :disabled="paymentMethodRadio === 'online'" v-model="paymentMethod" placeholder="请输入支付方式"
  46. class="info-input" />
  47. </u-col>
  48. </u-row>
  49. </view>
  50. <!-- 高清实物图卡片 -->
  51. <view class="card-wrap">
  52. <view class="detail-image-section">
  53. <view class="detail-image-header">
  54. <text class="detail-image-title">高清实物图(拖拽排序)</text>
  55. </view>
  56. <view class="detail-image-content">
  57. <view class="detail-image-list">
  58. <view v-for="(item, index) in displayImages" :key="item.id || `detail-${index}`" class="detail-image-item"
  59. :class="{
  60. 'dragging': draggingIndex === index,
  61. 'can-drop': canDropIndex === index && draggingIndex !== index
  62. }" :style="draggingIndex === index ? draggingStyle : ''" @touchstart.stop="onTouchStart($event, index)"
  63. @touchmove.stop="onTouchMove($event, index)" @touchend.stop="onTouchEnd">
  64. <PicComp :src="item.fileUrl" @needPreviewPic="previewImageDetail" />
  65. <view class="image-type-tag">{{ getImageType(index) }}</view>
  66. <view class="detail-delete-btn" @click.stop="handleHideImage(item, index)">
  67. ×
  68. </view>
  69. </view>
  70. <view class="detail-upload-btn" @click="handleUploadImage">
  71. <u-icon name="plus" size="40rpx" color="#999" />
  72. </view>
  73. </view>
  74. </view>
  75. </view>
  76. </view>
  77. <!-- 支付总额卡片 -->
  78. <view class="card-wrap payment-card">
  79. <view class="payment-section">
  80. <view class="payment-total-container">
  81. <text class="payment-label">支付总额</text>
  82. <u-input v-model="paymentAmount" class="payment-amount" type="number" decimal="2" prefix="¥" />
  83. </view>
  84. <view class="payment-buttons-row">
  85. <view class="payment-button" @click="handleUnpaidClick">
  86. <u-icon name="star" size="40rpx" color="#ff9500" />
  87. <text class="button-text">未收</text>
  88. </view>
  89. <view class="payment-button" @click="handleFollowUpClick">
  90. <u-icon name="chat" size="40rpx" color="#108cff" />
  91. <text class="button-text">待跟进</text>
  92. </view>
  93. </view>
  94. <view class="pay-now-button" @click="handlePayNowClick">
  95. <text class="button-text">立即支付</text>
  96. </view>
  97. </view>
  98. </view>
  99. <!-- 下一步按钮 -->
  100. <u-button class="next-btn" @click="handleNext" type="primary" size="middle">
  101. 下一步
  102. </u-button>
  103. <!-- 未收评级模态窗 -->
  104. <u-modal showCancelButton showConfirmButton @confirm="confirmUnpaid" @cancel="unpaidModalVisible = false"
  105. :show="unpaidModalVisible" title="未收评级">
  106. <view class="modal-content">
  107. <u-rate v-model="unpaidRating" :count="5" :size="50" active-color="#ff9500" />
  108. </view>
  109. </u-modal>
  110. <!-- 待跟进模态窗 -->
  111. <u-modal showCancelButton showConfirmButton @confirm="confirmFollowUp" @cancel="followUpModalVisible = false"
  112. :show="followUpModalVisible" title="填写跟进细节">
  113. <view class="modal-content">
  114. <u--textarea v-model="followUpNotes" placeholder="请输入情况" confirm-type="done"
  115. style="width: 100%; margin-bottom: 30rpx;" />
  116. </view>
  117. </u-modal>
  118. <!-- 确认支付模态窗 -->
  119. <u-modal :show="payNowModalVisible" title="确认支付信息" :showConfirmButton="false">
  120. <view class="modal-content">
  121. <view class="payment-amount-display">¥{{ paymentAmount }}</view>
  122. <view class="payment-info-section">
  123. <view class="info-item">
  124. <text class="info-label">收款姓名:</text>
  125. <text class="info-value">{{ paymentInfo.customName || '未填写' }}</text>
  126. </view>
  127. <view class="info-item">
  128. <text class="info-label">开户银行:</text>
  129. <text class="info-value">{{ paymentInfo.bankName || '未填写' }}</text>
  130. </view>
  131. <view class="info-item">
  132. <text class="info-label">银行卡号:</text>
  133. <text class="info-value">{{ paymentInfo.bankAccount || '未填写' }}</text>
  134. </view>
  135. <view class="info-item">
  136. <text class="info-label">支付方式:</text>
  137. <text class="info-value">{{ paymentMethod || '未填写' }}</text>
  138. </view>
  139. </view>
  140. <u-button type="primary" size="large" @click="confirmTransfer" style="margin-top: 40rpx;">
  141. 确认转账
  142. </u-button>
  143. <u-button type="primary" :plain="true" @click="payNowModalVisible = false" size="large"
  144. style="margin-top: 20rpx;">
  145. 取消
  146. </u-button>
  147. </view>
  148. </u-modal>
  149. </view>
  150. </template>
  151. <script>
  152. import PicComp from './PicComp.vue'
  153. import imageUpload from '../utils/imageUpload.js'
  154. export default {
  155. name: 'PageThree',
  156. components: {
  157. PicComp
  158. },
  159. props: {
  160. orderDetail: {
  161. type: Object,
  162. default: () => ({})
  163. },
  164. orderId: {
  165. type: String,
  166. default: ''
  167. },
  168. currentReceipt: {
  169. type: Object,
  170. default: () => ({})
  171. }
  172. },
  173. data() {
  174. return {
  175. paymentInfo: {
  176. customName: '',
  177. bankName: '',
  178. bankAccount: '',
  179. idNumber: ''
  180. },
  181. paymentMethodRadio: 'offline',
  182. paymentMethod: '',
  183. paymentAmount: '0.00',
  184. detailImages: [],
  185. // 拖拽相关
  186. draggingIndex: -1,
  187. canDropIndex: -1,
  188. startX: 0,
  189. startY: 0,
  190. currentX: 0,
  191. currentY: 0,
  192. // 模态窗
  193. unpaidModalVisible: false,
  194. followUpModalVisible: false,
  195. payNowModalVisible: false,
  196. unpaidRating: 0,
  197. followUpNotes: ''
  198. }
  199. },
  200. computed: {
  201. // 显示前6个图片用于拖拽
  202. displayImages() {
  203. return this.detailImages.slice(0, 6)
  204. },
  205. // 拖拽时的样式
  206. draggingStyle() {
  207. if (this.draggingIndex === -1) return ''
  208. return {
  209. transform: `translate(${this.currentX - this.startX}px, ${this.currentY - this.startY}px)`,
  210. zIndex: 1000
  211. }
  212. }
  213. },
  214. watch: {
  215. orderDetail: {
  216. handler(newVal) {
  217. if (newVal) {
  218. this.paymentInfo.customName = newVal.customName || ''
  219. this.paymentInfo.bankName = newVal.bankName || ''
  220. this.paymentInfo.bankAccount = newVal.bankCardNumber || ''
  221. this.paymentInfo.idNumber = newVal.idCard || ''
  222. this.initPaymentMethod(newVal.paymentMethod)
  223. }
  224. },
  225. deep: true,
  226. immediate: true
  227. },
  228. currentReceipt: {
  229. handler(newVal) {
  230. if (newVal) {
  231. this.paymentAmount = newVal.tableFee || '0.00'
  232. this.loadDetailImages()
  233. }
  234. },
  235. deep: true,
  236. immediate: true
  237. }
  238. },
  239. methods: {
  240. /**
  241. * 刷新图片列表(供父组件调用)
  242. */
  243. async refreshImageList() {
  244. await this.loadDetailImages()
  245. },
  246. /**
  247. * 加载细节图
  248. */
  249. async loadDetailImages() {
  250. if (!this.currentReceipt.id || !this.orderDetail.itemBrand) return
  251. try {
  252. const list = await imageUpload.getFileList(
  253. '2',
  254. '3',
  255. this.currentReceipt.id,
  256. this.orderDetail.itemBrand,
  257. this.currentReceipt.clueId
  258. )
  259. this.detailImages = list || []
  260. } catch (error) {
  261. console.error('加载细节图失败:', error)
  262. }
  263. },
  264. /**
  265. * 初始化支付方式
  266. */
  267. initPaymentMethod(value) {
  268. if (value === '小葫芦线上支付') {
  269. this.paymentMethod = '小葫芦线上支付'
  270. this.paymentMethodRadio = 'online'
  271. } else {
  272. this.paymentMethod = value || ''
  273. this.paymentMethodRadio = 'offline'
  274. }
  275. },
  276. /**
  277. * 支付方式选择改变
  278. */
  279. handlePaymentMethodRadioChange(value) {
  280. if (value === 'online') {
  281. this.paymentMethod = '小葫芦线上支付'
  282. } else {
  283. this.paymentMethod = ''
  284. }
  285. },
  286. /**
  287. * 开户人输入处理 - 只允许中文
  288. */
  289. handleCustomNameInput(value) {
  290. // 只保留中文字符(包括中文标点)
  291. const chineseReg = /[^\u4e00-\u9fa5]/g
  292. this.paymentInfo.customName = String(value || '').replace(chineseReg, '')
  293. },
  294. /**
  295. * 银行名称输入处理 - 只允许中文
  296. */
  297. handleBankNameInput(value) {
  298. // 只保留中文字符(包括中文标点)
  299. const chineseReg = /[^\u4e00-\u9fa5]/g
  300. this.paymentInfo.bankName = String(value || '').replace(chineseReg, '')
  301. },
  302. /**
  303. * 银行账号输入处理 - 只允许数字
  304. */
  305. handleBankAccountInput(value) {
  306. // 只保留数字
  307. const numberReg = /[^\d]/g
  308. this.paymentInfo.bankAccount = String(value || '').replace(numberReg, '')
  309. },
  310. /**
  311. * 身份证号输入处理 - 只允许数字
  312. */
  313. handleIdNumberInput(value) {
  314. // 只保留数字
  315. const numberReg = /[^\d]/g
  316. this.paymentInfo.idNumber = String(value || '').replace(numberReg, '')
  317. },
  318. /**
  319. * 获取图片类型
  320. */
  321. getImageType(index) {
  322. const types = ['正面', '反面', '侧面', '扣子', '编号']
  323. return types[index] || `细节${index - 4}`
  324. },
  325. /**
  326. * 触摸开始
  327. */
  328. onTouchStart(event, index) {
  329. if (this.draggingIndex !== -1) return
  330. this.draggingIndex = index
  331. const touch = event.touches[0]
  332. this.startX = touch.clientX
  333. this.startY = touch.clientY
  334. this.currentX = touch.clientX
  335. this.currentY = touch.clientY
  336. },
  337. /**
  338. * 触摸移动
  339. */
  340. onTouchMove(event, index) {
  341. if (this.draggingIndex === -1 || this.draggingIndex !== index) return
  342. const touch = event.touches[0]
  343. this.currentX = touch.clientX
  344. this.currentY = touch.clientY
  345. this.findTargetIndex(touch.clientX, touch.clientY)
  346. },
  347. /**
  348. * 触摸结束
  349. */
  350. async onTouchEnd() {
  351. if (this.draggingIndex === -1) return
  352. if (this.canDropIndex !== -1 && this.canDropIndex !== this.draggingIndex) {
  353. // 交换位置
  354. const images = [...this.detailImages]
  355. const temp = images[this.draggingIndex]
  356. images[this.draggingIndex] = images[this.canDropIndex]
  357. images[this.canDropIndex] = temp
  358. this.detailImages = images
  359. }
  360. this.resetDragState()
  361. //每次拖拽结束后把新的顺序传送给接口
  362. await uni.$u.api.updateReceiptForm({
  363. id: this.currentReceipt.id,
  364. fileIds: this.detailImages.map(item => item.id).join(',')
  365. })
  366. },
  367. /**
  368. * 查找目标索引
  369. */
  370. findTargetIndex(x, y) {
  371. const query = uni.createSelectorQuery().in(this)
  372. query.selectAll('.detail-image-item').boundingClientRect((rects) => {
  373. if (!rects || rects.length === 0) return
  374. let targetIndex = -1
  375. for (let i = 0; i < rects.length; i++) {
  376. if (i === this.draggingIndex) continue
  377. const rect = rects[i]
  378. if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
  379. targetIndex = i
  380. break
  381. }
  382. }
  383. this.canDropIndex = targetIndex
  384. }).exec()
  385. },
  386. /**
  387. * 重置拖拽状态
  388. */
  389. resetDragState() {
  390. this.draggingIndex = -1
  391. this.canDropIndex = -1
  392. this.startX = 0
  393. this.startY = 0
  394. this.currentX = 0
  395. this.currentY = 0
  396. },
  397. /**
  398. * 上传图片
  399. */
  400. async handleUploadImage() {
  401. try {
  402. const filePaths = await imageUpload.chooseImage(9)
  403. const uploadResults = await imageUpload.uploadFiles(filePaths)
  404. await imageUpload.bindOrderFile(
  405. this.currentReceipt.clueId,
  406. this.currentReceipt.id,
  407. '3',
  408. uploadResults
  409. )
  410. this.loadDetailImages()
  411. //上传新图片完成之后也要把新数据给接口
  412. await uni.$u.api.updateReceiptForm({
  413. id: this.currentReceipt.id,
  414. fileIds: this.detailImages.map(item => item.id).join(',')
  415. })
  416. } catch (error) {
  417. console.error('上传失败:', error)
  418. }
  419. },
  420. /**
  421. * 隐藏图片
  422. */
  423. handleHideImage(item, index) {
  424. const itemIndex = this.detailImages.findIndex(img => img.id === item.id || img.fileUrl === item.fileUrl)
  425. if (itemIndex !== -1) {
  426. this.detailImages.splice(itemIndex, 1)
  427. uni.$u.toast('图片已隐藏')
  428. }
  429. },
  430. /**
  431. * 预览图片
  432. */
  433. previewImageDetail(src) {
  434. const urlList = this.detailImages.map(item => item.fileUrl)
  435. uni.previewImage({
  436. urls: urlList,
  437. current: src
  438. })
  439. },
  440. /**
  441. * 未收点击
  442. */
  443. handleUnpaidClick() {
  444. this.unpaidModalVisible = true
  445. },
  446. /**
  447. * 待跟进点击
  448. */
  449. handleFollowUpClick() {
  450. this.followUpModalVisible = true
  451. },
  452. /**
  453. * 立即支付点击
  454. */
  455. async handlePayNowClick() {
  456. // 保存支付信息
  457. await uni.$u.api.updateReceiptForm({
  458. id: this.currentReceipt.id,
  459. tableFee: this.paymentAmount,
  460. fileIds: this.detailImages.map(item => item.id).join(',')
  461. })
  462. await uni.$u.api.updateClueOrderForm({
  463. id: this.orderDetail.id,
  464. customName: this.paymentInfo.customName || '',
  465. bankName: this.paymentInfo.bankName || '',
  466. bankCardNumber: this.paymentInfo.bankAccount || '',
  467. idCard: this.paymentInfo.idNumber || '',
  468. paymentMethod: this.paymentMethod || ''
  469. })
  470. if (!this.paymentInfo.customName || !this.paymentInfo.bankName ||
  471. !this.paymentInfo.bankAccount || !this.paymentInfo.idNumber || !this.paymentMethod) {
  472. uni.$u.toast('请填写完整的支付信息')
  473. return
  474. }
  475. if (this.paymentAmount <= 0) {
  476. uni.$u.toast('请填写正确的支付总额')
  477. return
  478. }
  479. this.payNowModalVisible = true
  480. },
  481. /**
  482. * 确认转账
  483. */
  484. confirmTransfer() {
  485. this.payNowModalVisible = false
  486. //如果是小葫芦线上刚支付就调用接口,如果不是小葫芦线上支付就不要调用接口,直接点击下一步
  487. if (this.paymentMethod === '小葫芦线上支付') {
  488. this.$emit('confirm-pay')
  489. } else {
  490. this.handleNext()
  491. }
  492. },
  493. /**
  494. * 确认未收
  495. */
  496. async confirmUnpaid() {
  497. try {
  498. await uni.$u.api.addOrderFollow({
  499. orderId: this.orderId,
  500. content: `未收评分_${this.unpaidRating}`
  501. })
  502. await uni.$u.api.oderForm({
  503. status: '4',
  504. id: this.orderId
  505. })
  506. uni.$u.toast('提交未收评级成功')
  507. this.unpaidModalVisible = false
  508. } catch (error) {
  509. console.error('提交失败:', error)
  510. uni.$u.toast('提交失败')
  511. }
  512. },
  513. /**
  514. * 确认跟进
  515. */
  516. async confirmFollowUp() {
  517. try {
  518. await uni.$u.api.addOrderFollow({
  519. orderId: this.orderId,
  520. content: `待跟进_${this.followUpNotes}`
  521. })
  522. uni.$u.toast('提交待跟进记录成功')
  523. this.followUpModalVisible = false
  524. this.followUpNotes = ''
  525. } catch (error) {
  526. console.error('提交失败:', error)
  527. uni.$u.toast('提交失败')
  528. }
  529. },
  530. /**
  531. * 下一步
  532. */
  533. async handleNext() {
  534. await uni.$u.api.updateReceiptForm({
  535. id: this.currentReceipt.id,
  536. tableFee: this.paymentAmount,
  537. fileIds: this.detailImages.map(item => item.id).join(',')
  538. })
  539. await uni.$u.api.updateClueOrderForm({
  540. id: this.orderDetail.id,
  541. customName: this.paymentInfo.customName || '',
  542. bankName: this.paymentInfo.bankName || '',
  543. bankCardNumber: this.paymentInfo.bankAccount || '',
  544. idCard: this.paymentInfo.idNumber || ''
  545. })
  546. this.$emit('save', {
  547. nowPage: 'formThree',
  548. form: {
  549. ...this.paymentInfo
  550. },
  551. fileIds: this.detailImages.map(item => item.id).join(',')
  552. })
  553. this.$emit('next', {
  554. nowPage: 'formThree',
  555. form: {
  556. ...this.paymentInfo
  557. }
  558. })
  559. }
  560. }
  561. }
  562. </script>
  563. <style scoped lang="scss">
  564. @import '../styles/common.scss';
  565. .page-three-container {
  566. @extend .page-container;
  567. padding-bottom: 100rpx;
  568. }
  569. .info-card {
  570. @extend .card-wrap;
  571. padding: 20rpx;
  572. margin-top: 20rpx;
  573. box-sizing: border-box;
  574. width: 100%;
  575. max-width: 100%;
  576. }
  577. .info-card-title {
  578. @include font-styles($size: title, $weight: bold, $color: primary);
  579. margin-bottom: 25rpx;
  580. padding-bottom: 15rpx;
  581. border-bottom: 1rpx solid map-get($colors, border);
  582. }
  583. .info-row {
  584. margin-bottom: 20rpx;
  585. }
  586. .info-label {
  587. @include font-styles($size: tiny, $weight: regular, $color: tertiary);
  588. margin-bottom: 8rpx;
  589. display: block;
  590. }
  591. .info-input {
  592. border-radius: 8rpx;
  593. border: 1rpx solid #e5e7eb;
  594. padding: 12rpx 16rpx;
  595. width: 100%;
  596. box-sizing: border-box;
  597. }
  598. .detail-image-section {
  599. padding: 20rpx;
  600. }
  601. .detail-image-header {
  602. display: flex;
  603. justify-content: space-between;
  604. align-items: center;
  605. margin-bottom: 20rpx;
  606. padding-bottom: 20rpx;
  607. border-bottom: 1rpx solid map-get($colors, border);
  608. }
  609. .detail-image-title {
  610. @include font-styles($size: content, $weight: bold, $color: primary);
  611. }
  612. .detail-image-list {
  613. display: flex;
  614. flex-wrap: wrap;
  615. gap: 20rpx;
  616. position: relative;
  617. }
  618. .detail-image-item {
  619. position: relative;
  620. width: 200rpx;
  621. height: 200rpx;
  622. touch-action: none;
  623. transition: transform 0.2s ease, opacity 0.2s ease;
  624. z-index: 1;
  625. box-sizing: border-box;
  626. &.dragging {
  627. opacity: 0.6;
  628. transform: scale(1.05);
  629. z-index: 999;
  630. box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.2);
  631. }
  632. &.can-drop {
  633. outline: 2rpx dashed #108cff;
  634. outline-offset: -2rpx;
  635. background-color: rgba(16, 140, 255, 0.1);
  636. border-radius: 8rpx;
  637. }
  638. }
  639. .image-type-tag {
  640. position: absolute;
  641. top: 10rpx;
  642. left: 10rpx;
  643. background-color: rgba(0, 0, 0, 0.6);
  644. color: white;
  645. padding: 5rpx 10rpx;
  646. border-radius: 12rpx;
  647. font-size: 22rpx;
  648. z-index: 1;
  649. }
  650. .detail-delete-btn {
  651. position: absolute;
  652. top: -10rpx;
  653. right: -10rpx;
  654. width: 40rpx;
  655. height: 40rpx;
  656. background-color: #ff4d4f;
  657. color: #fff;
  658. border-radius: 50%;
  659. display: flex;
  660. align-items: center;
  661. justify-content: center;
  662. font-weight: bold;
  663. z-index: 10;
  664. cursor: pointer;
  665. }
  666. .detail-upload-btn {
  667. width: 200rpx;
  668. height: 200rpx;
  669. border: 8rpx dashed #ddd;
  670. border-radius: 30rpx;
  671. display: flex;
  672. align-items: center;
  673. justify-content: center;
  674. background-color: #f9f9f9;
  675. cursor: pointer;
  676. }
  677. .payment-card {
  678. margin-top: 20rpx;
  679. }
  680. .payment-section {
  681. padding: 20rpx;
  682. }
  683. .payment-total-container {
  684. background-color: #f5f7fa;
  685. border: 2rpx solid #e5e7eb;
  686. border-radius: 12rpx;
  687. padding: 0rpx 30rpx;
  688. display: flex;
  689. align-items: center;
  690. justify-content: space-between;
  691. margin-bottom: 24rpx;
  692. }
  693. .payment-label {
  694. font-size: 36rpx;
  695. font-weight: 700;
  696. min-width: 140rpx;
  697. }
  698. .payment-amount {
  699. font-size: 48rpx;
  700. font-weight: 600;
  701. color: #f53f3f;
  702. width: auto;
  703. min-width: 150rpx;
  704. border: none;
  705. text-align: right !important;
  706. }
  707. .payment-buttons-row {
  708. display: flex;
  709. gap: 20rpx;
  710. margin-bottom: 24rpx;
  711. }
  712. .payment-button {
  713. flex: 1;
  714. border-radius: 12rpx;
  715. padding: 5rpx 0;
  716. display: flex;
  717. flex-direction: column;
  718. align-items: center;
  719. justify-content: center;
  720. background-color: #f5f7fa;
  721. border: 2rpx solid #e5e7eb;
  722. cursor: pointer;
  723. gap: 12rpx;
  724. }
  725. .pay-now-button {
  726. width: 100%;
  727. border-radius: 12rpx;
  728. padding: 32rpx 0;
  729. display: flex;
  730. flex-direction: column;
  731. align-items: center;
  732. justify-content: center;
  733. background-color: #108cff;
  734. color: #fff;
  735. cursor: pointer;
  736. box-shadow: 0 4rpx 12rpx rgba(16, 140, 255, 0.2);
  737. }
  738. .button-text {
  739. font-size: 28rpx;
  740. font-weight: 500;
  741. color: inherit;
  742. }
  743. .modal-content {
  744. width: 100%;
  745. padding: 40rpx 20rpx;
  746. display: flex;
  747. flex-direction: column;
  748. align-items: center;
  749. }
  750. .payment-amount-display {
  751. font-size: 64rpx;
  752. font-weight: bold;
  753. color: #108cff;
  754. text-align: center;
  755. margin-bottom: 40rpx;
  756. width: 100%;
  757. }
  758. .payment-info-section {
  759. width: 100%;
  760. background-color: #f5f7fa;
  761. border: 2rpx solid #e5e7eb;
  762. border-radius: 12rpx;
  763. padding: 30rpx 20rpx;
  764. margin-bottom: 40rpx;
  765. }
  766. .info-item {
  767. display: flex;
  768. margin-bottom: 20rpx;
  769. align-items: center;
  770. justify-content: space-between;
  771. &:last-child {
  772. margin-bottom: 0;
  773. }
  774. }
  775. .next-btn {
  776. position: fixed;
  777. bottom: 10rpx;
  778. left: 2.5%;
  779. width: 95%;
  780. height: 80rpx;
  781. line-height: 80rpx;
  782. text-align: center;
  783. border-radius: 20rpx;
  784. z-index: 1000;
  785. }
  786. </style>