Merge branch 'develop' of http://25.13.9.101:9000/K17_AITS/tra-app into develop
@@ -72,6 +72,7 @@ export const commonUploadVoiceFile = (file, url, data = {}, fileKey='voice') =>
|
||||
};
|
||||
if (token)
|
||||
header['summary'] = token
|
||||
console.log(`${base_url}${url}`)
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.uploadFile({
|
||||
url: `${base_url}${url}`,
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import request from '@/api/request'
|
||||
import common from "@/common/common";
|
||||
import {
|
||||
queryCurrentValidMascotInfo
|
||||
} from "@/api/mascot.js"
|
||||
|
||||
import {
|
||||
setToken,
|
||||
setUserInfo,
|
||||
@@ -21,7 +25,36 @@ export const useAccountLoginApp = (data) => request({
|
||||
if (rtnCode === '0000') {
|
||||
setToken(body)
|
||||
|
||||
// 获取科技鹿
|
||||
queryCurrentValidMascotInfo().then((res) => {
|
||||
const userInfo = getUserInfo()
|
||||
setUserInfo({
|
||||
...userInfo,
|
||||
'mascotInfo': res
|
||||
})
|
||||
console.log('科技', res);
|
||||
if (res.imgAddr) {
|
||||
setTimeout(() => {
|
||||
const img = new Image(); // 创建Image对象
|
||||
// 图片加载成功(缓存完成)
|
||||
img.onload = () => {
|
||||
console.log(`图片缓存成功: ${url}`);
|
||||
resolve(img); // 返回加载完成的Image对象
|
||||
};
|
||||
|
||||
// 图片加载失败
|
||||
img.onerror = () => {
|
||||
console.error(`图片缓存失败: ${url}`);
|
||||
reject(new Error(`Failed to load image: ${url}`));
|
||||
};
|
||||
|
||||
// 开始加载图片(设置src触发请求,浏览器会自动缓存)
|
||||
img.src = url;
|
||||
})
|
||||
}
|
||||
})
|
||||
const user_data = await queryCurrentUser()
|
||||
|
||||
return user_data
|
||||
|
||||
}
|
||||
@@ -76,46 +109,48 @@ export const queryCurrentUser = (data) => request({
|
||||
// 预加载头像
|
||||
// #ifdef APP-PLUS
|
||||
const updateUserAvatar = (imagePath) => {
|
||||
const userInfo = getUserInfo()
|
||||
setUserInfo({
|
||||
...userInfo,
|
||||
'imagePath': imagePath
|
||||
})
|
||||
const userInfo = getUserInfo()
|
||||
setUserInfo({
|
||||
...userInfo,
|
||||
'imagePath': imagePath
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
const pathName = res.body.imageAddr
|
||||
const url = base_url + pathName
|
||||
// 生成唯一文件名,避免冲突
|
||||
const filename = pathName.split('/').pop()
|
||||
const localFilePath = '_downloads/' + filename
|
||||
|
||||
// 先检查是否存在
|
||||
uni.getFileInfo({
|
||||
filePath: localFilePath,
|
||||
success: () => {
|
||||
console.log('头像已存在,无需下载');
|
||||
updateUserAvatar(localFilePath)
|
||||
},
|
||||
fail: () => {
|
||||
console.log('开始下载头像:', url);
|
||||
const dtask = plus.downloader.createDownload(
|
||||
url, {
|
||||
method: 'GET',
|
||||
filename: '_downloads/' + filename
|
||||
},
|
||||
(download, status) => {
|
||||
if (status === 200) {
|
||||
console.log('头像下载成功:', download.filename);
|
||||
updateUserAvatar(download.filename)
|
||||
}
|
||||
}
|
||||
)
|
||||
dtask.start();
|
||||
}
|
||||
})
|
||||
const pathName = res.body.imageAddr
|
||||
const url = base_url + pathName
|
||||
// 生成唯一文件名,避免冲突
|
||||
const filename = pathName.split('/').pop()
|
||||
const localFilePath = '_downloads/' + filename
|
||||
|
||||
// 先检查是否存在
|
||||
uni.getFileInfo({
|
||||
filePath: localFilePath,
|
||||
success: () => {
|
||||
console.log('头像已存在,无需下载');
|
||||
updateUserAvatar(localFilePath)
|
||||
},
|
||||
fail: () => {
|
||||
console.log('开始下载头像:', url);
|
||||
const dtask = plus.downloader.createDownload(
|
||||
url, {
|
||||
method: 'GET',
|
||||
filename: '_downloads/' + filename
|
||||
},
|
||||
(download, status) => {
|
||||
if (status === 200) {
|
||||
console.log('头像下载成功:', download.filename);
|
||||
updateUserAvatar(download.filename)
|
||||
}
|
||||
}
|
||||
)
|
||||
dtask.start();
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error('头像预加载过程发生错误:', error);
|
||||
console.error('头像预加载过程发生错误:', error);
|
||||
}
|
||||
// #endif
|
||||
return res.body
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import request from '@/api/request'
|
||||
|
||||
const base_url = '/traapp'
|
||||
|
||||
|
||||
/**
|
||||
* 查询吉祥物列表
|
||||
* 出参:
|
||||
mascotId 吉祥物ID String
|
||||
mascotName 吉祥物名称 String
|
||||
mascotNameEn 吉祥物英文名称 String
|
||||
mascotDesc 吉祥物简介 String
|
||||
mascotNo 吉祥物编号 String
|
||||
imgAddr 吉祥物图片 String
|
||||
imgThumbAddr 吉祥物缩略图 String
|
||||
showOrder 显示顺序 int
|
||||
*/
|
||||
export const queryValidTraMascotInfo = (data) => {
|
||||
return request({
|
||||
url: base_url + '/traMascotInfo/queryValidTraMascotInfo',
|
||||
method: 'post',
|
||||
toastErrors: true,
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 设置吉祥物
|
||||
* 入参:
|
||||
mascotId 必输项:true 类型:String
|
||||
*/
|
||||
export const setTraMascotInfo = (data) => {
|
||||
return request({
|
||||
url: base_url + '/traMascotInfo/setTraMascotInfo',
|
||||
method: 'post',
|
||||
toastErrors: true,
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
// 查询当前已经选择的吉祥物
|
||||
/**
|
||||
* 查询当前已经选择的吉祥物
|
||||
* 出参:
|
||||
mascotId 吉祥物ID String
|
||||
mascotName 吉祥物名称 String
|
||||
mascotNameEn 吉祥物英文名称 String
|
||||
mascotDesc 吉祥物简介 String
|
||||
mascotNo 吉祥物编号 String
|
||||
imgAddr 吉祥物图片 String
|
||||
imgThumbAddr 吉祥物缩略图 String
|
||||
showOrder 显示顺序 int
|
||||
*/
|
||||
export const queryCurrentValidMascotInfo = (data) => {
|
||||
return request({
|
||||
url: base_url + '/traMascotInfo/queryCurrentValidMascotInfo',
|
||||
method: 'post',
|
||||
toastErrors: true,
|
||||
data
|
||||
});
|
||||
};
|
||||
@@ -6,7 +6,9 @@ import common from '@/common/common.js'
|
||||
const ENV = import.meta.env
|
||||
|
||||
export const get_base_url = url => {
|
||||
|
||||
if (ENV.MODE === 'development') { // 开发环境
|
||||
return ENV.VITE_APP_BASE_API_Url
|
||||
// H5必须用非https,手机端必须用https
|
||||
// #ifdef H5
|
||||
const baseUrl = ENV.VITE_APP_BASE_API_Url
|
||||
|
||||
@@ -8,9 +8,5 @@ export const GENDER = [{
|
||||
{
|
||||
value: "f",
|
||||
label: "女性",
|
||||
},
|
||||
{
|
||||
value: "o",
|
||||
label: "其他",
|
||||
}
|
||||
] // 性别
|
||||
@@ -152,7 +152,7 @@
|
||||
<view
|
||||
class="icon text-right-btn"
|
||||
@click.stop="withdraw"
|
||||
v-show="isLast"
|
||||
v-show="showWithdraw"
|
||||
>撤回
|
||||
<!-- v-show="showWithdraw" -->
|
||||
</view>
|
||||
@@ -254,7 +254,7 @@ const audioCacheObj = computed(() => storageStore.audioObj)
|
||||
const itemVoice = ref('')
|
||||
|
||||
const showWithdraw = computed(()=>{
|
||||
let _isMe = unref(lastQuestionInfo).qnsLogId === unref(dataInfo).qnsLogId
|
||||
let _isMe = unref(lastQuestionInfo).qstLogId === unref(dataInfo).qstLogId
|
||||
let _isQuestion = unref(lastQuestionInfo).isQuestion
|
||||
return _isMe && _isQuestion
|
||||
})
|
||||
@@ -367,13 +367,17 @@ const audioCacheObj = computed(() => storageStore.audioObj)
|
||||
},100)
|
||||
}else{
|
||||
voiceLoading.value = true
|
||||
let _type = props.type == 2 ? 'ans' : props.type == 3 ? 'pgrh' : props.type == 4 ? 'qns' : ''
|
||||
let _readId = props.type == 2 ? unref(dataInfo)?.intrctId : props.type == 3 ? unref(dataInfo)?.pgrphId : props.type == 4 ? unref(dataInfo)?.qnsId : ''
|
||||
console.log(unref(dataInfo))
|
||||
let _params = {
|
||||
crsId: unref(dataInfo)?.crsId || '',
|
||||
pgrphId: unref(dataInfo)?.pgrphId || '',
|
||||
qnsId: unref(dataInfo)?.qnsId || '',
|
||||
readType: readType,
|
||||
readType: _type,// 2 文本回答 3, 段落信息 4 问题信息
|
||||
teachNo: unref(teacherInfo)?.teacherNo, // 必填
|
||||
content: _content
|
||||
readId: _readId
|
||||
// content: _content
|
||||
}
|
||||
|
||||
|
||||
@@ -388,19 +392,6 @@ const audioCacheObj = computed(() => storageStore.audioObj)
|
||||
talkVoiceObj.value.src = url
|
||||
talkVoiceObj.value.play()
|
||||
}else{
|
||||
// getAudioByText(_params).then(res=>{
|
||||
// // uni.env.USER_DATA_PATH ||
|
||||
// let filePath = `${'/'}/${dataInfo.value.id}.mp3`
|
||||
// saveFile(res, filePath, () => {
|
||||
// voiceLoading.value = false
|
||||
// itemVoice.value = filePath
|
||||
// talkVoiceObj.value.src = filePath
|
||||
// talkVoiceObj.value.play()
|
||||
// storageStore.setStorage('audio', _url + _params.teachNo, itemVoice.value)
|
||||
// })
|
||||
// }).catch(err=>{
|
||||
// console.log(err)
|
||||
// })
|
||||
downloadVoiceFile(_url).then(res=>{
|
||||
if(res?.data){
|
||||
common.msg(res.data.message)
|
||||
|
||||
@@ -446,7 +446,7 @@ const getQuestionInfoUnStudy = (pgrphId) => {
|
||||
id: _id,
|
||||
isQuestion: true
|
||||
}
|
||||
talkingList.value.push(lastTalkingInfo.value)
|
||||
talkingList.value.push(JSON.parse(JSON.stringify(lastTalkingInfo.value)))
|
||||
qstLogId.value = _body.chatBody?.qstLogId
|
||||
scrollToBottomNow()
|
||||
}else{
|
||||
@@ -786,6 +786,7 @@ const submitAnswerNow = (val, cb) => {
|
||||
talkingVoice: '',
|
||||
type: 2,
|
||||
userInfo: {...choiceTeacherInfo.value},
|
||||
qstLogId: qstLogId.value,
|
||||
id: _id
|
||||
})
|
||||
scrollToBottomNow()
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</view>
|
||||
<view class="info-middle font_pf">
|
||||
<view class="fz-30 fw-400 mb-8">更新日期</view>
|
||||
<view class="fz-30 fw-400">{{ common.formatDate2(modelValue.mtTime, 'yyyy-MM-dd HH:mm') }}</view>
|
||||
<view class="fz-30 fw-400">{{ (modelValue.mtTime || '').substr(0,16) }}</view>
|
||||
</view>
|
||||
<view class="info-bottom">
|
||||
<view class="bottom-left">
|
||||
@@ -104,6 +104,7 @@
|
||||
font-size: 22rpx;
|
||||
margin-right: 14rpx;
|
||||
background-color: #f1f3f8;
|
||||
margin-top: 6rpx;
|
||||
}
|
||||
}
|
||||
.bottom-right {
|
||||
|
||||
@@ -130,11 +130,11 @@
|
||||
onMounted(() => {
|
||||
uni.$on('refresh_comment_data', () => {
|
||||
commentRef.value?.getData();
|
||||
tabAct.value = 2
|
||||
})
|
||||
})
|
||||
onLoad((params) => {
|
||||
crsNum.value = params.crsNum;
|
||||
|
||||
});
|
||||
onShow(()=>{
|
||||
getData();
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
<view class="btns-cont">
|
||||
<view class="play-btn">
|
||||
<image class="icon"
|
||||
v-show="!isPlaying"
|
||||
v-show="!(!voiceLoading&&(props.activeVoiceId === dataInfo.id))"
|
||||
@click="playVoice"
|
||||
src="@/static/images/course/play-blue.png"
|
||||
style="width: 100%;height: 100%;"
|
||||
></image>
|
||||
<image class="icon"
|
||||
v-show="isPlaying"
|
||||
v-show="!voiceLoading&&(props.activeVoiceId === dataInfo.id)"
|
||||
@click.stop="pauseVoice"
|
||||
src="@/static/images/course/stop-blue.png"
|
||||
style="width: 100%;height: 100%;"
|
||||
@@ -63,6 +63,7 @@ import { onUnload } from '@dcloudio/uni-app';
|
||||
// 声音播放初始化
|
||||
const talkVoiceObj = ref(null)
|
||||
|
||||
const isPlaying = ref(false)
|
||||
const voiceLoading = ref(false)
|
||||
const translateLoading = ref(false)
|
||||
|
||||
@@ -88,34 +89,35 @@ import { onUnload } from '@dcloudio/uni-app';
|
||||
const pauseVoice = () => {
|
||||
if(!talkVoiceObj.value) return
|
||||
talkVoiceObj.value.pause()
|
||||
isPlaying.value = false
|
||||
emit('changePlay', '')
|
||||
}
|
||||
const playVoice = () =>{
|
||||
emit('changePlay', unref(dataInfo)?.id)
|
||||
if(talkVoiceObj.value && talkVoiceObj.value.src && talkVoiceObj.value.src === itemVoice.value) {
|
||||
if(talkVoiceObj.value && talkVoiceObj.value.src) {
|
||||
talkVoiceObj.value.play()
|
||||
return
|
||||
}else{
|
||||
initVoice()
|
||||
talkVoiceObj.value.src = ''
|
||||
if(itemVoice.value){
|
||||
if(unref(dataInfo).talkingVoice){
|
||||
setTimeout(()=>{
|
||||
talkVoiceObj.value.src = itemVoice.value
|
||||
talkVoiceObj.value.src = unref(dataInfo).talkingVoice
|
||||
talkVoiceObj.value.play()
|
||||
isPlaying.value = true
|
||||
},100)
|
||||
}
|
||||
}
|
||||
}
|
||||
const initVoice = () => {
|
||||
talkVoiceObj.value = uni.createInnerAudioContext()
|
||||
talkVoiceObj.value.onEnded(()=>{
|
||||
emit('changePlay', '')
|
||||
talkVoiceObj.value.src = ''
|
||||
})
|
||||
talkVoiceObj.value.onError(()=>{
|
||||
talkVoiceObj.value.src = ''
|
||||
})
|
||||
if(unref(dataInfo).intrctWay === '02'){
|
||||
talkVoiceObj.value = uni.createInnerAudioContext()
|
||||
talkVoiceObj.value.onEnded(()=>{
|
||||
emit('changePlay', '')
|
||||
talkVoiceObj.value.src = ''
|
||||
})
|
||||
talkVoiceObj.value.onError(()=>{
|
||||
talkVoiceObj.value.src = ''
|
||||
})
|
||||
itemVoice.value = unref(dataInfo).talkingVoice
|
||||
talkVoiceObj.value.src = itemVoice.value
|
||||
setTimeout(()=>{
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
v-if="talkingType === 'question'"
|
||||
@changePlay="changePlay"
|
||||
:dataInfo="talkingInfo"
|
||||
:activeVoiceId="activeVoiceId"
|
||||
></questionVue>
|
||||
<answerVue
|
||||
v-else-if="talkingType === 'answer'"
|
||||
@@ -28,8 +29,13 @@
|
||||
talkingInfo:{
|
||||
default: () => ({}),
|
||||
type: Object
|
||||
},
|
||||
activeVoiceId:{
|
||||
default:'',
|
||||
type: String
|
||||
}
|
||||
})
|
||||
watch(() => props.activeVoiceId, () => {},{deep: true,immediate: true})
|
||||
watch(() => props.talkingInfo, () => {},{deep: true,immediate: true})
|
||||
const { talkingType } = toRefs(props)
|
||||
const handleEvents = (type) => {
|
||||
|
||||
@@ -13,9 +13,11 @@
|
||||
AI问答
|
||||
</view>
|
||||
<view class="ai-info">
|
||||
<image src="@/static/images/dialog/pet-3.png" alt="" class="image-pet-bg"></image>
|
||||
<view class="ai-info-bg-box">
|
||||
<view class="hello-text">Hi,我是{{'李想'}}</view>
|
||||
<!-- <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="userInfo.mascotInfo?.imgAddr ||''" alt="" class="image-pet"></image>
|
||||
<view class="ai-info-bg-box">
|
||||
<view class="hello-text">Hi,我是{{ userInfo.mascotInfo?.mascotName || ''}}</view>
|
||||
<view class="info-text">工作学习,我都能帮你!</view>
|
||||
<view class="info-btn">试试他的能力</view>
|
||||
</view>
|
||||
@@ -50,6 +52,7 @@
|
||||
v-for="item in talkingList"
|
||||
:talkingType="item.type"
|
||||
:talkingInfo="item"
|
||||
:activeVoiceId="activeVoiceTalkingItemId"
|
||||
@handleEvents="talkItemEvents"
|
||||
>
|
||||
</TalkingItem>
|
||||
@@ -101,7 +104,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, unref, onMounted, watch, nextTick } from 'vue'
|
||||
import { ref, unref, onMounted, watch, nextTick, computed } from 'vue'
|
||||
import common from '@/common/common';
|
||||
import TouchBtn from '@/pages/course/components/touchBtn.vue'
|
||||
import TalkingItem from './components/talking-item.vue';
|
||||
@@ -110,12 +113,14 @@
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onLoad, onShow, onUnload, onHide } from '@dcloudio/uni-app';
|
||||
import { get_base_url, goto_login_fun } from '@/api/request'
|
||||
import {
|
||||
commonUploadVoiceFile
|
||||
} from "@/api/common.js"
|
||||
import { getUserInfo } from '@/common/common';
|
||||
import {
|
||||
commonUploadVoiceFile
|
||||
} from "@/api/common.js"
|
||||
|
||||
const socketStore = useSocketStore()
|
||||
const { SocketObj } = storeToRefs(socketStore)
|
||||
const userInfo = computed(() => getUserInfo())
|
||||
|
||||
const questionList = ref([
|
||||
'对公小程序开户流程?',
|
||||
@@ -139,13 +144,15 @@ import {
|
||||
},time)
|
||||
})
|
||||
}
|
||||
|
||||
const activeVoiceTalkingItemId = ref('')
|
||||
// ws 初始化逻辑
|
||||
const reconnectTimer = null // 重连timer
|
||||
const isManualClose = ref(false) // 是否手动关闭
|
||||
const reqBatch = ref('')
|
||||
const seqNo = ref('')
|
||||
const mascotId = ref('Tst00001')
|
||||
const mascotId = computed(() => {
|
||||
return unref(userInfo).mascotInfo?.mascotId || 'Tst00001'
|
||||
})
|
||||
const answerText = ref('')
|
||||
const answerIsOver = ref(true)
|
||||
const talkingList = ref([])
|
||||
@@ -197,7 +204,8 @@ import {
|
||||
talkingText: body.intrctContent,
|
||||
isLoading: false,
|
||||
id: _id,
|
||||
...body
|
||||
...body,
|
||||
talkingVoice: askData.value.talkingVoice
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -246,6 +254,7 @@ import {
|
||||
|
||||
if(commond === 'ASK-ERR'){
|
||||
console.log('提问失败,系统异常!')
|
||||
console.log('body')
|
||||
return
|
||||
}
|
||||
}else{
|
||||
@@ -313,6 +322,7 @@ import {
|
||||
break;
|
||||
case 'changePlay':
|
||||
console.log('播放/暂停')
|
||||
activeVoiceTalkingItemId.value = id
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -349,21 +359,31 @@ import {
|
||||
isLoading: true
|
||||
})
|
||||
scrollToBottomNow()
|
||||
console.log(voicePath,111111111)
|
||||
commonUploadVoiceFile(voicePath, '/traask/traAskchat/voiceTrans', {}).then(res=>{
|
||||
let _res = JSON.parse(res.data)
|
||||
if(_res.rtnCode === '0000'){
|
||||
askData.value = {
|
||||
reqBatch: reqBatch.value,
|
||||
intrctWay: '02',//01-文本;02-语音;03-图片
|
||||
intrctContent: _res.body.transContent,
|
||||
bucketKey: _res.body.fileId,
|
||||
ossFileAddr: _res.body.ossFileAddr,
|
||||
talkingVoice: voicePath
|
||||
if(!!(_res.body.transContent || '').trim()){
|
||||
askData.value = {
|
||||
reqBatch: reqBatch.value,
|
||||
intrctWay: '02',//01-文本;02-语音;03-图片
|
||||
intrctContent: _res.body.transContent,
|
||||
bucketKey: _res.body.fileId,
|
||||
ossFileAddr: _res.body.ossFileAddr,
|
||||
talkingVoice: voicePath
|
||||
}
|
||||
sendMessage({
|
||||
"commond" : 'ASK',
|
||||
"body": askData.value
|
||||
})
|
||||
}else{
|
||||
talkingList.value.pop()
|
||||
uni.showToast({
|
||||
title: '语音内容不能为空!',
|
||||
icon: "none",
|
||||
duration:1000
|
||||
});
|
||||
}
|
||||
sendMessage({
|
||||
"commond" : 'ASK',
|
||||
"body": askData.value
|
||||
})
|
||||
}else{}
|
||||
}).catch(err=>{
|
||||
talkingList.value.pop()
|
||||
@@ -525,14 +545,22 @@ import {
|
||||
margin-bottom: 24rpx;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
.image-pet{
|
||||
width: 230rpx;
|
||||
height: 235rpx;
|
||||
position: absolute;
|
||||
right: 24rpx;
|
||||
top: 15rpx;
|
||||
z-index: 2;
|
||||
}
|
||||
.image-pet-bg{
|
||||
position: absolute;
|
||||
padding: 0 24rpx;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
height: 230rpx;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
.ai-info-bg-box{
|
||||
@@ -567,7 +595,7 @@ import {
|
||||
text-align: center;
|
||||
border-radius: 15rpx 15rpx 0 0;
|
||||
position: absolute;
|
||||
left: 64rpx;
|
||||
left: 68rpx;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,7 +487,7 @@
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
|
||||
overflow-x: hidden;
|
||||
// 背景图
|
||||
.bg_img {
|
||||
position: absolute;
|
||||
|
||||
@@ -1,18 +1,55 @@
|
||||
<template>
|
||||
<view class="main_div max_page">
|
||||
<nav-bar :is_seat="false"></nav-bar>
|
||||
<image src="@/static/images/mascot/bg_1.png" class="bg_img" mode="aspectFit"></image>
|
||||
<!-- <nav-bar :is_seat="false"></nav-bar> -->
|
||||
<view class="bg_img">
|
||||
<image src="@/static/images/mascot/bg_1.png" class="img" mode="aspectFit"></image>
|
||||
</view>
|
||||
<view class="fl1"></view>
|
||||
<view class="title_div">
|
||||
<image src="@/static/images/mascot/title.png" class="img" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="fl1"></view>
|
||||
<view class="mascot_div">
|
||||
<image src="@/static/images/mascot/ma_2.png" class="img" mode="widthFix"></image>
|
||||
<view class="tip_div">
|
||||
<view class="tip_msg">选择形象开启学习之旅</view>
|
||||
</view>
|
||||
<view class="fl1"></view>
|
||||
<view class="mascot_div">
|
||||
<view class="doct_icon left" @click="doct_click(1)">
|
||||
<view class="doct_icon_div">
|
||||
<image src="/src/static/images/mascot/btn_left.png" class="img" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
<swiper class="swiper" circular :current="swiperIndex" @animationfinish='animationfinish'>
|
||||
<swiper-item class="" v-for="(item, index) in mascotList" :key="index">
|
||||
<view class="swiper-item-div">
|
||||
<!-- <image src="@/static/images/mascot/ma_1.png" class="img" mode="widthFix"></image> -->
|
||||
<image-preview :src="item.imgAddr" class="img" mode="widthFix"></image-preview>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<!-- <swiper-item class="">
|
||||
<view class="swiper-item-div">
|
||||
<image src="@/static/images/mascot/ma_2.png" class="img" mode="widthFix"></image>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<swiper-item class="">
|
||||
<view class="swiper-item-div">
|
||||
<image src="@/static/images/mascot/ma_3.png" class="img" mode="widthFix"></image>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<swiper-item class="">
|
||||
<view class="swiper-item-div">
|
||||
<image src="@/static/images/mascot/ma_4.png" class="img" mode="widthFix"></image>
|
||||
</view>
|
||||
</swiper-item> -->
|
||||
</swiper>
|
||||
<view class="doct_icon right" @click="doct_click(-1)">
|
||||
<view class="doct_icon_div">
|
||||
<image src="/src/static/images/mascot/btn_right.png" class="img" mode="widthFix"></image>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="button_div">
|
||||
<image src="@/static/images/mascot/btn_2.png" class="img" mode="aspectFit"></image>
|
||||
<image src="@/static/images/mascot/btn_2.png" class="img" mode="aspectFit" @click="select_it()"></image>
|
||||
</view>
|
||||
<view class="fl1"></view>
|
||||
</view>
|
||||
@@ -20,47 +57,205 @@
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
ref,
|
||||
reactive
|
||||
} from 'vue';
|
||||
import {
|
||||
queryValidTraMascotInfo,
|
||||
setTraMascotInfo
|
||||
} from "@/api/mascot.js"
|
||||
import common from '@/common/common.js'
|
||||
|
||||
import {
|
||||
setUserInfo,
|
||||
getUserInfo
|
||||
} from "@/common/common";
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app';
|
||||
const mascotList = reactive([])
|
||||
onLoad(() => {
|
||||
common.loading()
|
||||
queryValidTraMascotInfo().then(({
|
||||
body
|
||||
}) => {
|
||||
Object.assign(mascotList, {
|
||||
...body
|
||||
})
|
||||
console.log(mascotList);
|
||||
common.hideLoading()
|
||||
})
|
||||
})
|
||||
const swiperCount = 4; // 总共有4个轮播项
|
||||
let swiperIndex = ref(0); // 当前显示第1个(索引0)
|
||||
const isAnimating = ref(false); // 标记动画是否进行中
|
||||
|
||||
const animationfinish = () => {
|
||||
console.log("动画结束,允许下次点击");
|
||||
isAnimating.value = false; // 动画结束后重置状态
|
||||
};
|
||||
|
||||
const doct_click = (num) => {
|
||||
if (isAnimating.value) return; // 1. 如果动画正在进行,直接忽略点击
|
||||
isAnimating.value = true;
|
||||
let newIndex = (swiperIndex.value + num + swiperCount) % swiperCount;
|
||||
swiperIndex.value = newIndex; // 更新当前索引
|
||||
};
|
||||
|
||||
// 选择他
|
||||
const select_it = () => {
|
||||
const item = mascotList[swiperIndex.value]
|
||||
common.loading()
|
||||
setTraMascotInfo({
|
||||
mascotId: item.mascotId
|
||||
}).then(res => {
|
||||
const userInfo = getUserInfo()
|
||||
setUserInfo({
|
||||
...userInfo,
|
||||
'mascotInfo': item
|
||||
})
|
||||
common.hideLoading()
|
||||
common.msg('设置成功')
|
||||
setTimeout(() => {
|
||||
common.navigateBack()
|
||||
}, 400)
|
||||
}).catch(() => {
|
||||
common.hideLoading()
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.title_div{
|
||||
width: 70vw;
|
||||
.img{
|
||||
.title_div {
|
||||
width: 60vw;
|
||||
|
||||
.img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
text-shadow:10rpx 0 30rpx #3c3c3c;
|
||||
}
|
||||
.mascot_div{
|
||||
width: 90vw;
|
||||
.img{
|
||||
width: 100%;
|
||||
|
||||
.tip_div {
|
||||
.tip_msg {
|
||||
font-family: PingFangSC;
|
||||
font-weight: 400;
|
||||
font-size: 30rpx;
|
||||
color: #FFFFFF;
|
||||
line-height: 40rpx;
|
||||
text-align: center;
|
||||
font-style: normal;
|
||||
|
||||
}
|
||||
|
||||
text-shadow:0 0 30rpx #dedede;
|
||||
}
|
||||
.button_div{
|
||||
width: 80vw;
|
||||
.img{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.bg_img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
.mascot_div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.swiper {
|
||||
white-space: nowrap;
|
||||
height: 120vw;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.swiper-item-div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
height: 120vw;
|
||||
|
||||
//
|
||||
.img {
|
||||
width: 80vw;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.doct_icon {
|
||||
padding: 0%;
|
||||
display: flex;
|
||||
|
||||
.doct_icon_div {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 40rpx 0;
|
||||
}
|
||||
|
||||
&.left {
|
||||
top: 40%;
|
||||
left: 2%;
|
||||
z-index: 10;
|
||||
|
||||
}
|
||||
|
||||
&.right {
|
||||
top: 40%;
|
||||
right: 2%;
|
||||
}
|
||||
|
||||
position:absolute;
|
||||
width:100rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
.img {
|
||||
width: 40%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.button_div {
|
||||
// width: 50vw;
|
||||
margin-top: 20rpx;
|
||||
width: 80%;
|
||||
height: 120rpx;
|
||||
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.bg_img {
|
||||
position: absolute;
|
||||
top: -2%;
|
||||
left: -1%;
|
||||
width: 102%;
|
||||
height: 104%;
|
||||
z-index: -1;
|
||||
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.main_div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
max-width: 100vh;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
@@ -8,7 +8,6 @@
|
||||
<view class="title font_pf">设置</view>
|
||||
</view>
|
||||
<view class="detail-body">
|
||||
|
||||
<uv-cell-group :border="false">
|
||||
<uv-cell @click="click_update_avatar" name="avatar" isLink title="头像">
|
||||
<template #title>
|
||||
@@ -32,7 +31,7 @@
|
||||
</picker>
|
||||
</template>
|
||||
</uv-cell>
|
||||
<uv-cell title="形象" @click="common.navigateTo('/pages/mascot/mascot_select_list')" :isLink="true" :border="false"></uv-cell>
|
||||
<uv-cell title="形象" @click="gotoMascot()" :isLink="true" :border="false"></uv-cell>
|
||||
</uv-cell-group>
|
||||
</view>
|
||||
<avatar-cropper v-if="avatarCropperStatus" mode="ratio" :imageUrl="avatarCropperUrl" :width="500" :height="500"
|
||||
@@ -63,7 +62,10 @@
|
||||
updateDfSysUserExtandInfoGender,
|
||||
updateDfSysUserExtandInfoImageAddr
|
||||
} from "@/api/user.js"
|
||||
|
||||
import {queryValidTraMascotInfo} from "@/api/mascot.js"
|
||||
import {
|
||||
get_base_url
|
||||
} from '@/api/request.js'
|
||||
const index = ref(0);
|
||||
const avatarCropperUrl = ref('');
|
||||
const aaa = ref('');
|
||||
@@ -74,6 +76,40 @@
|
||||
});
|
||||
const avatarCropperStatus = ref(true)
|
||||
const sexOptions = GENDER
|
||||
const base_url = get_base_url()
|
||||
|
||||
// 去选择百禄
|
||||
const gotoMascot = () => {
|
||||
|
||||
common.navigateTo('/pages/mascot/mascot_select_list')
|
||||
|
||||
// common.loading()
|
||||
// queryValidTraMascotInfo().then(({body}) => {
|
||||
// console.log(body);
|
||||
// common.setPageCache('mascotList', body)
|
||||
// body.map(({imgAddr}) => {
|
||||
// const url = imgAddr
|
||||
// if (imgAddr){
|
||||
// const img = new Image();
|
||||
// img.onload = () => {
|
||||
// console.log(`图片缓存成功: ${url}`);
|
||||
// // resolve(img);
|
||||
// };
|
||||
|
||||
// img.onerror = () => {
|
||||
// console.error(`图片缓存失败: ${url}`);
|
||||
// // reject(new Error(`Failed to load image: ${url}`));
|
||||
// };
|
||||
|
||||
// img.src = base_url + url;
|
||||
// }
|
||||
// })
|
||||
// common.hideLoading()
|
||||
// common.navigateTo('/pages/mascot/mascot_select_list')
|
||||
|
||||
// })
|
||||
}
|
||||
|
||||
const showGenderText = computed(() => {
|
||||
const item = sexOptions.find((item) => item.value == userInfo.value.gender)
|
||||
if (item) {
|
||||
|
||||
|
After Width: | Height: | Size: 344 KiB |
|
After Width: | Height: | Size: 133 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 31 KiB |