PageThree.vue 23 KB

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