Browse Source

商学院

xiaohaizhao 1 year ago
parent
commit
8f41483c68

+ 5 - 1
components/My_listbox.vue

@@ -1,5 +1,5 @@
 <template>
-    <view class="container">
+    <view class="container" :style="{ background: boxBackground }">
         <view id="mylisttop" />
         <scroll-view class="scroll-view" scroll-y :refresher-enabled='pullDown' :refresher-triggered='inRefresh'
             :style="{ height: height + 'px' }" :triggered='true' @refresherrefresh='pullToRefresh'
@@ -41,6 +41,10 @@ export default {
         occupyHeight: {
             type: Number,
             default: 50
+        },
+        boxBackground: {
+            type: String,
+            default: ""
         }
     },
     data() {

+ 8 - 3
components/appList.vue

@@ -1,7 +1,7 @@
 <template>
     <view class="box">
         <navigator class="nav-box" v-for="item in appList" :key="item.name" :url="item.path" hover-class="navigator-hover">
-            <image v-if="item.cover" class="image" :src="item.cover" mode="aspectFit" lazy-load="false" />
+            <image v-if="item.cover" class="image" :src="item.cover" mode="aspectFill" lazy-load="false" />
             <text v-else>{{ item.remark }}</text>
         </navigator>
     </view>
@@ -18,8 +18,13 @@ export default {
             appList: []
         }
     }, mounted() {
-        this.appList = this.getApps(this.model)
-        console.log(this.model, this.appList)
+        try {
+            this.appList = this.getApps(this.model)
+            console.log(this.model, this.appList)
+        } catch (error) {
+            console.log("未获取到授权信息")
+        }
+
     }
 }
 </script>

+ 402 - 0
components/my-audio.vue

