初始化

This commit is contained in:
梁泽军
2025-02-24 17:34:19 +08:00
commit 8f5e6b5398
59 changed files with 4320 additions and 0 deletions

35
src/api/Axios.js Normal file
View File

@@ -0,0 +1,35 @@
import axios from 'axios'
import QS from 'qs';
let url = import.meta.env.VITE_HOST + import.meta.env.VITE_API
// 创建axios
const service = axios.create({
baseURL: url,
timeout: 50000,
});
// 添加请求拦截器
service.interceptors.request.use((config) => {
// 在发送请求之前做些什么
config
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
service.interceptors.response.use(
(response) => {
return response.data || {};
}, (error) => {
return Promise.reject(error);
});
export default service;

73
src/api/http.js Normal file
View File

@@ -0,0 +1,73 @@
import service from './Axios'
import qs from "qs";
// json格式请求头
const headerJSON = {
"Content-Type": "application/json;charset=UTF-8",
};
// FormData格式请求头
const headerFormData = {
"Content-Type": "application/x-www-form-urlencoded",
};
const http = {
/**
* methods: 请求
* @param url 请求地址
* @param params 请求参数
* @param json 判断数据发送是否是json格式: true-为是 false-为否
*/
get(url, params, json, authorization) {
if (authorization) {
headerJSON['authorization'] = authorization
}
const config = {
method: "get",
url: url,
headers: json ? headerJSON : headerFormData
};
if (params) config.params = params;
return service(config);
},
post(url, params, json, authorization) {
if (authorization) {
headerJSON['authorization'] = authorization
}
const config = {
method: "post",
url: url,
headers: json ? headerJSON : headerFormData
};
if (params) config.data = json ? params : qs.stringify(params);
return service(config);
},
put(url, params, json) {
const config = {
method: "put",
url: url,
headers: headerFormData
};
if (params) config.params = params;
return service(config);
},
delete(url, params, json) {
const config = {
method: "delete",
url: url,
headers: headerFormData
};
if (params) config.params = params;
return service(config);
},
}
//导出
export default http;

27
src/api/index.js Normal file
View File

@@ -0,0 +1,27 @@
import http from './http'
// 获取code
export function authorize(data, authorization) {
return http.get("/wechatApi/oauth2/wxLogin",
data,
true,
);
}
// 获取用户信息
export function getUserInfo(data, authorization) {
return http.get("/wechatApi/oauth2/getUserInfo",
data,
true,
);
}
// 兑奖
export function exchangePrize(data, authorization) {
return http.post("/pa/rewards",
data,
true,
authorization
);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
src/assets/images/share.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
src/assets/media/bgm.mp3 Normal file

Binary file not shown.

BIN
src/assets/media/click.mp3 Normal file

Binary file not shown.

BIN
src/assets/media/entry.mp3 Normal file

Binary file not shown.

23
src/components/Index.vue Normal file
View File

@@ -0,0 +1,23 @@
<template>
<div class="IndexPage">
</div>
</template>
<script setup>
</script>
<style lang="scss" scoped>
.IndexPage {
@include fixed();
@include flexCen();
}
</style>

View File

@@ -0,0 +1,44 @@
<template>
<div class="LoadPage">
<Loading size="24px" type="spinner" color="#0094ff" vertical>loading...</Loading>
</div>
</template>
<script setup>
import gsap from 'gsap'
import { Loading, Icon } from 'vant'
import { loadImg } from '@/data/imgList'
import Preloader from '@/plugins/Preloader'
// 初始化
const emit = defineEmits(["LoadPage"]); // 声明触发事件,对应父组件上面的方法
onMounted(() => {
Preloader(
{
name: '加载页资源',
imgs: loadImg,
callback: (progress) => console.log('进度:', progress)
}
).then(
res => {
console.log('加载完成');
gsap.to('.LoadPage', { duration: .5, autoAlpha: 0, onComplete: () => { emit("LoadPage", { action: 'hide' }) } })
}
)
})
</script>
<style lang="scss" scoped>
.LoadPage {
@include fixed();
@include flexCen();
.brrage {
width: 750px;
height: 750px;
}
}
</style>

31
src/data/data.js Normal file
View File

@@ -0,0 +1,31 @@
export default {
//manifest 加载到纹理缓存使用的资源
manifest: [
{
name: "test0",
url: new URL(`@/assets/images/m_0.png`, import.meta.url).href,
position: { x: 110, y: 210, w: 80, h: 80 },
zIndex: 4,
},
{
name: "test1",
url: new URL(`@/assets/images/m_1.png`, import.meta.url).href,
position: { x: 110, y: 200, w: 100, h: 100 },
zIndex: 3,
},
{
name: "test2",
url: new URL(`@/assets/images/m_2.png`, import.meta.url).href,
position: { x: 110, y: 300, w: 100, h: 100 },
zIndex: 2,
},
{
name: "test3",
url: new URL(`@/assets/images/share.jpg`, import.meta.url).href,
position: { x: 110, y: 400, w: 300, h: 300 },
zIndex: 1,
}
]
}

20
src/data/imgList.js Normal file
View File

@@ -0,0 +1,20 @@
const load = [
'load/1.png',
]
// 处理为vite引入图片格式
function imgCreate(url, img) {
let i = new URL(`../assets/images/${url}`, import.meta.url).href
img.push(i)
}
const loadImg = []
const pageImg = []
load.forEach(element => {
imgCreate(element, loadImg)
});
export { loadImg, pageImg }

25
src/page/Home/App.vue Normal file
View File

@@ -0,0 +1,25 @@
<script setup>
import Loading from '@/components/Loading.vue';
import Index from '@/components/Index.vue';
const showLoading = ref(true);
const showIndex = ref(false);
const LoadingFn = (item) =>{
}
const IndexFn = (item) =>{
}
</script>
<template>
<Index v-if="showIndex" />
<Loading v-if="showLoading" @LoadPage="LoadingFn" />
</template>
<style lang="scss">
</style>

26
src/page/Home/main.js Normal file
View File

@@ -0,0 +1,26 @@
import { createApp } from 'vue'
import App from './App.vue'
import { wxShare } from '@/plugins/wxshare';
import {isMobile} from '@/plugins'
import VConsole from 'vconsole';
import 'vant/lib/index.css';
const app = createApp(App)
// 微信分享配置
wxShare({
title: '今夜宜赏灯,来测测你的专属元宵花灯',
desc: '赏花灯,赢惊喜,欢天喜地闹元宵!',
link: '/index.html'
})
// 测试环境开vconsole
if (isMobile()) {
// const vConsole = new VConsole();
}
app.mount('#app')
console.log('Mode:', import.meta.env.VITE_MODE);

31
src/plugins/Preloader.js Normal file
View File

@@ -0,0 +1,31 @@
// 图片资源预加载器
const imgPreloader = url => {
return new Promise((resolve, reject) => {
let image = new Image();
image.src = url;
image.onload = () => {
resolve();
};
image.onerror = () => {
reject();
};
});
};
const Preloader = ({ name, imgs, callback }) => {
let promiseArr = [];
let num = 0
imgs.forEach(element => {
promiseArr.push(imgPreloader(element).then((res => {
num++
let progress = parseInt((num / imgs.length) * 100)
callback(progress)
})));
});
console.log(name, promiseArr.length, '张');
return Promise.all(promiseArr);
};
export default Preloader

13
src/plugins/algorithm.js Normal file
View File

@@ -0,0 +1,13 @@
// 洗牌算法
export function FYShuffle(arr) {
let len = arr.length;
while (len > 1) {
let rand = Math.floor(Math.random() * len);
len--;
[arr[len], arr[rand]] = [arr[rand], arr[len]] // 采用的数组的结构赋值
}
return arr;
}

49
src/plugins/hooks.js Normal file
View File

@@ -0,0 +1,49 @@
import { ref } from 'vue'
// 倒计时
export function useCountDown() {
const countNum = ref(0)
const countInterval = ref(null)
const startCountDown = num => {
countNum.value = Number(num)
clearCountDown()
countInterval.value = setInterval(() => {
if (countNum.value === 0) {
clearInterval(countInterval.value)
countInterval.value = null
return
}
countNum.value--
}, 1000)
}
const clearCountDown = () => {
if (countInterval.value) {
clearInterval(countInterval.value)
}
}
return { countNum, startCountDown, clearCountDown }
}
// 防抖
export function useDebounce(cb, delay = 150) {
const timer = ref(null)
const handler = () => {
if (timer.value) {
clearTimeout(timer.value)
timer.value = setTimeout(() => {
cb()
}, delay)
} else {
timer.value = setTimeout(() => {
cb()
}, delay)
}
}
return { handler }
}

521
src/plugins/index.js Normal file
View File

@@ -0,0 +1,521 @@
// 常用的方法
import gsap from 'gsap'
import { Howl, Howler } from 'howler';
import { Toast } from 'vant';
import { createVNode, render } from 'vue'
// 初始化
const btnEnable = ref(true) //按钮可点击状态
// 音效初始化
const sound = new Howl({
src: [new URL(`@/assets/media/click.mp3`, import.meta.url).href]
});
// 背景音乐
export function createBGM() {
const musicNode = createVNode(
'div',
{
class: 'music-icon',
id: 'musicBtn',
onClick: () => {
let auduoEle = document.querySelector("#audio")
let musicBox = document.querySelector("#musicBtn")
if (auduoEle.paused) {
auduoEle.play()
audioAni.play()
musicBox.classList.add('music-on')
musicBox.classList.remove('music-off')
} else {
gsap.set('#musicBtn', { rotation: '0deg' })
auduoEle.pause()
audioAni.pause()
musicBox.classList.add('music-off')
musicBox.classList.remove('music-on')
}
},
},
)
const audioNode = createVNode(
'audio',
{
class: 'audio-icon',
id: 'audio',
src: new URL(`@/assets/media/bgm.mp3`, import.meta.url).href,
autoPlay: true,
loop: true,
},
)
render(musicNode, document.querySelector('.home'));
render(audioNode, document.querySelector("#musicBtn"));
document.querySelector("#musicBtn").classList.add('music-on')
let audioAni = gsap.timeline({ paused: true })
audioAni.to('#musicBtn', { duration: 10, rotation: "+=360", repeat: -1, ease: 'none' })
setTimeout(() => {
audioAni.play()
}, 1000)
}
//是否在微信环境
export function isWX() {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
return true;
} else {
return false;
}
}
// 判断是否移动端
export function isMobile() {
let userAgentInfo = navigator.userAgent;
let Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod'];
let getArr = Agents.filter(i => userAgentInfo.includes(i));
return getArr.length ? true : false;
}
// 判断微博环境
export function isWeibo() {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/WeiBo/i) == "weibo") {
console.log("微博环境");
return true;
} else {
console.log("非微博环境");
return false;
}
}
// 判断Safari环境
export function isSafari() {
var ua = window.navigator.userAgent.toLowerCase();
if ((/Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent))) {
console.log("Safari环境");
return true;
} else {
console.log("非Safari环境");
return false;
}
}
//是否为安卓
export function isAndriod() {
var naviga = navigator.userAgent;
if (naviga.indexOf('Android') > -1 || naviga.indexOf('Adr') > -1) {
console.log("Andriod环境");
return true;
} else {
console.log("非Andriod环境");
return false;
}
}
//路径获取关键字
export function getQueryString(name) {
//截取页面传递字符串
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]);
return null;
}
// 判断全面屏和非全面屏true为全面屏
export function judgeBigScreen() {
let result = false;
const rate = window.screen.height / window.screen.width;
let limit = window.screen.height == window.screen.availHeight ? 1.8 : 1.65; // 临界判断值
// window.screen.height为屏幕高度
// window.screen.availHeight 为浏览器 可用高度
if (rate > limit) {
// console.log("全面屏");
result = true;
return result;
}
// console.log("非面屏");
return result;
}
// 获取url html名称
export function getUrlHtml() {
//获取url地址
var ts_href = window.location.href;
var ts_mainText = "";
//获取地址最后一个“/”的下标
var ts_indexof = ts_href.lastIndexOf("/");
//获取地址“/”之后的的内容
var ts_indexText = ts_href.substring(ts_indexof + 1);
//获取地址“.html”的下标
var ts_htmlBeforeText = ts_indexText.indexOf(".html");
//获取 “/”到".html"之间的内容
ts_mainText = ts_indexText.substring(0, ts_htmlBeforeText);
console.log("当前入口:", ts_mainText);
return ts_mainText;
}
// 获取cookie中的值
export function getSetCookie(name, value, options) {
if (typeof value != 'undefined') {
options = options || {};
if (value === null) {
value = '';
options = this._extend({}, options, true);
options.expires = -1;
}
var expires = '';
if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
var date;
if (typeof options.expires == 'number') {
date = new Date();
date.setTime(date.getTime() + options.expires * 24 * 60 * 60 * 1000);
} else {
date = options.expires;
}
expires = '; expires=' + date.toUTCString();
}
var path = options.path ? '; path=' + options.path : '';
var domain = options.domain ? '; domain=' + options.domain : '';
var secure = options.secure ? '; secure' : '';
document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
} else {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
// var cookie = $.trim(cookies[i]);
var cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) == name + '=') {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
}
// 安卓机型自动播放音乐
export function BGMAutoPlayMgr(url) {
this.audioContext = new (window.AudioContext || window.webkitAudioContext || window.mozAudioContext)();
this.sourceNode = null;
this.buffer = null;
this.isPlayingBGM = false;
this.toggleBGM = function () {
if (typeof this.sourceNode == 'object') {
if (this.isPlayingBGM) {
this.sourceNode.stop();
this.isPlayingBGM = false;
} else this._playSourceNode();
}
}
this._playSourceNode = function () {
const audioContext = this.audioContext;
audioContext.resume();
const _sourceNode = audioContext.createBufferSource();
_sourceNode.buffer = this.buffer;
_sourceNode.loop = true;
_sourceNode.connect(audioContext.destination);
_sourceNode.start(0);
this.sourceNode = _sourceNode;
this.isPlayingBGM = true;
}
let loadAndAutoPlay = (audioUrl) => {
const audioContext = this.audioContext;
const xhr = new XMLHttpRequest();
xhr.open('GET', audioUrl, true);
xhr.responseType = 'arraybuffer';
xhr.onreadystatechange = () => {
if (xhr.status < 400 && xhr.status >= 200 && xhr.readyState === 4) {
audioContext.decodeAudioData(xhr.response, buffer => {
this.buffer = buffer;
WeixinJSBridge.invoke("getNetworkType", {}, () => this._playSourceNode());
});
}
}
xhr.send();
}
loadAndAutoPlay(url);
loadAndAutoPlay = null;
}
// 金管家获取openid及openToken
export function getJGJId() {
return new Promise(resolve => {
// 获取openid
PALifeOpen.getOpenId(
{
appId: '1aeedce2a31340e591a5d64080d6105b' // 商户编号,区分⽣产和测试环境商户编号
},
rsp => {
// 调⽤接⼝成功后的回调函数
console.log('success', rsp.data);
store.state.openId = rsp.data.openId
store.state.openToken = rsp.data.openToken
if (rsp.ret == 0) {
store.state.openId = rsp.data.openId
store.state.openToken = rsp.data.openToken
const data = {
id: store.state.openId,
token: store.state.openToken
};
resolve(data);
// console.log(`获取到金管家openid时间${Math.abs(s_t - new Date().getTime())}`);
}
if (rsp.ret == -1) {
console.log(JSON.stringify(rsp));
}
},
e => {
// 调⽤接⼝异常的回调函数
console.log('failed', e);
}
)
})
}
// 金管家内部埋点
export function addPoint(page, spage, des = {}) {
const activityId = process.env.VUE_APP_ACTIVITYID;
PALifeOpen.invoke(
"device",
"addRecord",
{
eventId: `499${page}-${activityId}`, //必填,根据需求
labelId: `499${page}${spage}-${activityId}`, //必填,根据需求
// 扩展参数
parameters: {
ext: JSON.stringify(des)
}
},
// 调用接口成功后的回调函数 // alert(JSON.stringify(rsp))
rsp => console.debug("success ", rsp),
// 调用接口异常的回调函数
e => console.debug("failed ", e),
{
timeout: 86400000
}
);
return this;
}
// 百度统计埋点
export function addPointByBd(des) {
_hmt && _hmt.push(["_trackEvent", `${des}`, `${des} success`]);
return this;
}
// 防抖函数
export function debounceTap(target, callbacks, timeScale = 1) {
if (!btnEnable.value) return false
btnEnable.value = false;
let createAni = () => {
let timeline = new gsap.timeline({
onStart: () => {
sound.play()
},
onComplete: () => {
callbacks && callbacks();
btnEnable.value = true;
timeline.kill();
}
});
timeline
.to(target, { duration: timeScale * 0.2, scale: 0.8, })
.to(target, { duration: timeScale * 0.5, scale: 1, })
}
createAni();
}
// 节流函数
export function throttle(fn, wait) {
let inThrottle = false
return (...args) => {
// @ts-ignore
const context = this
if (!inThrottle) {
inThrottle = true
fn.apply(context, args)
setTimeout(() => {
inThrottle = false
}, wait)
}
}
}
// vite环境引用图片
export function imgUrl(url) {
return new URL(`../assets/images/${url}`, import.meta.url).href
}
// 计算两个日期之间的天数(开始日期,结束日期)
export function getDaysBetween(date1, date2) {
let day1 = new Date(date1.join('-'))
let day2 = new Date(date2.join('-'))
let oneDay = 24 * 60 * 60 * 1000;
let diffDays = Math.round(Math.abs((day2 - day1) / oneDay));
return diffDays;
}
// 计算星座
export function getAstro(month, day) {
var s = "魔羯水瓶双鱼牡羊金牛双子巨蟹狮子处女天秤天蝎射手魔羯";
var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22];
return s.substr(month * 2 - (day < arr[month - 1] ? 2 : 0), 2);
}
// 洗牌算法:打乱数组顺序
export function FYShuffle(arr) {
let len = arr.length;
while (len > 1) {
let rand = Math.floor(Math.random() * len);
len--;
[arr[len], arr[rand]] = [arr[rand], arr[len]] // 采用的数组的结构赋值
}
return arr;
}
// 选出数组中出现次数最多的值
export function mostValue(arr) {
// 创建一个空对象用于存储值及其出现的次数
let counter = {};
// 遍历数组中的每个元素
for (let i = 0; i < arr.length; i++) {
// 如果值已经在counter对象中增加其计数
// 如果值不在counter对象中设置计数为1
if (counter[arr[i]]) {
counter[arr[i]]++;
} else {
counter[arr[i]] = 1;
}
}
// 找出出现次数最多的值及其出现的次数
let mostFrequentValue = null;
let maxCount = 0;
for (let key in counter) {
if (counter[key] > maxCount) {
mostFrequentValue = key;
maxCount = counter[key];
}
}
// 返回出现次数最多的值和其出现的次数
return { value: mostFrequentValue, count: maxCount };
}
// 海报生成
export function posterCreate(option, imageArr, textArr, theme,eqcode) {
let posterUrl = ''
const { width, height } = option
Toast.loading({
message: '海报生成中',
duration: 0,
forbidClick: true
})
console.log('theme', theme);
let mycanvas = document.createElement('canvas') // 创建一个canvas画布元素
let ctx = mycanvas.getContext('2d')
mycanvas.style.width = '750px'; //设置canvas的宽
mycanvas.style.height = '1500px'; //设置canvas的高
mycanvas.width = width
mycanvas.height = height
console.log('imgs:', imageArr);
//Promise对象加载资源
let loader_p = [];
imageArr.map((item) => {
const _p = new Promise(resolve => {
const img = new Image();
img.crossOrigin = 'Anonymous'
img.onload = () => {
resolve(img)
};
img.src = item.src;
});
loader_p.push(_p);
})
//Promise的.all方法当所有预加载的图像加载好的回调函数
Promise.all(loader_p)
.then(imgList => {
imgList.map((item, index) => {
// console.log('item',imageArr[index]);
if (imageArr[index].name != 'eqcode') {
ctx.drawImage(item, imageArr[index].pos.x, imageArr[index].pos.y, imageArr[index].pos.w, imageArr[index].pos.h); //原生canvas的绘制图片方法直接百度搜索 `js drawImage`查看方法的参数
}
})
ctx.rotate(-4.3 * (Math.PI / 180));
// console.log('imgList[2]',imgList[2]);
ctx.drawImage(imgList[2], imageArr[2].pos.x, imageArr[2].pos.y, imageArr[2].pos.w, imageArr[2].pos.h)
// 画签文
// ctx.rotate(-4 * (Math.PI / 180));
ctx.textAlign = 'start'; //type2
ctx.textBaseline = 'top'
textArr.map((item, index) => {
const { x, y } = textArr[index].style.pos
ctx.font = textArr[index].style.font; // normal bold
// title绘制描边
if (index == 0) {
ctx.lineWidth = 5
ctx.strokeStyle = 'white'
ctx.strokeText(textArr[index].content, x, y);
}
ctx.fillStyle = textArr[index].style.color ? textArr[index].style.color : theme; //原生canvas的绘制文字方法,属性类似css确定好文字颜色、粗细、字号、字体、对齐方式
ctx.fillText(textArr[index].content, x, y); //绘制文字
})
//海报绘制完 ,转成图片对象
return mycanvas.toDataURL('image/jpeg', 1);
})
.then(baseURL => {
//返回的图片地址就是最后海报的地址可以放在DOM显示
let posterImg = document.querySelector('#poster')
posterImg.src = baseURL
setTimeout(() => {
Toast.success({ message: '生成成功!' })
gsap.to('.posterPop', { duration: 0.5, autoAlpha: 1 })
}, 500)
})
return posterUrl
}

