JLBA202505130001_关于吉林银行新建AI智能培训系统的需求_评论逻辑,文案调整

This commit is contained in:
杨航
2026-03-02 17:22:12 +08:00
parent 03a658fc57
commit ae8a4a5331
5 changed files with 275 additions and 45 deletions
+253 -30
View File
@@ -1,5 +1,5 @@
<template>
<view class="main-div">
<view class="main-div" @click.stop>
<view class="main-input-div">
<!-- 多行文本 -->
<view class="input-div">
@@ -14,43 +14,96 @@
autoHeight
:adjustPosition="false"
fixed
:focus="isFocus"
:cursor="cursorLength"
@focus="focus"
@blur="blur"
></uv-textarea>
</view>
<!-- 下方的图片展示框 -->
<view class="imgs-div" v-if="isShow">
<image class="upload-img" v-for="imgItem in uploadImgs" :src="imgItem" mode=""></image>
<view class="num" v-if="isShow">
<!-- 下方的图片展示框 -->
<view class="imgs-div" v-if="!isImg">
<image-preview class="upload-img" v-for="item in fileList" :src="item" mode=""></image-preview>
</view>
<view class="picture" v-if="isImg">
<picture-upload :limit="3" v-model="fileList"></picture-upload>
<!-- </view> -->
</view>
<view class="tips font_pf" v-if="isImg">最多可添加3张图片</view>
<view class="num-box">
<view class="font_pf fz-28 c-666">综合评分</view>
<view class="slider-box">
<slider
:min="0"
:max="10"
:value="10"
@change="sliderChange"
:step="0.1"
:show-value="true"
:blockSize="14"
></slider>
</view>
</view>
</view>
<view class="tab" v-if="isShow">
<view
class="tab-btn"
:class="{ 'is-active': bbsTag == 'SUG' }"
@click="bbsTag = 'SUG'"
>
建议
</view>
<view
class="tab-btn"
:class="{ 'is-active': bbsTag == 'ASK' }"
@click="bbsTag = 'ASK'"
>
提问
</view>
</view>
<!-- 工具框 -->
<view class="setting-div" v-if="isShow"></view>
</view>
<view class="tool-div" v-if="isShow">
<view class="tool-icon tool-icon-img" @click="upload">
<view class="tool-icon tool-icon-img" @click="upload()">
<image class="img" :src="commentInput3" mode="aspectFit"></image>
</view>
<view class="tool-icon tool-icon-emoji">
<view class="tool-icon tool-icon-emoji" @click="showKeyborad">
<image class="img" :src="commentInput2" mode="aspectFit"></image>
</view>
<view class="fl1"></view>
<view class="tool-send">发送</view>
<view class="tool-send" @click="submit">发送</view>
</view>
<!-- 下方主要表情输入框 -->
<view class="bottom-main-input-div">
<view class="expression-tool-div">
<view class="tool-icon tool-icon-img checked_tool">
<view :class="['tool-icon tool-icon-img checked_tool',currentIndex === 0 ? 'is-active-tool':'']" @click="currentIndex = 0">
<image class="img" :src="commentInput1" mode="aspectFit"></image>
</view>
<view class="tool-icon tool-icon-emoji checked_tool">
<view :class="['tool-icon tool-icon-img checked_tool',currentIndex === 1 ? 'is-active-tool':'']" @click="currentIndex = 1">
<image class="img" :src="commentInput4" mode="aspectFit"></image>
</view>
<view class="fl1"></view>
</view>
<view class="emoji-list">
<view class="emoji-item" v-for="emojiItem in emojiList" @click="insertValue(emojiItem)">
{{emojiItem}}
</view>
</view>
<swiper class="stack-swiper" :current="currentIndex" previous-margin="0"
next-margin="0" :autoplay="false" @change="changeCurrent">
<swiper-item key="1" class="swiper-item">
<scroll-view :scroll-y="true" class="emoji-list">
<view class="emoji-item" v-for="emojiItem in emojiList" @click="insertValue(emojiItem)">
{{emojiItem}}
</view>
</scroll-view>
</swiper-item>
<swiper-item key="2" class="swiper-item">
<scroll-view :scroll-y="true" class="img-list">
<view class="img-item" v-for="memItem in memList" @click="setMemValue(memItem)">
<image-preview class="img_100" :src="memItem.ossAddr" :isCache="true" mode="aspectFill"></image-preview>
</view>
</scroll-view>
</swiper-item>
</swiper>
</view>
</view>
</template>
@@ -60,9 +113,22 @@
import commentInput2 from '@/static/images/courseDetail/comment-input-2.png'
import commentInput3 from '@/static/images/courseDetail/comment-input-3.png'
import commentInput4 from '@/static/images/courseDetail/comment-input-4.png'
import { reactive, ref } from 'vue';
import { reactive, ref, watch, nextTick } from 'vue';
import { emojiList } from '@/emoji';
import { queryTraMemeInfoList } from '@/api/courseDetail.js'
import { publishCrsEvaluation, queryTraMemeInfoList } from '@/api/courseDetail.js'
import common from '@/common/common.js';
import {
uploadFile
} from '@/api/common'
const props = defineProps({
crsId:{
type: String,
default: ''
}
})
const customStyle = {
backgroundColor: 'rgb(227, 230, 237)',
padding: '18rpx'
@@ -77,11 +143,21 @@
if(!isShow.value) isShow.value = true
}
const textareaRef = ref()
const isFocus = ref(false)
const cursorLength = ref(0)
const currentIndex = ref(0)
const isImg = ref(true)
const changeCurrent = (event) => {
currentIndex.value = event.detail.current
}
const showKeyborad = () => {
isFocus.value = true
cursorLength.value = resStart.value || value.value.length
}
const focus = (event) => {
popHeight.value = '278px'
popHeight.value = 'calc(270px + 120rpx)'
isShow.value = true
console.log('event', event);
console.dir(textareaRef.value)
console.log('focusevent');
getMemList()
}
const resStart = ref(-1)
@@ -90,15 +166,34 @@
// popHeight.value = '0px'
resStart.value = event.detail.cursor
isShow.value = true
isFocus.value = false
}
const hideAll = () => {
popHeight.value = '0px'
isShow.value = false
isFocus.value = false
}
const insertValue = (emojiItem) => {
let _val = value.value
value.value = _val.substring(0, resStart.value) + emojiItem + _val.substring(resStart.value, _val.length)
resStart.value+=emojiItem.length
}
const fileList = reactive([]);
const fileList = ref([]);
const bbsTag = ref('SUG')
// 方法
const upload = (limit = 4) => {
const uploadNow = (limit = 3) => {
if(!isImg.value){
upload(limit)
}else{
common.show('','是否清空当前表情并重新添加?').then((res) => {
if (res) {
upload(limit)
}
});
}
}
const upload = (limit = 3) => {
uni.chooseImage({
count: limit,
sizeType: ['original', 'compressed'],
@@ -107,16 +202,19 @@
tempFilePaths
}) => {
const valid = tempFilePaths.every(url => {
const lastDotIndex = url.lastIndexOf('.')
const extension = url.slice(lastDotIndex + 1).split('?')[0].toLowerCase()
return ['png', 'jpg'].includes(extension)
})
console.log(tempFilePaths,valid)
if (!valid) return common.msg('您选择的图片格式有误。')
const data = {
bizScen: 'S3005'
}
const upload_map = tempFilePaths.map((file) => uploadFile(file, data))
Promise.all(upload_map).then(res => {
fileList.push(...res.splice(0, limit - fileList.length))
fileList.value.push(...res.splice(0, limit - fileList.value.length).map(t => t.fileId))
isImg.value = true
}).catch((err) => {
common.msg(err)
})
@@ -129,22 +227,107 @@
return
}
queryTraMemeInfoList().then(res=>{
console.log(res)
memList.value = res.body || []
})
}
const setMemValue = (item) => {
console.log(item)
if(!isImg.value || fileList.value.length == 0){
fileList.value = [item.ossAddr]
isImg.value = false
return
}
common.show('','是否清空当前图片并重新添加?').then((res) => {
if (res) {
fileList.value = [item.ossAddr]
isImg.value = false
}
});
}
const submit = () => {
if (value.value === '') {
if (bbsTag.value === 'SUG') {
return common.msg('请输入你的建议');
} else {
return common.msg('请输入你的问题');
}
}
const loadingStartTime = Date.now();
common.loading('评价中');
let _params = {
crsId: props.crsId,
imgIdList: fileList.value, // 发表图片ID列表,文件ID集
bbsGrade: bbsGrade.value, // 综合评分(最高10分)
bbsTag: bbsTag.value, // 评价标签 (SUG 建议 ASK 提问 )
bbsContent: value.value // 评价内容
}
console.log(_params)
publishCrsEvaluation(_params).then((res) => {
const loadingDuration = Date.now() - loadingStartTime;
const minLoadingTime = 700;
console.log(loadingStartTime, loadingDuration);
const delayTime = Math.max(0, minLoadingTime - loadingDuration);
console.log('delayTime', delayTime);
setTimeout(() => {
common.hideLoading();
nextTick(() => common.msg('发表成功'));
setTimeout(() => {
uni.$emit('refresh_comment_data');
hideAll()
if (from.value === 'study') {
} else {
}
}, 500);
}, delayTime);
}).catch(err=>{
console.log(err)
})
};
const bbsGrade = ref(10)
const sliderChange = (event) => {
bbsGrade.value = event.detail.value;
};
watch(()=> fileList.value, (val)=>{
if(val.length === 0){
isImg.value = true
}
})
defineExpose({hideAll})
</script>
<style scoped lang="scss">
.emoji-list{
// display: flex;
// flex-wrap: wrap;
.stack-swiper{
height: 270px;
}
.img-list{
box-sizing: border-box;
margin: 0 auto;
// background-color: red;
// justify-content: center;
height: calc(278px - 120rpx);
height: 270px;
overflow-y: auto;
padding: 0 14rpx;
width: 100%;
.img-item{
float: left;
width: 126rpx;
text-align: center;
&:not(:nth-child(5n)){
margin-right: 20rpx;
}
}
.img_100{
width: 126rpx;
height: 126rpx;
display: inline-block;
}
}
.emoji-list{
box-sizing: border-box;
margin: 0 auto;
height: 270px;
overflow-y: auto;
padding: 0 14rpx;
width: 100%;
.emoji-item{
font-size: 44rpx;
// padding: 14rpx;
@@ -175,6 +358,9 @@
}
.checked_tool{
background-color: rgb(243, 243, 243);
&.is-active-tool{
background-color: #ddd;
}
}
}
.bottom-main-input-div{
@@ -240,7 +426,8 @@
}
.main-input-div {
width: calc(100% - 40rpx);
margin: 20rpx;background-color: red;
margin: 20rpx;
background-color: red;
display: flex;
flex-direction: column;
border-radius: 40rpx;
@@ -272,4 +459,40 @@
.textarea{
padding: 14rpx;
}
.num-pic {
width: 92rpx;
height: 92rpx;
// margin-top: 20rpx;
margin-right: 20rpx;
border-radius: 8rpx;
overflow: hidden;
}
.num-box {
flex: 1;
display: flex;
// height: 100%;
justify-content: space-between;
flex-direction: column;
}
.tab-btn {
width: 78rpx;
height: 36rpx;
font-size: 22rpx;
color: #999999;
text-align: center;
border-radius: 8rpx;
border: 2rpx solid #999999;
margin-right: 30rpx;
&.is-active {
color: #0066ff;
border: 2rpx solid #0066ff;
}
}
.img-show{
width: 120rpx;
height: 120rpx;
}
</style>
@@ -158,9 +158,9 @@
}
.pic-item {
margin-right: 30rpx;
width: 170rpx;
height: 170rpx;
margin-right: 20rpx;
width: 120rpx;
height: 120rpx;
border-radius: 8rpx;
// background-color: red;
margin-bottom: 24rpx;
@@ -168,8 +168,8 @@
.add_icon {
position: relative;
width: 170rpx;
height: 170rpx;
width: 120rpx;
height: 120rpx;
border: 2rpx dashed #C0C0C0;
border-radius: 8rpx;
+5 -6
View File
@@ -1,11 +1,10 @@
export const emojiList = [
'😀', '😃', '😄', '😁', '😆', '😅', '🤣', '😂', '🙂', '🙃', '😉', '😊', '😇', '🥰', '😍', '🤩', '😘', '😗', '☺',
'😀', '😃', '😄', '😁', '😆', '😅', '🤣', '😂', '🙂', '🙃', '😉', '😊', '😇', '🥰', '😍', '🤩', '😘', '😗',
'😚', '😙', '🥲', '😋', '😛', '😜', '🤪', '😝', '🤑', '🤗', '🤭', '🤫', '🤔', '🤐', '🤨', '😐', '😑', '😶',
'😏', '😒', '🙄', '😬', '🤥', '😌', '😔', '😪', '🤤', '😴', '😷', '🤒', '🤕', '🤢', '🤮', '🤧', '🥵', '🥶',
'🥴', '😵', '🤯', '🤠', '🥳', '🥸', '😎', '🤓', '🧐', '😕', '😟', '🙁', '☹', '😮', '😯', '😲', '😳', '🥺', '😦',
'🥴', '😵', '🤯', '🤠', '🥳', '🥸', '😎', '🤓', '🧐', '😕', '😟', '🙁', '😮', '😯', '😲', '😳', '🥺', '😦',
'😧', '😨', '😰', '😥', '😢', '😭', '😱', '😖', '😣', '😞', '😓', '😩', '😫', '🥱', '😤', '😡', '😠', '🤬',
'😈', '👿', '💀', '☠', '*', '🤡', '👹', '👺', '👻', '👽', '👾', '🤖', '😺', '😸', '😹', '😻', '😼', '😽', '🙀',
'😿', '😾', '🙈', '🙉', '🙊', '💋', '💌', '💘', '💝', '💖', '💗', '💓', '💞', '💕', '💟', '❣', '💔', '❤', '🧡',
'💛', '💚', '💙', '💜', '🤎', '🖤', '🤍', '💯', '💢', '💥', '💫', '💦', '💨', '🕳', '💣', '💬', '👁‍🗨', '🗨',
'🗯', '💭', '💤'
'😈', '👿', '💀', '🤡', '👹', '👺', '👻', '👽', '👾', '🤖', '😺', '😸', '😹', '😻', '😼', '😽', '🙀',
'😿', '😾', '🙈', '🙉', '🙊', '💋', '💌', '💘', '💝', '💖', '💗', '💓', '💞', '💕', '💟', '💔', '🧡',
'💛', '💚', '💙', '💜', '🤎', '🖤', '🤍', '💯', '💢', '💥', '💫', '💦', '💨', '🕳', '💣', '💤'
]
+6 -3
View File
@@ -1,5 +1,5 @@
<template>
<view class="max_page">
<view class="max_page" @click="hideKeyboradNow">
<nav-bar :is_seat="false" :backgroundColor="bgOpacity"></nav-bar>
<scroll-view
:scroll-y="true"
@@ -102,7 +102,7 @@
<!-- </view> -->
<!-- </template> -->
</view>
<comment-input v-if="tabAct === 2"></comment-input>
<comment-input v-if="tabAct === 2" ref="commentInputRef" :crsId="crsId"></comment-input>
</view>
</template>
@@ -125,6 +125,7 @@
// tab栏
const tabList = ref([{ name: '课程介绍' }, { name: '知识点' }, { name: '评价' }]);
const commentRef = ref(null);
const commentInputRef = ref(null)
const form = ref({});
const crsId = ref('');
const collectId = ref(''); // 记录初始的收藏id
@@ -149,7 +150,9 @@
commentRef.value?.getData();
}
};
const hideKeyboradNow = () => {
commentInputRef.value.hideAll()
}
const getData = async () => {
common.loading();
try {
+6 -1
View File
@@ -52,7 +52,8 @@
<!-- sceneDesc -->
{{ detailInfo.sceneDesc }}
</view>
<view class="talking-desc"> 陪练角色不具备主动终止场景陪练的功能当用户完成预设陪练目标时需由用户手动发起结束陪练操作 </view>
<view class="talking-desc"> 1. 陪练角色不具备主动终止场景陪练的功能当用户完成预设陪练目标时需由用户手动发起结束陪练操作 </view>
<view class="talking-desc second"> 2. 存款挂牌利率仅供参考实际执行利率以吉林银行分支机构最终办理结果为准</view>
<view class="talking-box" v-if="detailInfo.traInterTyp !== '01'">
<view class="tip-text">-请点击下方按钮开始{{ detailInfo.traInterTypDesc }}</view>
</view>
@@ -889,9 +890,13 @@ onBackPress(res => {
.talking-desc {
// padding-top: 24rpx;
padding: 24rpx 20rpx 0;
white-space: pre-line;
font-size: 24rpx;
// text-align: center;
color: #999;
&.second{
padding-top:0;
}
}
.talking-box {