@@ -0,0 +1,402 @@
+<template>
+	<view class="audio_container">
+		<view class="title-box">
+			{{ title }}
+		</view>
+		<view>
+			<slider :backgroundColor='backgroundColor' :activeColor='activeColor' @change="handleSliderChange"
+				:value="sliderIndex" :max="maxSliderIndex" block-color="#C30D23" block-size="16" />
+		</view>
+		<view style="padding: 0px 7.5px 0px 7.5px ; display: block; ">
+			<view style="float: left; font-size: 10px;color:#848484;">
+				{{ currentTimeText }}
+			</view>
+			<view style="float: right;font-size: 10px;color:#848484;">
+				{{ totalTimeText }}
+			</view>
+		</view>
+		<view style="margin-top: 35px;">
+			<view class="control">
+				<view class="uni-grid-icon">
+					<image @tap="handleFastRewind" src="../static/images/get-back.svg"
+						style="width: 24px;height: 24px;top:3px;">
+					</image>
+				</view>
+				<view class="uni-grid-icon">
+					<image @tap="handleChangeAudioState" v-show="!isPlaying" src="../static/images/play.svg"
+						style="width: 24px;height: 24px;top:3px;">
+					</image>
+					<image @tap="handleChangeAudioState" v-show="isPlaying" src="../static/images/pause.svg"
+						style="width: 24px;height: 24px;top:3px;">
+					</image>
+				</view>
+				<view class="uni-grid-icon">
+					<image @tap="handleFastForward" src="../static/images/fast-forward.svg"
+						style="width: 24px;height: 24px;top:3px;">
+					</image>
+				</view>
+				<!-- <view class="uni-grid-icon">
+					<image @tap="handleLoopPlay" src="../static/images/Loop.svg"
+						style="width: 24px;height: 24px; top:3px; ">
+					</image>
+				</view> -->
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+export default {
+	name: 'my-audio',
+	//audioPlay开始播放
+	//audioPause停止播放
+	//audioEnd音频自然播放结束事件
+	//audioCanplay音频进入可以播放状态,但不保证后面可以流畅播放
+	//change播放状态改变 返回值false停止播放 true开始播放
+	//audioError 播放器错误
+	emits: ['audioPlay', 'audioPause', 'audioEnd', 'audioCanplay', 'change', 'audioError'],
+	props: {
+		title: {
+			type: String
+		},
+		//是否自动播放
+		autoplay: {
+			type: Boolean,
+			default: false
+		},
+		//滑块左侧已选择部分的线条颜色
+		activeColor: {
+			type: String,
+			default: '#C30D23'
+		},
+		//滑块右侧背景条的颜色
+		backgroundColor: {
+			type: String,
+			default: '#E5E5E5'
+		},
+		//音频地址
+		src: {
+			type: [String, Array],
+			default: ''
+		},
+		//是否倒计时
+		isCountDown: {
+			type: Boolean,
+			default: false
+		},
+		//音乐封面
+		audioCover: {
+			type: String,
+			default: ''
+		},
+		//是否显示收藏按钮
+		isCollectBtn: {
+			type: Boolean,
+			default: false
+		},
+		//是否显示分享按钮
+		isShareBtn: {
+			type: Boolean,
+			default: false
+		},
+	},
+	data() {
+		return {
+			totalTimeText: '00:00', //视频总长度文字
+			currentTimeText: '00:00:00', //视频已播放长度文字
+
+			isPlaying: false, //播放状态
+
+			sliderIndex: 0, //滑块当前值
+			maxSliderIndex: 100, //滑块最大值
+
+			IsReadyPlay: false, //是否已经准备好可以播放了
+
+			isLoop: false, //是否循环播放
+
+			speedValue: [0.5, 0.8, 1.0, 1.25, 1.5, 2.0],
+			speedValueIndex: 2,
+			playSpeed: '1.0', //播放倍速 可取值:0.5/0.8/1.0/1.25/1.5/2.0
+
+			stringObject: (data) => {
+				return typeof (data)
+			},
+			innerAudioContext: uni.createInnerAudioContext()
+		}
+	},
+	async mounted() {
+		this.innerAudioContext.src = typeof (this.src) == 'string' ? this.src : this.src[0];
+		if (this.autoplay) {
+			if (!this.src) return console.error('src cannot be empty,The target value is string or array')
+
+			// #ifdef H5
+			var ua = window.navigator.userAgent.toLowerCase();
+			if (ua.match(/MicroMessenger/i) == 'micromessenger') {
+				const jweixin = require('../utils/jweixin');
+
+				jweixin.config({});
+				jweixin.ready(() => {
+					WeixinJSBridge.invoke('getNetworkType', {}, (e) => {
+						this.innerAudioContext.play();
+
+					})
+				})
+			}
+			// #endif
+
+			// #ifndef H5
+			this.innerAudioContext.autoplay = true;
+			// #endif
+		}
+
+		//音频播放事件
+		this.innerAudioContext.onPlay(() => {
+			this.isPlaying = true;
+			this.$emit('audioPlay')
+
+			this.$emit('change', {
+				state: true
+			});
+
+			setTimeout(() => {
+				this.maxSliderIndex = parseFloat(this.innerAudioContext.duration).toFixed(2);
+
+			}, 100)
+		});
+
+		//音频暂停事件
+		this.innerAudioContext.onPause(() => {
+			this.$emit('audioPause');
+			this.$emit('change', {
+				state: false
+			});
+		});
+
+		//音频自然播放结束事件
+		this.innerAudioContext.onEnded(() => {
+			this.isPlaying = !this.isPlaying;
+			this.$emit('audioEnd');
+
+			if (this.isLoop) {
+				this.changePlayProgress(0);
+				this.innerAudioContext.play();
+			}
+		});
+
+		//音频进入可以播放状态,但不保证后面可以流畅播放
+		this.innerAudioContext.onCanplay((event) => {
+
+			this.IsReadyPlay = true;
+
+			this.$emit('audioCanplay');
+
+			let duration = this.innerAudioContext.duration;
+
+			//console.log('总时长', duration)
+
+			//将当前音频长度秒转换为00:00:00格式
+			this.totalTimeText = this.getFormateTime(duration);
+			this.maxSliderIndex = parseFloat(duration).toFixed(2);
+
+			//console.log(this.getFormateTime(duration))
+
+			//console.log('总时长1', this.totalTimeText)
+
+			//防止视频无法正确获取时长
+			setTimeout(() => {
+				duration = this.innerAudioContext.duration;
+
+				//将当前音频长度秒转换为00:00:00格式
+				this.totalTimeText = this.getFormateTime(duration);
+				this.maxSliderIndex = parseFloat(duration).toFixed(2);
+
+				//console.log('总时长2', this.totalTimeText)
+			}, 300)
+
+		});
+
+		//音频播放错误事件
+		this.innerAudioContext.onTimeUpdate((res) => {
+			this.sliderIndex = parseFloat(this.innerAudioContext.currentTime).toFixed(2);
+			this.currentTimeText = this.getFormateTime(this.innerAudioContext.currentTime);
+		});
+
+		//音频播放错误事件
+		this.innerAudioContext.onError((res) => {
+			console.log(res.errMsg);
+			console.log(res.errCode);
+			this.$emit('change', {
+				state: false
+			});
+			this.audioPause();
+
+			this.$emit('audioError', res);
+		});
+
+	},
+	methods: {
+		//销毁innerAudioContext()实例
+		audioDestroy() {
+			if (this.innerAudioContext) {
+				this.innerAudioContext.destroy();
+				this.isPlaying = false;
+			}
+		},
+		//点击变更播放状态
+		handleChangeAudioState() {
+			if (this.isPlaying && !this.innerAudioContext.paused) {
+				this.audioPause();
+			} else {
+				this.audioPlay();
+			}
+		},
+		//开始播放
+		audioPlay() {
+			this.innerAudioContext.play();
+			this.isPlaying = true;
+		},
+		//暂停播放
+		audioPause() {
+			this.innerAudioContext.pause();
+			this.isPlaying = false;
+		},
+		//变更滑块位置
+		handleSliderChange(e) {
+			this.changePlayProgress(e.detail ? e.detail.value : e)
+		},
+		//更改播放倍速
+		handleChageSpeed() {
+			//获取播放倍速列表长度
+			let speedCount = this.speedValue.length;
+			//如果当前是最大倍速,从-1开始
+			if (this.speedValueIndex == (speedCount - 1)) {
+				this.speedValueIndex = -1;
+			}
+			//最新倍速序号
+			this.speedValueIndex += 1;
+			//获取最新倍速文字
+			this.playSpeed = this.speedValue[this.speedValueIndex].toFixed(1);
+			//暂停播放
+			this.audioPause();
+			//变更播放倍速
+			this.innerAudioContext.playbackRate(this.speedValue[this.speedValueIndex]);
+			//开始播放
+			this.audioPlay();
+		},
+		//快退15秒
+		handleFastRewind() {
+			if (this.IsReadyPlay) {
+				let value = parseInt(this.sliderIndex) - 15;
+				this.changePlayProgress(value >= 0 ? value : 0);
+			}
+		},
+		//快进15秒
+		handleFastForward() {
+			if (this.IsReadyPlay) {
+				let value = parseInt(this.sliderIndex) + 15;
+				this.changePlayProgress(value <= this.innerAudioContext.duration ? value : this.innerAudioContext
+					.duration);
+			}
+		},
+		//开启循环播放
+		handleLoopPlay() {
+			this.isLoop = !this.isLoop;
+			if (this.isLoop) {
+				uni.showToast({
+					title: '已开启循环播放',
+					duration: 1000
+				});
+			} else {
+				uni.showToast({
+					title: '取消循环播放',
+					duration: 1000
+				});
+			}
+		},
+		//更改播放进度
+		changePlayProgress(value) {
+			this.innerAudioContext.seek(value);
+			this.sliderIndex = value;
+			this.currentTimeText = this.getFormateTime(value);
+		},
+		//秒转换为00:00:00
+		getFormateTime(time) {
+			let ms = time * 1000; // 1485000毫秒
+			let date = new Date(ms);
+
+			// 注意这里是使用的getUTCHours()方法,转换成UTC(协调世界时)时间的小时
+			let hour = date.getUTCHours();
+			// let hour = date.getHours(); 如果直接使用getHours()方法,则得到的时分秒格式会多出来8个小时(在国内开发基本都是使用的是东八区时间),getHours()方法会把当前的时区给加上。
+			let minute = date.getMinutes();
+			let second = date.getSeconds();
+
+			let formatTime =
+				`${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}:${second.toString().padStart(2, '0')}`;
+
+			return formatTime;
+		},
+		handleCollec() {
+			this.$emit('audioCollec');
+		},
+		handleShare() {
+			this.$emit('audioShare');
+		},
+	},
+	onUnload() {
+		this.audioDestroy()
+	},
+	onHide() {
+		this.audioDestroy()
+	},
+	beforeDestroy() {
+		this.audioDestroy()
+	}
+}
+</script>
+
+<style lang="scss" scoped>
+.control {
+	display: flex;
+	justify-content: space-around;
+	padding: 0 30px;
+	box-sizing: border-box;
+}
+
+.audio_container {
+	box-shadow: 0 0 5px #c3c3c3;
+	padding: 15px 10px 15px 10px;
+
+	.audio-title {
+		font-size: 14px;
+	}
+
+	.uni-noticebar {
+		padding: 0px;
+		padding-right: 25px;
+		margin-bottom: 0px;
+		display: inline-block;
+	}
+
+
+	.audio-subTitle {
+		width: 100%;
+		text-align: left;
+		font-size: 20px;
+		color: blue;
+	}
+
+	.speed-text {
+		position: absolute;
+		top: 0px;
+		left: 15px;
+		right: 0;
+		color: #475266;
+		font-size: 8px;
+		font-weight: 600;
+	}
+
+	.uni-grid-icon {
+		text-align: center;
+	}
+
+}
+</style>

