approvalTaskDetail.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  1. <template>
  2. <view class="container">
  3. <view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
  4. <view class="top">
  5. <image class="return" @click="goBack" src="/static/image/back_white.png"></image>
  6. <text>任务详情</text>
  7. </view>
  8. <scroll-view class="content" scroll-y>
  9. <!-- 审核表单(根据类型动态渲染) -->
  10. <view v-if="auditData">
  11. <!-- 只有完成任务审核和创建任务审核才涉及文章、短视频、长视频 -->
  12. <view v-if="businessType === 'ADUIT_WCRWSH' || businessType === 'ADUIT_CJRW'">
  13. <!-- 短视频审核 -->
  14. <ShortVideoAudit v-if="auditData.shortVideoData" :data="auditData.shortVideoData" />
  15. <!-- 长视频审核 -->
  16. <LongVideoAudit v-else-if="auditData.longVideoData" :data="auditData.longVideoData" />
  17. <!-- 文章审核 -->
  18. <ArticleAudit v-else-if="auditData.articleData" :data="auditData.articleData" />
  19. </view>
  20. <!-- 讲者审核 -->
  21. <SpeakerAudit v-else-if="businessType === 'ADUIT_JZSH'" :data="{ docterVO: auditData.docterVO, companyUserVO: auditData.companyUserVO }" />
  22. <!-- 提现审核 -->
  23. <WithdrawAudit v-else-if="businessType === 'ADUIT_TXSH'" :data="auditData.withdrawData" />
  24. <!-- 服务单生成配置模板审核 -->
  25. <view v-else-if="businessType === 'AUDIT_FWDRWSCPZ'" class="info-section">
  26. <view class="section-header">
  27. <view class="section-indicator"></view>
  28. <text class="section-title">服务单生成配置模板信息</text>
  29. </view>
  30. <view class="info-list">
  31. <view class="info-item">
  32. <text class="info-label">任务编号</text>
  33. <text class="info-value">{{ auditData.auditTaskInfoVO && auditData.auditTaskInfoVO.taskNo ? auditData.auditTaskInfoVO.taskNo : '-' }}</text>
  34. </view>
  35. <view class="info-item">
  36. <text class="info-label">任务名称</text>
  37. <text class="info-value">{{ auditData.auditTaskInfoVO && auditData.auditTaskInfoVO.taskName ? auditData.auditTaskInfoVO.taskName : '-' }}</text>
  38. </view>
  39. <view class="info-item">
  40. <text class="info-label">项目名称</text>
  41. <text class="info-value">{{ auditData.auditTaskInfoVO && auditData.auditTaskInfoVO.projectName ? auditData.auditTaskInfoVO.projectName : '-' }}</text>
  42. </view>
  43. <view class="info-item">
  44. <text class="info-label">归属部门</text>
  45. <text class="info-value">{{ auditData.auditTaskInfoVO && auditData.auditTaskInfoVO.deptName ? auditData.auditTaskInfoVO.deptName : '-' }}</text>
  46. </view>
  47. <view class="info-item">
  48. <text class="info-label">归属类型</text>
  49. <text class="info-value">{{ auditData.auditTaskInfoVO && auditData.auditTaskInfoVO.belongTypeName ? auditData.auditTaskInfoVO.belongTypeName : '-' }}</text>
  50. </view>
  51. <view class="info-item">
  52. <text class="info-label">任务数量</text>
  53. <text class="info-value">{{ auditData.auditTaskInfoVO && auditData.auditTaskInfoVO.taskCount ? auditData.auditTaskInfoVO.taskCount : '-' }}</text>
  54. </view>
  55. <view class="info-item">
  56. <text class="info-label">任务积分</text>
  57. <text class="info-value">{{ auditData.auditTaskInfoVO && auditData.auditTaskInfoVO.taskIntegral ? auditData.auditTaskInfoVO.taskIntegral : '-' }}</text>
  58. </view>
  59. <view class="info-item">
  60. <text class="info-label">计划开始时间</text>
  61. <text class="info-value">{{ auditData.auditTaskInfoVO && auditData.auditTaskInfoVO.planStartTime ? auditData.auditTaskInfoVO.planStartTime : '-' }}</text>
  62. </view>
  63. <view class="info-item">
  64. <text class="info-label">计划结束时间</text>
  65. <text class="info-value">{{ auditData.auditTaskInfoVO && auditData.auditTaskInfoVO.planEndTime ? auditData.auditTaskInfoVO.planEndTime : '-' }}</text>
  66. </view>
  67. <view class="info-item">
  68. <text class="info-label">申请人</text>
  69. <text class="info-value">{{ auditData.auditTaskInfoVO && auditData.auditTaskInfoVO.companyUserName ? auditData.auditTaskInfoVO.companyUserName : '-' }}</text>
  70. </view>
  71. </view>
  72. <!-- 审核流程信息 -->
  73. <view class="info-section" v-if="auditData.auditFlowVO && auditData.auditFlowVO.length > 0">
  74. <view class="section-header">
  75. <view class="section-indicator"></view>
  76. <text class="section-title">审核流程信息</text>
  77. </view>
  78. <view class="flow-list">
  79. <view v-for="(flow, index) in auditData.auditFlowVO" :key="index" class="flow-item">
  80. <view class="flow-step">
  81. <view class="step-number">{{ flow.stepNumber }}</view>
  82. <view class="step-line" v-if="index < auditData.auditFlowVO.length - 1"></view>
  83. </view>
  84. <view class="flow-content">
  85. <view class="flow-header">
  86. <text class="flow-title">{{ flow.stepDescription }}</text>
  87. <text class="flow-status" :class="{'status-pending': flow.status === 1, 'status-completed': flow.status === 2, 'status-submitted': flow.status === 0}">{{ flow.statusName }}</text>
  88. </view>
  89. <view class="flow-info">
  90. <text>审核人:{{ flow.auditUserName || '-' }}</text>
  91. </view>
  92. <view class="flow-info" v-if="flow.auditTime">
  93. <text>审核时间:{{ flow.auditTime }}</text>
  94. </view>
  95. <view class="flow-info" v-if="flow.comment">
  96. <text>审核意见:{{ flow.comment }}</text>
  97. </view>
  98. </view>
  99. </view>
  100. </view>
  101. </view>
  102. </view>
  103. </view>
  104. </scroll-view>
  105. <view class="bottom-bar">
  106. <view class="action-buttons">
  107. <view class="btn btn-cancel" @click="openRejectPopup">
  108. <image class="icon" src="/static/image/icon_approval_no.png"></image>
  109. <text>驳回</text>
  110. </view>
  111. <view class="btn btn-submit" @click="handleNext">
  112. <image class="icon" src="/static/image/icon_approval_yes.png"></image>
  113. <text>通过</text>
  114. </view>
  115. </view>
  116. </view>
  117. <!-- 驳回弹窗 -->
  118. <u-popup :show="showRejectPopup" mode="bottom" round="24" z-index="9999999">
  119. <view class="reject-popup-content">
  120. <view class="popup-header">
  121. <text class="popup-title">驳回</text>
  122. <image @click="showRejectPopup = false;" class="close" src="/static/image/icon_close.png"></image>
  123. </view>
  124. <view class="input-area">
  125. <textarea v-model="rejectReason" placeholder="请输入驳回意见" class="reason-input" :auto-height="true"
  126. maxlength="200" />
  127. </view>
  128. <view class="btn-group">
  129. <view class="button reject" @click="showRejectPopup = false">取消</view>
  130. <view class="button confirm" @click="handleConfirmReject ">确认驳回</view>
  131. </view>
  132. </view>
  133. </u-popup>
  134. </view>
  135. </template>
  136. <script>
  137. import { doAudit, getAuditFlows, getTaskFinishAuditInfo } from '@/api/audit.js'
  138. import ShortVideoAudit from './components/ShortVideoAudit.vue'
  139. import LongVideoAudit from './components/LongVideoAudit.vue'
  140. import ArticleAudit from './components/ArticleAudit.vue'
  141. import SpeakerAudit from './components/SpeakerAudit.vue'
  142. import WithdrawAudit from './components/WithdrawAudit.vue'
  143. export default {
  144. components: {
  145. ShortVideoAudit,
  146. LongVideoAudit,
  147. ArticleAudit,
  148. SpeakerAudit,
  149. WithdrawAudit
  150. },
  151. data() {
  152. return {
  153. userInfo:JSON.parse(uni.getStorageSync('userInfo')),
  154. // 弹窗默认隐藏
  155. showRejectPopup: false,
  156. // 驳回意见
  157. rejectReason: '',
  158. // 状态栏高度
  159. statusBarHeight: uni.getSystemInfoSync().statusBarHeight,
  160. // 任务ID
  161. taskId: '',
  162. // 接口返回的原始数据
  163. auditData: null,
  164. // 审批信息
  165. approvalInfo: [],
  166. businessType:null
  167. }
  168. },
  169. onLoad(options) {
  170. console.log("options参数",options)
  171. if(options.businessType){
  172. this.businessType = options.businessType
  173. }
  174. if (options.taskId) {
  175. this.taskId = options.taskId
  176. this.loadData()
  177. }
  178. },
  179. methods: {
  180. // 打开驳回弹窗
  181. openRejectPopup() {
  182. // 直接打开驳回弹窗
  183. this.showRejectPopup = true
  184. },
  185. // 确认驳回
  186. async handleConfirmReject() {
  187. if (!this.rejectReason.trim()) {
  188. uni.showToast({
  189. title: '请输入驳回意见',
  190. icon: 'none'
  191. })
  192. return
  193. }
  194. try {
  195. uni.showLoading({
  196. title: '提交中...'
  197. })
  198. // 调用审核接口,传递action=2表示驳回
  199. const res = await doAudit({
  200. auditId: this.taskId,
  201. userId: this.userInfo.userId,
  202. userType: 0,
  203. action: 2,
  204. comment: this.rejectReason,
  205. companyId: this.userInfo.companyId
  206. })
  207. uni.hideLoading()
  208. if (res.code === 200) {
  209. uni.showToast({
  210. title: res.data.message,
  211. icon: none
  212. })
  213. // 关闭弹窗
  214. this.showRejectPopup = false
  215. // 重置输入
  216. this.rejectReason = ''
  217. // 重新加载数据
  218. this.loadData()
  219. } else {
  220. uni.showToast({
  221. title: res.msg || '驳回失败',
  222. icon: 'none'
  223. })
  224. }
  225. } catch (e) {
  226. uni.hideLoading()
  227. console.error('驳回失败', e)
  228. uni.showToast({
  229. title: '驳回失败,请稍后重试',
  230. icon: 'none'
  231. })
  232. }
  233. },
  234. // 返回上一页
  235. goBack() {
  236. uni.navigateBack()
  237. },
  238. // 加载数据
  239. async loadData() {
  240. try {
  241. uni.showLoading({
  242. title: '加载中...'
  243. })
  244. // 获取审批流程信息
  245. // const auditFlowsRes = await getAuditFlows({
  246. // auditId: this.taskId,
  247. // userId: this.userInfo.userId,
  248. // userType: this.userInfo.userType,
  249. // action: 0,
  250. // comment: "comment_3498cb3111a7",
  251. // companyId: this.userInfo.companyId
  252. // })
  253. // if (auditFlowsRes.code === 200) {
  254. // console.log('审批流程信息:', auditFlowsRes.data)
  255. // this.approvalInfo = auditFlowsRes.data || []
  256. // }
  257. // 获取任务完成审核信息
  258. const taskFinishAuditRes = await getTaskFinishAuditInfo({ taskId: 69||this.taskId })
  259. if (taskFinishAuditRes.code === 200) {
  260. // 直接保存接口返回的原始数据
  261. console.log('任务完成审核信息:', taskFinishAuditRes.data)
  262. this.auditData = taskFinishAuditRes.data
  263. }
  264. // 实际项目中替换为接口请求:const res = await getTaskDetail({ id: this.taskId })
  265. // 这里模拟接口赋值
  266. uni.hideLoading()
  267. } catch (e) {
  268. uni.hideLoading()
  269. console.error('加载数据失败', e)
  270. }
  271. },
  272. // 复制到剪贴板
  273. copyToClipboard(text) {
  274. uni.setClipboardData({
  275. data: text,
  276. success() {
  277. uni.showToast({
  278. title: '复制成功',
  279. icon: 'success'
  280. })
  281. }
  282. })
  283. },
  284. // 下载附件
  285. downloadAttachment() {
  286. uni.showToast({
  287. title: '开始下载附件',
  288. icon: 'none'
  289. })
  290. // 实际项目中添加下载逻辑:uni.downloadFile + uni.saveFile
  291. },
  292. // 备用方法(实际用openRejectPopup)
  293. handlePrev() {
  294. this.openRejectPopup()
  295. },
  296. // 审批通过
  297. async handleNext() {
  298. try {
  299. uni.showLoading({
  300. title: '提交中...'
  301. })
  302. // 调用审核接口,传递action=1表示通过
  303. const res = await doAudit({
  304. auditId: this.taskId,
  305. userId: this.userInfo.userId,
  306. userType: 0,
  307. action: 1,
  308. comment: "",
  309. companyId: this.userInfo.companyId
  310. })
  311. uni.hideLoading()
  312. if (res.code === 200) {
  313. uni.showToast({
  314. title: res.data.message,
  315. icon: none
  316. })
  317. // 重新加载数据
  318. this.loadData()
  319. } else {
  320. uni.showToast({
  321. title: res.msg || '审批通过失败',
  322. icon: 'none'
  323. })
  324. }
  325. } catch (e) {
  326. uni.hideLoading()
  327. console.error('审批通过失败', e)
  328. uni.showToast({
  329. title: '审批通过失败,请稍后重试',
  330. icon: 'none'
  331. })
  332. }
  333. }
  334. }
  335. }
  336. </script>
  337. <style lang="scss" scoped>
  338. // 通用信息部分样式
  339. .info-section {
  340. background: #fff;
  341. border-radius: 16rpx;
  342. padding: 32rpx;
  343. margin-bottom: 20rpx;
  344. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
  345. }
  346. .section-header {
  347. display: flex;
  348. align-items: center;
  349. margin-bottom: 24rpx;
  350. }
  351. .section-indicator {
  352. width: 8rpx;
  353. height: 24rpx;
  354. background: #1989fa;
  355. border-radius: 4rpx;
  356. margin-right: 12rpx;
  357. }
  358. .section-title {
  359. font-size: 28rpx;
  360. font-weight: 600;
  361. color: #333;
  362. }
  363. .info-list {
  364. width: 100%;
  365. }
  366. .info-item {
  367. display: flex;
  368. justify-content: space-between;
  369. align-items: center;
  370. padding: 16rpx 0;
  371. border-bottom: 1rpx solid #f2f2f2;
  372. }
  373. .info-item:last-child {
  374. border-bottom: none;
  375. }
  376. .info-label {
  377. font-size: 26rpx;
  378. color: #666;
  379. flex: 1;
  380. }
  381. .info-value {
  382. font-size: 26rpx;
  383. color: #333;
  384. flex: 2;
  385. text-align: right;
  386. word-break: break-all;
  387. }
  388. // 审核流程样式
  389. .flow-list {
  390. position: relative;
  391. }
  392. .flow-item {
  393. display: flex;
  394. margin-bottom: 32rpx;
  395. position: relative;
  396. }
  397. .flow-step {
  398. width: 40rpx;
  399. display: flex;
  400. flex-direction: column;
  401. align-items: center;
  402. position: relative;
  403. }
  404. .step-number {
  405. width: 40rpx;
  406. height: 40rpx;
  407. border-radius: 50%;
  408. background: #1989fa;
  409. color: #fff;
  410. font-size: 24rpx;
  411. font-weight: bold;
  412. display: flex;
  413. justify-content: center;
  414. align-items: center;
  415. z-index: 2;
  416. }
  417. .step-line {
  418. width: 2rpx;
  419. height: 100%;
  420. background: #e5e5e5;
  421. position: absolute;
  422. top: 40rpx;
  423. left: 19rpx;
  424. z-index: 1;
  425. }
  426. .flow-content {
  427. flex: 1;
  428. margin-left: 24rpx;
  429. background: #f9f9f9;
  430. border-radius: 12rpx;
  431. padding: 24rpx;
  432. position: relative;
  433. }
  434. .flow-header {
  435. display: flex;
  436. justify-content: space-between;
  437. align-items: center;
  438. margin-bottom: 16rpx;
  439. }
  440. .flow-title {
  441. font-size: 26rpx;
  442. font-weight: 600;
  443. color: #333;
  444. }
  445. .flow-status {
  446. font-size: 24rpx;
  447. padding: 4rpx 16rpx;
  448. border-radius: 12rpx;
  449. }
  450. .status-pending {
  451. background: #fff7e6;
  452. color: #fa8c16;
  453. }
  454. .status-completed {
  455. background: #f0f9eb;
  456. color: #52c41a;
  457. }
  458. .status-submitted {
  459. background: #e6f7ff;
  460. color: #1890ff;
  461. }
  462. .flow-info {
  463. font-size: 24rpx;
  464. color: #666;
  465. margin-bottom: 8rpx;
  466. }
  467. // 弹窗样式
  468. .reject-popup-content {
  469. padding: 32rpx;
  470. box-sizing: border-box;
  471. overflow: hidden;
  472. border-radius: 24rpx 24rpx 0 0;
  473. .popup-header {
  474. display: flex;
  475. justify-content: center;
  476. align-items: center;
  477. margin-bottom: 32rpx;
  478. position: relative;
  479. .popup-title {
  480. font-size: 32rpx;
  481. font-weight: bold;
  482. color: #333;
  483. }
  484. .close {
  485. position: absolute;
  486. right: 0;
  487. width: 44rpx;
  488. height: 44rpx;
  489. }
  490. }
  491. .input-area {
  492. margin-bottom: 40rpx;
  493. .reason-input {
  494. min-height: 120rpx;
  495. padding: 20rpx;
  496. background: #F7F8FA;
  497. border-radius: 12rpx;
  498. font-size: 28rpx;
  499. color: #333;
  500. width: 100%; // 新增:确保输入框宽度100%
  501. box-sizing: border-box;
  502. }
  503. }
  504. .btn-group {
  505. display: flex;
  506. gap: 24rpx;
  507. .button {
  508. width: 332rpx;
  509. height: 80rpx;
  510. flex: 1;
  511. border-radius: 200rpx;
  512. font-size: 28rpx;
  513. text-align: center;
  514. line-height: 80rpx;
  515. }
  516. .reject {
  517. color: #388BFF;
  518. background: #FFFFFF;
  519. border-radius: 200rpx 200rpx 200rpx 200rpx;
  520. border: 2rpx solid #388BFF;
  521. }
  522. .confirm {
  523. background: #388BFF;
  524. color: #FFFFFF;
  525. }
  526. }
  527. }
  528. // 原有样式
  529. .container {
  530. min-height: 100vh;
  531. background: #f5f5f5;
  532. display: flex;
  533. flex-direction: column;
  534. height: auto;
  535. &::before {
  536. content: '';
  537. position: absolute;
  538. top: 0;
  539. left: 0;
  540. right: 0;
  541. width: 100%;
  542. height: 532rpx;
  543. background: linear-gradient(180deg, rgba(56, 139, 255, 0.79) 0%, rgba(56, 139, 255, 0) 100%);
  544. }
  545. }
  546. .top {
  547. display: flex;
  548. justify-content: center;
  549. align-items: center;
  550. height: 88rpx;
  551. position: relative;
  552. font-weight: 600;
  553. font-size: 36rpx;
  554. color: #FFFFFF;
  555. .return {
  556. position: absolute;
  557. left: 32rpx;
  558. width: 40rpx;
  559. height: 40rpx;
  560. }
  561. }
  562. .content {
  563. flex: 1;
  564. padding: 24rpx;
  565. box-sizing: border-box;
  566. padding-bottom: 200rpx;
  567. }
  568. /* 任务卡片样式 */
  569. .task-card {
  570. background: #fff;
  571. border-radius: 16rpx;
  572. padding: 24rpx;
  573. margin-bottom: 24rpx;
  574. .card-header {
  575. display: flex;
  576. justify-content: space-between;
  577. .card-title {
  578. font-weight: 500;
  579. font-size: 36rpx;
  580. color: #333333;
  581. margin-bottom: 24rpx;
  582. }
  583. .card-lable {
  584. height: 40rpx;
  585. box-sizing: border-box;
  586. padding: 4rpx 12rpx;
  587. font-size: 24rpx;
  588. border-radius: 8rpx;
  589. &.pending {
  590. background: #FEF8E3;
  591. color: #DE9B14;
  592. }
  593. &.reject {
  594. background: #FFF4F5;
  595. color: #CF3546;
  596. }
  597. &.pass {
  598. color: #07C160;
  599. background: #E6FAEF;
  600. }
  601. }
  602. }
  603. .card-meta {
  604. display: flex;
  605. align-items: center;
  606. gap: 16rpx;
  607. font-size: 24rpx;
  608. color: #666;
  609. .item{
  610. display: flex;
  611. align-items: center;
  612. image{
  613. width: 32rpx;
  614. height: 32rpx;
  615. margin-right: 16rpx;
  616. }
  617. }
  618. }
  619. }
  620. /* 通用信息区块样式 */
  621. .info-section {
  622. background: #fff;
  623. border-radius: 16rpx;
  624. padding: 24rpx;
  625. margin-bottom: 24rpx;
  626. .section-header {
  627. display: flex;
  628. align-items: center;
  629. margin-bottom: 24rpx;
  630. .section-indicator {
  631. width: 6rpx;
  632. height: 32rpx;
  633. background: #388BFF;
  634. border-radius: 3rpx;
  635. margin-right: 16rpx;
  636. }
  637. .section-title {
  638. font-weight: 600;
  639. font-size: 32rpx;
  640. color: #333333;
  641. }
  642. }
  643. .info-list {
  644. .info-item {
  645. display: flex;
  646. margin-bottom: 24rpx;
  647. &:last-child {
  648. margin-bottom: 0;
  649. }
  650. .info-label {
  651. width: 50%;
  652. font-size: 28rpx;
  653. color: #666;
  654. flex-shrink: 0;
  655. }
  656. .info-value {
  657. flex: 1;
  658. text-align: end;
  659. font-size: 28rpx;
  660. color: #333;
  661. }
  662. .copy-btn {
  663. margin-left: 16rpx;
  664. color: #2196F3;
  665. font-size: 24rpx;
  666. cursor: pointer;
  667. }
  668. .column {
  669. flex-direction: column;
  670. }
  671. .attachment-item {
  672. margin-top: 24rpx;
  673. display: flex;
  674. justify-content: space-between;
  675. align-items: center;
  676. gap: 16rpx;
  677. background: #F7F8FA;
  678. border-radius: 16rpx 16rpx 16rpx 16rpx;
  679. .left {
  680. display: flex;
  681. align-items: center;
  682. .img {
  683. width: 72rpx;
  684. height: 72rpx;
  685. margin-right: 24rpx;
  686. }
  687. .txt-item {
  688. .attachment-name {
  689. font-size: 28rpx;
  690. color: #333;
  691. }
  692. .attachment-size {
  693. font-size: 24rpx;
  694. color: #999;
  695. }
  696. }
  697. }
  698. .download-btn {
  699. width: 32rpx;
  700. height: 32rpx;
  701. }
  702. }
  703. }
  704. }
  705. }
  706. /* 客户信息样式 */
  707. .client-list {
  708. .client-item {
  709. display: flex;
  710. justify-content: space-between;
  711. align-items: center;
  712. padding: 16rpx 0;
  713. &:last-child {
  714. border-bottom: none;
  715. }
  716. .client-info {
  717. display: flex;
  718. align-items: center;
  719. .avatar {
  720. width: 88rpx;
  721. height: 88rpx;
  722. margin-right: 24rpx;
  723. }
  724. .client-txt {
  725. .client-name {
  726. font-size: 28rpx;
  727. font-weight: 500;
  728. color: #333;
  729. .client-level {
  730. margin-left: 8rpx;
  731. padding: 2rpx 8rpx;
  732. background: #FFF6E5;
  733. color: #C89743;
  734. font-size: 22rpx;
  735. border-radius: 8rpx;
  736. }
  737. }
  738. }
  739. .client-hospital {
  740. font-size: 24rpx;
  741. color: #666;
  742. margin-top: 4rpx;
  743. display: flex;
  744. align-items: center;
  745. .line {
  746. width: 2rpx;
  747. height: 28rpx;
  748. background: #EAEBEE;
  749. margin: 0 24rpx;
  750. }
  751. }
  752. }
  753. .client-stats {
  754. display: flex;
  755. gap: 24rpx;
  756. font-size: 24rpx;
  757. color: #999999;
  758. .stat-item {
  759. display: flex;
  760. flex-direction: column;
  761. align-items: center;
  762. .num {
  763. font-weight: 500;
  764. font-size: 28rpx;
  765. color: #333333;
  766. }
  767. }
  768. }
  769. }
  770. }
  771. /* 审批信息样式 */
  772. .approval-list {
  773. .approval-item {
  774. position: relative;
  775. padding-left: 24rpx;
  776. margin-bottom: 68rpx;
  777. display: flex;
  778. align-items: center;
  779. justify-content: space-between;
  780. &:last-child {
  781. margin-bottom: 0;
  782. }
  783. .left {
  784. display: flex;
  785. align-items: center;
  786. .avatar-box {
  787. width: 80rpx;
  788. height: 80rpx;
  789. margin-right: 32rpx;
  790. position: relative;
  791. .avatar {
  792. width: 100%;
  793. height: 100%;
  794. }
  795. .icon {
  796. position: absolute;
  797. bottom: 0;
  798. right: 0;
  799. width: 32rpx;
  800. height: 32rpx;
  801. }
  802. }
  803. .approval-user {
  804. gap: 12rpx;
  805. .user-name {
  806. font-weight: 500;
  807. font-size: 28rpx;
  808. color: #333;
  809. }
  810. .user-status {
  811. font-size: 24rpx;
  812. }
  813. }
  814. }
  815. .approval-time {
  816. font-size: 24rpx;
  817. color: #999;
  818. margin-top: 4rpx;
  819. }
  820. }
  821. .approval-line {
  822. position: absolute;
  823. left: 64rpx;
  824. bottom: -64rpx;
  825. width: 1rpx;
  826. height: 56rpx;
  827. background: #BFD8FF;
  828. }
  829. }
  830. .reason {
  831. font-size: 28rpx;
  832. color: #666666;
  833. line-height: 40rpx;
  834. margin-left: 136rpx;
  835. background: #F7F8FA;
  836. border-radius: 16rpx;
  837. line-height: 40rpx;
  838. padding: 20rpx;
  839. }
  840. .bottom-bar {
  841. position: fixed;
  842. bottom: 0;
  843. left: 0;
  844. right: 0;
  845. background: #fff;
  846. padding: 24rpx 32rpx;
  847. border-top: 1rpx solid #F2F3F5;
  848. z-index: 100;
  849. display: flex;
  850. align-items: center;
  851. .action-buttons {
  852. display: flex;
  853. flex: 1;
  854. justify-content: space-between;
  855. .btn {
  856. width: 292rpx;
  857. height: 88rpx;
  858. display: flex;
  859. align-items: center;
  860. justify-content: center;
  861. font-size: 32rpx;
  862. font-weight: 500;
  863. border-radius: 200rpx 200rpx 200rpx 200rpx;
  864. cursor: pointer;
  865. display: flex;
  866. align-items: center;
  867. &.btn-cancel {
  868. background: #fff;
  869. border: 2rpx solid #CF3546;
  870. color: #CF3546;
  871. }
  872. &.btn-submit {
  873. background: #388BFF;
  874. color: #fff;
  875. }
  876. .icon {
  877. width: 32rpx;
  878. height: 32rpx;
  879. margin-right: 16rpx;
  880. }
  881. }
  882. }
  883. }
  884. </style>