综合办公系统
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.

declareList.vue 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
  1. <!--
  2. * @Author: ysh
  3. * @Date: 2025-08-04 11:04:25
  4. * @LastEditors: Please set LastEditors
  5. * @LastEditTime: 2025-08-08 09:15:18
  6. -->
  7. <template>
  8. <view class="container">
  9. <mescroll-uni ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption"
  10. :up="upOption" :fixed="false" :top="10" style="padding: 30rpx;">
  11. <view>
  12. <view v-for="(item, index) in declareList" :key="index" class="modern-card">
  13. <view class="modern-card-header">
  14. <view class="modern-card-title">
  15. <text class="project-number">{{ formatterProjectNumber(item) }}</text>
  16. <text class="project-name">{{ formatterProjectName(item) }}</text>
  17. </view>
  18. </view>
  19. <view class="modern-card-body">
  20. <view class="avatar-section">
  21. <view class="avatar">
  22. <text>{{ item.user && item.user.nickName ? item.user.nickName[0] : '' }}</text>
  23. </view>
  24. <view>
  25. <text class="applier-name">{{ item.user ? item.user.nickName : '' }}</text>
  26. <text class="dept-name">填报人</text>
  27. </view>
  28. </view>
  29. <view class="info-row">
  30. <text class="info-label">工作类别:</text>
  31. <text class="info-value">{{ item.workType }}</text>
  32. </view>
  33. <view class="info-row">
  34. <text class="info-label">工作项目:</text>
  35. <text class="info-value">{{ item.workItem }}</text>
  36. </view>
  37. <view class="info-row">
  38. <text class="info-label">工作内容:</text>
  39. <text class="info-value">{{ item.workContent }}</text>
  40. </view>
  41. <view class="info-row">
  42. <text class="info-label">工作时间:</text>
  43. <text class="info-value">{{ item.beginDate }} ~ {{ item.endDate }}</text>
  44. </view>
  45. <view class="info-row">
  46. <text class="info-label">工天数量:</text>
  47. <text class="info-value">{{ item.workLoad }}天</text>
  48. </view>
  49. <view class="info-row">
  50. <text class="info-label">工天单价:</text>
  51. <text>{{ item.price }}</text>
  52. </view>
  53. <view class="info-row">
  54. <text class="info-label">系数:</text>
  55. <text class="info-value">{{ item.coefficient }}</text>
  56. </view>
  57. <view class="info-row">
  58. <text class="info-label">预估绩效:</text>
  59. <text class="amount-highlight">¥{{ predictMoney(item) }}</text>
  60. </view>
  61. <view class="info-row">
  62. <text class="info-label">填报时间:</text>
  63. <text class="info-value">{{ parseTime(item.submitTime, '{y}-{m}-{d}') }}</text>
  64. </view>
  65. <!-- 审核状态 -->
  66. <view class="status-section">
  67. <view class="status-item">
  68. <text class="status-label">一审:</text>
  69. <view class="status-tag" :class="formatFn(item, 'checkStatus') ? 'success' : 'warning'">
  70. <text>{{ formatFn(item, 'checkStatus') ? '已通过' : '待审核' }}</text>
  71. </view>
  72. </view>
  73. <view class="status-item">
  74. <text class="status-label">二审:</text>
  75. <view class="status-tag" :class="formatFn(item, 'auditStatus') ? 'success' : 'warning'">
  76. <text>{{ formatFn(item, 'auditStatus') ? '已通过' : '待审核' }}</text>
  77. </view>
  78. </view>
  79. <view class="status-item">
  80. <text class="status-label">确认:</text>
  81. <view class="status-tag" :class="formatFn(item, 'confirmStatus') ? 'success' : 'warning'">
  82. <text>{{ formatFn(item, 'confirmStatus') ? '已确认' : '待确认' }}</text>
  83. </view>
  84. </view>
  85. </view>
  86. </view>
  87. <view class="modern-card-footer">
  88. <button class="footer-btn detail-btn" @click="openFormInfo(item)">表单信息</button>
  89. <button class="footer-btn form-btn" @click="handleUpdate(item)">修改</button>
  90. </view>
  91. </view>
  92. </view>
  93. </mescroll-uni>
  94. <!-- 修改对话框 -->
  95. <uni-popup ref="updatePopup" type="center" :mask-click="false">
  96. <view class="update-dialog">
  97. <view class="dialog-header">
  98. <text class="dialog-title">修改工作填报</text>
  99. <text class="dialog-close" @click="closeUpdateDialog">×</text>
  100. </view>
  101. <view class="dialog-body">
  102. <!-- 只读信息 -->
  103. <view class="readonly-section">
  104. <view class="info-item">
  105. <text class="info-label">项目编号:</text>
  106. <text class="info-value">{{ updateForm.projectNumber }}</text>
  107. </view>
  108. <view class="info-item">
  109. <text class="info-label">项目名称:</text>
  110. <text class="info-value">{{ updateForm.projectName }}</text>
  111. </view>
  112. <view class="info-item">
  113. <text class="info-label">填报人:</text>
  114. <text class="info-value">{{ updateForm.nickName }}</text>
  115. </view>
  116. <view class="info-item">
  117. <text class="info-label">工作类别:</text>
  118. <text class="info-value">{{ updateForm.workType }}</text>
  119. </view>
  120. <view class="info-item">
  121. <text class="info-label">工作项目:</text>
  122. <text class="info-value">{{ updateForm.workItem }}</text>
  123. </view>
  124. <view class="info-item">
  125. <text class="info-label">工作内容:</text>
  126. <text class="info-value">{{ updateForm.workContent }}</text>
  127. </view>
  128. <view class="info-item">
  129. <text class="info-label">工作时间:</text>
  130. <text class="info-value">{{ updateForm.beginDate }} ~ {{ updateForm.endDate }}</text>
  131. </view>
  132. <view class="info-item">
  133. <text class="info-label">工天数量:</text>
  134. <text class="info-value">{{ updateForm.workLoad }}天</text>
  135. </view>
  136. <view class="info-item">
  137. <text class="info-label">工天单价:</text>
  138. <text class="info-value">¥{{ updateForm.price }}</text>
  139. </view>
  140. </view>
  141. <!-- 可修改的系数 -->
  142. <view class="edit-section">
  143. <view class="form-item">
  144. <text class="form-label">系数:</text>
  145. <uni-easyinput class="form-input" type="number" v-model="updateForm.coefficient"
  146. @input="calculatePredictMoney" @confirm="confirmUpdate" placeholder="请输入系数" :clearable="false"
  147. :trim="true" />
  148. </view>
  149. <!-- 预估绩效显示 -->
  150. <view class="predict-section">
  151. <text class="predict-label">预估绩效:</text>
  152. <text class="predict-amount">¥{{ predictMoney(updateForm) }}</text>
  153. </view>
  154. </view>
  155. </view>
  156. <view class="dialog-footer">
  157. <button class="dialog-btn cancel-btn" @click="closeUpdateDialog">取消</button>
  158. <button class="dialog-btn confirm-btn" @click="confirmUpdate">确认修改</button>
  159. </view>
  160. </view>
  161. </uni-popup>
  162. </view>
  163. </template>
  164. <script>
  165. import { listDeclare, getDeclare, updateDeclare } from '@/api/oa/declare/declare';
  166. import MescrollMixin from '@/uni_modules/mescroll/components/mescroll-uni/mescroll-mixins.js'
  167. export default {
  168. mixins: [MescrollMixin],
  169. data() {
  170. return {
  171. mescroll: null, // mescroll实例
  172. downOption: {
  173. auto: true,
  174. textOutOffset: '下拉刷新',
  175. textLoading: '加载中...'
  176. },
  177. upOption: {
  178. auto: false,
  179. page: { num: 1, size: 10 },
  180. noMoreSize: 5,
  181. empty: { tip: '暂无工作填报数据' },
  182. textNoMore: '~ 没有更多数据了 ~'
  183. },
  184. declareList: [],
  185. queryParams: {
  186. pageNum: 1,
  187. pageSize: 10,
  188. projectId: null,
  189. userId: null,
  190. submitTime: null
  191. },
  192. // 修改表单数据
  193. updateForm: {
  194. formId: null,
  195. workType: '',
  196. workItem: '',
  197. workContent: '',
  198. beginDate: '',
  199. endDate: '',
  200. workLoad: 0,
  201. price: 0,
  202. coefficient: 0
  203. }
  204. }
  205. },
  206. onLoad: function (options) {
  207. uni.startPullDownRefresh();
  208. },
  209. methods: {
  210. // 加载数据
  211. async loadData() {
  212. try {
  213. // 权限控制逻辑
  214. if (this.$store.getters.deptId > 103) {
  215. this.queryParams.deptId = this.$store.getters.deptId;
  216. }
  217. if (this.$store.getters.roles.includes('projectLeader')) {
  218. this.queryParams.projectLeader = this.$store.getters.userId
  219. }
  220. if (this.$store.getters.roles.includes('dept')) {
  221. this.queryParams.projectLeader = null
  222. }
  223. if (this.$store.getters.userId == 1) {
  224. this.queryParams.deptId = null
  225. this.queryParams.projectLeader = null
  226. }
  227. const res = await listDeclare(this.queryParams)
  228. return { data: res.rows, total: res.total }
  229. } catch (e) {
  230. return { data: [], error: true }
  231. }
  232. },
  233. mescrollInit(mescroll) {
  234. this.mescroll = mescroll;
  235. },
  236. // mescroll下拉刷新回调
  237. async downCallback() {
  238. this.declareList = []; // 清空列表
  239. this.queryParams.pageNum = 1
  240. const res = await this.loadData()
  241. if (res.error) {
  242. this.mescroll.endErr();
  243. } else {
  244. this.declareList = res.data;
  245. this.mescroll.endSuccess(res.data.length, res.total);
  246. }
  247. uni.stopPullDownRefresh();
  248. },
  249. // mescroll上拉加载回调
  250. async upCallback(page) {
  251. this.queryParams.pageNum = page.num
  252. const res = await this.loadData()
  253. if (res.error) {
  254. this.mescroll.endErr();
  255. } else {
  256. this.declareList = this.declareList.concat(res.data)
  257. this.mescroll.endSuccess(res.data.length, res.total);
  258. }
  259. },
  260. // 格式化项目编号
  261. formatterProjectNumber(row) {
  262. if (!row.projectId) {
  263. return '无'
  264. } else {
  265. return row.project.projectNumber
  266. }
  267. },
  268. // 格式化项目名称
  269. formatterProjectName(row) {
  270. if (!row.projectId) {
  271. let year = row.submitTime.substring(0, 4)
  272. return year + '年借调、零星项目'
  273. } else {
  274. return row.project.projectName
  275. }
  276. },
  277. // 格式化状态
  278. formatFn(row, type) {
  279. if (row[type] && row[type] == '1') {
  280. return true
  281. } else {
  282. return false
  283. }
  284. },
  285. // 计算预估绩效
  286. predictMoney(row) {
  287. try {
  288. const price = parseFloat(row.price) || 0
  289. const workLoad = parseFloat(row.workLoad) || 0
  290. const coefficient = parseFloat(row.coefficient) || 0
  291. let result = price * workLoad * coefficient
  292. return result.toFixed(2)
  293. } catch (error) {
  294. console.log('计算预估绩效失败:', error)
  295. return '0.00'
  296. }
  297. },
  298. // 时间解析函数
  299. parseTime(time, cFormat) {
  300. if (!time) return ''
  301. const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  302. let date
  303. if (typeof time === 'object') {
  304. date = time
  305. } else {
  306. if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
  307. time = parseInt(time)
  308. }
  309. date = new Date(time)
  310. }
  311. const formatObj = {
  312. y: date.getFullYear(),
  313. m: date.getMonth() + 1,
  314. d: date.getDate(),
  315. h: date.getHours(),
  316. i: date.getMinutes(),
  317. s: date.getSeconds(),
  318. a: date.getDay()
  319. }
  320. const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
  321. const value = formatObj[key]
  322. if (key === 'a') {
  323. return ['日', '一', '二', '三', '四', '五', '六'][value]
  324. }
  325. return value.toString().padStart(2, '0')
  326. })
  327. return time_str
  328. },
  329. // 打开表单信息
  330. openFormInfo(item) {
  331. uni.navigateTo({
  332. url: `/pages/components/formInfo?formId=${item.formId}&formType=declare`
  333. });
  334. },
  335. // 修改操作
  336. handleUpdate(item) {
  337. console.log(item)
  338. // 填充修改表单数据
  339. this.updateForm = {
  340. formId: item.formId,
  341. projectNumber: item.project.projectNumber,
  342. projectName: item.project.projectName,
  343. nickName: item.user.nickName,
  344. workType: item.workType,
  345. workItem: item.workItem,
  346. workContent: item.workContent,
  347. beginDate: item.beginDate,
  348. endDate: item.endDate,
  349. workLoad: item.workLoad,
  350. price: item.price,
  351. coefficient: item.coefficient
  352. }
  353. // 打开修改对话框
  354. this.$refs.updatePopup.open()
  355. // 延迟聚焦到系数输入框(移动端兼容)
  356. this.$nextTick(() => {
  357. setTimeout(() => {
  358. try {
  359. // 查找uni-easyinput内部的input元素
  360. const input = document.querySelector('.form-input .uni-easyinput__content-input')
  361. if (input && typeof input.focus === 'function') {
  362. input.focus()
  363. }
  364. } catch (error) {
  365. console.log('聚焦输入框失败:', error)
  366. }
  367. }, 300)
  368. })
  369. },
  370. // 关闭修改对话框
  371. closeUpdateDialog() {
  372. this.$refs.updatePopup.close()
  373. },
  374. // 计算预估绩效(当系数改变时)
  375. calculatePredictMoney() {
  376. // 系数输入时自动触发计算,这里不需要额外处理
  377. // 因为模板中已经绑定了 predictMoney(updateForm)
  378. },
  379. // 确认修改
  380. async confirmUpdate() {
  381. try {
  382. // 验证系数
  383. if (!this.updateForm.coefficient || this.updateForm.coefficient <= 0) {
  384. uni.showToast({
  385. title: '请输入有效的系数',
  386. icon: 'none'
  387. })
  388. return
  389. }
  390. // 显示加载状态
  391. uni.showLoading({
  392. title: '修改中...'
  393. })
  394. // 调用更新接口
  395. await updateDeclare(this.updateForm)
  396. // 隐藏加载状态
  397. uni.hideLoading()
  398. uni.showToast({
  399. title: '修改成功',
  400. icon: 'success'
  401. })
  402. // 关闭对话框
  403. this.closeUpdateDialog()
  404. // 刷新列表
  405. this.downCallback()
  406. } catch (error) {
  407. // 隐藏加载状态
  408. uni.hideLoading()
  409. console.error('修改失败:', error)
  410. uni.showToast({
  411. title: '修改失败,请重试',
  412. icon: 'none'
  413. })
  414. }
  415. }
  416. }
  417. }
  418. </script>
  419. <style lang="scss" scoped>
  420. .container {
  421. padding: 20rpx;
  422. background-color: #f5f5f5;
  423. height: 100vh;
  424. display: flex;
  425. flex-direction: column;
  426. }
  427. .modern-card {
  428. background: #fff;
  429. border-radius: 18rpx;
  430. margin-bottom: 32rpx;
  431. box-shadow: 0 6rpx 16rpx rgba(0, 0, 0, 0.08);
  432. overflow: hidden;
  433. transition: box-shadow 0.2s;
  434. border: 1rpx solid #f0f0f0;
  435. }
  436. .modern-card-header {
  437. display: flex;
  438. justify-content: space-between;
  439. align-items: center;
  440. background: linear-gradient(90deg, #e0e7ff 0%, #f8fafc 100%);
  441. padding: 24rpx 28rpx 16rpx 28rpx;
  442. }
  443. .modern-card-title {
  444. display: flex;
  445. flex-direction: column;
  446. }
  447. .project-number {
  448. font-size: 26rpx;
  449. color: #6366f1;
  450. font-weight: 600;
  451. }
  452. .project-name {
  453. font-size: 28rpx;
  454. color: #22223b;
  455. font-weight: bold;
  456. margin-top: 4rpx;
  457. }
  458. .amount-highlight {
  459. background: #fef3c7;
  460. color: #d97706;
  461. font-size: 28rpx;
  462. font-weight: bold;
  463. border-radius: 10rpx;
  464. padding: 8rpx 20rpx;
  465. min-width: 120rpx;
  466. text-align: center;
  467. }
  468. .amount-highlight-detail {
  469. background: #fef3c7;
  470. color: #d97706;
  471. font-size: 28rpx;
  472. font-weight: bold;
  473. border-radius: 10rpx;
  474. padding: 4rpx 18rpx;
  475. margin-left: 8rpx;
  476. }
  477. .modern-card-body {
  478. padding: 20rpx 28rpx 24rpx 28rpx;
  479. }
  480. .avatar-section {
  481. display: flex;
  482. align-items: center;
  483. margin-bottom: 18rpx;
  484. }
  485. .avatar {
  486. width: 56rpx;
  487. height: 56rpx;
  488. border-radius: 50%;
  489. background: #a5b4fc;
  490. color: #fff;
  491. display: flex;
  492. align-items: center;
  493. justify-content: center;
  494. font-size: 28rpx;
  495. font-weight: bold;
  496. margin-right: 18rpx;
  497. }
  498. .applier-name {
  499. font-size: 28rpx;
  500. color: #22223b;
  501. font-weight: 500;
  502. }
  503. .dept-name {
  504. font-size: 24rpx;
  505. color: #64748b;
  506. margin-left: 8rpx;
  507. }
  508. .info-row {
  509. display: flex;
  510. margin-bottom: 10rpx;
  511. }
  512. .info-label {
  513. color: #64748b;
  514. font-size: 24rpx;
  515. min-width: 120rpx;
  516. }
  517. .info-value {
  518. color: #22223b;
  519. font-size: 24rpx;
  520. flex: 1;
  521. word-break: break-all;
  522. }
  523. // 审核状态样式
  524. .status-section {
  525. margin-top: 16rpx;
  526. padding-top: 16rpx;
  527. border-top: 1px solid #f0f0f0;
  528. }
  529. .status-item {
  530. display: flex;
  531. align-items: center;
  532. margin-bottom: 8rpx;
  533. }
  534. .status-label {
  535. color: #64748b;
  536. font-size: 24rpx;
  537. min-width: 80rpx;
  538. }
  539. .status-tag {
  540. padding: 4rpx 12rpx;
  541. border-radius: 6rpx;
  542. font-size: 22rpx;
  543. margin-left: 8rpx;
  544. }
  545. .status-tag.success {
  546. background: #dcfce7;
  547. color: #16a34a;
  548. }
  549. .status-tag.warning {
  550. background: #fef3c7;
  551. color: #d97706;
  552. }
  553. .modern-card-footer {
  554. display: flex;
  555. justify-content: flex-end;
  556. gap: 20rpx;
  557. padding: 16rpx 28rpx 20rpx 28rpx;
  558. border-top: 1px solid #f0f0f0;
  559. background: #fafbfc;
  560. }
  561. .footer-btn {
  562. font-size: 26rpx;
  563. border-radius: 8rpx;
  564. border: none;
  565. outline: none;
  566. background: #e0e7ff;
  567. color: #3b3b4f;
  568. }
  569. .detail-btn {
  570. background: #6366f1;
  571. color: #fff;
  572. }
  573. .form-btn {
  574. background: #f4c542;
  575. color: #fff;
  576. }
  577. // 修改对话框样式
  578. .update-dialog {
  579. background: #fff;
  580. border-radius: 20rpx;
  581. width: 600rpx;
  582. max-height: 80vh;
  583. overflow: hidden;
  584. }
  585. .dialog-header {
  586. display: flex;
  587. justify-content: space-between;
  588. align-items: center;
  589. padding: 32rpx 32rpx 24rpx 32rpx;
  590. border-bottom: 1px solid #f0f0f0;
  591. background: linear-gradient(90deg, #e0e7ff 0%, #f8fafc 100%);
  592. }
  593. .dialog-title {
  594. font-size: 32rpx;
  595. font-weight: bold;
  596. color: #22223b;
  597. }
  598. .dialog-close {
  599. font-size: 40rpx;
  600. color: #64748b;
  601. cursor: pointer;
  602. padding: 8rpx;
  603. }
  604. .dialog-body {
  605. padding: 32rpx;
  606. max-height: 60vh;
  607. overflow-y: auto;
  608. }
  609. .readonly-section {
  610. margin-bottom: 32rpx;
  611. padding-bottom: 24rpx;
  612. border-bottom: 1px solid #f0f0f0;
  613. }
  614. .info-item {
  615. display: flex;
  616. margin-bottom: 16rpx;
  617. }
  618. .edit-section {
  619. padding-top: 16rpx;
  620. }
  621. .form-item {
  622. display: flex;
  623. align-items: center;
  624. margin-bottom: 24rpx;
  625. }
  626. .form-label {
  627. color: #64748b;
  628. font-size: 28rpx;
  629. min-width: 120rpx;
  630. }
  631. // uni-easyinput 样式调整
  632. :deep(.uni-easyinput) {
  633. flex: 1;
  634. .uni-easyinput__content {
  635. border: 1px solid #e2e8f0 !important;
  636. border-radius: 8rpx !important;
  637. background: #fff !important;
  638. padding: 16rpx 20rpx !important;
  639. }
  640. .uni-easyinput__content-input {
  641. border: none !important;
  642. background: transparent !important;
  643. font-size: 28rpx !important;
  644. color: #22223b !important;
  645. }
  646. .uni-easyinput__content:focus-within {
  647. border-color: #6366f1 !important;
  648. }
  649. }
  650. .predict-section {
  651. display: flex;
  652. align-items: center;
  653. background: #fef3c7;
  654. padding: 20rpx;
  655. border-radius: 12rpx;
  656. margin-top: 16rpx;
  657. }
  658. .predict-label {
  659. color: #d97706;
  660. font-size: 28rpx;
  661. font-weight: 500;
  662. }
  663. .predict-amount {
  664. color: #d97706;
  665. font-size: 32rpx;
  666. font-weight: bold;
  667. margin-left: 16rpx;
  668. }
  669. .dialog-footer {
  670. display: flex;
  671. justify-content: flex-end;
  672. gap: 20rpx;
  673. padding: 24rpx 32rpx 32rpx 32rpx;
  674. border-top: 1px solid #f0f0f0;
  675. background: #fafbfc;
  676. }
  677. .dialog-btn {
  678. font-size: 28rpx;
  679. border-radius: 8rpx;
  680. border: none;
  681. outline: none;
  682. padding: 16rpx 32rpx;
  683. cursor: pointer;
  684. }
  685. .cancel-btn {
  686. background: #f1f5f9;
  687. color: #64748b;
  688. }
  689. .confirm-btn {
  690. background: #6366f1;
  691. color: #fff;
  692. }
  693. .confirm-btn:hover {
  694. background: #4f46e5;
  695. }
  696. </style>