+ 176 - 0
packageA/course/detail.vue

@@ -0,0 +1,176 @@
+<template>
+    <view>
+        <view class="head">
+            <block v-if="detail.filetype == '视频'">
+                <video id="myVideo" class="video" :src="files[0].showUrl" />
+                <view class="video-bottom">
+                    倍数
+                    <view @click="changeSpeed(item)" v-for="item in speeds" :key="item" class="speed"
+                        :class="speed == item ? 'active' : ''" hover-class="navigator-hover">
+                        {{ item }}x
+                    </view>
+                </view>
+            </block>
+            <block v-else-if="detail.filetype == '图文'">
+                <scroll-view class="scroll" scroll-y>
+                    <u-parse :content="detail.content" />
+                </scroll-view>
+            </block>
+            <block v-else-if="detail.filetype == '音频'">
+                <my-audio :src="files[0].url" :title="files[0].document" />
+            </block>
+        </view>
+        <My_listbox v-if="showListbox" :pullDown="false" boxBackground="#fff">
+            <view class="introduce">
+                <view class="detail-title">详情</view>
+                <view class="group">
+                    <view class="title">课件名称</view>
+                    <view class="value">{{ detail.title || ' --' }}</view>
+                </view>
+                <view class="group">
+                    <view class="title">讲师</view>
+                    <view class="value">{{ detail.teacher || ' --' }}</view>
+                </view>
+                <view class="group">
+                    <view class="title">简介</view>
+                    <view class="value">{{ detail.description || ' --' }}</view>
+                </view>
+            </view>
+        </My_listbox>
+    </view>
+</template>
+
+<script>
+import myAudio from "../../components/my-audio.vue"
+export default {
+    components: { myAudio },
+    data() {
+        return {
+            sat_coursewaredetailid: 0,
+            detail: {},
+            files: [],
+            showListbox: false,
+            speed: '1.0',
+            speeds: ['0.5', '1.0', '1.5', '2.0']
+        }
+    },
+    onLoad(options) {
+        console.log(options)
+        this.sat_coursewaredetailid = options.id;
+        this.getDetail()
+    },
+    methods: {
+        getDetail() {
+            this.$Http.basic({
+                "id": 20240315131502,
+                "content": {
+                    "sat_coursewaredetailid": this.sat_coursewaredetailid
+                }
+            }).then(res => {
+                console.log("获取课件详情", res)
+                if (this.cutoff(res.msg)) return;
+                this.files = res.data.attinfos.filter(v => {
+                    if (v.usetype == "file") switch (res.data.filetype) {
+                        case '视频':
+                            v.showUrl = this.getSpecifiedImage(v, 'hls')
+                            break;
+                    }
+                    return v.usetype == "file"
+                });
+                this.detail = res.data;
+                setTimeout(() => { this.showListbox = true }, 100)
+            })
+        },
+        //修改视频播放倍数
+        changeSpeed(speed) {
+            if (!this.videoContext) this.videoContext = uni.createVideoContext('myVideo');
+            this.videoContext.playbackRate(speed - 0)
+            this.speed = speed;
+        }
+    }
+}
+</script>
+
+<style lang="scss">
+.head {
+    width: 100vw;
+    background: #fff;
+    margin-bottom: 10px;
+
+    .video {
+        width: 375px;
+        height: 230px;
+    }
+
+    .video-bottom {
+        display: flex;
+        align-items: center;
+        justify-content: space-around;
+        width: 375px;
+        height: 62px;
+        background: #FFFFFF;
+        box-sizing: border-box;
+
+        .speed {
+            width: 71px;
+            height: 32px;
+            text-align: center;
+            line-height: 32px;
+            background: #F2F2F2;
+            border-radius: 5px;
+            font-family: PingFang SC, PingFang SC;
+            font-size: 14px;
+            color: #333333;
+        }
+
+        .active {
+            color: #FFFFFF;
+            background: #C30D23;
+        }
+    }
+
+    .scroll {
+        width: 100vw;
+        height: 400px;
+        background: #fff;
+    }
+
+    .audio-box {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        height: 100px;
+    }
+
+}
+
+.introduce {
+    padding: 10px;
+
+    .detail-title {
+        height: 35px;
+        background: #FFFFFF;
+        padding-top: 2px;
+        font-family: PingFang SC, PingFang SC;
+        font-weight: bold;
+        font-size: 16px;
+        color: #333333;
+    }
+
+    .group {
+        margin-bottom: 20px;
+        font-family: Source Han Sans SC, Source Han Sans SC;
+        font-size: 14px;
+        line-height: 20px;
+
+        .title {
+            color: #666666;
+        }
+
+        .value {
+            color: #000000;
+            margin-top: 10px;
+        }
+    }
+}
+</style>