60
src/plugins/wxshare.js Normal file
View File

@@ -0,0 +1,60 @@
import wx from 'weixin-js-sdk';
import axios from "axios";
import { showToast } from "vant";
const imgUrl = new URL(`../assets/images/share.jpg`, import.meta.url).href
const linkUrl = import.meta.env.VITE_ACTIVITY_URL
export function wxShare(option) {
let url = location.href.split('#')[0];
axios.get('https://wx.xfhd.net/wxapi/api/jsconfig?appid=wx41d80a1bb01f658d', {
params: { url }
})
.then((res) => {
console.log('分享配置:', {
'title': option.title,
'desc': option.desc,
'link': linkUrl
});
let data = res.data;
wx.config({
debug: false, // 开启调试模式
appId: data.appId, // 必填,公众号的唯一标识
timestamp: data.timestamp, // 必填,生成签名的时间戳
nonceStr: data.nonceStr, // 必填,生成签名的随机串
signature: data.signature, // 必填签名见附录1
jsApiList: [
'checkJsApi',
'showMenuItems',
'onMenuShareAppMessage',
'onMenuShareTimeline',
] // 必填需要使用的JS接口列表所有JS接口列表见附录2
})
wx.ready(function () {
wx.onMenuShareTimeline({
link: linkUrl, // 分享链接
title: option.title, // 分享标题
desc: option.desc, // 分享描述
imgUrl: imgUrl, // 分享图标
success() {// 用户成功分享后执行的回调函数
showToast('分享成功')
},
});
wx.onMenuShareAppMessage({
link: linkUrl, // 分享链接
title: option.title, // 分享标题
desc: option.desc, // 分享描述
imgUrl: imgUrl, // 分享图标
success() {// 用户成功分享后执行的回调函数
showToast('分享成功')
},
})
})
})
.catch(() => {
});
}

15
src/store/index.js Normal file
View File

@@ -0,0 +1,15 @@
// pinia仓库
import { defineStore } from "pinia"
export const useMainStore = defineStore("counter", {
state: () => {
return {
name: '超级管理员'
}
},
// 相当于computed属性对state进行二次加工
getters: {},
// 异步处理方法
actions: {},
})

52
src/styles/global.scss Normal file
View File

@@ -0,0 +1,52 @@
@charset "utf-8";
$red: red;
$green: green;
// DIV宽高
@mixin box($width, $height) {
width: $width;
height: $height;
}
// DIV宽高定位
@mixin pos($width, $height, $left, $top) {
width: $width;
height: $height;
position: absolute;
left: $left;
top: $top;
}
// DIV背景
@mixin bg_pos($src) {
// new URL(`../assets/images/${url}`, import.meta.url).href
background-image: url("../assets/images/" + $src);
background-repeat: no-repeat;
background-size: 100% 100%;
}
// flex居中定位
@mixin flex() {
display: flex;
justify-content: center;
align-items: center;
}
// 全屏样式
@mixin fixed() {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
// flex垂直水平居中
@mixin flexCen() {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}