hookehuyr

新增页面,添加页面逻辑

...@@ -8,10 +8,10 @@ VITE_PROXY_TARGET = http://voice.onwall.cn ...@@ -8,10 +8,10 @@ VITE_PROXY_TARGET = http://voice.onwall.cn
8 VITE_PROXY_PREFIX = /srv/ 8 VITE_PROXY_PREFIX = /srv/
9 9
10 # 打包输出文件夹名称 10 # 打包输出文件夹名称
11 -VITE_OUTDIR = voice 11 +VITE_OUTDIR = carbon
12 12
13 # 是否开启调试 13 # 是否开启调试
14 -VITE_CONSOLE = 0 14 +VITE_CONSOLE = 1
15 15
16 # appID相关 16 # appID相关
17 VITE_APPID=微信appID 17 VITE_APPID=微信appID
......
1 # 资源公共路径 1 # 资源公共路径
2 -VITE_BASE = /f/voice/ 2 +VITE_BASE = /f/carbon/
3 3
4 # 测试open-id 4 # 测试open-id
5 -VITE_APP_OPENID = 5 +VITE_APP_OPENID =
6 6
7 # B端账号 7 # B端账号
8 -VITE_APP_ID = 8 +VITE_APP_ID =
9 9
10 # 验证码 10 # 验证码
11 -VITE_APP_PIN = 11 +VITE_APP_PIN =
......
...@@ -13,3 +13,4 @@ src/test/mocha/test.js ...@@ -13,3 +13,4 @@ src/test/mocha/test.js
13 cypress.json 13 cypress.json
14 src/test 14 src/test
15 .idea 15 .idea
16 +carbon
......
...@@ -7,37 +7,12 @@ export {} ...@@ -7,37 +7,12 @@ export {}
7 7
8 declare module 'vue' { 8 declare module 'vue' {
9 export interface GlobalComponents { 9 export interface GlobalComponents {
10 - '图形验证码': typeof import('./src/components/图形验证码.vue')['default'] 10 + Danmaku: typeof import('./src/components/danmaku.vue')['default']
11 - Agreement: typeof import('./src/components/DonateFlower/agreement.vue')['default']
12 - AuditVideoCard: typeof import('./src/components/AuditVideoCard/index.vue')['default']
13 - Banner: typeof import('./src/components/MuiVideo/banner.vue')['default']
14 - BookCard: typeof import('./src/components/BookCard/index.vue')['default']
15 - BVideoCard: typeof import('./src/components/BVideoCard/index.vue')['default']
16 - CommentBox: typeof import('./src/components/CommentBox/index.vue')['default']
17 - CommentList: typeof import('./src/components/CommentList/index.vue')['default']
18 - DonateBar: typeof import('./src/components/DonateBar/index.vue')['default']
19 - DonateBook: typeof import('./src/components/DonateBook/index.vue')['default']
20 - DonateCert: typeof import('./src/components/DonateCert/index.vue')['default']
21 - DonateCertPost: typeof import('./src/components/DonateCertPost/index.vue')['default']
22 - DonateFlower: typeof import('./src/components/DonateFlower/index.vue')['default']
23 - FlowerIcon: typeof import('./src/components/FlowerIcon/index.vue')['default']
24 - ImageSliderVerify: typeof import('./src/components/ImageSliderVerify/index.vue')['default']
25 - LocalismBox: typeof import('./src/components/LocalismBox/index.vue')['default']
26 - LoginBox: typeof import('./src/components/LoginBox/index.vue')['default']
27 - MuiVideo: typeof import('./src/components/MuiVideo/index.vue')['default']
28 - MyButton: typeof import('./src/components/MyButton/index.vue')['default']
29 - NoticeOverlay: typeof import('./src/components/NoticeOverlay/index.vue')['default']
30 - NoticeOverlayModule: typeof import('./src/components/NoticeOverlayModule/index.vue')['default']
31 - RankingItem: typeof import('./src/components/RankingItem/index.vue')['default']
32 - RightSideList: typeof import('./src/components/RightSideList/index.vue')['default']
33 RouterLink: typeof import('vue-router')['RouterLink'] 11 RouterLink: typeof import('vue-router')['RouterLink']
34 RouterView: typeof import('vue-router')['RouterView'] 12 RouterView: typeof import('vue-router')['RouterView']
35 - ShortcutFixed: typeof import('./src/components/ShortcutFixed/index.vue')['default'] 13 + VanIcon: typeof import('vant/es')['Icon']
36 - Status: typeof import('./src/components/MuiVideo/status.vue')['default'] 14 + VanImage: typeof import('vant/es')['Image']
37 - Template: typeof import('./src/components/template/index.vue')['default'] 15 + VanLoading: typeof import('vant/es')['Loading']
38 - Test: typeof import('./src/components/LoginBox/test.vue')['default'] 16 + VanUploader: typeof import('vant/es')['Uploader']
39 - VideoBar: typeof import('./src/components/MuiVideo/videoBar.vue')['default']
40 - VideoCard: typeof import('./src/components/VideoCard/index.vue')['default']
41 - VideoDetail: typeof import('./src/components/VideoDetail/index.vue')['default']
42 } 17 }
43 } 18 }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
28 "vite-plugin-dynamic-import": "^0.9.6", 28 "vite-plugin-dynamic-import": "^0.9.6",
29 "vite-plugin-mp": "^1.6.1", 29 "vite-plugin-mp": "^1.6.1",
30 "vue": "^3.2.36", 30 "vue": "^3.2.36",
31 + "vue3-danmaku": "^1.6.0",
31 "weixin-js-sdk": "^1.6.5" 32 "weixin-js-sdk": "^1.6.5"
32 }, 33 },
33 "devDependencies": { 34 "devDependencies": {
...@@ -5928,6 +5929,14 @@ ...@@ -5928,6 +5929,14 @@
5928 "vue": "^3.2.0" 5929 "vue": "^3.2.0"
5929 } 5930 }
5930 }, 5931 },
5932 + "node_modules/vue3-danmaku": {
5933 + "version": "1.6.0",
5934 + "resolved": "https://mirrors.cloud.tencent.com/npm/vue3-danmaku/-/vue3-danmaku-1.6.0.tgz",
5935 + "integrity": "sha512-XjwVKIelupDD3PWn6k22l5qS8y+SCdFUYq4sSpcPInqk7CyzXWSAfz2BL6WWx9HU9CRWS3x2oDMkepLkJoWvNQ==",
5936 + "peerDependencies": {
5937 + "vue": "^3.0.0"
5938 + }
5939 + },
5931 "node_modules/webpack-sources": { 5940 "node_modules/webpack-sources": {
5932 "version": "3.2.3", 5941 "version": "3.2.3",
5933 "resolved": "https://mirrors.cloud.tencent.com/npm/webpack-sources/-/webpack-sources-3.2.3.tgz", 5942 "resolved": "https://mirrors.cloud.tencent.com/npm/webpack-sources/-/webpack-sources-3.2.3.tgz",
...@@ -10380,6 +10389,12 @@ ...@@ -10380,6 +10389,12 @@
10380 "@vue/devtools-api": "^6.5.0" 10389 "@vue/devtools-api": "^6.5.0"
10381 } 10390 }
10382 }, 10391 },
10392 + "vue3-danmaku": {
10393 + "version": "1.6.0",
10394 + "resolved": "https://mirrors.cloud.tencent.com/npm/vue3-danmaku/-/vue3-danmaku-1.6.0.tgz",
10395 + "integrity": "sha512-XjwVKIelupDD3PWn6k22l5qS8y+SCdFUYq4sSpcPInqk7CyzXWSAfz2BL6WWx9HU9CRWS3x2oDMkepLkJoWvNQ==",
10396 + "requires": {}
10397 + },
10383 "webpack-sources": { 10398 "webpack-sources": {
10384 "version": "3.2.3", 10399 "version": "3.2.3",
10385 "resolved": "https://mirrors.cloud.tencent.com/npm/webpack-sources/-/webpack-sources-3.2.3.tgz", 10400 "resolved": "https://mirrors.cloud.tencent.com/npm/webpack-sources/-/webpack-sources-3.2.3.tgz",
......
...@@ -9,7 +9,13 @@ ...@@ -9,7 +9,13 @@
9 "build-watch": "vite build --watch", 9 "build-watch": "vite build --watch",
10 "build-ts": "vue-tsc --noEmit && vite build", 10 "build-ts": "vue-tsc --noEmit && vite build",
11 "serve": "vite preview", 11 "serve": "vite preview",
12 - "cypress:open": "cypress open" 12 + "cypress:open": "cypress open",
13 + "tar": "tar -czvpf dist.tar.gz carbon",
14 + "build_tar": "npm run build && npm run tar",
15 + "scp-oa": "scp dist.tar.gz itomix@ipadbiz.cn:/opt/voice/f/",
16 + "dec-oa": "ssh itomix@ipadbiz.cn 'cd /opt/voice/f/ && tar -xzvf dist.tar.gz && rm -rf dist.tar.gz'",
17 + "remove_tar": "rm -rf dist.tar.gz",
18 + "oa_upload": "npm run build_tar && npm run scp-oa && npm run dec-oa && npm run remove_tar"
13 }, 19 },
14 "dependencies": { 20 "dependencies": {
15 "@vitejs/plugin-legacy": "^1.8.2", 21 "@vitejs/plugin-legacy": "^1.8.2",
...@@ -32,6 +38,7 @@ ...@@ -32,6 +38,7 @@
32 "vite-plugin-dynamic-import": "^0.9.6", 38 "vite-plugin-dynamic-import": "^0.9.6",
33 "vite-plugin-mp": "^1.6.1", 39 "vite-plugin-mp": "^1.6.1",
34 "vue": "^3.2.36", 40 "vue": "^3.2.36",
41 + "vue3-danmaku": "^1.6.0",
35 "weixin-js-sdk": "^1.6.5" 42 "weixin-js-sdk": "^1.6.5"
36 }, 43 },
37 "devDependencies": { 44 "devDependencies": {
......
...@@ -14,7 +14,7 @@ set -e ...@@ -14,7 +14,7 @@ set -e
14 path=/Users/huyirui/program/itomix/git/isp/f 14 path=/Users/huyirui/program/itomix/git/isp/f
15 15
16 # 编译输出文件夹 16 # 编译输出文件夹
17 -output=voice 17 +output=carbon
18 18
19 # 打包 19 # 打包
20 npm run build 20 npm run build
...@@ -37,4 +37,4 @@ git commit -m '前端网页更新' ...@@ -37,4 +37,4 @@ git commit -m '前端网页更新'
37 git push 37 git push
38 38
39 # 更新SSH服务器上文件 39 # 更新SSH服务器上文件
40 -# ssh -p 22 itomix@ipadbiz.cn 'cd /opt/voice/f/voice && git pull'`` 40 +# ssh -p 22 itomix@ipadbiz.cn 'cd /opt/voice/f/carbon && git pull'``
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
2 * @Author: hookehuyr hookehuyr@gmail.com 2 * @Author: hookehuyr hookehuyr@gmail.com
3 * @Date: 2022-05-26 23:52:36 3 * @Date: 2022-05-26 23:52:36
4 * @LastEditors: hookehuyr hookehuyr@gmail.com 4 * @LastEditors: hookehuyr hookehuyr@gmail.com
5 - * @LastEditTime: 2024-01-02 13:59:58 5 + * @LastEditTime: 2024-04-11 09:50:51
6 - * @FilePath: /tswj/src/App.vue 6 + * @FilePath: /fxPark/src/App.vue
7 * @Description: 7 * @Description:
8 --> 8 -->
9 <template> 9 <template>
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
2 * @Author: hookehuyr hookehuyr@gmail.com 2 * @Author: hookehuyr hookehuyr@gmail.com
3 * @Date: 2022-06-09 13:32:44 3 * @Date: 2022-06-09 13:32:44
4 * @LastEditors: hookehuyr hookehuyr@gmail.com 4 * @LastEditors: hookehuyr hookehuyr@gmail.com
5 - * @LastEditTime: 2022-06-14 14:47:01 5 + * @LastEditTime: 2024-04-11 06:06:06
6 - * @FilePath: /tswj/src/api/wx/config.js 6 + * @FilePath: /fxPark/src/api/wx/config.js
7 * @Description: 7 * @Description:
8 */ 8 */
9 import { fn, fetch } from '@/api/fn'; 9 import { fn, fetch } from '@/api/fn';
......
1 +<!--
2 + * @Date: 2024-04-10 14:16:36
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-04-10 14:22:14
5 + * @FilePath: /fxPark/src/components/danmaku.vue
6 + * @Description: 文件描述
7 +-->
8 +<template>
9 + <div class="danmaku-page">
10 + <vue-danmaku ref="danmaku" v-model:danmus="danmus" useSlot loop :channels="4" :speeds="50" :top="20" style="height:12rem; width:100vw; position: absolute; top:0; z-index: 10;">
11 + <template v-slot:dm="{ index, danmu }">
12 + <span style="background-color: rgba(48, 48, 48, 0.50); padding: 0.25rem 1rem; border-radius: 14px;">{{ index }}{{ danmu.name }}:{{ danmu.text }}</span>
13 + </template>
14 + </vue-danmaku>
15 + </div>
16 +</template>
17 +
18 +<script setup>
19 +import { ref } from 'vue'
20 +import { useRoute, useRouter } from 'vue-router'
21 +
22 +import vueDanmaku from 'vue3-danmaku'
23 +import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js'
24 +//import { } from '@/utils/generateModules.js'
25 +//import { } from '@/utils/generateIcons.js'
26 +//import { } from '@/composables'
27 +const $route = useRoute();
28 +const $router = useRouter();
29 +useTitle($route.meta.title);
30 +
31 +const danmaku = ref(null)
32 +const danmus = ref([{ avatar: 'http://a.com/a.jpg', name: 'a', text: 'aaa' }, { avatar: 'http://a.com/b.jpg', name: 'b', text: 'bbb' }])
33 +
34 +</script>
35 +
36 +<style lang="less" scoped>
37 +.danmaku-page {}
38 +</style>
1 /* 1 /*
2 * @Date: 2024-04-07 10:14:17 2 * @Date: 2024-04-07 10:14:17
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2024-04-07 10:28:36 4 + * @LastEditTime: 2024-04-11 09:39:29
5 * @FilePath: /fxPark/src/router/routes/modules/fxPark/index.js 5 * @FilePath: /fxPark/src/router/routes/modules/fxPark/index.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
8 const index = [{ 8 const index = [{
9 - path: '/fxPark', 9 + path: '/',
10 name: '“碳”寻复兴公园', 10 name: '“碳”寻复兴公园',
11 component: () => import('@/views/fxPark/index.vue'), 11 component: () => import('@/views/fxPark/index.vue'),
12 redirect: '', 12 redirect: '',
...@@ -14,6 +14,42 @@ const index = [{ ...@@ -14,6 +14,42 @@ const index = [{
14 title: '“碳”寻复兴公园', 14 title: '“碳”寻复兴公园',
15 }, 15 },
16 children: [], 16 children: [],
17 +}, {
18 + path: '/audio',
19 + name: '植物之声',
20 + component: () => import('@/views/fxPark/audio.vue'),
21 + redirect: '',
22 + meta: {
23 + title: '植物之声',
24 + },
25 + children: [],
26 +}, {
27 + path: '/intro',
28 + name: '植被介绍',
29 + component: () => import('@/views/fxPark/intro.vue'),
30 + redirect: '',
31 + meta: {
32 + title: '植被介绍',
33 + },
34 + children: [],
35 +}, {
36 + path: '/share',
37 + name: '生成海报±',
38 + component: () => import('@/views/fxPark/share.vue'),
39 + redirect: '',
40 + meta: {
41 + title: '生成海报±',
42 + },
43 + children: [],
44 +}, {
45 + path: '/poster',
46 + name: '生成海报',
47 + component: () => import('@/views/fxPark/poster.vue'),
48 + redirect: '',
49 + meta: {
50 + title: '生成海报',
51 + },
52 + children: [],
17 },] 53 },]
18 54
19 export default index; 55 export default index;
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
2 * @Author: hookehuyr hookehuyr@gmail.com 2 * @Author: hookehuyr hookehuyr@gmail.com
3 * @Date: 2022-05-28 10:17:40 3 * @Date: 2022-05-28 10:17:40
4 * @LastEditors: hookehuyr hookehuyr@gmail.com 4 * @LastEditors: hookehuyr hookehuyr@gmail.com
5 - * @LastEditTime: 2024-01-02 18:02:31 5 + * @LastEditTime: 2024-04-10 17:37:44
6 - * @FilePath: /tswj/src/utils/axios.js 6 + * @FilePath: /fxPark/src/utils/axios.js
7 * @Description: 7 * @Description:
8 */ 8 */
9 import axios from 'axios'; 9 import axios from 'axios';
...@@ -13,7 +13,8 @@ import { strExist } from '@/utils/tools' ...@@ -13,7 +13,8 @@ import { strExist } from '@/utils/tools'
13 // import { parseQueryString } from '@/utils/tools' 13 // import { parseQueryString } from '@/utils/tools'
14 14
15 axios.defaults.params = { 15 axios.defaults.params = {
16 - f: 'voice', 16 + f: 'carbon',
17 + client_id: 313939,
17 }; 18 };
18 19
19 /** 20 /**
......
...@@ -17,7 +17,7 @@ onMounted(() => { ...@@ -17,7 +17,7 @@ onMounted(() => {
17 */ 17 */
18 let raw_url = encodeURIComponent(location.origin + location.pathname + $route.query.href); // 未授权的地址 18 let raw_url = encodeURIComponent(location.origin + location.pathname + $route.query.href); // 未授权的地址
19 // TAG: 开发环境测试数据 19 // TAG: 开发环境测试数据
20 - const short_url = `/srv/?f=voice&a=openid_${$route.query.prefixAPI}&res=${raw_url}`; 20 + const short_url = `/srv/?f=carbon&a=openid_c&res=${raw_url}`;
21 location.href = import.meta.env.DEV 21 location.href = import.meta.env.DEV
22 ? `${short_url}&input_openid=${import.meta.env.VITE_OPENID}` 22 ? `${short_url}&input_openid=${import.meta.env.VITE_OPENID}`
23 : `${short_url}`; 23 : `${short_url}`;
......
1 +<!--
2 + * @Date: 2024-04-10 15:08:08
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-04-10 15:54:46
5 + * @FilePath: /fxPark/src/views/fxPark/audio.vue
6 + * @Description: 文件描述
7 +-->
8 +<template>
9 + <div class="audio-page">
10 + <div class="audio-player">
11 + <div style="margin-right: 1rem;">
12 + <van-icon name="circle" size="5rem" />
13 + </div>
14 + <div>
15 + <div style="margin-bottom: 1rem;">微风轻轻吹树叶的声音</div>
16 + <div style="display: flex; justify-content: space-between;">
17 + <van-icon name="arrow-left" size="1.5rem" />
18 + <van-icon name="play" size="1.5rem" @click="audioPlayer.play()" />
19 + <van-icon name="pause" size="1.5rem" @click="audioPlayer.pause()" />
20 + <van-icon name="arrow" size="1.5rem" />
21 + </div>
22 + </div>
23 + <div>
24 + <audio ref="audioPlayer" loop="loop" id="audios" src="https://m10.music.126.net/20240410161841/940e4a035f48a82b1b4d4b01b2e7b1f1/ymusic/5353/0f0f/0358/d99739615f8e5153d77042092f07fd77.mp3" preoload></audio>
25 + </div>
26 + </div>
27 + </div>
28 +</template>
29 +
30 +<script setup>
31 +import { ref } from 'vue'
32 +import { useRoute, useRouter } from 'vue-router'
33 +
34 +import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js'
35 +//import { } from '@/utils/generateModules.js'
36 +//import { } from '@/utils/generateIcons.js'
37 +//import { } from '@/composables'
38 +const $route = useRoute();
39 +const $router = useRouter();
40 +useTitle($route.meta.title);
41 +
42 +const audioPlayer = ref(null);
43 +
44 +</script>
45 +
46 +<style lang="less" scoped>
47 +.audio-page {
48 + height: 100vh;
49 + position: relative;
50 + background-color: #47A3E4;
51 + display: flex;
52 + justify-content: center;
53 + .audio-player {
54 + border: 1px solid #fff;
55 + border-radius: 10px;
56 + padding: 1rem 2rem 1rem 1rem;
57 + position: absolute;
58 + top: 5rem;
59 + display: flex;
60 + justify-content: center;
61 + align-items: center;
62 + }
63 +}
64 +</style>
1 <!-- 1 <!--
2 * @Date: 2024-04-07 10:15:55 2 * @Date: 2024-04-07 10:15:55
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2024-04-07 10:19:13 4 + * @LastEditTime: 2024-04-10 15:01:38
5 * @FilePath: /fxPark/src/views/fxPark/index.vue 5 * @FilePath: /fxPark/src/views/fxPark/index.vue
6 * @Description: 文件描述 6 * @Description: 文件描述
7 --> 7 -->
8 <template> 8 <template>
9 - <div class="">123</div> 9 + <div class="fxPark-page">
10 + <danmaku />
11 + <div class="quick-entrance-wrapper">
12 + <div class="quick-entrance-item" style="">
13 + <van-icon name="chat-o" />&nbsp;&nbsp;<span>植物之声</span>
14 + </div>
15 + </div>
16 + <div class="container" v-for="(item, index) in img_list" :key="index" @click="onClick(item)">
17 + <img :src="item.src" class="img">
18 + </div>
19 + </div>
10 </template> 20 </template>
11 21
12 <script setup> 22 <script setup>
...@@ -17,12 +27,76 @@ import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@ ...@@ -17,12 +27,76 @@ import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@
17 //import { } from '@/utils/generateModules.js' 27 //import { } from '@/utils/generateModules.js'
18 //import { } from '@/utils/generateIcons.js' 28 //import { } from '@/utils/generateIcons.js'
19 //import { } from '@/composables' 29 //import { } from '@/composables'
30 +import danmaku from '@/components/danmaku.vue'
31 +
32 +// 初始化WX环境
33 +import wx from 'weixin-js-sdk'
34 +
20 const $route = useRoute(); 35 const $route = useRoute();
21 const $router = useRouter(); 36 const $router = useRouter();
22 useTitle($route.meta.title); 37 useTitle($route.meta.title);
23 38
39 +const img_list = ref([{
40 + src:'https://cdn.ipadbiz.cn/tmp/fx_park/s1.png' ,
41 +}, {
42 + src:'https://cdn.ipadbiz.cn/tmp/fx_park/s2.png' ,
43 +}, {
44 + src:'https://cdn.ipadbiz.cn/tmp/fx_park/s3.png' ,
45 +}, {
46 + src:'https://cdn.ipadbiz.cn/tmp/fx_park/s4.png' ,
47 +}, {
48 + src:'https://cdn.ipadbiz.cn/tmp/fx_park/s5.png' ,
49 +}, {
50 + src:'https://cdn.ipadbiz.cn/tmp/fx_park/s6.png' ,
51 +},])
52 +
53 +const onClick = (item) => {
54 + wx.scanQRCode({
55 + needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
56 + scanType: ["qrCode","barCode"], // 可以指定扫二维码还是一维码,默认二者都有
57 + success: function (res) {
58 + var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
59 + console.log("🚀 ~ file: index.vue:73 ~ onClick ~ result:", result);
60 + },
61 + fail: function (res) {
62 + console.log("🚀 ~ file: index.vue:77 ~ onClick ~ res:", res);
63 + }
64 + });
65 +}
24 </script> 66 </script>
25 67
26 <style lang="less" scoped> 68 <style lang="less" scoped>
27 - 69 +.fxPark-page {
70 + .quick-entrance-wrapper {
71 + .quick-entrance-item {
72 + position: absolute;
73 + right: 0;
74 + top: 1.5rem;
75 + color: white;
76 + background-color: green;
77 + border-top-left-radius: 1rem;
78 + border-bottom-left-radius: 1rem;
79 + z-index: 20;
80 + font-size: 0.9rem;
81 + padding: 0.5rem;
82 + }
83 + }
84 + .container {
85 + width: 100%;
86 + height: 100%;
87 + background-size: contain;
88 + position: absolute;
89 + z-index: 1;
90 + top: 0;
91 + left: 0;
92 + background-repeat: no-repeat;
93 + .img {
94 + position: absolute;
95 + top: 0;
96 + left: 0;
97 + width: 100%;
98 + object-fit: cover;
99 + }
100 + }
101 +}
28 </style> 102 </style>
......
1 +<!--
2 + * @Date: 2024-04-10 16:08:09
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-04-10 17:24:25
5 + * @FilePath: /fxPark/src/views/fxPark/intro.vue
6 + * @Description: 文件描述
7 +-->
8 +<template>
9 + <div class="intro-page">
10 + <div></div>
11 + <div style="margin: 1rem;">
12 + <div style="margin-bottom: 1rem;">
13 + <span style="font-size: 1.25rem;">悬铃木</span>
14 + <span style="font-size: 0.85rem;">智者长老</span>
15 + </div>
16 + <div style="border: 1px solid #000; padding: 1rem; border-radius: 8px;">
17 + <div style="margin-bottom: 1.5rem;"><span style="background-color: #D0FCF0; padding: 0.5rem 0.75rem; border-radius: 1rem;">植被类型:</span>&nbsp;待补充</div>
18 + <div style="margin-bottom: 1.5rem;"><span style="background-color: #D0FCF0; padding: 0.5rem 0.75rem; border-radius: 1rem;">植被学名:</span>&nbsp;待补充</div>
19 + <div style="margin-bottom: 1.5rem;">
20 + 截至2022年累计固定二氧化碳约7.7吨,可抵消用煤炭发电7.7万度所排放的二氧化碳量,或者可抵消一辆轻型汽车行驶绕地球1周排放的二氧化碳量。
21 + </div>
22 + <div style="margin-bottom: 1rem;"><span style="background-color: #D0FCF0; padding: 0.5rem 0.75rem; border-radius: 1rem;">植被介绍:</span></div>
23 + <div>
24 + 这棵悬铃木已经有120岁,胸径为123cm,被称为“沪上老二”,拥有悠久的历史和深厚的底蕴。<br/>
25 + 悬铃木生长快,成型后树大荫浓,是作为庭荫树和行道树的优良树种,是上海最常见的行道树种之一。
26 + </div>
27 + </div>
28 + </div>
29 + <div class="task-tips">
30 + <div class="title-wrapper">
31 + <span class="title-text">任务卡</span>
32 + </div>
33 + <div class="task-wrapper">
34 + <div class="task-title">自带咖啡杯</div>
35 + <div>去咖啡店时自带咖啡杯,<br/>代替一次性纸杯。</div>
36 + </div>
37 + </div>
38 + <div class="light-up-text">恭喜您植被已被点亮</div>
39 + <div style="margin: 1rem 1rem 2rem 1rem; color: white; text-align: center;">
40 + <div style="background-color: #F68015; display: inline-block; padding: 0.7rem 2rem; border-radius: 1.5rem;">生成海报</div>
41 + </div>
42 + </div>
43 +</template>
44 +
45 +<script setup>
46 +import { ref } from 'vue'
47 +import { useRoute, useRouter } from 'vue-router'
48 +
49 +import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js'
50 +//import { } from '@/utils/generateModules.js'
51 +//import { } from '@/utils/generateIcons.js'
52 +//import { } from '@/composables'
53 +const $route = useRoute();
54 +const $router = useRouter();
55 +useTitle($route.meta.title);
56 +
57 +</script>
58 +
59 +<style lang="less" scoped>
60 +.intro-page {
61 + display: flex;
62 + flex-direction: column;
63 + .task-tips {
64 + .title-wrapper {
65 + text-align: center;
66 + .title-text {
67 + font-size: 24px;
68 + font-weight: bold;
69 + color: #BBFEE2; /* 文字颜色 */
70 + text-shadow:
71 + -1px -1px 0 #000,
72 + 1px -1px 0 #000,
73 + -1px 1px 0 #000,
74 + 1px 1px 0 #000;
75 + }
76 + }
77 + .task-wrapper {
78 + border: 1px solid #000;
79 + margin: 1rem;
80 + padding: 1rem;
81 + border-radius: 10px;
82 + background: linear-gradient(to bottom, #FBFFE9, #BEE9F8);
83 + text-align: center;
84 + .task-title {
85 + background-color: #D6F4BD;
86 + padding: 0.5rem 1.5rem;
87 + border-radius: 1.5rem;
88 + display: inline-block;
89 + font-weight: bold;
90 + margin-bottom: 1rem;
91 + }
92 + }
93 + }
94 + .light-up-text {
95 + text-align: center;
96 + font-size: 24px;
97 + font-weight: bold;
98 + color: #F8E9C1; /* 文字颜色 */
99 + text-shadow:
100 + -1px -1px 0 #000,
101 + 1px -1px 0 #000,
102 + -1px 1px 0 #000,
103 + 1px 1px 0 #000;
104 + margin: 1rem 0;
105 + }
106 +}
107 +</style>
1 +<template>
2 + <div class="poster-page">
3 + <div style="height: calc(83vh - 2rem); padding: 1rem;">
4 + <div v-if="flag" ref="canvasRef" style="position: relative; padding: 1rem; background-color: #fff;">
5 + <div style="position: absolute; top: 3rem; left: 2rem; color: #FFF; writing-mode: vertical-lr; text-orientation: upright;">
6 + <div style="position: relative;">
7 + <span style="font-size: 2.5rem; font-weight: bolder; letter-spacing: 5px;">悬铃木</span>
8 + <div style="position: absolute; bottom: -1rem; letter-spacing: 5px;">智者长老</div>
9 + </div>
10 + </div>
11 + <img :src="imgSrc" style="width: 100%; height: 67vh;">
12 + <div style="color: #CCCCCC; margin-top: 1rem;">
13 + <div style="font-weight: bold; text-decoration: underline; margin-bottom: 0.5rem;">自带咖啡杯</div>
14 + <div style="font-size: 0.9rem;">去咖啡店时自带咖啡杯,代替一次性纸杯。</div>
15 + </div>
16 + </div>
17 + <div v-if="imgUrl">
18 + <img :src="imgUrl" alt="" crossOrigin="anonymous" :style="{ width: ref_width, height: ref_height }">
19 + </div>
20 + </div>
21 + <div class="poster-control-wrapper">
22 + <p class="save-text">长按保存到相册</p>
23 + <div class="poster-control">
24 + <div class="poster-prev">上一个</div>
25 + <van-uploader :before-read="beforeRead" :after-read="afterRead" :max-size="1000 * 1024" accept="file">
26 + <div v-if="!upload_loading" class="poster-upload-btn" style="">上传图片</div>
27 + <van-loading v-else size="24px" color="#E82D2D" text-color="#E82D2D" vertical>上传中...</van-loading>
28 + </van-uploader>
29 + <div class="poster-next">下一个</div>
30 + </div>
31 + </div>
32 + </div>
33 +</template>
34 +
35 +<script setup>
36 +import { ref } from 'vue'
37 +import { useRoute, useRouter } from 'vue-router'
38 +import { v4 as uuidv4 } from 'uuid';
39 +import { qiniuTokenAPI, qiniuUploadAPI, saveFileAPI } from '@/api/common';
40 +import html2canvas from "html2canvas";
41 +import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js'
42 +//import { } from '@/utils/generateModules.js'
43 +//import { } from '@/utils/generateIcons.js'
44 +//import { } from '@/composables'
45 +const $route = useRoute();
46 +const $router = useRouter();
47 +useTitle($route.meta.title);
48 +
49 +const canvasRef = ref(null);
50 +const imgUrl = ref('');
51 +const imgSrc = ref('https://picsum.photos/800');
52 +const flag = ref(true);
53 +const ref_width = ref('');
54 +const ref_height = ref('');
55 +
56 +onMounted(async () => {
57 + nextTick(() => {
58 + let canvasDom = canvasRef.value;
59 + ref_width.value = canvasDom.offsetWidth + 'px';
60 + ref_height.value = canvasDom.offsetHeight + 'px';
61 + // const screenWidth = window.innerWidth;
62 + // alert(screenWidth); // 输出移动设备屏幕的宽度
63 + });
64 + createImage();
65 +});
66 +
67 +// 获取像素比
68 +const DPR = () => {
69 + // 获取设备dpi
70 + if (window.devicePixelRatio && window.devicePixelRatio > 1) {
71 + return window.devicePixelRatio * 2
72 + }
73 + // 直接返回高像素比
74 + return 8
75 +}
76 +
77 +const createImage = () => {
78 + nextTick(() => {
79 + // 获取要生成图片的 DOM 元素
80 + let canvasDom = canvasRef.value;
81 + const options = {
82 + backgroundColor: '#fff',
83 + // canvas: canvas,
84 + useCORS: true,//配置允许跨域
85 + scale: DPR(),
86 + // windowWidth: document.body.scrollWidth,
87 + // windowHeight: document.body.scrollHeight,
88 + // x: 0,
89 + // y: window.pageYOffset,
90 + // allowTaint: true,
91 + // background: "#d21f2c", // 一定要添加背景颜色,否则出来的图片,背景全部都是透明的
92 + // dpi: 300 // 处理模糊问题
93 + };
94 + // console.log("获取指定的宽高", width, height, canvas);
95 + html2canvas(canvasDom, options)
96 + .then(canvas => {
97 + try {
98 + // 生成图片地址
99 + imgUrl.value = canvas.toDataURL("image/png");
100 + // console.log("canvas.toDataURL('image/png')", this.imgUrl);
101 + flag.value = false;
102 + } catch (e) {
103 + alert("图片跨域,保存失败");
104 + }
105 + })
106 + .catch(error => {
107 + console.error("绘制失败");
108 + console.error(error);
109 + });
110 + });
111 +}
112 +
113 +const upload_loading = ref(false);
114 +const beforeRead = (file) => {
115 + // if (file.type.indexOf('audio') < 0) {
116 + // showToast('请上传音频格式');
117 + // return false;
118 + // }
119 + return true;
120 +};
121 +
122 +const afterRead = async (res) => {
123 + upload_loading.value = true;
124 + let affix = uuidv4();
125 + // 此时可以自行将文件上传至服务器
126 + let dataURL = res.content;
127 + let base64url = dataURL.slice(dataURL.indexOf(',') + 1); // 截取前缀的base64 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAnoAAAJeCAYAA.......
128 + // 获取七牛token
129 + const { token, key, code } = await qiniuTokenAPI({ filename: `${affix}_${res.file.name}`, file: base64url });
130 + if (code) {
131 + const config = {
132 + headers: {
133 + 'Content-Type': 'application/octet-stream',
134 + 'Authorization': 'UpToken ' + token, // UpToken后必须有一个 ' '(空格)
135 + }
136 + }
137 + // 上传七牛服务器
138 + const { filekey, hash, image_info } = await qiniuUploadAPI('http://upload.qiniup.com/putb64/-1/key/' + key, base64url, config)
139 + if (filekey) {
140 + // 保存图片
141 + const { data } = await saveFileAPI({ filekey, hash, format: '0', height: '0', width: '0' });
142 + flag.value = true;
143 + imgUrl.value = '';
144 + imgSrc.value = data.src;
145 + upload_loading.value = false;
146 + createImage();
147 + }
148 + }
149 +};
150 +</script>
151 +
152 +<style lang="less" scoped>
153 +.poster-page {
154 + height: 100vh;
155 + background-color: green;
156 + .poster-control-wrapper {
157 + .save-text {
158 + text-align: center;
159 + margin-top: 2rem;
160 + margin-bottom: 1rem;
161 + color: #fff;
162 + font-size: 0.9rem;
163 + }
164 + .poster-control {
165 + display: flex;
166 + justify-content: space-between;
167 + align-items: center;
168 + .poster-prev {
169 + background-color: rgba(0, 0, 0, 0.3);
170 + color: #FFF;
171 + padding: 0.5rem 0.8rem 0.5rem 1rem;
172 + border-top-right-radius: 15px;
173 + border-bottom-right-radius: 15px;
174 + font-size: 0.9rem;
175 + }
176 + .poster-next {
177 + background-color: rgba(0, 0, 0, 0.3);
178 + color: #FFF;
179 + padding: 0.5rem 1rem 0.5rem 0.8rem;
180 + border-top-left-radius: 15px;
181 + border-bottom-left-radius: 15px;
182 + font-size: 0.9rem;
183 + }
184 + .poster-upload-btn {
185 + display: inline-block;
186 + background-color: #F68015;
187 + color: #fff;
188 + padding: 0.5rem 2.5rem;
189 + border-radius: 1.5rem;
190 + font-size: 0.95rem;
191 + }
192 + }
193 + }
194 +}
195 +</style>
1 +<!--
2 + * @Date: 2023-12-30 22:43:25
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-04-11 13:29:29
5 + * @FilePath: /fxPark/src/views/fxPark/share.vue
6 + * @Description: 文件描述
7 +-->
8 +<template>
9 + <div class="share-page">
10 + <div v-if="flag" ref="canvasRef" class="share-bg">
11 + <div style="width: 90vw; height: 90vh;position: relative; overflow: hidden;">
12 + <img src="https://cdn.ipadbiz.cn/gy/new_year_2024/-h-%E6%96%B0%E5%B9%B4%E7%AD%BE.png" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); max-width: 100%; max-height: 100%;">
13 + </div>
14 + <div style="text-align: center; position: absolute; top: 27.5vh; left: calc(50% - 10vw); font-size: 0.6rem;color:#000;">交往 · 交流 · 交融</div>
15 + <div class="desc-text" v-for="(item, index) in sloganStyle" :key="index" :style="{ ...item }">{{ stringToArray(slogan)[index] }}</div>
16 + <!-- <img :src="qr_code" :style="{ ...qrCodeStyle }"> -->
17 + <div style="text-align: center; position: absolute; bottom: 11vh; left: calc(50% - 15vw); font-size: 0.8rem;color:#c53447;">收听来自远方的祝福</div>
18 + </div>
19 + <div v-if="imgUrl" class="share-img">
20 + <img :src="imgUrl" alt="" crossOrigin="anonymous" :style="{ width: ref_width, height: ref_height }">
21 + </div>
22 + <div v-if="wish_list.length > 1" class="control-wrapper">
23 + <div class="prev" @click="prevWish">上一个</div>
24 + <div>长按保存到相册分享</div>
25 + <div class="next" @click="nextWish">下一个</div>
26 + </div>
27 + <div v-else class="control-wrapper" style="justify-content: center;">
28 + <div>长按保存到相册分享</div>
29 + </div>
30 + </div>
31 +</template>
32 +
33 +<script setup>
34 +import { ref } from 'vue'
35 +import { useRoute, useRouter } from 'vue-router'
36 +import { shareWishListAPI } from '@/api/new_year_2024.js'
37 +import { showToast } from 'vant';
38 +import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js'
39 +//import { } from '@/utils/generateModules.js'
40 +//import { } from '@/utils/generateIcons.js'
41 +//import { } from '@/composables'
42 +// import qr_code from '@images/new_year_2024/http_qr_code.png'
43 +
44 +const $route = useRoute();
45 +const $router = useRouter();
46 +useTitle($route.meta.title);
47 +
48 +const wish_index = ref(0);
49 +const slogan = ref('');
50 +const wish_list = ref([]);
51 +
52 +const canvasRef = ref(null);
53 +const imgUrl = ref('');
54 +const flag = ref(true);
55 +const ref_width = ref('');
56 +const ref_height = ref('');
57 +
58 +// TAG: slogan位置配置
59 +const sloganStyle = [{
60 + top: '34vh',
61 + left: '26vw',
62 + fontSize: '14vw'
63 +}, {
64 + top: '34vh',
65 + right: '26vw',
66 + fontSize: '14vw'
67 +}, {
68 + top: '48vh',
69 + left: '26vw',
70 + fontSize: '14vw'
71 +}, {
72 + top: '48vh',
73 + right: '26vw',
74 + fontSize: '14vw'
75 +}];
76 +
77 +const qrCodeStyle = ref({
78 + position: 'absolute',
79 + bottom: '15.5vh',
80 + left: '36vw',
81 + width: '19vw',
82 + height: '10vh',
83 +})
84 +
85 +onMounted(async () => {
86 + nextTick(() => {
87 + let canvasDom = canvasRef.value;
88 + ref_width.value = canvasDom.offsetWidth + 'px';
89 + ref_height.value = canvasDom.offsetHeight + 'px';
90 + // const screenWidth = window.innerWidth;
91 + // alert(screenWidth); // 输出移动设备屏幕的宽度
92 + });
93 + const { code, data } = await shareWishListAPI();
94 + if (code) {
95 + wish_list.value = data;
96 + if (wish_list.value.length) {
97 + slogan.value = wish_list.value[wish_index.value].slogon;
98 + createImage();
99 + }
100 + }
101 +});
102 +
103 +const stringToArray = (str) => {
104 + return str.split('');
105 +}
106 +
107 +const prevWish = () => {
108 + if (!wish_index.value) {
109 + showToast('已经是第一张了');
110 + return;
111 + }
112 + wish_index.value -= 1;
113 + slogan.value = wish_list.value[wish_index.value].slogon;
114 + // 生成图片
115 + imgUrl.value = '';
116 + flag.value = true;
117 + createImage();
118 +}
119 +
120 +const nextWish = () => {
121 + if (wish_index.value === wish_list.value.length - 1) {
122 + showToast('已经是最后一张了');
123 + return;
124 + }
125 + wish_index.value += 1;
126 + slogan.value = wish_list.value[wish_index.value].slogon;
127 + // 生成图片
128 + imgUrl.value = '';
129 + flag.value = true;
130 + createImage();
131 +}
132 +
133 +// 获取像素比
134 +const DPR = () => {
135 + // 获取设备dpi
136 + if (window.devicePixelRatio && window.devicePixelRatio > 1) {
137 + return window.devicePixelRatio * 2
138 + }
139 + // 直接返回高像素比
140 + return 8
141 +}
142 +
143 +const createImage = () => {
144 + nextTick(() => {
145 + // 获取要生成图片的 DOM 元素
146 + let canvasDom = canvasRef.value;
147 + const options = {
148 + backgroundColor: '#d21f2c',
149 + // canvas: canvas,
150 + useCORS: true,//配置允许跨域
151 + scale: DPR(),
152 + // windowWidth: document.body.scrollWidth,
153 + // windowHeight: document.body.scrollHeight,
154 + // x: 0,
155 + // y: window.pageYOffset,
156 + // allowTaint: true,
157 + // background: "#d21f2c", // 一定要添加背景颜色,否则出来的图片,背景全部都是透明的
158 + // dpi: 300 // 处理模糊问题
159 + };
160 + // console.log("获取指定的宽高", width, height, canvas);
161 + html2canvas(canvasDom, options)
162 + .then(canvas => {
163 + try {
164 + // 生成图片地址
165 + imgUrl.value = canvas.toDataURL("image/png");
166 + // console.log("canvas.toDataURL('image/png')", this.imgUrl);
167 + flag.value = false;
168 + } catch (e) {
169 + alert("图片跨域,保存失败");
170 + }
171 + })
172 + .catch(error => {
173 + console.error("绘制失败");
174 + console.error(error);
175 + });
176 + });
177 +}
178 +</script>
179 +
180 +<script>
181 +import mixin from 'common/mixin';
182 +import html2canvas from "html2canvas";
183 +import wx from 'weixin-js-sdk'
184 +
185 +export default {
186 + mixins: [mixin.init],
187 + data() {
188 + return {
189 + }
190 + },
191 + mounted() {
192 + },
193 + methods: {
194 + }
195 +}
196 +</script>
197 +
198 +<style lang="less" scoped>
199 +.share-page {
200 + position: relative;
201 + background-color: #d21f2c;
202 + height: 100vh;
203 + width: 100vw;
204 + .share-bg {
205 + position: absolute;
206 + // top: 8vh;
207 + top: 0;
208 + left: 5vw;
209 + width: 90vw;
210 + height: 90vh;
211 + // background-image: url('https://cdn.ipadbiz.cn/gy/new_year_2024/%E6%96%B0%E5%B9%B4%E7%AD%BE@2x.png');
212 + // background-image: url('https://cdn.ipadbiz.cn/gy/new_year_2024/-h-%E6%96%B0%E5%B9%B4%E7%AD%BE.png');
213 + // background-repeat: no-repeat;
214 + // background-size: contain;
215 + // background-position: center;
216 + .desc-text {
217 + color: #c53447;
218 + // font-size: 13vw;
219 + // font-size: 7vh;
220 + // font-size: 3.5rem;
221 + position: absolute;
222 + font-weight: bold;
223 + }
224 + }
225 +
226 + .share-img {
227 + position: absolute;
228 + // top: 8vh;
229 + top: 0;
230 + left: 5vw;
231 + }
232 +
233 + .control-wrapper {
234 + display: flex;
235 + position: absolute;
236 + bottom: 5vh;
237 + width: 100%;
238 + justify-content: space-between;
239 + color: #FFF;
240 + align-items: center;
241 + .prev {
242 + background: #B41C1E;
243 + border-radius: 0px 33px 33px 0px;
244 + padding: 0.5rem 1rem 0.5rem 0.35rem;
245 + }
246 + .next {
247 + background: #B41C1E;
248 + border-radius: 33px 0px 0px 33px;
249 + padding: 0.5rem 0.35rem 0.5rem 1rem;
250 + }
251 + }
252 +}
253 +</style>
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
2 <div> 2 <div>
3 <!-- 生成图片后隐藏原始结构 --> 3 <!-- 生成图片后隐藏原始结构 -->
4 <div v-if="flag" ref="canvasRef" style="width: 200px; height: 200px;"> 4 <div v-if="flag" ref="canvasRef" style="width: 200px; height: 200px;">
5 - <img :src="logo_image" alt=""> 5 + <!-- <img :src="logo_image" alt=""> -->
6 </div> 6 </div>
7 <div v-if="imgUrl"> 7 <div v-if="imgUrl">
8 <img :src="imgUrl" alt="" crossOrigin="anonymous" style="width: 300px; height: 300px;"> 8 <img :src="imgUrl" alt="" crossOrigin="anonymous" style="width: 300px; height: 300px;">
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
17 17
18 <script setup> 18 <script setup>
19 19
20 -import logo_image from '@images/logo@3x.png' 20 +// import logo_image from '@images/logo@3x.png'
21 </script> 21 </script>
22 22
23 <script> 23 <script>
......
...@@ -3307,6 +3307,11 @@ ...@@ -3307,6 +3307,11 @@
3307 "@vue/server-renderer" "3.3.13" 3307 "@vue/server-renderer" "3.3.13"
3308 "@vue/shared" "3.3.13" 3308 "@vue/shared" "3.3.13"
3309 3309
3310 +"vue3-danmaku@^1.6.0":
3311 + "integrity" "sha512-XjwVKIelupDD3PWn6k22l5qS8y+SCdFUYq4sSpcPInqk7CyzXWSAfz2BL6WWx9HU9CRWS3x2oDMkepLkJoWvNQ=="
3312 + "resolved" "https://mirrors.cloud.tencent.com/npm/vue3-danmaku/-/vue3-danmaku-1.6.0.tgz"
3313 + "version" "1.6.0"
3314 +
3310 "webpack-sources@^3.2.3": 3315 "webpack-sources@^3.2.3":
3311 "integrity" "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==" 3316 "integrity" "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w=="
3312 "resolved" "https://mirrors.cloud.tencent.com/npm/webpack-sources/-/webpack-sources-3.2.3.tgz" 3317 "resolved" "https://mirrors.cloud.tencent.com/npm/webpack-sources/-/webpack-sources-3.2.3.tgz"
......