generateList.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. <template>
  2. <view class="gbox">
  3. <u-list @scrolltolower="scrolltolower" height="100%">
  4. <u-list-item v-for="(item, index) in list" :key="index">
  5. <view class="gbox-item">
  6. <view class="gbox-item-top adf">
  7. <view class="gbox-item-top-type">{{typeCfg[item.type]||'个人版'}}</view>
  8. <view class="gbox-item-top-title">{{item.reportName||''}}</view>
  9. </view>
  10. <view class="gbox-item-ps">
  11. <view class="gbox-item-p adfac">
  12. <view class="gbox-item-p-left">团队名称:</view>
  13. <view class="gbox-item-p-right">{{item.teamName||''}}</view>
  14. </view>
  15. <view class="gbox-item-p adf">
  16. <view class="gbox-item-p-left">报告状态:</view>
  17. <view class="gbox-item-p-right" :style="{'color':stateColor[item.state]}">{{stateDict[item.state]}}</view>
  18. </view>
  19. <view class="gbox-item-p adf">
  20. <view class="gbox-item-p-left">创建时间:</view>
  21. <view class="gbox-item-p-right">{{item.createDate||''}}</view>
  22. </view>
  23. <!-- <image class="gbox-item-ask" :src="imgBase+'report_ask.png'" @click="askReport(item)" v-if="item.state==1&&item.fileUrl"></image> -->
  24. <image class="gbox-item-ask" :src="imgBase+'report_ask.png'" @click="testShow=true" v-if="item.state==1&&item.fileUrl"></image>
  25. </view>
  26. <view class="gbox-item-bottom adfacjb">
  27. <view class="gbox-item-bottom-rightbox adfac" v-if="item.type==1">
  28. <view class="gbox-item-bottom-right" @click="openEvaluation(item)" v-if="canEditEvaluation(item)">评估修改</view>
  29. <view class="gbox-item-bottom-right" @click="showReportSelector(item)" v-if="item.state==1">查看报告</view>
  30. <view class="gbox-item-bottom-right" @click="reSendReport(item)" v-if="item.state==-1">重新生成</view>
  31. </view>
  32. <view class="gbox-item-bottom-rightbox adfac" v-else-if="item.type==2">
  33. <view class="gbox-item-bottom-right" @click="openEvaluation(item)" v-if="canEditEvaluation(item)">评估修改</view>
  34. <view class="gbox-item-bottom-right" @click="showReportSelector(item)" v-if="item.state==1">查看报告</view>
  35. <view class="gbox-item-bottom-right" @click="forwardReport(item)" v-if="item.state==1&&item.fileUrl">发送邮件</view>
  36. <view class="gbox-item-bottom-right" @click="sendReport(item)" v-if="item.state!=-1">发送报告</view>
  37. <view class="gbox-item-bottom-right" @click="reSendReport(item)" v-if="item.state==-1">重新生成</view>
  38. </view>
  39. </view>
  40. <view class="gbox-item-generating-mask" v-if="isReportGenerating(item)" @click.stop="showGeneratingReminder"></view>
  41. </view>
  42. </u-list-item>
  43. </u-list>
  44. <view class="kind-reminder adffcacjc" v-if="testShow">
  45. <view class="kr-box adffcac">
  46. <view class="kr-title">温馨提示</view>
  47. <view class="kr-p" style="margin-top: 54rpx;">功能测试中,即将上线,敬请期待!</view>
  48. <view class="kr-btn" @click="testShow=false">确定</view>
  49. </view>
  50. </view>
  51. <view class="kind-reminder adffcacjc" v-if="reportSelectorShow">
  52. <view class="kr-box adffcac report-selector-box">
  53. <view class="kr-title">查看报告</view>
  54. <view class="report-selector-tip">请选择要查看的报告</view>
  55. <view class="report-selector-btn" :class="{disabled: reportSelectorUnavailable('background')}" @click="selectReportArtifact('background')">背景报告</view>
  56. <view class="report-selector-btn" :class="{disabled: reportSelectorUnavailable('professional')}" @click="selectReportArtifact('professional')">教练报告</view>
  57. <view class="report-selector-btn" @click="selectReportArtifact('public')">团队报告</view>
  58. <view class="report-selector-cancel" @click="closeReportSelector">取消</view>
  59. </view>
  60. </view>
  61. <view class="kind-reminder adffcacjc" v-if="reportReminderShow">
  62. <view class="kr-box adffcac">
  63. <view class="kr-title">温馨提示</view>
  64. <view class="kr-p" style="margin-top: 54rpx;">{{reportReminderMsg}}</view>
  65. <view class="kr-btn" @click="reportReminderShow=false">确定</view>
  66. </view>
  67. </view>
  68. <view class="evaluation-mask adffcacjc" v-if="evaluationVisible">
  69. <view class="evaluation-box">
  70. <view class="kr-title">修改评估内容</view>
  71. <view class="evaluation-label">总体评估结果</view>
  72. <textarea class="evaluation-textarea" maxlength="20000" v-model="evaluationForm.overallAssessment" placeholder="请输入总体评估结果"></textarea>
  73. <view class="evaluation-label">团队发展建议</view>
  74. <textarea class="evaluation-textarea" maxlength="20000" v-model="evaluationForm.developmentAdvice" placeholder="请输入团队发展建议"></textarea>
  75. <view class="evaluation-actions">
  76. <view class="evaluation-cancel" @click="closeEvaluation">取消</view>
  77. <view class="evaluation-submit" :class="{disabled:evaluationSubmitting}" @click="submitEvaluation">{{evaluationSubmitting?'提交中':'保存提交'}}</view>
  78. </view>
  79. </view>
  80. </view>
  81. <cus-select-team-user
  82. ref="selectTeamUser"
  83. :show="teamUserShow"
  84. :list="teamUserList"
  85. @close="handleClose"
  86. @changeAll="changeAll"
  87. @handleSelectUser="handleSelectUser"
  88. @handleConfirm="sendConfirm"
  89. ></cus-select-team-user>
  90. </view>
  91. </template>
  92. <script>
  93. import { getPlatformInfo } from '@/utils/platform.js';
  94. import { reportArtifactUrl, reportArtifactDownloadUrl } from '@/utils/reportArtifactLinks.js'
  95. import { canEditEvaluation, isReportGenerating, EVALUATION_PROCESSING_PROMPT, normalizeEvaluationForm } from '@/utils/reportEvaluationEdit.js'
  96. import CusSelectTeamUser from '@/components/CusSelectTeamUser/index.vue'
  97. export default {
  98. props:{
  99. list:{
  100. typeof:Array,
  101. default:[]
  102. }
  103. },
  104. components:{ CusSelectTeamUser },
  105. data(){
  106. return {
  107. typeCfg:{
  108. 1:'个人版',
  109. 2:'团队版',
  110. 0:'团队PRO版'
  111. },
  112. stateDict:{
  113. '0':'生成中',
  114. '1':'生成成功',
  115. '-1':'生成失败'
  116. },
  117. stateColor:{
  118. '0':'#FFD750',
  119. '1':'#33A7A7',
  120. '-1':'#F4657A'
  121. },
  122. teamUserShow:false,
  123. teamUserList:[],
  124. categoryData:[],
  125. sendType:1,
  126. selectItem:null,
  127. testShow:false,
  128. reportReminderShow:false,
  129. reportReminderMsg:'',
  130. reportSelectorShow:false,
  131. reportSelectorItem:null,
  132. evaluationVisible:false,
  133. evaluationSubmitting:false,
  134. evaluationReportId:'',
  135. evaluationForm:{overallAssessment:'',developmentAdvice:''}
  136. }
  137. },
  138. methods:{
  139. isReportGenerating(item){
  140. return isReportGenerating(item);
  141. },
  142. showGeneratingReminder(){
  143. this.$showToast('报告正在生成中,暂不可操作,请稍候。');
  144. },
  145. guardReportOperation(item){
  146. if(!this.isReportGenerating(item)) return true;
  147. this.showGeneratingReminder();
  148. return false;
  149. },
  150. scrolltolower(){
  151. this.$emit('scrolltolower')
  152. },
  153. getUserCategoryData(){
  154. return new Promise((resolve,reject)=>{
  155. this.$api.get('/getListByType/UserCategory').then(({data:res})=>{
  156. if(res.code!==0) return this.$showToast(res.msg)
  157. this.categoryData = res.data.map(d=>({name:d.dictLabel,id:d.dictValue}))
  158. resolve()
  159. })
  160. })
  161. },
  162. async forwardReport(item){
  163. if(!this.guardReportOperation(item)) return;
  164. //发送给账号自己的邮箱
  165. if(!uni.getStorageSync('userInfo')||!JSON.parse(uni.getStorageSync('userInfo')).email) return this.$showModal('发送邮件前请先在我的-设置-用户信息中绑定邮箱')
  166. uni.showModal({
  167. title:'温馨提示',
  168. content:`是否确认将“${item.reportName||''}”下的PDF报告文件发送到账号绑定邮箱中?`,
  169. confirmText:'确认',
  170. success: (res) => {
  171. if(res.confirm){
  172. this.$api.get(`/core/report/sendToEmail/${item.reportId}`).then(({data:res})=>{
  173. if(res.code!==0) return this.$showToast(res.msg)
  174. this.$showModal('邮件发送成功,可在绑定的邮箱中查看详细内容。')
  175. })
  176. }
  177. }
  178. })
  179. // this.sendType = 1;
  180. // this.$refs.selectTeamUser.title = '发送邮件'
  181. // await this.getUserCategoryData()
  182. // this.$api.get(`/core/member/listByQueTeamId/${item.teamQueId}`).then(({data:res})=>{
  183. // if(res.code!==0) return this.$showToast(res.msg)
  184. // this.teamUserList = res.data;
  185. // this.teamUserList.forEach((l,i)=>{
  186. // l.categoryName = this.categoryData.find(c=>c.id==l.category)?.name;
  187. // this.$set(this.teamUserList[i],'select',false);
  188. // })
  189. // this.teamUserShow = true;
  190. // })
  191. },
  192. handleSelectUser(index){
  193. this.$set(this.teamUserList[index],'select',!this.teamUserList[index].select);
  194. this.dealNumAndAll()
  195. },
  196. handleClose(){
  197. this.teamUserShow = false;
  198. this.initSelectUserComponent();
  199. },
  200. changeAll(selected){
  201. this.teamUserList.forEach((l,i)=>{
  202. this.$set(this.teamUserList[i],'select',selected);
  203. })
  204. this.$refs.selectTeamUser.selectNums = this.teamUserList.filter(l=>l.select).length;
  205. },
  206. dealNumAndAll(){
  207. const selectnum = this.teamUserList.filter(l=>l.select).length;
  208. this.$refs.selectTeamUser.selectNums = selectnum;
  209. this.$refs.selectTeamUser.selectAll = selectnum === this.teamUserList.length;
  210. },
  211. showReportUnavailable(kind){
  212. this.reportReminderMsg = kind === 'background'
  213. ? '背景报告需配合团队版评估数据生成'
  214. : '教练报告需要配合团队版评估数据生成';
  215. this.reportReminderShow = true;
  216. },
  217. showReportSelector(item){
  218. if(!this.guardReportOperation(item) || String(item.state) !== '1') return;
  219. this.reportSelectorItem = item;
  220. this.reportSelectorShow = true;
  221. },
  222. closeReportSelector(){
  223. this.reportSelectorShow = false;
  224. this.reportSelectorItem = null;
  225. },
  226. reportSelectorUnavailable(kind){
  227. return this.reportSelectorItem && String(this.reportSelectorItem.type) === '1'
  228. && ['background', 'professional'].indexOf(kind) !== -1;
  229. },
  230. selectReportArtifact(kind){
  231. const item = this.reportSelectorItem;
  232. this.closeReportSelector();
  233. if(!item || !this.guardReportOperation(item)) return;
  234. if(String(item.type) === '1' && ['background', 'professional'].indexOf(kind) !== -1) {
  235. return this.showReportUnavailable(kind);
  236. }
  237. this.reviewArtifact(item, kind);
  238. },
  239. canEditEvaluation(item){
  240. return canEditEvaluation(item);
  241. },
  242. openEvaluation(item){
  243. if(!this.guardReportOperation(item)) return;
  244. if(!this.canEditEvaluation(item)) return;
  245. this.evaluationReportId = item.reportId;
  246. this.evaluationSubmitting = false;
  247. this.evaluationVisible = true;
  248. this.$api.get('/core/report/evaluation/'+item.reportId).then(({data:res})=>{
  249. if(res.code!==0){ this.closeEvaluation(); return this.$showToast(res.msg); }
  250. if(res.data && res.data.processing){ this.closeEvaluation(); return this.$showToast('评估分析正在重新生成中,请稍候'); }
  251. this.evaluationForm = normalizeEvaluationForm(res.data || {});
  252. })
  253. },
  254. closeEvaluation(){
  255. if(this.evaluationSubmitting) return;
  256. this.evaluationVisible = false;
  257. this.evaluationReportId = '';
  258. },
  259. submitEvaluation(){
  260. if(this.evaluationSubmitting) return;
  261. if(!this.evaluationForm.overallAssessment.trim()) return this.$showToast('请输入总体评估结果');
  262. if(!this.evaluationForm.developmentAdvice.trim()) return this.$showToast('请输入团队发展建议');
  263. this.evaluationSubmitting = true;
  264. this.$api.post('/core/report/evaluation/'+this.evaluationReportId, this.evaluationForm).then(({data:res})=>{
  265. if(res.code!==0) return this.$showToast(res.msg);
  266. this.evaluationVisible = false;
  267. this.$emit('reSendReport');
  268. this.reportReminderMsg = EVALUATION_PROCESSING_PROMPT;
  269. this.reportReminderShow = true;
  270. }).finally(()=>{ this.evaluationSubmitting = false; });
  271. },
  272. sendConfirm(){
  273. if(!this.guardReportOperation(this.selectItem)) return;
  274. if(this.teamUserList.filter(t=>t.select).length===0) return this.$showToast('请选择要发送的用户')
  275. if(this.sendType===1&&(!uni.getStorageSync('userInfo')||!JSON.parse(uni.getStorageSync('userInfo')).email)) return this.$showModal('发送前请先在我的-设置-用户信息中绑定邮箱')
  276. if(this.sendType===1){
  277. this.handleClose();
  278. } else if(this.sendType===2){
  279. const item = JSON.parse(JSON.stringify(this.selectItem));
  280. uni.showModal({
  281. title:'发送报告',
  282. content:`是否确认将“${item.reportName||''}”发送给团队成员`,
  283. confirmText:'确认',
  284. success: (res) => {
  285. if(res.confirm){
  286. this.$api.post(`/core/report/sendReport`,{
  287. reportId:item.reportId,
  288. memberList:this.teamUserList.filter(t=>t.select).map(t=>({id:t.id,mobile:t.mobile,category:t.category}))
  289. }).then(({data:res})=>{
  290. if(res.code!==0) return this.$showToast(res.msg)
  291. this.handleClose();
  292. uni.navigateTo({
  293. url:'/pagesHome/sendResult?result='+res.code
  294. })
  295. })
  296. }
  297. }
  298. })
  299. }
  300. },
  301. initSelectUserComponent(){
  302. this.$refs.selectTeamUser.selectNums = 0;
  303. this.$refs.selectTeamUser.selectAll = false;
  304. },
  305. reviewArtifact(item, kind){
  306. if(!this.guardReportOperation(item)) return;
  307. const url = reportArtifactUrl(item, kind)
  308. if(!url) return this.$showToast('该报告尚未生成,请稍后再试。')
  309. const { isPC, isMobile, platform } = getPlatformInfo();
  310. console.log(platform,'platform');//android
  311. if (isPC) {
  312. this.$showModal('请在手机端该微信小程序中查看报告')
  313. } else if (isMobile||platform==='devtools') {
  314. this.openReportDocument(url)
  315. // uni.navigateTo({
  316. // url:'/pages/webView?src='+item.fileUrl
  317. // })
  318. }
  319. },
  320. async openReportDocument(fileUrl) {
  321. try {
  322. // 1. 显示加载提示
  323. uni.showLoading({ title: '加载中...' });
  324. // 2. 先下载PDF文件到本地(解决安卓直接预览网络文件慢的问题)
  325. const downloadRes = await uni.downloadFile({
  326. url: reportArtifactDownloadUrl(fileUrl),
  327. // 可选:设置超时时间,避免长时间等待
  328. timeout: 30000
  329. });
  330. const dres = downloadRes[1]||null;
  331. if (dres.statusCode !== 200) {
  332. uni.hideLoading();
  333. uni.showToast({ title: '文件下载失败', icon: 'none' });
  334. return;
  335. }
  336. // 3. 按实际扩展名使用微信原生文档预览
  337. const openRes = await uni.openDocument({
  338. filePath: dres.tempFilePath,
  339. fileType: this.documentType(fileUrl),
  340. showMenu: false
  341. });
  342. uni.hideLoading();
  343. } catch (error) {
  344. uni.hideLoading();
  345. uni.showToast({ title: '加载失败,请重试', icon: 'none' });
  346. }
  347. },
  348. documentType(fileUrl) {
  349. const path = (fileUrl || '').split('?')[0].toLowerCase()
  350. return path.endsWith('.docx') ? 'docx' : 'pdf'
  351. },
  352. askReport(item){
  353. if(!this.guardReportOperation(item)) return;
  354. uni.navigateTo({
  355. url:`/pages/reportAsk?pdfUrl=${item.fileUrl}&fileName=${this.typeCfg[item.type]||'个人版'}-${item.reportName}`
  356. })
  357. },
  358. async sendReport(item){
  359. if(!this.guardReportOperation(item)) return;
  360. if(!item.fileUrl) return this.$showModal('该报告尚未生成PDF文件,请等待生成后发送。')
  361. this.sendType = 2;
  362. this.$refs.selectTeamUser.title = '发送报告'
  363. this.selectItem = item;
  364. await this.getUserCategoryData()
  365. this.$api.get(`/core/member/listByQueTeamId/${item.teamQueId}`).then(({data:res})=>{
  366. if(res.code!==0) return this.$showToast(res.msg)
  367. this.teamUserList = res.data;
  368. this.teamUserList.forEach((l,i)=>{
  369. l.categoryName = this.categoryData.find(c=>c.id==l.category)?.name;
  370. this.$set(this.teamUserList[i],'select',false);
  371. })
  372. this.teamUserShow = true;
  373. })
  374. },
  375. reSendReport(item){
  376. if(!this.guardReportOperation(item)) return;
  377. this.$api.get(`/core/report/regenerateReport/${item.reportId}`).then(({data:res})=>{
  378. if(res.code!==0) return this.$showToast(res.msg)
  379. this.$emit('reSendReport')
  380. })
  381. }
  382. }
  383. }
  384. </script>
  385. <style scoped lang="scss">
  386. @import '../../../static/_asset-config';
  387. .gbox{
  388. height: 100%;
  389. &-item{
  390. margin-top: 20rpx;
  391. background: #FFFFFF;
  392. border-radius: 24rpx;
  393. padding: 40rpx 20rpx 20rpx;
  394. position: relative;
  395. &-generating-mask{
  396. position: absolute;
  397. left: 0;
  398. right: 0;
  399. top: 0;
  400. bottom: 0;
  401. z-index: 10;
  402. border-radius: 24rpx;
  403. background: rgba(255, 255, 255, .35);
  404. }
  405. &-top{
  406. &-type{
  407. width: 98rpx;
  408. height: 36rpx;
  409. padding: 2rpx 13rpx;
  410. box-sizing: border-box;
  411. background: #FFF7DC;
  412. border-radius: 6rpx;
  413. font-family: PingFangSC, PingFang SC;
  414. font-weight: 400;
  415. font-size: 24rpx;
  416. color: #BA9B31;
  417. line-height: 33rpx;
  418. }
  419. &-title{
  420. width: calc(100% - 98rpx);
  421. font-family: PingFang-SC, PingFang-SC;
  422. font-weight: bold;
  423. font-size: 32rpx;
  424. color: #002846;
  425. line-height: 32rpx;
  426. text-indent: 17rpx;
  427. }
  428. }
  429. &-ps{
  430. margin-top: 20rpx;
  431. background: #F5F8FA;
  432. border-radius: 5px;
  433. padding: 20rpx 20rpx 30rpx;
  434. position: relative;
  435. }
  436. &-p{
  437. margin-top: 32rpx;
  438. &:first-child{
  439. margin-top: 0;
  440. }
  441. &>view{
  442. font-family: PingFangSC, PingFang SC;
  443. font-weight: 400;
  444. font-size: 24rpx;
  445. color: #667E90;
  446. line-height: 24rpx;
  447. }
  448. &-left{
  449. width: 134rpx;
  450. }
  451. &-right{
  452. width: calc(100% - 134rpx);
  453. }
  454. &-progress{
  455. width: calc(100% - 134rpx);
  456. &-l{
  457. width: 410rpx;
  458. height: 12rpx;
  459. background: #F0F2F8;
  460. border-radius: 6rpx;
  461. position: relative;
  462. &-current{
  463. height: 12rpx;
  464. background: #FFDF73;
  465. border-radius: 6rpx;
  466. position: absolute;
  467. left: 0;
  468. top: 0;
  469. }
  470. }
  471. &-r{
  472. width: calc(100% - 410rpx);
  473. font-family: PingFangSC, PingFang SC;
  474. font-weight: 400;
  475. font-size: 24rpx;
  476. color: #002846;
  477. line-height: 24rpx;
  478. text-align: right;
  479. }
  480. }
  481. }
  482. &-ask{
  483. width: 64rpx;
  484. height: 64rpx;
  485. position: absolute;
  486. right: 20rpx;
  487. bottom: 42rpx;
  488. }
  489. &-bottom{
  490. margin-top: 20rpx;
  491. overflow: hidden;
  492. &-rightbox{
  493. flex: 1;
  494. margin-left: -35rpx;
  495. justify-content: flex-end;
  496. }
  497. &-left{
  498. &>view{
  499. font-family: PingFangSC, PingFang SC;
  500. font-weight: 400;
  501. font-size: 24rpx;
  502. color: #667E90;
  503. line-height: 24rpx;
  504. }
  505. }
  506. &-right{
  507. flex: 1;
  508. width: 0;
  509. height: 64rpx;
  510. padding: 0 8rpx;
  511. text-align: center;
  512. box-sizing: border-box;
  513. line-height: 64rpx;
  514. white-space: nowrap;
  515. background: linear-gradient( 90deg, #33A7A7 0%, #4DB2B2 100%);
  516. border-radius: 20rpx;
  517. font-family: PingFang-SC, PingFang-SC;
  518. font-size: 24rpx;
  519. color: #FFFFFF;
  520. margin-left: 35rpx;
  521. &.report-button-disabled{
  522. background: #D5DDE2;
  523. color: #FFFFFF;
  524. }
  525. }
  526. }
  527. }
  528. .kind-reminder{
  529. position: fixed;
  530. left: 0;
  531. right: 0;
  532. top: 0;
  533. bottom: 0;
  534. z-index: 1000;
  535. background: rgba(0, 0, 0, .6);
  536. .kr-box{
  537. width: calc(100% - 100rpx);
  538. padding: 54rpx 60rpx 48rpx;
  539. box-sizing: border-box;
  540. background: asset-image('remind_bg.png') no-repeat;
  541. background-size: 100% 100%;
  542. position: relative;
  543. image{
  544. width: 48rpx;
  545. height: 48rpx;
  546. position: absolute;
  547. top: 40rpx;
  548. right: 30rpx;
  549. }
  550. .kr-title{
  551. font-family: PingFang-SC, PingFang-SC;
  552. font-weight: bold;
  553. font-size: 36rpx;
  554. color: #002846;
  555. line-height: 56rpx;
  556. text-align: center;
  557. }
  558. .kr-p{
  559. font-family: PingFangSC, PingFang SC;
  560. font-weight: 400;
  561. font-size: 30rpx;
  562. color: #002846;
  563. line-height: 48rpx;
  564. text-align: center;
  565. span{
  566. font-weight: bold;
  567. margin: 0 10rpx;
  568. }
  569. }
  570. .kr-btn{
  571. width: calc(100% - 80rpx);
  572. height: 88rpx;
  573. background: linear-gradient( 90deg, #33A7A7 0%, #64BBBB 100%);;
  574. border-radius: 44rpx;
  575. font-family: PingFang-SC, PingFang-SC;
  576. font-weight: bold;
  577. font-size: 32rpx;
  578. color: #FFFFFF;
  579. line-height: 88rpx;
  580. text-align: center;
  581. letter-spacing: 2rpx;
  582. margin-top: 66rpx;
  583. }
  584. }
  585. }
  586. }
  587. .report-selector-box{padding-bottom: 36rpx;}
  588. .report-selector-tip{margin-top: 20rpx;text-align:center;font-size:28rpx;color:#667E90;}
  589. .report-selector-btn{width:calc(100% - 40rpx);height:76rpx;margin:22rpx 20rpx 0;border-radius:38rpx;background:linear-gradient(90deg,#33A7A7 0%,#64BBBB 100%);color:#fff;text-align:center;line-height:76rpx;font-size:30rpx;}
  590. .report-selector-btn.disabled{background:#D5DDE2;}
  591. .report-selector-cancel{margin-top:24rpx;text-align:center;font-size:28rpx;line-height:48rpx;color:#667E90;}
  592. .evaluation-mask{position:fixed;left:0;right:0;top:0;bottom:0;z-index:30;background:rgba(0,0,0,.45);}
  593. .evaluation-box{width:650rpx;background:#fff;border-radius:16rpx;padding:34rpx 28rpx 26rpx;box-sizing:border-box;}
  594. .evaluation-label{font-size:28rpx;font-weight:bold;color:#333;margin:18rpx 0 12rpx;}
  595. .evaluation-textarea{width:100%;height:180rpx;box-sizing:border-box;background:#f7f7f7;border-radius:8rpx;padding:18rpx;font-size:26rpx;color:#333;}
  596. .evaluation-actions{display:flex;justify-content:flex-end;gap:20rpx;margin-top:28rpx;}
  597. .evaluation-cancel,.evaluation-submit{padding:18rpx 28rpx;border-radius:10rpx;font-size:28rpx;}
  598. .evaluation-cancel{color:#666;background:#f2f2f2;}.evaluation-submit{color:#fff;background:#833478;}.evaluation-submit.disabled{opacity:.5;}
  599. </style>