JLBA202505130001_关于吉林银行新建AI智能培训系统的需求_合并两个分支冲突

This commit is contained in:
田岩
2026-01-16 08:48:47 +08:00
21 changed files with 294 additions and 161 deletions
+37 -9
View File
@@ -33,11 +33,17 @@
<!-- 加载状态 -->
<CommonLoading color="#06f" v-show="dataInfo.isLoading" />
<!-- 参考答案 -->
<view class="talking-text" v-if="type === 5 && !dataInfo.isLoading" style="overflow: hidden">
<view class="talking-text" v-if="
false
//type === 5
&& !dataInfo.isLoading" style="overflow: hidden">
参考答案:{{ dataInfo.itemAnswer }}
</view>
<!-- 维度信息预览 -->
<view v-if="type === 5 && !dataInfo.isLoading" style="padding-top: 16rpx">
<view v-if="
false
//type === 5
&& !dataInfo.isLoading" style="padding-top: 16rpx">
<ChartFour v-if="dataInfo.evalDimens.length === 4" :dataList="dataInfo.evalDimens"
:score="dataInfo.asrGrade" />
<ChartThree v-if="dataInfo.evalDimens.length === 3" :dataList="dataInfo.evalDimens"
@@ -46,16 +52,17 @@
:score="dataInfo.asrGrade" />
</view>
<!-- 题干/段落内容 -->
<text class="talking-text" v-if="[3, 5, 6, 9].indexOf(type) >= 0 && !dataInfo.isLoading">
<text class="talking-text" v-if="[3,
// 5,
6, 9].indexOf(type) >= 0 && !dataInfo.isLoading">
{{ type === 5 ? '试题解析:' : '' }}{{ showContent }}
</text>
<view class="type-tag" v-if="[4].indexOf(type) >= 0 && dataInfo.qnsTyp === 'ES'">问答题</view>
<!-- <view class="type-tag" v-if="[4].indexOf(type) >= 0 && dataInfo.qnsTyp === 'ES'">问答题</view>
<text class="talking-text" v-if="[4].indexOf(type) >= 0 && dataInfo.qnsTyp === 'ES'">
<!-- 请您思考并作答:<br> -->
{{ showContent }}
</text>
</text> -->
<!-- 试题问题 -->
<Subject v-if="[4, 8].indexOf(type) >= 0 && dataInfo.qnsTyp !== 'ES'" :isPreview="!isLast" :item="subjectInfo" :showStem="type===4"
<Subject v-if="[4, 5, 8].indexOf(type) >= 0 && !dataInfo.isLoading" :isPreview="!isLast" :item="subjectInfo"
:mode="mode" :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" /> -->
@@ -275,6 +282,10 @@
default: '',
type: String
},
answerMethod: {
default: '01',
type: String
},
isLast: {
default: false,
type: Boolean
@@ -324,10 +335,27 @@
return {
...dataInfo.value,
...(dataInfo.value?.traQnsInfoVo || {}),
my_answer: dataInfo.value?.traQnsInfoVo?.anserResult || ''
my_answer: dataInfo.value?.traQnsInfoVo?.anserResult || '',
answerMethod: props.answerMethod,
...(props.type === 5?{
"qnsTyp": "ES",
my_answer: dataInfo.value,
itemVos: [{
...dataInfo.value,
"qnsTyp": "ES",
"qnsId": dataInfo.value.qnsId,
"itemAnswer": dataInfo.value.itemAnswer,
"relKeyword": dataInfo.value.relKeyword,
anserResult:dataInfo.value?.traQnsInfoVo?.anserResult || '',
"evalSettingVos": dataInfo.value?.essayEvalVo,
}]
}:{})
};
});
const mode = ref('study'); // 考试 examination 练习practice 学习study
const mode = computed(()=>{
return props.type == 5 ? 'study_answer' : 'study'
}); // 考试 examination 练习practice 学习study 学习结果study_answer
const imgAddrs = computed(()=>{
return (dataInfo.value.imageAddrs || [])
+8 -7
View File
@@ -10,7 +10,7 @@
placeholder="请输入文字"></uv-input>
</view>
<!-- @click="showTalkingModel = true" -->
<view class="talk-btn-box" v-show="!onlyVoice">
<view class="talk-btn-box" v-show="!onlyVoice && props.answerMethod !== '03'">
<image class="talk-btn-icon" v-show="!keyboardIsShow" src="/src/static/images/course/jianpan.png" mode=""
@click="changeBtn"></image>
<image class="talk-btn-icon" v-show="keyboardIsShow && !answerValue" src="/src/static/images/course/record.png"
@@ -36,7 +36,7 @@
</view>
<view class="btns-box" v-if="transVoiceIng">
<view class="cancel-btn transVoiceIng" @click="closeModel()"></view>
<view class="trans-btn transVoiceIng" @click="sendVoice()"></view>
<view class="trans-btn transVoiceIng" @click="sendVoice()" v-show="props.answerMethod !== '02'"></view>
<view class="send-btn" @click="sendText()">发送</view>
</view>
<view class="btns-box" v-else>
@@ -51,10 +51,10 @@
<image class="btn-box" v-else src="/src/static/images/course/translate-active.png" mode="heightFix"></image>
</view>
</view>
<view :class="['talk-dialog', isOut ? 'is-out' : '']" v-show="!isOutRight">
<view :class="['talk-dialog', isOut ? 'is-out' : '']" v-show="!isOutRight && !transVoiceIng">
<image src="@/static/images/course/voice-white.gif" mode="" class="gif-box"></image>
</view>
<view :class="['talk-dialog talk-textarea' ]" v-show="isOutRight" @click.stop>
<view :class="['talk-dialog talk-textarea' ]" v-show="isOutRight || transVoiceIng" @click.stop>
<view class="trans-loading-box" v-show="transLoading">
<CommonLoading color="#fff" class="loading-box" />
</view>
@@ -231,7 +231,8 @@
}
audioPath.value = res.tempFilePath;
console.log(isOut.value, isOutLeft.value, isOutRight.value)
if (!isOut.value) {
if (!isOut.value && (props.answerMethod !== '02')) {
console.log(11111111111)
if (startFlag.value !== 2) {
closeModel(() => {
nextTick(() => {
@@ -249,7 +250,7 @@
} else if (isOutLeft.value) {
console.log('取消')
closeModel();
} else if (isOutRight.value) {
} else if (isOutRight.value || (props.answerMethod === '02')) {
console.log('转文本')
transLoading.value = true
commonUploadVoiceFile(audioPath.value, '/traapp/voice/voiceChart', {}).then(res => {
@@ -551,7 +552,7 @@
isMoving.value = false;
if (!showTalkingModel.value) return;
//#ifdef APP-PLUS
transVoiceIng.value = isOutRight.value
transVoiceIng.value = isOutRight.value || (props.answerMethod === '02')
stopRecord();
// #endif
+57 -15
View File
@@ -47,13 +47,13 @@
课程学习
</view>
<view class="study-num">
<view class="color-blue">{{ showOrder }}</view>
<view class="color-black ml-40">学习中<text class="color-gray"><text class="color-black">{{ showOrder }}</text>/{{ pgrphNum }}</text></view>
<view class="bg-block">
<view class="bg-gray">
<view class="bg-blue" :style="`width: ${showOrder/pgrphNum * 100}%;`"></view>
</view>
</view>
<text>{{ pgrphNum }}</text>
</view>
<scroll-view class="talking-list" :scroll-y="true" :scroll-top="scrollTop" :show-scrollbar="false" :scroll-with-animation="true">
@@ -69,6 +69,7 @@
:voiceRate="chooseRate"
:lastQuestionInfo="lastTalkingInfo"
:teacherInfo="choiceTeacherInfo"
:answerMethod="answerMethod"
@changePlay="changePlayItemId"
@nextQuestion="nextQuestionSuccess"
@withdraw="withdrawNow"
@@ -80,6 +81,20 @@
<!-- </view> -->
</scroll-view>
<TouchBtn
v-if="answerMethod !== '03'"
class="talk-btns"
@uploadVoice="uploadRecordNow"
@submitAnswer="submitAnswerNow"
@startRecord="changePlayItemId('')"
:isLoading="isUploadingVoice"
:onlyVoice="answerOnlyVoice"
:canAnswer="testAnswer"
:adjustPosition="true"
:canAnswerText="canAnswerText"
:answerMethod="answerMethod"
:isDisabled="(lastTalkingInfo.type || 0) !== 4 || ['SN', 'MU', 'JD'].includes(lastTalkingInfo.qnsTyp)" />
<TouchBtnOnlyVoice
v-else
class="talk-btns"
@uploadVoice="uploadRecordNow"
@submitAnswer="submitAnswerNow"
@@ -152,6 +167,7 @@ import TalkingItem from '@/pages/course/components/talkingItem.vue'
import ImagePreview from '@/components/image-preview/image-preview.vue'
import PreviewDetail from '@/components/image-preview/preview-detail.vue'
import TouchBtn from '@/pages/course/components/touchBtn.vue'
import TouchBtnOnlyVoice from '@/pages/course/components/touchBtnOnlyVoice.vue'
import badge from '@/components/points-and-badge/badge';
import points from '@/components/points-and-badge/points';
import usePointsAndBadge from '@/components/points-and-badge/usePointsAndBadge';
@@ -406,7 +422,7 @@ const backRouter = () => {
}
const answerOnlyVoice = computed(() => {
return lastTalkingInfo.value.answerWay === 'V'
return lastTalkingInfo.value.answerWay === 'V' || (answerMethod.value === '03')
})
const canAnswerText = computed(() => {
@@ -1315,38 +1331,64 @@ const chooseRateNow = item => {
}
.study-num {
height: 56rpx;
height: 110rpx;
line-height: 46rpx;
font-size: 36rpx;
text-align: center;
padding-top: 10rpx;
text-align: left;
padding-left: 30rpx;
padding-right: 30rpx;
padding-top: 20rpx;
box-sizing: border-box;
background: url(@/static/images/course/study-bg.png) no-repeat;
border-radius: 30rpx 30rpx 0 0;
display: flex;
flex-direction: row;
justify-content: center;
font-size: 29rpx;
.color-blue {
color: #06f;
display: inline;
}
.color-black{
color: #333;
position: relative;
height: 44rpx;
line-height: 44rpx;
&.ml-40{
padding-left: 24rpx;
&::before{
content: '';
display: block;
width: 12rpx;
height: 12rpx;
overflow: hidden;
position: absolute;
border-radius: 50%;
background-color: #06f;
top: 50%;
left: 0;
transform: translateY(-50%);
}
}
}
.color-gray{
color: #999;
}
.bg-block{
display: inline-block;
width: 200rpx;
height: 100%;
display: block;
width: 100%;
height: 56rpx;
// padding: 4rpx 0 12rpx;
position: relative;
margin: 0 30rpx;
// margin: 0 30rpx;
}
.bg-gray{
width: 100%;
background-color: #e6eafd;
background-color: #ededed;
overflow: hidden;
border-radius: 15rpx;
position: absolute;
top: 13rpx;
left:0;
height: 20rpx;
height: 16rpx;
.bg-blue{
height: 100%;
float: left;
@@ -14,6 +14,7 @@
<view class="fz-30 fw-600 mb-8">更新时间</view>
<view class="fz-30 fw-400 color-666">{{ (modelValue.mtTime || '').substr(0, 16) }}</view>
</view>
<view class="info-bottom">
<view class="bottom-left">
<view class="mb-64">
@@ -37,10 +38,14 @@
<image src="/src/static/images/courseDetail/ditu.png" class="right-img" mode="widthFix"></image>
</view>
</view>
<view class="info-middle font_pf">
<view class="fz-30 fw-600 mb-8">回答方式</view>
<view class="fz-30 fw-400 color-666">{{answerMethod}}</view>
</view>
<view class="mb-64">
<view class="fz-30 font_pf fw-600 mb-4">课程核心</view>
<view class="examination_core color-666">
{{ modelValue.crsCore }}
{{ modelValue.crsCore || '无' }}
</view>
</view>
<view class="mb-64 file-items" v-if="(modelValue.fileList || []).length>0">
@@ -53,12 +58,16 @@
</template>
<script setup>
import {computed} from 'vue'
import {
previewFileFnc
} from '@/common/common'
const props = defineProps({
modelValue: Object
});
import {ANSWER_METHOD_MAP} from '@/enum.js'
const answerMethod = computed(() => ANSWER_METHOD_MAP[props.item?.answerMethod || ''] || ANSWER_METHOD_MAP['01']);
const previewFile = info => {
previewFileFnc({
fileId: info.fileId,
+29 -20
View File
@@ -26,21 +26,14 @@
src="/src/static/images/courseDetail/zhishidian.png"
mode="widthFix"
></image>
<view class="">知识点</view>
<view class="text-1">当前进度</view>
</view>
<view class="line-progress-div">
<view class="text-1">{{ form.styParaGraphNum || 0 }}</view>
<uv-line-progress
:percentage="progress"
:showText="false"
activeColor="#0066FF"
inactiveColor="#D9DEE8"
:height="8"
></uv-line-progress>
<view class="text-2">{{ form.pgrphNum || 0 }}</view>
<text class="text-2">(<text class="text-1">{{ form.styParaGraphNum || 0 }}</text>/{{ form.pgrphNum || 0 }})</text>
<view class="progress-div">
<view class="progress-line"></view>
</view>
</view>
<view
class="num-item examination"
@click="common.navigateTo(`/pages/examRanking/index?crsId=${crsId}`)"
@@ -143,9 +136,9 @@
const progress = computed(() => {
// 计算进度百分比(保留两位小数)
const total = form.value.pgrphNum;
if (total === 0) return 0;
if (total === 0) return '0%';
const completed = form.value.styParaGraphNum;
return Math.min(Math.round((completed / total) * 10000) / 100, 100);
return Math.min(Math.round((completed / total) * 10000) / 100, 100)+'%';
});
const tabSwitch = (item) => {
tabAct.value = item.index;
@@ -450,7 +443,7 @@
.examination {
color: #0066ff;
margin: 0 14rpx;
.back-icon {
position: relative;
width: 40rpx;
@@ -538,9 +531,8 @@
display: flex;
align-items: center;
font-size: 30rpx;
margin-right: 16rpx;
color: #666666;
height: 30rpx;
}
.line-progress-div {
display: flex;
@@ -548,14 +540,31 @@
flex: 1;
margin-right: 20rpx;
.text-1 {
color: #0066ff;
color: #333333;
font-size: 30rpx;
margin: 0 16rpx;
}
.text-2 {
color: #999999;
font-size: 30rpx;
margin: 0 16rpx;
margin: 0 8rpx;
}
.progress-div{
position: relative;
background-color: #D9DEE8;
width: 100%;
height: 16rpx;
border-radius: 10rpx;
overflow: hidden;
.progress-line{
position: absolute;
top: 0;
left: 0;
background-color: #0066FF;
// width: 100%;
width: v-bind(progress);
height: 100%;
border-radius: 10rpx;
}
}
}
.learn {
@@ -31,10 +31,10 @@
{{ showContent }}
</text>
<!-- 试题问题 -->
<Subject v-if="[4, 8].indexOf(type) >= 0 && dataInfo.qnsTyp !== 'ES'" :isPreview="!isLast" :item="subjectInfo"
<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" /> -->
<!-- 试题问题反馈 -->
<!-- <RadioSubjectRequest v-if="[8].indexOf(type) >= 0 && dataInfo.qnsTyp !== 'ES'" :item="dataInfo" :mode="mode" @subject_click="subject_click" /> -->
<!-- 段落图片视频预览 -->
@@ -55,14 +55,14 @@
></VideoPreview>
</view>
<!-- 维度信息预览 -->
<view v-if="[4, 8].indexOf(type) >= 0 && dataInfo.qnsTyp === 'ES'" style="padding-top: 16rpx;">
<!-- <view v-if="[4, 8].indexOf(type) >= 0 && dataInfo.qnsTyp === 'ES'" style="padding-top: 16rpx;">
<ChartFour v-if="esSubjectInfo?.evalSettingVos?.length === 4" :dataList="esSubjectInfo.evalSettingVos"
:score="intrctGrade" />
<ChartThree v-if="esSubjectInfo?.evalSettingVos?.length === 3" :dataList="esSubjectInfo.evalSettingVos"
:score="intrctGrade" />
<ChartFive v-if="esSubjectInfo?.evalSettingVos?.length === 5" :dataList="esSubjectInfo.evalSettingVos"
:score="intrctGrade" />
</view>
</view> -->
<!-- 参考答案 -->
<view class="talking-text" v-if="type === 5 && !dataInfo.isLoading" style="overflow: hidden;">
参考答案{{ dataInfo.itemAnswer }}
+4 -7
View File
@@ -407,6 +407,7 @@
}
topicList.push(
...examination.qnsInfoVos.map((res) => {
const es_status = (() => {
try {
@@ -471,7 +472,8 @@
...res,
mark: false,
es_status: es_status,
my_answer: my_answer
my_answer: my_answer,
answerMethod:answerMethod.value
};
})
);
@@ -955,11 +957,8 @@
.nav-div {
position: relative;
.title {
// padding-top:var(--status-bar-height);
// padding: 0 30rpx;
margin: 0 calc($bg-margin-left + 70rpx);
margin: 0 calc($bg-margin-left + 90rpx);
height: 70rpx;
font-family: PingFangSC;
font-weight: 500;
@@ -974,9 +973,7 @@
position: absolute;
right: $bg-margin-left;
top: 0;
// width: 70rpx;
height: 70rpx;
// background-color: red;
display: flex;
align-items: center;
justify-content: flex-end;
+3 -6
View File
@@ -370,13 +370,13 @@
isPreview: false,
clearResult: true,
es_status: '', // 预设一下问答题的状态,'' 空为没有 00 转圈 01 播放,其他暂定
my_answer: []
my_answer: [],
answerMethod:answerMethod.value
}));
answerMethod.value = practice.answerMethod ?? '01'
console.log('answerMethod', answerMethod.value);
addProblem();
// 记录练习起始时间
practiceStartTime = new Date().getTime();
setupKeyboardHeightListener((height) => {
popup_input_bottom.value = `${height}px`;
@@ -739,11 +739,8 @@
.nav-div {
position: relative;
.title {
// padding-top:var(--status-bar-height);
// padding: 0 30rpx;
margin: 0 calc($bg-margin-left + 70rpx);
margin: 0 calc($bg-margin-left + 90rpx);
height: 70rpx;
font-family: PingFangSC;
font-weight: 500;
+3 -2
View File
@@ -28,10 +28,11 @@ export class ProtocolConst {
export enum MessageType {
PING = 0b0001, // 心跳消息(支持空包体)
AUDIO_DATA = 0b0010, // 纯音频数据
TEXT_MESSAGE = 0b0011, // 文本消息
TEXT_MESSAGE = 0b0011, // 大模型回复的文本消息
CONTROL_CMD = 0b0100, // 控制指令
IDENTITY = 0b0101, // 身份校验包json格式
ERROR = 0b0110 // 错误信息json格式
ERROR = 0b0110, // 错误信息json格式
TIP_MESSAGE = 0b0111 // 大模型生成的回答提示
// 预留12种类型用于扩展(0b0100 ~ 0b1111
}
+1 -1
View File
@@ -124,7 +124,7 @@ export default function useWebSocket(aaas = null, options = {}) {
}
break;
case MessageType.TEXT_MESSAGE:
console.log('TEXT_MESSAGE', body);
break;