作者 徐浩

20240621记录代买

正在显示 59 个修改的文件 包含 1962 行增加474 行删除
1 <script> 1 <script>
2 import Vue from 'vue' 2 import Vue from 'vue'
  3 + import { update } from "@/common/uitls.js"
3 import { 4 import {
4 mapState, 5 mapState,
5 mapMutations 6 mapMutations
6 } from 'vuex' 7 } from 'vuex'
7 var that 8 var that
8 export default { 9 export default {
  10 +
9 onLaunch: function() { 11 onLaunch: function() {
10 that=this 12 that=this
11 console.log('App Launch') 13 console.log('App Launch')
@@ -26,7 +28,17 @@ @@ -26,7 +28,17 @@
26 // }) 28 // })
27 // } 29 // }
28 // } 30 // }
29 - 31 + // 拦截页面跳转并检查更新
  32 + // #ifdef APP-PLUS
  33 + uni.addInterceptor('navigateTo', {
  34 + success() {
  35 + const currentPage = (getCurrentPages()).map(item => item.route);
  36 + if(!currentPage.includes('pages/update/update')){
  37 + update()
  38 + }
  39 + }
  40 + })
  41 + // #endif
30 uni.getSystemInfo({ 42 uni.getSystemInfo({
31 success: function(e) { 43 success: function(e) {
32 that.$store.commit('setplatform',e.platform) 44 that.$store.commit('setplatform',e.platform)
  1 +export const ENV = 'dev'
  2 +
  3 +export const REFERER = (() => {
  4 + if(ENV === 'dev') {
  5 + return 'https://edudev.baoshanjiaoyu.com/'
  6 + }
  7 +})()
  1 +
  2 +import service from "@/common/service.js"
  3 +/**
  4 + * @description: 版本判断以及更新逻辑
  5 + * @param {Object} obj
  6 + * @author: xuhao
  7 + */
  8 +export async function update() {
  9 + await inspectApk()
  10 + await inspectWgt()
  11 +}
  12 +// 检查是否有apk包更新
  13 +function inspectApk() {
  14 + return new Promise((req, err) => {
  15 + let version = plus.runtime.version
  16 + // let version = '1.0.0'
  17 + console.log('version', version)
  18 + service.P_post('/version/index', {
  19 + client: uni.getSystemInfoSync().platform,
  20 + version: version
  21 + }).then(res => {
  22 + if(res.msg.version) {
  23 + uni.navigateTo({
  24 + url: '/pages/update/update'
  25 + })
  26 + err()
  27 + } else {
  28 + req()
  29 + }
  30 + })
  31 + })
  32 +}
  33 +// 检查是否有wgt包更新
  34 +function inspectWgt() {
  35 + return new Promise((req, err) => {
  36 + plus.runtime.getProperty(plus.runtime.appid, (widgetInfo) => {
  37 + let version = widgetInfo.version
  38 + console.log('version', version)
  39 + service.P_post('/version/index', {
  40 + client: uni.getSystemInfoSync().platform,
  41 + version: version
  42 + }).then(res => {
  43 + if(res.msg.version) {
  44 + wgtUpdate(res.msg.url)
  45 + err()
  46 + } else {
  47 + req()
  48 + }
  49 + })
  50 + })
  51 + })
  52 +}
  53 +/**
  54 + * 热更新逻辑
  55 + */
  56 +function wgtUpdate(url) {
  57 + // 检查是否正在更新
  58 + if(uni.getStorageSync('updatingInProgress')){
  59 + return
  60 + }
  61 + uni.setStorageSync('updatingInProgress', true)
  62 + let urlSystem = uni.getStorageSync('url')
  63 + const downloadTask = uni.downloadFile({
  64 + url: urlSystem + '/app/renew/download?filename=' + url,
  65 + success: (downloadResult) => {
  66 + if (downloadResult.statusCode === 200) {
  67 + plus.runtime.install(downloadResult.tempFilePath, {
  68 + force: true
  69 + }, function() {
  70 + console.log('install success...');
  71 + plus.runtime.restart();
  72 + }, function(e) {
  73 + console.error('install fail...', e);
  74 + },);
  75 + }
  76 + },
  77 + complete: () => {
  78 + uni.removeStorageSync('updatingInProgress')
  79 + }
  80 + });
  81 + var showLoading = plus.nativeUI.showWaiting("正在更新", {
  82 + back: "none"
  83 + });
  84 + downloadTask.onProgressUpdate((res) => {
  85 + showLoading.setTitle("正在更新" + res.progress + "% ");
  86 + if (res.progress == 100) {
  87 + plus.nativeUI.closeWaiting();
  88 + }
  89 + })
  90 +}
  1 +<template>
  2 + <view class="Countdown">
  3 + <view v-if="remainingTime === 0" @click="startCountdown">获取验证码</view>
  4 + <view v-else>{{ remainingTime }}s 后重新获取</view>
  5 + </view>
  6 +</template>
  7 +
  8 +<script>
  9 + export default {
  10 + name: 'Countdown',
  11 + data() {
  12 + return {
  13 + remainingTime: 0,
  14 + timer: null
  15 + }
  16 + },
  17 + methods: {
  18 + startCountdown() {
  19 + this.$emit('start')
  20 + },
  21 + start() {
  22 + this.remainingTime = 60;
  23 + this.timer = setInterval(() => {
  24 + this.remainingTime--;
  25 + if (this.remainingTime === 0) {
  26 + clearInterval(this.timer);
  27 + }
  28 + }, 1000);
  29 + }
  30 + },
  31 + beforeDestroy() {
  32 + clearInterval(this.timer);
  33 + }
  34 + }
  35 +</script>
  36 +
  37 +<style lang="scss" scoped>
  38 + .Countdown{
  39 + font-size: 26rpx;
  40 + }
  41 +</style>
1 <template> 1 <template>
2 <view> 2 <view>
3 - <!-- #ifdef MP-WEIXIN -->  
4 <view class="CustomReturn-container" :style="{height: titleHeight, paddingTop: paddingTop, backgroundColor: bgColor}"> 3 <view class="CustomReturn-container" :style="{height: titleHeight, paddingTop: paddingTop, backgroundColor: bgColor}">
5 <view class="CustomReturn"> 4 <view class="CustomReturn">
6 <view v-if="isShowBreak" class="CustomReturn-r"> 5 <view v-if="isShowBreak" class="CustomReturn-r">
@@ -17,7 +16,6 @@ @@ -17,7 +16,6 @@
17 <slot></slot> 16 <slot></slot>
18 </view> 17 </view>
19 </view> 18 </view>
20 - <!-- #endif -->  
21 </view> 19 </view>
22 20
23 21
@@ -112,10 +110,11 @@ @@ -112,10 +110,11 @@
112 this.paddingTop = uni.getSystemInfoSync().statusBarHeight + 'px' 110 this.paddingTop = uni.getSystemInfoSync().statusBarHeight + 'px'
113 // #ifdef MP-WEIXIN 111 // #ifdef MP-WEIXIN
114 let res = wx.getMenuButtonBoundingClientRect(); 112 let res = wx.getMenuButtonBoundingClientRect();
115 - // #endif  
116 this.paddingTop = res.top + 'px' 113 this.paddingTop = res.top + 'px'
117 this.titleHeight = res.height + 10 + 'px'; 114 this.titleHeight = res.height + 10 + 'px';
118 this.entityHeight = res.top + res.height 115 this.entityHeight = res.top + res.height
  116 + // #endif
  117 +
119 118
120 }, 119 },
121 toBreak(){ 120 toBreak(){
@@ -39,15 +39,16 @@ @@ -39,15 +39,16 @@
39 }, 39 },
40 methods:{ 40 methods:{
41 setOtherHeight(height) { 41 setOtherHeight(height) {
  42 + // #ifdef APP-PLUS
  43 + let paddingTop = uni.getSystemInfoSync().statusBarHeight
  44 + let titleHeight = 88 + 'rpx';
  45 + // #endif
42 // #ifdef MP-WEIXIN 46 // #ifdef MP-WEIXIN
43 let res = wx.getMenuButtonBoundingClientRect(); 47 let res = wx.getMenuButtonBoundingClientRect();
  48 + let paddingTop = res.top;
  49 + let titleHeight = res.height + 10 + 'px';
44 // #endif 50 // #endif
45 - let paddingTop = res.top  
46 - let titleHeight = res.height + 10;  
47 -  
48 - this.PaddingTop = `calc(${paddingTop + titleHeight}px + ${height + this.otherUnit})`  
49 -  
50 - // this.PaddingTop = `calc(${uni.getSystemInfoSync().statusBarHeight}px + ${height}rpx + 88rpx + 5px)` 51 + this.PaddingTop = `calc(${paddingTop}px + ${titleHeight} + ${height + this.otherUnit})`
51 } 52 }
52 } 53 }
53 } 54 }
  1 +<template>
  2 + <u-popup :show="show" :round="10" mode="bottom">
  3 + <view class="UserAgreement">
  4 + <view class="UserAgreement-top">
  5 + <view class="UserAgreement-top-content">隐私政策</view>
  6 + </view>
  7 + <scroll-view :scroll-y="true" style="height: 60vh;">
  8 + <view class="UserAgreement-body" v-html="content"></view>
  9 + </scroll-view>
  10 + <view class="UserAgreement-bottom-container">
  11 + <view class="UserAgreement-bottom" @click="cancel">
  12 + 知道了
  13 + </view>
  14 + </view>
  15 + </view>
  16 + </u-popup>
  17 +</template>
  18 +
  19 +<script>
  20 + export default {
  21 + name:"UserAgreement",
  22 + data() {
  23 + return {
  24 + show: false,
  25 + title: '',
  26 + content: ''
  27 + };
  28 + },
  29 + mounted() {
  30 +
  31 + },
  32 + methods: {
  33 + getData() {
  34 + this.$service.P_get('config/policy').then(res => {
  35 + console.log('=======>', res)
  36 + this.content = res.data.content
  37 + })
  38 + },
  39 + open() {
  40 + this.getData()
  41 + this.show = true
  42 + },
  43 + cancel(){
  44 + this.show = false
  45 + this.$emit('cancel')
  46 + },
  47 + close() {
  48 + this.show = false
  49 + this.$emit('close')
  50 + }
  51 + }
  52 + }
  53 +</script>
  54 +
  55 +<style lang="scss" scoped>
  56 + .UserAgreement{
  57 + padding: 0 40rpx;
  58 + background-color: #fff;
  59 + border-radius: 20rpx;
  60 + text-align: left;
  61 + .UserAgreement-top{
  62 + text-align: center;
  63 + padding: 49rpx 0;
  64 + display: flex;
  65 + justify-content: center;
  66 + .UserAgreement-top-content{
  67 + position: relative;
  68 + font-size: 32rpx;
  69 + color: #323232;
  70 + }
  71 +
  72 + }
  73 + .UserAgreement-body{
  74 + color: #646464;
  75 + font-size: 28rpx;
  76 + overflow: auto;
  77 + padding-bottom: 20rpx;
  78 + }
  79 + .UserAgreement-bottom-container{
  80 + display: flex;
  81 + justify-content: space-between;
  82 + .UserAgreement-bottom{
  83 + line-height: 90rpx;
  84 + font-size: 34rpx;
  85 + color: #FFFFFF;
  86 + background-color: #2d81ff;
  87 + border-radius: 500rpx;
  88 + text-align: center;
  89 + margin-top: 40rpx;
  90 + margin-bottom: calc(env(safe-area-inset-bottom) + 30rpx);
  91 + width: 100%;
  92 + }
  93 + .UserAgreement-bottom-2{
  94 + color: rgba(100, 100, 100, 1);
  95 + line-height: 90rpx;
  96 + font-size: 34rpx;
  97 + background-color: rgba(239, 239, 239, 1);
  98 + border-radius: 500rpx;
  99 + text-align: center;
  100 + margin-top: 40rpx;
  101 + margin-bottom: 30rpx;
  102 + width: 300rpx;
  103 + }
  104 + }
  105 +
  106 + }
  107 +</style>
  1 +<template>
  2 + <view>
  3 + <view class="Protocol" @click="select">
  4 + <u-checkbox-group v-model="checked">
  5 + <u-checkbox shape="circle" label=" " :name="1"></u-checkbox>
  6 + </u-checkbox-group>
  7 + <view>
  8 + 我已阅读并同意<text style="color: #2d81ff;" @tap.stop ="openYonghu">《用户协议》</text>和<text style="color: #2d81ff;" @tap.stop="openYinSi">《隐私政策》</text>
  9 + </view>
  10 + </view>
  11 + <UserAgreementPop ref="userAgreementPopRef" />
  12 + <PrivacyPolicyPop ref="privacyPolicyPopRef" />
  13 + </view>
  14 +</template>
  15 +
  16 +<script>
  17 + import UserAgreementPop from "@/components/UserAgreementPop/index.vue"
  18 + import PrivacyPolicyPop from "@/components/PrivacyPolicyPop/index.vue"
  19 + export default {
  20 + name: 'Protocol',
  21 + components: {
  22 + UserAgreementPop,
  23 + PrivacyPolicyPop
  24 + },
  25 + computed: {
  26 + checked: {
  27 + get() {
  28 + if(!this.value) {
  29 + return []
  30 + } else {
  31 + return [1]
  32 + }
  33 + },
  34 + set(val) {
  35 + console.log(val)
  36 + if(val.length) {
  37 + this.$emit('input', true)
  38 + } else {
  39 + this.$emit('input', false)
  40 + }
  41 + }
  42 + }
  43 + },
  44 + model: {
  45 + event: 'input',
  46 + prop: 'value'
  47 + },
  48 + props: {
  49 + value: {
  50 + type: Boolean,
  51 + default: false
  52 + }
  53 + },
  54 + data() {
  55 + return {
  56 + }
  57 + },
  58 + methods: {
  59 + openYinSi() {
  60 + this.$refs.privacyPolicyPopRef.open()
  61 + },
  62 + openYonghu() {
  63 + this.$refs.userAgreementPopRef.open()
  64 + },
  65 + select() {
  66 + if(this.checked.length) {
  67 + this.checked = []
  68 + } else {
  69 + this.checked = [1]
  70 + }
  71 + }
  72 + }
  73 +
  74 + }
  75 +</script>
  76 +
  77 +<style lang="scss" scoped>
  78 + .Protocol{
  79 + display: flex;
  80 + align-items: center;
  81 + font-size: 26rpx;
  82 + }
  83 +</style>
  1 +<template>
  2 + <u-popup :show="show" :round="10" mode="bottom">
  3 + <view class="UserAgreement">
  4 + <view class="UserAgreement-top">
  5 + <view class="UserAgreement-top-content">用户协议</view>
  6 + </view>
  7 + <scroll-view :scroll-y="true" style="height: 60vh;">
  8 + <view class="UserAgreement-body" v-html="content"></view>
  9 + </scroll-view>
  10 + <view class="UserAgreement-bottom-container">
  11 + <view class="UserAgreement-bottom" @click="cancel">
  12 + 知道了
  13 + </view>
  14 + </view>
  15 + </view>
  16 + </u-popup>
  17 +</template>
  18 +
  19 +<script>
  20 + export default {
  21 + name:"UserAgreement",
  22 + data() {
  23 + return {
  24 + show: false,
  25 + title: '',
  26 + content: ''
  27 + };
  28 + },
  29 + mounted() {
  30 +
  31 + },
  32 + methods: {
  33 + getData() {
  34 + this.$service.P_get('config/agreement').then(res => {
  35 + console.log('=======>', res)
  36 + this.content = res.data.content
  37 + })
  38 + },
  39 + open() {
  40 + this.getData()
  41 + this.show = true
  42 + },
  43 + cancel(){
  44 + this.show = false
  45 + this.$emit('cancel')
  46 + },
  47 + close() {
  48 + this.show = false
  49 + this.$emit('close')
  50 + }
  51 + }
  52 + }
  53 +</script>
  54 +
  55 +<style lang="scss" scoped>
  56 + .UserAgreement{
  57 + padding: 0 40rpx;
  58 + background-color: #fff;
  59 + border-radius: 20rpx;
  60 + text-align: left;
  61 + .UserAgreement-top{
  62 + text-align: center;
  63 + padding: 49rpx 0;
  64 + display: flex;
  65 + justify-content: center;
  66 + .UserAgreement-top-content{
  67 + position: relative;
  68 + font-size: 32rpx;
  69 + color: #323232;
  70 + }
  71 +
  72 + }
  73 + .UserAgreement-body{
  74 + color: #646464;
  75 + font-size: 28rpx;
  76 + overflow: auto;
  77 + padding-bottom: 20rpx;
  78 + }
  79 + .UserAgreement-bottom-container{
  80 + display: flex;
  81 + justify-content: space-between;
  82 + .UserAgreement-bottom{
  83 + line-height: 90rpx;
  84 + font-size: 34rpx;
  85 + color: #FFFFFF;
  86 + background-color: #2d81ff;
  87 + border-radius: 500rpx;
  88 + text-align: center;
  89 + margin-top: 40rpx;
  90 + margin-bottom: calc(env(safe-area-inset-bottom) + 30rpx);
  91 + width: 100%;
  92 + }
  93 + .UserAgreement-bottom-2{
  94 + color: rgba(100, 100, 100, 1);
  95 + line-height: 90rpx;
  96 + font-size: 34rpx;
  97 + background-color: rgba(239, 239, 239, 1);
  98 + border-radius: 500rpx;
  99 + text-align: center;
  100 + margin-top: 40rpx;
  101 + margin-bottom: 30rpx;
  102 + width: 300rpx;
  103 + }
  104 + }
  105 +
  106 + }
  107 +</style>
@@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
11 <script> 11 <script>
12 export default { 12 export default {
13 name: 'VoicePlayback', 13 name: 'VoicePlayback',
  14 +
14 data() { 15 data() {
15 return { 16 return {
16 audioContext: null, 17 audioContext: null,
@@ -40,7 +41,7 @@ @@ -40,7 +41,7 @@
40 this.duration = duration 41 this.duration = duration
41 }, 42 },
42 init({ url, duration }) { 43 init({ url, duration }) {
43 - this.audioContext = wx.createInnerAudioContext(); 44 + this.audioContext = uni.createInnerAudioContext();
44 this.audioContext.src = url 45 this.audioContext.src = url
45 this.audioContext.onPlay(() => { 46 this.audioContext.onPlay(() => {
46 this.isPlay = true 47 this.isPlay = true
@@ -50,6 +51,7 @@ @@ -50,6 +51,7 @@
50 }); 51 });
51 this.audioContext.onEnded(() => { 52 this.audioContext.onEnded(() => {
52 this.audioContext.stop() 53 this.audioContext.stop()
  54 + this.init({ url, duration })
53 }) 55 })
54 this.audioContext.onStop(() => { 56 this.audioContext.onStop(() => {
55 this.isPlay = false 57 this.isPlay = false
1 <template> 1 <template>
2 <view class="qxcplayer-box" :style="'height:' + height + 'rpx'"> 2 <view class="qxcplayer-box" :style="'height:' + height + 'rpx'">
3 - <video id="qxc_player" class="qxc-video" :src="playUrl"  
4 - autoplay="" @play="videoPlay()" @pause="videoPause()" @timeupdate="videoTimeUpdate"  
5 - @error="videoError"  
6 - referrer-policy="origin"  
7 - @controlstoggle="controlstoggle"  
8 - @fullscreenchange="fullScreenChange"  
9 - :custom-cache="false"  
10 - > 3 + <video id="qxc_player" class="qxc-video" :src="playUrl" autoplay="" @play="videoPlay()" @pause="videoPause()"
  4 + @timeupdate="videoTimeUpdate" @error="videoError" :header="{'Referer':REFERER}" referrer-policy="origin"
  5 + @controlstoggle="controlstoggle" @fullscreenchange="fullScreenChange" :custom-cache="false">
11 <view :class="fullScreen? 'controller-top controller-top-nobg': 'controller-top'" v-if="topShow"> 6 <view :class="fullScreen? 'controller-top controller-top-nobg': 'controller-top'" v-if="topShow">
12 <text class="speed-txt" @click="speedTap">X {{speedVal}}</text> 7 <text class="speed-txt" @click="speedTap">X {{speedVal}}</text>
13 </view> 8 </view>
14 - <cover-image v-if="!isPlay && topShow" @click="centerPlayClick" src="../../static/qxc_play.png" :class="fullScreen ? 'centerbtn-fullscreen' : 'centerbtn'"></cover-image>  
15 - <cover-image v-if="isPlay && topShow" @click="centerPauseClick" src="../../static/qxc_pause.png" :class="fullScreen ? 'centerbtn-fullscreen' : 'centerbtn'"></cover-image> 9 + <cover-image v-if="!isPlay && topShow" @click="centerPlayClick" src="../../static/qxc_play.png"
  10 + :class="fullScreen ? 'centerbtn-fullscreen' : 'centerbtn'"></cover-image>
  11 + <cover-image v-if="isPlay && topShow" @click="centerPauseClick" src="../../static/qxc_pause.png"
  12 + :class="fullScreen ? 'centerbtn-fullscreen' : 'centerbtn'"></cover-image>
16 <SpeedView @speedChange="speedChange" ref="speedBox" class="speed-box"></SpeedView> 13 <SpeedView @speedChange="speedChange" ref="speedBox" class="speed-box"></SpeedView>
17 </video> 14 </video>
18 </view> 15 </view>
@@ -21,11 +18,16 @@ @@ -21,11 +18,16 @@
21 <script> 18 <script>
22 import QXCMiniPlayerSDK from './lib/qxcplaysdk.es' 19 import QXCMiniPlayerSDK from './lib/qxcplaysdk.es'
23 import SpeedView from './speed/speedview.vue' 20 import SpeedView from './speed/speedview.vue'
  21 + import {
  22 + REFERER
  23 + } from "@/common/config.js"
24 let qxcplayerSDK = null 24 let qxcplayerSDK = null
25 let videoCtx = null 25 let videoCtx = null
26 export default { 26 export default {
27 - name:"qxcplayer",  
28 - components: {SpeedView}, 27 + name: "qxcplayer",
  28 + components: {
  29 + SpeedView
  30 + },
29 props: { 31 props: {
30 height: { 32 height: {
31 type: Number, 33 type: Number,
@@ -34,6 +36,7 @@ @@ -34,6 +36,7 @@
34 }, 36 },
35 data() { 37 data() {
36 return { 38 return {
  39 + REFERER,
37 count: 0, 40 count: 0,
38 isPlay: false, 41 isPlay: false,
39 showControls: true, 42 showControls: true,
@@ -50,7 +53,8 @@ @@ -50,7 +53,8 @@
50 videoCtx = uni.createVideoContext('qxc_player', this) 53 videoCtx = uni.createVideoContext('qxc_player', this)
51 }, 54 },
52 methods: { 55 methods: {
53 - setTime: function(time) {/*设置视频初始化播放位置 参数 第一个 时间*/ 56 + setTime: function(time) {
  57 + /*设置视频初始化播放位置 参数 第一个 时间*/
54 let that = this; 58 let that = this;
55 if (time && time > 0) { 59 if (time && time > 0) {
56 videoCtx.seek(time); 60 videoCtx.seek(time);
@@ -69,18 +73,18 @@ @@ -69,18 +73,18 @@
69 isWx: true 73 isWx: true
70 }, 74 },
71 playerCallback: { 75 playerCallback: {
72 - onConnectResult: (type, reason) => {  
73 - }, 76 + onConnectResult: (type, reason) => {},
74 onDuplicateLoginKickOut: () => { 77 onDuplicateLoginKickOut: () => {
75 // 异地登录 78 // 异地登录
76 this.playUrl = '' 79 this.playUrl = ''
77 uni.showToast({ 80 uni.showToast({
78 title: '异地登录' + this.count, 81 title: '异地登录' + this.count,
79 - icon:'error', 82 + icon: 'error',
80 duration: 2000 83 duration: 2000
81 }); 84 });
82 }, 85 },
83 onPlayUrl: (url, time) => { 86 onPlayUrl: (url, time) => {
  87 + // console.log(url)
84 // uni.showToast({ 88 // uni.showToast({
85 // title: 'onPlayUrl' + url, 89 // title: 'onPlayUrl' + url,
86 // icon: 'none' 90 // icon: 'none'
@@ -88,14 +92,12 @@ @@ -88,14 +92,12 @@
88 this.playUrl = url 92 this.playUrl = url
89 videoCtx.seek(time) 93 videoCtx.seek(time)
90 }, 94 },
91 - onLineList: (linelist) => {  
92 - },  
93 - onPlayerInfo: (title, total) => {  
94 - }, 95 + onLineList: (linelist) => {},
  96 + onPlayerInfo: (title, total) => {},
95 onMediaError: (code, msg) => { 97 onMediaError: (code, msg) => {
96 uni.showToast({ 98 uni.showToast({
97 title: msg + "#" + code, 99 title: msg + "#" + code,
98 - icon:'error', 100 + icon: 'error',
99 duration: 2000 101 duration: 2000
100 }); 102 });
101 } 103 }
@@ -105,46 +107,46 @@ @@ -105,46 +107,46 @@
105 this.count = this.count + 1 107 this.count = this.count + 1
106 console.log('mgs: initData', this.count) 108 console.log('mgs: initData', this.count)
107 }, 109 },
108 - videoPlay: function () { 110 + videoPlay: function() {
109 this.isPlay = true 111 this.isPlay = true
110 }, 112 },
111 - videoPause: function () { 113 + videoPause: function() {
112 this.isPlay = false 114 this.isPlay = false
113 }, 115 },
114 - videoTimeUpdate: function (e) { 116 + videoTimeUpdate: function(e) {
115 qxcplayerSDK.setCurTime(Math.floor(e.detail.currentTime)) 117 qxcplayerSDK.setCurTime(Math.floor(e.detail.currentTime))
116 this.VVideo.curTime = e.detail.currentTime 118 this.VVideo.curTime = e.detail.currentTime
117 }, 119 },
118 - videoError: function (e) {  
119 - console.log(e) 120 + videoError: function(e) {
  121 + console.log('=========>', e)
120 uni.showToast({ 122 uni.showToast({
121 title: '播放失败' + this.count, 123 title: '播放失败' + this.count,
122 - icon:'error', 124 + icon: 'error',
123 duration: 2000 125 duration: 2000
124 }); 126 });
125 this.isPlay = false 127 this.isPlay = false
126 }, 128 },
127 - speedTap: function (e) { 129 + speedTap: function(e) {
128 this.$refs.speedBox.setShow() 130 this.$refs.speedBox.setShow()
129 }, 131 },
130 - speedChange: function (val) { 132 + speedChange: function(val) {
131 videoCtx.playbackRate(Number(val)) 133 videoCtx.playbackRate(Number(val))
132 this.speedVal = val 134 this.speedVal = val
133 }, 135 },
134 - controlstoggle: function (e) { 136 + controlstoggle: function(e) {
135 let show = e.detail.show 137 let show = e.detail.show
136 this.topShow = show 138 this.topShow = show
137 }, 139 },
138 - fullScreenChange: function (e) { 140 + fullScreenChange: function(e) {
139 this.fullScreen = e.detail.fullScreen 141 this.fullScreen = e.detail.fullScreen
140 }, 142 },
141 - centerPlayClick: function () { 143 + centerPlayClick: function() {
142 if (videoCtx) videoCtx.play() 144 if (videoCtx) videoCtx.play()
143 }, 145 },
144 - centerPauseClick: function () { 146 + centerPauseClick: function() {
145 if (videoCtx) videoCtx.pause() 147 if (videoCtx) videoCtx.pause()
146 }, 148 },
147 - destory: function () { 149 + destory: function() {
148 this.playUrl = '' 150 this.playUrl = ''
149 qxcplayerSDK.release() 151 qxcplayerSDK.release()
150 } 152 }
@@ -153,16 +155,17 @@ @@ -153,16 +155,17 @@
153 </script> 155 </script>
154 156
155 <style scoped> 157 <style scoped>
156 - .qxcplayer-box{ 158 + .qxcplayer-box {
157 position: relative; 159 position: relative;
158 width: 100%; 160 width: 100%;
159 } 161 }
160 162
161 - .qxc-video{ 163 + .qxc-video {
162 width: 100%; 164 width: 100%;
163 height: 100%; 165 height: 100%;
164 } 166 }
165 - .controller-top{ 167 +
  168 + .controller-top {
166 width: 100%; 169 width: 100%;
167 height: 30rpx; 170 height: 30rpx;
168 position: fixed; 171 position: fixed;
@@ -172,11 +175,12 @@ @@ -172,11 +175,12 @@
172 background: rgba(0, 0, 0, 0.3); 175 background: rgba(0, 0, 0, 0.3);
173 padding-top: 20rpx; 176 padding-top: 20rpx;
174 } 177 }
175 - .controller-top-nobg{ 178 +
  179 + .controller-top-nobg {
176 background: rgba(0, 0, 0, 0.0); 180 background: rgba(0, 0, 0, 0.0);
177 } 181 }
178 182
179 - .speed-txt{ 183 + .speed-txt {
180 color: white; 184 color: white;
181 font-size: 10pt; 185 font-size: 10pt;
182 pointer-events: all; 186 pointer-events: all;
@@ -184,7 +188,7 @@ @@ -184,7 +188,7 @@
184 padding: 2rpx; 188 padding: 2rpx;
185 } 189 }
186 190
187 - .centerbtn{ 191 + .centerbtn {
188 position: absolute; 192 position: absolute;
189 width: 30rpx; 193 width: 30rpx;
190 height: 30rpx; 194 height: 30rpx;
@@ -195,7 +199,7 @@ @@ -195,7 +199,7 @@
195 padding: 20rpx; 199 padding: 20rpx;
196 } 200 }
197 201
198 - .centerbtn-fullscreen{ 202 + .centerbtn-fullscreen {
199 position: absolute; 203 position: absolute;
200 width: 30rpx; 204 width: 30rpx;
201 height: 30rpx; 205 height: 30rpx;
@@ -70,15 +70,23 @@ @@ -70,15 +70,23 @@
70 currentTime:0, 70 currentTime:0,
71 playState:"pause",//"loading"/"playing"/"pause" 71 playState:"pause",//"loading"/"playing"/"pause"
72 isSliderChanging:false, 72 isSliderChanging:false,
73 - backgroundAudioManager: wx.getBackgroundAudioManager() 73 + backgroundAudioManager: uni.getBackgroundAudioManager()
74 }; 74 };
75 }, 75 },
76 mounted: function(){ 76 mounted: function(){
77 if(this.autoplay) { 77 if(this.autoplay) {
78 // this.play() 78 // this.play()
  79 +
79 } 80 }
80 }, 81 },
  82 + destroyed() {
  83 + console.log('destroyed')
  84 + this.stop()
  85 + },
81 methods:{ 86 methods:{
  87 + stop() {
  88 + this.backgroundAudioManager.stop()
  89 + },
82 previousSong() { 90 previousSong() {
83 this.$emit('previousSong') 91 this.$emit('previousSong')
84 }, 92 },
@@ -90,8 +98,19 @@ @@ -90,8 +98,19 @@
90 this.$refs.NotificationD.show = false 98 this.$refs.NotificationD.show = false
91 }, 99 },
92 setSrc(src) { 100 setSrc(src) {
93 - this.src = src  
94 - this.play() 101 + this.src = 'https://edudev.baoshanjiaoyu.com/code.mp3'
  102 + this.backgroundAudioManager.title = this.title;//
  103 + this.backgroundAudioManager.epname = this.epname;//
  104 + this.backgroundAudioManager.singer = this.singer;//
  105 + this.backgroundAudioManager.src = this.src
  106 + this.backgroundAudioManager.onPlay(this.playerOnPlay)
  107 + // this.setProgress(10)
  108 + this.backgroundAudioManager.onEnded(this.playerOnEnded)
  109 + this.backgroundAudioManager.onError(this.playerOnError)
  110 + // #ifdef APP-PLUS
  111 + this.backgroundAudioManager.play()
  112 + // #endif
  113 + // this.play()
95 }, 114 },
96 openNotificationD() { 115 openNotificationD() {
97 this.$refs.NotificationD.show = true 116 this.$refs.NotificationD.show = true
@@ -113,6 +132,8 @@ @@ -113,6 +132,8 @@
113 playerOnEnded:function(e) 132 playerOnEnded:function(e)
114 { 133 {
115 this.playState="pause"; 134 this.playState="pause";
  135 + console.log('playerOnEnded')
  136 + // this.backgroundAudioManager.stop()
116 this.$emit("ended"); 137 this.$emit("ended");
117 }, 138 },
118 playerOnTimeupdate:function(e) 139 playerOnTimeupdate:function(e)
@@ -128,6 +149,7 @@ @@ -128,6 +149,7 @@
128 }, 149 },
129 playerOnError:function(e) 150 playerOnError:function(e)
130 { 151 {
  152 + console.log(e)
131 uni.showToast({ 153 uni.showToast({
132 title:"播放出错"+e 154 title:"播放出错"+e
133 }); 155 });
@@ -150,14 +172,16 @@ @@ -150,14 +172,16 @@
150 return `${m}:${s}`; 172 return `${m}:${s}`;
151 }, 173 },
152 play:function(){ 174 play:function(){
  175 + console.log('=======》')
  176 + // #ifdef MP-WEIXIN
153 this.backgroundAudioManager.title = this.title;// 177 this.backgroundAudioManager.title = this.title;//
154 this.backgroundAudioManager.epname = this.epname;// 178 this.backgroundAudioManager.epname = this.epname;//
155 this.backgroundAudioManager.singer = this.singer;// 179 this.backgroundAudioManager.singer = this.singer;//
156 this.backgroundAudioManager.src = this.src 180 this.backgroundAudioManager.src = this.src
157 - this.backgroundAudioManager.onPlay(this.playerOnPlay)  
158 - // this.setProgress(10)  
159 - this.backgroundAudioManager.onEnded(this.playerOnEnded)  
160 - this.backgroundAudioManager.onError(this.playerOnError) 181 + // #endif
  182 + // #ifdef APP-PLUS
  183 + this.backgroundAudioManager.play()
  184 + // #endif
161 }, 185 },
162 pause:function(){ 186 pause:function(){
163 this.backgroundAudioManager.pause(); 187 this.backgroundAudioManager.pause();
@@ -184,4 +208,7 @@ @@ -184,4 +208,7 @@
184 208
185 <style lang="scss"> 209 <style lang="scss">
186 @import './index.scss'; 210 @import './index.scss';
  211 +.imt-audio-2{
  212 + margin-top: 100rpx;
  213 +}
187 </style> 214 </style>
1 { 1 {
2 - "name" : "teaching",  
3 - "appid" : "__UNI__C551C4D", 2 + "name" : "中志云校园",
  3 + "appid" : "__UNI__8740A53",
4 "description" : "", 4 "description" : "",
5 "versionName" : "1.0.0", 5 "versionName" : "1.0.0",
6 - "versionCode" : "100", 6 + "versionCode" : 20240619,
7 "transformPx" : false, 7 "transformPx" : false,
8 /* 5+App特有相关 */ 8 /* 5+App特有相关 */
9 "app-plus" : { 9 "app-plus" : {
@@ -17,7 +17,10 @@ @@ -17,7 +17,10 @@
17 "delay" : 0 17 "delay" : 0
18 }, 18 },
19 /* 模块配置 */ 19 /* 模块配置 */
20 - "modules" : {}, 20 + "modules" : {
  21 + "OAuth" : {},
  22 + "VideoPlayer" : {}
  23 + },
21 /* 应用发布信息 */ 24 /* 应用发布信息 */
22 "distribute" : { 25 "distribute" : {
23 /* android打包配置 */ 26 /* android打包配置 */
@@ -41,9 +44,49 @@ @@ -41,9 +44,49 @@
41 ] 44 ]
42 }, 45 },
43 /* ios打包配置 */ 46 /* ios打包配置 */
44 - "ios" : {}, 47 + "ios" : {
  48 + "dSYMs" : false
  49 + },
45 /* SDK配置 */ 50 /* SDK配置 */
46 - "sdkConfigs" : {} 51 + "sdkConfigs" : {
  52 + "payment" : {},
  53 + "oauth" : {
  54 + "univerify" : {}
  55 + },
  56 + "ad" : {}
  57 + },
  58 + "icons" : {
  59 + "android" : {
  60 + "hdpi" : "unpackage/res/icons/72x72.png",
  61 + "xhdpi" : "unpackage/res/icons/96x96.png",
  62 + "xxhdpi" : "unpackage/res/icons/144x144.png",
  63 + "xxxhdpi" : "unpackage/res/icons/192x192.png"
  64 + },
  65 + "ios" : {
  66 + "appstore" : "unpackage/res/icons/1024x1024.png",
  67 + "ipad" : {
  68 + "app" : "unpackage/res/icons/76x76.png",
  69 + "app@2x" : "unpackage/res/icons/152x152.png",
  70 + "notification" : "unpackage/res/icons/20x20.png",
  71 + "notification@2x" : "unpackage/res/icons/40x40.png",
  72 + "proapp@2x" : "unpackage/res/icons/167x167.png",
  73 + "settings" : "unpackage/res/icons/29x29.png",
  74 + "settings@2x" : "unpackage/res/icons/58x58.png",
  75 + "spotlight" : "unpackage/res/icons/40x40.png",
  76 + "spotlight@2x" : "unpackage/res/icons/80x80.png"
  77 + },
  78 + "iphone" : {
  79 + "app@2x" : "unpackage/res/icons/120x120.png",
  80 + "app@3x" : "unpackage/res/icons/180x180.png",
  81 + "notification@2x" : "unpackage/res/icons/40x40.png",
  82 + "notification@3x" : "unpackage/res/icons/60x60.png",
  83 + "settings@2x" : "unpackage/res/icons/58x58.png",
  84 + "settings@3x" : "unpackage/res/icons/87x87.png",
  85 + "spotlight@2x" : "unpackage/res/icons/80x80.png",
  86 + "spotlight@3x" : "unpackage/res/icons/120x120.png"
  87 + }
  88 + }
  89 + }
47 } 90 }
48 }, 91 },
49 /* 快应用特有相关 */ 92 /* 快应用特有相关 */
@@ -51,9 +94,10 @@ @@ -51,9 +94,10 @@
51 /* 小程序特有相关 */ 94 /* 小程序特有相关 */
52 "mp-weixin" : { 95 "mp-weixin" : {
53 "appid" : "wx5bbc433d447d1a86", 96 "appid" : "wx5bbc433d447d1a86",
54 - "permissions": {  
55 - "scope.record": {  
56 - "desc": "用于录制音频" 97 + "requiredBackgroundModes" : [ "audio", "location" ],
  98 + "permissions" : {
  99 + "scope.record" : {
  100 + "desc" : "用于录制音频"
57 } 101 }
58 }, 102 },
59 "setting" : { 103 "setting" : {
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 <view class="oneSettingV2-c-1-l">头像</view> 6 <view class="oneSettingV2-c-1-l">头像</view>
7 <view class="oneSettingV2-c-1-r"> 7 <view class="oneSettingV2-c-1-r">
8 <avatar selWidth="100rpx" selHeight="100rpx" @upload="myUpload" 8 <avatar selWidth="100rpx" selHeight="100rpx" @upload="myUpload"
9 - :avatarSrc="userdata.img?$service.getimg(userdata.img):'/static/images/tx.png'" 9 + :avatarSrc="userdata.img_url ? $service.getimg(userdata.img_url):'/static/images/tx.png'"
10 avatarStyle="width: 100rpx;height: 100rpx;border-radius: 50%;" inner=true></avatar> 10 avatarStyle="width: 100rpx;height: 100rpx;border-radius: 50%;" inner=true></avatar>
11 </view> 11 </view>
12 </view> 12 </view>
@@ -45,7 +45,7 @@ @@ -45,7 +45,7 @@
45 <view class="myQuestion-2-i-3-c-1"> 45 <view class="myQuestion-2-i-3-c-1">
46 <view class="myQuestion-2-i-3-c-1-l"> 46 <view class="myQuestion-2-i-3-c-1-l">
47 <view class="myQuestion-2-i-3-c-1-l-i"> 47 <view class="myQuestion-2-i-3-c-1-l-i">
48 - <image :src="info.lecturer.img_url || '/static/images/tx.png'" mode="widthFix"></image> 48 + <image :src="info.lecturer ? info.lecturer.img_url : '/static/images/tx.png'" mode="widthFix"></image>
49 </view> 49 </view>
50 <text class="myQuestion-2-i-3-c-1-l-t">{{info.lecturer.title}}老师回复</text> 50 <text class="myQuestion-2-i-3-c-1-l-t">{{info.lecturer.title}}老师回复</text>
51 </view> 51 </view>
@@ -317,6 +317,10 @@ @@ -317,6 +317,10 @@
317 height: 48rpx; 317 height: 48rpx;
318 width: 48rpx; 318 width: 48rpx;
319 border-radius: 200rpx; 319 border-radius: 200rpx;
  320 + image{
  321 + height: 100%;
  322 + width: 100%;
  323 + }
320 } 324 }
321 .myQuestion-2-i-3-c-1-l-t{ 325 .myQuestion-2-i-3-c-1-l-t{
322 font-size: 26rpx; 326 font-size: 26rpx;
@@ -27,6 +27,7 @@ @@ -27,6 +27,7 @@
27 import MarkReadPop from "../MarkReadPop/index.vue" 27 import MarkReadPop from "../MarkReadPop/index.vue"
28 import InfoPop from "../InfoPop/index.vue" 28 import InfoPop from "../InfoPop/index.vue"
29 import { READINGSTATUS } from "../../emit.js" 29 import { READINGSTATUS } from "../../emit.js"
  30 + import { GENDER } from "@/emit/index.js"
30 export default { 31 export default {
31 name: 'ListItem', 32 name: 'ListItem',
32 props: { 33 props: {
@@ -43,6 +44,7 @@ @@ -43,6 +44,7 @@
43 }, 44 },
44 data() { 45 data() {
45 return { 46 return {
  47 + GENDER,
46 READINGSTATUS 48 READINGSTATUS
47 } 49 }
48 }, 50 },
@@ -75,7 +77,6 @@ @@ -75,7 +77,6 @@
75 .ListItem-t-l { 77 .ListItem-t-l {
76 display: flex; 78 display: flex;
77 align-items: center; 79 align-items: center;
78 -  
79 .ListItem-t-l-1 { 80 .ListItem-t-l-1 {
80 font-size: 30rpx; 81 font-size: 30rpx;
81 color: #3D4054; 82 color: #3D4054;
@@ -84,6 +84,24 @@ @@ -84,6 +84,24 @@
84 "navigationStyle": "custom" 84 "navigationStyle": "custom"
85 } 85 }
86 86
  87 + },
  88 + {
  89 + "path" : "pages/update/update",
  90 + "style" :
  91 + {
  92 + "navigationBarTitleText": "",
  93 + "enablePullDownRefresh": false,
  94 + "navigationStyle": "custom",
  95 + "app-plus": {
  96 + "animationType": "fade-in", // 设置fade-in淡入动画,为最合理的动画类型
  97 + "background": "transparent", // 背景透明
  98 + "backgroundColor": "transparent", // 背景透明
  99 + "webviewBGTransparent":true,
  100 + "mask":"none",
  101 + "popGesture": "none" // 关闭IOS屏幕左边滑动关闭当前页面的功能
  102 + }
  103 + }
  104 +
87 } 105 }
88 ], 106 ],
89 "globalStyle": { 107 "globalStyle": {
@@ -249,6 +249,9 @@ @@ -249,6 +249,9 @@
249 } 249 }
250 &:last-child{ 250 &:last-child{
251 padding-right: 0; 251 padding-right: 0;
  252 + &:before{
  253 + border-left: none;
  254 + }
252 } 255 }
253 } 256 }
254 } 257 }
@@ -56,6 +56,10 @@ @@ -56,6 +56,10 @@
56 .UserMenu-i-1{ 56 .UserMenu-i-1{
57 height: 74rpx; 57 height: 74rpx;
58 width: 74rpx; 58 width: 74rpx;
  59 + image{
  60 + height: 100%;
  61 + width: 100%;
  62 + }
59 } 63 }
60 .UserMenu-i-2{ 64 .UserMenu-i-2{
61 font-size: 24rpx; 65 font-size: 24rpx;
@@ -78,135 +78,6 @@ @@ -78,135 +78,6 @@
78 </view> 78 </view>
79 </view> 79 </view>
80 </view> 80 </view>
81 - <view v-if="userDatas" class="header-wrap">  
82 - <view class="study-report area">  
83 - <image class="study-report-icon" src="@/static/images/xh_icon3.png"></image>  
84 - <text>学习报告:{{userDatas.name||''}}</text>  
85 - </view>  
86 - <view class="study-report-wrap area">  
87 - <view class="credit-wrap flex">  
88 - <view class="credit-item flex" @tap="$sjuNav.navigateTo(`/pagesB/oneMyCredit/oneMyCredit`,{credit})">  
89 - <view class="credit-num">  
90 - {{userDatas.credit||''}}  
91 - </view>  
92 - <view>  
93 - 我的学分  
94 - </view>  
95 - </view>  
96 - <view class="credit-item flex">  
97 - <view class="percentage-num">  
98 - {{userDatas.pm_num||''}}  
99 - </view>  
100 - <view>  
101 - <!-- {{userDatas.pm_title||''}} <text>(排名)</text> -->  
102 - 模拟全校排名  
103 - </view>  
104 - </view>  
105 - </view>  
106 - <view class="matter-wrap flex">  
107 - <view class="matter-item flex">  
108 - <view class="second-num">  
109 - {{userDatas.leave_num||'0'}}  
110 - </view>  
111 - <view class="">  
112 - <!-- <text class="leave"></text> -->  
113 - 请假  
114 - </view>  
115 - </view>  
116 - <view class="matter-item flex">  
117 - <view class="second-num">  
118 - {{userDatas.late_num||'0'}}  
119 - </view>  
120 - <view class="">  
121 - <!-- <text class="leave2"></text> -->  
122 - 迟到  
123 - </view>  
124 - </view>  
125 - <view class="matter-item flex">  
126 - <view class="second-num">  
127 - {{userDatas.truancy_num||'0'}}  
128 - </view>  
129 - <view class="">  
130 - <!-- <text class="leave3"></text> -->  
131 - 旷课  
132 - </view>  
133 - </view>  
134 - <view class="matter-item flex">  
135 - <view class="second-num">  
136 - {{userDatas.nophone_num||'0'}}  
137 - </view>  
138 - <view class="">  
139 - <!-- <text class="leave4"></text> -->  
140 - 未交手机  
141 - </view>  
142 - </view>  
143 - </view>  
144 - </view>  
145 - </view>  
146 - <!-- 说明内容 -->  
147 - <view class="explain">  
148 - 模块正确率达到上岸基准线,对应模块徽章将被点亮。全部  
149 - 徽章点亮即可凭荣誉勋章截图到学生服务中心领取奖品1份!  
150 - </view>  
151 - <!-- 勋章墙 -->  
152 - <view class="medalWall">  
153 - <view class="medalWall-Item" v-for="item in medalList" :key="item.id">  
154 - <view class="medalWall-Item-icon">  
155 - <image src="@/static/images/xh_icon1.png" v-if="item.is_light"></image>  
156 - <image src="@/static/images/xh_icon2.png" v-else></image>  
157 - </view>  
158 - <view class="medalWall-Item-text">{{ item.name }}</view>  
159 - </view>  
160 - </view>  
161 - <!--  
162 - 菜单2.0  
163 - author: xuhao  
164 - date: 2023.02.20  
165 - -->  
166 - <view class="menu area">  
167 - <view class="menu-item" @tap="go_txz">  
168 - <view class="menu-item-icon">  
169 - <image src="@/static/images/xh_icon4.png"></image>  
170 - </view>  
171 - <view class="menu-item-text">走读通行证</view>  
172 - </view>  
173 - <view class="menu-item" @click="$service.jump" data-url="/pagesB/oneRanking/oneRanking">  
174 - <view class="menu-item-icon">  
175 - <image src="@/static/images/xh_icon5.png"></image>  
176 - </view>  
177 - <view class="menu-item-text">班级考勤排名</view>  
178 - </view>  
179 - <view class="menu-item" @click="$service.jump" data-url="/pagesB/oneLeave/oneLeave">  
180 - <view class="menu-item-icon">  
181 - <image src="@/static/images/xh_icon6.png"></image>  
182 - </view>  
183 - <view class="menu-item-text">请假申请</view>  
184 - </view>  
185 - <view class="menu-item" @click="$service.jump" data-url="/pagesB/notHand/notHand">  
186 - <view class="menu-item-icon">  
187 - <image src="@/static/images/xh_icon7.png"></image>  
188 - </view>  
189 - <view class="menu-item-text">不交手机申请</view>  
190 - </view>  
191 - <view class="menu-item" @click="$service.jump" data-url="/pagesStu/sq_list/sq_list">  
192 - <view class="menu-item-icon">  
193 - <image src="@/static/images/xh_icon8.png"></image>  
194 - </view>  
195 - <view class="menu-item-text">申请审批结果</view>  
196 - </view>  
197 - <view class="menu-item" @click="$service.jump" data-url="/pages_v2/stu_jspf_index/stu_jspf_index">  
198 - <view class="menu-item-icon">  
199 - <image src="@/static/images/xh_icon9.png"></image>  
200 - </view>  
201 - <view class="menu-item-text">评价反馈</view>  
202 - </view>  
203 - <view class="menu-item" @click="$service.jump" data-url="/page_admin/praise_andLike/praise_andLike">  
204 - <view class="menu-item-icon">  
205 - <image src="@/static/images/admin/icon5.png"></image>  
206 - </view>  
207 - <view class="menu-item-text">点赞表扬</view>  
208 - </view>  
209 - </view>  
210 <PopupA ref="popupARef"/> 81 <PopupA ref="popupARef"/>
211 <HonorWall ref="honorWallRef" :dataList="medalList" /> 82 <HonorWall ref="honorWallRef" :dataList="medalList" />
212 </view> 83 </view>
@@ -493,6 +364,7 @@ @@ -493,6 +364,7 @@
493 position: relative; 364 position: relative;
494 .contentV2-1-bg{ 365 .contentV2-1-bg{
495 height: 375rpx; 366 height: 375rpx;
  367 + width: 100%;
496 box-sizing: border-box; 368 box-sizing: border-box;
497 } 369 }
498 .contentV2-1-c{ 370 .contentV2-1-c{
@@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
10 10
11 <script> 11 <script>
12 import Vue from 'vue' 12 import Vue from 'vue'
  13 + import { update } from "@/common/uitls.js"
13 import { 14 import {
14 mapState, 15 mapState,
15 mapMutations 16 mapMutations
@@ -41,6 +42,9 @@ @@ -41,6 +42,9 @@
41 // url:'/new_tec/homePage/homePage' 42 // url:'/new_tec/homePage/homePage'
42 // }) 43 // })
43 // return 44 // return
  45 + // #ifdef APP-PLUS
  46 + update()
  47 + // #endif
44 if(identity==2){ 48 if(identity==2){
45 uni.reLaunch({ 49 uni.reLaunch({
46 url:'/pages/tch_index/tch_index' 50 url:'/pages/tch_index/tch_index'
@@ -49,6 +53,10 @@ @@ -49,6 +53,10 @@
49 uni.switchTab({ 53 uni.switchTab({
50 url:'/pages/index/index' 54 url:'/pages/index/index'
51 }) 55 })
  56 + } else if(identity==4){
  57 + uni.reLaunch({
  58 + url:'/new_tec/homePage/homePage'
  59 + })
52 } else { 60 } else {
53 uni.reLaunch({ 61 uni.reLaunch({
54 url:'/pages/admin_index/admin_index' 62 url:'/pages/admin_index/admin_index'
1 <template> 1 <template>
2 <view class="oneSubmitted"> 2 <view class="oneSubmitted">
3 - <CustomReturn bgColor="none" title="登录"/> 3 + <CustomReturn bgColor="none" title="登录" />
4 <view class="oneSubmitted-v2"> 4 <view class="oneSubmitted-v2">
5 <image class="oneSubmitted-v2-bg" src="@/static/imagesV2/icon29.png" mode="widthFix"></image> 5 <image class="oneSubmitted-v2-bg" src="@/static/imagesV2/icon29.png" mode="widthFix"></image>
6 <PaddingTopB> 6 <PaddingTopB>
@@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
9 <image class="oneSubmitted-v2-1-i" src="@/static/imagesV2/icon68.png" mode="widthFix"></image> 9 <image class="oneSubmitted-v2-1-i" src="@/static/imagesV2/icon68.png" mode="widthFix"></image>
10 </view> 10 </view>
11 <view class="oneSubmitted-v2-2"> 11 <view class="oneSubmitted-v2-2">
  12 +
12 <view class="oneSubmitted-v2-2-1" @click="openMajor"> 13 <view class="oneSubmitted-v2-2-1" @click="openMajor">
13 <view class="oneSubmitted-v2-2-1-l"> 14 <view class="oneSubmitted-v2-2-1-l">
14 <text style="color: #979797;" v-if="!school.id">请选择学校</text> 15 <text style="color: #979797;" v-if="!school.id">请选择学校</text>
@@ -16,15 +17,57 @@ @@ -16,15 +17,57 @@
16 </view> 17 </view>
17 <u-icon name="arrow-down-fill" size="10"></u-icon> 18 <u-icon name="arrow-down-fill" size="10"></u-icon>
18 </view> 19 </view>
  20 + <!-- #ifdef APP-PLUS -->
  21 + <view class="oneSubmitted-v2-2-1">
  22 + <input v-model="phoneNumber" class="oneSubmitted-v2-2-1-i" type="text"
  23 + placeholder="请输入账号/手机号" />
  24 + </view>
  25 + <view class="oneSubmitted-v2-2-1" style="margin-bottom: 20rpx;"
  26 + v-if="loginType === LOGINMETHOD.CODE">
  27 + <input class="oneSubmitted-v2-2-1-i" type="text" v-model="code" placeholder="请输入验证码" />
  28 + <view class="oneSubmitted-v2-2-1-r">
  29 + <Countdown ref="countdownRef" @start="sendCode" />
  30 + </view>
  31 + </view>
  32 + <view class="oneSubmitted-v2-2-1" style="margin-bottom: 20rpx;" v-else>
  33 + <input class="oneSubmitted-v2-2-1-i" type="text" v-if="isPlaintext" v-model="password" placeholder="请输入密码" />
  34 + <input class="oneSubmitted-v2-2-1-i" type="password" v-else v-model="password" placeholder="请输入密码" />
  35 + <view @click="changePlaintext">
  36 + <u-icon name="eye-off" v-if="isPlaintext" color="#BDBDBD" size="20"></u-icon>
  37 + <u-icon name="eye-fill" v-else color="#BDBDBD" size="20"></u-icon>
  38 + </view>
  39 + </view>
  40 + <view class="oneSubmitted-v2-2-c" @click="">
  41 + <text v-if="loginType === LOGINMETHOD.CODE"
  42 + @click="changeLoginType(LOGINMETHOD.PASSWORDLOGIN)">密码登录</text>
  43 + <text v-else @click="changeLoginType(LOGINMETHOD.CODE)">验证码登录</text>
  44 + </view>
  45 + <view class="oneSubmitted-v2-2-xy">
  46 + <Protocol v-model="isReadProtocol" />
  47 + </view>
  48 + <!-- #endif -->
  49 + <!-- #ifdef APP-PLUS -->
  50 + <view class="oneSubmitted-v2-2-2" @click="appLogin">
  51 + 登录
  52 + </view>
  53 + <view class="oneSubmitted-v2-2-4">
  54 + <view class="oneSubmitted-v2-2-4-i" @click="oneClickLogin">
  55 + <image src="@/static/imagesV2/icon71.png" mode="widthFix"></image>
  56 + </view>
  57 + </view>
  58 + <!-- #endif -->
  59 + <!-- #ifdef MP-WEIXIN -->
19 <view class="oneSubmitted-v2-2-2" v-if="!school.id" @click="prompt"> 60 <view class="oneSubmitted-v2-2-2" v-if="!school.id" @click="prompt">
20 登录 61 登录
21 </view> 62 </view>
22 - <button class="oneSubmitted-v2-2-2" open-type="getPhoneNumber" @getphonenumber="onGetPhoneNumber" v-else> 63 + <button class="oneSubmitted-v2-2-2" open-type="getPhoneNumber" @getphonenumber="onGetPhoneNumber"
  64 + v-else>
23 登录 65 登录
24 </button> 66 </button>
25 <view class="oneSubmitted-v2-2-3"> 67 <view class="oneSubmitted-v2-2-3">
26 本小程序为中志教育内部系统,不对外开放 68 本小程序为中志教育内部系统,不对外开放
27 </view> 69 </view>
  70 + <!-- #endif -->
28 </view> 71 </view>
29 </view> 72 </view>
30 </PaddingTopB> 73 </PaddingTopB>
@@ -59,31 +102,218 @@ @@ -59,31 +102,218 @@
59 <script> 102 <script>
60 import CustomReturn from "@/components/CustomReturn/index.vue" 103 import CustomReturn from "@/components/CustomReturn/index.vue"
61 import PaddingTopB from "@/components/PaddingTopB/index.vue" 104 import PaddingTopB from "@/components/PaddingTopB/index.vue"
  105 + import Countdown from "@/components/Countdown/index.vue"
  106 + import Protocol from "@/components/Protocol/index.vue"
62 import Vue from 'vue' 107 import Vue from 'vue'
63 import { 108 import {
64 mapState, 109 mapState,
65 mapMutations 110 mapMutations
66 } from 'vuex' 111 } from 'vuex'
  112 + /**
  113 + * 大咖课类型
  114 + */
  115 + const LOGINMETHOD = {
  116 + /**
  117 + * 密码登录
  118 + * @value 1
  119 + */
  120 + 'PASSWORDLOGIN': 1,
  121 + /**
  122 + * 验证码登录
  123 + * @value 1
  124 + */
  125 + 'CODE': 2
  126 + }
67 var that 127 var that
68 export default { 128 export default {
69 components: { 129 components: {
70 CustomReturn, 130 CustomReturn,
71 - PaddingTopB 131 + PaddingTopB,
  132 + Countdown,
  133 + Protocol
72 }, 134 },
73 data() { 135 data() {
74 return { 136 return {
  137 + LOGINMETHOD,
  138 + loginType: LOGINMETHOD.PASSWORDLOGIN,
75 show: false, 139 show: false,
76 columns: [], 140 columns: [],
77 - school: {} 141 + school: {},
  142 + // 手机号/账号
  143 + phoneNumber: '',
  144 + // 验证码
  145 + code: '',
  146 + // 密码
  147 + password: '',
  148 + // 协议状态
  149 + isReadProtocol: false,
  150 + // 是否是明文密码
  151 + isPlaintext: false
78 } 152 }
79 }, 153 },
80 onLoad(option) { 154 onLoad(option) {
81 - that=this 155 + that = this
82 console.log(option); 156 console.log(option);
83 console.log(process.env.NODE_ENV) 157 console.log(process.env.NODE_ENV)
84 this.getColumns() 158 this.getColumns()
85 }, 159 },
86 methods: { 160 methods: {
  161 + changePlaintext() {
  162 + this.isPlaintext = !this.isPlaintext
  163 + },
  164 + changeLoginType(type) {
  165 + this.loginType = type
  166 + },
  167 + sendCode() {
  168 + if(!this.phoneNumber) {
  169 + uni.showToast({
  170 + title: '请输入手机号',
  171 + icon: 'none'
  172 + })
  173 + return
  174 + }
  175 + let form = {
  176 + phone: this.phoneNumber
  177 + }
  178 + console.log(form)
  179 + that.$service.P_post('login/send_sms', form).then(res => {
  180 + if (res.code == 1) {
  181 + this.$refs.countdownRef.start()
  182 + } else {
  183 + if (res.msg) {
  184 + uni.showToast({
  185 + icon: 'none',
  186 + title: res.msg
  187 + })
  188 + } else {
  189 + uni.showToast({
  190 + icon: 'none',
  191 + title: '获取数据失败'
  192 + })
  193 + }
  194 + }
  195 + })
  196 + },
  197 + oneClickLogin() {
  198 + if (!this.school.id) {
  199 + uni.showToast({
  200 + icon: 'none',
  201 + title: '请选择学校'
  202 + })
  203 + return
  204 + }
  205 + this.loginPhone()
  206 + },
  207 + // 手机号一键登录
  208 + loginPhone(callBack = null) {
  209 + let that = this
  210 + uni.showLoading({
  211 + title: '加载中'
  212 + })
  213 + uni.preLogin({
  214 + provider: 'univerify',
  215 + success(res) {
  216 + //预登录成功
  217 + uni.hideLoading()
  218 + if (callBack) {
  219 + callBack()
  220 + }
  221 + uni.login({
  222 + provider: 'univerify',
  223 + univerifyStyle: { // 自定义登录框样式
  224 + "fullScreen": true,
  225 + "authButton": {
  226 + "normalColor": '#2d81ff',
  227 + "highlightColor": "#2d81ff",
  228 + "disabledColor": "#2d81ff",
  229 + "title": '本机号码一键登录/注册'
  230 + },
  231 + "otherLoginButton": {
  232 + "title": "其他登录方式"
  233 + },
  234 + "privacyTerms": {
  235 + "defaultCheckBoxState": false,
  236 + "checkBoxSize": 14,
  237 + "termsColor": "#2d81ff",
  238 + "textColor": "#202020",
  239 + // "uncheckedImage": "static/login/icon4.png",
  240 + // "checkedImage": "static/login/icon5.png",
  241 + "isCenterHint": true,
  242 + "privacyItems": [{
  243 + "url": "https://edudev.baoshanjiaoyu.com/agreement/yonghuxieyi.html", // 点击跳转的协议详情页面
  244 + "title": "校园通用户协议" // 协议名称
  245 + },
  246 + {
  247 + "url": "https://edudev.baoshanjiaoyu.com/agreement/yinsixieyi.html", // 点击跳转的协议详情页面
  248 + "title": "校园通隐私政策" // 协议名称
  249 + }
  250 + ]
  251 + }
  252 + },
  253 + success(res) { // 登录成功
  254 + console.log('===========》', res)
  255 + uni.closeAuthView()
  256 + let form = {
  257 + access_token: res.authResult.access_token,
  258 + openid: res.authResult.openid,
  259 + school_id: that.school.id
  260 + }
  261 + that.$service.P_post('login/loginByOperator', form).then(res => {
  262 + if (res.code == 1) {
  263 + that.jumpLogic(res.data)
  264 + } else {
  265 + if (res.msg) {
  266 + uni.showToast({
  267 + icon: 'none',
  268 + title: res.msg
  269 + })
  270 + } else {
  271 + uni.showToast({
  272 + icon: 'none',
  273 + title: '获取数据失败'
  274 + })
  275 + }
  276 + }
  277 +
  278 + })
  279 + },
  280 + // 当用户点击自定义按钮时,会触发uni.login的fail回调[点击其他登录方式,可以跳转页面]
  281 + // 判断返回数据执行任意逻辑
  282 + fail(res) { // 登录失败
  283 + console.log(res.errCode)
  284 + console.log(res.errMsg)
  285 + uni.closeAuthView()
  286 + uni.hideLoading()
  287 + if (res.code == 30003) {
  288 + uni.navigateBack({
  289 + delta: 1
  290 + })
  291 + }
  292 + if (res.code == "30002") {
  293 + console.log('密码登录');
  294 + } else if (res.code == "30008") {
  295 + console.log('自定义按钮登录方式');
  296 + }
  297 + }
  298 + })
  299 + },
  300 + fail(res) { // 预登录失败
  301 + // 不显示一键登录选项(或置灰)
  302 + // 根据错误信息判断失败原因,如有需要可将错误提交给统计服务器
  303 + uni.hideLoading()
  304 + if (callBack) {
  305 + callBack()
  306 + }
  307 + uni.closeAuthView()
  308 + // uni.navigateTo({
  309 + // url: '/pages/Login/Login'
  310 + // })
  311 + console.log('失败', 2222);
  312 + console.log(res.errCode)
  313 + console.log(res.errMsg)
  314 + }
  315 + });
  316 + },
87 prompt() { 317 prompt() {
88 uni.showToast({ 318 uni.showToast({
89 icon: 'none', 319 icon: 'none',
@@ -95,27 +325,30 @@ @@ -95,27 +325,30 @@
95 this.show = false 325 this.show = false
96 }, 326 },
97 getColumns() { 327 getColumns() {
98 - var jkurl='/login/school' 328 + var jkurl = '/login/school'
  329 + console.log('columns')
99 that.$service.P_get(jkurl).then(res => { 330 that.$service.P_get(jkurl).then(res => {
100 - console.log(res) 331 + console.log('columns', res)
101 this.columns = [res.data] 332 this.columns = [res.data]
  333 + }).catch(e => {
  334 + console.log('catch', e)
102 }) 335 })
103 }, 336 },
104 openMajor() { 337 openMajor() {
105 this.show = true 338 this.show = true
106 }, 339 },
107 - onGetPhoneNumber(e){  
108 - var that =this  
109 - if(e.detail.errMsg=="getPhoneNumber:fail user deny"){ //用户决绝授权  
110 - }else{ //允许授权 340 + onGetPhoneNumber(e) {
  341 + var that = this
  342 + if (e.detail.errMsg == "getPhoneNumber:fail user deny") { //用户决绝授权
  343 + } else { //允许授权
111 console.log(e) 344 console.log(e)
112 //e.detail.encryptedData //加密的用户信息 345 //e.detail.encryptedData //加密的用户信息
113 //e.detail.iv //加密算法的初始向量 时要用到 346 //e.detail.iv //加密算法的初始向量 时要用到
114 // uni.setStorageSync('res_code', res_login.code); 347 // uni.setStorageSync('res_code', res_login.code);
115 - var datas={ 348 + var datas = {
116 code: e.detail.code 349 code: e.detail.code
117 } 350 }
118 - var jkurl='login/getPhone' 351 + var jkurl = 'login/getPhone'
119 352
120 that.$service.P_post(jkurl, datas).then(res => { 353 that.$service.P_post(jkurl, datas).then(res => {
121 that.btnkg = 0 354 that.btnkg = 0
@@ -128,7 +361,7 @@ @@ -128,7 +361,7 @@
128 // if (typeof datas == 'string') { 361 // if (typeof datas == 'string') {
129 // datas = JSON.parse(datas) 362 // datas = JSON.parse(datas)
130 // } 363 // }
131 - var datas=JSON.stringify(datas) 364 + var datas = JSON.stringify(datas)
132 console.log(res) 365 console.log(res)
133 // uni.showModal({ 366 // uni.showModal({
134 // title:e.detail.code, 367 // title:e.detail.code,
@@ -161,44 +394,131 @@ @@ -161,44 +394,131 @@
161 }) 394 })
162 } 395 }
163 }, 396 },
164 - login_fuc(){ 397 + login_fuc() {
165 // /pages/index/index 398 // /pages/index/index
166 // console.log(that.$service.VER) 399 // console.log(that.$service.VER)
167 // return 400 // return
168 - if(that.$service.VER==0){  
169 - uni.setStorageSync('identity',0) 401 + if (that.$service.VER == 0) {
  402 + uni.setStorageSync('identity', 0)
170 uni.switchTab({ 403 uni.switchTab({
171 - url:'/pages/index/index' 404 + url: '/pages/index/index'
172 }) 405 })
173 return 406 return
174 407
175 - }else{ 408 + } else {
176 409
177 that.getdata('18300000000') 410 that.getdata('18300000000')
178 } 411 }
179 412
180 }, 413 },
181 - login_fuc1(){ 414 + login_fuc1() {
182 that.getdata('15536043014') 415 that.getdata('15536043014')
183 return 416 return
184 - uni.setStorageSync('identity',1) 417 + uni.setStorageSync('identity', 1)
185 uni.reLaunch({ 418 uni.reLaunch({
186 - url:'/pages/tch_index/tch_index' 419 + url: '/pages/tch_index/tch_index'
  420 + })
  421 + },
  422 + appLogin() {
  423 + // #ifdef APP-PLUS
  424 + if(!this.isReadProtocol) {
  425 + uni.showToast({
  426 + icon: 'none',
  427 + title: '请阅读并同意《用户协议》和《隐私政策》'
  428 + })
  429 + return
  430 + }
  431 + if (!this.school.id) {
  432 + uni.showToast({
  433 + icon: 'none',
  434 + title: '请选择学校'
  435 + })
  436 + return
  437 + }
  438 + if(!this.phoneNumber) {
  439 + uni.showToast({
  440 + icon: 'none',
  441 + title: '请填写手机号'
  442 + })
  443 + return
  444 + }
  445 + if(this.loginType === LOGINMETHOD.PASSWORDLOGIN) {
  446 + if(!this.password) {
  447 + uni.showToast({
  448 + icon: 'none',
  449 + title: '请输入密码'
  450 + })
  451 + return
  452 + }
  453 + let form = {
  454 + school_id: this.school.id,
  455 + phone: this.phoneNumber,
  456 + pass: this.password
  457 + }
  458 + that.$service.P_post('login/loginByPassword', form).then(res => {
  459 + if (res.code == 1) {
  460 + that.jumpLogic(res.data)
  461 + } else {
  462 + if (res.msg) {
  463 + uni.showToast({
  464 + icon: 'none',
  465 + title: res.msg
  466 + })
  467 + } else {
  468 + uni.showToast({
  469 + icon: 'none',
  470 + title: '获取数据失败'
  471 + })
  472 + }
  473 + }
  474 + })
  475 + } else if(this.loginType === LOGINMETHOD.CODE) {
  476 + if(!this.code) {
  477 + uni.showToast({
  478 + icon: 'none',
  479 + title: '请输入验证码'
  480 + })
  481 + return
  482 + }
  483 + let form = {
  484 + school_id: this.school.id,
  485 + phone: this.phoneNumber,
  486 + code: this.code
  487 + }
  488 + that.$service.P_post('login/loginByCode', form).then(res => {
  489 + if (res.code == 1) {
  490 + that.jumpLogic(res.data)
  491 + } else {
  492 + if (res.msg) {
  493 + uni.showToast({
  494 + icon: 'none',
  495 + title: res.msg
  496 + })
  497 + } else {
  498 + uni.showToast({
  499 + icon: 'none',
  500 + title: '获取数据失败'
187 }) 501 })
  502 + }
  503 + }
  504 + })
  505 + }
  506 + // #endif
188 }, 507 },
189 - getdata(tel){ 508 + getdata(tel) {
190 509
  510 + // #ifdef MP-WEIXIN
191 wx.login({ 511 wx.login({
192 success: function(res_login) { 512 success: function(res_login) {
193 console.log(res_login) 513 console.log(res_login)
194 uni.setStorageSync('res_code', res_login.code); 514 uni.setStorageSync('res_code', res_login.code);
195 - var datas={ 515 + var datas = {
196 code: res_login.code, 516 code: res_login.code,
197 - type:1,  
198 - phone:tel, 517 + type: 1,
  518 + phone: tel,
199 school_id: that.school.id 519 school_id: that.school.id
200 } 520 }
201 - var jkurl='/login' 521 + var jkurl = '/login'
202 522
203 that.$service.P_post(jkurl, datas).then(res => { 523 that.$service.P_post(jkurl, datas).then(res => {
204 that.btnkg = 0 524 that.btnkg = 0
@@ -206,44 +526,13 @@ @@ -206,44 +526,13 @@
206 if (res.code == 1) { 526 if (res.code == 1) {
207 that.htmlReset = 0 527 that.htmlReset = 0
208 var datas = res.data 528 var datas = res.data
209 - console.log(typeof datas) 529 + console.log('datas', datas)
210 530
211 if (typeof datas == 'string') { 531 if (typeof datas == 'string') {
212 datas = JSON.parse(datas) 532 datas = JSON.parse(datas)
213 } 533 }
214 - console.log(res)  
215 - var identity=datas.identity  
216 - var token=datas.token  
217 - uni.setStorageSync('identity',identity)  
218 - uni.setStorageSync('token',token)  
219 - that.$store.commit('login', datas)  
220 - uni.showToast({  
221 - icon: 'none',  
222 - title: '登陆成功'  
223 - })  
224 - setTimeout(function(){  
225 - // uni.reLaunch({  
226 - // url:'/new_tec/homePage/homePage'  
227 - // })  
228 - // return  
229 - if(identity==2){  
230 - uni.reLaunch({  
231 - url:'/pages/tch_index/tch_index'  
232 - })  
233 - }else if(identity==1){  
234 - uni.switchTab({  
235 - url:'/pages/index/index'  
236 - })  
237 - } else if(identity==4){  
238 - uni.reLaunch({  
239 - url:'/new_tec/homePage/homePage'  
240 - })  
241 - } else {  
242 - uni.reLaunch({  
243 - url:'/pages/admin_index/admin_index'  
244 - })  
245 - }  
246 - },1000) 534 +
  535 + that.jumpLogic(datas)
247 536
248 } else { 537 } else {
249 538
@@ -271,8 +560,44 @@ @@ -271,8 +560,44 @@
271 }) 560 })
272 } 561 }
273 }) 562 })
274 - 563 + // #endif
275 }, 564 },
  565 +
  566 + jumpLogic(datas) {
  567 + console.log(datas)
  568 + var identity = datas.identity
  569 + var token = datas.token
  570 + uni.setStorageSync('identity', identity)
  571 + uni.setStorageSync('token', token)
  572 + that.$store.commit('login', datas)
  573 + uni.showToast({
  574 + icon: 'none',
  575 + title: '登陆成功'
  576 + })
  577 + setTimeout(function() {
  578 + // uni.reLaunch({
  579 + // url:'/new_tec/homePage/homePage'
  580 + // })
  581 + // return
  582 + if (identity == 2) {
  583 + uni.reLaunch({
  584 + url: '/pages/tch_index/tch_index'
  585 + })
  586 + } else if (identity == 1) {
  587 + uni.switchTab({
  588 + url: '/pages/index/index'
  589 + })
  590 + } else if (identity == 4) {
  591 + uni.reLaunch({
  592 + url: '/new_tec/homePage/homePage'
  593 + })
  594 + } else {
  595 + uni.reLaunch({
  596 + url: '/pages/admin_index/admin_index'
  597 + })
  598 + }
  599 + }, 1000)
  600 + }
276 } 601 }
277 } 602 }
278 </script> 603 </script>
@@ -281,24 +606,30 @@ @@ -281,24 +606,30 @@
281 .oneSubmitted { 606 .oneSubmitted {
282 position: relative; 607 position: relative;
283 } 608 }
284 - .oneSubmitted-v2{ 609 +
  610 + .oneSubmitted-v2 {
285 position: relative; 611 position: relative;
286 background-color: #ebf5ff; 612 background-color: #ebf5ff;
287 - .oneSubmitted-v2-bg{ 613 +
  614 + .oneSubmitted-v2-bg {
288 position: absolute; 615 position: absolute;
289 width: 100%; 616 width: 100%;
290 } 617 }
291 - .oneSubmitted-v2-1{ 618 +
  619 + .oneSubmitted-v2-1 {
292 text-align: center; 620 text-align: center;
293 margin-top: 150rpx; 621 margin-top: 150rpx;
294 - .oneSubmitted-v2-1-i{ 622 +
  623 + .oneSubmitted-v2-1-i {
295 height: 240rpx; 624 height: 240rpx;
296 width: 240rpx; 625 width: 240rpx;
297 } 626 }
298 } 627 }
299 - .oneSubmitted-v2-2{ 628 +
  629 + .oneSubmitted-v2-2 {
300 padding: 0 75rpx; 630 padding: 0 75rpx;
301 - .oneSubmitted-v2-2-1{ 631 +
  632 + .oneSubmitted-v2-2-1 {
302 display: flex; 633 display: flex;
303 background-color: #FFFFFF; 634 background-color: #FFFFFF;
304 height: 102rpx; 635 height: 102rpx;
@@ -306,11 +637,40 @@ @@ -306,11 +637,40 @@
306 border-radius: 300rpx; 637 border-radius: 300rpx;
307 padding: 0 40rpx; 638 padding: 0 40rpx;
308 box-sizing: border-box; 639 box-sizing: border-box;
309 - .oneSubmitted-v2-2-1-l{ 640 + margin-bottom: 49rpx;
  641 +
  642 + &:last-child {
  643 + margin-bottom: 0;
  644 + }
  645 +
  646 + .oneSubmitted-v2-2-1-l {
310 flex-grow: 1; 647 flex-grow: 1;
311 } 648 }
  649 +
  650 + .oneSubmitted-v2-2-1-i {
  651 + flex-grow: 1;
  652 + font-size: 32rpx;
  653 + }
  654 +
  655 + .oneSubmitted-v2-2-1-r {
  656 + width: 200rpx;
  657 + display: flex;
  658 + justify-content: flex-end;
  659 + flex-shrink: 0;
312 } 660 }
313 - .oneSubmitted-v2-2-2{ 661 + }
  662 +
  663 + .oneSubmitted-v2-2-c {
  664 + margin-bottom: 30rpx;
  665 + text-align: right;
  666 + padding-right: 20rpx;
  667 + color: #646464;
  668 + font-size: 28rpx;
  669 + }
  670 +
  671 + .oneSubmitted-v2-2-xy {}
  672 +
  673 + .oneSubmitted-v2-2-2 {
314 height: 90rpx; 674 height: 90rpx;
315 border-radius: 200rpx; 675 border-radius: 200rpx;
316 font-size: 34rpx; 676 font-size: 34rpx;
@@ -320,12 +680,26 @@ @@ -320,12 +680,26 @@
320 margin-top: 60rpx; 680 margin-top: 60rpx;
321 background-color: #2D81FF; 681 background-color: #2D81FF;
322 } 682 }
323 - .oneSubmitted-v2-2-3{ 683 +
  684 + .oneSubmitted-v2-2-3 {
324 font-size: 24rpx; 685 font-size: 24rpx;
325 margin-top: 26rpx; 686 margin-top: 26rpx;
326 text-align: center; 687 text-align: center;
327 color: #323232; 688 color: #323232;
328 } 689 }
  690 + .oneSubmitted-v2-2-4{
  691 + display: flex;
  692 + justify-content: center;
  693 + margin-top: 40rpx;
  694 + .oneSubmitted-v2-2-4-i{
  695 + width: 88rpx;
  696 + height: 88rpx;
  697 + image{
  698 + height: 100%;
  699 + width: 100%;
  700 + }
  701 + }
  702 + }
329 } 703 }
330 } 704 }
331 705
@@ -369,10 +743,12 @@ @@ -369,10 +743,12 @@
369 margin: 28rpx 0 28rpx 0; 743 margin: 28rpx 0 28rpx 0;
370 744
371 } 745 }
372 - .botm-btn1{ 746 +
  747 + .botm-btn1 {
373 margin-top: 40rpx; 748 margin-top: 40rpx;
374 } 749 }
375 - .botm-btn-2{ 750 +
  751 + .botm-btn-2 {
376 margin-top: 40rpx; 752 margin-top: 40rpx;
377 background-color: #F4F4F4; 753 background-color: #F4F4F4;
378 width: 100%; 754 width: 100%;
@@ -383,6 +759,7 @@ @@ -383,6 +759,7 @@
383 border-radius: 200rpx; 759 border-radius: 200rpx;
384 font-size: 25rpx; 760 font-size: 25rpx;
385 } 761 }
  762 +
386 .samll-text { 763 .samll-text {
387 height: 28rpx; 764 height: 28rpx;
388 font-size: 28rpx; 765 font-size: 28rpx;
@@ -390,7 +767,8 @@ @@ -390,7 +767,8 @@
390 font-weight: 400; 767 font-weight: 400;
391 color: #545D6E; 768 color: #545D6E;
392 } 769 }
393 - .login_top{ 770 +
  771 + .login_top {
394 width: 100%; 772 width: 100%;
395 } 773 }
396 </style> 774 </style>
@@ -91,161 +91,6 @@ @@ -91,161 +91,6 @@
91 </view> 91 </view>
92 </PaddingTopB> 92 </PaddingTopB>
93 </view> 93 </view>
94 - <!-- 我的 -->  
95 - <!-- 头部卡片 -->  
96 - <view v-if="mymsg" class="header-wrap">  
97 - <view class="header-all area flex">  
98 - <view class="header-left flex" @tap="$sjuNav.navigateTo(`/pagesB/oneSetting/oneSetting`)">  
99 - <view class="header-img">  
100 - <!-- <image :src="userImg" mode="aspectFill"></image> -->  
101 - <myLazyLoad class="image" :src="$service.getimg(mymsg.img)" mode="aspectFill" :borderRadius="112"></myLazyLoad>  
102 - </view>  
103 - <view class="header-user">  
104 - <view class="header-userName flex">  
105 - <view class="user_name oh1">  
106 - {{mymsg.name||''}}  
107 - </view> <text class="oh1">{{mymsg.className||''}}</text>  
108 - </view>  
109 - <view class="header-userNum oh1">  
110 - {{mymsg.study_code||''}}  
111 - </view>  
112 - </view>  
113 - </view>  
114 - <view class="pass-check" @tap="go_txz">  
115 - 通行证  
116 - </view>  
117 - </view>  
118 - </view>  
119 -  
120 - <view>  
121 - <!-- 我的住宿办理 -->  
122 - <view class="handle-wrap area">  
123 - <image class="handle-img" src="/static/images/wdzsbl.png" mode="aspectFit" />  
124 - <view class="handle-item flex">  
125 - <view class="handle-item-left flex">  
126 - <text class="icon icon-xiangxingtujianzhu handle-icon"></text>  
127 - <view class="my-handle">  
128 - 我的住宿办理  
129 - </view>  
130 - </view>  
131 - <!-- <view class="go-see" @click="$service.jump" data-url="/pagesStu/stu_live/stu_live"> -->  
132 - <view class="go-see" @click="gozs" data-url="/pagesStu/stu_live/stu_live">  
133 - 去查看  
134 - </view>  
135 - </view>  
136 - </view>  
137 -  
138 - <!-- 我的床位 手机箱 -->  
139 - <view class="content-wrap-bed-phone area flex">  
140 - <view class="content-item">  
141 - <image class="content-img" src="/static/images/wdcw.png" mode="aspectFit"></image>  
142 - <view class="content-text flex">  
143 - <view class="content-bed">  
144 - 我的床位  
145 - </view>  
146 - <view class="content-bed-num">  
147 - {{mymsg.bed_title||''}}  
148 - </view>  
149 - </view>  
150 - </view>  
151 - <view class="content-item">  
152 - <image class="content-img" src="/static/images/sjx.png" mode="aspectFit"></image>  
153 - <view class="content-text flex">  
154 - <view class="content-bed">  
155 - 手机箱  
156 - </view>  
157 - <view class="content-bed-num">  
158 - {{mymsg.phone_box||''}}  
159 - </view>  
160 - </view>  
161 - </view>  
162 - </view>  
163 -  
164 - <!-- 列表 -->  
165 - <view class="seat-num-wrap area">  
166 - <!-- <view class="seat-num-item flex">  
167 - <view class="seat-num-left flex">  
168 - <text class="icon icon-banji seat-icon"></text>  
169 - <view class="seat-text">  
170 - 小班座位  
171 - </view>  
172 - </view>  
173 - <view class="seat-num">  
174 - {{mymsg.small_seat||''}}  
175 - </view>  
176 - </view> -->  
177 - <view class="seat-num-item flex">  
178 - <view class="seat-num-left flex">  
179 - <text class="icon icon-xuexi seat-icon2"></text>  
180 - <view class="seat-text">  
181 - 听课座位  
182 - </view>  
183 - </view>  
184 - <view class="seat-num">  
185 - {{mymsg.big_seat||''}}  
186 - </view>  
187 - </view>  
188 - <view class="seat-num-item flex">  
189 - <view class="seat-num-left flex flex_0">  
190 - <text class="icon icon-banji seat-icon"></text>  
191 - <view class="seat-text">  
192 - 我的班级  
193 - </view>  
194 - </view>  
195 - <view class="seat-num">  
196 - {{mymsg.className||''}}  
197 - </view>  
198 - </view>  
199 - <view class="seat-num-item flex">  
200 - <view class="seat-num-left flex">  
201 - <text class="icon icon-banzhuren seat-icon"></text>  
202 - <view class="seat-text">  
203 - 班主任电话  
204 - </view>  
205 - </view>  
206 - <view class="seat-num">  
207 - {{mymsg.teacher_phone||''}}  
208 - </view>  
209 - </view>  
210 - <view class="seat-num-item flex">  
211 - <view class="seat-num-left flex">  
212 - <text class="icon icon-kechengqiri seat-icon"></text>  
213 - <view class="seat-text">  
214 - 课程有效期  
215 - </view>  
216 - </view>  
217 - <view class="seat-num">  
218 - {{mymsg.end_time||''}}  
219 - </view>  
220 - </view>  
221 - <!-- <view class="seat-num-item flex" @click="$service.jump" data-url="/pagesStu/sq_list/sq_list">  
222 - <view class="seat-num-left flex">  
223 - <text class="icon icon-xiangxingtujianzhu seat-icon"></text>  
224 - <view class="seat-text">  
225 - 请假申请记录  
226 - </view>  
227 - </view>  
228 - <view class="seat-num">  
229 - <text class="icon icon-arrow-right-copy seat-icon"></text>  
230 - </view>  
231 - </view>  
232 - <view class="seat-num-item flex" @click="$service.jump" data-url="/pagesStu/sq_list_tel/sq_list_tel">  
233 - <view class="seat-num-left flex">  
234 - <text class="icon icon-xiangxingtujianzhu seat-icon"></text>  
235 - <view class="seat-text">  
236 - 不交手机申请记录  
237 - </view>  
238 - </view>  
239 -  
240 -  
241 - <view class="seat-num">  
242 - <text class="icon icon-arrow-right-copy seat-icon"></text>  
243 - </view>  
244 - </view> -->  
245 -  
246 - </view>  
247 -  
248 - </view>  
249 </view> 94 </view>
250 </template> 95 </template>
251 96
@@ -248,6 +248,10 @@ @@ -248,6 +248,10 @@
248 right: 0; 248 right: 0;
249 width: 100rpx; 249 width: 100rpx;
250 height: 40rpx; 250 height: 40rpx;
  251 + image{
  252 + height: 100%;
  253 + width: 100%;
  254 + }
251 } 255 }
252 } 256 }
253 .entrance-container { 257 .entrance-container {
@@ -298,6 +302,10 @@ @@ -298,6 +302,10 @@
298 width: 78rpx; 302 width: 78rpx;
299 height: 40rpx; 303 height: 40rpx;
300 margin-top: 20rpx; 304 margin-top: 20rpx;
  305 + image{
  306 + height: 100%;
  307 + width: 100%;
  308 + }
301 } 309 }
302 } 310 }
303 } 311 }
@@ -13,8 +13,8 @@ @@ -13,8 +13,8 @@
13 <PaddingTopB> 13 <PaddingTopB>
14 14
15 <view class="main" v-if="userDatas"> 15 <view class="main" v-if="userDatas">
16 - <view class="user-wrap" @click="$service.jump" data-url="/pagesA/tch_msg/tch_msg">  
17 - <view class="user-info"> 16 + <view class="user-wrap">
  17 + <view class="user-info" @click="$service.jump" data-url="/pagesA/tch_msg/tch_msg">
18 <view class="avatar"> 18 <view class="avatar">
19 <view class="img"> 19 <view class="img">
20 <image :src="$service.getimg(userDatas.img)" mode="aspectFill"></image> 20 <image :src="$service.getimg(userDatas.img)" mode="aspectFill"></image>
@@ -323,11 +323,19 @@ @@ -323,11 +323,19 @@
323 .set-up { 323 .set-up {
324 width: 40rpx; 324 width: 40rpx;
325 height: 40rpx; 325 height: 40rpx;
  326 + image{
  327 + height: 100%;
  328 + width: 100%;
  329 + }
326 } 330 }
327 .bg-img { 331 .bg-img {
328 height: 360rpx; 332 height: 360rpx;
329 position: absolute; 333 position: absolute;
330 width: 100%; 334 width: 100%;
  335 + image{
  336 + height: 100%;
  337 + width: 100%;
  338 + }
331 } 339 }
332 .main { 340 .main {
333 width: 100%; 341 width: 100%;
@@ -355,6 +363,10 @@ @@ -355,6 +363,10 @@
355 box-sizing: border-box; 363 box-sizing: border-box;
356 border-radius: 50%; 364 border-radius: 50%;
357 overflow: hidden; 365 overflow: hidden;
  366 + image{
  367 + height: 100%;
  368 + width: 100%;
  369 + }
358 } 370 }
359 .identity { 371 .identity {
360 background: linear-gradient(0deg, #2D81FF 0%, #458FFE 100%); 372 background: linear-gradient(0deg, #2D81FF 0%, #458FFE 100%);
@@ -366,6 +378,8 @@ @@ -366,6 +378,8 @@
366 padding: 6rpx 20rpx; 378 padding: 6rpx 20rpx;
367 margin-top: -20rpx; 379 margin-top: -20rpx;
368 text-align: center; 380 text-align: center;
  381 + position: relative;
  382 + z-index: 2;
369 } 383 }
370 } 384 }
371 .info { 385 .info {
@@ -382,6 +396,10 @@ @@ -382,6 +396,10 @@
382 width: 30rpx; 396 width: 30rpx;
383 height: 30rpx; 397 height: 30rpx;
384 margin: 0 15rpx 0 10rpx; 398 margin: 0 15rpx 0 10rpx;
  399 + image{
  400 + height: 100%;
  401 + width: 100%;
  402 + }
385 } 403 }
386 .tab { 404 .tab {
387 background: rgba(49, 132, 255, 0.08); 405 background: rgba(49, 132, 255, 0.08);
@@ -431,6 +449,14 @@ @@ -431,6 +449,14 @@
431 } 449 }
432 .class-division { 450 .class-division {
433 margin-right: 100rpx; 451 margin-right: 100rpx;
  452 + .cell-item-icon{
  453 + height: 70rpx;
  454 + width: 70rpx;
  455 + image{
  456 + height: 100%;
  457 + width: 100%;
  458 + }
  459 + }
434 } 460 }
435 } 461 }
436 } 462 }
@@ -467,6 +493,10 @@ @@ -467,6 +493,10 @@
467 .icon { 493 .icon {
468 width: 70rpx; 494 width: 70rpx;
469 height: 70rpx; 495 height: 70rpx;
  496 + image{
  497 + height: 100%;
  498 + width: 100%;
  499 + }
470 } 500 }
471 } 501 }
472 .bg { 502 .bg {
  1 +<template>
  2 + <u-popup :show="show" bgColor="transparent" mode="center" :safeAreaInsetBottom="false" borderRadius="20">
  3 + <view class="new-update">
  4 + <view class="new-update-1">
  5 + <image class="new-update-1-i" src="@/static/imagesV2/icon70.png" mode="widthFix"></image>
  6 + <view class="new-update-1-c">
  7 + <view class="new-update-1-c-1">
  8 + 发现新版本
  9 + </view>
  10 + </view>
  11 + </view>
  12 + <view class="new-update-2">
  13 + <view class="new-update-2-1">新版本更新内容</view>
  14 + <scroll-view :scroll-y="true" style="height: 300rpx;">
  15 + <view style="font-size: 28rpx !important;">
  16 + <view v-html="content"></view>
  17 + </view>
  18 + </scroll-view>
  19 + <view class="immediate" @click="update" v-if="!is_load">立即升级</view>
  20 + <view class="progress" v-else>
  21 + <u-line-progress :percentage="progressOf" activeColor="#1b60b2"></u-line-progress>
  22 + <view class="progress-t">安装包下载中,请稍后({{ size.schedule }}M/{{ size.total }}M)</view>
  23 + </view>
  24 + </view>
  25 + </view>
  26 + </u-popup>
  27 +</template>
  28 +
  29 +<script>
  30 + export default {
  31 + data() {
  32 + return {
  33 + show: true,
  34 + content: '更新内容',
  35 + is_load: false,
  36 + progressOf: 0,
  37 + urlObj: {
  38 + ios: '',
  39 + apk: ''
  40 + },
  41 + size: {
  42 + total: 0,
  43 + schedule: 0
  44 + }
  45 + }
  46 + },
  47 + onBackPress(e) {
  48 + // 这里可以自定义返回逻辑
  49 + return true // return true 表示禁止默认返回
  50 + },
  51 + onLoad() {
  52 + this.getData()
  53 + },
  54 + methods: {
  55 + getData() {
  56 + let version = plus.runtime.version
  57 + this.$service.P_post('/version/index', {
  58 + client: uni.getSystemInfoSync().platform,
  59 + version: version
  60 + }).then(res => {
  61 + this.content = res.msg.content
  62 + if(plus.os.name.toLowerCase() == 'ios') {
  63 + this.urlObj.ios = res.msg.url
  64 + } else {
  65 + this.urlObj.apk = res.msg.url
  66 + }
  67 + })
  68 + },
  69 + update() {
  70 + let that = this
  71 + if (plus.os.name.toLowerCase() == 'ios') {
  72 + plus.runtime.openURL(this.urlObj.ios)
  73 + } else {
  74 + this.is_load = true
  75 + var dtask = this.getCreateDownload()
  76 + try {
  77 + dtask.start();
  78 + var prg = 0;
  79 + dtask.addEventListener('statechanged', (task, status) => {
  80 + switch (task.state) {
  81 + case 3:
  82 + that.progressOf = parseInt(
  83 + (parseFloat(task.downloadedSize) /
  84 + parseFloat(task.totalSize)) *
  85 + 100
  86 + );
  87 + that.size.total = (task.totalSize / (1024 * 1024)).toFixed(2)
  88 + that.size.schedule = (task.downloadedSize / (1024 * 1024)).toFixed(2)
  89 + break;
  90 + case 4:
  91 + that.is_load = false
  92 + //下载完成
  93 + break;
  94 + }
  95 + })
  96 + } catch (err) {
  97 + console.log('err', err)
  98 + // plus.nativeUI.closeWaiting();
  99 + that.is_load = false
  100 + uni.showToast({
  101 + title: '更新失败-03',
  102 + mask: false,
  103 + duration: 1500
  104 + });
  105 + }
  106 + }
  107 + },
  108 + // 获取下载实例
  109 + getCreateDownload() {
  110 + return plus.downloader.createDownload(this.urlObj.apk, {},
  111 + function(d, status) {
  112 + // 下载完成
  113 + if (status == 200) {
  114 + plus.runtime.install(plus.io.convertLocalFileSystemURL(d.filename), {}, e => e,
  115 + function(error) {
  116 + uni.showToast({
  117 + title: '安装失败-01',
  118 + mask: false,
  119 + duration: 1500
  120 + });
  121 + })
  122 + } else {
  123 + uni.showToast({
  124 + title: '更新失败-02',
  125 + mask: false,
  126 + duration: 1500
  127 + });
  128 + }
  129 + });
  130 + }
  131 + }
  132 + }
  133 +</script>
  134 +
  135 +<style lang="scss" scoped>
  136 + .new-update{
  137 + width: 611rpx;
  138 + .new-update-1{
  139 + position: relative;
  140 + height: 260rpx;
  141 + .new-update-1-i{
  142 + width: 100%;
  143 + position: absolute;
  144 + }
  145 + .new-update-1-c{
  146 + padding-top: 50rpx;
  147 + position: relative;
  148 + display: flex;
  149 + flex-direction: column;
  150 + justify-content: center;
  151 + height: 100%;
  152 + box-sizing: border-box;
  153 + padding-left: 54rpx;
  154 + .new-update-1-c-1{
  155 + font-size: 36rpx;
  156 + font-weight: 800;
  157 + color: #FFFFFF;
  158 + margin-bottom: 10rpx;
  159 + }
  160 + .new-update-1-c-2{
  161 + font-size: 26rpx;
  162 + color: #fff;
  163 + }
  164 + }
  165 + }
  166 + .new-update-2{
  167 + background: #fff;
  168 + border-radius:0 0 40rpx 40rpx;
  169 + padding: 50rpx;
  170 + padding-top: 20rpx;
  171 + box-sizing: border-box;
  172 + .new-update-2-1{
  173 + margin-bottom: 20rpx;
  174 + color: #1b60b2;
  175 + font-weight: bold;
  176 + }
  177 + .immediate{
  178 + line-height: 90rpx;
  179 + background: linear-gradient(0deg, #098ad5 0%, #1b60b2 100%);
  180 + color: #fff;
  181 + margin: 60rpx 0 0 0;
  182 + border-radius: 500rpx;
  183 + text-align: center;
  184 + }
  185 + .progress{
  186 + height: 80rpx;
  187 + margin: 60rpx 0 0 0;
  188 + .progress-t{
  189 + font-size: 26rpx;
  190 + color: #323232;
  191 + margin-top: 15rpx;
  192 + text-align: center;
  193 + }
  194 + }
  195 + }
  196 + }
  197 +</style>
@@ -401,6 +401,10 @@ @@ -401,6 +401,10 @@
401 width: 30rpx; 401 width: 30rpx;
402 height: 30rpx; 402 height: 30rpx;
403 margin-right: 10rpx; 403 margin-right: 10rpx;
  404 + image{
  405 + height: 100%;
  406 + width: 100%;
  407 + }
404 } 408 }
405 } 409 }
406 } 410 }
@@ -251,6 +251,8 @@ @@ -251,6 +251,8 @@
251 margin-right: 30rpx; 251 margin-right: 30rpx;
252 .avatar-img { 252 .avatar-img {
253 border-radius: 50%; 253 border-radius: 50%;
  254 + height: 100%;
  255 + width: 100%;
254 } 256 }
255 .gender { 257 .gender {
256 position: absolute; 258 position: absolute;
@@ -258,6 +260,10 @@ @@ -258,6 +260,10 @@
258 height: 24rpx; 260 height: 24rpx;
259 right: 0rpx; 261 right: 0rpx;
260 bottom: 12rpx; 262 bottom: 12rpx;
  263 + image{
  264 + height: 100%;
  265 + width: 100%;
  266 + }
261 } 267 }
262 } 268 }
263 .info { 269 .info {
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 {{item.name}} 16 {{item.name}}
17 </view> 17 </view>
18 <image class="gender" v-if="item.sex!=1" src="/static/imagesV2/stu_selection/icon_female.png" mode="aspectFit"></image> 18 <image class="gender" v-if="item.sex!=1" src="/static/imagesV2/stu_selection/icon_female.png" mode="aspectFit"></image>
19 - <image class="gender" v-else src="/static/imagesV2/stu_selection/icon_male.png" mode="aspectFit"></image> 19 + <image class="gender" v-else src="/static/imagesV2/stu_selection/icon_male.png" mode="widthFix"></image>
20 </view> 20 </view>
21 <view class="operate"> 21 <view class="operate">
22 <view class="btn" @click="$service.jump" :data-url="'/pagesA/stu_bz_index/stu_bz_index?id='+item.id"> 22 <view class="btn" @click="$service.jump" :data-url="'/pagesA/stu_bz_index/stu_bz_index?id='+item.id">
@@ -224,8 +224,8 @@ @@ -224,8 +224,8 @@
224 align-items: center; 224 align-items: center;
225 } 225 }
226 .gender { 226 .gender {
227 - width: 29rpx !important;  
228 - height: 24rpx !important; 227 + width: 29rpx;
  228 + height: 29rpx;
229 margin-left: 20rpx; 229 margin-left: 20rpx;
230 } 230 }
231 231
@@ -245,6 +245,10 @@ @@ -245,6 +245,10 @@
245 margin-right: 10rpx; 245 margin-right: 10rpx;
246 width: 30rpx; 246 width: 30rpx;
247 height: 30rpx; 247 height: 30rpx;
  248 + image{
  249 + height: 100%;
  250 + width: 100%;
  251 + }
248 } 252 }
249 } 253 }
250 } 254 }
@@ -206,6 +206,9 @@ @@ -206,6 +206,9 @@
206 height: 504rpx; 206 height: 504rpx;
207 position: absolute; 207 position: absolute;
208 width: 100%; 208 width: 100%;
  209 + image{
  210 + width: 100%;
  211 + }
209 } 212 }
210 .main { 213 .main {
211 width: 100%; 214 width: 100%;
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 4
5 </CustomReturn> 5 </CustomReturn>
6 <view class="bg-img"> 6 <view class="bg-img">
7 - <image src="/static/imagesV2/icon18.png" mode="aspectFill"></image> 7 + <image src="/static/imagesV2/icon18.png" mode="widthFix"></image>
8 </view> 8 </view>
9 9
10 <PaddingTopB> 10 <PaddingTopB>
@@ -220,12 +220,16 @@ @@ -220,12 +220,16 @@
220 position: absolute; 220 position: absolute;
221 width: 100%; 221 width: 100%;
222 top: 0; 222 top: 0;
  223 + image{
  224 + width: 100%;
  225 + height: 100%;
  226 + }
223 } 227 }
224 .main { 228 .main {
225 width: 100%; 229 width: 100%;
226 padding: 25rpx 25rpx 135rpx; 230 padding: 25rpx 25rpx 135rpx;
227 box-sizing: border-box; 231 box-sizing: border-box;
228 - margin-top: 250rpx; 232 + margin-top: 160rpx;
229 } 233 }
230 234
231 .card { 235 .card {
@@ -241,6 +245,10 @@ @@ -241,6 +245,10 @@
241 .icon { 245 .icon {
242 width: 40rpx; 246 width: 40rpx;
243 height: 40rpx; 247 height: 40rpx;
  248 + image{
  249 + height: 100%;
  250 + width: 100%;
  251 + }
244 } 252 }
245 .title { 253 .title {
246 font-size: 32rpx; 254 font-size: 32rpx;
@@ -15,16 +15,17 @@ @@ -15,16 +15,17 @@
15 </view> 15 </view>
16 </view> 16 </view>
17 <!-- #ifdef APP-PLUS --> 17 <!-- #ifdef APP-PLUS -->
18 - <view class="oneSettingV2-c-1"> 18 + <view class="oneSettingV2-c-1" @click="clearCache">
19 <view class="oneSettingV2-c-1-l">清理缓存</view> 19 <view class="oneSettingV2-c-1-l">清理缓存</view>
20 <view class="oneSettingV2-c-1-r"> 20 <view class="oneSettingV2-c-1-r">
21 <text>{{ cache }}</text> 21 <text>{{ cache }}</text>
22 <u-icon name="arrow-right"></u-icon> 22 <u-icon name="arrow-right"></u-icon>
23 </view> 23 </view>
24 </view> 24 </view>
25 - <view class="oneSettingV2-c-1"> 25 + <view class="oneSettingV2-c-1" @click="checkVersion">
26 <view class="oneSettingV2-c-1-l">检查版本</view> 26 <view class="oneSettingV2-c-1-l">检查版本</view>
27 <view class="oneSettingV2-c-1-r"> 27 <view class="oneSettingV2-c-1-r">
  28 + <text>v{{ version }}</text>
28 <u-icon name="arrow-right"></u-icon> 29 <u-icon name="arrow-right"></u-icon>
29 </view> 30 </view>
30 </view> 31 </view>
@@ -44,15 +45,49 @@ @@ -44,15 +45,49 @@
44 export default { 45 export default {
45 data() { 46 data() {
46 return { 47 return {
  48 + cache: '',
  49 + version: ''
47 } 50 }
48 }, 51 },
49 onLoad(option) { 52 onLoad(option) {
50 // #ifdef APP-PLUS 53 // #ifdef APP-PLUS
51 this.getCache() 54 this.getCache()
  55 + this.getVersion()
52 // #endif 56 // #endif
53 }, 57 },
54 computed: {}, 58 computed: {},
55 methods: { 59 methods: {
  60 + checkVersion() {
  61 + uni.navigateTo({
  62 + url: '/pages/update/update'
  63 + })
  64 + },
  65 + getVersion() {
  66 + plus.runtime.getProperty(plus.runtime.appid, (widgetInfo) => {
  67 + console.log('=========>', widgetInfo.version)
  68 + this.version = widgetInfo.version
  69 + })
  70 + },
  71 + clearCache(){
  72 + let that = this
  73 + uni.showModal({
  74 + title:'提示',
  75 + content:'确定清除缓存吗?',
  76 + success(res) {
  77 + // 用户确定要删除
  78 + if(res.confirm){
  79 + //使用plus.cache.clear 清除应用中的缓存数据 这里清除后还要二十几KB没有清除,达不到全部清除
  80 + plus.cache.clear(() => {
  81 + that.getCache()
  82 + uni.showToast({
  83 + title:'清除成功',
  84 + icon:'none'
  85 + })
  86 + });
  87 + }
  88 + }
  89 + })
  90 + },
56 toRichText(type) { 91 toRichText(type) {
57 uni.navigateTo({ 92 uni.navigateTo({
58 url: '/pagesB/richText/richText?type=' + type 93 url: '/pagesB/richText/richText?type=' + type
@@ -111,6 +146,7 @@ @@ -111,6 +146,7 @@
111 .oneSettingV2-c-1-r{ 146 .oneSettingV2-c-1-r{
112 font-size: 28rpx; 147 font-size: 28rpx;
113 color: #646464; 148 color: #646464;
  149 + display: flex;
114 } 150 }
115 } 151 }
116 } 152 }
@@ -172,6 +172,10 @@ @@ -172,6 +172,10 @@
172 height: 504rpx; 172 height: 504rpx;
173 position: absolute; 173 position: absolute;
174 width: 100%; 174 width: 100%;
  175 + image{
  176 + height: 100%;
  177 + width: 100%;
  178 + }
175 } 179 }
176 .main { 180 .main {
177 width: 100%; 181 width: 100%;
@@ -220,6 +220,10 @@ @@ -220,6 +220,10 @@
220 height: 30rpx; 220 height: 30rpx;
221 margin-right: 10rpx; 221 margin-right: 10rpx;
222 margin-top: 5rpx; 222 margin-top: 5rpx;
  223 + image{
  224 + height: 100%;
  225 + width: 100%;
  226 + }
223 } 227 }
224 textarea { 228 textarea {
225 width: 100%; 229 width: 100%;
1 <template> 1 <template>
2 <view> 2 <view>
3 - <!-- #ifdef MP-WEIXIN -->  
4 <view class="CustomReturn-container" :style="{height: titleHeight, paddingTop: paddingTop, backgroundColor: bgColor}"> 3 <view class="CustomReturn-container" :style="{height: titleHeight, paddingTop: paddingTop, backgroundColor: bgColor}">
5 <view class="CustomReturn"> 4 <view class="CustomReturn">
6 <view v-if="isShowBreak" class="CustomReturn-r"> 5 <view v-if="isShowBreak" class="CustomReturn-r">
@@ -15,13 +14,14 @@ @@ -15,13 +14,14 @@
15 <u-icon name="close-circle-fill" size="20" color="#E6E6E6"></u-icon> 14 <u-icon name="close-circle-fill" size="20" color="#E6E6E6"></u-icon>
16 </view> 15 </view>
17 </view> 16 </view>
  17 + <!-- #ifdef MP-WEIXIN -->
18 <view style="width: 200rpx;"></view> 18 <view style="width: 200rpx;"></view>
  19 + <!-- #endif -->
19 </view> 20 </view>
20 <view class="other"> 21 <view class="other">
21 <slot></slot> 22 <slot></slot>
22 </view> 23 </view>
23 </view> 24 </view>
24 - <!-- #endif -->  
25 </view> 25 </view>
26 26
27 27
@@ -120,10 +120,10 @@ @@ -120,10 +120,10 @@
120 this.paddingTop = uni.getSystemInfoSync().statusBarHeight + 'px' 120 this.paddingTop = uni.getSystemInfoSync().statusBarHeight + 'px'
121 // #ifdef MP-WEIXIN 121 // #ifdef MP-WEIXIN
122 let res = wx.getMenuButtonBoundingClientRect(); 122 let res = wx.getMenuButtonBoundingClientRect();
123 - // #endif  
124 this.paddingTop = res.top + 'px' 123 this.paddingTop = res.top + 'px'
125 this.titleHeight = res.height + 10 + 'px'; 124 this.titleHeight = res.height + 10 + 'px';
126 this.entityHeight = res.top + res.height 125 this.entityHeight = res.top + res.height
  126 + // #endif
127 127
128 }, 128 },
129 toBreak(){ 129 toBreak(){
@@ -169,6 +169,7 @@ @@ -169,6 +169,7 @@
169 169
170 .CustomReturn-title{ 170 .CustomReturn-title{
171 font-size: 36rpx; 171 font-size: 36rpx;
  172 + flex-grow: 1;
172 .CustomReturn-title-c{ 173 .CustomReturn-title-c{
173 background-color: #F6F6F6; 174 background-color: #F6F6F6;
174 border: 1px solid #E6E6E6; 175 border: 1px solid #E6E6E6;
@@ -323,6 +323,10 @@ @@ -323,6 +323,10 @@
323 height: 48rpx; 323 height: 48rpx;
324 width: 48rpx; 324 width: 48rpx;
325 border-radius: 200rpx; 325 border-radius: 200rpx;
  326 + image{
  327 + height: 100%;
  328 + width: 100%;
  329 + }
326 } 330 }
327 .myQuestion-2-i-3-c-1-l-t{ 331 .myQuestion-2-i-3-c-1-l-t{
328 font-size: 26rpx; 332 font-size: 26rpx;
1 <template> 1 <template>
2 <view class="audioPlayback"> 2 <view class="audioPlayback">
3 <view class="audioPlayback-bg"> 3 <view class="audioPlayback-bg">
4 - <image class="audioPlayback-bg-img" src="@/static/images/txz.jpg"></image> 4 + <image class="audioPlayback-bg-img" :src="info.cover"></image>
5 </view> 5 </view>
6 <TopNavigation /> 6 <TopNavigation />
7 <PaddingTopB> 7 <PaddingTopB>
@@ -9,18 +9,18 @@ @@ -9,18 +9,18 @@
9 <view class="audioPlayback-content-1"> 9 <view class="audioPlayback-content-1">
10 <view class="ItemQ"> 10 <view class="ItemQ">
11 <view class="ItemQ-1"> 11 <view class="ItemQ-1">
12 - <image src="@/static/images/txz.jpg"></image> 12 + <image :src="info.cover"></image>
13 </view> 13 </view>
14 - <view class="ItemQ-2">音频</view> 14 + <view class="ItemQ-2">{{ info.name }}</view>
15 </view> 15 </view>
16 </view> 16 </view>
17 <view class="audioPlayback-content-2"> 17 <view class="audioPlayback-content-2">
18 <yz-audio 18 <yz-audio
19 @ended="ended" 19 @ended="ended"
20 :autoplay="true" 20 :autoplay="true"
21 - singer="歌手"  
22 - epname="专辑名称"  
23 - title="歌曲标题" 21 + :singer="info.created_user"
  22 + :epname="info.name"
  23 + :title="info.name"
24 ref="player1"></yz-audio> 24 ref="player1"></yz-audio>
25 </view> 25 </view>
26 </view> 26 </view>
@@ -38,10 +38,32 @@ @@ -38,10 +38,32 @@
38 }, 38 },
39 data() { 39 data() {
40 return { 40 return {
41 - 41 + id: null,
  42 + info: {}
42 }; 43 };
43 }, 44 },
  45 + onLoad({ id }) {
  46 + this.id = id
  47 + this.getData()
  48 + },
  49 + onUnload() {
  50 + console.log('onUnload')
  51 + },
44 methods: { 52 methods: {
  53 + getData() {
  54 + this.$service.P_get('/course/info', { id: this.id }).then(res => {
  55 + console.log(res.data.data)
  56 + this.info = res.data.data
  57 + this.$nextTick(() => {
  58 + // const bgAudioManager = uni.getBackgroundAudioManager();
  59 + // bgAudioManager.title = '致爱丽丝';
  60 + // bgAudioManager.singer = '暂无';
  61 + // bgAudioManager.coverImgUrl = 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/music-a.png';
  62 + // bgAudioManager.src = 'https://edudev.baoshanjiaoyu.com/code.mp3';
  63 + this.$refs.player1.setSrc(this.info.url)
  64 + })
  65 + })
  66 + },
45 ended() { 67 ended() {
46 68
47 } 69 }
1 <template> 1 <template>
2 <view> 2 <view>
3 - <!-- #ifdef MP-WEIXIN -->  
4 <view class="CustomReturn-container" :style="{height: titleHeight, paddingTop: paddingTop, backgroundColor: bgColor}"> 3 <view class="CustomReturn-container" :style="{height: titleHeight, paddingTop: paddingTop, backgroundColor: bgColor}">
5 <view class="CustomReturn"> 4 <view class="CustomReturn">
6 <view v-if="isShowBreak" class="CustomReturn-r"> 5 <view v-if="isShowBreak" class="CustomReturn-r">
@@ -15,7 +14,6 @@ @@ -15,7 +14,6 @@
15 <slot></slot> 14 <slot></slot>
16 </view> 15 </view>
17 </view> 16 </view>
18 - <!-- #endif -->  
19 </view> 17 </view>
20 18
21 19
@@ -110,10 +108,10 @@ @@ -110,10 +108,10 @@
110 this.paddingTop = uni.getSystemInfoSync().statusBarHeight + 'px' 108 this.paddingTop = uni.getSystemInfoSync().statusBarHeight + 'px'
111 // #ifdef MP-WEIXIN 109 // #ifdef MP-WEIXIN
112 let res = wx.getMenuButtonBoundingClientRect(); 110 let res = wx.getMenuButtonBoundingClientRect();
113 - // #endif  
114 this.paddingTop = res.top + 'px' 111 this.paddingTop = res.top + 'px'
115 this.titleHeight = res.height + 10 + 'px'; 112 this.titleHeight = res.height + 10 + 'px';
116 this.entityHeight = res.top + res.height 113 this.entityHeight = res.top + res.height
  114 + // #endif
117 115
118 }, 116 },
119 toBreak(){ 117 toBreak(){
@@ -149,7 +147,7 @@ @@ -149,7 +147,7 @@
149 display: flex; 147 display: flex;
150 align-items: center; 148 align-items: center;
151 flex-grow: 1; 149 flex-grow: 1;
152 - padding: 0 24rpx; 150 + padding: 24rpx 24rpx;
153 justify-content: space-between; 151 justify-content: space-between;
154 position: relative; 152 position: relative;
155 z-index: 1002; 153 z-index: 1002;
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 <view @tap="tabsClick(BIGSHOTS.AUDIOLESSONS)" :class="{'bigShots-1-1-i': true, 'bigShots-1-1-is': type === BIGSHOTS.AUDIOLESSONS}">音频课程</view> 6 <view @tap="tabsClick(BIGSHOTS.AUDIOLESSONS)" :class="{'bigShots-1-1-i': true, 'bigShots-1-1-is': type === BIGSHOTS.AUDIOLESSONS}">音频课程</view>
7 </view> 7 </view>
8 <view class="bigShots-1-2"> 8 <view class="bigShots-1-2">
9 - <picker @change="bindpickerChange" :value="index" :range="subjectList" range-key="title"> 9 + <picker @change="bindpickerChange" :range="subjectList" range-key="title">
10 <view class="bigShots-1-2-i"> 10 <view class="bigShots-1-2-i">
11 <text class="bigShots-1-2-i-t">{{ selectType.name || '请选择分类' }} </text> 11 <text class="bigShots-1-2-i-t">{{ selectType.name || '请选择分类' }} </text>
12 <u-icon size="10" name="arrow-down-fill" color="#646464"></u-icon> 12 <u-icon size="10" name="arrow-down-fill" color="#646464"></u-icon>
@@ -92,6 +92,11 @@ @@ -92,6 +92,11 @@
92 'LIKECOUNT': 'up_count' 92 'LIKECOUNT': 'up_count'
93 } 93 }
94 export default { 94 export default {
  95 + watch: {
  96 + type(newVal) {
  97 + this.onRetry()
  98 + }
  99 + },
95 data() { 100 data() {
96 return { 101 return {
97 SORTINGTYPE, 102 SORTINGTYPE,
@@ -168,7 +173,8 @@ @@ -168,7 +173,8 @@
168 page: this.page, 173 page: this.page,
169 order_field: this.currentSorting, 174 order_field: this.currentSorting,
170 order_sort: this.currentSorting ? this.sortLog[this.currentSorting] : '', 175 order_sort: this.currentSorting ? this.sortLog[this.currentSorting] : '',
171 - cate_id: this.selectType.id || '' 176 + cate_id: this.selectType.id || '',
  177 + type: this.type
172 }).then(res => { 178 }).then(res => {
173 uni.hideLoading(); 179 uni.hideLoading();
174 if (res.code == 1) { 180 if (res.code == 1) {
@@ -198,12 +204,15 @@ @@ -198,12 +204,15 @@
198 this.type = type 204 this.type = type
199 }, 205 },
200 toBigShotsDetails(item) { 206 toBigShotsDetails(item) {
  207 + if(item.type === BIGSHOTS.VIDEOLESSONS) {
201 uni.navigateTo({ 208 uni.navigateTo({
202 url: '/pagesStu/bigShotsDetails/bigShotsDetails?id=' + item.id 209 url: '/pagesStu/bigShotsDetails/bigShotsDetails?id=' + item.id
203 }) 210 })
204 - // uni.navigateTo({  
205 - // url: '/pagesStu/audioFrequency/audioFrequency'  
206 - // }) 211 + } else {
  212 + uni.navigateTo({
  213 + url: '/pagesStu/audioFrequency/audioFrequency?id=' + item.id
  214 + })
  215 + }
207 } 216 }
208 } 217 }
209 } 218 }
@@ -2,45 +2,54 @@ @@ -2,45 +2,54 @@
2 <view class="bigShotsDetails"> 2 <view class="bigShotsDetails">
3 <view class="bigShotsDetails-1"> 3 <view class="bigShotsDetails-1">
4 <qxcplayer class="qxcplayer-style" ref="qxcplayerRef"></qxcplayer> 4 <qxcplayer class="qxcplayer-style" ref="qxcplayerRef"></qxcplayer>
5 - <view class="bigShotsDetails-1-c">视频专辑:行测</view> 5 + <view class="bigShotsDetails-1-c">视频专辑:{{ info.name }}</view>
6 </view> 6 </view>
7 <view class="bigShotsDetails-2"> 7 <view class="bigShotsDetails-2">
8 <view class="bigShotsDetails-2-1"> 8 <view class="bigShotsDetails-2-1">
9 - 共<text style="color: #2D81FF;">20</text>条评价 9 + 共<text style="color: #2D81FF;">{{ info.comment_count }}</text>条评价
10 </view> 10 </view>
11 <view class="bigShotsDetails-2-2"> 11 <view class="bigShotsDetails-2-2">
12 - <view class="bigShotsDetails-2-2-i" v-for="(item, index) in 10" :key="index">  
13 - <image class="bigShotsDetails-2-2-i-l" src="@/static/images/tx.png" mode="widthFix"></image> 12 + <view class="bigShotsDetails-2-2-i" v-for="(item, index) in commitList" :key="item.id">
  13 + <image class="bigShotsDetails-2-2-i-l" v-if="item.answer" :src="item.answer" mode="widthFix"></image>
  14 + <image class="bigShotsDetails-2-2-i-l" v-else src="@/static/images/tx.png" mode="widthFix"></image>
14 <view class="bigShotsDetails-2-2-i-r"> 15 <view class="bigShotsDetails-2-2-i-r">
15 <view class="bigShotsDetails-2-2-i-r-1"> 16 <view class="bigShotsDetails-2-2-i-r-1">
16 - <view class="bigShotsDetails-2-2-i-r-1-l">栾珍</view>  
17 - <view class="bigShotsDetails-2-2-i-r-1-r">2023-12-10</view> 17 + <view class="bigShotsDetails-2-2-i-r-1-l">{{ item.user_name }}</view>
  18 + <view class="bigShotsDetails-2-2-i-r-1-r">{{ item.created_at }}</view>
18 </view> 19 </view>
19 <view class="bigShotsDetails-2-2-i-r-2"> 20 <view class="bigShotsDetails-2-2-i-r-2">
20 - 老师讲的很仔细,可能第一册比较简单吧,没有很多 的语法知识,不过我也学到很多,这就是积累的过程, 谢谢老师 21 + {{ item.comment }}
21 </view> 22 </view>
22 </view> 23 </view>
23 </view> 24 </view>
  25 + <u-empty
  26 + v-if="notData"
  27 + mode="data"
  28 + text="暂无数据"
  29 + icon="/static/imagesV2/icon24.png"
  30 + >
  31 + </u-empty>
24 </view> 32 </view>
25 </view> 33 </view>
26 <view class="bigShotsDetails-3-c"> 34 <view class="bigShotsDetails-3-c">
27 <view class="bigShotsDetails-3"> 35 <view class="bigShotsDetails-3">
28 <view class="bigShotsDetails-3-l"> 36 <view class="bigShotsDetails-3-l">
29 <view class="bigShotsDetails-3-l-1"> 37 <view class="bigShotsDetails-3-l-1">
30 - <input class="bigShotsDetails-3-l-1-in" type="text" placeholder="请输入"/> 38 + <input class="bigShotsDetails-3-l-1-in" v-model="commentText" type="text" placeholder="请输入"/>
31 </view> 39 </view>
32 - <view class="bigShotsDetails-3-l-2"> 40 + <view class="bigShotsDetails-3-l-2" @click="release">
33 发布 41 发布
34 </view> 42 </view>
35 </view> 43 </view>
36 <view class="bigShotsDetails-3-r"> 44 <view class="bigShotsDetails-3-r">
37 <view class="bigShotsDetails-3-r-i"> 45 <view class="bigShotsDetails-3-r-i">
38 <image class="bigShotsDetails-3-r-i-i" src="@/static/imagesV2/icon47.png" mode="widthFix"></image> 46 <image class="bigShotsDetails-3-r-i-i" src="@/static/imagesV2/icon47.png" mode="widthFix"></image>
39 - <text>0</text> 47 + <text>{{ info.comment_count }}</text>
40 </view> 48 </view>
41 - <view class="bigShotsDetails-3-r-i">  
42 - <image class="bigShotsDetails-3-r-i-i" src="@/static/imagesV2/icon48.png" mode="widthFix"></image>  
43 - <text>0</text> 49 + <view class="bigShotsDetails-3-r-i" @click="like">
  50 + <image class="bigShotsDetails-3-r-i-i" v-if="info.is_up" src="@/static/imagesV2/icon69.png" mode="widthFix"></image>
  51 + <image class="bigShotsDetails-3-r-i-i" v-else src="@/static/imagesV2/icon48.png" mode="widthFix"></image>
  52 + <text>{{ info.up_count }}</text>
44 </view> 53 </view>
45 </view> 54 </view>
46 </view> 55 </view>
@@ -55,23 +64,116 @@ @@ -55,23 +64,116 @@
55 components: { 64 components: {
56 qxcplayer 65 qxcplayer
57 }, 66 },
58 - destroyed() { 67 + onUnload() {
59 // 销毁 68 // 销毁
60 this.$refs.qxcplayerRef.destory() 69 this.$refs.qxcplayerRef.destory()
61 }, 70 },
  71 + computed: {
  72 + notData() {
  73 + return this.status === 'nomore' && !this.commitList.length
  74 + }
  75 + },
62 data() { 76 data() {
63 return { 77 return {
  78 + id: null,
  79 + page: 1,
  80 + info: {},
  81 + commitList: [],
  82 + // 加载前值为loadmore,加载中为loading,没有数据为nomore
  83 + status: 'loadmore',
  84 + commentText: ''
64 }; 85 };
65 }, 86 },
  87 + onLoad({ id }) {
  88 + this.id = id
  89 + this.getData()
  90 + this.onRetry()
  91 + },
66 onReachBottom() { 92 onReachBottom() {
67 debugger 93 debugger
68 }, 94 },
69 mounted() { 95 mounted() {
  96 +
  97 + },
  98 + methods: {
  99 + like() {
  100 + this.$service.P_post('/course/up', {
  101 + id: this.id
  102 + }).then(res => {
  103 + if(this.info.is_up){
  104 + this.$set(this.info, 'up_count', this.info.up_count - 1)
  105 + } else {
  106 + this.$set(this.info, 'up_count', this.info.up_count + 1)
  107 + }
  108 + this.$set(this.info, 'is_up', !this.info.is_up)
  109 + })
  110 + },
  111 + release() {
  112 + this.$service.P_post('/course/comment_add', {
  113 + id: this.id,
  114 + comment: this.commentText
  115 + }).then(res => {
  116 + uni.showToast({
  117 + icon: 'none',
  118 + title: '评论成功,审核后可查看'
  119 + })
  120 + })
  121 + },
  122 + onRetry(){
  123 + this.page=1
  124 + this.commitList = []
  125 + this.status = 'loadmore'
  126 + this.getComment()
  127 + },
  128 + getComment() {
  129 + if(this.status === 'loading' || this.status === 'nomore') return;
  130 + this.status = 'loading';
  131 + uni.showLoading({
  132 + title: '加载中',
  133 + mask: true
  134 + })
  135 + this.$service.P_get('/course/comment', {
  136 + page: this.page,
  137 + id: this.id,
  138 +
  139 + }).then((res) => {
  140 + if (res.code == 1) {
  141 + this.page++;
  142 + this.commitList = [
  143 + ...this.commitList,
  144 + ...res.data.data
  145 + ]
  146 + this.status = res.data.data.length < res.data.per_page ? 'nomore' : 'loadmore'
  147 + } else {
  148 + this.status = 'loadmore';
  149 + if (res.msg) {
  150 + uni.showToast({
  151 + icon: 'none',
  152 + title: res.msg
  153 + })
  154 + } else {
  155 + uni.showToast({
  156 + icon: 'none',
  157 + title: '获取数据失败'
  158 + })
  159 + }
  160 + }
  161 + console.log(res)
  162 + })
  163 + },
  164 + getData() {
  165 + this.$service.P_get('/course/info', { id: this.id }).then(res => {
  166 + console.log(res.data.data)
  167 + this.info = res.data.data
  168 + this.$nextTick(() => {
70 this.$refs.qxcplayerRef.initData({ 169 this.$refs.qxcplayerRef.initData({
71 - token: 'fb08f60a1b9b32e4ba80|0|1705377109|3743-4262|6021|e7wDu4613bceC0R25|200|',  
72 - env: 'product', 170 + token: this.info.qxy_token,
  171 + env: 'test',
73 name: 'qxcname', 172 name: 'qxcname',
74 }) 173 })
  174 + })
  175 + })
  176 + }
75 } 177 }
76 } 178 }
77 </script> 179 </script>
@@ -339,6 +339,10 @@ @@ -339,6 +339,10 @@
339 height: 504rpx; 339 height: 504rpx;
340 position: absolute; 340 position: absolute;
341 width: 100%; 341 width: 100%;
  342 + image{
  343 + width: 100%;
  344 + height: 100%;
  345 + }
342 } 346 }
343 347
344 .vio_list{ 348 .vio_list{
@@ -412,6 +416,10 @@ @@ -412,6 +416,10 @@
412 top: 0; 416 top: 0;
413 width: 130rpx; 417 width: 130rpx;
414 height: 40rpx; 418 height: 40rpx;
  419 + image{
  420 + height: 100%;
  421 + width: 100%;
  422 + }
415 } 423 }
416 .rule_msg{ 424 .rule_msg{
417 .xz_room{ 425 .xz_room{
@@ -527,6 +535,10 @@ @@ -527,6 +535,10 @@
527 width: 60rpx; 535 width: 60rpx;
528 height: 60rpx; 536 height: 60rpx;
529 margin-right: 20rpx; 537 margin-right: 20rpx;
  538 + image{
  539 + height: 100%;
  540 + width: 100%;
  541 + }
530 } 542 }
531 .d1{ 543 .d1{
532 font-size: 32rpx; 544 font-size: 32rpx;
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 4
5 </CustomReturn> 5 </CustomReturn>
6 <view class="bg-img"> 6 <view class="bg-img">
7 - <image src="/static/imagesV2/icon18.png" mode="aspectFill"></image> 7 + <image src="/static/imagesV2/icon18.png" mode="widthFix"></image>
8 </view> 8 </view>
9 9
10 <PaddingTopB> 10 <PaddingTopB>
@@ -220,6 +220,10 @@ @@ -220,6 +220,10 @@
220 position: absolute; 220 position: absolute;
221 width: 100%; 221 width: 100%;
222 top: 0; 222 top: 0;
  223 + image{
  224 + height: 100%;
  225 + width: 100%;
  226 + }
223 } 227 }
224 .main { 228 .main {
225 width: 100%; 229 width: 100%;
@@ -241,6 +245,10 @@ @@ -241,6 +245,10 @@
241 .icon { 245 .icon {
242 width: 40rpx; 246 width: 40rpx;
243 height: 40rpx; 247 height: 40rpx;
  248 + image{
  249 + height: 100%;
  250 + width: 100%;
  251 + }
244 } 252 }
245 .title { 253 .title {
246 font-size: 32rpx; 254 font-size: 32rpx;
@@ -259,6 +259,10 @@ @@ -259,6 +259,10 @@
259 .head-bg { 259 .head-bg {
260 width: 100%; 260 width: 100%;
261 height: 100%; 261 height: 100%;
  262 + image{
  263 + height: 100%;
  264 + width: 100%;
  265 + }
262 } 266 }
263 &-box { 267 &-box {
264 position: absolute; 268 position: absolute;
  1 +'use strict';
  2 +// const crypto = require('crypto')
  3 +exports.main = async (event, context) => {
  4 + //event为客户端上传的参数
  5 + const res = await uniCloud.getPhoneNumber({
  6 + appid: '__UNI__8740A53', // 替换成自己开通一键登录的应用的DCloud appid,使用callFunction方式调用时可以不传(会自动取当前客户端的appid),如果使用云函数URL化的方式访问必须传此参数
  7 + provider: 'univerify',
  8 + access_token: event.queryStringParameters.access_token,
  9 + openid: event.queryStringParameters.openid
  10 + })
  11 + // 执行用户信息入库等操作,正常情况下不要把完整手机号返回给前端
  12 + // 如果数据库在uniCloud上,可以直接入库
  13 + // 如果数据库不在uniCloud上,可以通过 uniCloud.httpclient API,将手机号通过http方式传递给其他服务器的接口,详见:https://uniapp.dcloud.net.cn/uniCloud/cf-functions?id=httpclient
  14 + //返回数据给客户端
  15 + return {
  16 + code: 0,
  17 + message: '获取手机号成功',
  18 + data: res
  19 + }
  20 +}
  21 +
  1 +{
  2 + "name": "getPhoneNumber",
  3 + "dependencies": {},
  4 + "extensions": {
  5 + "uni-cloud-jql": {},
  6 + "uni-cloud-verify": {}
  7 + }
  8 +}
  1 +// 本文件用于,使用JQL语法操作项目关联的uniCloud空间的数据库,方便开发调试和远程数据库管理
  2 +// 编写clientDB的js API(也支持常规js语法,比如var),可以对云数据库进行增删改查操作。不支持uniCloud-db组件写法
  3 +// 可以全部运行,也可以选中部分代码运行。点击工具栏上的运行按钮或者按下【F5】键运行代码
  4 +// 如果文档中存在多条JQL语句,只有最后一条语句生效
  5 +// 如果混写了普通js,最后一条语句需是数据库操作语句
  6 +// 此处代码运行不受DB Schema的权限控制,移植代码到实际业务中注意在schema中配好permission
  7 +// 不支持clientDB的action
  8 +// 数据库查询有最大返回条数限制,详见:https://uniapp.dcloud.net.cn/uniCloud/cf-database.html#limit
  9 +// 详细JQL语法,请参考:https://uniapp.dcloud.net.cn/uniCloud/jql.html
  10 +
  11 +// 下面示例查询uni-id-users表的所有数据
  12 +db.collection('uni-id-users').get();
  1 +## 0.0.3(2022-11-11)
  2 +- 修复 config 方法获取根节点为数组格式配置时错误的转化为了对象的Bug
  3 +## 0.0.2(2021-04-16)
  4 +- 修改插件package信息
  5 +## 0.0.1(2021-03-15)
  6 +- 初始化项目
  1 +{
  2 + "id": "uni-config-center",
  3 + "displayName": "uni-config-center",
  4 + "version": "0.0.3",
  5 + "description": "uniCloud 配置中心",
  6 + "keywords": [
  7 + "配置",
  8 + "配置中心"
  9 +],
  10 + "repository": "",
  11 + "engines": {
  12 + "HBuilderX": "^3.1.0"
  13 + },
  14 +"dcloudext": {
  15 + "sale": {
  16 + "regular": {
  17 + "price": "0.00"
  18 + },
  19 + "sourcecode": {
  20 + "price": "0.00"
  21 + }
  22 + },
  23 + "contact": {
  24 + "qq": ""
  25 + },
  26 + "declaration": {
  27 + "ads": "无",
  28 + "data": "无",
  29 + "permissions": "无"
  30 + },
  31 + "npmurl": "",
  32 + "type": "unicloud-template-function"
  33 + },
  34 + "directories": {
  35 + "example": "../../../scripts/dist"
  36 + },
  37 + "uni_modules": {
  38 + "dependencies": [],
  39 + "encrypt": [],
  40 + "platforms": {
  41 + "cloud": {
  42 + "tcb": "y",
  43 + "aliyun": "y"
  44 + },
  45 + "client": {
  46 + "App": {
  47 + "app-vue": "u",
  48 + "app-nvue": "u"
  49 + },
  50 + "H5-mobile": {
  51 + "Safari": "u",
  52 + "Android Browser": "u",
  53 + "微信浏览器(Android)": "u",
  54 + "QQ浏览器(Android)": "u"
  55 + },
  56 + "H5-pc": {
  57 + "Chrome": "u",
  58 + "IE": "u",
  59 + "Edge": "u",
  60 + "Firefox": "u",
  61 + "Safari": "u"
  62 + },
  63 + "小程序": {
  64 + "微信": "u",
  65 + "阿里": "u",
  66 + "百度": "u",
  67 + "字节跳动": "u",
  68 + "QQ": "u"
  69 + },
  70 + "快应用": {
  71 + "华为": "u",
  72 + "联盟": "u"
  73 + },
  74 + "Vue": {
  75 + "vue2": "y",
  76 + "vue3": "u"
  77 + }
  78 + }
  79 + }
  80 + }
  81 +}
  1 +# 为什么使用uni-config-center
  2 +
  3 +实际开发中很多插件需要配置文件才可以正常运行,如果每个插件都单独进行配置的话就会产生下面这样的目录结构
  4 +
  5 +```bash
  6 +cloudfunctions
  7 +└─────common 公共模块
  8 + ├─plugin-a // 插件A对应的目录
  9 + │ ├─index.js
  10 + │ ├─config.json // plugin-a对应的配置文件
  11 + │ └─other-file.cert // plugin-a依赖的其他文件
  12 + └─plugin-b // plugin-b对应的目录
  13 + ├─index.js
  14 + └─config.json // plugin-b对应的配置文件
  15 +```
  16 +
  17 +假设插件作者要发布一个项目模板,里面使用了很多需要配置的插件,无论是作者发布还是用户使用都是一个大麻烦。
  18 +
  19 +uni-config-center就是用了统一管理这些配置文件的,使用uni-config-center后的目录结构如下
  20 +
  21 +```bash
  22 +cloudfunctions
  23 +└─────common 公共模块
  24 + ├─plugin-a // 插件A对应的目录
  25 + │ └─index.js
  26 + ├─plugin-b // plugin-b对应的目录
  27 + │ └─index.js
  28 + └─uni-config-center
  29 + ├─index.js // config-center入口文件
  30 + ├─plugin-a
  31 + │ ├─config.json // plugin-a对应的配置文件
  32 + │ └─other-file.cert // plugin-a依赖的其他文件
  33 + └─plugin-b
  34 + └─config.json // plugin-b对应的配置文件
  35 +```
  36 +
  37 +使用uni-config-center后的优势
  38 +
  39 +- 配置文件统一管理,分离插件主体和配置信息,更新插件更方便
  40 +- 支持对config.json设置schema,插件使用者在HBuilderX内编写config.json文件时会有更好的提示(后续HBuilderX会提供支持)
  41 +
  42 +# 用法
  43 +
  44 +在要使用uni-config-center的公共模块或云函数内引入uni-config-center依赖,请参考:[使用公共模块](https://uniapp.dcloud.net.cn/uniCloud/cf-common)
  45 +
  46 +```js
  47 +const createConfig = require('uni-config-center')
  48 +
  49 +const uniIdConfig = createConfig({
  50 + pluginId: 'uni-id', // 插件id
  51 + defaultConfig: { // 默认配置
  52 + tokenExpiresIn: 7200,
  53 + tokenExpiresThreshold: 600,
  54 + },
  55 + customMerge: function(defaultConfig, userConfig) { // 自定义默认配置和用户配置的合并规则,不设置的情况侠会对默认配置和用户配置进行深度合并
  56 + // defaudltConfig 默认配置
  57 + // userConfig 用户配置
  58 + return Object.assign(defaultConfig, userConfig)
  59 + }
  60 +})
  61 +
  62 +
  63 +// 以如下配置为例
  64 +// {
  65 +// "tokenExpiresIn": 7200,
  66 +// "passwordErrorLimit": 6,
  67 +// "bindTokenToDevice": false,
  68 +// "passwordErrorRetryTime": 3600,
  69 +// "app-plus": {
  70 +// "tokenExpiresIn": 2592000
  71 +// },
  72 +// "service": {
  73 +// "sms": {
  74 +// "codeExpiresIn": 300
  75 +// }
  76 +// }
  77 +// }
  78 +
  79 +// 获取配置
  80 +uniIdConfig.config() // 获取全部配置,注意:uni-config-center内不存在对应插件目录时会返回空对象
  81 +uniIdConfig.config('tokenExpiresIn') // 指定键值获取配置,返回:7200
  82 +uniIdConfig.config('service.sms.codeExpiresIn') // 指定键值获取配置,返回:300
  83 +uniIdConfig.config('tokenExpiresThreshold', 600) // 指定键值获取配置,如果不存在则取传入的默认值,返回:600
  84 +
  85 +// 获取文件绝对路径
  86 +uniIdConfig.resolve('custom-token.js') // 获取uni-config-center/uni-id/custom-token.js文件的路径
  87 +
  88 +// 引用文件(require)
  89 +uniIDConfig.requireFile('custom-token.js') // 使用require方式引用uni-config-center/uni-id/custom-token.js文件。文件不存在时返回undefined,文件内有其他错误导致require失败时会抛出错误。
  90 +
  91 +// 判断是否包含某文件
  92 +uniIDConfig.hasFile('custom-token.js') // 配置目录是否包含某文件,true: 文件存在,false: 文件不存在
  93 +```
  1 +"use strict";var t=require("fs"),r=require("path");function e(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var n=e(t),o=e(r),i="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var u=function(t){var r={exports:{}};return t(r,r.exports),r.exports}((function(t,r){var e="__lodash_hash_undefined__",n=9007199254740991,o="[object Arguments]",u="[object Function]",c="[object Object]",a=/^\[object .+?Constructor\]$/,f=/^(?:0|[1-9]\d*)$/,s={};s["[object Float32Array]"]=s["[object Float64Array]"]=s["[object Int8Array]"]=s["[object Int16Array]"]=s["[object Int32Array]"]=s["[object Uint8Array]"]=s["[object Uint8ClampedArray]"]=s["[object Uint16Array]"]=s["[object Uint32Array]"]=!0,s[o]=s["[object Array]"]=s["[object ArrayBuffer]"]=s["[object Boolean]"]=s["[object DataView]"]=s["[object Date]"]=s["[object Error]"]=s[u]=s["[object Map]"]=s["[object Number]"]=s[c]=s["[object RegExp]"]=s["[object Set]"]=s["[object String]"]=s["[object WeakMap]"]=!1;var l="object"==typeof i&&i&&i.Object===Object&&i,h="object"==typeof self&&self&&self.Object===Object&&self,p=l||h||Function("return this")(),_=r&&!r.nodeType&&r,v=_&&t&&!t.nodeType&&t,d=v&&v.exports===_,y=d&&l.process,g=function(){try{var t=v&&v.require&&v.require("util").types;return t||y&&y.binding&&y.binding("util")}catch(t){}}(),b=g&&g.isTypedArray;function j(t,r,e){switch(e.length){case 0:return t.call(r);case 1:return t.call(r,e[0]);case 2:return t.call(r,e[0],e[1]);case 3:return t.call(r,e[0],e[1],e[2])}return t.apply(r,e)}var w,O,m,A=Array.prototype,z=Function.prototype,M=Object.prototype,x=p["__core-js_shared__"],C=z.toString,F=M.hasOwnProperty,U=(w=/[^.]+$/.exec(x&&x.keys&&x.keys.IE_PROTO||""))?"Symbol(src)_1."+w:"",S=M.toString,I=C.call(Object),P=RegExp("^"+C.call(F).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),T=d?p.Buffer:void 0,q=p.Symbol,E=p.Uint8Array,$=T?T.allocUnsafe:void 0,D=(O=Object.getPrototypeOf,m=Object,function(t){return O(m(t))}),k=Object.create,B=M.propertyIsEnumerable,N=A.splice,L=q?q.toStringTag:void 0,R=function(){try{var t=vt(Object,"defineProperty");return t({},"",{}),t}catch(t){}}(),G=T?T.isBuffer:void 0,V=Math.max,W=Date.now,H=vt(p,"Map"),J=vt(Object,"create"),K=function(){function t(){}return function(r){if(!xt(r))return{};if(k)return k(r);t.prototype=r;var e=new t;return t.prototype=void 0,e}}();function Q(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r<e;){var n=t[r];this.set(n[0],n[1])}}function X(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r<e;){var n=t[r];this.set(n[0],n[1])}}function Y(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r<e;){var n=t[r];this.set(n[0],n[1])}}function Z(t){var r=this.__data__=new X(t);this.size=r.size}function tt(t,r){var e=Ot(t),n=!e&&wt(t),o=!e&&!n&&At(t),i=!e&&!n&&!o&&Ft(t),u=e||n||o||i,c=u?function(t,r){for(var e=-1,n=Array(t);++e<t;)n[e]=r(e);return n}(t.length,String):[],a=c.length;for(var f in t)!r&&!F.call(t,f)||u&&("length"==f||o&&("offset"==f||"parent"==f)||i&&("buffer"==f||"byteLength"==f||"byteOffset"==f)||dt(f,a))||c.push(f);return c}function rt(t,r,e){(void 0!==e&&!jt(t[r],e)||void 0===e&&!(r in t))&&ot(t,r,e)}function et(t,r,e){var n=t[r];F.call(t,r)&&jt(n,e)&&(void 0!==e||r in t)||ot(t,r,e)}function nt(t,r){for(var e=t.length;e--;)if(jt(t[e][0],r))return e;return-1}function ot(t,r,e){"__proto__"==r&&R?R(t,r,{configurable:!0,enumerable:!0,value:e,writable:!0}):t[r]=e}Q.prototype.clear=function(){this.__data__=J?J(null):{},this.size=0},Q.prototype.delete=function(t){var r=this.has(t)&&delete this.__data__[t];return this.size-=r?1:0,r},Q.prototype.get=function(t){var r=this.__data__;if(J){var n=r[t];return n===e?void 0:n}return F.call(r,t)?r[t]:void 0},Q.prototype.has=function(t){var r=this.__data__;return J?void 0!==r[t]:F.call(r,t)},Q.prototype.set=function(t,r){var n=this.__data__;return this.size+=this.has(t)?0:1,n[t]=J&&void 0===r?e:r,this},X.prototype.clear=function(){this.__data__=[],this.size=0},X.prototype.delete=function(t){var r=this.__data__,e=nt(r,t);return!(e<0)&&(e==r.length-1?r.pop():N.call(r,e,1),--this.size,!0)},X.prototype.get=function(t){var r=this.__data__,e=nt(r,t);return e<0?void 0:r[e][1]},X.prototype.has=function(t){return nt(this.__data__,t)>-1},X.prototype.set=function(t,r){var e=this.__data__,n=nt(e,t);return n<0?(++this.size,e.push([t,r])):e[n][1]=r,this},Y.prototype.clear=function(){this.size=0,this.__data__={hash:new Q,map:new(H||X),string:new Q}},Y.prototype.delete=function(t){var r=_t(this,t).delete(t);return this.size-=r?1:0,r},Y.prototype.get=function(t){return _t(this,t).get(t)},Y.prototype.has=function(t){return _t(this,t).has(t)},Y.prototype.set=function(t,r){var e=_t(this,t),n=e.size;return e.set(t,r),this.size+=e.size==n?0:1,this},Z.prototype.clear=function(){this.__data__=new X,this.size=0},Z.prototype.delete=function(t){var r=this.__data__,e=r.delete(t);return this.size=r.size,e},Z.prototype.get=function(t){return this.__data__.get(t)},Z.prototype.has=function(t){return this.__data__.has(t)},Z.prototype.set=function(t,r){var e=this.__data__;if(e instanceof X){var n=e.__data__;if(!H||n.length<199)return n.push([t,r]),this.size=++e.size,this;e=this.__data__=new Y(n)}return e.set(t,r),this.size=e.size,this};var it,ut=function(t,r,e){for(var n=-1,o=Object(t),i=e(t),u=i.length;u--;){var c=i[it?u:++n];if(!1===r(o[c],c,o))break}return t};function ct(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":L&&L in Object(t)?function(t){var r=F.call(t,L),e=t[L];try{t[L]=void 0;var n=!0}catch(t){}var o=S.call(t);n&&(r?t[L]=e:delete t[L]);return o}(t):function(t){return S.call(t)}(t)}function at(t){return Ct(t)&&ct(t)==o}function ft(t){return!(!xt(t)||function(t){return!!U&&U in t}(t))&&(zt(t)?P:a).test(function(t){if(null!=t){try{return C.call(t)}catch(t){}try{return t+""}catch(t){}}return""}(t))}function st(t){if(!xt(t))return function(t){var r=[];if(null!=t)for(var e in Object(t))r.push(e);return r}(t);var r=yt(t),e=[];for(var n in t)("constructor"!=n||!r&&F.call(t,n))&&e.push(n);return e}function lt(t,r,e,n,o){t!==r&&ut(r,(function(i,u){if(o||(o=new Z),xt(i))!function(t,r,e,n,o,i,u){var a=gt(t,e),f=gt(r,e),s=u.get(f);if(s)return void rt(t,e,s);var l=i?i(a,f,e+"",t,r,u):void 0,h=void 0===l;if(h){var p=Ot(f),_=!p&&At(f),v=!p&&!_&&Ft(f);l=f,p||_||v?Ot(a)?l=a:Ct(j=a)&&mt(j)?l=function(t,r){var e=-1,n=t.length;r||(r=Array(n));for(;++e<n;)r[e]=t[e];return r}(a):_?(h=!1,l=function(t,r){if(r)return t.slice();var e=t.length,n=$?$(e):new t.constructor(e);return t.copy(n),n}(f,!0)):v?(h=!1,d=f,y=!0?(g=d.buffer,b=new g.constructor(g.byteLength),new E(b).set(new E(g)),b):d.buffer,l=new d.constructor(y,d.byteOffset,d.length)):l=[]:function(t){if(!Ct(t)||ct(t)!=c)return!1;var r=D(t);if(null===r)return!0;var e=F.call(r,"constructor")&&r.constructor;return"function"==typeof e&&e instanceof e&&C.call(e)==I}(f)||wt(f)?(l=a,wt(a)?l=function(t){return function(t,r,e,n){var o=!e;e||(e={});var i=-1,u=r.length;for(;++i<u;){var c=r[i],a=n?n(e[c],t[c],c,e,t):void 0;void 0===a&&(a=t[c]),o?ot(e,c,a):et(e,c,a)}return e}(t,Ut(t))}(a):xt(a)&&!zt(a)||(l=function(t){return"function"!=typeof t.constructor||yt(t)?{}:K(D(t))}(f))):h=!1}var d,y,g,b;var j;h&&(u.set(f,l),o(l,f,n,i,u),u.delete(f));rt(t,e,l)}(t,r,u,e,lt,n,o);else{var a=n?n(gt(t,u),i,u+"",t,r,o):void 0;void 0===a&&(a=i),rt(t,u,a)}}),Ut)}function ht(t,r){return bt(function(t,r,e){return r=V(void 0===r?t.length-1:r,0),function(){for(var n=arguments,o=-1,i=V(n.length-r,0),u=Array(i);++o<i;)u[o]=n[r+o];o=-1;for(var c=Array(r+1);++o<r;)c[o]=n[o];return c[r]=e(u),j(t,this,c)}}(t,r,Pt),t+"")}var pt=R?function(t,r){return R(t,"toString",{configurable:!0,enumerable:!1,value:(e=r,function(){return e}),writable:!0});var e}:Pt;function _t(t,r){var e,n,o=t.__data__;return("string"==(n=typeof(e=r))||"number"==n||"symbol"==n||"boolean"==n?"__proto__"!==e:null===e)?o["string"==typeof r?"string":"hash"]:o.map}function vt(t,r){var e=function(t,r){return null==t?void 0:t[r]}(t,r);return ft(e)?e:void 0}function dt(t,r){var e=typeof t;return!!(r=null==r?n:r)&&("number"==e||"symbol"!=e&&f.test(t))&&t>-1&&t%1==0&&t<r}function yt(t){var r=t&&t.constructor;return t===("function"==typeof r&&r.prototype||M)}function gt(t,r){if(("constructor"!==r||"function"!=typeof t[r])&&"__proto__"!=r)return t[r]}var bt=function(t){var r=0,e=0;return function(){var n=W(),o=16-(n-e);if(e=n,o>0){if(++r>=800)return arguments[0]}else r=0;return t.apply(void 0,arguments)}}(pt);function jt(t,r){return t===r||t!=t&&r!=r}var wt=at(function(){return arguments}())?at:function(t){return Ct(t)&&F.call(t,"callee")&&!B.call(t,"callee")},Ot=Array.isArray;function mt(t){return null!=t&&Mt(t.length)&&!zt(t)}var At=G||function(){return!1};function zt(t){if(!xt(t))return!1;var r=ct(t);return r==u||"[object GeneratorFunction]"==r||"[object AsyncFunction]"==r||"[object Proxy]"==r}function Mt(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=n}function xt(t){var r=typeof t;return null!=t&&("object"==r||"function"==r)}function Ct(t){return null!=t&&"object"==typeof t}var Ft=b?function(t){return function(r){return t(r)}}(b):function(t){return Ct(t)&&Mt(t.length)&&!!s[ct(t)]};function Ut(t){return mt(t)?tt(t,!0):st(t)}var St,It=(St=function(t,r,e){lt(t,r,e)},ht((function(t,r){var e=-1,n=r.length,o=n>1?r[n-1]:void 0,i=n>2?r[2]:void 0;for(o=St.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,r,e){if(!xt(e))return!1;var n=typeof r;return!!("number"==n?mt(e)&&dt(r,e.length):"string"==n&&r in e)&&jt(e[r],t)}(r[0],r[1],i)&&(o=n<3?void 0:o,n=1),t=Object(t);++e<n;){var u=r[e];u&&St(t,u,e,o)}return t})));function Pt(t){return t}t.exports=It}));const c=Object.prototype.hasOwnProperty,a=(t,r)=>c.call(t,r);class f{constructor({pluginId:t,defaultConfig:r={},customMerge:e,root:n}){this.pluginId=t,this.defaultConfig=r,this.pluginConfigPath=o.default.resolve(n||__dirname,t),this.customMerge=e,this._config=void 0}resolve(t){return o.default.resolve(this.pluginConfigPath,t)}hasFile(t){return n.default.existsSync(this.resolve(t))}requireFile(t){try{return require(this.resolve(t))}catch(t){if("MODULE_NOT_FOUND"===t.code)return;throw t}}_getUserConfig(){return this.requireFile("config.json")}config(t,r){if(!this._config){const t=this._getUserConfig();this._config=Array.isArray(t)?t:(this.customMerge||u)(this.defaultConfig,t)}let e=this._config;return t?function(t,r,e){if("number"==typeof r)return t[r];if("symbol"==typeof r)return a(t,r)?t[r]:e;const n="string"!=typeof(o=r)?o:o.split(".").reduce(((t,r)=>(r.split(/\[([^}]+)\]/g).forEach((r=>r&&t.push(r))),t)),[]);var o;let i=t;for(let t=0;t<n.length;t++){const r=n[t];if(!a(i,r))return e;i=i[r]}return i}(e,t,r):e}}const s=new class{constructor(){this._configMap=new Map}plugin({pluginId:t,defaultConfig:r,customMerge:e,root:n=__dirname,cache:o=!0}){if(this._configMap.has(t)&&o)return this._configMap.get(t);const i=new f({pluginId:t,defaultConfig:r,customMerge:e,root:n});return o&&this._configMap.set(t,i),i}};var l=s.plugin.bind(s);module.exports=l;
  1 +{
  2 + "name": "uni-config-center",
  3 + "version": "0.0.3",
  4 + "description": "配置中心",
  5 + "main": "index.js",
  6 + "keywords": [],
  7 + "author": "DCloud",
  8 + "license": "Apache-2.0"
  9 +}
  1 +## 1.0.16(2023-04-25)
  2 +- 新增maxTokenLength配置,用于限制数据库用户记录token数组的最大长度
  3 +## 1.0.15(2023-04-06)
  4 +- 修复部分语言国际化出错的Bug
  5 +## 1.0.14(2023-03-07)
  6 +- 修复 admin用户包含其他角色时未包含在token的Bug
  7 +## 1.0.13(2022-07-21)
  8 +- 修复 创建token时未传角色权限信息生成的token不正确的bug
  9 +## 1.0.12(2022-07-15)
  10 +- 提升与旧版本uni-id的兼容性(补充读取配置文件时回退平台app-plus、h5),但是仍推荐使用新平台名进行配置(app、web)
  11 +## 1.0.11(2022-07-14)
  12 +- 修复 部分情况下报`read property 'reduce' of undefined`的错误
  13 +## 1.0.10(2022-07-11)
  14 +- 将token存储在用户表的token字段内,与旧版本uni-id保持一致
  15 +## 1.0.9(2022-07-01)
  16 +- checkToken兼容token内未缓存角色权限的情况,此时将查库获取角色权限
  17 +## 1.0.8(2022-07-01)
  18 +- 修复clientDB默认依赖时部分情况下获取不到uni-id配置的Bug
  19 +## 1.0.7(2022-06-30)
  20 +- 修复config文件不合法时未抛出具体错误的Bug
  21 +## 1.0.6(2022-06-28)
  22 +- 移除插件内的数据表schema
  23 +## 1.0.5(2022-06-27)
  24 +- 修复使用多应用配置时报`Cannot read property 'appId' of undefined`的Bug
  25 +## 1.0.4(2022-06-27)
  26 +- 修复使用自定义token内容功能报错的Bug [详情](https://ask.dcloud.net.cn/question/147945)
  27 +## 1.0.2(2022-06-23)
  28 +- 对齐旧版本uni-id默认配置
  29 +## 1.0.1(2022-06-22)
  30 +- 补充对uni-config-center的依赖
  31 +## 1.0.0(2022-06-21)
  32 +- 提供uni-id token创建、校验、刷新接口,简化旧版uni-id公共模块
  1 +{
  2 + "id": "uni-id-common",
  3 + "displayName": "uni-id-common",
  4 + "version": "1.0.16",
  5 + "description": "包含uni-id token生成、校验、刷新功能的云函数公共模块",
  6 + "keywords": [
  7 + "uni-id-common",
  8 + "uniCloud",
  9 + "token",
  10 + "权限"
  11 + ],
  12 + "repository": "https://gitcode.net/dcloud/uni-id-common",
  13 + "engines": {
  14 + "HBuilderX": "^3.1.0"
  15 + },
  16 + "dcloudext": {
  17 + "sale": {
  18 + "regular": {
  19 + "price": "0.00"
  20 + },
  21 + "sourcecode": {
  22 + "price": "0.00"
  23 + }
  24 + },
  25 + "contact": {
  26 + "qq": ""
  27 + },
  28 + "declaration": {
  29 + "ads": "无",
  30 + "data": "无",
  31 + "permissions": "无"
  32 + },
  33 + "npmurl": "",
  34 + "type": "unicloud-template-function"
  35 + },
  36 + "uni_modules": {
  37 + "dependencies": ["uni-config-center"],
  38 + "encrypt": [],
  39 + "platforms": {
  40 + "cloud": {
  41 + "tcb": "y",
  42 + "aliyun": "y"
  43 + },
  44 + "client": {
  45 + "Vue": {
  46 + "vue2": "u",
  47 + "vue3": "u"
  48 + },
  49 + "App": {
  50 + "app-vue": "u",
  51 + "app-nvue": "u"
  52 + },
  53 + "H5-mobile": {
  54 + "Safari": "u",
  55 + "Android Browser": "u",
  56 + "微信浏览器(Android)": "u",
  57 + "QQ浏览器(Android)": "u"
  58 + },
  59 + "H5-pc": {
  60 + "Chrome": "u",
  61 + "IE": "u",
  62 + "Edge": "u",
  63 + "Firefox": "u",
  64 + "Safari": "u"
  65 + },
  66 + "小程序": {
  67 + "微信": "u",
  68 + "阿里": "u",
  69 + "百度": "u",
  70 + "字节跳动": "u",
  71 + "QQ": "u",
  72 + "钉钉": "u",
  73 + "快手": "u",
  74 + "飞书": "u",
  75 + "京东": "u"
  76 + },
  77 + "快应用": {
  78 + "华为": "u",
  79 + "联盟": "u"
  80 + }
  81 + }
  82 + }
  83 + }
  84 +}
  1 +# uni-id-common
  2 +
  3 +文档请参考:[uni-id-common](https://uniapp.dcloud.net.cn/uniCloud/uni-id-common.html)
  1 +"use strict";var e,t=(e=require("crypto"))&&"object"==typeof e&&"default"in e?e.default:e;const n={TOKEN_EXPIRED:"uni-id-token-expired",CHECK_TOKEN_FAILED:"uni-id-check-token-failed",PARAM_REQUIRED:"uni-id-param-required",ACCOUNT_EXISTS:"uni-id-account-exists",ACCOUNT_NOT_EXISTS:"uni-id-account-not-exists",ACCOUNT_CONFLICT:"uni-id-account-conflict",ACCOUNT_BANNED:"uni-id-account-banned",ACCOUNT_AUDITING:"uni-id-account-auditing",ACCOUNT_AUDIT_FAILED:"uni-id-account-audit-failed",ACCOUNT_CLOSED:"uni-id-account-closed"};function i(e){return!!e&&("object"==typeof e||"function"==typeof e)&&"function"==typeof e.then}function r(e){if(!e)return;const t=e.match(/^(\d+).(\d+).(\d+)/);return t?t.slice(1,4).map(e=>parseInt(e)):void 0}function o(e,t){const n=r(e),i=r(t);return n?i?function(e,t){const n=Math.max(e.length,t.length);for(let i=0;i<n;i++){const n=e[i],r=t[i];if(n>r)return 1;if(n<r)return-1}return 0}(n,i):1:i?-1:0}const s={"uni-id-token-expired":30203,"uni-id-check-token-failed":30202};function c(e){const{errCode:t,errMsgValue:n}=e;e.errMsg=this._t(t,n),t in s&&(e.code=s[t]),delete e.errMsgValue}function a(e){return"object"===(i=e,Object.prototype.toString.call(i).slice(8,-1).toLowerCase())&&e.errCode&&(t=e.errCode,Object.values(n).includes(t))&&!!e.errCode;var t,i}let u={"zh-Hans":{"uni-id-token-expired":"登录状态失效,token已过期","uni-id-check-token-failed":"token校验未通过","uni-id-param-required":"缺少参数: {param}","uni-id-account-exists":"此账号已注册","uni-id-account-not-exists":"此账号未注册","uni-id-account-conflict":"用户账号冲突","uni-id-account-banned":"从账号已封禁","uni-id-account-auditing":"此账号正在审核中","uni-id-account-audit-failed":"此账号审核失败","uni-id-account-closed":"此账号已注销"},en:{"uni-id-token-expired":"The login status is invalid, token has expired","uni-id-check-token-failed":"Check token failed","uni-id-param-required":"Parameter required: {param}","uni-id-account-exists":"Account exists","uni-id-account-not-exists":"Account does not exists","uni-id-account-conflict":"User account conflict","uni-id-account-banned":"Account has been banned","uni-id-account-auditing":"Account audit in progress","uni-id-account-audit-failed":"Account audit failed","uni-id-account-closed":"Account has been closed"}};try{const e=require.resolve("uni-config-center/uni-id/lang/index.js");u=function(e,t){const n=Object.keys(e);n.push(...Object.keys(t));const i={};for(let r=0;r<n.length;r++){const o=n[r];i[o]=Object.assign({},e[o],t[o])}return i}(u,require(e))}catch(e){}var d=u;function l(e){return e.replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}function h(e){return JSON.parse((t=function(e){var t=4-(e=e.toString()).length%4;if(4!==t)for(var n=0;n<t;++n)e+="=";return e.replace(/-/g,"+").replace(/_/g,"/")}(e),Buffer.from(t,"base64").toString("utf-8")));var t}function f(e){return l((t=JSON.stringify(e),Buffer.from(t,"utf-8").toString("base64")));var t}function p(e,n){return l(t.createHmac("sha256",n).update(e).digest("base64"))}const k=function(e,t){if("string"!=typeof e)throw new Error("Invalid token");const n=e.split(".");if(3!==n.length)throw new Error("Invalid token");const[i,r,o]=n;if(p(i+"."+r,t)!==o)throw new Error("Invalid token");const s=h(i);if("HS256"!==s.alg||"JWT"!==s.typ)throw new Error("Invalid token");const c=h(r);if(1e3*c.exp<Date.now()){const e=new Error("Token expired");throw e.name="TokenExpiredError",e}return c},g=function(e,t,n={}){const{expiresIn:i}=n;if(!i)throw new Error("expiresIn is required");const r=parseInt(Date.now()/1e3),o={...e,iat:r,exp:r+n.expiresIn},s=f({alg:"HS256",typ:"JWT"})+"."+f(o);return s+"."+p(s,t)},I=uniCloud.database(),_=I.command,C=I.collection("uni-id-users"),T=I.collection("uni-id-roles");class m{constructor({uniId:e}={}){this.uid=null,this.userRecord=null,this.userPermission=null,this.oldToken=null,this.oldTokenPayload=null,this.uniId=e,this.config=this.uniId._getConfig(),this.clientInfo=this.uniId._clientInfo,this.checkConfig()}checkConfig(){const{tokenExpiresIn:e,tokenExpiresThreshold:t}=this.config;if(t>=e)throw new Error("Config error, tokenExpiresThreshold should be less than tokenExpiresIn");t>e/2&&console.warn(`Please check whether the tokenExpiresThreshold configuration is set too large, tokenExpiresThreshold: ${t}, tokenExpiresIn: ${e}`)}get customToken(){return this.uniId.interceptorMap.get("customToken")}isTokenInDb(e){return o(e,"1.0.10")>=0}async getUserRecord(){if(this.userRecord)return this.userRecord;const e=await C.doc(this.uid).get();if(this.userRecord=e.data[0],!this.userRecord)throw{errCode:n.ACCOUNT_NOT_EXISTS};switch(this.userRecord.status){case void 0:case 0:break;case 1:throw{errCode:n.ACCOUNT_BANNED};case 2:throw{errCode:n.ACCOUNT_AUDITING};case 3:throw{errCode:n.ACCOUNT_AUDIT_FAILED};case 4:throw{errCode:n.ACCOUNT_CLOSED}}if(this.oldTokenPayload){if(this.isTokenInDb(this.oldTokenPayload.uniIdVersion)){if(-1===(this.userRecord.token||[]).indexOf(this.oldToken))throw{errCode:n.CHECK_TOKEN_FAILED}}if(this.userRecord.valid_token_date&&this.userRecord.valid_token_date>1e3*this.oldTokenPayload.iat)throw{errCode:n.TOKEN_EXPIRED}}return this.userRecord}async updateUserRecord(e){await C.doc(this.uid).update(e)}async getUserPermission(){if(this.userPermission)return this.userPermission;const e=(await this.getUserRecord()).role||[];if(0===e.length)return this.userPermission={role:[],permission:[]},this.userPermission;if(e.includes("admin"))return this.userPermission={role:e,permission:[]},this.userPermission;const t=await T.where({role_id:_.in(e)}).get(),n=(i=t.data.reduce((e,t)=>(t.permission&&e.push(...t.permission),e),[]),Array.from(new Set(i)));var i;return this.userPermission={role:e,permission:n},this.userPermission}async _createToken({uid:e,role:t,permission:i}={}){if(!t||!i){const e=await this.getUserPermission();t=e.role,i=e.permission}let r={uid:e,role:t,permission:i};if(this.uniId.interceptorMap.has("customToken")){const n=this.uniId.interceptorMap.get("customToken");if("function"!=typeof n)throw new Error("Invalid custom token file");r=await n({uid:e,role:t,permission:i})}const o=Date.now(),{tokenSecret:s,tokenExpiresIn:c,maxTokenLength:a=10}=this.config,u=g({...r,uniIdVersion:"1.0.16"},s,{expiresIn:c}),d=await this.getUserRecord(),l=(d.token||[]).filter(e=>{try{const t=this._checkToken(e);if(d.valid_token_date&&d.valid_token_date>1e3*t.iat)return!1}catch(e){if(e.errCode===n.TOKEN_EXPIRED)return!1}return!0});return l.push(u),l.length>a&&l.splice(0,l.length-a),await this.updateUserRecord({last_login_ip:this.clientInfo.clientIP,last_login_date:o,token:l}),{token:u,tokenExpired:o+1e3*c}}async createToken({uid:e,role:t,permission:i}={}){if(!e)throw{errCode:n.PARAM_REQUIRED,errMsgValue:{param:"uid"}};this.uid=e;const{token:r,tokenExpired:o}=await this._createToken({uid:e,role:t,permission:i});return{errCode:0,token:r,tokenExpired:o}}async refreshToken({token:e}={}){if(!e)throw{errCode:n.PARAM_REQUIRED,errMsgValue:{param:"token"}};this.oldToken=e;const t=this._checkToken(e);this.uid=t.uid,this.oldTokenPayload=t;const{uid:i}=t,{role:r,permission:o}=await this.getUserPermission(),{token:s,tokenExpired:c}=await this._createToken({uid:i,role:r,permission:o});return{errCode:0,token:s,tokenExpired:c}}_checkToken(e){const{tokenSecret:t}=this.config;let i;try{i=k(e,t)}catch(e){if("TokenExpiredError"===e.name)throw{errCode:n.TOKEN_EXPIRED};throw{errCode:n.CHECK_TOKEN_FAILED}}return i}async checkToken(e,{autoRefresh:t=!0}={}){if(!e)throw{errCode:n.PARAM_REQUIRED,errMsgValue:{param:"token"}};this.oldToken=e;const i=this._checkToken(e);this.uid=i.uid,this.oldTokenPayload=i;const{tokenExpiresThreshold:r}=this.config,{uid:o,role:s,permission:c}=i,a={role:s,permission:c};if(!s&&!c){const{role:e,permission:t}=await this.getUserPermission();a.role=e,a.permission=t}if(!r||!t){const e={code:0,errCode:0,...i,...a};return delete e.uniIdVersion,e}const u=Date.now();let d={};1e3*i.exp-u<1e3*r&&(d=await this._createToken({uid:o}));const l={code:0,errCode:0,...i,...a,...d};return delete l.uniIdVersion,l}}var E=Object.freeze({__proto__:null,checkToken:async function(e,{autoRefresh:t=!0}={}){return new m({uniId:this}).checkToken(e,{autoRefresh:t})},createToken:async function({uid:e,role:t,permission:n}={}){return new m({uniId:this}).createToken({uid:e,role:t,permission:n})},refreshToken:async function({token:e}={}){return new m({uniId:this}).refreshToken({token:e})}});const w=require("uni-config-center")({pluginId:"uni-id"});class x{constructor({context:e,clientInfo:t,config:n}={}){this._clientInfo=e?function(e){return{appId:e.APPID,platform:e.PLATFORM,locale:e.LOCALE,clientIP:e.CLIENTIP,deviceId:e.DEVICEID}}(e):t,this.config=n||this._getOriginConfig(),this.interceptorMap=new Map,w.hasFile("custom-token.js")&&this.setInterceptor("customToken",require(w.resolve("custom-token.js")));this._i18n=uniCloud.initI18n({locale:this._clientInfo.locale,fallbackLocale:"zh-Hans",messages:JSON.parse(JSON.stringify(d))}),d[this._i18n.locale]||this._i18n.setLocale("zh-Hans")}setInterceptor(e,t){this.interceptorMap.set(e,t)}_t(...e){return this._i18n.t(...e)}_parseOriginConfig(e){return Array.isArray(e)?e:e[0]?Object.values(e):e}_getOriginConfig(){if(w.hasFile("config.json")){let e;try{e=w.config()}catch(e){throw new Error("Invalid uni-id config file\n"+e.message)}return this._parseOriginConfig(e)}try{return this._parseOriginConfig(require("uni-id/config.json"))}catch(e){throw new Error("Invalid uni-id config file")}}_getAppConfig(){const e=this._getOriginConfig();return Array.isArray(e)?e.find(e=>e.dcloudAppid===this._clientInfo.appId)||e.find(e=>e.isDefaultConfig):e}_getPlatformConfig(){const e=this._getAppConfig();if(!e)throw new Error(`Config for current app (${this._clientInfo.appId}) was not found, please check your config file or client appId`);let t;switch("app-plus"===this._clientInfo.platform&&(this._clientInfo.platform="app"),"h5"===this._clientInfo.platform&&(this._clientInfo.platform="web"),this._clientInfo.platform){case"web":t="h5";break;case"app":t="app-plus"}const n=[{tokenExpiresIn:7200,tokenExpiresThreshold:1200,passwordErrorLimit:6,passwordErrorRetryTime:3600},e];t&&e[t]&&n.push(e[t]),n.push(e[this._clientInfo.platform]);const i=Object.assign(...n);return["tokenSecret","tokenExpiresIn"].forEach(e=>{if(!i||!i[e])throw new Error(`Config parameter missing, ${e} is required`)}),i}_getConfig(){return this._getPlatformConfig()}}for(const e in E)x.prototype[e]=E[e];function y(e){const t=new x(e);return new Proxy(t,{get(e,t){if(t in e&&0!==t.indexOf("_")){if("function"==typeof e[t])return(n=e[t],function(){let e;try{e=n.apply(this,arguments)}catch(e){if(a(e))return c.call(this,e),e;throw e}return i(e)?e.then(e=>(a(e)&&c.call(this,e),e),e=>{if(a(e))return c.call(this,e),e;throw e}):(a(e)&&c.call(this,e),e)}).bind(e);if("context"!==t&&"config"!==t)return e[t]}var n}})}x.prototype.createInstance=y;const A={createInstance:y};module.exports=A;
  1 +{
  2 + "name": "uni-id-common",
  3 + "version": "1.0.16",
  4 + "description": "uni-id token生成、校验、刷新",
  5 + "main": "index.js",
  6 + "homepage": "https://uniapp.dcloud.io/uniCloud/uni-id-common.html",
  7 + "repository": {
  8 + "type": "git",
  9 + "url": "git+https://gitee.com/dcloud/uni-id-common.git"
  10 + },
  11 + "author": "DCloud",
  12 + "license": "Apache-2.0",
  13 + "dependencies": {
  14 + "uni-config-center": "file:../../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
  15 + }
  16 +}