diff --git a/src/App.vue b/src/App.vue index cc47636..9a9a1aa 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,16 +1,21 @@ <script> import useUserStore from '@/jtools/store/user' import useQuestionStore from '@/jtools/store/question' //引入store +import storage from './jtools/storage' export default { - onLaunch: function () { + onLaunch: function (options) { + // 如果是二维码扫描过来的,需要保存公司id + if (options.query?.scene) { + storage.set('companyId', options.query?.scene) + } useUserStore().queryVipList() - if(useUserStore().isLogin) { + if (useUserStore().isLogin) { useUserStore().getUserInfo() useUserStore().searchUserVip() } }, onShow: function () { - useQuestionStore().getAllQuestion() + useQuestionStore().getAllQuestion() console.log('App Show') }, onHide: function () { @@ -23,5 +28,8 @@ export default { /*每个页面公共css */ @import "uni_modules/uview-plus/index.scss"; @import "static/style/index.scss"; -button::after{ border: none;} + +button::after { + border: none; +} </style> diff --git a/src/jtools/store/user.js b/src/jtools/store/user.js index e52c605..2e4f518 100644 --- a/src/jtools/store/user.js +++ b/src/jtools/store/user.js @@ -1,6 +1,6 @@ import { defineStore } from 'pinia'; -import { login,logout,getInfo } from '@/jtools/api/login'; -import { queryVip,getVipList } from '@/jtools/api/vip' +import { login, logout, getInfo } from '@/jtools/api/login'; +import { queryVip, getVipList } from '@/jtools/api/vip'; import constants from '@/jtools/constants'; import storage from '@/jtools/storage'; @@ -16,76 +16,77 @@ const useUserStore = defineStore({ }), actions: { - login(params) { - return new Promise(async (resolve, reject) => { - const resp = await login(params); - if (resp.code === '0000') { - // 保存登录信息,用于重新登录 - this.isLogin = true; - this.token = resp.data.token; - this.userInfo = resp.data - storage.set('isLogin', true) - storage.set('token', resp.data.token) - storage.set('userInfo', resp.data) - resolve(resp.data); - } else { - reject(); - } - }); - }, + login(params) { + return new Promise(async (resolve, reject) => { + const resp = await login(params); + if (resp.code === '0000') { + // 保存登录信息,用于重新登录 + this.isLogin = true; + this.token = resp.data.token; + this.userInfo = resp.data; + storage.set('isLogin', true); + storage.set('token', resp.data.token); + storage.set('userInfo', resp.data); + storage.remove('companyId'); + resolve(resp.data); + } else { + reject(); + } + }); + }, // 登出 logout(force = false) { return new Promise((resolve, reject) => { this.resetUserData(); uni.redirectTo({ url: '/pages/login/login' - }) + }); resolve(); - }) + }); + }, + //过期登出 + logoutWithoutToken(force = false) { + return new Promise((resolve, reject) => { + this.resetUserData(); + resolve(); + }); }, - //过期登出 - logoutWithoutToken(force = false) { - return new Promise((resolve, reject) => { - this.resetUserData(); - resolve(); - }) - }, // 获取用户信息 getUserInfo() { getInfo().then(resp => { - if(resp.code == '0000') { - this.userInfo = resp.data - storage.set('userInfo', resp.data) + if (resp.code == '0000') { + this.userInfo = resp.data; + storage.set('userInfo', resp.data); } - }) + }); }, resetUserData() { this.isLogin = false; this.token = ''; - this.userInfo = {} - this.vipOnList = [] - storage.remove('isLogin') - storage.remove('token') - storage.remove('userInfo') + this.userInfo = {}; + this.vipOnList = []; + storage.remove('isLogin'); + storage.remove('token'); + storage.remove('userInfo'); }, // 查询当前用户的vip开通情况 async searchUserVip() { - this.currentCartype=storage.get('carType') || '1001' - const resp=await queryVip({ carTypeId: this.currentCartype,memberId: null, subject:'' }) - if(resp.code == '0000') { - this.vipOnList = resp.data - } + this.currentCartype = storage.get('carType') || '1001'; + const resp = await queryVip({ carTypeId: this.currentCartype, memberId: null, subject: '' }); + if (resp.code == '0000') { + this.vipOnList = resp.data; + } }, // 查询所有的vip queryVipList() { - this.currentCartype= storage.get('carType') || '1001' - getVipList({ carTypeId: this.currentCartype,memberId: null, subject:'' }).then(resp => { - if(resp.code == '0000') { - this.vipAllList = resp.data + this.currentCartype = storage.get('carType') || '1001'; + getVipList({ carTypeId: this.currentCartype, memberId: null, subject: '' }).then(resp => { + if (resp.code == '0000') { + this.vipAllList = resp.data; } - }) + }); } - }, + } }); export default useUserStore; diff --git a/src/pages/index/videoVip.vue b/src/pages/index/videoVip.vue index 7013ce1..8d99db2 100644 --- a/src/pages/index/videoVip.vue +++ b/src/pages/index/videoVip.vue @@ -4,12 +4,15 @@ <image style="width: 100%;height: 600rpx;" src="https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/vip%E9%A2%98%E5%BA%93_20230911211532.png"></image> <view style="margin-bottom: 100px;"> <view class="flex jc-fa ai-c wp100 p14"> - <view style="width: 33.3%;" v-for="(item,index) of priceList" :key="index"> - <view class="option_tem relative" :class="checkedId===item.memberId?'checked_item':''" @click="checkPrice(item.memberId,item.price)"> - <text class="fw600 fs12 cor-333">{{item.memberName}}</text> - <view class="mt5"> + <view style="width: 33.3%;" v-for="(item, index) of priceList" :key="index"> + <view class="option_tem relative" :class="checkedId === item.memberId ? 'checked_item' : ''" @click="checkPrice(item.memberId, item.price)"> + <text class="fw600 fs12 cor-333">{{ item.memberName }}</text> + <view class="mt5" v-if="!isIOS"> <text class="fs14" style="color: #FF6E02;">¥</text> - <text class="fs30 fw600" style="color: #FF6E02;">{{item.price}}</text> + <text class="fs30 fw600" style="color: #FF6E02;">{{ item.price }}</text> + </view> + <view v-else class="mt5"> + <text class="fs14" style="color: #FF6E02;">iOS暂不支持</text> </view> <text class="fs12 cor-999">一年有效</text> <!-- <view class="bottom_box fs12 cor-333" :class="checkedId===item.memberId?'checked_bottom':''">赠送vip题库</view> --> @@ -21,12 +24,12 @@ </view> <view class="intr_box p14"> <view class="fw600 fs16 cor-000">尊享以下权益</view> - <view class="flex ai-c jc-sb mt15" v-if="subject=='1'||subject=='4'"> + <view class="flex ai-c jc-sb mt15" v-if="subject == '1' || subject == '4'"> <view class="text-center" style="width: 33%"> <view class="wp100 flex ai-c jc-c mb5"> <image style="width: 63rpx;height: 63rpx;margin-right: 5px;" src="../../static/image/index/vip500.png"></image> </view> - <text>精简{{titleNum}}题</text> + <text>精简{{ titleNum }}题</text> </view> <view class="text-center" style="width: 33%;"> <view class="wp100 flex ai-c jc-c mb5"> @@ -59,14 +62,14 @@ </view> </view> </view> - <view class="wp100 mt15" v-if="subject=='1'||subject=='4'"> + <view class="wp100 mt15" v-if="subject == '1' || subject == '4'"> <image class="wp100" mode="widthFix" :src="picUrl"></image> </view> </view> </view> - <view class="wp100 p14" style="position: absolute;left: 0;bottom:20px" @tap="handlePay()"> + <view v-if="!isIOS" class="wp100 p14" style="position: absolute;left: 0;bottom:20px" @tap="handlePay()"> <view class="sub_btn flex ai-c jc-sb"> - <text class="cor-fff fs14">¥<text class="fs24 cor-fff">{{nowPrice}}</text></text> + <text class="cor-fff fs14">¥<text class="fs24 cor-fff">{{ nowPrice }}</text></text> <image style="width: 276rpx;height: 88rpx;margin-top: -5px;" src="../../static/image/index/buy.png"></image> </view> </view> @@ -74,187 +77,197 @@ </template> <script> - import { - mapState, - mapActions - } from 'pinia' //引入映射函数 - import { getVipList } from '@/jtools/api/vip' - import { querySysConfig } from '@/jtools/api/question'; - import storage from '@/jtools/storage'; - import Pay from '@/jtools/pay/index.js'; - import useUserStore from '@/jtools/store/user' - export default { - data(){ - return{ - picUrl:'', - titleNum:500, - subject:'1', - loading:true, - nowPrice:168, - checkedId:0, - priceList:[], - order:{ - money:0, - description:'会员充值' +import { + mapState, + mapActions +} from 'pinia' //引入映射函数 +import { getVipList } from '@/jtools/api/vip' +import { querySysConfig } from '@/jtools/api/question'; +import storage from '@/jtools/storage'; +import Pay from '@/jtools/pay/index.js'; +import useUserStore from '@/jtools/store/user' +export default { + data() { + return { + picUrl: '', + titleNum: 500, + subject: '1', + loading: true, + nowPrice: 168, + checkedId: 0, + priceList: [], + order: { + money: 0, + description: '会员充值' + }, + isIOS: true + } + }, + onLoad(op) { + this.isIOS = this.$platform.device().includes('ios') + if (op.subject) { + this.subject = op.subject + } + this.loading = true + this.getVipList() + this.getWXOpenId() + this.getTitle() + this.getPic() + this.$set(this.order, 'userId', this.userInfo.userId); + }, + computed: { + ...mapState(useUserStore, ["userInfo"]) + }, + methods: { + getPic() { + const currentCartype = storage.get('carType') || '1001' + querySysConfig(currentCartype, 'VipDescImageUrl').then(res => { + this.picUrl = JSON.parse(res.data.configJson).url + }) + }, + getTitle() { + const carId = storage.get('carType') || '1001' + querySysConfig(carId, 'SimplifyQuestionNum').then(resp => { + if (resp.code === '0000') { + const list = JSON.parse(resp.data.configJson) + this.titleNum = list.find(item => item.subject == this.subject).num } - } + }) }, - onLoad(op){ - if(op.subject){ - this.subject=op.subject + async handlePay() { + if (this.loading) { + this.loading = false + await this.getWXOpenId() + new Pay('wechat', this.order); + this.loading = true } - this.loading=true - this.getVipList() - this.getWXOpenId() - this.getTitle() - this.getPic() - this.$set(this.order, 'userId', this.userInfo.userId); }, - computed: { - ...mapState(useUserStore, ["userInfo"]) + getWXOpenId() { + const that = this + uni.login({ + success(res) { + that.$set(that.order, 'code', res.code); + } + }) }, - methods:{ - getPic(){ - const currentCartype = storage.get('carType') || '1001' - querySysConfig(currentCartype, 'VipDescImageUrl').then(res => { - this.picUrl = JSON.parse(res.data.configJson).url + getVipList() { + getVipList({ + carTypeId: storage.get('carType') || '1001', + subject: this.subject + }).then(resp => { + if (resp.code === '0000') { + this.priceList = resp.data + this.checkedId = this.priceList[0].memberId + this.order.outTradeNo = this.priceList[0].memberId + this.order.money = this.priceList[0].price + this.nowPrice = this.priceList[0].price + this.priceList.forEach(item => { + if (item.subjects.length > 1) { + item.all = true + } }) - }, - getTitle(){ - const carId=storage.get('carType') || '1001' - querySysConfig(carId,'SimplifyQuestionNum').then(resp=>{ - if(resp.code==='0000'){ - const list = JSON.parse(resp.data.configJson) - this.titleNum=list.find(item=>item.subject==this.subject).num - } - }) - }, - async handlePay(){ - if(this.loading){ - this.loading=false - await this.getWXOpenId() - new Pay('wechat', this.order); - this.loading=true } - }, - getWXOpenId() { - const that = this - uni.login({ - success(res) { - that.$set(that.order, 'code', res.code); - } - }) - }, - getVipList(){ - getVipList({ - carTypeId: storage.get('carType') || '1001', - subject:this.subject - }).then(resp=>{ - if(resp.code==='0000'){ - this.priceList=resp.data - this.checkedId=this.priceList[0].memberId - this.order.outTradeNo=this.priceList[0].memberId - this.order.money=this.priceList[0].price - this.nowPrice=this.priceList[0].price - this.priceList.forEach(item=>{ - if(item.subjects.length>1){ - item.all=true - } - }) - } - }) - }, - checkPrice(val,price){ - this.checkedId=val - this.order.outTradeNo=val - this.nowPrice=price - this.order.money=price - } - } + }) + }, + checkPrice(val, price) { + this.checkedId = val + this.order.outTradeNo = val + this.nowPrice = price + this.order.money = price } + } +} </script> <style scoped> - .option_tem{ - width: 220rpx; - height: 241rpx; - text-align: center; - background: #FFFFFF; - border: 2px solid #D8D8D8; - border-radius: 16rpx 46rpx 16rpx 16rpx; - padding: 14px; - } - .checked_item{ - background: #FFF0E5; - border: 4px solid #FF6E02; - } - .bottom_box{ - width: 214rpx; - height: 40rpx; - line-height: 40rpx; - text-align: center; - background: rgb(239,239,239); - border-radius: 0 0 16rpx 16rpx; - position: absolute; - bottom: 0; - left: 0; - } - .checked_bottom{ - width: 218rpx; - border-radius: 0 0 16rpx 5rpx; - background-color: #FF6E02; - color:#fff - } - .tag{ - padding:0 5px; - height: 36rpx; - background: linear-gradient(90deg, #E66501 0%, #F8A42C 100%); - border-radius: 8rpx 20rpx 8rpx 8rpx; - line-height: 36rpx; - text-align: center; - font-size: 12px; - color: #FFFC27; - position: absolute; - left: 10rpx; - top:-18rpx - } - .intr_box{ - width: 100%; - text-align: center; - padding: 40rpx; - background: #FFF0E5; - border-radius: 16rpx; - } - .vip_item{ - width: 208rpx; - height: 54rpx; - line-height: 54rpx; - text-align: center; - font-size: 14px; - background: #F3D7C2; - border-radius: 0rpx 10rpx 10rpx 10rpx; - } - .sub_btn{ - width:100%; - height: 110rpx; - border: 4px solid #F59B26; - background: linear-gradient(0deg, #E66501 0%, #F8A42C 100%); - box-shadow: 0rpx 16rpx 20rpx 1rpx rgba(245,155,38,0.78); - border-radius: 55rpx; - padding: 14rpx; - } - .contain-box { - width: 344rpx; - height: 196rpx; - background: #00B74F; - border-radius: 16rpx; - } - - .play_btn_2 { - width: 65rpx; - height: 65rpx; - position: absolute; - left: 165.5rpx; - top: 78rpx - } +.option_tem { + width: 220rpx; + height: 241rpx; + text-align: center; + background: #FFFFFF; + border: 2px solid #D8D8D8; + border-radius: 16rpx 46rpx 16rpx 16rpx; + padding: 14px; +} + +.checked_item { + background: #FFF0E5; + border: 4px solid #FF6E02; +} + +.bottom_box { + width: 214rpx; + height: 40rpx; + line-height: 40rpx; + text-align: center; + background: rgb(239, 239, 239); + border-radius: 0 0 16rpx 16rpx; + position: absolute; + bottom: 0; + left: 0; +} + +.checked_bottom { + width: 218rpx; + border-radius: 0 0 16rpx 5rpx; + background-color: #FF6E02; + color: #fff +} + +.tag { + padding: 0 5px; + height: 36rpx; + background: linear-gradient(90deg, #E66501 0%, #F8A42C 100%); + border-radius: 8rpx 20rpx 8rpx 8rpx; + line-height: 36rpx; + text-align: center; + font-size: 12px; + color: #FFFC27; + position: absolute; + left: 10rpx; + top: -18rpx +} + +.intr_box { + width: 100%; + text-align: center; + padding: 40rpx; + background: #FFF0E5; + border-radius: 16rpx; +} + +.vip_item { + width: 208rpx; + height: 54rpx; + line-height: 54rpx; + text-align: center; + font-size: 14px; + background: #F3D7C2; + border-radius: 0rpx 10rpx 10rpx 10rpx; +} + +.sub_btn { + width: 100%; + height: 110rpx; + border: 4px solid #F59B26; + background: linear-gradient(0deg, #E66501 0%, #F8A42C 100%); + box-shadow: 0rpx 16rpx 20rpx 1rpx rgba(245, 155, 38, 0.78); + border-radius: 55rpx; + padding: 14rpx; +} + +.contain-box { + width: 344rpx; + height: 196rpx; + background: #00B74F; + border-radius: 16rpx; +} + +.play_btn_2 { + width: 65rpx; + height: 65rpx; + position: absolute; + left: 165.5rpx; + top: 78rpx +} </style> \ No newline at end of file diff --git a/src/pages/login/login.vue b/src/pages/login/login.vue index 9744561..9939448 100644 --- a/src/pages/login/login.vue +++ b/src/pages/login/login.vue @@ -13,7 +13,7 @@ <view class="list-call"> <u-input class="sl-input" v-model="login.code" type="text" maxlength="6" border="none" placeholder="输入验证码"> <template #suffix> - <text class="fs14 mr10" style="color: #05C341;" @tap="getCode">{{countDown==0?'获取验证码':countDown}}</text> + <text class="fs14 mr10" style="color: #05C341;" @tap="getCode">{{ countDown == 0 ? '获取验证码' : countDown }}</text> </template> </u-input> </view> @@ -27,138 +27,142 @@ </template> <script> - import { - isPhone - } from '@/jtools/utils/validate.js' - import { - getCode, - login - } from '@/jtools/api/login' - import useUserStore from '@/jtools/store/user' - export default { - data() { - return { - login: { - phone: '', - code: '' - }, - countDown: 0, - js: undefined - }; - }, - onShow() { - if(useUserStore().isLogin) { - this.toHome() - } - }, - methods: { - getCode() { - if (isPhone(this.login.phone) && this.countDown == 0) { - getCode({ - phone: this.login.phone - }).then(resp => { - // if (resp.code == '0000') { - uni.showToast({ - title: '发送成功!', - icon: 'none' - }) - this.countDown = 60 - this.js = setInterval(() => { - this.countDown--; - if (this.countDown == 0) { - this.clear() - } - }, 1000) - // } - }) - } - }, - clear() { - clearInterval(js) - this.js = null - this.countDown = 0 +import { + isPhone +} from '@/jtools/utils/validate.js' +import { + getCode, + login +} from '@/jtools/api/login' +import useUserStore from '@/jtools/store/user' +import storage from '@/jtools/storage'; +export default { + data() { + return { + login: { + phone: '', + code: '' }, - bindLogin() { - if(isPhone(this.login.phone) && this.login.code) { - useUserStore().login(this.login).then(resp => { - if(resp.userId) { - useUserStore().getUserInfo() - useUserStore().searchUserVip() - this.toHome() - } + countDown: 0, + js: undefined + }; + }, + onShow() { + if (useUserStore().isLogin) { + this.toHome() + } + }, + methods: { + getCode() { + if (isPhone(this.login.phone) && this.countDown == 0) { + getCode({ + phone: this.login.phone + }).then(resp => { + // if (resp.code == '0000') { + uni.showToast({ + title: '发送成功!', + icon: 'none' }) + this.countDown = 60 + this.js = setInterval(() => { + this.countDown--; + if (this.countDown == 0) { + this.clear() + } + }, 1000) + // } + }) + } + }, + clear() { + clearInterval(js) + this.js = null + this.countDown = 0 + }, + bindLogin() { + if (isPhone(this.login.phone) && this.login.code) { + let params = { ...this.login } + if (storage.get('companyId')) { + params.id = storage.get('companyId') } - }, - toHome() { - uni.switchTab({ - url: '/pages/index/index' + useUserStore().login(params).then(resp => { + if (resp.userId) { + useUserStore().getUserInfo() + useUserStore().searchUserVip() + this.toHome() + } }) } + }, + toHome() { + uni.switchTab({ + url: '/pages/index/index' + }) } } +} </script> <style> - page { - background-color: #fff; - } - - .content { - display: flex; - flex-direction: column; - justify-content: center; - } +page { + background-color: #fff; +} - .header { - margin-top: 166rpx; - margin-left: auto; - margin-right: auto; - letter-spacing: 10rpx; - } +.content { + display: flex; + flex-direction: column; + justify-content: center; +} - .header image { - width: 383rpx; - } +.header { + margin-top: 166rpx; + margin-left: auto; + margin-right: auto; + letter-spacing: 10rpx; +} - .list { - display: flex; - flex-direction: column; - padding-top: 120rpx; - padding-left: 90rpx; - padding-right: 90rpx; - } +.header image { + width: 383rpx; +} - .list-call { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - height: 100rpx; - color: #333333; - border-bottom: 0.5px solid #e2e2e2; - } +.list { + display: flex; + flex-direction: column; + padding-top: 120rpx; + padding-left: 90rpx; + padding-right: 90rpx; +} +.list-call { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + height: 100rpx; + color: #333333; + border-bottom: 0.5px solid #e2e2e2; +} - .list-call .sl-input { - flex: 1; - text-align: left; - font-size: 32rpx; - margin-left: 16rpx; - } - .button-login { - color: #FFFFFF; - font-size: 34rpx; - width: 560rpx; - height: 100rpx; - background: linear-gradient(90deg, #11DF20 0%, #00B74F 100%); - border-radius: 50rpx; - line-height: 100rpx; - text-align: center; - margin-top: 100rpx; - margin-left: auto; - margin-right: auto; - } +.list-call .sl-input { + flex: 1; + text-align: left; + font-size: 32rpx; + margin-left: 16rpx; +} +.button-login { + color: #FFFFFF; + font-size: 34rpx; + width: 560rpx; + height: 100rpx; + background: linear-gradient(90deg, #11DF20 0%, #00B74F 100%); + border-radius: 50rpx; + line-height: 100rpx; + text-align: center; + margin-top: 100rpx; + margin-left: auto; + margin-right: auto; +} </style> \ No newline at end of file diff --git a/src/pages/me/index.vue b/src/pages/me/index.vue index 7e674d4..e3bf2b8 100644 --- a/src/pages/me/index.vue +++ b/src/pages/me/index.vue @@ -40,7 +40,7 @@ <view v-if="!isLogin || !vipOn.length" class="text-center"> <view class="fs18 fwb" style="color: #7E4012FF;">开通VIP尊享以下权益</view> <view class="fs15" style="color: #7E4012FF;">精选500题 / 真是模考 / 考前密卷</view> - <view class="study fs16 text-center" style="margin: 25px auto 0;color: #F6E99FFF;">立即开通</view> + <view class="study fs16 text-center" style="margin: 25px auto 0;color: #F6E99FFF;">{{ isIOS ? 'iOS暂不可用' : '立即开通' }}</view> </view> <view v-else-if="vipOn.length" class="text-center"> <view class="fs18 fwb" style="color: #7E4012FF;">{{ vipText }}</view> @@ -135,26 +135,31 @@ export default { } } }, - data(){ - return{ - carName:storage.get('carName') || '小车C1/C2/C3' - } - }, + data() { + return { + carName: storage.get('carName') || '小车C1/C2/C3', + isIOS: true + } + }, onShow() { - this.carName=storage.get('carName') || '小车C1/C2/C3' + this.isIOS = this.$platform.device().includes('ios') + this.carName = storage.get('carName') || '小车C1/C2/C3' }, methods: { - toChangeCarType(){ - uni.navigateTo({ - url:"/pages/me/changeCarType" - }) - }, + toChangeCarType() { + uni.navigateTo({ + url: "/pages/me/changeCarType" + }) + }, handleVip() { + if (this.isIOS) { + return + } if (this.isLogin) { // if (this.vipOn.length) { - uni.navigateTo({ - url: '/pages/me/vip' - }) + uni.navigateTo({ + url: '/pages/me/vip' + }) // } else { // uni.navigateTo({ // url: '/pages/index/videoVip' @@ -192,10 +197,10 @@ export default { // uni.navigateTo({ // url: '/pages/me/tijian' // }) - uni.showToast({ - title:'敬请期待', - icon:'none' - }) + uni.showToast({ + title: '敬请期待', + icon: 'none' + }) } else { this.toLogin() }