JLBA202505130001_关于吉林银行新建AI智能培训系统的需求_和杨航一起合并的代码,他承认

This commit is contained in:
田岩
2026-01-26 08:53:20 +08:00
24 changed files with 684 additions and 172 deletions
+3 -2
View File
@@ -4,7 +4,7 @@ ENV = 'development'
#VITE_APP_BASE_API_Url = 'https://aits.jlbank.com.cn:7002'
#VITE_APP_BASE_API_Url = 'https://aits.jlbank.com.cn:7001'
VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7001'
@@ -17,6 +17,7 @@ VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7001'
# DEV
#VITE_APP_BASE_API_Url = 'http://25.18.122.65:7001'
# sit
#VITE_APP_BASE_API_Url = 'http://25.18.122.91:9786'
@@ -42,7 +43,7 @@ VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7001'
# VITE_APP_BASE_H5_API_Url = 'http://25.18.122.78:9786'
# VITE_APP_BASE_H5_API_Url_TRAAPP = 'http://25.64.32.150:9601'
#VITE_APP_BASE_H5_API_Url_TRAAPP = 'http://25.64.32.154:9601'
# VITE_APP_BASE_H5_API_Url_TRASTUDY = 'http://25.64.16.130:9602'
# VITE_APP_BASE_H5_API_Url_TRAASK = 'http://25.64.16.144:9605'
+2 -2
View File
@@ -4,8 +4,8 @@ ENV = 'development.yh'
# VITE_APP_BASE_H5_API_Url = 'http://25.18.122.65:7001'
# VITE_APP_BASE_H5_API_Url = 'http://25.18.122.91:9786'
VITE_APP_BASE_H5_API_Url = 'http://25.18.122.78:9786'
VITE_APP_BASE_H5_API_Url = 'http://25.18.122.91:9786'
# VITE_APP_BASE_H5_API_Url = 'http://25.18.122.78:9786'
# VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7002'
# VITE_APP_BASE_H5_API_Url_TRAEXAM = 'http://25.64.32.154:9604'
# VITE_APP_BASE_H5_API_Url_TRAPRACTICE = 'http://25.64.32.156:9603'
+86 -76
View File
@@ -3,101 +3,111 @@ import request from '@/api/request'
// 获取首页统计数据方法(查询个人学习统计信息 )
export const getStatisticsData = (data) => {
/**
userId 学员ID String
stdtTmLen 本年学习时长 double
accmPracticeCnt 累计训练次数 int
accmExamCnt 累计考试次数 int
**/
return request({
url: '/traapp/traStdyInfo/queryTraStdyStatisticsPerson',
method: 'post',
data
});
/**
userId 学员ID String
stdtTmLen 本年学习时长 double
accmPracticeCnt 累计训练次数 int
accmExamCnt 累计考试次数 int
**/
return request({
url: '/traapp/traStdyInfo/queryTraStdyStatisticsPerson',
method: 'post',
data
});
};
// 最新课程查询接口
export const queryCrsInfoByLastnew = (data) => {
/**
crsNum 课程编号 String
crsName 课程名称 String
tagId 课程分类 String
prdLineId 生产线分类 String
issuTm 发布日期 String
imgId 课程封面ID String
accmStdyCnt 累计学习次数 int
evalGrade 课程评分 Bigdecimal
tagCataList 课程标签集 List<Object>
tagId 标签ID String
tagName 标签名称 String
**/
return request({
url: '/traapp/mycrs/queryCrsInfoByLastnew',
method: 'post',
data
});
/**
crsNum 课程编号 String
crsName 课程名称 String
tagId 课程分类 String
prdLineId 生产线分类 String
issuTm 发布日期 String
imgId 课程封面ID String
accmStdyCnt 累计学习次数 int
evalGrade 课程评分 Bigdecimal
tagCataList 课程标签集 List<Object>
tagId 标签ID String
tagName 标签名称 String
**/
return request({
url: '/traapp/mycrs/queryCrsInfoByLastnew',
method: 'post',
data
});
};
// 热门课程查询接口
export const queryCrsInfoByPopular = (data) => {
/**
tagId 标签ID(可选填),为空时查全部 必输项:false 类型:String
出参:
tagId 标签ID(可选填),为空时查全部 必输项:false 类型:String
出参:
crsId 课程ID StringcrsNum 课程编号 String
crsName 课程名称 String
tagId 课程分类 String
prdLineId 生产线分类 String
issuTm 发布日期 String
imgId 课程封面ID String
accmStdyCnt 累计学习次数 int
evalGrade 课程评分 Bigdecimal
tagCataList 课程标签集 List<Object>
tagId 标签ID String
tagName 标签名称 String
**/
return request({
url: '/traapp/mycrs/queryCrsInfoByPopular',
method: 'post',
data
});
/**
tagId 标签ID(可选填),为空时查全部 必输项:false 类型:String
出参:
tagId 标签ID(可选填),为空时查全部 必输项:false 类型:String
出参:
crsId 课程ID StringcrsNum 课程编号 String
crsName 课程名称 String
tagId 课程分类 String
prdLineId 生产线分类 String
issuTm 发布日期 String
imgId 课程封面ID String
accmStdyCnt 累计学习次数 int
evalGrade 课程评分 Bigdecimal
tagCataList 课程标签集 List<Object>
tagId 标签ID String
tagName 标签名称 String
**/
return request({
url: '/traapp/mycrs/queryCrsInfoByPopular',
method: 'post',
data
});
};
// 推荐课程查询接口
export const queryCrsInfoByRecmd = (data) => {
/**
crsNum 课程编号 String
crsName 课程名称 String
tagId 课程分类 String
prdLineId 生产线分类 String
issuTm 发布日期 String
imgId 课程封面ID String
accmStdyCnt 累计学习次数 int
evalGrade 课程评分 Bigdecimal
tagCataList 课程标签集 List<Object>
tagId 标签ID String
tagName 标签名称 String
**/
return request({
url: '/traapp/mycrs/queryCrsInfoByRecmd',
method: 'post',
data
});
/**
crsNum 课程编号 String
crsName 课程名称 String
tagId 课程分类 String
prdLineId 生产线分类 String
issuTm 发布日期 String
imgId 课程封面ID String
accmStdyCnt 累计学习次数 int
evalGrade 课程评分 Bigdecimal
tagCataList 课程标签集 List<Object>
tagId 标签ID String
tagName 标签名称 String
**/
return request({
url: '/traapp/mycrs/queryCrsInfoByRecmd',
method: 'post',
data
});
};
// 新政新品
export const queryNewPolicyNewProducts = (data) => {
return request({
url: '/traapp/mycrs/queryNewPolicyNewProducts',
method: 'post',
data
});
return request({
url: '/traapp/mycrs/queryNewPolicyNewProducts',
method: 'post',
data
});
};
// 待办事项mycrs/queryHaveToDo
export const queryHaveToDo = (data) => {
/**
date 日期 String
**/
return request({
url: '/traapp/mycrs/queryHaveToDo',
method: 'post',
data
});
};
+10 -10
View File
@@ -2,7 +2,7 @@
<view class="item" :class="{'no-touch':qnsTyp === 'ES' && !isDisabled && ['examination', 'practice', 'mistake_in', 'pk_in'].includes(props.mode)}">
<view class="top">
<!-- v-if="!['study'].includes(props.mode)" -->
<view class="type" v-if="!['study_answer'].includes(props.mode)">{{ subject_type_text }}</view>
<view class="type" v-if="!['study_answer', 'study_record'].includes(props.mode)">{{ subject_type_text }}</view>
<view class="score" v-if="['settlement', 'examination', 'pk_in'].includes(props.mode)">
{{ item.tgtGrade }}
</view>
@@ -44,14 +44,13 @@
</template>
</view>
</view>
<view class="question_text" v-if="!['study_answer'].includes(props.mode)">
<view class="question_text" v-if="!['study_answer', 'study_record'].includes(props.mode)">
{{ subject_data.qnsContent }}
</view>
<view :style="{ height: animationHeight }" :class="{ collapse_wrapper: props.mode === 'mistake' }" ref="wrapperRef">
<view class="collapse-content" ref="contentRef">
<view class="option_div" v-if="!['study_answer'].includes(props.mode)">
<view class="option_div" v-if="!['study_answer', 'study_record'].includes(props.mode)">
<template v-if="qnsTyp === 'ES'">
<questionVue
:status="subject_data.es_status"
:dataInfo="props.item?.my_answer"
@@ -75,7 +74,7 @@
class="option_div_button"
v-if="
qnsTyp === 'MU' &&
['practice', 'study', 'study_answer', 'pk_in', 'mistake_in'].includes(props.mode) &&
['practice', 'study', 'study_answer', 'study_record', 'pk_in', 'mistake_in'].includes(props.mode) &&
!props.isPreview &&
clearResult
"
@@ -96,7 +95,7 @@
class="analysis_div"
v-if="
!clearResult &&
['study', 'study_answer', 'mistake', 'settlement', 'practice', 'mistake_in', 'practice_record', 'pk_in'].includes(props.mode)
['study', 'study_answer', 'study_record', 'mistake', 'settlement', 'practice', 'mistake_in', 'practice_record', 'pk_in'].includes(props.mode)
"
>
<view class="analysis_title" v-if="qnsTyp !== 'ES'">
@@ -106,7 +105,7 @@
<text :class="right_or_wrong_class ? 'success' : 'error'">{{ myResultLabel.join('') }}</text>
</view>
</view>
<view class="reference_answer" v-if="qnsTyp === 'ES' && !['study', 'study_answer'].includes(props.mode)">
<view class="reference_answer" v-if="qnsTyp === 'ES' && !['study', 'study_answer', 'study_record'].includes(props.mode)">
<view class="reference_answer_title">你的答案:</view>
{{ subject_data.anserResult ?? '' }}
</view>
@@ -171,7 +170,7 @@
// 学习: study
// 考试结算页 settlement
// 练习记录页 practice_record, 'practice_record'
return ['examination', 'practice', 'mistake', 'mistake_in', 'study', 'study_answer', 'settlement', 'practice_record', 'pk_in'].includes(
return ['examination', 'practice', 'mistake', 'mistake_in', 'study', 'study_answer', 'study_record', 'settlement', 'practice_record', 'pk_in'].includes(
value
);
}
@@ -318,7 +317,7 @@
if (item_answer.value.includes(analysisVo.itemId)) {
item_answer.value = item_answer.value.filter((id) => id !== analysisVo.itemId);
modelValue.value = item_answer.value;
if (!['study','study_answer'].includes(props.mode)) {
if (!['study','study_answer', 'study_record'].includes(props.mode)) {
muCheckbox('choose');
}
} else if (props.item.qnsTyp === 'SN') {
@@ -332,7 +331,7 @@
// 多选直接插入
item_answer.value.push(analysisVo.itemId);
modelValue.value = item_answer.value;
if (!['study','study_answer'].includes(props.mode)) {
if (!['study','study_answer', 'study_record'].includes(props.mode)) {
muCheckbox('choose');
}
} else if (props.item.qnsTyp === 'JD') {
@@ -473,6 +472,7 @@
margin-top: 28rpx;
}
.reference_answer {
white-space: pre-line;
.reference_answer_title {
font-weight: 700;
font-size: 30rpx;
@@ -84,11 +84,11 @@
imgId: {
handler(newval, oldval) {
if (newval.indexOf('/') === 0) {
this.imgUrlShow = this.base_url + newval;
this.imgUrlShow = this.base_url + newval + '?tk=' + this.token;
return;
}
if (newval.indexOf('http') === 0) {
this.imgUrlShow = newval;
this.imgUrlShow = newval + '?tk=' + this.token;
return;
}
if (newval && this.watching) {
@@ -322,7 +322,10 @@
movable-view image {
width: 100%;
}
.detail-img {
width: calc(100% - 40rpx);
height: calc(100% - 100rpx);
}
// .detail-img {
// position: absolute;
// left: 50%;
+11 -9
View File
@@ -157,15 +157,17 @@ export default function useCheckIn() {
checkInDays: localStatus.checkInDays,
popUpStatus: localStatus.popupDay === today
}
let holidayBody = {
rewardFlag: localStatus.rewardFlag,
obtainFlag: localStatus.obtainFlag
}
// 如果没有记录获取节日徽章,那么需要重新获取节日徽章信息
if(holidayBody.rewardFlag && !holidayBody.obtainFlag) {
const {body:holidayData} = await queryHolidayReward()
holidayBody = holidayData
}
// let holidayBody = {
// rewardFlag: localStatus.rewardFlag,
// obtainFlag: localStatus.obtainFlag
// }
// // 如果没有记录获取节日徽章,那么需要重新获取节日徽章信息
// if(holidayBody.rewardFlag && !holidayBody.obtainFlag) {
// const {body:holidayData} = await queryHolidayReward()
// holidayBody = holidayData
// }
// 永远重新获取节日
const {body:holidayBody} = await queryHolidayReward()
complete(checkInInfo, holidayBody)
return true;
}
+25 -13
View File
@@ -60,8 +60,8 @@
</view>
<view class="voice-input-box">
<uv-textarea ref="inputRef" v-model="answerValue" :maxlength="props.textValueLength" v-show="!transLoading"
@click.stop customStyle="background: #ffffff00; padding-bottom: 50rpx; color: #fff; caret-color: #fff" height="200rpx"
text-style="color: #fff"
@click.stop customStyle="background: #ffffff00; padding-bottom: 50rpx; color: #fff; caret-color: #fff"
height="200rpx" text-style="color: #fff"
placeholderStyle="color:#999999;font-size:26rpx;border-color: #ffffff00 !important;"
placeholder=""></uv-textarea>
</view>
@@ -151,9 +151,9 @@
adjustPosition,
formatType
} = toRefs(props);
const isLoadingState = computed(() => props.isLoading);
const showTalkingModel = ref(false);
@@ -216,11 +216,11 @@
const isGettingPermission = ref(false)
const isStartNum = ref(0);
const isStopNum = ref(0);
const transLoading = ref(false)
//#ifdef APP-PLUS
// app端
const recordObjCom = ref({});
const IsAndEnv = getPhoneEnvBool('AND');
const transLoading = ref(false)
const initRecord = () => {
recordObjCom.value = uni.getRecorderManager();
unref(recordObjCom)?.onStop((res, duration) => {
@@ -301,6 +301,15 @@
}
}
});
unref(recordObjCom).onError((err) => {
isRecording.value = false
isGettingPermission.value = false
if (showTalkingModel.value) {
closeModel();
}
common.msg(err)
// common.msg(err'语音输入错误,请重试!')
});
};
@@ -326,15 +335,16 @@
const stopRecord = () => {
isStopNum.value = isStartNum.value;
try {
if (unref(recordObjCom).stop) {
if (isRecording.value && unref(recordObjCom).stop) {
setTimeout(() => {
isGettingPermission.value = false
}, 1000)
unref(recordObjCom).stop();
if (!transVoiceIng.value) {
console.log('1234')
setTimeout(() => {
closeModel()
}, 300)
}
setTimeout(() => {
closeModel()
}, 300)
} else {
isGettingPermission.value = false
closeModel();
}
} catch {
@@ -618,7 +628,9 @@
onHide(() => {
isGettingPermission.value = true
})
defineExpose({clearInputText})
defineExpose({
clearInputText
})
</script>
<style lang="scss" scoped>
@@ -487,6 +487,14 @@
});
}
};
const clearInputText = (text = '') => {
let oldText = answerValue.value
answerValue.value = text;
return oldText
}
const give_up = () => {
console.log('调用结束语音回答');
};
const changeBtn = () => {
if (props.isDisabled) return;
keyboardIsShow.value = !keyboardIsShow.value;
@@ -495,6 +503,7 @@
onHide(() => {
isGettingPermission.value = true
})
defineExpose({clearInputText, give_up})
</script>
<style lang="scss" scoped>
@@ -6,15 +6,17 @@
</view>
<view class="qns-desc">你的答案</view>
<view class="ans-list">
<!-- {...item, ossAddr: 'http://25.18.122.91:9786' + item.ossAddr.slice(35,)} -->
<esQuestionAnswer v-for="item in dataInfo.analyContentVos" :dataInfo="item" :intrctWay="item.ossKey?'02':'01'"
:activeVoiceId="activeVoiceId" @changePlay="changePlay" />
</view>
<view class="analysis_div">
<slot></slot>
<!-- <view class="analysis_div">
<view class="analysis_title">
<view class="success_answer">参考答案{{ dataInfo.itemAnswer }}</view>
</view>
<view class="analysis_note">试题解析{{ dataInfo?.analyContent }}</view>
</view>
</view> -->
</view>
</template>
@@ -54,7 +56,6 @@
});
const emit = defineEmits(['changePlay', 'buutton_click']);
const changePlay = (val) => {
console.log('esq')
emit('changePlay', val)
}
watch(
@@ -119,6 +120,8 @@
font-size: 30rpx;
margin-top: 20rpx;
margin-bottom: 20rpx;
font-weight: bold;
color: #333333;
}
.talking-info {
@@ -49,6 +49,9 @@
import {
onUnload
} from '@dcloudio/uni-app';
import {
getToken
} from '@/common/common.js'
const props = defineProps({
dataInfo: {
default: () => ({
@@ -135,21 +138,23 @@
emit('buutton_click', type, props.dataInfo);
};
const pauseVoice = () => {
console.log('pauseVoice')
if (!talkVoiceObj.value) return;
talkVoiceObj.value.pause();
isPlaying.value = false;
emit('changePlay', '');
// emit('changePlay', '');
};
const playVoice = () => {
emit('changePlay', unref(dataInfo)?.ossAddr);
// emit('changePlay', unref(dataInfo)?.ossAddr);
if (talkVoiceObj.value && talkVoiceObj.value.src) {
talkVoiceObj.value.play();
isPlaying.value = true;
return;
} else {
talkVoiceObj.value.src = '';
// talkVoiceObj.value.src = '';
if (unref(dataInfo).ossAddr) {
setTimeout(() => {
talkVoiceObj.value.src = unref(dataInfo).ossAddr;
talkVoiceObj.value.src = unref(dataInfo).ossAddr + '?tk=' + getToken();
talkVoiceObj.value.play();
isPlaying.value = true;
}, 100);
@@ -160,22 +165,26 @@
talkVoiceObj.value = uni.createInnerAudioContext();
let prevTime = -1;
talkVoiceObj.value.onEnded(() => {
console.log('onEnded')
emit('changePlay', '');
prevTime = -1;
talkVoiceObj.value.src = '';
});
talkVoiceObj.value.onStop(() => {
console.log('onStop')
emit('changePlay', '');
prevTime = -1;
talkVoiceObj.value.src = '';
});
talkVoiceObj.value.onPause(() => {
console.log('onPause')
prevTime = talkVoiceObj.value.currentTime;
emit('changePlay', '');
});
talkVoiceObj.value.onError(() => {
prevTime = -1;
emit('changePlay', '');
console.log('onError')
// prevTime = -1;
// emit('changePlay', '');
});
talkVoiceObj.value.onPlay(() => {
prevTime = talkVoiceObj.value.currentTime;
@@ -194,12 +203,8 @@
}, 500);
}
});
if (unref(dataInfo).intrctWay === '02') {
itemVoice.value = unref(dataInfo).ossAddr;
talkVoiceObj.value.src = itemVoice.value;
setTimeout(() => {
setVoiceTime(0);
}, 100);
if (unref(dataInfo).ossKey) {
talkVoiceObj.value.src = unref(dataInfo).ossAddr + '?tk=' + getToken();
}
};
const setVoiceTime = (sum) => {
@@ -31,10 +31,13 @@
{{ showContent }}
</text>
<!-- 试题问题 -->
<Subject v-if="[4, 8].indexOf(type) >= 0" :isPreview="!isLast" :item="subjectInfo"
:mode="mode" :clearResult="type === 4" @subject_click="subject_click" />
<!-- <esQuestion v-if="[4, 8].indexOf(type) >= 0 && dataInfo.qnsTyp === 'ES'" @changePlay="changePlay"
:activeVoiceId="activeVoiceId" :dataInfo="esSubjectInfo" /> -->
<esQuestion v-if="[4, 8].indexOf(type) >= 0 && dataInfo.qnsTyp === 'ES'" @changePlay="changePlay"
:activeVoiceId="activeVoiceId" :dataInfo="esSubjectInfo">
<Subject :isPreview="!isLast" :item="subjectInfo"
:mode="mode" :clearResult="type === 4" @subject_click="subject_click" />
</esQuestion>
<Subject v-if="[4, 8].indexOf(type) >= 0 && dataInfo.qnsTyp !== 'ES'" :isPreview="!isLast" :item="subjectInfo"
mode="study" :clearResult="type === 4" @subject_click="subject_click" />
<!-- 试题问题反馈 -->
<!-- <RadioSubjectRequest v-if="[8].indexOf(type) >= 0 && dataInfo.qnsTyp !== 'ES'" :item="dataInfo" :mode="mode" @subject_click="subject_click" /> -->
<!-- 段落图片视频预览 -->
@@ -257,7 +260,7 @@
})
return _sum
})
const mode = ref('study') // 考试 examination 练习practice 学习study
const mode = ref('study_record') // 考试 examination 练习practice 学习study
const showWithdraw = computed(() => {
let _isMe = unref(lastQuestionInfo).qstLogId === unref(dataInfo).qstLogId
+1
View File
@@ -106,6 +106,7 @@
loadingText="只能进行一条回答"
:adjustPosition="false"
:isDisabled="false"
:onlyVoice="true"
:answerMethod="answerMethod"
/>
<TouchBtn
+14 -8
View File
@@ -10,7 +10,7 @@
todayWeek > index ?'is-pass':'',
tipDateList.includes(item)?'is-tip':''
]">
<view class="item-box" @click="chooseDate(item)">
<view class="item-box" @click="chooseDate(item, todayWeek > index)">
{{
nowDayStr === item ?'今':
item.split('-')[2]
@@ -32,7 +32,7 @@
onShow
} from '@dcloudio/uni-app'
const emit = defineEmits(['update:modelValue'])
const emit = defineEmits(['update:modelValue', 'change'])
const props = defineProps({
modelValue: {
default: String,
@@ -54,7 +54,8 @@
}
})
const activeDateShow = ref(1)
const chooseDate = (item) => {
const chooseDate = (item, isDisabled) => {
if (isDisabled) return
activeDate.value = item
}
const nowDate = ref(new Date())
@@ -114,13 +115,15 @@
<style lang="scss" scoped>
$day-width: 54rpx;
.year-box{
.year-box {
height: 50rpx;
line-height: 50rpx;
margin-bottom: 12rpx;
text-align: center;
font-size: 29rpx;
}
.day-box {
width: 100%;
overflow: hidden;
@@ -141,16 +144,18 @@
font-size: 29rpx;
}
&.label-name{
&.label-name {
color: #999;
height: 50rpx;
line-height: 50rpx;
}
&.is-pass {
color: #999
}
&.is-tip{
&::after{
&.is-tip {
&::after {
content: '';
width: 8rpx;
height: 8rpx;
@@ -164,11 +169,12 @@
transform: translateX(-50%);
}
}
.item-box {
width: $day-width;
height: 100%;
text-align: center;
border-radius: calc( $day-width/2);
border-radius: calc($day-width/2);
background-color: #fff;
position: absolute;
left: 50%;
@@ -0,0 +1,30 @@
<template>
<view class="table-item custom-todo-item">
<view :class="['item-status', dataInfo.status === '11' ? '' : 'in-progress']">
{{dataInfo.status === '11' ? '未开始' :'进行中'}}</view>
<view class="item-title">
<view class="item-type course-type">课程</view>
<view class="item-name">卡拉华师大击杀看来是打算报考打不上卡了卡拉华师大击杀看来是打算报考打不上卡了</view>
</view>
<view class="item-info">
<view class="item-info-item inline-item">更新{{'2026-01-02'}}</view>
<view class="item-info-item inline-item">已学{{'454'}}</view>
</view>
<view class="item-btn">去学习</view>
</view>
</template>
<script setup>
const props = defineProps({
dataInfo: {
default: () => ({
type: 1
}),
type: Object
}
})
</script>
<style lang="scss" scoped>
@import './item.scss';
</style>
@@ -0,0 +1,30 @@
<template>
<view class="table-item custom-todo-item">
<view :class="['item-status', dataInfo.status === '11' ? '' : 'in-progress']">
{{dataInfo.status === '11' ? '未开始' :'进行中'}}</view>
<view class="item-title">
<view class="item-type exam-type">考试</view>
<view class="item-name">卡拉华师大击杀看来是打算报考打不上卡了</view>
</view>
<view class="item-info">
<view class="item-info-item">起止时间<text class="color-blue">{{'2026-01-02'}}</text></view>
<view class="item-info-item">完成人数<text class="color-black">{{'202'}}/{{3033}}</text></view>
</view>
<view class="item-btn">去考试</view>
</view>
</template>
<script setup>
const props = defineProps({
dataInfo: {
default: () => ({
type: 1
}),
type: Object
}
})
</script>
<style lang="scss" scoped>
@import './item.scss';
</style>
@@ -0,0 +1,115 @@
.custom-todo-item.table-item{
border-bottom: 2rpx solid #efefef;
margin-bottom: 25rpx;
position: relative;
padding-bottom: 32rpx;
&:last-child{
border: 0;
}
.item-status{
width: 100%;
font-size: 29rpx;
line-height: 40rpx;
margin-bottom: 14rpx;
color: #06f;
&.in-progress{
color: #ff8a2d;
}
}
.item-title{
overflow: hidden;
margin-bottom: 25rpx;
padding: 5rpx 0;
.item-type{
float: left;
width: 64rpx;
height: 33rpx;
border-radius: 4rpx;
text-align: center;
font-size: 23rpx;
line-height: 30rpx;
box-sizing: border-box;
margin-right: 12rpx;
&.course-type{
color: #06f;
border: 2rpx solid #06f;
background-color: rgba(0, 102, 255,.2);
}
&.exam-type{
color: rgb(72, 174, 128);
border: 2rpx solid rgb(72, 174, 128);
background-color: rgba(72, 174, 128,.2);
}
&.task-type{
color: rgb(130, 96, 253);
border: 2rpx solid rgb(130, 96, 253);
background-color: rgba(130, 96, 253,.2);
}
&.pk-type{
color: rgb(245, 130, 73);
border: 2rpx solid rgb(245, 130, 73);
background-color: rgba(245, 130, 73,.2);
}
&.sparring-type{
color: rgb(230, 192, 14);
border: 2rpx solid rgb(230, 192, 14);
background-color: rgba(230, 192, 14,.2);
}
}
.item-name{
width: calc(100% - 76rpx);
float: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 29rpx;
line-height: 33rpx;
font-weight: 600;
color: #333;
}
}
.item-info{
min-height: 33rpx;
overflow: hidden;
.item-info-item{
display: block;
color: #666;
font-size: 23rpx;
margin-bottom: 15rpx;
line-height: 33rpx;
height: 33rpx;
&:last-child{
margin-bottom: 0;
}
&.inline-item{
float: left;
margin-bottom: 0;
&+.inline-item{
margin-left: 30rpx;
}
}
}
}
.item-btn{
position: absolute;
background-color: #ebf1ff;
width: 120rpx;
height: 54rpx;
line-height: 54rpx;
color: #2c8ef2;
font-size: 25rpx;
text-align: center;
border-radius: 27rpx;
right: 0;
bottom: 23rpx;
}
}
.color-blue{
color: #06f;
}
.color-black{
color: #333;
}
.inline-item{
float: left;
}
@@ -0,0 +1,29 @@
<template>
<view class="table-item custom-todo-item">
<view :class="['item-status', dataInfo.status === '11' ? '' : 'in-progress']">
{{dataInfo.status === '11' ? '未开始' :'进行中'}}</view>
<view class="item-title">
<view class="item-type pk-type">竞赛</view>
<view class="item-name">卡拉华师大击杀看来是打算报考打不上卡了</view>
</view>
<view class="item-info">
<view class="item-info-item">起止时间<text class="color-blue">{{'2026-01-02'}}</text></view>
</view>
<view class="item-btn">去竞赛</view>
</view>
</template>
<script setup>
const props = defineProps({
dataInfo: {
default: () => ({
type: 1
}),
type: Object
}
})
</script>
<style lang="scss" scoped>
@import './item.scss';
</style>
@@ -0,0 +1,31 @@
<template>
<view class="table-item custom-todo-item">
<view :class="['item-status', dataInfo.status === '11' ? '' : 'in-progress']">
{{dataInfo.status === '11' ? '未开始' :'进行中'}}</view>
<view class="item-title">
<view class="item-type sparring-type">陪练</view>
<view class="item-name">卡拉华师大击杀看来是打算报考打不上卡了</view>
</view>
<view class="item-info">
<view class="item-info-item">截止时间<text
class="color-blue">{{dataInfo.limitTyp === '01' ? '不限制' : dataInfo.endTm}}</text></view>
<view class="item-info-item">陪练次数<text class="color-black">{{3033}}</text></view>
</view>
<view class="item-btn">去陪练</view>
</view>
</template>
<script setup>
const props = defineProps({
dataInfo: {
default: () => ({
type: 1
}),
type: Object
}
})
</script>
<style lang="scss" scoped>
@import './item.scss';
</style>
@@ -0,0 +1,66 @@
<template>
<view class="table-item custom-todo-item">
<view :class="['item-status', dataInfo.status === '11' ? '' : 'in-progress']">
{{dataInfo.status === '11' ? '未开始' :'进行中'}}</view>
<view class="item-title">
<view class="item-type task-type">任务</view>
<view class="item-name">卡拉华师大击杀看来是打算报考打不上卡了</view>
</view>
<view class="item-info">
<view class="item-info-item">起止时间<text class="color-blue">{{'2026-01-02'}}{{'2026-01-02'}}</text></view>
<view class="item-info-item inline-item">
完成人数<text class="color-black">{{'202'}}/{{3033}}</text>
</view>
<view class="item-info-item inline-item">
<view class="bg-block inline-item">
<view class="bg-gray">
<view class="bg-blue" :style="`width: ${2/4 * 100}%;`"></view>
</view>
</view>
<view class="color-blue inline-item">{{'32'}}%</view>
</view>
</view>
<view class="item-btn">做任务</view>
</view>
</template>
<script setup>
const props = defineProps({
dataInfo: {
default: () => ({
type: 1
}),
type: Object
}
})
</script>
<style lang="scss" scoped>
@import './item.scss';
.bg-block {
display: inline-block;
width: 100%;
height: 33rpx;
position: relative;
width: 100rpx;
margin-right: 20rpx;
}
.bg-gray {
width: 100%;
background-color: #ededed;
overflow: hidden;
border-radius: 15rpx;
position: absolute;
top: 10rpx;
left: 0;
height: 14rpx;
.bg-blue {
height: 100%;
float: left;
background-color: #06f;
}
}
</style>
+30
View File
@@ -0,0 +1,30 @@
<template>
<taskCom v-if="itemIndex === 1" :dataInfo="props.dataInfo"/>
<pkCom v-else-if="itemIndex === 2" :dataInfo="props.dataInfo"/>
<sparringCom v-else-if="itemIndex === 3" :dataInfo="props.dataInfo"/>
<examCom v-else-if="itemIndex === 4" :dataInfo="props.dataInfo"/>
<courseCom v-else-if="itemIndex === 5" :dataInfo="props.dataInfo"/>
</template>
<script setup>
import courseCom from './todo-com/course.vue'
import taskCom from './todo-com/task.vue'
import pkCom from './todo-com/pk.vue'
import sparringCom from './todo-com/sparring.vue'
import examCom from './todo-com/exam.vue'
const props = defineProps({
dataInfo: {
default: () => ({
type: 1
}),
type: Object
},
itemIndex: {
default: 0,
type: Number
}
})
</script>
<style lang="scss" scoped>
</style>
+69 -7
View File
@@ -1,32 +1,84 @@
<template>
<view class="module_title_div" >
<view class="module_title_div">
<view class="icon icon_1">
<!-- <image class="img" :src="icon"></image> -->
</view>
<view class="text font_pf">待办事项</view>
<view class="text font_pf">我的待办</view>
</view>
<view class="cont-box">
<calendarCom />
{{activeDate}}
<calendarCom @change="changeDate" />
<view class="table-list">
<todoItem v-for="item in 5" :itemIndex="item" @click="handleDetail(item)"></todoItem>
</view>
<view class="more-btn" v-show="showMoreBtn" @click="getMoreData">点击加载更多</view>
</view>
</template>
<script setup>
import { ref, onMounted, computed } from 'vue'
import {
ref,
onMounted,
computed
} from 'vue'
import calendarCom from './calendar.vue'
import todoItem from './todo-item.vue'
import {
queryHaveToDo
} from '@/api/index'
const activeDate = ref('')
const tableData = ref([])
const pageObj = ref({
totalNum: 0,
page: 1,
limit: 10
})
const changeDate = (date) => {
console.log('date: '+date)
activeDate.value = date
getDataList(date, 1)
}
const showMoreBtn = computed(() => {
return pageObj.value.totalNum > pageObj.value.page * pageObj.value.limit
})
const getMoreData = () => {
pageObj.value.page += 1
getDataList(activeDate.value)
}
const getDataList = (date, flag) => {
if(flag === 1){
tableData.value = []
pageObj.value = {
totalNum: 0,
page: 1,
limit: 999
}
}
console.log('date: ' + date)
console.log(pageObj.value)
queryHaveToDo({
date,
...pageObj.value
}).then(res => {
console.log(res)
let _arr = res.body || []
pageObj.value.totalNum = res.total
tableData.value = tableData.value.concat(_arr)
})
}
const handleDetail = (item) => {
console.log(item)
}
</script>
<style lang="scss" scoped>
$bg-margin-left: 30rpx;
.module_title_div {
display: flex;
margin: 30rpx $bg-margin-left;
align-items: center;
.icon {
margin-right: 6rpx;
}
@@ -48,13 +100,14 @@
}
.icon_3 {
// margin-top: 10rpx;
.img {
width: 38rpx;
height: 31rpx;
}
}
.title {
font-size: 34rpx;
color: #323e57;
@@ -64,10 +117,19 @@
}
}
.cont-box{
.cont-box {
margin: 0 $bg-margin-left;
background-color: #fff;
border-radius: 22rpx;
padding: 20rpx;
.table-list {
padding: 16rpx;
}
.more-btn{
color: rgb(144, 147, 153);
text-align: center;
font-size: 23rpx;
}
}
</style>
+84 -22
View File
@@ -22,7 +22,7 @@
</view>
</view>
<view class="ai-info">
<view class="ai-info" v-show="talkingList.length === 0">
<!-- <image src="@/static/images/dialog/pet-3.png" alt="" class="image-pet-bg"></image> -->
<image src="@/static/images/dialog/pet-bg-base.png" alt="" class="image-pet-bg"></image>
<image :src="luimgAddr" alt="" class="image-pet" mode="widthFix"></image>
@@ -32,28 +32,51 @@
<view class="info-btn">试试他的能力</view>
</view>
</view>
<view class="questions-view">
<scroll-view :scroll-x="true" :show-scrollbar="false">
<view class="question-row">
<view class="question-item" v-for="item in Math.ceil(questionList.length / 2)"
@click="sendText(questionList[item - 1].hotContent)">
{{ questionList[item - 1].hotContent }}
</view>
</view>
<view class="question-row">
<view class="question-item" v-for="item in questionList.length - Math.ceil(questionList.length / 2)"
@click="sendText(questionList[item + Math.ceil(questionList.length / 2) - 1].hotContent)">
{{ questionList[item + Math.ceil(questionList.length / 2) - 1].hotContent }}
<view class="talking-list talking-list-qns" v-show="talkingList.length === 0">
<scroll-view class="talking-scroll-list" :scroll-y="true" :scroll-top="scrollTop" :show-scrollbar="false"
:scroll-with-animation="false">
<view class="question-item-box" v-show="talkingList.length === 0" v-for="item in questionList">
<view class="question-item" @click="sendText(item.hotContent)">
{{ item.hotContent }}
</view>
</view>
</scroll-view>
</view>
<view class="talking-list">
<!-- <view class="questions-view">
<scroll-view :scroll-x="true" :show-scrollbar="false">
<view class="question-row">
<view
class="question-item"
v-for="item in Math.ceil(questionList.length / 2)"
@click="sendText(questionList[item - 1].hotContent)"
>
{{ questionList[item - 1].hotContent }}
</view>
</view>
<view class="question-row">
<view
class="question-item"
v-for="item in questionList.length - Math.ceil(questionList.length / 2)"
@click="sendText(questionList[item + Math.ceil(questionList.length / 2) - 1].hotContent)"
>
{{ questionList[item + Math.ceil(questionList.length / 2) - 1].hotContent }}
</view>
</view>
</scroll-view>
</view> -->
<view class="talking-list" v-show="talkingList.length > 0">
<scroll-view class="talking-scroll-list" :scroll-y="true" :scroll-top="scrollTop" :show-scrollbar="false"
:scroll-with-animation="false">
<TalkingItem v-for="(item, index) in talkingList" :talkingType="item.type" :talkingInfo="item"
:isLast="index + 1 === talkingList.length" :isAnswering="!answerIsOver"
:activeVoiceId="activeVoiceTalkingItemId" @handleEvents="talkItemEvents"></TalkingItem>
<view class="question-item-box mt-16" v-for="item in talkQnsList">
<view class="question-item" @click="sendText(item)">
{{ item }}
</view>
</view>
</scroll-view>
</view>
<view class="router-list">
@@ -229,6 +252,7 @@
const showModelComfirm = ref(false);
const reconcatNum = ref(1);
const askTime = ref(0)
const talkQnsList = ref([])
const initsocketTask = () => {
isHistory.value = false;
socketStore.creatSocket('/traask/asksocket/open?summary=');
@@ -300,8 +324,7 @@
if (commond === 'ASK') {
console.log('发送问题成功!');
if (talkingList.value.length > 0 && talkingList.value[talkingList.value.length - 1].isLoading) {
// talkingList.value.pop();
talkingList.value = talkingList.value.filter(t => !t.isLoading)
talkingList.value.pop();
}
seqNo.value = body.seqNo;
touchBtnCallBack.value && touchBtnCallBack.value();
@@ -319,7 +342,6 @@
isLoading: true,
id: _id + 'loading'
});
answerIsOver.value = false;
scrollToBottomNow();
return;
}
@@ -342,7 +364,6 @@
answerIsOver.value = false;
answerText.value = '';
talkingList.value.pop();
talkingList.value = talkingList.value.filter(t => !t.isLoading)
talkingList.value.push({
type: 'answer',
talkingText: answerText.value,
@@ -361,6 +382,7 @@
} else if (body.event === 'end') {
console.log('完成回答!');
answerIsOver.value = true;
console.log(answerText.value)
} else if (body.event === 'sourceDocuments') {
console.log('回答返回文件列表!');
console.log('body: ', body);
@@ -368,6 +390,10 @@
let _data = body.data;
talkingList.value[talkingList.value.length - 1].talkingFiles = _data.knowledgeList || [];
talkingList.value[talkingList.value.length - 1].talkingCrsList = _data.crsList || [];
} else if (body.event === 'recommend') {
console.log('回答返回问题列表!');
if (talkingList.value.length === 0) return;
talkQnsList.value = body.data || []//questionList.value.splice(0, 3);
}
return;
}
@@ -387,7 +413,6 @@
if (commond === 'ASK-ERR') {
console.log('提问失败,系统异常!');
answerIsOver.value = true;
return;
}
} else {
@@ -406,6 +431,9 @@
}, 3000);
};
const sendMessage = (data) => {
if (data.commond === 'ASK') {
talkQnsList.value = []
}
unref(SocketObj).send(data);
};
watch(
@@ -704,7 +732,6 @@
});
} else {
talkingList.value.pop();
talkingList.value = talkingList.value.filter(t => !t.isLoading)
uni.showToast({
title: '未识别到文字',
icon: 'none',
@@ -714,7 +741,6 @@
})
.catch((err) => {
talkingList.value.pop();
talkingList.value = talkingList.value.filter(t => !t.isLoading)
uni.showToast({
title: '系统异常,请联系管理员',
icon: 'none',
@@ -1168,14 +1194,50 @@
}
.talking-list {
height: calc(100% - 772rpx);
height: calc(100% - 328rpx);
min-height: 300rpx;
padding: 12rpx 24rpx;
box-sizing: border-box;
min-height: 300rpx;
&.talking-list-qns {
height: calc(100% - 600rpx);
}
.talking-scroll-list {
height: 100%;
.question-item-box {
float: left;
width: 100%;
&.mt-16 {
margin-top: 16rpx;
.question-item {
margin-bottom: 0rpx;
}
}
.question-item {
// white-space: nowrap;
float: left;
width: auto;
min-height: 66rpx;
line-height: 56rpx;
background-color: #fff;
border: 2rpx solid #e0dede;
padding: 5rpx 16rpx;
border-radius: 11rpx;
margin-bottom: 16rpx;
// display: inline-block;
font-size: 26rpx;
&:last-child {
margin-right: 0;
}
}
}
}
}
}
+2
View File
@@ -77,6 +77,7 @@
loadingText="只能进行一条回答"
:adjustPosition="false"
:isDisabled="false"
:onlyVoice="true"
:answerMethod="answerMethod"
/>
<TouchBtn
@@ -90,6 +91,7 @@
:adjustPosition="false"
:isDisabled="false"
:answerMethod="answerMethod"
/>
</view>