风险测评小程序前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

330 lines
8.4 KiB

1 week ago
1 week ago
2 days ago
2 days ago
2 days ago
2 days ago
1 week ago
2 days ago
1 week ago
1 week ago
2 days ago
1 week ago
2 days ago
2 days ago
1 week ago
1 week ago
  1. <template>
  2. <view ref="report" class="page__view export">
  3. <!-- <navbar title="报告" leftClick @leftClick="$utils.navigateBack" /> -->
  4. <template v-if="tempFilePath">
  5. <img
  6. :src="tempFilePath"
  7. @contextmenu.prevent
  8. style="display: block; width: 100vw; height: auto;"
  9. />
  10. </template>
  11. <template v-else-if="detail">
  12. <view class="title">{{ detail.title }}</view>
  13. <view class="section">
  14. <view class="flex section-header">
  15. <view class="line"></view>
  16. <view>总概述</view>
  17. </view>
  18. <view class="section-content">
  19. <view class="summary">
  20. <view class="text">
  21. 经过本次问答信息收集的综合分析检测出风险点共<text class="highlight">{{ detail.levelAllNum - detail.level3Num }}</text>其中高风险{{ detail.level2Num }}中风险{{ detail.level1Num }}低风险{{ detail.level0Num }}
  22. </view>
  23. <view class="flex charts">
  24. <progressCircle label="高风险" :value="detail.level2Num" color="#FF0000"></progressCircle>
  25. <progressCircle label="中风险" :value="detail.level1Num" color="#FFA800"></progressCircle>
  26. <progressCircle label="低风险" :value="detail.level0Num" color="#014FA2"></progressCircle>
  27. <progressCircle label="合规" :value="detail.level3Num" color="#5AC725"></progressCircle>
  28. </view>
  29. </view>
  30. <view class="table">
  31. <!-- 全部合规 -->
  32. <template v-if="detail.level3Num === detail.levelAllNum">
  33. <img ref="succ" class="img-succ" style="display: block;" :src="configList.compliance_img" crossorigin=anonymous />
  34. </template>
  35. <template v-else>
  36. <reportTableView :list="tableList"></reportTableView>
  37. </template>
  38. </view>
  39. </view>
  40. </view>
  41. <view class="flex flex-column contact" v-if="configList.company_qrcode">
  42. <view>扫下方二维码联系我们给你1V1解决方案</view>
  43. <img ref="qr" class="qr" style="display: block;" :src="configList.company_qrcode" crossorigin=anonymous />
  44. </view>
  45. <view>
  46. <img v-if="configList.company_info" ref="info" class="img" style="display: block;" :src="configList.company_info" crossorigin=anonymous />
  47. <view class="logo" v-if="configList.company_logo">
  48. <img ref="logo" class="img" style="display: block;" :src="configList.company_logo" crossorigin=anonymous />
  49. </view>
  50. </view>
  51. </template>
  52. </view>
  53. </template>
  54. <script>
  55. import html2canvas from 'html2canvas'
  56. import progressCircle from './progressCircle.vue';
  57. import reportTableView from './reportTableView.vue';
  58. export default {
  59. components: {
  60. progressCircle,
  61. reportTableView,
  62. },
  63. data() {
  64. return {
  65. batchNo: null,
  66. detail: null,
  67. tableList: [],
  68. canvas: null,
  69. tempFilePath: null
  70. }
  71. },
  72. async onLoad(arg) {
  73. uni.showLoading({
  74. title: '生成中...'
  75. })
  76. document.addEventListener('UniAppJSBridgeReady', function() {
  77. console.log('UniAppJSBridgeReady', uni)
  78. uni.getEnv(function(res) {
  79. console.log('当前环境:' + JSON.stringify(res));
  80. });
  81. })
  82. const { batchNo, token } = arg
  83. token && uni.setStorageSync('token', token)
  84. this.batchNo = batchNo
  85. },
  86. async mounted() {
  87. console.log('mounted', this.batchNo)
  88. await this.getData(this.batchNo)
  89. let fetchs = [
  90. { ref: 'qr', url: this.configList.company_qrcode },
  91. { ref: 'info', url: this.configList.company_info },
  92. { ref: 'logo', url: this.configList.company_logo },
  93. { ref: 'succ', url: this.configList.compliance_img },
  94. ].map(item => {
  95. return this.preLoadImage(item.ref, item.url)
  96. })
  97. await Promise.all(fetchs)
  98. setTimeout(async () => {
  99. await this.createImage()
  100. uni.hideLoading()
  101. // H5环境下提示用户长按保存
  102. uni.showModal({
  103. title: '保存报告',
  104. content: '请长按图片,选择"保存图片"即可保存到手机',
  105. showCancel: false,
  106. confirmText: '知道了'
  107. })
  108. }, 1000)
  109. },
  110. methods: {
  111. async getData(batchNo) {
  112. try {
  113. const result = await this.$fetch('queryReportById', { batchNo })
  114. const {
  115. title,
  116. level0Num, // 低风险
  117. level1Num, // 中风险
  118. level2Num, // 高风险
  119. level3Num, // 合规
  120. levelAllNum,
  121. pageList,
  122. } = result
  123. this.tableList = pageList.reduce((arr, item) => {
  124. const { id, risk, reason, level, consequence } = item
  125. if (level == '3') {
  126. return arr
  127. }
  128. const obj = {
  129. id,
  130. reason,
  131. level,
  132. result: consequence,
  133. }
  134. const index = arr.findIndex(row => row.title === risk)
  135. if (index === -1) {
  136. arr.push({
  137. id: arr.length,
  138. title: risk,
  139. children: [obj]
  140. })
  141. } else {
  142. arr[index].children.push(obj)
  143. }
  144. return arr
  145. }, [])
  146. this.detail = {
  147. title,
  148. level0Num, // 低风险
  149. level1Num, // 中风险
  150. level2Num, // 高风险
  151. level3Num, // 合规
  152. levelAllNum,
  153. }
  154. } catch (err) {
  155. }
  156. },
  157. async preLoadImage(ref, url) {
  158. return new Promise((resolve) => {
  159. console.log(ref, url)
  160. if (!this.$refs[ref] || !url) {
  161. resolve()
  162. return
  163. }
  164. uni.downloadFile({
  165. url,
  166. success: (res) => {
  167. if (res.statusCode === 200) {
  168. console.log('下载成功');
  169. this.$refs[ref].src = res.tempFilePath
  170. resolve()
  171. }
  172. },
  173. fail: (err) => {
  174. resolve()
  175. }
  176. });
  177. })
  178. },
  179. async createImage() {
  180. console.log('createImage')
  181. const node = document.querySelector('.export')
  182. const canvas = await html2canvas(node, { allowTaint: true, useCORS: true, })
  183. const image = canvas.toDataURL('image/png')
  184. this.tempFilePath = image
  185. uni?.postMessage?.({
  186. data: {
  187. imageData: image,
  188. }
  189. });
  190. },
  191. },
  192. }
  193. </script>
  194. <style scoped lang="scss">
  195. .title {
  196. width: 100%;
  197. padding: 42rpx 0 40rpx 0;
  198. box-sizing: border-box;
  199. text-align: center;
  200. font-size: 30rpx;
  201. font-weight: 600;
  202. color: #000000;
  203. }
  204. .section {
  205. padding: 0 12rpx;
  206. &-header {
  207. justify-content: flex-start;
  208. column-gap: 9rpx;
  209. padding: 0 17rpx;
  210. font-size: 28rpx;
  211. font-weight: 600;
  212. color: #014FA2;
  213. .line {
  214. width: 9rpx;
  215. height: 33rpx;
  216. background: #014FA2;
  217. border-radius: 6rpx;
  218. }
  219. }
  220. &-content {
  221. margin-top: 30rpx;
  222. }
  223. }
  224. .summary {
  225. .text {
  226. padding: 20rpx 10rpx;
  227. font-size: 26rpx;
  228. color: #014FA2;
  229. background: rgba($color: #014FA2, $alpha: 0.16);
  230. .highlight {
  231. color: #DB5742;
  232. }
  233. }
  234. .charts {
  235. margin-top: 54rpx;
  236. justify-content: space-between;
  237. padding: 0 42rpx;
  238. }
  239. }
  240. .table {
  241. margin-top: 49rpx;
  242. }
  243. .img-succ {
  244. width: 100%;
  245. height: auto;
  246. }
  247. .contact {
  248. margin-top: 53rpx;
  249. row-gap: 40rpx;
  250. width: 100%;
  251. padding: 30rpx 0 22rpx 0;
  252. box-sizing: border-box;
  253. font-size: 28rpx;
  254. color: #014FA2;
  255. border: 1rpx dashed #014FA2;
  256. .qr {
  257. width: 157rpx;
  258. height: auto;
  259. }
  260. }
  261. .img {
  262. width: 100%;
  263. height: auto;
  264. }
  265. .logo {
  266. width: 100%;
  267. padding: 42rpx 127rpx 46rpx 127rpx;
  268. box-sizing: border-box;
  269. }
  270. .bottom {
  271. position: sticky;
  272. left: 0;
  273. bottom: 0;
  274. width: 100%;
  275. padding: 35rpx 56rpx;
  276. padding-bottom: calc(env(safe-area-inset-bottom) + 35rpx);
  277. background: #FFFFFF;
  278. box-sizing: border-box;
  279. .btn {
  280. width: 100%;
  281. padding: 29rpx 0;
  282. font-size: 30rpx;
  283. line-height: 1.5;
  284. color: #FFFFFF;
  285. background: #014FA2;
  286. border-radius: 50rpx;
  287. }
  288. }
  289. </style>