+ 140 - 0
packageA/course/index.vue

@@ -0,0 +1,140 @@
+<template>
+    <view>
+        <view style="height: 10px;">
+
+        </view>
+        <My_listbox ref="List" @getlist="getList" boxBackground="#fff">
+            <view class="list-box">
+                <navigator class="item" v-for="item in list" :key="item.sat_coursewareid"
+                    :url="'/packageA/course/list?id=' + item.sat_coursewareid">
+                    <image class="image" :src="item.cover" mode="aspectFill" lazy-load="true" />
+                    <view class="text">
+                        <view class="title u-line-1">{{ item.title || '--' }}</view>
+                        <view class="teacher u-line-1">讲师:{{ item.teacher || '--' }}</view>
+                        <view class="count u-line-1">共{{ item.courseware_count || 0 }}个课件 | {{ item.study_count || 0 }}人已学习
+                        </view>
+                    </view>
+                </navigator>
+            </view>
+        </My_listbox>
+    </view>
+</template>
+
+<script>
+export default {
+    data() {
+        return {
+            crumbs: [],
+            types: [],
+            list: [],
+            "content": {
+                "where": {
+                    "condition": "",
+                    "sat_courseware_classids": [[]]
+                }
+            }
+        }
+    },
+    onLoad(options) {
+        this.crumbs = [{
+            classname: "商学院"
+        }, {
+            classname: options.classname,
+            parentid: options.id
+        }, {
+            classname: "全部",
+            parentid: ''
+        },]
+        this.getType()
+        this.getList(true)
+    },
+    methods: {
+        getType() {
+            this.$Http.basic({
+                "id": "20221102143302",
+                content: {
+                    pageSize: 9999,
+                    parentid: this.crumbs[1].parentid,
+                    "where": {
+                        "isenable": 1
+                    }
+                }
+            }).then(res => {
+                console.log("获取二级列表", res)
+                if (this.cutoff(res.msg)) return;
+                this.types = res.pageNumber == 1 ? res.data : this.types.concat(res.data);
+            })
+        },
+        getList(init = false) {
+            if (this.paging(this.content, init)) return;
+            this.content.where.sat_courseware_classids = [
+                [
+                    this.crumbs[1].parentid,
+                    this.crumbs[2].parentid,
+                ].filter(v => v)
+            ]
+            this.$Http.basic({
+                "id": 20240318101802,
+                content: this.content
+            }).then(res => {
+                this.$refs.List.RefreshToComplete()
+                console.log("获取课程列表", res)
+                if (this.cutoff(res.msg)) return;
+                this.list = res.pageNumber == 1 ? res.data : this.list.concat(res.data);
+                this.content = this.$refs.List.paging(this.content, res)
+            })
+        },
+    }
+}
+</script>
+
+<style lang="scss">
+.list-box {
+    padding: 10px;
+    width: 100vw;
+    box-sizing: border-box;
+
+    .item {
+        display: flex;
+        width: 100%;
+        border-radius: 5px;
+        overflow: hidden;
+        margin-top: 10px;
+
+        .image {
+            width: 120px;
+            height: 74px;
+            margin-right: 10px;
+            border-radius: 5px;
+            flex-shrink: 0;
+        }
+
+        .text {
+            flex: 1;
+            font-family: Source Han Sans SC, Source Han Sans SC;
+
+            .title {
+                font-weight: bold;
+                font-size: 16px;
+                color: #000000;
+                line-height: 24px;
+            }
+
+            .teacher {
+                font-size: 14px;
+                color: #999999;
+                line-height: 20px;
+                margin-top: 4px;
+            }
+
+            .count {
+                font-size: 12px;
+                color: #666666;
+                line-height: 17px;
+                margin-top: 8px;
+            }
+        }
+
+    }
+}
+</style>

