approvalTaskDetail.vue 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773
  1. <template>
  2. <view class="container">
  3. <Watermark />
  4. <view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
  5. <view class="top">
  6. <image class="return" @click="goBack"
  7. src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/back_white.png"></image>
  8. <text>任务详情</text>
  9. </view>
  10. <scroll-view class="content" scroll-y>
  11. <!-- 任务卡片 -->
  12. <view class="task-card" v-if="auditData">
  13. <view class="card-header">
  14. <view class="card-title">
  15. {{ auditData.audit && auditData.audit.auditName ? auditData.audit.auditName : '-' }}</view>
  16. <view class="card-lable" :class="'pending'" v-if="auditData.audit && auditData.audit.status==1">待审核
  17. </view>
  18. <view class="card-lable" :class="'pass'" v-if="auditData.audit && auditData.audit.status==2">审核通过
  19. </view>
  20. <view class="card-lable" :class="'reject'" v-if="auditData.audit && auditData.audit.status==3">已驳回
  21. </view>
  22. </view>
  23. <view class="card-meta">
  24. <view class="item">
  25. <image src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_user.png"></image>
  26. {{ auditData.audit.initiatorId||'-' }}
  27. </view>
  28. <view class="item">
  29. <image src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_time.png"></image>
  30. {{ auditData.audit.createTime||'-' }}
  31. </view>
  32. </view>
  33. </view>
  34. <!-- 讲者审核详情 -->
  35. <view class="info-section" v-if="auditData.audit && auditData.audit.auditType=='ADUIT_JZSH'">
  36. <view class="section-header">
  37. <view class="section-indicator"></view>
  38. <text class="section-title">基础信息</text>
  39. </view>
  40. <view class="info-list">
  41. <view class="info-item">
  42. <text class="info-label">账户身份(医生/药剂师)</text>
  43. <text class="info-value">{{ auditData.businessData.doctorName||'-' }}</text>
  44. </view>
  45. <view class="info-item">
  46. <text class="info-label">账户身份</text>
  47. <text class="info-value">{{ auditData.businessData.accountType=='0'?'医生':'药剂师' }}</text>
  48. </view>
  49. <view class="info-item">
  50. <text class="info-label">手机号码</text>
  51. <text class="info-value">{{ utils.parseIdCard(auditData.businessData.mobile)||'-' }}</text>
  52. </view>
  53. <view class="info-item">
  54. <text class="info-label">身份证号</text>
  55. <text class="info-value">{{ utils.parseIdCard(auditData.businessData.idCard)||'-'}}</text>
  56. </view>
  57. <view class="info-item">
  58. <text class="info-label">机构名称</text>
  59. <text class="info-value">{{ auditData.businessData.institution||'-'}}</text>
  60. </view>
  61. <view class="info-item">
  62. <text class="info-label">注册时间</text>
  63. <text class="info-value">{{ auditData.businessData. registerTime||'-'}}</text>
  64. </view>
  65. </view>
  66. </view>
  67. <view class="info-section" v-if="auditData.audit && auditData.audit.auditType=='ADUIT_JZSH'">
  68. <view class="section-header">
  69. <view class="section-indicator"></view>
  70. <text class="section-title">执业信息</text>
  71. </view>
  72. <view class="info-list">
  73. <view class="info-item">
  74. <text class="info-label">地址(省市区)</text>
  75. <text class="info-value">{{ auditData.businessData.provinceName||'-' }}
  76. {{ auditData.businessData.cityName||'-' }}
  77. {{ auditData.businessData.districtName||'-' }}</text>
  78. </view>
  79. <view class="info-item">
  80. <text class="info-label">公司名称</text>
  81. <text class="info-value">{{ auditData.businessData.companyName||'-'}}</text>
  82. </view>
  83. <view class="info-item">
  84. <text class="info-label">科室</text>
  85. <text class="info-value">{{ auditData.businessData.department||'-'}}</text>
  86. </view>
  87. <view class="info-item">
  88. <text class="info-label">职称</text>
  89. <text class="info-value">{{ getHospitalTitle(auditData.businessData.jobTitle)||'-'}}</text>
  90. </view>
  91. <view class="info-item">
  92. <text class="info-label">第三方业务编码</text>
  93. <text class="info-value">{{ auditData.businessData.thirdPartyCode||'-'}}</text>
  94. </view>
  95. <view class="info-item">
  96. <text class="info-label">签约协议状态</text>
  97. <text class="info-value">{{ auditData.businessData.contractStatus=='0'?'未签约':'已签约'}}</text>
  98. </view>
  99. </view>
  100. </view>
  101. <view class="info-section" v-if="auditData.audit && auditData.audit.auditType=='ADUIT_JZSH'">
  102. <view class="section-header">
  103. <view class="section-indicator"></view>
  104. <text class="section-title">资质信息</text>
  105. </view>
  106. <view class="qualification-list">
  107. <view class="qualification-item">
  108. <text class="qualification-label">执业证图片</text>
  109. <view class="image-grid" v-if="imageList('licenseImage').length">
  110. <image v-for="(url, idx) in imageList('licenseImage')" :key="idx"
  111. class="qualification-image" :src="url" @click="showImagePreview(url)"></image>
  112. </view>
  113. </view>
  114. <view class="qualification-item">
  115. <text class="qualification-label">职称证/工牌图片</text>
  116. <view class="image-grid" v-if="imageList('titleCertImage').length">
  117. <image v-for="(url, idx) in imageList('titleCertImage')" :key="idx"
  118. class="qualification-image" :src="url" @click="showImagePreview(url)"></image>
  119. </view>
  120. </view>
  121. </view>
  122. </view>
  123. <!-- 提现审核详情 -->
  124. <view class="info-section" v-if="auditData.audit && auditData.audit.auditType=='ADUIT_TXSH'">
  125. <view class="section-header">
  126. <view class="section-indicator"></view>
  127. <text class="section-title">基础信息</text>
  128. </view>
  129. <view class="info-list">
  130. <view class="info-item">
  131. <text class="info-label">公司名称</text>
  132. <text class="info-value">{{ auditData.businessData.companyName ||'-'}}</text>
  133. </view>
  134. <view class="info-item">
  135. <text class="info-label">医生姓名</text>
  136. <text class="info-value">{{auditData.businessData.doctorName||'-'}}</text>
  137. </view>
  138. </view>
  139. </view>
  140. <view class="info-section" v-if="auditData.audit && auditData.audit.auditType=='ADUIT_TXSH'">
  141. <view class="section-header">
  142. <view class="section-indicator"></view>
  143. <text class="section-title">提现信息</text>
  144. </view>
  145. <view class="info-list">
  146. <view class="info-item">
  147. <text class="info-label">提现积分数量</text>
  148. <text class="info-value">{{ auditData.businessData.pointsAmount||'-'}}</text>
  149. </view>
  150. <view class="info-item">
  151. <text class="info-label">提现金额(积分折算)</text>
  152. <text class="info-value">{{ auditData.businessData.readConverterExp||'-'}}</text>
  153. </view>
  154. <view class="info-item">
  155. <text class="info-label">提现申请时间</text>
  156. <text class="info-value">{{ auditData.businessData.applyTime||'-'}}</text>
  157. </view>
  158. <view class="info-item">
  159. <text class="info-label">审核状态</text>
  160. <text class="info-value">
  161. {{auditData.businessData.auditStatus == '0' ? '待审核' :
  162. auditData.businessData.auditStatus == '1' ? '审核通过' :
  163. auditData.businessData.auditStatus == '2' ? '审核驳回' : ''
  164. }}
  165. </text>
  166. </view>
  167. <view class="info-item">
  168. <text class="info-label"> 审核时间</text>
  169. <text class="info-value">{{ auditData.businessData.auditTime||'-'}}</text>
  170. </view>
  171. <view class="info-item">
  172. <text class="info-label"> 审核备注(驳回原因等)</text>
  173. <text class="info-value">{{ auditData.businessData.auditRemark||'-'}}</text>
  174. </view>
  175. <view class="info-item">
  176. <text class="info-label"> 打款状态</text>
  177. <text class="info-value">{{ auditData.businessData.paymentStatus=='0'?'待打款':'已打款'}}</text>
  178. </view>
  179. <view class="info-item">
  180. <text class="info-label"> 打款时间</text>
  181. <text class="info-value">{{ auditData.businessData.paymentTime||'-'}}</text>
  182. </view>
  183. <view class="info-item">
  184. <text class="info-label"> 银行回执编号</text>
  185. <text class="info-value">{{ auditData.businessData.bankReceiptNo||'-'}}</text>
  186. </view>
  187. <view class="qualification-list">
  188. <view class="qualification-item">
  189. <text class="qualification-label">银行回执图片URL</text>
  190. <view class="image-grid" v-if="auditData.businessData.bankReceiptUrl||''">
  191. <image class="qualification-image" :src=" auditData.businessData.bankReceiptUrl||''"
  192. @click="showImagePreview(auditData.businessData.bankReceiptUrl||'')"></image>
  193. </view>
  194. </view>
  195. </view>
  196. </view>
  197. </view>
  198. <!-- 创建任务审核详情和完成任务审核-->
  199. <view class="info-section"
  200. v-if="auditData.audit && (auditData.audit.auditType=='ADUIT_WCRWSH'||auditData.audit.auditType=='ADUIT_CJRW')">
  201. <view class="section-header">
  202. <view class="section-indicator"></view>
  203. <text class="section-title">基础信息</text>
  204. </view>
  205. <view class="info-list">
  206. <view class="info-item">
  207. <text class="info-label">公司名称</text>
  208. <text class="info-value">{{ auditData.businessData.auditTaskInfoVO.taskNo ||'-'}}</text>
  209. </view>
  210. <view class="info-item">
  211. <text class="info-label">任务名称</text>
  212. <text class="info-value">{{auditData.businessData.auditTaskInfoVO.taskName||'-'}}</text>
  213. </view>
  214. </view>
  215. </view>
  216. <view class="info-section"
  217. v-if="auditData.audit && (auditData.audit.auditType=='ADUIT_WCRWSH'||auditData.audit.auditType=='ADUIT_CJRW')">
  218. <view class="section-header">
  219. <view class="section-indicator"></view>
  220. <text class="section-title">任务信息</text>
  221. </view>
  222. <view class="info-list">
  223. <view class="info-item">
  224. <text class="info-label">费用分摊名字</text>
  225. <text class="info-value">{{ auditData.businessData.auditTaskInfoVO.costShareName||'-'}}</text>
  226. </view>
  227. <view class="info-item">
  228. <text class="info-label">任务积分</text>
  229. <text class="info-value">{{ auditData.businessData.auditTaskInfoVO.taskIntegral||'-'}}</text>
  230. </view>
  231. <view class="info-item">
  232. <text class="info-label">任务数量</text>
  233. <text class="info-value">{{ auditData.businessData.auditTaskInfoVO.taskCount||'-'}}</text>
  234. </view>
  235. <view class="info-item">
  236. <text class="info-label">任务单位名称</text>
  237. <text class="info-value">{{ auditData.businessData.auditTaskInfoVO.taskUnitName||'-'}}</text>
  238. </view>
  239. <view class="info-item">
  240. <text class="info-label">归属名字</text>
  241. <text class="info-value">{{ auditData.businessData.auditTaskInfoVO.belongTypeName||'-'}}</text>
  242. </view>
  243. <view class="info-item">
  244. <text class="info-label">计划开始时间</text>
  245. <text class="info-value">{{ auditData.businessData.auditTaskInfoVO.planStartTime||'-'}}</text>
  246. </view>
  247. <view class="info-item">
  248. <text class="info-label">计划结束时间</text>
  249. <text class="info-value">{{ auditData.businessData.auditTaskInfoVO.planEndTime||'-'}}</text>
  250. </view>
  251. <!-- <view class="info-item">
  252. <text class="info-label">归属项目ID</text>
  253. <text class="info-value">{{ auditData.businessData.auditTaskInfoVO.projectId||'-'}}</text>
  254. </view> -->
  255. <view class="info-item">
  256. <text class="info-label">项目名称</text>
  257. <text class="info-value">{{ auditData.businessData.auditTaskInfoVO.projectName||'-'}}</text>
  258. </view>
  259. <!-- <view class="info-item">
  260. <text class="info-label">医生id</text>
  261. <text class="info-value">{{ auditData.businessData.auditTaskInfoVO.doctorId||'-'}}</text>
  262. </view>
  263. <view class="info-item">
  264. <text class="info-label">归属部门ID</text>
  265. <text class="info-value">{{ auditData.businessData.auditTaskInfoVO.deptId||'-'}}</text>
  266. </view> -->
  267. <view class="info-item">
  268. <text class="info-label">部门名称</text>
  269. <text class="info-value">{{ auditData.businessData.auditTaskInfoVO.deptName||'-'}}</text>
  270. </view>
  271. <view class="info-item">
  272. <text class="info-label">交付物审核时间</text>
  273. <text
  274. class="info-value">{{ auditData.businessData.auditTaskInfoVO.deliveryAuditTime||'-'}}</text>
  275. </view>
  276. </view>
  277. </view>
  278. <!-- 长视频信息 -->
  279. <view class="info-section"
  280. v-if="auditData.audit && auditData.audit.auditType=='ADUIT_WCRWSH' && auditData.businessData && auditData.businessData.auditTaskInfoVO && auditData.businessData.auditTaskInfoVO.taskType==6">
  281. <view class="section-header">
  282. <view class="section-indicator"></view>
  283. <text class="section-title">长视频信息</text>
  284. </view>
  285. <view class="info-list">
  286. <view class="info-item">
  287. <text class="info-label">项目名称/视频标题</text>
  288. <text class="info-value">{{ auditData.businessData.ctLongVideo.title ||'-'}}</text>
  289. </view>
  290. <view class="info-item">
  291. <text class="info-label">是否原创</text>
  292. <text
  293. class="info-value">{{auditData.businessData.ctLongVideo.isOriginal==0?'否':'是'||'-'}}</text>
  294. </view>
  295. <view class="qualification-list">
  296. <view class="qualification-item">
  297. <text class="qualification-label">封面图URL</text>
  298. <view class="image-grid" v-if="auditData.businessData.ctLongVideo.coverUrl||''">
  299. <image class="qualification-image"
  300. :src="auditData.businessData.ctLongVideo.coverUrl||''"
  301. @click="showImagePreview(auditData.businessData.ctLongVideo.coverUrl||'')"></image>
  302. </view>
  303. </view>
  304. </view>
  305. <view class="info-item">
  306. <text class="info-label">摘要</text>
  307. <text class="info-value">{{ auditData.businessData.ctLongVideo.summary ||'-'}}</text>
  308. </view>
  309. <!-- <view class="info-item">
  310. <video class="info-value" :src="auditData.businessData.ctLongVideo.videoUrl||''" controls></video>
  311. </view> -->
  312. <view class="info-item">
  313. <text class="info-label">视频附件URL</text>
  314. <text class="info-value link"
  315. v-if="auditData.businessData.ctLongVideo && auditData.businessData.ctLongVideo.videoUrl"
  316. @click="openUrl(auditData.businessData.ctLongVideo.videoUrl)">{{ auditData.businessData.ctLongVideo.videoUrl }}</text>
  317. <text class="info-value" v-else>-</text>
  318. </view>
  319. </view>
  320. </view>
  321. <!-- 直播信息 -->
  322. <view class="info-section"
  323. v-if="auditData.audit && auditData.audit.auditType=='ADUIT_WCRWSH' && auditData.businessData && auditData.businessData.auditTaskInfoVO && auditData.businessData.auditTaskInfoVO.taskType==1">
  324. <view class="section-header">
  325. <view class="section-indicator"></view>
  326. <text class="section-title">直播信息</text>
  327. </view>
  328. <view class="info-list">
  329. <view class="info-item">
  330. <text class="info-label">项目名称/视频标题</text>
  331. <text class="info-value">{{ auditData.businessData.liveBroadcast.title ||'-'}}</text>
  332. </view>
  333. <!-- <view class="info-item">
  334. <text class="info-label">是否原创</text>
  335. <text
  336. class="info-value">{{auditData.businessData.liveBroadcast.isOriginal==0?'否':'是'||'-'}}</text>
  337. </view> -->
  338. <view class="info-item">
  339. <text class="info-label">直播时长</text>
  340. <text class="info-value">{{ liveDuration||'0'}}</text>
  341. </view>
  342. <view class="info-item">
  343. <text class="info-label">医生实际开播时间</text>
  344. <text class="info-value">{{ realLiveDuration||'0'}}</text>
  345. </view>
  346. <view class="info-item">
  347. <text class="info-label">观看人数</text>
  348. <text class="info-value">{{ auditData.businessData.liveBroadcast.viewCount ||'0'}}</text>
  349. </view>
  350. <!-- <view class="info-item">
  351. <text class="info-label">点赞数</text>
  352. <text class="info-value">{{ auditData.businessData.liveBroadcast.likeCount||'0'}}</text>
  353. </view>
  354. <view class="info-item">
  355. <text class="info-label">收藏数</text>
  356. <text class="info-value">{{ auditData.businessData.liveBroadcast.favoriteCount ||'0'}}</text>
  357. </view> -->
  358. <view class="qualification-list">
  359. <view class="qualification-item">
  360. <text class="qualification-label">封面图</text>
  361. <view class="image-grid" v-if="auditData.businessData.liveBroadcast.coverUrl||''">
  362. <image class="qualification-image"
  363. :src="auditData.businessData.liveBroadcast.coverUrl||''"
  364. @click="showImagePreview(auditData.businessData.liveBroadcast.coverUrl||'')"></image>
  365. </view>
  366. </view>
  367. </view>
  368. <!-- <view class="info-item">
  369. <text class="info-label">视频附件链接</text>
  370. <text class="info-value link"
  371. v-if="auditData.businessData.liveBroadcast && auditData.businessData.liveBroadcast.videoUrl"
  372. @click="openUrl(auditData.businessData.liveBroadcast.videoUrl)">{{ auditData.businessData.liveBroadcast.videoUrl }}</text>
  373. <text class="info-value" v-else>-</text>
  374. </view> -->
  375. <view class="info-item">
  376. <text class="info-label">直播间链接</text>
  377. <text class="info-value link"
  378. v-if="auditData.businessData.liveBroadcast && auditData.businessData.liveBroadcast.liveUrl"
  379. @click="openUrl(auditData.businessData.liveBroadcast.liveUrl)">{{ auditData.businessData.liveBroadcast.liveUrl }}</text>
  380. <text class="info-value" v-else>-</text>
  381. </view>
  382. <view class="info-item">
  383. <text class="info-label">回放链接</text>
  384. <text class="info-value link"
  385. v-if="auditData.businessData.liveBroadcast && auditData.businessData.liveBroadcast.playbackUrl"
  386. @click="openUrl(auditData.businessData.liveBroadcast.playbackUrl)">{{ auditData.businessData.liveBroadcast.playbackUrl }}</text>
  387. <text class="info-value" v-else>-</text>
  388. </view>
  389. <view class="info-item">
  390. <text class="info-label">分享二维码链接</text>
  391. <text class="info-value link"
  392. @click="openUrl(`https://company.qicaijiaxiang.com/watch?liveId=${auditData.businessData.liveBroadcast.id}`)">{{`https://company.qicaijiaxiang.com/watch?liveId=${auditData.businessData.liveBroadcast.id}`}}</text>
  393. </view>
  394. <!-- <view class="info-item" v-if="auditData.businessData.liveBroadcast.rtmpPullUrl">
  395. <text class="info-label">拉流地址</text>
  396. <text class="info-value link"
  397. v-if="auditData.businessData.liveBroadcast && auditData.businessData.liveBroadcast.rtmpPullUrl"
  398. @click="openUrl(auditData.businessData.liveBroadcast.rtmpPullUrl)">{{ auditData.businessData.liveBroadcast.rtmpPullUrl }}</text>
  399. <text class="info-value" v-else>-</text>
  400. </view> -->
  401. </view>
  402. </view>
  403. <!-- 短视频 -->
  404. <view class="info-section"
  405. v-if="auditData.audit && auditData.audit.auditType=='ADUIT_WCRWSH' && auditData.businessData && auditData.businessData.auditTaskInfoVO && auditData.businessData.auditTaskInfoVO.taskType==5">
  406. <view class="section-header">
  407. <view class="section-indicator"></view>
  408. <text class="section-title">短视频信息</text>
  409. </view>
  410. <view class="info-list">
  411. <view class="info-item">
  412. <text class="info-label">项目名称/视频标题</text>
  413. <text class="info-value">{{ auditData.businessData.ctShortVideo.title ||'-'}}</text>
  414. </view>
  415. <view class="info-item">
  416. <text class="info-label">是否原创</text>
  417. <text
  418. class="info-value">{{auditData.businessData.ctShortVideo.isOriginal==0?'否':'是'||'-'}}</text>
  419. </view>
  420. <view class="qualification-list">
  421. <view class="qualification-item">
  422. <text class="qualification-label">封面图URL</text>
  423. <view class="image-grid" v-if="auditData.businessData.ctShortVideo.coverUrl||''">
  424. <image class="qualification-image"
  425. :src=" auditData.businessData.ctShortVideo.coverUrl||''"
  426. @click="showImagePreview(auditData.businessData.ctShortVideo.coverUrl||'')"></image>
  427. </view>
  428. </view>
  429. </view>
  430. <view class="info-item">
  431. <text class="info-label">摘要</text>
  432. <text class="info-value">{{auditData.businessData.ctShortVideo.summary||'-'}}</text>
  433. </view>
  434. <view class="info-item">
  435. <text class="info-label">视频附件URL</text>
  436. <text class="info-value link"
  437. v-if="auditData.businessData.ctShortVideo && auditData.businessData.ctShortVideo.videoUrl"
  438. @click="openUrl(auditData.businessData.ctShortVideo.videoUrl)">{{ auditData.businessData.ctShortVideo.videoUrl }}</text>
  439. <text class="info-value" v-else>-</text>
  440. </view>
  441. <!-- <view class="qualification-list">
  442. <view class="qualification-item">
  443. <text class="qualification-label">视频附件URL</text>
  444. <view class="image-grid" v-if="auditData.businessData.ctShortVideo.videoUrl||''">
  445. <image class="qualification-image" :src=" auditData.businessData.ctShortVideo.videoUrl||''"
  446. @click="showImagePreview(auditData.businessData.ctShortVideo.videoUrl||'')"></image>
  447. </view>
  448. </view>
  449. </view> -->
  450. <view class="info-item">
  451. <text class="info-label">上下架状态</text>
  452. <text class="info-value">{{auditData.businessData.ctShortVideo.status==0?'上架':'下架'||'-'}}</text>
  453. </view>
  454. </view>
  455. </view>
  456. <!-- 文章 -->
  457. <view class="info-section"
  458. v-if="auditData.audit && auditData.audit.auditType=='ADUIT_WCRWSH' && auditData.businessData && auditData.businessData.auditTaskInfoVO && auditData.businessData.auditTaskInfoVO.taskType==4">
  459. <view class="section-header">
  460. <view class="section-indicator"></view>
  461. <text class="section-title">文章信息</text>
  462. </view>
  463. <view class="info-list">
  464. <view class="info-item">
  465. <text class="info-label">项目名称/视频标题</text>
  466. <text class="info-value">{{ auditData.businessData.ctArticle.title ||'-'}}</text>
  467. </view>
  468. <view class="info-item">
  469. <text class="info-label">是否原创</text>
  470. <text class="info-value">{{auditData.businessData.ctArticle.isOriginal==0?'否':'是'||'-'}}</text>
  471. </view>
  472. <view class="qualification-list">
  473. <view class="qualification-item">
  474. <text class="qualification-label">封面图URL</text>
  475. <view class="image-grid" v-if="auditData.businessData.ctArticle.coverImage||''">
  476. <image class="qualification-image"
  477. :src=" auditData.businessData.ctArticle.coverImage||''"
  478. @click="showImagePreview(auditData.businessData.ctArticle.coverImage||'')"></image>
  479. </view>
  480. </view>
  481. </view>
  482. <view class="info-item">
  483. <text class="info-label">富文本</text>
  484. <text class="info-value">{{auditData.businessData.ctArticle.content||'-'}}</text>
  485. </view>
  486. <view class="info-item">
  487. <text class="info-label">摘要</text>
  488. <text class="info-value">{{auditData.businessData.ctArticle.summary||'-'}}</text>
  489. </view>
  490. <view class="info-item">
  491. <text class="info-label">附件URL</text>
  492. <text class="info-value link"
  493. v-if="auditData.businessData.ctArticle && auditData.businessData.ctArticle.attachmentUrl"
  494. @click="openUrl(auditData.businessData.ctArticle.attachmentUrl)">{{ auditData.businessData.ctArticle.attachmentUrl }}</text>
  495. <text class="info-value" v-else>-</text>
  496. </view>
  497. <!-- <view class="qualification-list">
  498. <view class="qualification-item">
  499. <text class="qualification-label">附件URL</text>
  500. <view class="image-grid" v-if="auditData.businessData.ctArticle.attachmentUrl||''">
  501. <image class="qualification-image" :src=" auditData.businessData.ctArticle.attachmentUrl||''"
  502. @click="showImagePreview(auditData.businessData.ctArticle.attachmentUrl||'')"></image>
  503. </view>
  504. </view>
  505. </view> -->
  506. <view class="info-item">
  507. <text class="info-label">上下架状态</text>
  508. <text class="info-value">{{auditData.businessData.ctArticle.status==0?'上架':'下架'||'-'}}</text>
  509. </view>
  510. </view>
  511. </view>
  512. <!-- 定级审核-->
  513. <view class="info-section" v-if="auditData.audit && auditData.audit.auditType=='ADUIT_DJSH'">
  514. <view class="section-header">
  515. <view class="section-indicator"></view>
  516. <text class="section-title">定级信息</text>
  517. </view>
  518. <view class="info-list">
  519. <view class="info-item" v-if="getFieldDisplay('学术头衔', true)">
  520. <text class="info-label">学术头衔</text>
  521. <text class="info-value">{{ getFieldDisplay('学术头衔', true)}}</text>
  522. </view>
  523. <view class="info-item" v-if="getFieldDisplay('学位', true)">
  524. <text class="info-label">学位</text>
  525. <text class="info-value">{{ getFieldDisplay('学位', true)}}</text>
  526. </view>
  527. <view class="info-item" v-if="getFieldDisplay('学术研究', true)">
  528. <text class="info-label">学术研究</text>
  529. <text class="info-value">{{ getFieldDisplay('学术研究', true)}}</text>
  530. </view>
  531. <view class="info-item" v-if="getFieldDisplay('学术任职', true)">
  532. <text class="info-label">学术任职</text>
  533. <text class="info-value">{{ getFieldDisplay('学术任职', true)}}</text>
  534. </view>
  535. <view class="info-item">
  536. <text class="info-label">申请级别</text>
  537. <text
  538. class="info-value">{{ auditData.businessData.doctorLevelApplyVO.applyLevelName ||'-'}}</text>
  539. </view>
  540. <view class="info-item">
  541. <text class="info-label">国际性期刊论文/著作数</text>
  542. <text
  543. class="info-value">{{auditData.businessData.doctorLevelApplyVO.internationalPapers ||'-'}}</text>
  544. </view>
  545. <view class="info-item">
  546. <text class="info-label">全国性期刊论文/著作数</text>
  547. <text
  548. class="info-value">{{auditData.businessData.doctorLevelApplyVO.nationalPapers ||'-'}}</text>
  549. </view>
  550. <view class="info-item">
  551. <text class="info-label">临床工作经验年数</text>
  552. <text
  553. class="info-value">{{auditData.businessData.doctorLevelApplyVO.clinicalExperienceYears ||'-'}}</text>
  554. </view>
  555. </view>
  556. </view>
  557. <!-- 项目信息 -->
  558. <view class="info-section" v-if="auditData.projectVO">
  559. <view class="section-header">
  560. <view class="section-indicator"></view>
  561. <text class="section-title">项目信息</text>
  562. </view>
  563. <view class="info-list">
  564. <view class="info-item">
  565. <text class="info-label">项目名称</text>
  566. <text class="info-value">{{ auditData.projectVO.projectName }}</text>
  567. </view>
  568. <view class="info-item">
  569. <text class="info-label">项目活动ID</text>
  570. <text class="info-value">{{ auditData.projectVO.projectTypeId }}</text>
  571. </view>
  572. </view>
  573. </view>
  574. <!-- 客户信息 -->
  575. <view class="info-section" v-if="auditData.docterVO">
  576. <view class="section-header">
  577. <view class="section-indicator"></view>
  578. <text class="section-title">客户信息</text>
  579. </view>
  580. <view class="client-list">
  581. <view class="client-item">
  582. <view class="client-info">
  583. <image class="avatar"
  584. src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/my_heads_icon.png">
  585. </image>
  586. <view class="client-txt">
  587. <view class="client-name">
  588. {{ auditData.docterVO.doctorName }}
  589. <text class="client-level">一级</text>
  590. </view>
  591. <view class="client-hospital">
  592. <text>{{ auditData.docterVO.institution }} </text>
  593. <view class="line"></view>
  594. <text>{{ auditData.docterVO.department || '-' }}</text>
  595. </view>
  596. </view>
  597. </view>
  598. <view class="client-stats">
  599. <view class="stat-item"><text class="num">{{ auditData.auditTaskInfoVO.taskCount }}
  600. </text>任务</view>
  601. <view class="stat-item"><text class="num">{{ auditData.auditTaskInfoVO.taskIntegral }}
  602. </text>积分</view>
  603. </view>
  604. </view>
  605. </view>
  606. </view>
  607. <!-- 审批信息 -->
  608. <view class="info-section">
  609. <view class="section-header">
  610. <view class="section-indicator"></view>
  611. <text class="section-title">审批流程</text>
  612. </view>
  613. <view class="approval-list">
  614. <view class="approval-item" v-for="(item, index) in auditData.auditFlows" :key="index">
  615. <view class="left">
  616. <view class="avatar-box">
  617. <image class="avatar"
  618. src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/my_heads_icon.png">
  619. </image>
  620. <image class="icon" v-if="item.status==1"
  621. src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_wait.png">
  622. </image>
  623. <image class="icon" v-if="item.status==2|| item.status ===0"
  624. src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_pass.png">
  625. </image>
  626. <image class="icon" v-if="item.status==3"
  627. src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_refuse.png">
  628. </image>
  629. </view>
  630. <view class="approval-user">
  631. <view class="user-name">{{ item.auditUserName }}</view>
  632. <view class="user-status"
  633. :style="{ color: item.status ===2|| item.status ===0 ? '#4CAF50' : item.status === 1 ? '#FF9800' : '#F44336' }">
  634. {{ item.statusName||'-' }}
  635. </view>
  636. <view class="approval-comment" v-if="item.comment">{{item.comment||'-'}}</view>
  637. </view>
  638. </view>
  639. <text class="approval-time">{{ item.auditTime || '-' }}</text>
  640. <view class="approval-line" v-if="index < auditData.auditFlows.length - 1"></view>
  641. </view>
  642. </view>
  643. <!-- <view class="approval-list">
  644. <view class="approval-item" v-for="(item, index) in auditData.auditFlows" :key="index">
  645. <view class="left">
  646. <view class="avatar-box">
  647. <image class="avatar"
  648. src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/my_heads_icon.png">
  649. </image>
  650. <image class="icon" v-if="item.status==1"
  651. src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_wait.png">
  652. </image>
  653. <image class="icon" v-if="item.status==2|| item.status ===0"
  654. src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_pass.png">
  655. </image>
  656. <image class="icon" v-if="item.status==3"
  657. src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_refuse.png">
  658. </image>
  659. </view>
  660. <view class="approval-user">
  661. <view class="user-name">{{ item.auditUserName }}</view>
  662. <view class="user-status"
  663. :style="{ color: item.status ===2|| item.status ===0 ? '#4CAF50' : item.status === 1 ? '#FF9800' : '#F44336' }">
  664. {{ item.statusName||'-' }}
  665. </view>
  666. <view class="approval-comment" v-if="item.comment">{{item.comment||'-'}}</view>
  667. </view>
  668. </view>
  669. <text class="approval-time">{{ item.auditTime || '-' }}</text>
  670. <view class="approval-line" v-if="index < auditData.auditFlows.length - 1"></view>
  671. </view>
  672. </view> -->
  673. </view>
  674. </scroll-view>
  675. <!-- 自定义图片预览模态框 -->
  676. <view class="image-preview-modal" v-if="imagePreview.show" @click="closeImagePreview">
  677. <view class="image-preview-content" @click.stop>
  678. <image class="preview-image" :src="imagePreview.urls[imagePreview.current]" mode="widthFix"></image>
  679. </view>
  680. </view>
  681. <view class="bottom-bar" v-if="auditData.audit && auditData.audit.status === 1 && isUserInLatestAuditUsers()">
  682. <view class="action-buttons">
  683. <view class="btn btn-cancel" @click="openRejectPopup">
  684. <image class="icon"
  685. src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_approval_no.png"></image>
  686. <text>驳回</text>
  687. </view>
  688. <view class="btn btn-submit" @click="handleNext">
  689. <image class="icon"
  690. src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_approval_yes.png"></image>
  691. <text>通过</text>
  692. </view>
  693. </view>
  694. </view>
  695. <!-- 驳回弹窗 -->
  696. <u-popup :show="showRejectPopup" mode="bottom" round="24" z-index="9999999">
  697. <view class="reject-popup-content">
  698. <view class="popup-header">
  699. <text class="popup-title">驳回</text>
  700. <image @click="showRejectPopup = false;" class="close"
  701. src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_close.png"></image>
  702. </view>
  703. <view class="input-area">
  704. <textarea v-model="rejectReason" placeholder="请输入驳回意见" class="reason-input" :auto-height="true"
  705. maxlength="200" />
  706. </view>
  707. <view class="btn-group">
  708. <view class="button reject" @click="showRejectPopup = false">取消</view>
  709. <view class="button confirm" @click="handleConfirmReject ">确认驳回</view>
  710. </view>
  711. </view>
  712. </u-popup>
  713. </view>
  714. </template>
  715. <script>
  716. import utils from '@/utils/common.js'
  717. import {
  718. doAudit,
  719. doCreateAudit,
  720. getAuditFlows,
  721. getTaskFinishAuditInfo,
  722. detail
  723. } from '@/api/audit.js'
  724. import image from 'uview-ui/libs/config/props/image';
  725. export default {
  726. data() {
  727. return {
  728. userInfo: uni.getStorageSync('userInfo'),
  729. // 弹窗默认隐藏
  730. showRejectPopup: false,
  731. // 驳回意见
  732. rejectReason: '',
  733. // 状态栏高度
  734. statusBarHeight: (uni.getWindowInfo ? uni.getWindowInfo().statusBarHeight : (typeof wx !== 'undefined' &&
  735. wx.getWindowInfo ? wx.getWindowInfo().statusBarHeight : (uni.getSystemInfoSync && uni
  736. .getSystemInfoSync().statusBarHeight) || 0)),
  737. // 任务ID
  738. taskId: '',
  739. // 接口返回的原始数据(初始化为安全空对象,避免渲染期空指针)
  740. auditData: {
  741. // audit: {},
  742. // businessData: {},
  743. // auditFlows: [],
  744. // projectVO: null,
  745. // docterVO: null,
  746. },
  747. // 审批信息
  748. approvalInfo: [],
  749. // 图片预览
  750. imagePreview: {
  751. show: false,
  752. urls: [],
  753. current: 0
  754. },
  755. hospitalTitle: [],
  756. }
  757. },
  758. computed: {
  759. // 预计时长
  760. liveDuration() {
  761. const { scheduledStartTime, scheduledEndTime } = this.auditData?.businessData?.liveBroadcast || {}
  762. return this.formatDuration(scheduledStartTime, scheduledEndTime)
  763. },
  764. // 实际时长
  765. realLiveDuration() {
  766. const { actualStartTime, actualEndTime } = this.auditData?.businessData?.liveBroadcast || {}
  767. return this.formatDuration(actualStartTime, actualEndTime)
  768. }
  769. },
  770. onLoad(options) {
  771. if (options.taskId) {
  772. this.taskId = options.taskId
  773. this.loadData()
  774. utils.getDicts("hospital_title").then(res => {
  775. this.hospitalTitle = res || [];
  776. console.log(this.hospitalTitle, 'hospitalTitle')
  777. });
  778. }
  779. },
  780. methods: {
  781. // 格式化时长:开始时间、结束时间 → 小时分秒
  782. formatDuration(startTime, endTime) {
  783. // 无时间直接返回 0
  784. if (!startTime || !endTime) return '0'
  785. const start = new Date(startTime).getTime()
  786. const end = new Date(endTime).getTime()
  787. const duration = end - start
  788. // 小于0直接返回0
  789. if (duration < 0) return '0'
  790. // 计算时分秒
  791. const hours = Math.floor(duration / (1000 * 60 * 60))
  792. const minutes = Math.floor((duration % (1000 * 60 * 60)) / (1000 * 60))
  793. const seconds = Math.floor((duration % (1000 * 60)) / 1000)
  794. // 拼接文案
  795. const parts = []
  796. if (hours > 0) parts.push(`${hours}小时`)
  797. if (minutes > 0) parts.push(`${minutes}分`)
  798. if (seconds > 0 || parts.length === 0) parts.push(`${seconds}秒`)
  799. return parts.join('')
  800. },
  801. getStatusBarHeight() {
  802. if (uni.getWindowInfo) return uni.getWindowInfo().statusBarHeight || 0
  803. if (typeof wx !== 'undefined' && wx.getWindowInfo) return wx.getWindowInfo().statusBarHeight || 0
  804. const info = uni.getSystemInfoSync && uni.getSystemInfoSync()
  805. return (info && info.statusBarHeight) || 0
  806. },
  807. imageList(field) {
  808. const b = (this.auditData && this.auditData.businessData) || {}
  809. const v = b[field]
  810. if (!v) return []
  811. if (Array.isArray(v)) return v.filter(Boolean)
  812. return String(v).split(',').map(s => String(s).trim().replace(/`/g, '')).filter(Boolean)
  813. },
  814. // 打开驳回弹窗
  815. openRejectPopup() {
  816. // 直接打开驳回弹窗
  817. this.showRejectPopup = true
  818. },
  819. //动态表单
  820. getFieldDisplay(label, isMultiple = false) {
  821. const apply = this.auditData.businessData.doctorLevelApplyVO;
  822. console.log(this.auditData, 'apply')
  823. if (!apply || !apply.formJson || !apply.dynamicFormData) return '-';
  824. let formJson = apply.formJson;
  825. if (typeof formJson === 'string') {
  826. try {
  827. formJson = JSON.parse(formJson);
  828. } catch (e) {
  829. return '-';
  830. }
  831. }
  832. const fields = formJson.fields || [];
  833. const field = fields.find(f => f.__config__.label === label);
  834. if (!field) return '-';
  835. const vModel = field.__vModel__;
  836. let value = apply.dynamicFormData[vModel];
  837. if (value === null || value === undefined || value === '') return '-';
  838. const options = field.__slot__?.options || [];
  839. const optionMap = new Map(options.map(opt => [String(opt.value), opt.label]));
  840. if (isMultiple) {
  841. const values = String(value).split(',').filter(Boolean);
  842. return values.map(v => optionMap.get(v) || v).join('、');
  843. } else {
  844. return optionMap.get(String(value)) || value;
  845. }
  846. },
  847. // 确认驳回
  848. async handleConfirmReject() {
  849. if (!this.rejectReason.trim()) {
  850. uni.showToast({
  851. title: '请输入驳回意见',
  852. icon: 'none'
  853. })
  854. return
  855. }
  856. try {
  857. uni.showLoading({
  858. title: '提交中...'
  859. })
  860. // 调用审核接口,传递action=2表示驳回
  861. const res = await doAudit({
  862. auditId: this.taskId,
  863. userId: this.userInfo.userId,
  864. businessType: this.auditData.audit.businessType,
  865. userType: 0,
  866. action: 2,
  867. comment: this.rejectReason,
  868. companyId: this.userInfo.companyId,
  869. businessId: this.auditData.audit.businessId
  870. })
  871. uni.hideLoading()
  872. if (res.code === 200) {
  873. uni.showToast({
  874. title: res.msg||res.message || '操作成功',
  875. icon: 'none',
  876. duration: 2000,
  877. mask: true
  878. })
  879. // 关闭弹窗
  880. this.showRejectPopup = false
  881. // 重置输入
  882. this.rejectReason = ''
  883. // 重新加载数据
  884. setTimeout(() => {
  885. this.loadData()
  886. }, 2000)
  887. this.goBack()
  888. } else {
  889. uni.showToast({
  890. title: res.message || res.msg || '操作失败',
  891. icon: 'none'
  892. })
  893. }
  894. } catch (e) {
  895. uni.hideLoading()
  896. console.error('驳回失败', e)
  897. }
  898. },
  899. // 返回上一页
  900. goBack() {
  901. uni.navigateBack()
  902. },
  903. // 加载数据
  904. async loadData() {
  905. try {
  906. uni.showLoading({
  907. title: '加载中...'
  908. })
  909. // 获取任务完成审核信息
  910. const res = await detail({
  911. auditId: this.taskId
  912. })
  913. if (res.code === 200) {
  914. this.auditData = res.data || {
  915. audit: {},
  916. businessData: {},
  917. auditFlows: []
  918. }
  919. }
  920. uni.hideLoading()
  921. } catch (e) {
  922. uni.hideLoading()
  923. console.error('加载数据失败', e)
  924. }
  925. },
  926. // 复制到剪贴板
  927. copyToClipboard(text) {
  928. uni.setClipboardData({
  929. data: text,
  930. success() {
  931. uni.showToast({
  932. title: '复制成功',
  933. icon: 'success'
  934. })
  935. }
  936. })
  937. },
  938. // 下载附件
  939. downloadAttachment() {
  940. uni.showToast({
  941. title: '开始下载附件',
  942. icon: 'none'
  943. })
  944. // 实际项目中添加下载逻辑:uni.downloadFile + uni.saveFile
  945. },
  946. // 解析formJson数据
  947. parseFormJson(formJson) {
  948. try {
  949. if (!formJson) return {};
  950. // 解析JSON字符串
  951. const parsed = typeof formJson === 'string' ? JSON.parse(formJson) : formJson;
  952. const fields = parsed.fields || [];
  953. const result = {};
  954. // 遍历所有字段,提取label和value
  955. fields.forEach(field => {
  956. const config = field.__config__;
  957. const label = config.label;
  958. const vModel = field.__vModel__;
  959. const value = field[vModel];
  960. // 对于select类型的字段,可能需要根据value找到对应的label
  961. if (field.options && Array.isArray(field.options)) {
  962. const option = field.options.find(opt => opt.value === value);
  963. result[label] = option ? option.label : value;
  964. } else {
  965. result[label] = value;
  966. }
  967. });
  968. return result;
  969. } catch (e) {
  970. console.error('解析formJson失败:', e);
  971. return {};
  972. }
  973. },
  974. // 备用方法(实际用openRejectPopup)
  975. handlePrev() {
  976. this.openRejectPopup()
  977. },
  978. // 审批通过
  979. async handleNext() {
  980. try {
  981. uni.showLoading({
  982. title: '提交中...'
  983. })
  984. // 调用审核接口,传递action=1表示通过
  985. const res = await doAudit({
  986. auditId: this.taskId,
  987. userId: this.userInfo.userId,
  988. businessType: this.auditData.audit.businessType,
  989. userType: 0,
  990. action: 1,
  991. comment: "",
  992. companyId: this.userInfo.companyId,
  993. businessId: this.auditData.audit.businessId
  994. })
  995. uni.hideLoading()
  996. if (res.code === 200) {
  997. uni.showToast({
  998. title: res.message || res.msg || '操作成功',
  999. icon: 'none',
  1000. duration: 2000,
  1001. mask: true
  1002. })
  1003. // 重新加载数据
  1004. setTimeout(() => {
  1005. this.loadData()
  1006. }, 2000)
  1007. this.goBack()
  1008. } else {
  1009. uni.showToast({
  1010. title: res.message || res.msg || '操作失败',
  1011. icon: 'none'
  1012. })
  1013. }
  1014. } catch (e) {
  1015. }
  1016. },
  1017. // 自定义图片预览
  1018. showImagePreview(url) {
  1019. if (url) {
  1020. this.imagePreview.show = true;
  1021. this.imagePreview.urls = [url];
  1022. this.imagePreview.current = 0;
  1023. }
  1024. },
  1025. // 关闭图片预览
  1026. closeImagePreview() {
  1027. this.imagePreview.show = false;
  1028. },
  1029. openUrl(url) {
  1030. if (!url) {
  1031. return
  1032. }
  1033. // #ifdef H5
  1034. window.open(url, '_blank')
  1035. // #endif
  1036. // #ifdef APP-PLUS
  1037. plus.runtime.openURL(url)
  1038. // #endif
  1039. // #ifdef MP-WEIXIN
  1040. this.copyToClipboard(url)
  1041. uni.showToast({
  1042. title: '链接已复制,可在浏览器打开',
  1043. icon: 'none'
  1044. })
  1045. // #endif
  1046. },
  1047. // 判断用户是否在最新的审核人中
  1048. isUserInLatestAuditUsers() {
  1049. try {
  1050. // 获取用户信息
  1051. const userInfo = uni.getStorageSync('userInfo');
  1052. if (!userInfo || !userInfo.userId) {
  1053. console.log('用户信息不存在或没有 userId');
  1054. return false;
  1055. }
  1056. const userId = userInfo.userId.toString();
  1057. console.log('当前用户 userId:', userId);
  1058. // 检查 auditData 和 auditFlows 是否存在且不为空
  1059. if (!this.auditData || !this.auditData.auditFlows || this.auditData.auditFlows.length === 0) {
  1060. console.log('auditData 或 auditFlows 不存在或为空');
  1061. return false;
  1062. }
  1063. // 获取 auditFlows 数组的最后一个项作为最新的审核步骤
  1064. const latestFlow = this.auditData.auditFlows[this.auditData.auditFlows.length - 1];
  1065. console.log('最新的审核步骤:', latestFlow);
  1066. // 检查最新步骤的审核人
  1067. if (latestFlow && latestFlow.auditUserIds) {
  1068. console.log('最新步骤的 auditUserIds:', latestFlow.auditUserIds);
  1069. // 解析 auditUserIds 字符串为数组
  1070. try {
  1071. const auditUserIds = JSON.parse(latestFlow.auditUserIds);
  1072. console.log('解析后的 auditUserIds:', auditUserIds);
  1073. if (Array.isArray(auditUserIds)) {
  1074. // 检查 userId 是否在最新的审核人中,转换类型以确保匹配
  1075. const result = auditUserIds.some(id => id.toString() === userId);
  1076. console.log('用户是否在最新审核人中:', result);
  1077. return result;
  1078. }
  1079. } catch (error) {
  1080. console.error('解析 auditUserIds 失败:', error);
  1081. }
  1082. }
  1083. console.log('用户不在最新审核人中');
  1084. return false;
  1085. } catch (error) {
  1086. console.error('判断用户是否在最新审核人中失败:', error);
  1087. return false;
  1088. }
  1089. },
  1090. // 根据职称值获取职称名称
  1091. getHospitalTitle(jobTitle) {
  1092. console.log(jobTitle, 'jobTitle')
  1093. console.log(this.hospitalTitle, 'hospitalTitle')
  1094. if (!jobTitle || !this.hospitalTitle ) {
  1095. return '-';
  1096. }
  1097. const title = this.hospitalTitle.find(item => item.dictValue == jobTitle);
  1098. console.log(title, 'title')
  1099. return title ? title.dictLabel : '-';
  1100. }
  1101. }
  1102. }
  1103. </script>
  1104. <style lang="scss" scoped>
  1105. // 弹窗样式
  1106. .reject-popup-content {
  1107. padding: 32rpx;
  1108. box-sizing: border-box;
  1109. overflow: hidden;
  1110. border-radius: 24rpx 24rpx 0 0;
  1111. .popup-header {
  1112. display: flex;
  1113. justify-content: center;
  1114. align-items: center;
  1115. margin-bottom: 32rpx;
  1116. position: relative;
  1117. .popup-title {
  1118. font-size: 32rpx;
  1119. font-weight: bold;
  1120. color: #333;
  1121. }
  1122. .close {
  1123. position: absolute;
  1124. right: 0;
  1125. width: 44rpx;
  1126. height: 44rpx;
  1127. }
  1128. }
  1129. .input-area {
  1130. margin-bottom: 40rpx;
  1131. .reason-input {
  1132. min-height: 120rpx;
  1133. padding: 20rpx;
  1134. background: #F7F8FA;
  1135. border-radius: 12rpx;
  1136. font-size: 28rpx;
  1137. color: #333;
  1138. width: 100%; // 新增:确保输入框宽度100%
  1139. box-sizing: border-box;
  1140. }
  1141. }
  1142. .btn-group {
  1143. display: flex;
  1144. gap: 24rpx;
  1145. .button {
  1146. width: 332rpx;
  1147. height: 80rpx;
  1148. flex: 1;
  1149. border-radius: 200rpx;
  1150. font-size: 28rpx;
  1151. text-align: center;
  1152. line-height: 80rpx;
  1153. }
  1154. .reject {
  1155. color: #388BFF;
  1156. background: #FFFFFF;
  1157. border-radius: 200rpx 200rpx 200rpx 200rpx;
  1158. border: 2rpx solid #388BFF;
  1159. }
  1160. .confirm {
  1161. background: #388BFF;
  1162. color: #FFFFFF;
  1163. }
  1164. }
  1165. }
  1166. // 原有样式
  1167. .container {
  1168. min-height: 100vh;
  1169. background: #f5f5f5;
  1170. display: flex;
  1171. flex-direction: column;
  1172. height: auto;
  1173. &::before {
  1174. content: '';
  1175. position: absolute;
  1176. top: 0;
  1177. left: 0;
  1178. right: 0;
  1179. width: 100%;
  1180. height: 532rpx;
  1181. background: linear-gradient(180deg, rgba(56, 139, 255, 0.79) 0%, rgba(56, 139, 255, 0) 100%);
  1182. }
  1183. }
  1184. .top {
  1185. display: flex;
  1186. justify-content: center;
  1187. align-items: center;
  1188. height: 88rpx;
  1189. position: relative;
  1190. font-weight: 600;
  1191. font-size: 36rpx;
  1192. color: #FFFFFF;
  1193. .return {
  1194. position: absolute;
  1195. left: 32rpx;
  1196. width: 40rpx;
  1197. height: 40rpx;
  1198. }
  1199. }
  1200. .content {
  1201. flex: 1;
  1202. padding: 24rpx;
  1203. box-sizing: border-box;
  1204. padding-bottom: 200rpx;
  1205. }
  1206. /* 任务卡片样式 */
  1207. .task-card {
  1208. background: #fff;
  1209. border-radius: 16rpx;
  1210. padding: 24rpx;
  1211. margin-bottom: 24rpx;
  1212. .card-header {
  1213. display: flex;
  1214. justify-content: space-between;
  1215. .card-title {
  1216. font-weight: 500;
  1217. font-size: 36rpx;
  1218. color: #333333;
  1219. margin-bottom: 24rpx;
  1220. }
  1221. .card-lable {
  1222. height: 40rpx;
  1223. box-sizing: border-box;
  1224. padding: 4rpx 12rpx;
  1225. font-size: 24rpx;
  1226. border-radius: 8rpx;
  1227. &.pending {
  1228. background: #FEF8E3;
  1229. color: #DE9B14;
  1230. }
  1231. &.reject {
  1232. background: #FFF4F5;
  1233. color: #CF3546;
  1234. }
  1235. &.pass {
  1236. color: #07C160;
  1237. background: #E6FAEF;
  1238. }
  1239. }
  1240. }
  1241. .card-meta {
  1242. display: flex;
  1243. align-items: center;
  1244. gap: 16rpx;
  1245. font-size: 24rpx;
  1246. color: #666;
  1247. .item {
  1248. display: flex;
  1249. align-items: center;
  1250. image {
  1251. width: 32rpx;
  1252. height: 32rpx;
  1253. margin-right: 16rpx;
  1254. }
  1255. }
  1256. }
  1257. }
  1258. /* 通用信息区块样式 */
  1259. .info-section {
  1260. background: #fff;
  1261. border-radius: 16rpx;
  1262. padding: 24rpx;
  1263. margin-bottom: 24rpx;
  1264. .section-header {
  1265. display: flex;
  1266. align-items: center;
  1267. margin-bottom: 24rpx;
  1268. .section-indicator {
  1269. width: 6rpx;
  1270. height: 32rpx;
  1271. background: #388BFF;
  1272. border-radius: 3rpx;
  1273. margin-right: 16rpx;
  1274. }
  1275. .section-title {
  1276. font-weight: 600;
  1277. font-size: 32rpx;
  1278. color: #333333;
  1279. }
  1280. }
  1281. .info-list {
  1282. .info-item {
  1283. display: flex;
  1284. margin-bottom: 24rpx;
  1285. &:last-child {
  1286. margin-bottom: 0;
  1287. }
  1288. .info-label {
  1289. width: 50%;
  1290. font-size: 28rpx;
  1291. color: #666;
  1292. flex-shrink: 0;
  1293. }
  1294. .info-value {
  1295. flex: 1;
  1296. text-align: end;
  1297. font-size: 28rpx;
  1298. color: #333;
  1299. }
  1300. .copy-btn {
  1301. margin-left: 16rpx;
  1302. color: #2196F3;
  1303. font-size: 24rpx;
  1304. cursor: pointer;
  1305. }
  1306. .column {
  1307. flex-direction: column;
  1308. }
  1309. .attachment-item {
  1310. margin-top: 24rpx;
  1311. display: flex;
  1312. justify-content: space-between;
  1313. align-items: center;
  1314. gap: 16rpx;
  1315. background: #F7F8FA;
  1316. border-radius: 16rpx 16rpx 16rpx 16rpx;
  1317. .left {
  1318. display: flex;
  1319. align-items: center;
  1320. .img {
  1321. width: 72rpx;
  1322. height: 72rpx;
  1323. margin-right: 24rpx;
  1324. }
  1325. .txt-item {
  1326. .attachment-name {
  1327. font-size: 28rpx;
  1328. color: #333;
  1329. }
  1330. .attachment-size {
  1331. font-size: 24rpx;
  1332. color: #999;
  1333. }
  1334. }
  1335. }
  1336. .download-btn {
  1337. width: 32rpx;
  1338. height: 32rpx;
  1339. }
  1340. }
  1341. }
  1342. }
  1343. }
  1344. /* 客户信息样式 */
  1345. .client-list {
  1346. .client-item {
  1347. display: flex;
  1348. justify-content: space-between;
  1349. align-items: center;
  1350. padding: 16rpx 0;
  1351. &:last-child {
  1352. border-bottom: none;
  1353. }
  1354. .client-info {
  1355. display: flex;
  1356. align-items: center;
  1357. .avatar {
  1358. width: 88rpx;
  1359. height: 88rpx;
  1360. margin-right: 24rpx;
  1361. }
  1362. .client-txt {
  1363. .client-name {
  1364. font-size: 28rpx;
  1365. font-weight: 500;
  1366. color: #333;
  1367. .client-level {
  1368. margin-left: 8rpx;
  1369. padding: 2rpx 8rpx;
  1370. background: #FFF6E5;
  1371. color: #C89743;
  1372. font-size: 22rpx;
  1373. border-radius: 8rpx;
  1374. }
  1375. }
  1376. }
  1377. .client-hospital {
  1378. font-size: 24rpx;
  1379. color: #666;
  1380. margin-top: 4rpx;
  1381. display: flex;
  1382. align-items: center;
  1383. .line {
  1384. width: 2rpx;
  1385. height: 28rpx;
  1386. background: #EAEBEE;
  1387. margin: 0 24rpx;
  1388. }
  1389. }
  1390. }
  1391. .client-stats {
  1392. display: flex;
  1393. gap: 24rpx;
  1394. font-size: 24rpx;
  1395. color: #999999;
  1396. .stat-item {
  1397. display: flex;
  1398. flex-direction: column;
  1399. align-items: center;
  1400. .num {
  1401. font-weight: 500;
  1402. font-size: 28rpx;
  1403. color: #333333;
  1404. }
  1405. }
  1406. }
  1407. }
  1408. }
  1409. /* 资质信息样式 */
  1410. .qualification-list {
  1411. .qualification-item {
  1412. margin-bottom: 32rpx;
  1413. &:last-child {
  1414. margin-bottom: 0;
  1415. }
  1416. .qualification-label {
  1417. display: block;
  1418. font-size: 28rpx;
  1419. color: #666666;
  1420. margin-bottom: 16rpx;
  1421. }
  1422. .image-grid {
  1423. display: flex;
  1424. flex-wrap: wrap;
  1425. gap: 16rpx;
  1426. .qualification-image {
  1427. width: calc((100% - 32rpx) / 2);
  1428. height: 240rpx;
  1429. border-radius: 8rpx;
  1430. object-fit: cover;
  1431. }
  1432. }
  1433. }
  1434. }
  1435. /* 审批信息样式 */
  1436. .approval-list {
  1437. .approval-item {
  1438. position: relative;
  1439. padding-left: 24rpx;
  1440. margin-bottom: 68rpx;
  1441. display: flex;
  1442. align-items: center;
  1443. justify-content: space-between;
  1444. &:last-child {
  1445. margin-bottom: 0;
  1446. }
  1447. .left {
  1448. display: flex;
  1449. // align-items: center;
  1450. .avatar-box {
  1451. width: 80rpx;
  1452. height: 80rpx;
  1453. margin-right: 32rpx;
  1454. position: relative;
  1455. .avatar {
  1456. width: 100%;
  1457. height: 100%;
  1458. }
  1459. .icon {
  1460. position: absolute;
  1461. bottom: 0;
  1462. right: 0;
  1463. width: 32rpx;
  1464. height: 32rpx;
  1465. }
  1466. }
  1467. .approval-user {
  1468. gap: 12rpx;
  1469. .user-name {
  1470. font-weight: 500;
  1471. font-size: 28rpx;
  1472. color: #333;
  1473. }
  1474. .user-status {
  1475. font-size: 24rpx;
  1476. }
  1477. }
  1478. }
  1479. .approval-time {
  1480. font-size: 24rpx;
  1481. color: #999;
  1482. margin-top: 4rpx;
  1483. }
  1484. .approval-comment{
  1485. margin-top: 14rpx;
  1486. width: 100%;
  1487. padding: 20rpx;
  1488. font-size: 28rpx;
  1489. background: #F7F8FA;
  1490. border-radius: 16rpx 16rpx 16rpx 16rpx;
  1491. }
  1492. }
  1493. .approval-line {
  1494. position: absolute;
  1495. left: 64rpx;
  1496. bottom: -64rpx;
  1497. width: 1rpx;
  1498. height: 56rpx;
  1499. background: #BFD8FF;
  1500. }
  1501. }
  1502. .reason {
  1503. font-size: 28rpx;
  1504. color: #666666;
  1505. line-height: 40rpx;
  1506. margin-left: 136rpx;
  1507. background: #F7F8FA;
  1508. border-radius: 16rpx;
  1509. line-height: 40rpx;
  1510. padding: 20rpx;
  1511. }
  1512. .bottom-bar {
  1513. position: fixed;
  1514. bottom: 0;
  1515. left: 0;
  1516. right: 0;
  1517. background: #fff;
  1518. padding: 24rpx 32rpx;
  1519. border-top: 1rpx solid #F2F3F5;
  1520. z-index: 100;
  1521. display: flex;
  1522. align-items: center;
  1523. .action-buttons {
  1524. display: flex;
  1525. flex: 1;
  1526. justify-content: space-between;
  1527. .btn {
  1528. width: 292rpx;
  1529. height: 88rpx;
  1530. display: flex;
  1531. align-items: center;
  1532. justify-content: center;
  1533. font-size: 32rpx;
  1534. font-weight: 500;
  1535. border-radius: 200rpx 200rpx 200rpx 200rpx;
  1536. cursor: pointer;
  1537. display: flex;
  1538. align-items: center;
  1539. &.btn-cancel {
  1540. background: #fff;
  1541. border: 2rpx solid #CF3546;
  1542. color: #CF3546;
  1543. }
  1544. &.btn-submit {
  1545. background: #388BFF;
  1546. color: #fff;
  1547. }
  1548. .icon {
  1549. width: 32rpx;
  1550. height: 32rpx;
  1551. margin-right: 16rpx;
  1552. }
  1553. }
  1554. }
  1555. }
  1556. /* 自定义图片预览样式 */
  1557. .image-preview-modal {
  1558. position: fixed;
  1559. top: 0;
  1560. left: 0;
  1561. right: 0;
  1562. bottom: 0;
  1563. background-color: rgba(0, 0, 0, 0.8);
  1564. display: flex;
  1565. justify-content: center;
  1566. align-items: center;
  1567. z-index: 9999;
  1568. }
  1569. .image-preview-content {
  1570. position: relative;
  1571. width: 100%;
  1572. max-height: 90vh;
  1573. display: flex;
  1574. flex-direction: column;
  1575. align-items: center;
  1576. }
  1577. .preview-image {
  1578. width: 100%;
  1579. max-height: 80vh;
  1580. object-fit: contain;
  1581. }
  1582. .link {
  1583. color: #388BFF;
  1584. text-decoration: underline;
  1585. display: block;
  1586. overflow: hidden;
  1587. text-overflow: ellipsis;
  1588. white-space: nowrap;
  1589. max-width: 100%;
  1590. }
  1591. .close-button {
  1592. position: absolute;
  1593. top: -60rpx;
  1594. right: 0;
  1595. width: 60rpx;
  1596. height: 60rpx;
  1597. background-color: rgba(0, 0, 0, 0.5);
  1598. color: #ffffff;
  1599. border-radius: 50%;
  1600. display: flex;
  1601. justify-content: center;
  1602. align-items: center;
  1603. font-size: 40rpx;
  1604. font-weight: bold;
  1605. cursor: pointer;
  1606. }
  1607. </style>