Merge branch 'develop' into 'sit'

Develop

See merge request K17_AITS/tra-app!11
This commit is contained in:
田岩
2025-07-11 16:14:02 +08:00
17 changed files with 467 additions and 344 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
package-lock
package-lock.json
node_modules
.DS_Store
dist
+3 -2
View File
@@ -6,8 +6,8 @@
"dev:h5": "uni",
"dev:h5:sit": "uni -p h5 --mode sit",
"dev:h5:uat": "uni -p h5 --mode uat",
"dev:h5:production": "uni -p h5 --mode production",
"build:app-plus:dev": "uni build -p app-plus --mode development",
"dev:h5:production": "uni -p h5 --mode production",
"build:app-plus:dev": "uni build -p app-plus --mode development",
"build:app-plus:sit": "uni build -p app-plus --mode sit",
"build:app-plus:uat": "uni build -p app-plus --mode uat",
"build:app-plus": "uni build -p app-plus",
@@ -31,6 +31,7 @@
"@dcloudio/uni-mp-xhs": "3.0.0-4060620250520001",
"@dcloudio/uni-quickapp-webview": "3.0.0-4060620250520001",
"crypto-js": "^3.1.9-1",
"markdown-it": "^14.1.0",
"pinia": "^2.3.1",
"terser": "^5.42.0",
"uuid": "^11.1.0",
+3 -2
View File
@@ -59,8 +59,9 @@ const navigateBack = (delta = 1, fun = () => {}) => {
}
//关闭当前页面,跳转到应用内的某个页面。
const redirectTo = url => uni.redirectTo({
url: url
const redirectTo = (url, obj = {}) => uni.redirectTo({
url: url,
...obj
});
// 时间转换时间戳
+41 -5
View File
@@ -1,5 +1,12 @@
<template>
<image :src="imgUrlShow" fit="cover" :mode="mode"></image>
<view v-bind="$attrs">
<image :src="imgUrlShow" fit="cover" :mode="mode" @click="showDetail" style="width: 100%;height: 100%;"></image>
<uv-overlay :show="showModel" opacity=".6" @click="showModel = false">
<view class="overlay-box">
<image class="detail-img" :src="imgUrlShow" fit="cover" :mode="mode"></image>
</view>
</uv-overlay>
</view>
</template>
<script>
@@ -35,12 +42,17 @@
type: String,
default: 'widthFix'
},
previewDetail: {
default: '',
type:[String, Boolean]
}
},
data() {
return {
imgUrlShow: '',
watching: false,
base_url: get_base_url()
base_url: get_base_url(),
showModel: false
};
},
computed:{
@@ -52,6 +64,10 @@
watch: {
imgId: {
handler(newval, oldval) {
if(newval.indexOf('http') === 0){
this.imgUrlShow = newval
return
}
if (newval && this.watching) {
this.getPreviewUrlBlob(newval);
}
@@ -70,6 +86,11 @@
}
},
methods: {
showDetail(){
if(!!this.previewDetail){
this.showModel = true
}
},
getPreviewUrlBlob(id) {
if (!id) {
this.imgUrlShow = ''
@@ -107,7 +128,11 @@
},
mounted() {
if (this.imgId) {
this.getPreviewUrlBlob(this.imgId);
if(this.imgId.indexOf('http') === 0){
this.imgUrlShow = this.imgId
}else{
this.getPreviewUrlBlob(this.imgId);
}
}
this.watching = true
if(this.src) {
@@ -117,6 +142,17 @@
}
</script>
<style>
<style lang="scss" scoped>
.overlay-box{
position: relative;
height: 100%;
.detail-img{
position: absolute;
left: 50%;
top: 50%;
max-width: 100%;
max-height: 100%;
transform: translate(-50%, -50%);
}
}
</style>
@@ -30,6 +30,10 @@
watch: {
fileId: {
handler(newval, oldval) {
if(newval.indexOf('http:') === 0){
this.fileUrlShow = newval
return
}
if (newval && this.watching) {
this.getPreviewUrlBlob(newval);
}
@@ -57,7 +61,11 @@
},
mounted() {
if (this.fileId) {
this.getPreviewUrlBlob(this.fileId);
if(this.fileId.indexOf('http:') === 0){
this.fileUrlShow = this.fileId
}else{
this.getPreviewUrlBlob(this.fileId);
}
}
this.watching = true
},
@@ -5,11 +5,18 @@
</template>
<script>
// import {Marked} from 'marked';
import MarkdownIt from 'markdown-it';
export default {
name:"markdown-preview",
props: {
mdString: {
default:`在客服交流中使用标准术语是提高专业形象和服务质量的重要手段。以下是一些常见的客服标准用语及其适用场景:
default:`## 我是二级标题
### 我是三级标题
| 我是表头 | 表头 2 |
| :----------- | :----------- |
|1|2|
在客服交流中使用标准术语是提高专业形象和服务质量的重要手段。以下是一些常见的客服标准用语及其适用场景:
1. **问候与介绍:**
- “您好,欢迎来到[公司名称],我是您的客服代表[姓名],很高兴为您服务。”
@@ -41,20 +48,34 @@
},
data() {
return {
contentHtml:''
contentHtml:'',
mdObj:null
};
},
watch:{
mdString: {
handler(val){
this.contentHtml = this.parseContent(val)
},
deep: true,
immediate: true
}
},
methods:{
parseContent(text){
if(this.mdObj){
return this.mdObj.render(text)
}else{
setTimeout(()=>{
return this.parseContent(text)
},500)
}
}
},
mounted(){
this.mdObj = new MarkdownIt()
this.contentHtml = this.parseContent(this.mdString)
console.log(this.contentHtml)
}
}
</script>
@@ -52,7 +52,13 @@
mark: {
type: [String, Number],
default: ''
}
},
fileType: {
type: Array,
default: function() {
return ['jpg', 'png']
}
},
})
// 状态管理
const fileList = reactive([])
@@ -105,13 +111,22 @@
success: async ({
tempFilePaths
}) => {
const valid = tempFilePaths.every(url => {
if (props.fileType.length === 0) return true;
console.log(url);
const lastDotIndex = url.lastIndexOf('.')
if (lastDotIndex === -1) return false;
const extension = url.slice(lastDotIndex + 1).split('?')[0].toLowerCase()
return props.fileType.includes(extension)
})
if (!valid) return common.msg('您选择的图片格式有误。')
console.log(valid)
const data = {
bizScen: 'S3005'
}
console.log(tempFilePaths[0]);
const upload_map = tempFilePaths.map((file) => uploadFile(file, data))
Promise.all(upload_map).then(res => {
fileList.push(...res)
fileList.push(...res.splice(0, props.limit - fileList.length))
emits('update:modelValue', fileList.map(res => res.fileId))
}).catch(() => {
+4 -2
View File
@@ -24,7 +24,7 @@
{{ showContent }}
</text>
<view v-if="type === 3">
<ImagePreview class="cont-img-box" v-if="(dataInfo.imageAddrs||[]).length>0" :imgId="dataInfo.imageAddrs[0]"></ImagePreview>
<ImagePreview class="cont-img-box" v-if="(dataInfo.imageAddrs||[]).length>0" :imgId="dataInfo.imageAddrs[0]" :previewDetail="true"></ImagePreview>
<VideoPreview class="cont-img-box" v-if="(dataInfo.vidoAddrs||[]).length>0" :imgId="dataInfo.vidoAddrs[0]"></VideoPreview>
</view>
<view v-if="type === 5 && !dataInfo.isLoading" style="padding-top: 16rpx;">
@@ -317,9 +317,11 @@ const audioCacheObj = computed(() => storageStore.audioObj)
// 重播
const restartPlay = () => {
if(itemVoice.value){
emit('changePlay', '')
emit('changePlay', unref(dataInfo)?.id)
setTimeout(()=>{
talkVoiceObj.value.src = itemVoice.value
talkVoiceObj.value.seek(0)
talkVoiceObj.value.play()
},100)
}else{
@@ -335,7 +337,7 @@ const audioCacheObj = computed(() => storageStore.audioObj)
}
// readType 阅读内容类型pgrh段落/qns问题
emit('changePlay', unref(dataInfo)?.id)
if(talkVoiceObj.value.src === itemVoice.value) {
if(talkVoiceObj.value.src && talkVoiceObj.value.src === itemVoice.value) {
talkVoiceObj.value.play()
return
}
+3 -1
View File
@@ -9,7 +9,7 @@
>按住说话
</view>
<view class="touch-btn" v-if="keyboardIsShow">
<uv-input class="input-box" ref="inputRef" v-model.trim="answerValue" maxlength="1000"
<uv-input class="input-box" ref="inputRef" v-model.trim="answerValue" maxlength="500"
placeholderStyle='color:#999999;font-size:26rpx' placeholder="请输入答案">
</uv-input>
</view>
@@ -60,6 +60,7 @@ const recordObjCom = uni.getRecorderManager()
const initRecord = () => {
unref(recordObjCom)?.onStop((res, duration)=>{
audioPath.value = res.tempFilePath
console.log(duration)
})
}
const startRecord = () => {
@@ -112,6 +113,7 @@ const showOverlayTalking = (obj) => {
}
}
const hideOverlayTalking = (obj) => {
if(!showTalkingModel.value) return
showTalkingModel.value = false
//#ifdef APP-PLUS
stopRecord()
+3 -8
View File
@@ -167,16 +167,11 @@ import { onMounted, ref, computed } from 'vue'
}
// 点击生产线分类
const changePrdLine = (item)=>{
activePrdlineType.value = item.value
activePrdlineType.value = item.value === activePrdlineType.value ? '' : item.value
}
// 点击课程分类
const changeCourseType = (item)=>{
activeCourseType.value = item.value
setTimeout(()=>{
console.log(courseListTreeShow.value)
})
activeCourseType.value = item.value === activeCourseType.value ? '' : item.value
}
const showTypeName = computed(()=>{
return (activeTab.value === '全部' && activeCourseType.value === '') || (activeTab.value === '生产线' && activePrdlineType.value === '')
@@ -241,7 +236,7 @@ import { onMounted, ref, computed } from 'vue'
const changeTab = (item) => {
if(!item) return
activeTab.value = item.name
activeTag.value = ''
// activeTag.value = ''
activeCourseType.value = ''
activePrdlineType.value = ''
switch (item.name){
+24 -20
View File
@@ -21,7 +21,8 @@
<view class="right-name">{{item.teacherName}}</view>
<view class="right-desc">描述{{item.voiceDesc || '--'}}</view>
<view class="audio-box">
<view :class="['talking-gif', activeVoiceTeachNo === item.teacherNo ? 'is-play':'']"></view>
<view :class="['talking-gif', activeVoiceTeachNo === item.teacherNo && !loadingTeacherVoice ? 'is-play':'']"></view>
<CommonLoading color="#06f" v-show="activeVoiceTeachNo === item.teacherNo && loadingTeacherVoice" style="float: left;"/>
<view class="play-btn" @click="playTeacherVoice(item)">
<image class="icon" v-if="activeVoiceTeachNo !== item.teacherNo" src="@/static/images/course/play-blue.png" style="width: 100%;height: 100%;"></image>
<image class="icon" v-else src="@/static/images/course/stop-blue.png" style="width: 100%;height: 100%;"></image>
@@ -243,6 +244,7 @@ teacherVoiceObj.onEnded(()=>{
activeVoiceTeachNo.value = ''
teacherVoiceObj.src = ''
})
const loadingTeacherVoice = ref(false)
const playTeacherVoice = (item) =>{
teacherVoiceObj.stop()
teacherVoiceObj.src = ''
@@ -253,12 +255,15 @@ const playTeacherVoice = (item) =>{
teacherVoiceObj.src = item.voicePath
teacherVoiceObj.play()
}else{
loadingTeacherVoice.value = true
storageStore.getStorageById('audio', item.teacherNo, (url)=>{
if(url){
teacherVoiceObj.src = _cache
teacherVoiceObj.src = url
teacherVoiceObj.play()
loadingTeacherVoice.value = false
}else{
downloadVoiceFile('/trastudy/traStdyInfo/trialListening?teachNo='+item.teacherNo).then(res=>{
loadingTeacherVoice.value = false
item.voicePath = res.tempFilePath
teacherVoiceObj.src = item.voicePath
teacherVoiceObj.play()
@@ -534,12 +539,13 @@ onLoad((params) => {
crsId.value = params.crsId||'';
crsNum.value = params.crsNum||'';
startPgrphId.value = params.pgrphId||'';
getData('1');
});
const showTalkingModel = ref(false)
// 录音
onMounted(()=>{
getData('1');
})
// onMounted(()=>{
// getData('1');
// })
// onShow(()=>{
// getData('2');
// })
@@ -675,17 +681,6 @@ const withdrawNow = (data) => {
const loadingQstLogId = ref('')
// 完成
const finishQuestionNow = (data) => {
let _id1 = new Date().getTime() + 'id'
talkingList.value.push({
id: _id1,
talkingContent: '完成',
userInfo: {...choiceTeacherInfo.value},
type: 0
})
// waitMakeEvaluateApi({
// qstLogId: data.qstLogId
// })
textChartApi({
processType: 'ANSER-OVER',
requestBody: JSON.stringify({
@@ -694,6 +689,18 @@ const finishQuestionNow = (data) => {
})
.then(res=> {
// common.msg('完成成功,开始获取评分维度数据!')
let _state = res.body.chatBody.processStat
if(_state = 'ER'){
common.msg('提交答案失败!')
return
}
let _id1 = new Date().getTime() + 'id'
talkingList.value.push({
id: _id1,
talkingContent: '完成',
userInfo: {...choiceTeacherInfo.value},
type: 0
})
loadingQstLogId.value = res.body.chatBody.qstLogId
qstLogId.value = loadingQstLogId.value
let _id = new Date().getTime() + 'id'
@@ -711,10 +718,6 @@ const finishQuestionNow = (data) => {
// 查询问题回答评分
const getQuestionEvalateRequest = (id, data) => {
if(loadingQstLogId.value){
// queryQuestionEvalateApi({
// qstLogId:loadingQstLogId.value
// })
textChartApi({
processType: 'ANSER-RESULT',
requestBody: JSON.stringify({
@@ -957,6 +960,7 @@ const chooseRateNow = (item) => {
.talking-gif{
width: 140rpx;
height: 40rpx;
margin-right: 20rpx;
// background-color: #ccc;
background: url(@/static/images/course/voice-gray.png) no-repeat;
background-size: 100%;
@@ -5,9 +5,9 @@
<view class="blue-ball">
<view class="ball"></view>
</view>
<view class="fz-30 font_pf title">知识点0{{ index + 1 }}</view>
<view class="fz-30 font_pf title">知识点{{ item.pgrphNm }}</view>
<view class="fl1">
</view>
<view class="font_pf fz-24 study-status" >
{{ item.pgrphStdyStateName }}
@@ -21,14 +21,24 @@
</template>
<script setup>
import {computed} from "vue"
import common from '@/common/common';
const emit = defineEmits(['toStudyPrgh'])
const props = defineProps({
modelValue: Object
})
const min_no_success_id = computed(() => {
const find_item = props.modelValue?.pgrphData.find(res => (res.pgrphStdyStateName == '未学习' || res.pgrphStdyStateName == '学习中'))
return find_item?.pgrphId || ''
})
const toDetail = (item) => {
emit('toStudyPrgh', item)
if (item.pgrphStdyStateName == '已学习' || item.pgrphStdyStateName == '学习中' || min_no_success_id.value == item.pgrphId) {
emit('toStudyPrgh', item)
} else {
common.msg('请按顺序学习知识点')
}
}
</script>
+1
View File
@@ -82,6 +82,7 @@
import {
getCourseDetailApi
} from '@/api/courseDetail.js';
import common from '@/common/common';
import introduceVue from './components/introduce.vue';
import knowledge from './components/knowledge.vue';
+2 -4
View File
@@ -37,7 +37,7 @@
</view>
<view class="input-textarea">
<uv-textarea v-model="formData.bbsContent" height="124" count
:maxlength="TextareaInputLimitCharacter"
:maxlength="100"
:placeholder="formData.bbsTag == 'SUG'?'请输入你的建议...':'请输入你的问题...'"></uv-textarea>
</view>
</view>
@@ -53,9 +53,7 @@
reactive,
ref
} from 'vue';
import {
TextareaInputLimitCharacter
} from "@/enum.js"
import {
onLoad
} from '@dcloudio/uni-app';
+5 -2
View File
@@ -1,8 +1,11 @@
<template>
<view>AI问答</view>
<view>
<MarkdownPreview/>
</view>
</template>
<script>
<script setup>
import MarkdownPreview from '@/components/markdown-preview/markdown-preview.vue';
</script>
<style>
+2 -2
View File
@@ -21,7 +21,7 @@
</view>
<!-- 文字logo -->
<view class="title_logo" @click="common.navigateTo('/pages/login/login')">
<view class="title_logo">
<image src="@/static/images/index/logo_text.png" class="log_img"></image>
<view class="fl1"></view>
</view>
@@ -84,7 +84,7 @@
<image class="icon" src="@/static/images/index/navigation_course.png"></image>
<view class="title">课程中心</view>
</view>
<view class="item">
<view class="item" @click="common.navigateTo('/pages/index/dialog',{ animationType: 'slide-in-bottom'})">
<image class="icon" src="@/static/images/index/navigation_question_answering.png"></image>
<view class="title">AI问答</view>
</view>
+310 -284
View File
@@ -10,7 +10,8 @@
<view class="profile">
<!-- <image-preview v-if="user_info.imageAddr" class="img_100" :src="user_info.imageAddr"></image-preview> -->
<image v-if="user_info.imagePath" class="img_100" :src="user_info.imagePath"></image>
<image-preview v-else-if="user_info.imageAddr" class="img_100" :src="user_info.imageAddr"></image-preview>
<image-preview v-else-if="user_info.imageAddr" class="img_100"
:src="user_info.imageAddr"></image-preview>
<image v-else class="img_100" src="/static/images/me/default_user_avatar.png"></image>
</view>
<view class="personal_information_data">
@@ -19,8 +20,10 @@
{{ user_info.userName }}
</view>
<view class="sex">
<image v-if="user_info.gender === 'f'" class="img_100" src="/static/images/me/wuman.png"></image>
<image v-if="user_info.gender === 'm'" class="img_100" src="/static/images/me/man.png"></image>
<image v-if="user_info.gender === 'f'" class="img_100"
src="/static/images/me/wuman.png"></image>
<image v-if="user_info.gender === 'm'" class="img_100" src="/static/images/me/man.png">
</image>
</view>
</view>
<view class="work_number_div">工号{{ user_info.userId }}</view>
@@ -32,31 +35,25 @@
<view class="item">
<view class="top">累计学习时长</view>
<view class="bottom">
<uv-count-to
:startVal="statistics_data['startAccmPoint']"
:endVal="statistics_data['accmPoint']"
:useEasing="true"
:decimals="1"
ref="accmPointRef"
></uv-count-to>
h
<uv-count-to :startVal="statistics_data['startStdtTmLen']"
:endVal="statistics_data['stdtTmLen']" :useEasing="true" :decimals="1"
ref="stdtTmLenRef"></uv-count-to>h
</view>
</view>
<view class="item">
<view class="top">累计完成任务</view>
<view class="bottom">
<uv-count-to
:startVal="statistics_data['startAccmTaskCnt']"
:endVal="statistics_data['accmTaskCnt']"
:useEasing="true"
ref="accmTaskCntRef"
></uv-count-to>
<uv-count-to :startVal="statistics_data['startAccmTaskCnt']"
:endVal="statistics_data['accmTaskCnt']" :useEasing="true"
ref="accmTaskCntRef"></uv-count-to>
</view>
</view>
<view class="item">
<view class="top">累计获得积分</view>
<view class="bottom">
<uv-count-to :startVal="statistics_data['startStdtTmLen']" :endVal="statistics_data['stdtTmLen']" :useEasing="true" ref="stdtTmLenRef"></uv-count-to>
<uv-count-to :startVal="statistics_data['startAccmPoint']"
:endVal="statistics_data['accmPoint']" :useEasing="true"
ref="accmPointRef"></uv-count-to>
</view>
</view>
</view>
@@ -94,8 +91,9 @@
<view class="cell_div">
<uv-cell-group :border="false">
<uv-cell title="设置" :isLink="true" @click="common.navigateTo('/pages/setting/index')"></uv-cell>
<uv-cell title="客服" :isLink="true" @click="common.navigateTo('/pages/test/index')"></uv-cell>
<uv-cell title="退出登录" :isLink="true" :clickable="false" :border="false" @click="click_loginout()"></uv-cell>
<uv-cell title="客服" :isLink="true" @click="goTest"></uv-cell>
<uv-cell title="退出登录" :isLink="true" :clickable="false" :border="false"
@click="click_loginout()"></uv-cell>
</uv-cell-group>
</view>
<tabbar-shadow></tabbar-shadow>
@@ -103,297 +101,325 @@
</template>
<script setup>
import { ref, computed, reactive } from 'vue';
import { onShow } from '@dcloudio/uni-app';
import common from '@/common/common';
import { getUserInfo } from '@/common/common';
import { onPullDownRefresh } from '@dcloudio/uni-app';
import { loginOut } from '@/api/login.js';
import { queryTraStdyStatisticsSelf } from '@/api/user.js';
import { useSocketStore } from "@/store/socket.js"
const socketStore = useSocketStore()
import {
ref,
computed,
reactive
} from 'vue';
import {
onShow
} from '@dcloudio/uni-app';
import common from '@/common/common';
import {
getUserInfo
} from '@/common/common';
import {
onPullDownRefresh
} from '@dcloudio/uni-app';
import {
loginOut
} from '@/api/login.js';
import {
queryTraStdyStatisticsSelf
} from '@/api/user.js';
import {
useSocketStore
} from "@/store/socket.js"
const socketStore = useSocketStore()
const accmTaskCntRef = ref(null);
const accmPointRef = ref(null);
const stdtTmLenRef = ref(null);
const statistics_data = reactive({
stdtTmLen: 0, //
accmTaskCnt: 0, //
accmPoint: 0, //
startStdtTmLen: 0, //
startAccmTaskCnt: 0, //
startAccmPoint: 0, //
request_time: 0, //
init: function () {
//
const me_statistics_data = common.getValue('me_statistics_data'); //
if (me_statistics_data) {
this.stdtTmLen = me_statistics_data.stdtTmLen;
this.accmTaskCnt = me_statistics_data.accmTaskCnt;
this.accmPoint = me_statistics_data.accmPoint;
}
},
get_statistics_data: async function () {
try {
const time_now = Date.now();
if (time_now - this.request_time > 300) {
this.request_time = time_now;
//
const res = await queryTraStdyStatisticsSelf();
common.setValue('me_statistics_data', res.body);
const accmPoint = res.body.accmPoint;
const accmTaskCnt = res.body.accmTaskCnt;
const stdtTmLen = res.body.stdtTmLen;
if (accmPoint != this.accmPoint) {
//
this.startAccmPoint = this.accmPoint;
this.accmPoint = accmPoint;
accmPointRef.value.start();
const accmTaskCntRef = ref(null);
const accmPointRef = ref(null);
const stdtTmLenRef = ref(null);
const statistics_data = reactive({
stdtTmLen: 0, //
accmTaskCnt: 0, //
accmPoint: 0, //
startStdtTmLen: 0, //
startAccmTaskCnt: 0, //
startAccmPoint: 0, //
request_time: 0, //
init: function() {
//
const me_statistics_data = common.getValue('me_statistics_data'); //
if (me_statistics_data) {
this.stdtTmLen = me_statistics_data.stdtTmLen;
this.accmTaskCnt = me_statistics_data.accmTaskCnt;
this.accmPoint = me_statistics_data.accmPoint;
}
},
get_statistics_data: async function() {
try {
const time_now = Date.now();
if (time_now - this.request_time > 300) {
this.request_time = time_now;
//
const res = await queryTraStdyStatisticsSelf();
common.setValue('me_statistics_data', res.body);
const accmPoint = res.body.accmPoint;
const accmTaskCnt = res.body.accmTaskCnt;
const stdtTmLen = res.body.stdtTmLen;
if (accmPoint != this.accmPoint) {
//
this.startAccmPoint = this.accmPoint;
this.accmPoint = accmPoint;
accmPointRef.value.start();
}
if (accmTaskCnt != this.accmTaskCnt) {
//
this.startAccmTaskCnt = this.accmTaskCnt;
this.accmTaskCnt = accmTaskCnt;
accmTaskCntRef.value.start();
}
if (stdtTmLen != this.stdtTmLen) {
//
this.startStdtTmLen = this.stdtTmLen;
this.stdtTmLen = stdtTmLen;
stdtTmLenRef.value.start();
}
console.log('统计数据已更新');
} else {
console.log('时间没到无需更新');
}
if (accmTaskCnt != this.accmTaskCnt) {
//
this.startAccmTaskCnt = this.accmTaskCnt;
this.accmTaskCnt = accmTaskCnt;
accmTaskCntRef.value.start();
}
if (stdtTmLen != this.stdtTmLen) {
//
this.startStdtTmLen = this.stdtTmLen;
this.stdtTmLen = stdtTmLen;
stdtTmLenRef.value.start();
}
console.log('统计数据已更新');
} else {
console.log('时间没到无需更新');
} catch (error) {
console.error('获取统计数据失败:', error);
}
} catch (error) {
console.error('获取统计数据失败:', error);
}
}
});
const user_info = reactive({
userName: '',
userId: '',
imageAddr: '',
});
onShow(() => {
const user_info_cache = getUserInfo();
Object.assign(user_info, user_info_cache);
console.log('user_info', user_info);
statistics_data['get_statistics_data'](); //
});
const click_loginout = () => {
common.show('确定退出登录?').then(async (res) => {
console.log(res);
if (!res) return;
try {
common.loading('正在退出登录');
socketStore.closeSocket()
await loginOut();
} catch (e) {}
common.hideLoading();
// 退
common.reLaunch('/pages/login/login');
});
};
onPullDownRefresh(() => {
console.log('下拉刷新');
uni.stopPullDownRefresh();
});
const user_info = reactive({
userName: '',
userId: '',
imageAddr: '',
});
const goTest = () => {
const now = Date.now();
if (now - lastClickTime.value > 500) {
clickCount.value = 0;
}
clickCount.value++;
lastClickTime.value = now;
if (clickCount.value == 6) {
common.navigateTo('/pages/test/index');
clickCount.value = 0;
}
};
const click_loginout = () => {
common.show('确定退出登录?').then(async (res) => {
console.log(res);
if (!res) return;
try {
common.loading('正在退出登录');
socketStore.closeSocket()
await loginOut();
} catch (e) {}
common.hideLoading();
// 退
common.reLaunch('/pages/login/login');
});
};
onShow(() => {
const user_info_cache = getUserInfo();
Object.assign(user_info, user_info_cache);
console.log('user_info', user_info);
statistics_data['get_statistics_data'](); //
});
onPullDownRefresh(() => {
console.log('下拉刷新');
uni.stopPullDownRefresh();
});
</script>
<style scoped lang="scss">
$bg-margin-left: 50rpx;
$bg-margin-left: 50rpx;
//
.cell_div {
margin: 30rpx $bg-margin-left 0 $bg-margin-left;
background: #ffffff;
border-radius: 15rpx;
z-index: 101;
overflow: hidden;
//
.cell_div {
margin: 30rpx $bg-margin-left 0 $bg-margin-left;
background: #ffffff;
border-radius: 15rpx;
z-index: 101;
overflow: hidden;
// 线24
:deep(.uv-line) {
width: calc(100% - 48rpx) !important;
margin: 0 24rpx !important;
// 线24
:deep(.uv-line) {
width: calc(100% - 48rpx) !important;
margin: 0 24rpx !important;
}
:deep(.uv-cell__body) {
padding: 12px 15px;
}
}
:deep(.uv-cell__body) {
padding: 12px 15px;
}
}
//
.navigation_div {
margin: 30rpx $bg-margin-left 0 $bg-margin-left;
padding: 24rpx 0 20rpx 0;
background-color: #ffffff;
border-radius: 23rpx;
display: flex;
flex-direction: column;
justify-content: space-around;
z-index: 101;
.group {
display: flex;
justify-content: space-around;
}
.item {
//
.navigation_div {
margin: 30rpx $bg-margin-left 0 $bg-margin-left;
padding: 24rpx 0 20rpx 0;
background-color: #ffffff;
border-radius: 23rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
justify-content: space-around;
z-index: 101;
// background-color: red;
.icon {
width: 88rpx;
height: 86rpx;
}
.title {
margin-top: 10rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 25rpx;
color: #323e57;
line-height: 35rpx;
text-align: left;
font-style: normal;
}
}
}
.bg_div {
display: flex;
flex-direction: column;
position: relative;
padding: 0 $bg-margin-left;
z-index: 50;
.bg_img {
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: -1;
height: 858rpx;
}
//
.user_data_div {
margin-top: 158rpx;
background: linear-gradient(180deg, rgba(241, 245, 255, 0.5) 0%, #f6f9fe 50%, #ffffff 100%);
border-radius: 14rpx;
border: 2rpx solid #ffffff;
box-shadow: #f6f8ff 0 0 2rpx;
.personal_information {
padding: 20rpx 18rpx 0 26rpx;
display: flex;
//
.profile {
border-radius: 100%;
border: 2px solid #ffffff;
width: 108rpx;
height: 108rpx;
overflow: hidden;
}
//
.personal_information_data {
flex: 1;
display: flex;
flex-direction: column;
margin-left: 26rpx;
overflow: hidden;
//
.name_sex_div {
display: flex;
margin-top: 6rpx;
.name {
font-family: PingFangSC;
font-weight: 600;
font-size: 28rpx;
color: #000000;
line-height: 40rpx;
}
.sex {
margin-left: 10rpx;
width: 30rpx;
height: 30rpx;
}
}
.work_number_div {
font-family: PingFangSC;
font-weight: 400;
font-size: 25rpx;
color: #666666;
line-height: 38rpx;
text-align: left;
font-style: normal;
white-space: nowrap;
text-overflow: ellipsis;
}
}
}
.study_information {
.group {
display: flex;
justify-content: space-around;
z-index: 20;
margin: 30rpx 50rpx;
}
.item {
flex: 1;
.item {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
// background-color: red;
.icon {
width: 88rpx;
height: 86rpx;
}
.title {
margin-top: 10rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 25rpx;
color: #323e57;
line-height: 35rpx;
text-align: left;
font-style: normal;
}
}
}
.bg_div {
display: flex;
flex-direction: column;
position: relative;
padding: 0 $bg-margin-left;
z-index: 50;
.bg_img {
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: -1;
height: 858rpx;
}
//
.user_data_div {
margin-top: 158rpx;
background: linear-gradient(180deg, rgba(241, 245, 255, 0.5) 0%, #f6f9fe 50%, #ffffff 100%);
border-radius: 14rpx;
border: 2rpx solid #ffffff;
box-shadow: #f6f8ff 0 0 2rpx;
.personal_information {
padding: 20rpx 18rpx 0 26rpx;
display: flex;
flex-direction: column;
justify-content: center;
.top {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 25rpx;
color: #666666;
line-height: 35rpx;
text-align: center;
font-style: normal;
//
.profile {
border-radius: 100%;
border: 2px solid #ffffff;
width: 108rpx;
height: 108rpx;
overflow: hidden;
}
.bottom {
margin-top: 5%;
font-weight: bold;
font-size: 50rpx;
color: #000000;
line-height: 58rpx;
text-align: left;
font-style: normal;
text-align: center;
//
.personal_information_data {
flex: 1;
display: flex;
flex-direction: column;
margin-left: 26rpx;
overflow: hidden;
//
:deep(.uv-count-num) {
font-weight: bold !important;
font-size: 50rpx !important;
color: #000000 !important;
//
.name_sex_div {
display: flex;
margin-top: 6rpx;
.name {
font-family: PingFangSC;
font-weight: 600;
font-size: 28rpx;
color: #000000;
line-height: 40rpx;
}
.sex {
margin-left: 10rpx;
width: 30rpx;
height: 30rpx;
}
}
.work_number_div {
font-family: PingFangSC;
font-weight: 400;
font-size: 25rpx;
color: #666666;
line-height: 38rpx;
text-align: left;
font-style: normal;
white-space: nowrap;
text-overflow: ellipsis;
}
}
}
.study_information {
display: flex;
justify-content: space-around;
z-index: 20;
margin: 30rpx 50rpx;
.item {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
.top {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 25rpx;
color: #666666;
line-height: 35rpx;
text-align: center;
font-style: normal;
}
.bottom {
margin-top: 5%;
font-weight: bold;
font-size: 50rpx;
color: #000000;
line-height: 58rpx;
text-align: left;
font-style: normal;
text-align: center;
//
:deep(.uv-count-num) {
font-weight: bold !important;
font-size: 50rpx !important;
color: #000000 !important;
}
}
}
}
}
}
}
.main_div {
display: flex;
flex-direction: column;
background-color: #f6f8ff;
}
</style>
.main_div {
display: flex;
flex-direction: column;
background-color: #f6f8ff;
}
</style>