+ 254 - 0
packageA/course/list.vue

@@ -0,0 +1,254 @@
+<template>
+    <view>
+        <view class="cover">
+            <image class="image" :src="detail.cover || ''" mode="aspectFill" />
+        </view>
+        <view class="head">
+            <view class="title">{{ detail.title || '--' }}</view>
+            <view class="text">
+                <view class="teacher">讲师:{{ detail.teacher || ' --' }}</view>
+                <view class="count">共{{ detail.courseware_count || 0 }}个课件 | {{ detail.study_count || 1 }}人已学习</view>
+            </view>
+        </view>
+        <view style="height: 10px;" />
+        <view class="tabs">
+            <view class="tab-item" :class="tabsActive == '目录' ? 'active' : ''" @click="tabsActive = '目录'">
+                目录
+            </view>
+            <view class="tab-item" :class="tabsActive == '介绍' ? 'active' : ''" @click="tabsActive = '介绍'">
+                介绍
+            </view>
+        </view>
+        <My_listbox v-show="tabsActive == '目录'" ref="List" @getlist="getList" boxBackground="#fff">
+            <view class="catalog">
+                <navigator class="item" :url="'/packageA/course/detail?id=' + item.sat_coursewaredetailid"
+                    v-for="item in list" :key="item.sat_coursewaredetailid">
+                    <view class="cover">
+                        <view class="u-icon" v-if="item.filetype == '视频' || item.filetype == '音频'">
+                            <u-icon name="play-right-fill" color="#FFFFFF" size="30" />
+                        </view>
+                        <image class="image" :src="item.cover" mode="aspectFill" lazy-load="true" />
+                    </view>
+                    <view class="title u-line-2">
+                        {{ item.title || '--' }}
+                    </view>
+                </navigator>
+            </view>
+        </My_listbox>
+
+        <My_listbox v-if="tabsActive == '介绍'" :pullDown="false" boxBackground="#fff">
+            <view class="introduce">
+                <view class="title">
+                    课程介绍
+                </view>
+                <view class="description">
+                    {{ detail.description || '--' }}
+                </view>
+            </view>
+        </My_listbox>
+    </view>
+</template>
+
+<script>
+export default {
+    data() {
+        return {
+            tabsActive: "目录",
+            list: [],
+            detail: {},
+            "content": {
+                "sat_coursewareid": 0,
+                "where": {
+                    "condition": "",
+                    "status": ""
+                }
+            }
+        }
+    },
+    onLoad(options) {
+        this.content.sat_coursewareid = options.id;
+        this.getList(true)
+        this.$Http.basic({
+            "id": 20240314134002,
+            "content": {
+                "sat_coursewareid": options.id
+            }
+        }).then(res => {
+            console.log("获取课程详情", res)
+            if (this.cutoff(res.msg)) return;
+            res.data.cover = this.getSpecifiedImage(res.data.attinfos[0] || {})
+            this.detail = res.data;
+        })
+    },
+    methods: {
+        getList(init = false) {
+            if (this.paging(this.content, init)) return;
+            this.$Http.basic({
+                "id": 20240315131602,
+                content: this.content
+            }).then(res => {
+                this.$refs.List.RefreshToComplete()
+                console.log("获取课件列表", res)
+                if (this.cutoff(res.msg)) return;
+                res.data = res.data.map(v => {
+                    v.cover = v.attinfos.length ? this.getSpecifiedImage(v.attinfos.find(s => s.usetype == "avatar") || v.attinfos[0]) : ''
+                    return v
+                })
+                this.list = res.pageNumber == 1 ? res.data : this.list.concat(res.data);
+                this.content = this.$refs.List.paging(this.content, res)
+            })
+        }
+    }
+}
+</script>
+
+<style lang="scss">
+.cover {
+    width: 375px;
+    height: 229px;
+    background: #FFFFFF;
+    box-sizing: border-box;
+    overflow: hidden;
+
+    .image {
+        width: 375px;
+        height: 229px;
+    }
+}
+
+.head {
+    padding: 10px;
+    box-sizing: border-box;
+    background: #fff;
+
+    .title {
+        line-height: 24px;
+        font-family: Source Han Sans SC, Source Han Sans SC;
+        font-weight: bold;
+        font-size: 16px;
+        color: #000000;
+    }
+
+    .text {
+        display: flex;
+        justify-content: space-between;
+        align-items: flex-end;
+        font-family: Source Han Sans SC, Source Han Sans SC;
+        margin-top: 10px;
+
+        .teacher {
+            font-size: 14px;
+            color: #999999;
+        }
+
+        .count {
+            font-size: 12px;
+            color: #666666;
+        }
+    }
+}
+
+.tabs {
+    display: flex;
+    align-items: center;
+    justify-content: space-around;
+    box-sizing: border-box;
+    padding: 0 20px;
+    width: 375px;
+    height: 50px;
+    background: #FFFFFF;
+
+    .tab-item {
+        line-height: 20px;
+        font-family: Source Han Sans SC, Source Han Sans SC;
+        font-size: 14px;
+        color: #333333;
+        padding: 10px;
+        border-radius: 8px;
+    }
+
+    .active {
+        position: relative;
+        font-weight: bold;
+        color: #C30D23;
+    }
+
+    .active::after {
+        position: absolute;
+        content: "";
+        width: 14px;
+        height: 3px;
+        background: #C30D23;
+        border-radius: 5px;
+        bottom: 0;
+        left: 50%;
+        margin-left: -7px;
+    }
+
+
+}
+
+.catalog {
+    padding: 10px;
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: space-between;
+
+    .item {
+        flex-shrink: 0;
+        margin-bottom: 10px;
+        border-radius: 5px;
+
+        .cover {
+            position: relative;
+            width: 173px;
+            height: 106px;
+            border-radius: 5px;
+            overflow: hidden;
+
+            .u-icon {
+                position: absolute;
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                width: 100%;
+                height: 100%;
+                z-index: 9999999;
+                opacity: .9;
+            }
+
+            .image {
+                width: 100%;
+                height: 100%;
+            }
+        }
+
+        .title {
+            height: 34px;
+            font-size: 12px;
+            color: #333333;
+            line-height: 17px;
+            margin-top: 10px;
+            width: 173px;
+        }
+    }
+}
+
+.introduce {
+    padding: 10px;
+
+    .title {
+        line-height: 20px;
+        font-family: Source Han Sans SC, Source Han Sans SC;
+        font-weight: bold;
+        font-size: 14px;
+        color: #333333;
+    }
+
+    .description {
+        font-size: 14px;
+        color: #333333;
+        line-height: 24px;
+    }
+}
+</style>

