main
xy 2 years ago
parent 1ccf273669
commit 7a37ee72ad

@ -2,72 +2,71 @@
const jwx = require('jweixin-module')
export default {
onLaunch: function() {
// let link = window.location.href;
// if (/code=/.test(link) || link.indexOf("code") > -1) {
// let temp = decodeURIComponent((new RegExp('[?|&]' + 'code' + '=' + '([^&;]+?)(&|#|;|$)').exec(link) ||
// [, ''])[1].replace(/\+/g, '%20')) || null
// let lifeData = uni.getStorageSync('lifeData')
// if (!lifeData.vuex_token || !lifeData.vuex_userId) {
// this.$u.api.login({
// code: temp
// }).then(res => {
// uni.setStorageSync('lifeData', {
// vuex_token: res.token,
// vuex_userId: res.user_id
// })
// this.$u.vuex('vuex_token', res.token)
// this.$u.vuex('vuex_userId', res.user_id)
// })
// }
// } else {
// this.$u.api.getAppId().then(res => {
// let redirect = encodeURIComponent(link.replace(/#\//, ""))
// window.location.href =
// `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${res.appid}&redirect_uri=${redirect}&response_type=code&scope=snsapi_base#wechat_redirect`
// })
// }
this.$nextTick(() => {
let url = location.href.split('#')[0]
this.$u.api.share({
url
}).then(res => {
jwx.config({
debug: false, // , api alert pc log pc
appId: res.appId,
jsApiList: res.jsApiList,
nonceStr: res.nonceStr,
signature: res.signature,
timestamp: res.timestamp,
})
jwx.ready(() => {
jwx.updateAppMessageShareData({
title: '我是党史记录人-红色少年行 未成年人研学', //
desc: '我是党史记录人-红色少年行 未成年人研学',
link: url, // ,JS
imgUrl: 'http://h5.ali251.langye.net/res/share-img.jpeg', //
});
jwx.updateTimelineShareData({
title: '我是党史记录人-红色少年行 未成年人研学', //
desc: '我是党史记录人-红色少年行 未成年人研学',
link: url, // ,JS
imgUrl: 'http://h5.ali251.langye.net/res/share-img.jpeg', //
});
jwx.onMenuShareAppMessage({
title: '我是党史记录人-红色少年行 未成年人研学', //
desc: '我是党史记录人-红色少年行 未成年人研学',
link: url, // ,JS
imgUrl: 'http://h5.ali251.langye.net/res/share-img.jpeg', //
});
jwx.onMenuShareTimeline({
title: '我是党史记录人-红色少年行 未成年人研学', //
desc: '我是党史记录人-红色少年行 未成年人研学',
link: url, // ,JS
imgUrl: 'http://h5.ali251.langye.net/res/share-img.jpeg', //
});
let link = window.location.href;
if (/code=/.test(link) || link.indexOf("code") > -1) {
let temp = decodeURIComponent((new RegExp('[?|&]' + 'code' + '=' + '([^&;]+?)(&|#|;|$)').exec(link) ||
[, ''])[1].replace(/\+/g, '%20')) || null
let lifeData = uni.getStorageSync('lifeData')
if (!lifeData.vuex_token || !lifeData.vuex_userId) {
this.$u.api.login({
code: temp
}).then(res => {
this.$u.api.user().then(res => {
this.$u.vuex('vuex_user', res)
})
this.$u.vuex('vuex_token', res.token)
let url = location.href.split('#')[0]
this.$u.api.share({
url
}).then(res => {
jwx.config({
debug: false, // , api alert pc log pc
appId: res.appId,
jsApiList: res.jsApiList,
nonceStr: res.nonceStr,
signature: res.signature,
timestamp: res.timestamp,
})
jwx.ready(() => {
jwx.updateAppMessageShareData({
title: '我是党史记录人-红色少年行 未成年人研学', //
desc: '我是党史记录人-红色少年行 未成年人研学',
link: url, // ,JS
imgUrl: 'http://h5.ali251.langye.net/res/share-img.jpeg', //
});
jwx.updateTimelineShareData({
title: '我是党史记录人-红色少年行 未成年人研学', //
desc: '我是党史记录人-红色少年行 未成年人研学',
link: url, // ,JS
imgUrl: 'http://h5.ali251.langye.net/res/share-img.jpeg', //
});
jwx.onMenuShareAppMessage({
title: '我是党史记录人-红色少年行 未成年人研学', //
desc: '我是党史记录人-红色少年行 未成年人研学',
link: url, // ,JS
imgUrl: 'http://h5.ali251.langye.net/res/share-img.jpeg', //
});
jwx.onMenuShareTimeline({
title: '我是党史记录人-红色少年行 未成年人研学', //
desc: '我是党史记录人-红色少年行 未成年人研学',
link: url, // ,JS
imgUrl: 'http://h5.ali251.langye.net/res/share-img.jpeg', //
});
})
})
})
}
} else {
this.$u.api.getAppId().then(res => {
let redirect = encodeURIComponent(link.replace(/#\//, ""))
window.location.href =
`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${res.appid}&redirect_uri=${redirect}&response_type=code&scope=snsapi_base#wechat_redirect`
})
})
}
})
},
onShow: function() {
console.log('App Show')

@ -1,6 +1,8 @@
//api集合
let apiApp = {
login: '/api/mobile/user/wechat-login',
user: '/api/mobile/user/show',
saveUser: '/api/mobile/user/save',
getAppId: '/api/mobile/user/wechat-login-url',
getQuestions: '/api/mobile/quiz/get-questions',
getPoints: '/api/mobile/map-point/point-list',
@ -19,6 +21,7 @@ const install = (Vue, vm) => {
//api方法
let login = (params = {}) => vm.$u.get(apiApp.login, params);
let user = (params = {}) => vm.$u.get(apiApp.user, params);
let getAppId = (params = {}) => vm.$u.get(apiApp.getAppId, params);
let getQuestions = (params = {}) => vm.$u.get(apiApp.getQuestions, params);
let getPoints = (params = {}) => vm.$u.get(apiApp.getPoints, params)
@ -29,9 +32,11 @@ const install = (Vue, vm) => {
let saveQuiz = (params = {}) => vm.$u.post(apiApp.saveQuiz, params);
let pointDetail = (params = {}) => vm.$u.get(apiApp.pointDetail, params);
let share = (params = {}) => vm.$u.get(apiApp.share, params);
const savePoster = (params = {}) => vm.$u.get(apiApp.savePoster, params);
let savePoster = (params = {}) => vm.$u.get(apiApp.savePoster, params);
let saveUser = (params = {}) => vm.$u.post(apiApp.saveUser, params);
// 将各个定义的接口名称统一放进对象挂载到vm.$u.api(因为vm就是this也即this.$u.api)下
vm.$u.api = { login, getAppId, getQuestions, baseFormIndex, baseFormShow, baseFormSave, baseFormDestroy, getPoints, saveQuiz, pointDetail, share, savePoster };
vm.$u.api = { login, getAppId, getQuestions, baseFormIndex, baseFormShow, baseFormSave, baseFormDestroy, getPoints, saveQuiz, pointDetail, share, savePoster, user, saveUser };
}
export default {

@ -71,7 +71,7 @@
"vueVersion" : "2",
"h5" : {
"router" : {
"base" : ""
"base" : "h5hssnx"
}
}
}

@ -14,13 +14,13 @@
<div class="container__text">
<div class="container__text--title">
<span>王晓明</span>同学
<span>{{ vuex_user.name ? vuex_user.name : name }}</span>同学
</div>
<div class="container__text--total">
你已完成2023年我是党史记录人红色少年行未成年人研学线上打卡
</div>
<div class="container__text--total">
学党史悟精神聚力量你是第<span>2023</span>位完成者快邀请你的同学一起完成线上打卡吧!
学党史悟精神聚力量你是第<span>{{ vuex_user.address || 0 }}</span>位完成者快邀请你的同学一起完成线上打卡吧!
</div>
</div>
</div>
@ -53,6 +53,12 @@
</view>
</view>
</view>
<u-modal v-model="isShowModal" title="您的名字是?" @confirm="saveName">
<view class="slot-content" style="padding: 10rpx 20rpx;">
<u-input v-model="name"></u-input>
</view>
</u-modal>
</div>
</template>
@ -68,11 +74,17 @@ export default {
isShare: false,
isHidden: false,
imgData: '',
isShowModal: false,
name: '',
};
},
methods: {
showShare () {
this.isShare = true
saveName () {
this.$u.api.saveUser(Object.assign(this.vuex_user, {
name: this.name
}))
},
share() {
@ -90,7 +102,7 @@ export default {
scrollX: 0,
useCORS: true,
ignoreElements:(element) => {
return element.attributes.id == 'share-img'
return element.id == 'share-img'
}
}).then(cnv => {
uni.hideLoading()
@ -161,6 +173,11 @@ export default {
xhr.send(form)
})
}
},
onShow() {
if (!this.vuex_user.name) {
this.isShowModal = true
}
}
}
</script>

@ -14,18 +14,27 @@
:key="index"
:style="{ 'transform': `translate(calc(${area.w * item.x / 100}px - 50%),calc(${area.h * item.y / 100}px - 50%))` }"
@click="$u.throttle(() => toDetail(item))">
<div class="box" :class="{ 'box--active': item.has_answer > 0 }" :style="{ 'transform': `rotate(${item.d}deg)` }">
<img :style="{ 'transform': `rotate(${-item.d}deg)` }" :src="item.image ? item.image.url : ''" alt="">
<div class="pointer__horn" :class="{ 'pointer__horn--active': item.has_answer > 0 }" :style="{ 'transform': `translate(-3rpx, calc(-50% - 4rpx)) rotate(${item.d}deg)` }"></div>
<div class="box" :style="{ 'transform': transformBox(item.d) }">
<div class="box__image" :class="{ 'box--active': item.has_answer > 0 }">
<img :src="item.image ? item.image.url : ''" alt="">
</div>
<div class="box__text" :class="{ 'box__text--active': item.has_answer > 0 }" :style="{ 'transform': (item.d > 100 || item.d < -100) ? 'translate(-50rpx, 136rpx)' : '' }">{{ item.name }}</div>
</div>
<div class="text"
:class="{ 'text--active': item.has_answer > 0 }"
:style="{
'transform': translateText(item.d)
}">
{{ item.name }}
</div>
<!-- <div class="box" :class="{ 'box&#45;&#45;active': item.has_answer > 0 }" :style="{ 'transform': `rotate(${item.d}deg)` }">-->
<!-- <img :style="{ 'transform': `rotate(${-item.d}deg)` }" :src="item.image ? item.image.url : ''" alt="">-->
<!-- </div>-->
<!-- <div class="text"-->
<!-- :class="{ 'text&#45;&#45;active': item.has_answer > 0 }"-->
<!-- :style="{-->
<!-- 'transform': translateText(item.d)-->
<!-- }">-->
<!-- {{ item.name }}-->
<!-- </div>-->
</div>
</div>
</div>
@ -129,7 +138,7 @@ export default {
this.done = res.point_answer_total || 0
this.pointers = res.points?.map((i, index) => {
return {
d: convertToEquivalentAngle(60 * index + 1),
d: convertToEquivalentAngle(70 * index + 1),
...i
}
})
@ -137,6 +146,21 @@ export default {
},
computed: {
transformBox () {
return function (deg) {
if (deg) {
if ((deg % 360) > -90 && (deg % 360) < 90) {
return `translate(calc(${Math.floor(Math.sin(Math.PI / 180 * deg) * 80)}rpx - 48rpx), calc(${-1 * Math.floor(Math.cos(Math.PI / 180 * deg) * 80)}rpx - 48rpx))`
} else {
return `translate(calc(${Math.floor(Math.sin(Math.PI / 180 * deg) * 80)}rpx - 48rpx), calc(${-1 * Math.floor(Math.cos(Math.PI / 180 * deg) * 80)}rpx - 48rpx))`
}
} else {
return 'translate(0, 0)'
}
}
},
translateText () {
return function (deg) {
if (deg) {
@ -190,72 +214,78 @@ export default {
padding: 20rpx 0;
margin: 0 auto;
.pointer {
width: 16rpx;
height: 16rpx;
border-radius: 100%;
background: #fff;
transform-origin: center;
border: 3rpx solid #C52A34;
display: inline-block;
position: relative;
& .text {
&__horn {
width: 20rpx;
height: 26rpx;
clip-path: polygon(20% 0, 80% 0%, 50% 100%, 20% 0);
background: #F5D8AD;
border-radius: 6rpx;
word-break: keep-all;
filter: drop-shadow(2rpx 4rpx 2rpx #90D2CF);
color: #C52A34;
font-size: 20rpx;
text-align: center;
transform-origin: 50% 0;
transform-origin: 50% 100%;
padding: 12rpx 10rpx;
position: absolute;
&--active {
background: #b93736;
color: #fff;
background: #C52A34;
}
}
& .box {
width: 116rpx;
height: 116rpx;
border-radius: 100%;
box-sizing: border-box;
border: 5rpx #F5D8AD solid;
display: flex;
justify-content: center;
align-items: center;
filter: drop-shadow(2rpx 4rpx 2rpx #90D2CF);
transform-origin: 50% calc(100% + 26rpx + 5rpx);
transform-origin: 0 0;
// overflow: hidden;
position: absolute;
top: calc(-116rpx - 26rpx);
left: -50rpx;
&__text {
width: 200rpx;
word-break: break-word;
background: #F5D8AD;
border-radius: 6rpx;
filter: drop-shadow(2rpx 4rpx 2rpx #90D2CF);
color: #C52A34;
font-size: 20rpx;
zoom: .85;
text-align: center;
transform: translate(-50rpx,-100%);
&--active {
border-color: #b93736;
padding: 10rpx 8rpx;
position: absolute;
top: 0;
&--active {
background: #b93736;
color: #fff;
}
}
& > img {
width: 106rpx;
height: 106rpx;
&__image {
width: 116rpx;
height: 116rpx;
border-radius: 100%;
box-sizing: border-box;
border: 5rpx #F5D8AD solid;
display: flex;
justify-content: center;
align-items: center;
filter: drop-shadow(2rpx 4rpx 4rpx #90D2CF);
& > img {
width: 106rpx;
height: 106rpx;
border-radius: 100%;
}
}
&::after {
content: '';
height: 26rpx;
width: 22rpx;
background: #F5D8AD;
clip-path: polygon(0 0, 100% 0, 50% 100%,0 0);
transform: translate(-50% , 100%);
position: absolute;
bottom: 0;
left: 50%;
&--active {
border-color: #b93736;
}
&--active::before {
content: '已打卡';
font-size: 20rpx;
@ -276,6 +306,91 @@ export default {
}
}
}
//.pointer {
// width: 16rpx;
// height: 16rpx;
// border-radius: 100%;
// background: #fff;
// border: 3rpx solid #C52A34;
// display: inline-block;
//
// position: relative;
//
// & .text {
// background: #F5D8AD;
// border-radius: 6rpx;
// word-break: keep-all;
// filter: drop-shadow(2rpx 4rpx 2rpx #90D2CF);
// color: #C52A34;
// font-size: 20rpx;
// text-align: center;
// transform-origin: 50% 0;
//
// padding: 12rpx 10rpx;
// position: absolute;
//
// &--active {
// background: #b93736;
// color: #fff;
// }
// }
// & .box {
// width: 116rpx;
// height: 116rpx;
// border-radius: 100%;
// box-sizing: border-box;
// border: 5rpx #F5D8AD solid;
// display: flex;
// justify-content: center;
// align-items: center;
// filter: drop-shadow(2rpx 4rpx 2rpx #90D2CF);
// transform-origin: 50% calc(100% + 26rpx + 5rpx);
//
// position: absolute;
// top: calc(-116rpx - 26rpx);
// left: -50rpx;
//
// &--active {
// border-color: #b93736;
// }
// & > img {
// width: 106rpx;
// height: 106rpx;
// border-radius: 100%;
//
// }
// &::after {
// content: '';
// height: 26rpx;
// width: 22rpx;
// background: #F5D8AD;
// clip-path: polygon(0 0, 100% 0, 50% 100%,0 0);
//
// transform: translate(-50% , 100%);
// position: absolute;
// bottom: 0;
// left: 50%;
// }
// &--active::before {
// content: '';
// font-size: 20rpx;
// color: #fff;
// background: #b93736;
// border-radius: 30rpx;
// zoom: .8;
// clip-path: circle(84rpx at 84% 178%);
//
// padding: 6rpx 14rpx 5rpx 122rpx;
// z-index: 2;
// position: absolute;
// top: -1rpx;
// left: -96rpx;
// }
// &--active::after {
// background: #b93736;
// }
// }
//}
}
}

@ -33,7 +33,7 @@ const store = new Vuex.Store({
// 如果上面从本地获取的lifeData对象下有对应的属性就赋值给state中对应的变量
// 加上vuex_前缀是防止变量名冲突也让人一目了然
vuex_user: lifeData.vuex_user ? lifeData.vuex_user : {},
vuex_token: lifeData.vuex_token ? lifeData.vuex_token : '1945|mGcboS5ApGYxvWUUJNk2ytorapfOU18d20AgiXqJ',
vuex_token: lifeData.vuex_token ? lifeData.vuex_token : '',
// 如果vuex_version无需保存到本地永久存储无需lifeData.vuex_version方式
vuex_version: '1.0.0',

Loading…
Cancel
Save