PopularizationScience.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. <script setup lang="ts">
  2. import CpmdHeader from '@/components/CpmdHeader.vue';
  3. import { onMounted, onUnmounted, ref } from 'vue'
  4. import { format } from 'date-fns/format';
  5. import { menuStatusStore, userInfoStore } from '@/stores'
  6. import { userPlanApi } from '@/api/home';
  7. import { getUnread, planNumGet } from '@/utils/test';
  8. const userInfo = userInfoStore()
  9. const menuStatus = menuStatusStore();
  10. menuStatus.saveActiveIndex('2')
  11. const homeHeaderOut = ref<any>()
  12. const height = ref<number>()
  13. //心灵探索高度
  14. const xlts = ref<number>()
  15. //计划提醒的高度
  16. const plan_jihua = ref<number>()
  17. //显示标题及文本的标志
  18. const flag_text = ref<number>(1)
  19. //定时器标志
  20. const flag_time = ref<any>()
  21. //
  22. const centerDialogVisible = ref<boolean>(false)
  23. const moreList = ref<any>([
  24. {
  25. id: '6',
  26. title: 'MBTI16型人格测试',
  27. poster: 'mb',// 展示图
  28. qrCode: 'mbCode',
  29. isProfession: true,
  30. isRecommend: true
  31. },
  32. {
  33. id: '1',
  34. title: '标准情商测试',
  35. poster: 'qs',// 展示图
  36. qrCode: 'qsCode',
  37. isProfession: true,
  38. isRecommend: true
  39. },
  40. {
  41. id: '4',
  42. title: '你让异性心动指数有多高?',
  43. poster: 'xd',// 展示图
  44. qrCode: 'xdCode',
  45. isProfession: false,
  46. isRecommend: true
  47. },
  48. {
  49. id: '2',
  50. title: '测测你的睡眠质量吧!',
  51. poster: 'sm',// 展示图
  52. qrCode: 'smCode',
  53. isProfession: false,
  54. isRecommend: true
  55. },
  56. {
  57. id: '9',
  58. title: '职业心理年龄测试',
  59. poster: 'zy',// 展示图
  60. qrCode: 'zyCode',
  61. isProfession: true,
  62. isRecommend: false
  63. },
  64. {
  65. id: '3',
  66. title: '看一下自己“神经”是否正常?',
  67. poster: 'sj',// 展示图
  68. qrCode: 'sjCode',
  69. isProfession: false,
  70. isRecommend: false
  71. },
  72. {
  73. id: '5',
  74. title: '你是否正在逐渐老化?',
  75. poster: 'lh',// 展示图
  76. qrCode: 'lhCode',
  77. isProfession: false,
  78. isRecommend: false
  79. },
  80. {
  81. id: '8',
  82. title: '你的家庭关系健康吗?',
  83. poster: 'jk',// 展示图
  84. qrCode: 'jkCode',
  85. isProfession: false,
  86. isRecommend: false
  87. },
  88. {
  89. id: '10',
  90. title: '工作倦怠测试',
  91. poster: 'jd',// 展示图
  92. qrCode: 'jdCode',
  93. isProfession: false,
  94. isRecommend: false
  95. },
  96. {
  97. id: '7',
  98. title: '在婚姻里,你有安全感吗?',
  99. poster: 'aq',// 展示图
  100. qrCode: 'aqCode',
  101. isProfession: false,
  102. isRecommend: false
  103. }]
  104. )
  105. // vue3+vite 实现动态加载图片
  106. const requireImg = (name: string) => {
  107. return new URL(`../assets/moreTest/${name}.png`, import.meta.url).href
  108. }
  109. //保存二维码的变量
  110. const scaleObj = ref<any>({
  111. title: '你的家庭关系健康吗?',
  112. qrCode: 'jkCode',
  113. })
  114. //打开二维码
  115. const openCode = (item: any) => {
  116. scaleObj.value = item;
  117. centerDialogVisible.value = true
  118. }
  119. //得到图片,进行canvas下载
  120. const downImgByCanvas = () => {
  121. let id = "img";
  122. const canvas = document.createElement('canvas')
  123. const ctx: any = canvas.getContext('2d')
  124. //得到原始的宽高
  125. let sourceImage: any = document.getElementById(id);
  126. canvas.width = sourceImage.naturalWidth;
  127. canvas.height = sourceImage.naturalHeight;
  128. //保存图片到canvas
  129. ctx.drawImage(sourceImage, 0, 0);
  130. downJpgByCanvas(canvas);
  131. }
  132. //得到图片的url,然后下载
  133. const downImgByUrl = () => {
  134. let img: any = document.getElementById('img');
  135. downJpgByUrl(img.src);
  136. }
  137. //下载图片:通过canvas
  138. const downJpgByCanvas = (canvas: any) => {
  139. var oA = document.createElement("a");
  140. let time = timeFormat();
  141. oA.download = "img_" + time + '.jpg';// 设置下载的文件名,默认是'下载'
  142. oA.href = canvas.toDataURL("image/jpeg");
  143. document.body.appendChild(oA);
  144. oA.click();
  145. oA.remove(); // 下载之后把创建的元素删除
  146. }
  147. const downJpgByUrl = (url: string) => {
  148. let time = timeFormat();
  149. var a = document.createElement('a'); // 创建一个a节点插入的document
  150. var event = new MouseEvent('click') // 模拟鼠标click点击事件
  151. a.download = "img_" + time + '.jpg'; // 设置a节点的download属性值
  152. a.href = url; // 将图片的src赋值给a节点的href
  153. a.dispatchEvent(event)
  154. a.remove(); // 下载之后把创建的元素删除
  155. }
  156. //格式化时间
  157. const timeFormat = () => {
  158. var time = new Date();
  159. return format(time, "yyyy年MM月dd日 HH时mm分ss秒");
  160. }
  161. // //补0
  162. // const add0 = (m: number) => {
  163. // return m < 10 ? '0' + m : m
  164. // }
  165. //刚进入页面就将高度设置为页面需要的
  166. onMounted(() => {
  167. if (userInfo.token) {
  168. getUnread()
  169. planNumGet()
  170. }
  171. //进到界面开始轮询
  172. })
  173. //界面销毁函数
  174. //退出页面销毁 方法
  175. onUnmounted(() => {
  176. })
  177. </script>
  178. <template>
  179. <div class="home_header_out" ref="homeHeaderOut">
  180. <div class=" home_header_inner">
  181. <CpmdHeader />
  182. <div style="text-align: center;">
  183. <!-- <img class="xlts_img" style="margin-top:40px" src="../assets/home/other_text.png" /> -->
  184. </div>
  185. </div>
  186. <div style="background: linear-gradient( 180deg, #B2EDFF 0%, #FFFFFF 33%);padding-top: 20px;">
  187. <div class="leave_message">
  188. <!-- <img class="img" src="../assets/zs/community.png" alt=""> -->
  189. <div class="font_blue"> 更多测试 </div>
  190. </div>
  191. <div class="kply">
  192. <div class="kply_inner">
  193. <div
  194. style="padding:10px 0px;width: 100%;display: flex;flex-wrap: wrap;padding-bottom:20px;justify-content: space-between;">
  195. <div v-for="item in moreList" :key="item.id" class="out">
  196. <img class="poster" :src="requireImg(item.poster)">
  197. <div class="des">
  198. <div>
  199. <div class="scale_title">
  200. {{ item.title }}
  201. </div>
  202. <div style="display: flex;">
  203. <div v-show="item.isProfession">
  204. <!-- <img style="width: 80px;":src="requireImg('isProfession')"> -->
  205. <div class="isProfession">专业报告</div>
  206. </div>
  207. <span v-show="item.isProfession"> &nbsp;&nbsp;</span>
  208. <div v-show="item.isRecommend">
  209. <div class="isM">强烈推荐</div>
  210. <!-- <img style="width: 80px;" :src="requireImg('isM')"> -->
  211. </div>
  212. </div>
  213. </div>
  214. <div class="cyc"><span class="cyc_te" @click="openCode(item)">测一测</span></div>
  215. </div>
  216. </div>
  217. </div>
  218. </div>
  219. </div>
  220. </div>
  221. </div>
  222. <div class="code_dig">
  223. <el-dialog v-model="centerDialogVisible" :title="scaleObj.title" width="500" align-center>
  224. <template #footer>
  225. <div style="text-align: center;">
  226. <img id="img" :src="requireImg(scaleObj.qrCode)">
  227. </div>
  228. <div class="dialog-footer">
  229. <!-- <el-button @click="centerDialogVisible = false">关闭</el-button>
  230. <el-button type="primary">
  231. 下载
  232. </el-button> -->
  233. <div style="display: flex;justify-content: end;">
  234. <div class="close_code" @click="centerDialogVisible = false">关闭</div>
  235. <div class="down_code" @click="downImgByCanvas">下载</div>
  236. </div>
  237. <!-- <div>
  238. </div> -->
  239. </div>
  240. </template>
  241. </el-dialog>
  242. </div>
  243. </template>
  244. <style>
  245. .code_dig>>>.el-dialog {
  246. /* border-radius: 40px !important; */
  247. }
  248. </style>
  249. <style lang="scss" scoped>
  250. :deep(.el-dialog) {
  251. border-radius: 40px !important;
  252. }
  253. .home_header_out {
  254. scroll-snap-align: start;
  255. flex: 1;
  256. // position: relative;
  257. padding-bottom: 60px;
  258. width: 100%;
  259. min-width: 1200px;
  260. background-repeat: no-repeat;
  261. background-size: contain;
  262. // background-color: #B3F1DA; //估计是需要动态
  263. .home_header_inner {
  264. min-height: 1;
  265. left: 0;
  266. right: 0;
  267. margin: auto;
  268. // height: 100px;
  269. width: 100%;
  270. .xlts_img {
  271. height: 60px;
  272. }
  273. }
  274. .leave_message {
  275. left: 0;
  276. right: 0;
  277. margin: auto;
  278. width: 1200px;
  279. margin-bottom: 20px;
  280. // margin-top: 20px;
  281. .font_blue {
  282. position: relative;
  283. color: #30D5DD;
  284. font-weight: 700;
  285. font-size: 22px;
  286. font-family: 'Rammetto One-Regular';
  287. padding-top: 30px;
  288. z-index: 10;
  289. background: url(../assets/zs/more_test2.png) no-repeat;
  290. background-size: auto 50px;
  291. }
  292. }
  293. .kply {
  294. width: 100%;
  295. .kply_inner {
  296. left: 0;
  297. right: 0;
  298. margin: auto;
  299. width: 1200px;
  300. background-color: transparent;
  301. border-radius: 40px;
  302. display: flex;
  303. flex-direction: row;
  304. flex-wrap: wrap;
  305. .out {
  306. margin-bottom: 40px;
  307. background-color: #ffffff;
  308. width: 48%;
  309. // background-color: antiquewhite;
  310. display: flex;
  311. // box-shadow: 0px 4px 32px 0px rgba(0, 0, 0, 0.17);
  312. ;
  313. box-shadow: 0px 4px 31px 0px rgba(0, 0, 0, 0.09);
  314. padding: 20px;
  315. box-sizing: border-box;
  316. border-radius: 36px;
  317. .poster {
  318. width: 150px;
  319. // padding-left: 40px;
  320. }
  321. .des {
  322. padding-left: 20px;
  323. flex: 1;
  324. display: flex;
  325. flex-direction: column;
  326. justify-content: space-between;
  327. // background-color: aqua;
  328. .scale_title {
  329. letter-spacing: 3px;
  330. font-size: 20px;
  331. font-weight: 700;
  332. line-height: 40px;
  333. }
  334. .cyc {
  335. text-align: right;
  336. .cyc_te {
  337. margin-right: 40px;
  338. cursor: pointer;
  339. // width: 100px;
  340. border-radius: 14px;
  341. border: 2px solid #FF52CE;
  342. color: #ffffff;
  343. background-color: #000000;
  344. padding: 8px 30px;
  345. cursor: pointer;
  346. margin-bottom: 5px;
  347. // display: flex;
  348. align-items: center;
  349. }
  350. }
  351. .isProfession {
  352. color: #836000;
  353. background-color: #FFFF9F;
  354. font-size: 10px;
  355. border: 1px solid #E7DF42;
  356. padding: 2px 10px;
  357. border-radius: 4px;
  358. }
  359. .isM {
  360. color: #266208;
  361. background-color: #CFFF9F;
  362. font-size: 10px;
  363. border: 1px solid #6FEB32;
  364. padding: 2px 10px;
  365. border-radius: 4px;
  366. }
  367. }
  368. }
  369. }
  370. }
  371. }
  372. .close_code {
  373. border: 1px solid #cccaca;
  374. padding: 2px 20px;
  375. border-radius: 10px;
  376. cursor: pointer;
  377. height: 30px;
  378. display: flex;
  379. justify-content: center;
  380. align-items: center;
  381. font-size: 14px;
  382. }
  383. .down_code {
  384. margin-left: 20px;
  385. cursor: pointer;
  386. border: 2px solid #FF52CE;
  387. padding: 2px 20px;
  388. border-radius: 10px;
  389. background-color: #000000;
  390. color: #ffffff;
  391. display: flex;
  392. justify-content: center;
  393. align-items: center;
  394. height: 30px;
  395. font-size: 14px;
  396. }
  397. </style>