+ 10 - 1
pages.json

@@ -2,7 +2,10 @@
 	"pages": [{
 		"path": "pages/login/login"
 	}, {
-		"path": "pages/login/selectSite"
+		"path": "pages/login/selectSite",
+		"style": {
+			"navigationBarTitleText": "选择登录站点"
+		}
 	}, {
 		"path": "pages/index/index"
 	}],
@@ -12,6 +15,12 @@
 			"path": "affiche/index"
 		}, {
 			"path": "affiche/detail"
+		}, {
+			"path": "course/index"
+		}, {
+			"path": "course/list"
+		}, {
+			"path": "course/detail"
 		}]
 	}],
 	"globalStyle": {

+ 69 - 0
pages/index/cloud/school.vue

@@ -0,0 +1,69 @@
+<template>
+    <My_listbox ref="List" @getlist="getList">
+        <view class="box">
+            <navigator class="nav-box" v-for="item in list" :key="item.sat_courseware_classid"
+                :url="'/packageA/course/index?id=' + item.sat_courseware_classid + '&classname=' + item.classname"
+                hover-class="navigator-hover">
+                <image v-if="item.cover" class="image" :src="item.cover" mode="aspectFill" lazy-load="false" />
+                <text v-else>{{ item.classname }}</text>
+            </navigator>
+        </view>
+    </My_listbox>
+</template>
+
+<script>
+export default {
+    data() {
+        return {
+            list: []
+        }
+    },
+    created() {
+        this.getList()
+    },
+    methods: {
+        getList() {
+            this.$Http.basic({
+                "id": "20221102143302",
+                "content": {
+                    "parentid": 0,
+                    pageSize: 9999,
+                    "where": {
+                        "isenable": 1
+                    }
+                }
+            }).then(res => {
+                console.log("课程分类", res)
+                this.$refs.List.RefreshToComplete()
+                if (this.cutoff(res.msg)) return;
+                this.list = res.data.map(v => {
+                    v.cover = this.getSpecifiedImage(v.attinfos[0] || {})
+                    return v
+                });
+            })
+        }
+    },
+}
+</script>
+
+<style lang="scss">
+.box {
+    padding: 0 10px;
+    box-sizing: border-box;
+    display: flex;
+    justify-content: space-between;
+    flex-wrap: wrap;
+
+    .nav-box {
+        width: 172.5px;
+        height: 92px;
+        flex-shrink: 0;
+        margin-top: 10px;
+
+        .image {
+            width: 100%;
+            height: 100%;
+        }
+    }
+}
+</style>

+ 4 - 2
pages/index/index.vue

@@ -2,6 +2,7 @@
 	<view>
 		<index ref="首页" v-show="page == '首页'" />
 		<dataBank ref="资料库" v-show="page == '资料库'" />
+		<school ref="商学院" v-show="page == '商学院'" />
 		<bottom-suspension-frame ref="pages" @onChange="pageChange" />
 	</view>
 </template>
@@ -9,14 +10,15 @@
 <script>
 import index from './index/index.vue'
 import dataBank from './cloud/dataBank.vue'
+import school from './cloud/school.vue'
 
 import bottomSuspensionFrame from "./modules/bottomSuspensionFrame.vue";
 export default {
-	components: { bottomSuspensionFrame, index, dataBank },
+	components: { bottomSuspensionFrame, index, dataBank, school },
 	data() {
 		return {
 			swiperItemID: 'cloud',
-			page: '资料库'
+			page: '商学院'
 		}
 	},
 	onLoad() {

+ 1 - 0
static/images/Loop.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1703664219110" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7586" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M46.08 272.213333a42.666667 42.666667 0 0 0 8.96 14.08l128 128a42.666667 42.666667 0 0 0 60.586667 0 42.666667 42.666667 0 0 0 0-60.586666L188.16 298.666667H704a192.426667 192.426667 0 0 1 192 192 42.666667 42.666667 0 0 0 85.333333 0A277.76 277.76 0 0 0 704 213.333333H188.16l55.466667-55.04a42.666667 42.666667 0 0 0-60.586667-60.586666l-128 128a42.666667 42.666667 0 0 0-8.96 14.08 42.666667 42.666667 0 0 0 0 32.426666zM977.92 751.786667a42.666667 42.666667 0 0 0-8.96-14.08l-128-128a42.666667 42.666667 0 0 0-60.586667 60.586666l55.466667 55.04H320A192.426667 192.426667 0 0 1 128 533.333333a42.666667 42.666667 0 0 0-85.333333 0A277.76 277.76 0 0 0 320 810.666667h515.84l-55.466667 55.04a42.666667 42.666667 0 0 0 0 60.586666 42.666667 42.666667 0 0 0 60.586667 0l128-128a42.666667 42.666667 0 0 0 8.96-14.08 42.666667 42.666667 0 0 0 0-32.426666z" p-id="7587" fill="#3d3d3d"></path></svg>

+ 1 - 0
static/images/fast-forward.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><defs><style>.a,.b{fill:none;}.b{stroke:#3d3d3d;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-width:1.5px;}.c{}</style></defs><rect class="a" width="24" height="24"/><path  class="b" d="M1515.681,625a8,8,0,1,1,0-8v-4" transform="translate(-1496.22 -609)"/><path class="c" d="M3.17,0V-7.12H1.83L.74-6.27v1.5l1.09-.78V0ZM7.95-2.47a3.4,3.4,0,0,0-.33-1.9,1.206,1.206,0,0,0-1.04-.45,1.135,1.135,0,0,0-.51.13,1.407,1.407,0,0,0-.39.34V-5.92H7.87v-1.2H4.46v4.04H5.74v-.05c0-.33.18-.49.42-.49a.389.389,0,0,1,.36.21,3.037,3.037,0,0,1,.09,1.07,3.166,3.166,0,0,1-.12,1.22.359.359,0,0,1-.33.16c-.24,0-.42-.16-.42-.49v-.49H4.4v.28A1.579,1.579,0,0,0,4.89-.38,1.822,1.822,0,0,0,6.16.08,1.869,1.869,0,0,0,7.43-.38,2.647,2.647,0,0,0,7.95-2.47Z" transform="translate(8.26 15.52)"/><rect class="c" width="5.5" height="1.5" rx="0.75" transform="translate(17.5 11.23)"/><rect class="c" width="5.5" height="1.5" rx="0.75" transform="translate(21 9.23) rotate(90)" /></svg>

+ 1 - 0
static/images/get-back.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><defs><style>.a,.b{fill:none;}.b{stroke:#475266;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-width:1.5px;}.c{color:'#3d3d3d'}</style></defs><rect class="a" width="24" height="24"/><g transform="translate(-1496.22 -609)"><path class="b" d="M1500.76,625a8,8,0,1,0,0-8v-4"/></g><path class="c" d="M3.17,0V-7.12H1.83L.74-6.27v1.5l1.09-.78V0ZM7.95-2.47a3.4,3.4,0,0,0-.33-1.9,1.206,1.206,0,0,0-1.04-.45,1.135,1.135,0,0,0-.51.13,1.407,1.407,0,0,0-.39.34V-5.92H7.87v-1.2H4.46v4.04H5.74v-.05c0-.33.18-.49.42-.49a.389.389,0,0,1,.36.21,3.037,3.037,0,0,1,.09,1.07,3.166,3.166,0,0,1-.12,1.22.359.359,0,0,1-.33.16c-.24,0-.42-.16-.42-.49v-.49H4.4v.28A1.579,1.579,0,0,0,4.89-.38,1.822,1.822,0,0,0,6.16.08,1.869,1.869,0,0,0,7.43-.38,2.647,2.647,0,0,0,7.95-2.47Z" transform="translate(7 15.5)"/><rect class="c" width="4.5" height="1.5" rx="0.75" transform="translate(2 11.23)"/></svg>

+ 1 - 0
static/images/multiple.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><defs><style>.a{fill:none;}.b,.c{fill:#475266;}.c{font-size:8px;font-family:PingFangSC-Semibold, PingFang SC;font-weight:600;letter-spacing:-0.02em;}</style></defs><rect class="a" width="24" height="24"/><path class="b" d="M1530.26,598.75V604a2.5,2.5,0,0,1-2.5,2.5h-16a2.5,2.5,0,0,1-2.5-2.5V594a2.5,2.5,0,0,1,2.5-2.5h7.25a.75.75,0,0,0,.75-.75h0a.75.75,0,0,0-.75-.75h-7.25a4,4,0,0,0-4,4v10a4,4,0,0,0,4,4h16a4,4,0,0,0,4-4v-5.25a.75.75,0,0,0-.75-.75h0A.75.75,0,0,0,1530.26,598.75Z" transform="translate(-1507.76 -587)"/><text class="c" transform="translate(4 15)"><tspan x="0" y="0">倍速</tspan></text></svg>

+ 1 - 0
static/images/pause.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1703643608574" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7023" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M256 810.666667h170.666667V213.333333H256v597.333334z m341.333333-597.333334v597.333334h170.666667V213.333333h-170.666667z" p-id="7024"></path></svg>

+ 1 - 0
static/images/play.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1703643757308" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8148" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M820.053 473.316l-527.929-327.68c-29.582-18.205-68.266 4.55-68.266 38.684v655.36c0 34.133 38.684 56.889 68.266 38.684l525.654-327.68c31.858-15.928 31.858-61.44 2.275-77.368z" p-id="8149"></path></svg>

+ 1 - 0
static/images/定时.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1703642624873" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5229" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M878.885769 568.138291c0 201.397023-163.248995 364.646017-364.646017 364.646017S149.485359 769.535314 149.485359 568.138291c0-192.076766 148.582234-349.076131 336.901997-363.309391 0-0.4335-0.252875-0.903126-0.252875-1.408876V147.353983h-112.168207c-15.497636 0-28.033021-12.535384-28.033021-28.105271 0-15.497636 12.535384-28.033021 28.033021-28.03302h280.51083c15.461511 0 28.105271 12.535384 28.105271 28.03302 0 15.569886-12.643759 28.105271-28.105271 28.105271h-112.168207V203.383899c0 0.541875-0.252875 0.975376-0.252875 1.408876 188.247513 14.269385 336.829747 171.26875 336.829747 363.345516zM514.239752 259.52219c-170.437875 0-308.616101 138.142101-308.616101 308.616101s138.142101 308.616101 308.616101 308.616101c170.365625 0 308.507726-138.142101 308.507726-308.616101s-138.142101-308.616101-308.507726-308.616101z m0 392.787413c-46.529034 0-84.171312-37.714528-84.171312-84.171312 0-36.558527 23.481267-67.445424 56.029916-79.005433V343.693502c0-15.497636 12.535384-28.033021 28.105271-28.033021 15.497636 0 28.033021 12.535384 28.03302 28.033021v145.439356c32.657024 11.560008 56.138291 42.446906 56.138291 79.005433 0 46.456784-37.714528 84.171312-84.135186 84.171312z"  p-id="5230"></path></svg>

File diff suppressed because it is too large
+ 0 - 0
utils/jweixin.js


Some files were not shown because too many files changed in this diff