修改获取录音权限,修改登录页完成直接进首页,首页下方课程列表组件化
This commit is contained in:
+1
-1
@@ -11,7 +11,7 @@ VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7001'
|
||||
# app入口
|
||||
|
||||
|
||||
# VITE_APP_BASE_API_Url = 'http://25.16.122.65:7001'
|
||||
#VITE_APP_BASE_API_Url = 'http://25.16.122.65:7001'
|
||||
# VITE_APP_BASE_API_Url = 'http://25.16.122.92:9786'
|
||||
# VITE_APP_BASE_API_Url = 'http://25.18.122.66:9786'
|
||||
|
||||
|
||||
+2
-1
@@ -95,6 +95,8 @@ export const commonUploadVoiceFile = (file, url, data = {}, fileKey = 'voice') =
|
||||
} else if (REQUES_ERROR_CODES['NO_LOGIN'].includes(res.rtnCode)) {
|
||||
goto_login_fun()
|
||||
return reject('NO_LOGIN');
|
||||
}else if(res.rtnCode === '0004') {
|
||||
return reject('N');
|
||||
}
|
||||
return reject('Other');
|
||||
} catch (error) {
|
||||
@@ -102,7 +104,6 @@ export const commonUploadVoiceFile = (file, url, data = {}, fileKey = 'voice') =
|
||||
}
|
||||
},
|
||||
fail(error) {
|
||||
console.log('err', error);
|
||||
return reject('Other');
|
||||
}
|
||||
});
|
||||
|
||||
+2
-1
@@ -50,7 +50,8 @@ export const goto_login_fun = (from = 'http') => {
|
||||
if (from === 'socket' && page_route !== '') {
|
||||
common.redirectTo('/pages/login/login?path=' + page_route)
|
||||
} else {
|
||||
common.navigateTo('/pages/login/login')
|
||||
common.redirectTo('/pages/login/login')
|
||||
// common.navigateTo('/pages/login/login')
|
||||
}
|
||||
|
||||
}).finally(() => {
|
||||
|
||||
@@ -75,12 +75,13 @@ const RecordPermission = {
|
||||
// 安卓需要再次请求权限
|
||||
const permResult = await permission.requestAndroidPermission(
|
||||
'android.permission.RECORD_AUDIO');
|
||||
console.log('permResultx', permResult);
|
||||
if(permResult === 1) {
|
||||
|
||||
resolve('need_request');
|
||||
} else {
|
||||
reject('permResultx')
|
||||
}
|
||||
} else {
|
||||
reject('need_request');
|
||||
resolve('need_request');
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
|
||||
@@ -189,15 +189,15 @@
|
||||
item_answer.value = typeof newVal === 'string' ? newVal.split(',') : newVal;
|
||||
}
|
||||
);
|
||||
watch(
|
||||
item_answer,
|
||||
(newVal) => {
|
||||
console.log('item_answer', newVal);
|
||||
emit('update:modelValue', newVal);
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
// watch(
|
||||
// item_answer,
|
||||
// (newVal) => {
|
||||
// console.log('item_answer', newVal);
|
||||
// emit('update:modelValue', newVal);
|
||||
// },
|
||||
// { deep: true }
|
||||
// );
|
||||
|
||||
const feedback_click = () => {
|
||||
emit('subject_click', 'feedback', props.item);
|
||||
};
|
||||
@@ -297,7 +297,7 @@
|
||||
// 无论什么类型如果表里已经有了,再次点击就是弹出
|
||||
if (item_answer.value.includes(analysisVo.itemId)) {
|
||||
item_answer.value = item_answer.value.filter((id) => id !== analysisVo.itemId);
|
||||
// modelValue.value = item_answer.value;
|
||||
modelValue.value = item_answer.value;
|
||||
if (!['study'].includes(props.mode)) {
|
||||
muCheckbox('choose');
|
||||
}
|
||||
@@ -305,13 +305,13 @@
|
||||
// 单选
|
||||
// 单选插入,并且移除其他
|
||||
item_answer.value[0] = analysisVo.itemId;
|
||||
// modelValue.value = item_answer.value;
|
||||
modelValue.value = item_answer.value;
|
||||
muCheckbox('choose');
|
||||
} else if (props.item.qnsTyp === 'MU') {
|
||||
// 多选题
|
||||
// 多选直接插入
|
||||
item_answer.value.push(analysisVo.itemId);
|
||||
// modelValue.value = item_answer.value;
|
||||
modelValue.value = item_answer.value;
|
||||
if (!['study'].includes(props.mode)) {
|
||||
muCheckbox('choose');
|
||||
}
|
||||
@@ -319,7 +319,7 @@
|
||||
// 判断题
|
||||
// 判断插入,并且移除其他
|
||||
item_answer.value = [analysisVo.itemId];
|
||||
// modelValue.value = item_answer.value;
|
||||
modelValue.value = item_answer.value;
|
||||
muCheckbox('choose');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -163,10 +163,6 @@
|
||||
const endTime = Date.now();
|
||||
const times = Math.max(500 - endTime + startTime, 0);
|
||||
setTimeout(() => {
|
||||
console.log('延迟数据', times);
|
||||
// nextTick(() => {
|
||||
|
||||
// });
|
||||
popupRef.value.close();
|
||||
console.log('停止录音');
|
||||
recorderManager.stop();
|
||||
@@ -177,7 +173,6 @@
|
||||
onMounted(async () => {
|
||||
// #ifdef APP-PLUS
|
||||
recorderManager.onStop(function (res) {
|
||||
console.log('recorder stop' + JSON.stringify(res));
|
||||
console.log('录音文件临时位置', res.tempFilePath, isOut.value);
|
||||
if (isOut.value) return; // 被划掉的语音
|
||||
const endTime = Date.now();
|
||||
|
||||
@@ -1,52 +1,51 @@
|
||||
<template>
|
||||
<view v-bind="$attrs">
|
||||
<image :src="imgUrlShow" :mode="mode" @click="showDetail" style="width: 100%;height: 100%;"></image>
|
||||
<!-- <uv-overlay :show="showModel" opacity=".6" @click="showModel = false"> -->
|
||||
<view>
|
||||
<image :src="imgUrlShow" :mode="mode" @click="showDetail" style="width: 100%; height: 100%"></image>
|
||||
<uni-popup ref="PopupRef" class="popup" mask-background-color="rgba(0,0,0,.2)">
|
||||
<view class="overlay-box" @click="closePopup">
|
||||
<image class="detail-img" :src="imgUrlShow" :mode="mode"></image>
|
||||
</view>
|
||||
</uni-popup>
|
||||
<!-- </uv-overlay> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {previewFile, previewCacheThumbImage} from'@/api/common.js'
|
||||
import { get_base_url } from '@/api/request.js'
|
||||
import { useStorageStore } from "@/store/storage.js"
|
||||
|
||||
import { previewFile, previewCacheThumbImage } from '@/api/common.js';
|
||||
import { get_base_url } from '@/api/request.js';
|
||||
import { useStorageStore } from '@/store/storage.js';
|
||||
|
||||
// const storageStore = useStorageStore()
|
||||
export default {
|
||||
name:"image-preview",
|
||||
props:{
|
||||
imgId:{
|
||||
default:'',
|
||||
type:String
|
||||
name: 'image-preview',
|
||||
props: {
|
||||
imgId: {
|
||||
default: '',
|
||||
type: String
|
||||
},
|
||||
src:{
|
||||
default:'',
|
||||
type:String
|
||||
src: {
|
||||
default: '',
|
||||
type: String
|
||||
},
|
||||
width:{
|
||||
default:50,
|
||||
type:[String, Number]
|
||||
width: {
|
||||
default: 50,
|
||||
type: [String, Number]
|
||||
},
|
||||
height:{
|
||||
default:50,
|
||||
type:[String, Number]
|
||||
height: {
|
||||
default: 50,
|
||||
type: [String, Number]
|
||||
},
|
||||
isCache:{ // 获取缩略图
|
||||
isCache: {
|
||||
// 获取缩略图
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
mode:{
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'scaleToFill'
|
||||
default: 'aspectFill'
|
||||
},
|
||||
previewDetail: {
|
||||
default: '',
|
||||
type:[String, Boolean]
|
||||
type: [String, Boolean]
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -57,122 +56,122 @@
|
||||
showModel: false
|
||||
};
|
||||
},
|
||||
computed:{
|
||||
storageStore:() => useStorageStore(),
|
||||
computed: {
|
||||
storageStore: () => useStorageStore(),
|
||||
imageObj() {
|
||||
return this.storageStore?.imgObj||{}
|
||||
}
|
||||
return this.storageStore?.imgObj || {};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
imgId: {
|
||||
handler(newval, oldval) {
|
||||
if(newval.indexOf('/') === 0) {
|
||||
this.imgUrlShow = this.base_url + newval
|
||||
return
|
||||
if (newval.indexOf('/') === 0) {
|
||||
this.imgUrlShow = this.base_url + newval;
|
||||
return;
|
||||
}
|
||||
if(newval.indexOf('http') === 0){
|
||||
this.imgUrlShow = newval
|
||||
return
|
||||
if (newval.indexOf('http') === 0) {
|
||||
this.imgUrlShow = newval;
|
||||
return;
|
||||
}
|
||||
if (newval && this.watching) {
|
||||
this.getPreviewUrlBlob(newval);
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
deep: true
|
||||
},
|
||||
src: {
|
||||
handler(newval, oldval) {
|
||||
if (newval && this.watching) {
|
||||
this.imgUrlShow = this.base_url + this.src
|
||||
this.imgUrlShow = this.base_url + this.src;
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
closePopup(){
|
||||
this.showModel = false
|
||||
this.storageStore.setTouchBtnZIndex(9)
|
||||
this.$refs.PopupRef.close()
|
||||
closePopup() {
|
||||
this.showModel = false;
|
||||
this.storageStore.setTouchBtnZIndex(9);
|
||||
this.$refs.PopupRef.close();
|
||||
},
|
||||
showDetail(){
|
||||
if(!!this.previewDetail){
|
||||
this.showModel = true
|
||||
this.storageStore.setTouchBtnZIndex(-1)
|
||||
this.$refs.PopupRef.open()
|
||||
showDetail() {
|
||||
if (!!this.previewDetail) {
|
||||
this.showModel = true;
|
||||
this.storageStore.setTouchBtnZIndex(-1);
|
||||
this.$refs.PopupRef.open();
|
||||
}
|
||||
},
|
||||
getPreviewUrlBlob(id) {
|
||||
if (!id) {
|
||||
this.imgUrlShow = ''
|
||||
return
|
||||
this.imgUrlShow = '';
|
||||
return;
|
||||
}
|
||||
if(this.isCache){
|
||||
let _cache = this.imageObj[`/${id}/${this.width}/${this.height}`] || ''
|
||||
if(_cache){
|
||||
if (this.isCache) {
|
||||
let _cache = this.imageObj[`/${id}/${this.width}/${this.height}`] || '';
|
||||
if (_cache) {
|
||||
this.imgUrlShow = _cache;
|
||||
return
|
||||
return;
|
||||
}
|
||||
previewCacheThumbImage(id, this.width,this.height).then((res) => {
|
||||
previewCacheThumbImage(id, this.width, this.height).then((res) => {
|
||||
this.imgUrlShow = res;
|
||||
this.storageStore.setStorage('image', `/${id}/${this.width}/${this.height}`, res)
|
||||
this.storageStore.setStorage('image', `/${id}/${this.width}/${this.height}`, res);
|
||||
});
|
||||
}else{
|
||||
let _cache = this.imageObj[`${id}`] || ''
|
||||
if(_cache){
|
||||
} else {
|
||||
let _cache = this.imageObj[`${id}`] || '';
|
||||
if (_cache) {
|
||||
this.imgUrlShow = _cache;
|
||||
return
|
||||
return;
|
||||
}
|
||||
previewFile(id).then((result) => {
|
||||
//#ifdef APP-PLUS
|
||||
let _header = result.header['Content-Type'].split(';')[0]
|
||||
let _header = result.header['Content-Type'].split(';')[0];
|
||||
// #endif
|
||||
//#ifndef APP-PLUS
|
||||
let _header = result.header['content-type'].split(';')[0]
|
||||
let _header = result.header['content-type'].split(';')[0];
|
||||
// #endif
|
||||
let base64 = `data:${_header};base64,` + uni.arrayBufferToBase64(result.data)
|
||||
let base64 = `data:${_header};base64,` + uni.arrayBufferToBase64(result.data);
|
||||
this.imgUrlShow = base64;
|
||||
this.storageStore.setStorage('image', id, base64)
|
||||
this.storageStore.setStorage('image', id, base64);
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.imgId) {
|
||||
if(this.imgId.indexOf('/') === 0) {
|
||||
this.imgUrlShow = this.base_url + this.imgId
|
||||
}else if(this.imgId.indexOf('http') === 0){
|
||||
this.imgUrlShow = this.imgId
|
||||
}else{
|
||||
if (this.imgId.indexOf('/') === 0) {
|
||||
this.imgUrlShow = this.base_url + this.imgId;
|
||||
} else if (this.imgId.indexOf('http') === 0) {
|
||||
this.imgUrlShow = this.imgId;
|
||||
} else {
|
||||
this.getPreviewUrlBlob(this.imgId);
|
||||
}
|
||||
}
|
||||
this.watching = true
|
||||
if(this.src) {
|
||||
this.imgUrlShow = this.base_url + this.src
|
||||
this.watching = true;
|
||||
if (this.src) {
|
||||
this.imgUrlShow = this.base_url + this.src;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.overlay-box{
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
z-index: 999;
|
||||
background-color: rgba(0, 0, 0, .65);
|
||||
.detail-img{
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
.overlay-box {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100vw;
|
||||
max-height: 100%;
|
||||
transform: translate(-50%, -50%);
|
||||
height: 100vh;
|
||||
z-index: 999;
|
||||
background-color: rgba(0, 0, 0, 0.65);
|
||||
.detail-img {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 100vw;
|
||||
max-height: 100%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<view class="item">
|
||||
<view class="details_div">
|
||||
<view class="img_div">
|
||||
<image-preview class="img" :src="item.ossAddr" mode="scaleToFill"></image-preview>
|
||||
<image-preview class="img" :src="item.ossAddr"></image-preview>
|
||||
</view>
|
||||
<view class="right_div">
|
||||
<view class="title ellipsis-text">
|
||||
@@ -128,13 +128,13 @@
|
||||
|
||||
.img_div {
|
||||
position: relative;
|
||||
width: 226rpx;
|
||||
width: 224rpx;
|
||||
height: 168rpx;
|
||||
overflow: hidden;
|
||||
border-radius: 22rpx;
|
||||
|
||||
.img {
|
||||
width: 226rpx;
|
||||
width: 224rpx;
|
||||
height: 168rpx;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<view class="item">
|
||||
<view class="details_div">
|
||||
<view class="img_div">
|
||||
<image-preview class="img" :src="item.ossAddr" mode="scaleToFill"></image-preview>
|
||||
<image-preview class="img" :src="item.ossAddr"></image-preview>
|
||||
</view>
|
||||
<view class="right_div">
|
||||
<view class="title ellipsis-text">
|
||||
@@ -127,13 +127,13 @@
|
||||
|
||||
.img_div {
|
||||
position: relative;
|
||||
width: 226rpx;
|
||||
width: 224rpx;
|
||||
height: 168rpx;
|
||||
overflow: hidden;
|
||||
border-radius: 22rpx;
|
||||
|
||||
.img {
|
||||
width: 226rpx;
|
||||
width: 224rpx;
|
||||
height: 168rpx;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<view class="item">
|
||||
<view class="details_div">
|
||||
<view class="img_div">
|
||||
<image-preview class="img" :src="item.ossAddr" mode="scaleToFill"></image-preview>
|
||||
<image-preview class="img" :src="item.ossAddr"></image-preview>
|
||||
</view>
|
||||
<view class="right_div">
|
||||
<view class="title ellipsis-text">
|
||||
@@ -128,13 +128,13 @@
|
||||
|
||||
.img_div {
|
||||
position: relative;
|
||||
width: 226rpx;
|
||||
width: 224rpx;
|
||||
height: 168rpx;
|
||||
overflow: hidden;
|
||||
border-radius: 22rpx;
|
||||
|
||||
.img {
|
||||
width: 226rpx;
|
||||
width: 224rpx;
|
||||
height: 168rpx;
|
||||
}
|
||||
|
||||
|
||||
@@ -303,12 +303,13 @@
|
||||
const topic = topicList[questionNumber.value];
|
||||
touchBtnRef.value?.clearinputText(); // 清除发送框数据
|
||||
if (type === 'voice') {
|
||||
if(topic.es_status == '00') return;
|
||||
if (topic.es_status == '00') return;
|
||||
topic.es_status = '00'; // 00转圈
|
||||
const voicePath = submitObj;
|
||||
commonUploadVoiceFile(voicePath, '/traask/traAskchat/voiceTrans', {})
|
||||
.then((res) => {
|
||||
let _res = JSON.parse(res.data);
|
||||
console.log('voicePath_res_res_res', _res);
|
||||
if (_res.rtnCode === '0000') {
|
||||
const _content = _res.body.transContent.trim();
|
||||
if (_content === '') {
|
||||
@@ -351,6 +352,7 @@
|
||||
// 添加试题答案缓存
|
||||
const addTopicAnswerCache = () => {
|
||||
const my_answer = topic.value.my_answer;
|
||||
console.log('my_answer', my_answer);
|
||||
const qnsId = topic.value.qnsId;
|
||||
console.log('asdsadas', answerCacheList.value);
|
||||
const newCache = { ...answerCacheList.value };
|
||||
@@ -611,6 +613,7 @@
|
||||
addTopicAnswerCache();
|
||||
|
||||
const answerDtoList = getAnswerDtoList();
|
||||
console.log('answerDtoList', answerDtoList);
|
||||
commitPaperCache({
|
||||
examTyp: paperData.examId ? 'PAPERS' : 'CRS',
|
||||
papersId: paperData.papersId,
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
>
|
||||
<view class="item" @click="click_item(item)">
|
||||
<view class="img_div">
|
||||
<image-preview class="img" :src="item?.ossAddr" mode="scaleToFill"></image-preview>
|
||||
<image-preview class="img" :src="item?.ossAddr"></image-preview>
|
||||
<view class="subscript">{{ item.evalGrade ?? 0 }}分</view>
|
||||
</view>
|
||||
<view class="right_div">
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
>
|
||||
<view class="item" :class="getStatusClass(item.isFinish)" @click="click_item(item)">
|
||||
<view class="img_div">
|
||||
<image-preview class="img" :src="item?.ossAddr" mode="scaleToFill"></image-preview>
|
||||
<image-preview class="img" :src="item?.ossAddr"></image-preview>
|
||||
<view class="subscript" v-if="item.isFinish === '02'">已完成</view>
|
||||
<view class="subscript" v-else>未完成</view>
|
||||
</view>
|
||||
@@ -204,7 +204,7 @@
|
||||
border-radius: 22rpx;
|
||||
|
||||
.img {
|
||||
width: 226rpx;
|
||||
width: 224rpx;
|
||||
height: 168rpx;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
<template>
|
||||
<!-- 热门课程分模块标题 -->
|
||||
<view class="module_title_div">
|
||||
<view class="icon icon_1">
|
||||
<image class="img" :src="icon"></image>
|
||||
</view>
|
||||
<view class="text font_pf">{{ title }}</view>
|
||||
</view>
|
||||
<!-- 热门课程 -->
|
||||
<view class="hot_class_div">
|
||||
<scroll-view class="scroll-view" :scroll-x="true" :show-scrollbar="false">
|
||||
<view class="scroll-view-item" v-for="(item, index) in class_list" :key="index">
|
||||
<view class="item_div">
|
||||
<!-- <uv-skeletons :loading="!item.crsNum" :rows="3" avatar avatar-shape="square" :title="false">
|
||||
<view class="item" @click="goto_course_detail(item.crsId)">
|
||||
<view class="left">
|
||||
<image-preview
|
||||
class="img-box img"
|
||||
:imgId="item.imgId"
|
||||
:isCache="true"
|
||||
:width="240"
|
||||
:height="240"
|
||||
></image-preview>
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="title ellipsis-text">{{ item.crsName }}</view>
|
||||
<view class="note ellipsis-text">更新:{{ (item.mtTime || '').substr(0, 10) }}</view>
|
||||
<view class="button_div">
|
||||
<view class="note ellipsis-text">已学:{{ item.accmStdyCnt }}人次</view>
|
||||
<view class="button">去学习</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uv-skeletons> -->
|
||||
|
||||
<uv-skeletons :loading="!item.crsNum" avatar avatar-shape="square" :title="false" :skeleton="skeleton">
|
||||
<view class="item" @click="goto_course_detail(item.crsId)">
|
||||
<view class="left">
|
||||
<image-preview
|
||||
class="img-box img"
|
||||
:imgId="item.imgId"
|
||||
:isCache="true"
|
||||
:width="240"
|
||||
:height="160"
|
||||
></image-preview>
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="title ellipsis-text">
|
||||
{{ item.crsName }}
|
||||
</view>
|
||||
<view class="note ellipsis-text">更新:{{ (item.mtTime || '').substr(0, 10) }}</view>
|
||||
<view class="button_div">
|
||||
<view class="note ellipsis-text">已学:{{ item.accmStdyCnt }}人次</view>
|
||||
<view class="button">去学习</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uv-skeletons>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, nextTick, onBeforeMount, onMounted, reactive, ref } from 'vue';
|
||||
import { queryCrsInfoByLastnew, queryCrsInfoByPopular, queryCrsInfoByRecmd } from '@/api/index.js';
|
||||
import common from '@/common/common';
|
||||
import hostIcon from '@/static/images/index/hot.png';
|
||||
import recommendIcon from '@/static/images/index/recommend.png';
|
||||
import newIcon from '@/static/images/index/new.png';
|
||||
const props = defineProps({
|
||||
name: {
|
||||
type: String
|
||||
}
|
||||
});
|
||||
// 1. 先定义命名函数,明确函数用途
|
||||
const getConfigByProps = () => {
|
||||
if (props.name === 'hot_class') {
|
||||
return {
|
||||
fetchFunction: queryCrsInfoByPopular,
|
||||
title: '热门课程',
|
||||
icon: hostIcon
|
||||
};
|
||||
} else if (props.name === 'recommend_class') {
|
||||
return {
|
||||
fetchFunction: queryCrsInfoByRecmd,
|
||||
title: '推荐课程',
|
||||
icon: recommendIcon
|
||||
};
|
||||
} else if (props.name === 'new_class') {
|
||||
return {
|
||||
fetchFunction: queryCrsInfoByLastnew,
|
||||
title: '最新课程',
|
||||
icon: newIcon
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// 2. 调用命名函数,解构赋值
|
||||
const { fetchFunction, title, icon } = getConfigByProps(); // 调用函数,获取返回对象后解构
|
||||
|
||||
const init_class_data = [
|
||||
{
|
||||
crsNum: '',
|
||||
img: '',
|
||||
crsName: '',
|
||||
issuTm: '',
|
||||
accmStdyCnt: ''
|
||||
},
|
||||
{
|
||||
crsNum: '',
|
||||
img: '',
|
||||
crsName: '',
|
||||
issuTm: '',
|
||||
accmStdyCnt: ''
|
||||
}
|
||||
];
|
||||
const class_list = ref([...init_class_data]);
|
||||
const skeleton = [
|
||||
{
|
||||
type: 'flex',
|
||||
num: 1,
|
||||
children: [
|
||||
{
|
||||
type: 'avatar',
|
||||
num: 1,
|
||||
style: 'marginRight: 22rpx;width: 200rpx;height:150rpx;border-radius:16rpx;'
|
||||
},
|
||||
{
|
||||
type: 'line',
|
||||
num: 3,
|
||||
|
||||
style: ['width: 240rpx;', null, null]
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
const get_data = () => {
|
||||
fetchFunction().then((res) => {
|
||||
if (props.name === 'hot_class') {
|
||||
} else {
|
||||
// class_list.value = res.body;
|
||||
}
|
||||
class_list.value = res.body;
|
||||
});
|
||||
};
|
||||
defineExpose({ get_data });
|
||||
|
||||
// 进入课程详情页
|
||||
const goto_course_detail = (crsId) => {
|
||||
common.navigateTo('/pages/courseDetail/index?crsId=' + crsId);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$bg-margin-left: 30rpx;
|
||||
// 设置骨架屏左侧图片框的大小,设置成和图片大小一致,否则横向滑动会串行(对不齐)
|
||||
// 热门课程等三个横向滑动模块的样式
|
||||
.hot_class_div {
|
||||
margin-left: $bg-margin-left;
|
||||
.scroll-view {
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scroll-view-item {
|
||||
display: inline-block;
|
||||
margin-right: 30rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 22rpx;
|
||||
box-shadow: #eaeaea 0 0 6rpx;
|
||||
padding: 32rpx 22rpx 36rpx 26rpx;
|
||||
}
|
||||
|
||||
.item_div {
|
||||
width: 562rpx;
|
||||
// display: block;
|
||||
}
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
width: 562rpx;
|
||||
.left {
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
width: 200rpx;
|
||||
height: 150rpx;
|
||||
.img {
|
||||
width: 200rpx;
|
||||
height: 150rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
padding-left: 22rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
.title {
|
||||
font-weight: 500;
|
||||
font-size: 30rpx;
|
||||
color: #333333;
|
||||
line-height: 40rpx;
|
||||
}
|
||||
.note {
|
||||
font-family: PingFangSC, PingFang SC;
|
||||
font-weight: 400;
|
||||
font-size: 23rpx;
|
||||
color: #666666;
|
||||
line-height: 33rpx;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.button_div {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.button {
|
||||
text-align: center;
|
||||
line-height: 62rpx;
|
||||
width: 138rpx;
|
||||
height: 62rpx;
|
||||
background: #ebf1ff;
|
||||
border-radius: 30rpx;
|
||||
font-weight: 500;
|
||||
font-size: 30rpx;
|
||||
color: #0066ff;
|
||||
font-style: normal;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.module_title_div {
|
||||
display: flex;
|
||||
margin: 30rpx $bg-margin-left;
|
||||
align-items: center;
|
||||
|
||||
.icon {
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
|
||||
.icon_1 {
|
||||
.img {
|
||||
width: 31rpx;
|
||||
height: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.icon_2 {
|
||||
margin-top: 10rpx;
|
||||
|
||||
.img {
|
||||
width: 38rpx;
|
||||
height: 38rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.icon_3 {
|
||||
// margin-top: 10rpx;
|
||||
.img {
|
||||
width: 38rpx;
|
||||
height: 31rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 34rpx;
|
||||
color: #323e57;
|
||||
font-weight: 700;
|
||||
line-height: 46rpx;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
+32
-201
@@ -152,15 +152,12 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 热门课程分模块标题 -->
|
||||
<view class="module_title_div">
|
||||
<view class="icon icon_1">
|
||||
<image class="img" src="@/static/images/index/hot.png"></image>
|
||||
</view>
|
||||
<view class="text font_pf">热门课程</view>
|
||||
</view>
|
||||
<!-- 热门课程 -->
|
||||
<view class="hot_class_div">
|
||||
<classScroll :ref="(el) => (classScrollRef[0] = el)" name="hot_class"></classScroll>
|
||||
<classScroll :ref="(el) => (classScrollRef[1] = el)" name="recommend_class"></classScroll>
|
||||
<classScroll :ref="(el) => (classScrollRef[2] = el)" name="new_class"></classScroll>
|
||||
|
||||
|
||||
<!-- <view class="hot_class_div">
|
||||
<scroll-view class="scroll-view" :scroll-x="true" :show-scrollbar="false">
|
||||
<view class="scroll-view-item" v-for="(item, index) in hot_class_list" :key="index">
|
||||
<view class="item_div">
|
||||
@@ -170,7 +167,6 @@
|
||||
<image-preview
|
||||
class="img-box img"
|
||||
:imgId="item.imgId"
|
||||
mode="scaleToFill"
|
||||
:isCache="true"
|
||||
:width="240"
|
||||
:height="240"
|
||||
@@ -189,84 +185,8 @@
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 推荐课程分模块标题 -->
|
||||
<view class="module_title_div">
|
||||
<view class="icon icon_2">
|
||||
<image class="img" src="@/static/images/index/recommend.png"></image>
|
||||
</view>
|
||||
<view class="text font_pf">推荐课程</view>
|
||||
</view>
|
||||
<!-- 推荐课程 -->
|
||||
<view class="hot_class_div">
|
||||
<scroll-view class="scroll-view" :scroll-x="true" :show-scrollbar="false">
|
||||
<view class="scroll-view-item" v-for="(item, index) in recommend_class_list" :key="index">
|
||||
<view class="item_div">
|
||||
<uv-skeleton :loading="!item.crsNum" :rows="3" avatar avatar-shape="square" :title="false">
|
||||
<view class="item" @click="goto_course_detail(item.crsId)">
|
||||
<view class="left">
|
||||
<image-preview
|
||||
class="img-box img"
|
||||
:imgId="item.imgId"
|
||||
mode="scaleToFill"
|
||||
:isCache="true"
|
||||
:width="240"
|
||||
:height="240"
|
||||
></image-preview>
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="title ellipsis-text">{{ item.crsName }}</view>
|
||||
<view class="note ellipsis-text">更新:{{ (item.mtTime || '').substr(0, 10) }}</view>
|
||||
<view class="button_div">
|
||||
<view class="note ellipsis-text">已学:{{ item.accmStdyCnt }}人次</view>
|
||||
<view class="button">去学习</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uv-skeleton>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<!-- 最新课程分模块标题 -->
|
||||
<view class="module_title_div">
|
||||
<view class="icon icon_3">
|
||||
<image class="img" src="@/static/images/index/new.png"></image>
|
||||
</view>
|
||||
<view class="text font_pf">最新课程</view>
|
||||
</view>
|
||||
<!-- 最新课程 -->
|
||||
<view class="hot_class_div">
|
||||
<scroll-view class="scroll-view" :scroll-x="true" :show-scrollbar="false">
|
||||
<view class="scroll-view-item" v-for="(item, index) in new_class_list" :key="index">
|
||||
<view class="item_div">
|
||||
<uv-skeleton :loading="!item.crsNum" :rows="3" avatar avatar-shape="square" :title="false">
|
||||
<view class="item" @click="goto_course_detail(item.crsId)">
|
||||
<view class="left">
|
||||
<image-preview
|
||||
class="img-box img"
|
||||
:imgId="item.imgId"
|
||||
mode="aspectFill"
|
||||
:isCache="true"
|
||||
:width="240"
|
||||
:height="240"
|
||||
></image-preview>
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="title ellipsis-text">{{ item.crsName }}</view>
|
||||
<view class="note ellipsis-text">更新:{{ (item.mtTime || '').substr(0, 10) }}</view>
|
||||
<view class="button_div">
|
||||
<view class="note ellipsis-text">已学:{{ item.accmStdyCnt }}人次</view>
|
||||
<view class="button">去学习</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uv-skeleton>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
<view class="bottom_line">
|
||||
<uv-divider text="我是有底线的" lineColor="#9cB0DC" :hairline="true"></uv-divider>
|
||||
</view>
|
||||
@@ -282,11 +202,13 @@
|
||||
import { getUserInfo } from '@/common/common';
|
||||
import common from '@/common/common';
|
||||
import { setMascot } from '@/common/mascot.js';
|
||||
import { getStatisticsData, queryCrsInfoByLastnew, queryCrsInfoByPopular, queryCrsInfoByRecmd } from '@/api/index.js';
|
||||
import { getStatisticsData } from '@/api/index.js';
|
||||
import { noticeMessageCount } from '@/api/messageNotification.js';
|
||||
|
||||
import classScroll from './components/class_scroll.vue';
|
||||
const scrollTop = ref(0);
|
||||
const no_read_message_num = ref(0);
|
||||
const classScrollRef = ref([]);
|
||||
|
||||
// 处理显示的消息数量文本
|
||||
const messageDisplayText = computed(() => {
|
||||
return no_read_message_num.value > 99 ? '99+' : no_read_message_num.value;
|
||||
@@ -301,14 +223,13 @@
|
||||
const stdtTmLenRef = ref(null);
|
||||
const accmPracticeCntRef = ref(null);
|
||||
const accmExamCntRef = ref(null);
|
||||
const three_list_request_time = ref(0); // 三个列表更新时间
|
||||
|
||||
// 计算透明度
|
||||
const opacity = computed(() => {
|
||||
if (scrollTop.value <= 130) return 0;
|
||||
return Math.min(3, (scrollTop.value - 130) / 30);
|
||||
});
|
||||
|
||||
|
||||
const bgOpacity = computed(() => {
|
||||
return `rgba(246,248,255,${opacity.value})`;
|
||||
});
|
||||
@@ -319,27 +240,9 @@
|
||||
});
|
||||
// 滚动消息
|
||||
const notice_text = ref(['绿色金融政策解析与商业银行绿色水水水水水水水水水水水水水', '绿色金融政策解析与商业银行红色']);
|
||||
const init_class_data = [
|
||||
{
|
||||
crsNum: '',
|
||||
img: '',
|
||||
crsName: '',
|
||||
issuTm: '',
|
||||
accmStdyCnt: ''
|
||||
},
|
||||
{
|
||||
crsNum: '',
|
||||
img: '',
|
||||
crsName: '',
|
||||
issuTm: '',
|
||||
accmStdyCnt: ''
|
||||
}
|
||||
];
|
||||
// 热门课程
|
||||
const hot_class_list = ref([...init_class_data]);
|
||||
const new_class_list = ref([...init_class_data]);
|
||||
const recommend_class_list = ref([...init_class_data]);
|
||||
|
||||
const mascotInfo = ref({});
|
||||
|
||||
const statistics_data = reactive({
|
||||
stdtTmLen: 0, // 学习
|
||||
accmPracticeCnt: 0, // 训练
|
||||
@@ -403,43 +306,19 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const index = ref(0);
|
||||
const ai_test = () => {
|
||||
index.value++;
|
||||
if (index.value == 4) {
|
||||
index.value = 1;
|
||||
}
|
||||
uni.setTabBarStyle({
|
||||
midButton: {
|
||||
iconPath: '/static/images/icon/fawn-' + index.value + '.png',
|
||||
width: '86px',
|
||||
height: '86px',
|
||||
iconWidth: '90px'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// 进入搜索页
|
||||
const goto_search_page = () => {
|
||||
common.navigateTo('/pages/search/search?from=index');
|
||||
};
|
||||
// 进入课程详情页
|
||||
const goto_course_detail = (crsId) => {
|
||||
common.navigateTo('/pages/courseDetail/index?crsId=' + crsId);
|
||||
};
|
||||
const scrolltolower = () => {
|
||||
common.navigateTo('/pages/index/dialog', {
|
||||
animationType: 'slide-in-bottom'
|
||||
});
|
||||
};
|
||||
|
||||
onLoad(() => {
|
||||
statistics_data['init'](); // 初始化数据
|
||||
// 检测如果没设置吉祥物,跳转到吉祥物界面
|
||||
// 判断下如果没有设置吉祥物就跳转到吉祥物页面
|
||||
const userInfo = getUserInfo();
|
||||
if (userInfo?.mascotInfo.mascotId === null) {
|
||||
//说明这人在上次选吉祥物的时候退出了,没有选到吉祥物
|
||||
//说明这人在上次选吉祥物的时候退出了,没有选到吉祥物(概率很低)
|
||||
common.redirectTo('/pages/mascot/mascot_select_list');
|
||||
return;
|
||||
}
|
||||
@@ -456,18 +335,12 @@
|
||||
}
|
||||
setMascot();
|
||||
statistics_data['get_statistics_data'](); // 获取统计数据
|
||||
queryCrsInfoByLastnew().then((res) => {
|
||||
new_class_list.value = res.body;
|
||||
});
|
||||
queryCrsInfoByPopular().then((res) => {
|
||||
hot_class_list.value = res.body;
|
||||
});
|
||||
queryCrsInfoByRecmd().then((res) => {
|
||||
recommend_class_list.value = res.body;
|
||||
nextTick(() => {
|
||||
classScrollRef.value.forEach((item) => item?.get_data());
|
||||
});
|
||||
|
||||
noticeMessageCount().then((res) => {
|
||||
no_read_message_num.value = res.body;
|
||||
// no_read_message_num.value = 109;
|
||||
});
|
||||
});
|
||||
onHide(() => {});
|
||||
@@ -476,11 +349,11 @@
|
||||
<style scoped lang="scss">
|
||||
$bg-margin-left: 30rpx;
|
||||
// 设置骨架屏左侧图片框的大小,设置成和图片大小一致,否则横向滑动会串行(对不齐)
|
||||
:deep(.uv-skeleton__wrapper__avatar) {
|
||||
height: 146rpx !important;
|
||||
width: 146rpx !important;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
// :deep(.uv-skeleton__wrapper__avatar) {
|
||||
// height: 146rpx !important;
|
||||
// width: 146rpx !important;
|
||||
// border-radius: 16rpx;
|
||||
// }
|
||||
|
||||
// 底线样式
|
||||
.bottom_line {
|
||||
@@ -517,18 +390,18 @@
|
||||
.left {
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
width: 180rpx;
|
||||
height: 146rpx;
|
||||
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
width: 200rpx;
|
||||
height: 150rpx;
|
||||
}
|
||||
// margin-right: 22rpx;
|
||||
}
|
||||
|
||||
.right {
|
||||
width: calc(100% - 180rpx);
|
||||
margin-left: 22rpx;
|
||||
flex: 1;
|
||||
// width: calc(100% - 180rpx);
|
||||
padding-left: 22rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
@@ -850,48 +723,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.module_title_div {
|
||||
display: flex;
|
||||
margin: 30rpx $bg-margin-left;
|
||||
align-items: center;
|
||||
|
||||
.icon {
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
|
||||
.icon_1 {
|
||||
.img {
|
||||
width: 31rpx;
|
||||
height: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.icon_2 {
|
||||
margin-top: 10rpx;
|
||||
|
||||
.img {
|
||||
width: 38rpx;
|
||||
height: 38rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.icon_3 {
|
||||
// margin-top: 10rpx;
|
||||
.img {
|
||||
width: 38rpx;
|
||||
height: 31rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 34rpx;
|
||||
color: #323e57;
|
||||
font-weight: 700;
|
||||
line-height: 46rpx;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.main_div {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<view class="item" :class="getStatusClass(item.isFinish)" @click="click_item(item)">
|
||||
<view class="img_div">
|
||||
<image-preview class="img" :src="item.ossAddr" mode="scaleToFill"></image-preview>
|
||||
<image-preview class="img" :src="item.ossAddr"></image-preview>
|
||||
<view class="subscript" v-if="item.isFinish === '02'">已完成</view>
|
||||
<view class="subscript" v-else>未完成</view>
|
||||
</view>
|
||||
@@ -109,7 +109,7 @@
|
||||
border-radius: 22rpx;
|
||||
|
||||
.img {
|
||||
width: 226rpx;
|
||||
width: 224rpx;
|
||||
height: 168rpx;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</template>
|
||||
<view class="detail_div">
|
||||
<view class="left">
|
||||
<image-preview class="img" :src="detailData.ossAddr" mode="scaleToFill"></image-preview>
|
||||
<image-preview class="img" :src="detailData.ossAddr"></image-preview>
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="title_div">
|
||||
@@ -508,8 +508,6 @@
|
||||
}
|
||||
|
||||
.body-title {
|
||||
|
||||
|
||||
width: 100%;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
@@ -522,14 +520,14 @@
|
||||
font-size: 32rpx;
|
||||
color: #000000;
|
||||
font-style: normal;
|
||||
|
||||
|
||||
background-image: url('@/static/images/learningTasks/learningTasksBg.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% calc(420rpx + var(--status-bar-height)); /* 宽度充满,高度自适应比例 */
|
||||
background-position: top;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
|
||||
.detail_div {
|
||||
height: 250rpx;
|
||||
z-index: 2;
|
||||
@@ -558,8 +556,8 @@
|
||||
border-radius: 0 0 0 28rpx;
|
||||
}
|
||||
.left > .img {
|
||||
width: 225rpx;
|
||||
height: 169rpx;
|
||||
width: 224rpx;
|
||||
height: 168rpx;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
>
|
||||
<view class="item" v-for="item in data_list" @click="goto_course_detail(item)">
|
||||
<view class="img_div">
|
||||
<image-preview class="img" :imgId="item.imgId" mode="scaleToFill"></image-preview>
|
||||
<image-preview class="img" :imgId="item.imgId"></image-preview>
|
||||
</view>
|
||||
<view class="right_div">
|
||||
<view class="title ellipsis-text">{{ item.crsName }}</view>
|
||||
@@ -60,7 +60,7 @@
|
||||
height: 168rpx;
|
||||
overflow: hidden;
|
||||
border-radius: 22rpx;
|
||||
|
||||
|
||||
.img {
|
||||
width: 224rpx;
|
||||
height: 168rpx;
|
||||
|
||||
@@ -112,7 +112,9 @@
|
||||
:custom-style="customStyle"
|
||||
:throttleTime="300"
|
||||
:hairline="false"
|
||||
:loading="fixed_button_loading"
|
||||
:disabled="isTimeInvalid"
|
||||
loadingText="正在加载"
|
||||
>
|
||||
开始考试
|
||||
</uv-button>
|
||||
@@ -127,9 +129,8 @@
|
||||
import { startTraExamPapersInfo, queryTraExamPapersByPapersId } from '@/api/examination.js';
|
||||
import common from '@/common/common';
|
||||
import { setPageCache, getPageCache } from '@/common/common';
|
||||
import useZpaging from '@/composables/useZpaging.js';
|
||||
const pagingRef = ref(null);
|
||||
|
||||
const fixed_button_loading = ref(false);
|
||||
const detailData = reactive({
|
||||
papersId: '',
|
||||
papersName: '',
|
||||
@@ -171,8 +172,6 @@
|
||||
const query = () => {
|
||||
setTimeout(() => {
|
||||
queryTraExamPapersByPapersId({ papersId: detailData.papersId }).then((res) => {
|
||||
console.log('水水水水', res.body);
|
||||
|
||||
const compareKeys = [
|
||||
'examId',
|
||||
'papersName',
|
||||
@@ -215,7 +214,8 @@
|
||||
return common.msg('考试时间已结束');
|
||||
}
|
||||
}
|
||||
common.loading();
|
||||
// common.loading();
|
||||
fixed_button_loading.value = true;
|
||||
startTraExamPapersInfo({
|
||||
examId: detailData.examId
|
||||
})
|
||||
@@ -223,8 +223,12 @@
|
||||
setPageCache('examination', { ...res.body, examId: detailData.examId });
|
||||
common.navigateTo('/pages/examination/index');
|
||||
})
|
||||
.catch(() => {
|
||||
pagingRef.value.reload();
|
||||
})
|
||||
.finally(() => {
|
||||
common.hideLoading();
|
||||
fixed_button_loading.value = false;
|
||||
// common.hideLoading();
|
||||
});
|
||||
};
|
||||
onLoad((e) => {
|
||||
@@ -236,7 +240,7 @@
|
||||
// 考试完成,考试中心这里任务要完成
|
||||
setTimeout(() => {
|
||||
pagingRef.value.reload();
|
||||
}, 100);
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
## 1.0.1(2023-11-15)
|
||||
1. 修复支付宝小程序报错的BUG
|
||||
## 1.0.0(2023-10-30)
|
||||
1. 新版骨架屏上线
|
||||
@@ -0,0 +1,247 @@
|
||||
<template>
|
||||
<view class="uv-skeleton">
|
||||
<view v-if="loading">
|
||||
<view v-for="(item, index) in elements" :key="index">
|
||||
<!-- 横向并列布局 -->
|
||||
<view class="uv-skeleton__group" :style="[style(item)]" v-if="item.type=='flex'">
|
||||
<view v-for="(item2,index2) in item.children" :class="[item2.clas]" :style="[style(item2)]" :key="index2">
|
||||
<view v-for="(item3,index3) in item2.elements" :key="index3">
|
||||
<!-- 垂直高度站位 -->
|
||||
<view :style="{height: $uv.addUnit(item3.height,'rpx')}" v-if="item3.type=='gap'"></view>
|
||||
<view :class="[item3.clas, roundClass, animateClass]" :style="[style(item3)]" v-else ref="skeleton"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 自定义骨架屏内容 -->
|
||||
<!-- ps 自定义扩展说明: -->
|
||||
<!-- 如果你需要自定义模板,可以参照这个custom的写法,增加一个skeleton配置类型,编写布局和样式就可以了 -->
|
||||
<!-- 注意事项:为了保证骨架效果和动态效果的一致,扩展时,在你希望实际展示在页面中的元素上加上 :class="[style, animateClass]" 和 :style="[style(item)]" 和 ref="skeleton" -->
|
||||
<view :class="[item.clas, animateClass]" :style="[style(item)]" ref="skeleton" v-else-if="item.type == 'custom'"></view>
|
||||
<!-- 垂直高度站位 -->
|
||||
<view :style="{height: $uv.addUnit(item.height,'rpx')}" v-else-if="item.type=='gap'"></view>
|
||||
<!-- 其他基本单位 line avatar 等 -->
|
||||
<view :class="[item.clas, roundClass, animateClass]" :style="[style(item)]" v-else ref="skeleton"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<slot />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
||||
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
||||
// #ifdef APP-NVUE
|
||||
const animation = weex.requireModule('animation');
|
||||
// #endif
|
||||
export default {
|
||||
name: 'uv-skeletons',
|
||||
mixins: [mpMixin, mixin],
|
||||
props: {
|
||||
// 是否显示骨架
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 骨架内容 具体说明参考文档:
|
||||
skeleton: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
// 是否开启动画效果
|
||||
animate: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 是否圆角骨架风格
|
||||
round: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
...uni.$uv?.props?.skeleton
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
elements: [],
|
||||
opacity: 0.5,
|
||||
duration: 600
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
animateClass() {
|
||||
return this.animate ? 'uv-skeleton--animation' : 'uv-skeleton--static';
|
||||
},
|
||||
roundClass() {
|
||||
return this.round ? 'uv-skeleton--round' : 'uv-skeleton--radius';
|
||||
},
|
||||
style(item) {
|
||||
return item => {
|
||||
const style = {};
|
||||
return this.$uv.deepMerge(style, this.$uv.addStyle(item.style));
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init();
|
||||
// #ifdef APP-NVUE
|
||||
if (this.loading && this.animate) {
|
||||
this.$uv.sleep(50).then(res => {
|
||||
this.createAnimation(this.opacity);
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
init() {
|
||||
let elements = [];
|
||||
if (!this.$uv.test.array(this.skeleton)) return this.$uv.error('skeleton参数必须为数组形式,参考文档示例:');
|
||||
this.skeleton.forEach(el => {
|
||||
const elClass = this.getElCounts(el);
|
||||
elements = elements.concat(elClass);
|
||||
})
|
||||
this.elements = [...elements];
|
||||
},
|
||||
/**
|
||||
* 处理骨架屏参数内容
|
||||
* @param {Object} el 每项数据
|
||||
*/
|
||||
getElCounts(el) {
|
||||
let elements = [];
|
||||
let children = [];
|
||||
if (this.$uv.test.number(el)) {
|
||||
elements.push({
|
||||
type: 'gap',
|
||||
height: el
|
||||
});
|
||||
return elements;
|
||||
} else {
|
||||
const type = el.type ? el.type : 'line';
|
||||
const num = el.num ? el.num : 1;
|
||||
const style = el.style ? el.style : {};
|
||||
const styleIsArray = this.$uv.test.array(style);
|
||||
const gap = el.gap ? el.gap : '20rpx';
|
||||
const child = el.children ? el.children : [];
|
||||
for (let i = 0; i < child.length; i++) {
|
||||
children[i] = {
|
||||
clas: child[i].type.indexOf('avatar') > -1 || child[i].type.indexOf('custom') > -1 ? '' : 'uv-skeleton__group__sub',
|
||||
elements: this.getElCounts(child[i])
|
||||
};
|
||||
}
|
||||
for (let i = 0; i < num; i++) {
|
||||
if (gap && i < num && i > 0) {
|
||||
elements.push({
|
||||
type: 'gap',
|
||||
height: gap
|
||||
});
|
||||
}
|
||||
elements.push({
|
||||
clas: `uv-skeleton__${type}`,
|
||||
type,
|
||||
style: styleIsArray ? style[i] : style,
|
||||
gap,
|
||||
children
|
||||
});
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 创建动画
|
||||
*/
|
||||
createAnimation(opacity = 1) {
|
||||
// loading结束之后或未开启动画不执行
|
||||
if (!this.loading || !this.animate) return;
|
||||
let count = 0;
|
||||
const skeletons = this.$refs.skeleton;
|
||||
skeletons.forEach(item => {
|
||||
animation.transition(item, {
|
||||
styles: {
|
||||
opacity: opacity,
|
||||
},
|
||||
duration: this.duration
|
||||
}, () => {
|
||||
count++;
|
||||
if (count >= skeletons.length) {
|
||||
setTimeout(() => {
|
||||
this.createAnimation(opacity < 1 ? 1 : this.opacity);
|
||||
}, 200)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
||||
@mixin background {
|
||||
/* #ifdef APP-NVUE */
|
||||
background-color: #e6e6e6;
|
||||
/* #endif */
|
||||
/* #ifndef APP-NVUE */
|
||||
background: linear-gradient(90deg, #F1F2F4 25%, #e6e6e6 37%, #F1F2F4 50%);
|
||||
background-size: 400% 100%;
|
||||
/* #endif */
|
||||
}
|
||||
.uv-skeleton__line {
|
||||
height: 32rpx;
|
||||
// margin-bottom: 30rpx;
|
||||
}
|
||||
.uv-skeleton__line--sm {
|
||||
height: 24rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
.uv-skeleton__line--lg {
|
||||
height: 48rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
.uv-skeleton--static {
|
||||
@include background;
|
||||
}
|
||||
.uv-skeleton--radius {
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
.uv-skeleton--round {
|
||||
border-radius: 30rpx;
|
||||
}
|
||||
.uv-skeleton__avatar {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50rpx;
|
||||
}
|
||||
.uv-skeleton__avatar--sm {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
border-radius: 25rpx;
|
||||
}
|
||||
.uv-skeleton__avatar--lg {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
border-radius: 100rpx;
|
||||
}
|
||||
.uv-skeleton__group {
|
||||
@include flex;
|
||||
&__sub {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
.uv-skeleton--animation {
|
||||
@include background;
|
||||
/* #ifndef APP-NVUE */
|
||||
animation: skeleton 1.8s ease infinite
|
||||
/* #endif */
|
||||
}
|
||||
/* #ifndef APP-NVUE */
|
||||
@keyframes skeleton {
|
||||
0% {
|
||||
background-position: 100% 50%
|
||||
}
|
||||
100% {
|
||||
background-position: 0 50%
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
</style>
|
||||
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"id": "uv-skeletons",
|
||||
"displayName": "uv-skeletons 骨架屏 全面兼容小程序、nvue、vue2、vue3等多端",
|
||||
"version": "1.0.1",
|
||||
"description": "全新升级骨架屏,更加灵活,体验更加,强烈推荐使用新版骨架屏。一般用于页面在请求远程数据尚未完成时,在内容加载出来前展示与内容布局结构一致的灰白块,提升用户视觉体验。",
|
||||
"keywords": [
|
||||
"uv-skeletons",
|
||||
"uvui",
|
||||
"uv-ui",
|
||||
"skeleton",
|
||||
"骨架屏"
|
||||
],
|
||||
"repository": "",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0"
|
||||
},
|
||||
"dcloudext": {
|
||||
"type": "component-vue",
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "插件不采集任何数据",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [
|
||||
"uv-ui-tools",
|
||||
"uv-text"
|
||||
],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
},
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "y"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y",
|
||||
"钉钉": "u",
|
||||
"快手": "u",
|
||||
"飞书": "u",
|
||||
"京东": "u"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
# Skeletons 新版骨架屏
|
||||
|
||||
> **组件名:uv-skeletons**
|
||||
|
||||
骨架屏一般用于页面在请求远程数据尚未完成时,在内容加载出来前展示与内容布局结构一致的灰白块,提升用户视觉体验。
|
||||
|
||||
新版骨架屏与老版本使用参数有很大的区别,所以才有了新版本,无法替换老版本。
|
||||
|
||||
新版骨架屏比老版本骨架屏更加灵活,理论上简单的左右上下布局结构均可以轻松实现,样式自由度较高,只要你会写css,推荐使用新版。
|
||||
|
||||
# <a href="https://www.uvui.cn/components/skeletons.html" target="_blank">查看文档</a>
|
||||
|
||||
## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small>(请不要 下载插件ZIP)</small>
|
||||
|
||||
### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
||||
|
||||
<a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank">
|
||||
|
||||

|
||||
|
||||
</a>
|
||||
|
||||
#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>
|
||||
Reference in New Issue
Block a user