本地临时存储
This commit is contained in:
+133
-133
@@ -1,149 +1,149 @@
|
||||
<script>
|
||||
export default {
|
||||
onLaunch: function () {
|
||||
uni.onTabBarMidButtonTap(() => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/index/dialog',
|
||||
animationType: 'slide-in-bottom'
|
||||
export default {
|
||||
onLaunch: function () {
|
||||
uni.onTabBarMidButtonTap(() => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/index/dialog',
|
||||
animationType: 'slide-in-bottom'
|
||||
});
|
||||
});
|
||||
})
|
||||
// console.log('预加载');
|
||||
},
|
||||
onShow: function () {
|
||||
// console.log('App Show')
|
||||
},
|
||||
onHide: function () {
|
||||
// console.log('App Hide')
|
||||
}
|
||||
};
|
||||
// console.log('预加载');
|
||||
},
|
||||
onShow: function () {
|
||||
// console.log('App Show')
|
||||
},
|
||||
onHide: function () {
|
||||
// console.log('App Hide')
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/* 注意要写在第一行,同时给style标签加入lang="scss"属性 */
|
||||
// @import "@/uni_modules/uview-ui/index.scss";
|
||||
/* 注意要写在第一行,同时给style标签加入lang="scss"属性 */
|
||||
// @import "@/uni_modules/uview-ui/index.scss";
|
||||
|
||||
@font-face {
|
||||
font-family: 'PingFangSC';
|
||||
src: url('@/static/font/PingFang-SC.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
view {
|
||||
box-sizing: border-box;
|
||||
font-family: "PingFangSC";
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'PingFangSC';
|
||||
src: url('@/static/font/PingFang-SC.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
view {
|
||||
box-sizing: border-box;
|
||||
font-family: 'PingFangSC';
|
||||
}
|
||||
|
||||
// 解决uview离线环境下没有图标
|
||||
@font-face {
|
||||
font-family: 'uicon-iconfont';
|
||||
src: url('@/static/font/font_2225171_8kdcwk4po24.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
// 解决uview离线环境下没有图标
|
||||
@font-face {
|
||||
font-family: 'uicon-iconfont';
|
||||
src: url('@/static/font/font_2225171_8kdcwk4po24.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.max_page {
|
||||
min-height: 100vh;
|
||||
}
|
||||
.mr-10 {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
.mb-8 {
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
.pt-8 {
|
||||
padding-top: 8rpx;
|
||||
}
|
||||
.mb- {
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
.mb-18 {
|
||||
margin-bottom: 18rpx;
|
||||
}
|
||||
.mb-64 {
|
||||
margin-bottom: 64rpx;
|
||||
}
|
||||
.mb-30 {
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
.mb-36 {
|
||||
margin-bottom: 36rpx;
|
||||
}
|
||||
.mb-4 {
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
.fz-30 {
|
||||
font-size: 30rpx;
|
||||
}
|
||||
.fz-28 {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.fz-24 {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.w_100 {
|
||||
width: 100%;
|
||||
}
|
||||
.max_page {
|
||||
min-height: 100vh;
|
||||
}
|
||||
.mr-10 {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
.mb-8 {
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
.pt-8 {
|
||||
padding-top: 8rpx;
|
||||
}
|
||||
.mb- {
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
.mb-18 {
|
||||
margin-bottom: 18rpx;
|
||||
}
|
||||
.mb-64 {
|
||||
margin-bottom: 64rpx;
|
||||
}
|
||||
.mb-30 {
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
.mb-36 {
|
||||
margin-bottom: 36rpx;
|
||||
}
|
||||
.mb-4 {
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
.fz-30 {
|
||||
font-size: 30rpx;
|
||||
}
|
||||
.fz-28 {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.fz-24 {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.w_100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.h_100 {
|
||||
height: 100%;
|
||||
}
|
||||
.h_100 {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
.flex-jcsb {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.flex-c-c {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.tar{
|
||||
text-align: right;
|
||||
}
|
||||
.fw-600 {
|
||||
font-weight: 600;
|
||||
}
|
||||
.fw-400 {
|
||||
font-weight: 400;
|
||||
}
|
||||
.img_100 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
.flex-jcsb {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.flex-c-c {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.tar {
|
||||
text-align: right;
|
||||
}
|
||||
.fw-600 {
|
||||
font-weight: 600;
|
||||
}
|
||||
.fw-400 {
|
||||
font-weight: 400;
|
||||
}
|
||||
.img_100 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.fl1 {
|
||||
flex: 1;
|
||||
}
|
||||
.fl1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.font_pf {
|
||||
font-family: 'PingFangSC';
|
||||
}
|
||||
.font_pf {
|
||||
font-family: 'PingFangSC';
|
||||
}
|
||||
|
||||
.ellipsis-text {
|
||||
white-space: nowrap;
|
||||
/* 强制不换行 */
|
||||
overflow: hidden;
|
||||
/* 超出部分隐藏 */
|
||||
text-overflow: ellipsis;
|
||||
/* 超出部分显示省略号 */
|
||||
}
|
||||
.ellipsis-text {
|
||||
white-space: nowrap;
|
||||
/* 强制不换行 */
|
||||
overflow: hidden;
|
||||
/* 超出部分隐藏 */
|
||||
text-overflow: ellipsis;
|
||||
/* 超出部分显示省略号 */
|
||||
}
|
||||
|
||||
/* 多行文本溢出 */
|
||||
.multi-line-ellipsis {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
/* 显示的行数 */
|
||||
overflow: hidden;
|
||||
}
|
||||
/* 多行文本溢出 */
|
||||
.multi-line-ellipsis {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
/* 显示的行数 */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.no-overflow{
|
||||
overflow: hidden;
|
||||
}
|
||||
.bold{
|
||||
font-weight: bold;
|
||||
}
|
||||
.no-overflow {
|
||||
overflow: hidden;
|
||||
}
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
+2
-2
@@ -72,7 +72,7 @@ export const commonUploadVoiceFile = (file, url, data = {}, fileKey='voice') =>
|
||||
};
|
||||
if (token)
|
||||
header['summary'] = token
|
||||
console.log(`${base_url}${url}`)
|
||||
// console.log(`${base_url}${url}`)
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.uploadFile({
|
||||
url: `${base_url}${url}`,
|
||||
@@ -83,7 +83,7 @@ export const commonUploadVoiceFile = (file, url, data = {}, fileKey='voice') =>
|
||||
success(result) {
|
||||
try {
|
||||
const res = JSON.parse(result.data);
|
||||
console.log(res)
|
||||
// console.log(res)
|
||||
if (res.rtnCode === '0000') {
|
||||
resolve(result);
|
||||
} else {
|
||||
|
||||
@@ -1,21 +1,49 @@
|
||||
<template>
|
||||
<view class="talk-btns">
|
||||
<uv-button class="touch-btn" @touchstart="startRecord" @touchend="stopRecord" @touchmove="handleMove"
|
||||
v-if="!keyboardIsShow" :customStyle="{height:'92rpx'}">按住说话
|
||||
<uv-button
|
||||
class="touch-btn"
|
||||
@touchstart="startRecord"
|
||||
@touchend="stopRecord"
|
||||
@touchmove="handleMove"
|
||||
v-if="!keyboardIsShow"
|
||||
:customStyle="{ height: '92rpx' }"
|
||||
>
|
||||
按住说话
|
||||
</uv-button>
|
||||
<view class="touch-btn" v-if="keyboardIsShow">
|
||||
<uv-input class="input-box" ref="inputRef" v-model="inputText" :maxlength="props.textValueLength"
|
||||
:adjustPosition="false" placeholderStyle='color:#999999;font-size:26rpx' placeholder="请输入文字">
|
||||
</uv-input>
|
||||
<uv-input
|
||||
class="input-box"
|
||||
ref="inputRef"
|
||||
v-model="inputText"
|
||||
:maxlength="props.textValueLength"
|
||||
:adjustPosition="false"
|
||||
placeholderStyle="color:#999999;font-size:26rpx"
|
||||
placeholder="请输入文字"
|
||||
></uv-input>
|
||||
</view>
|
||||
<view class="talk-btn-box">
|
||||
<image class="talk-btn-icon" v-show="!keyboardIsShow" src="@/static/images/course/jianpan.png" mode=""
|
||||
@click="changeBtn"></image>
|
||||
<image class="talk-btn-icon" v-show="keyboardIsShow && !inputText" src="@/static/images/course/record.png"
|
||||
mode="" @click="changeBtn"></image>
|
||||
<image
|
||||
class="talk-btn-icon"
|
||||
v-show="!keyboardIsShow"
|
||||
src="@/static/images/course/jianpan.png"
|
||||
mode=""
|
||||
@click="changeBtn"
|
||||
></image>
|
||||
<image
|
||||
class="talk-btn-icon"
|
||||
v-show="keyboardIsShow && !inputText"
|
||||
src="@/static/images/course/record.png"
|
||||
mode=""
|
||||
@click="changeBtn"
|
||||
></image>
|
||||
|
||||
<image class="talk-btn-icon" v-show="keyboardIsShow && !!inputText" src="@/static/images/course/send.png"
|
||||
mode="" @click.stop="showKeyboard"></image>
|
||||
<image
|
||||
class="talk-btn-icon"
|
||||
v-show="keyboardIsShow && !!inputText"
|
||||
src="@/static/images/course/send.png"
|
||||
mode=""
|
||||
@click.stop="showKeyboard"
|
||||
></image>
|
||||
</view>
|
||||
|
||||
<uni-popup ref="popupRef" class="popup">
|
||||
@@ -27,39 +55,27 @@
|
||||
</view>
|
||||
<view class="tips-box">松开发送</view>
|
||||
<view class="btns-box">
|
||||
<view :class="['close-btn',isOut?'is-out':'']" id="circleBox">取消
|
||||
<view :class="['close-btn', isOut ? 'is-out' : '']" id="circleBox">
|
||||
取消
|
||||
<image class="btn-box" v-if="!isOut" src="@/static/images/course/close.png" mode=""></image>
|
||||
<image class="btn-box" v-else src="@/static/images/course/close-active.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
<view :class="['talk-dialog',isOut?'is-out':'']">
|
||||
<view :class="['talk-dialog', isOut ? 'is-out' : '']">
|
||||
<image src="@/static/images/course/voice-white.gif" mode="" class="gif-box"></image>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
toRefs,
|
||||
ref,
|
||||
computed,
|
||||
unref,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
nextTick,
|
||||
watch,
|
||||
reactive
|
||||
} from 'vue';
|
||||
import { toRefs, ref, computed, unref, onMounted, onUnmounted, nextTick, watch, reactive } from 'vue';
|
||||
import common from '@/common/common';
|
||||
import permission from '@/common/permission.js'
|
||||
import {
|
||||
getPhoneEnvBool
|
||||
} from '@/common/common.js'
|
||||
import permission from '@/common/permission.js';
|
||||
import { getPhoneEnvBool } from '@/common/common.js';
|
||||
|
||||
const emit = defineEmits(['submit'])
|
||||
const emit = defineEmits(['submit']);
|
||||
const props = defineProps({
|
||||
isDisabled: {
|
||||
default: true,
|
||||
@@ -85,140 +101,116 @@
|
||||
type: Number,
|
||||
default: 500
|
||||
},
|
||||
minRecordDuration: { // 最小录音间隔
|
||||
minRecordDuration: {
|
||||
// 最小录音间隔
|
||||
type: Number,
|
||||
default: 1000
|
||||
},
|
||||
|
||||
})
|
||||
const {
|
||||
isDisabled,
|
||||
} = toRefs(props)
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
const { isDisabled } = toRefs(props);
|
||||
|
||||
// 键盘还是语音
|
||||
const keyboardIsShow = ref(false)
|
||||
const popupRef = ref(null)
|
||||
|
||||
watch(() => props.isLoading, () => {}, {
|
||||
deep: true,
|
||||
immediate: true
|
||||
})
|
||||
watch(() => props.canAnswer, () => {}, {
|
||||
deep: true,
|
||||
immediate: true
|
||||
})
|
||||
|
||||
watch(() => props.isDisabled, (val) => {
|
||||
if (val) {
|
||||
keyboardIsShow.value = false
|
||||
}
|
||||
}, {
|
||||
deep: true,
|
||||
immediate: true
|
||||
})
|
||||
|
||||
const inputText = ref('')
|
||||
const keyboardIsShow = ref(false);
|
||||
const popupRef = ref(null);
|
||||
const inputText = ref('');
|
||||
let startTime = 0;
|
||||
|
||||
// not_started 未开始, preparing 准备中, in_recording 录音中,ending 结束中
|
||||
const recordingStatus = ref('not_started')
|
||||
const recordingStatus = ref('not_started');
|
||||
// 获取全局唯一的录音管理器 recorderManager
|
||||
const recorderManager = uni.getRecorderManager();
|
||||
// const innerAudioContext = uni.createInnerAudioContext();
|
||||
const startTimer = ref(null); // 延迟启动的定时器ID
|
||||
const startFlag = ref(1)
|
||||
const startRecord = (obj) => { // 开始录音
|
||||
const startFlag = ref(1);
|
||||
const startRecord = (obj) => {
|
||||
// 开始录音
|
||||
console.log('开始录音', recordingStatus.value);
|
||||
if (recordingStatus.value !== 'not_started') return;
|
||||
touchY.value = obj.changedTouches[0].pageY
|
||||
touchY.value = obj.changedTouches[0].pageY;
|
||||
startTimer.value = setTimeout(() => {
|
||||
console.log('延迟开始');
|
||||
recordingStatus.value = 'preparing'
|
||||
isMoving.value = true
|
||||
recordingStatus.value = 'preparing';
|
||||
popupRef.value.open();
|
||||
recorderManager.start();
|
||||
}, 80);
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
// 结束录音
|
||||
const stopRecord = (obj) => {
|
||||
console.log('结束录音', obj);
|
||||
const stopRecord = () => {
|
||||
console.log('结束录音');
|
||||
if (startTimer.value) {
|
||||
clearTimeout(startTimer.value);
|
||||
startTimer.value = null;
|
||||
}
|
||||
recorderManager.stop();
|
||||
popupRef.value.close()
|
||||
nextTick(() => {
|
||||
setTimeout(() => {
|
||||
recordingStatus.value = 'not_started'
|
||||
}, 300)
|
||||
})
|
||||
}
|
||||
const endTime = Date.now();
|
||||
const times = Math.max(400 - endTime + startTime, 0);
|
||||
setTimeout(() => {
|
||||
console.log('延迟数据', times);
|
||||
nextTick(() => {
|
||||
popupRef.value.close();
|
||||
recorderManager.stop();
|
||||
});
|
||||
}, times);
|
||||
nextTick(() => setTimeout(() => recordingStatus.value = 'not_started', 300));
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
recorderManager.onStop(function(res) {
|
||||
recorderManager.onStop(function (res) {
|
||||
console.log('recorder stop' + JSON.stringify(res));
|
||||
console.log('录音文件临时位置', res.tempFilePath);
|
||||
if (isOut) return; // 被划掉的语音
|
||||
console.log('录音文件临时位置', res.tempFilePath, isOut.value);
|
||||
if (isOut.value) return; // 被划掉的语音
|
||||
const endTime = Date.now();
|
||||
const recordDuration = (endTime - startTime);
|
||||
const recordDuration = endTime - startTime;
|
||||
console.log('说话时长', recordDuration);
|
||||
if (props.minRecordDuration > recordDuration) {
|
||||
return common.msg('说话时间太短,没有听清!')
|
||||
nextTick(()=>common.msg('说话时间太短,没有听清!'))
|
||||
return ;
|
||||
}
|
||||
console.log('录音结束,时长:', recordDuration, '秒');
|
||||
emit('submit', 'voice', res.tempFilePath)
|
||||
emit('submit', 'voice', res.tempFilePath);
|
||||
});
|
||||
recorderManager.onStart(function(res) {
|
||||
recorderManager.onStart(function (res) {
|
||||
// 检测是否已经抬手结束了
|
||||
console.log('检测是否已经抬手结束了', recordingStatus.value);
|
||||
if (recordingStatus.value !== 'preparing') {
|
||||
|
||||
stopRecord()
|
||||
stopRecord();
|
||||
}
|
||||
startTime = Date.now();
|
||||
popupRef.value.open()
|
||||
recordingStatus.value = 'in_recording'
|
||||
recordingStatus.value = 'in_recording';
|
||||
});
|
||||
})
|
||||
|
||||
const touchY = ref(0)
|
||||
const windowInfo = uni.getWindowInfo()
|
||||
|
||||
});
|
||||
|
||||
const touchY = ref(0);
|
||||
const windowInfo = uni.getWindowInfo();
|
||||
// 安全区域信息
|
||||
const safeArea = windowInfo.safeArea;
|
||||
|
||||
// 计算是否超出按下盒子位置
|
||||
const isOut = computed(() => {
|
||||
const btnHeight = windowInfo.screenWidth / 750 * 234;
|
||||
const btnHeight = (windowInfo.screenWidth / 750) * 234;
|
||||
return touchY.value < safeArea.bottom - btnHeight;
|
||||
});
|
||||
const activeNum = ref(1)
|
||||
|
||||
const isMoving = ref(false)
|
||||
|
||||
const activeNum = ref(1);
|
||||
const handleMove = (obj) => {
|
||||
touchY.value = obj.changedTouches[0].pageY
|
||||
}
|
||||
touchY.value = obj.changedTouches[0].pageY;
|
||||
};
|
||||
// 发送文本
|
||||
const showKeyboard = () => {
|
||||
if (keyboardIsShow.value) {
|
||||
const inputTextTram = inputText.value.trim()
|
||||
const inputTextTram = inputText.value.trim();
|
||||
if (inputTextTram) {
|
||||
emit('submit', 'text', inputTextTram)
|
||||
emit('submit', 'text', inputTextTram);
|
||||
} else {
|
||||
common.msg("不能发送空白消息!")
|
||||
common.msg('不能发送空白消息!');
|
||||
}
|
||||
} else {
|
||||
keyboardIsShow.value = !keyboardIsShow.value
|
||||
keyboardIsShow.value = !keyboardIsShow.value;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
// 切换键盘语音
|
||||
const changeBtn = () => {
|
||||
if (props.isDisabled) return
|
||||
keyboardIsShow.value = !keyboardIsShow.value
|
||||
inputText.value = ''
|
||||
}
|
||||
if (props.isDisabled) return;
|
||||
keyboardIsShow.value = !keyboardIsShow.value;
|
||||
inputText.value = '';
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -230,7 +222,7 @@
|
||||
|
||||
.touch-btn {
|
||||
height: 92rpx;
|
||||
box-shadow: 0 8rpx 20rpx 0 rgba(0, 0, 0, .06);
|
||||
box-shadow: 0 8rpx 20rpx 0 rgba(0, 0, 0, 0.06);
|
||||
text-align: center;
|
||||
line-height: 92rpx;
|
||||
color: #000;
|
||||
@@ -409,4 +401,4 @@
|
||||
::v-deep .uv-input__content__field-wrapper__field {
|
||||
padding-right: 60rpx;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<view class="nav-bar-div" >
|
||||
<view class="nav-bar" v-if="is_fixed" :style="{ backgroundColor: backgroundColor }"></view>
|
||||
<view class="nav-bar-seat" v-if="is_seat" :style="{ backgroundColor: backgroundColor }"></view>
|
||||
</view>
|
||||
<!-- <view class="nav-bar-div" >
|
||||
<view class="nav-bar" v-if="props.is_fixed" :style="{ backgroundColor: props.backgroundColor }"></view>
|
||||
<view class="nav-bar-seat" :style="{ backgroundColor: props.backgroundColor }"></view>
|
||||
</view> -->
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const windowInfo = uni.getWindowInfo()
|
||||
// const windowInfo = uni.getWindowInfo()
|
||||
|
||||
const props = defineProps({
|
||||
is_fixed: {
|
||||
@@ -34,11 +34,13 @@
|
||||
.nav-bar-seat {
|
||||
width: 100%;
|
||||
height: var(--status-bar-height);
|
||||
height: 200rpx;
|
||||
background-color: gold;
|
||||
}
|
||||
|
||||
.nav-bar-div {
|
||||
z-index: 1900;
|
||||
z-index: 2001;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
// position: relative;
|
||||
}
|
||||
</style>
|
||||
+1
-1
@@ -30,5 +30,5 @@ export const SUBJECT_TYPE = [{
|
||||
{
|
||||
value: "ES",
|
||||
label: "问答题",
|
||||
},
|
||||
}
|
||||
]
|
||||
@@ -89,7 +89,7 @@
|
||||
<view class="title">AI问答</view>
|
||||
</view>
|
||||
|
||||
<view class="item">
|
||||
<view class="item" @click="common.navigateTo('/pages/learningTasks/details')">
|
||||
<image class="icon" src="@/static/images/index/navigation_ai.png"></image>
|
||||
<view class="title">AI陪练</view>
|
||||
</view>
|
||||
|
||||
@@ -1,8 +1,272 @@
|
||||
<template>
|
||||
<view class="main_div max_page">
|
||||
<nav-bar :is_seat="true"></nav-bar>
|
||||
<view class="body-title">
|
||||
<view class="back_div" @click="common.navigateBack()">
|
||||
<view class="back-icon"></view>
|
||||
</view>
|
||||
<view>任务详情</view>
|
||||
</view>
|
||||
<view class="detail_div" :class="'completed'">
|
||||
<view class="subscript" v-if="detailData.examStatText === 'N'">未完成</view>
|
||||
<view class="subscript" v-if="detailData.examStatText === 'Y'">已完成</view>
|
||||
<view class="left">
|
||||
<image src="/src/static/images/test/2.png" mode="aspectFill" class="img"></image>
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="title_div">
|
||||
<view class="title">
|
||||
JBank银行服诉旦撒大银行服诉旦撒大银行服诉旦撒大银行服诉旦撒大银行服诉旦撒大银行服诉旦撒大
|
||||
</view>
|
||||
</view>
|
||||
<view class="time">
|
||||
<text class="color_3">起止时间:</text>
|
||||
<text class="color_class">2025-05-13至2025-05-13</text>
|
||||
</view>
|
||||
<view class="num_div">
|
||||
<view class="num_div_item">
|
||||
<text class="color_3">完成人数:</text>
|
||||
<text class="color_2">34/125</text>
|
||||
</view>
|
||||
<view class="num_div_item">
|
||||
<text class="color_3">进度:</text>
|
||||
<text class="color_2">2/4门课程</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view
|
||||
ref="scrollRef"
|
||||
:scroll-y="true"
|
||||
class="scroll-Y"
|
||||
:show-scrollbar="false"
|
||||
@scrolltolower="scrolltolower"
|
||||
></scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import { reactive, computed } from 'vue';
|
||||
import { startTraExamPapersInfo } from '@/api/examination.js';
|
||||
|
||||
import common from '@/common/common';
|
||||
import { setPageCache, getPageCache } from '@/common/common';
|
||||
const detailData = reactive({
|
||||
papersId: '',
|
||||
papersName: '',
|
||||
examStartTm: '',
|
||||
examEndTm: '',
|
||||
execPersionNumer: '',
|
||||
planPersionNumber: '',
|
||||
judgeNumber: 0,
|
||||
singleNumber: 0,
|
||||
multiNumber: 0,
|
||||
essayNumber: 0,
|
||||
judgeGrade: 0,
|
||||
singleGrade: 0,
|
||||
multiGrade: 0,
|
||||
essayGrade: 0
|
||||
});
|
||||
const scrolltolower = () => {};
|
||||
onLoad((e) => {
|
||||
const testing_hall_details = getPageCache('testing_hall_details');
|
||||
Object.assign(detailData, {
|
||||
...testing_hall_details
|
||||
});
|
||||
console.log('detailData', detailData);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
<style scoped lang="scss">
|
||||
.scroll-Y {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: calc(100vh - var(--status-bar-height) - 120rpx - 250rpx + 20rpx + 20rpx - 20rpx);
|
||||
width: calc(100% - 52rpx);
|
||||
margin: 0 auto;
|
||||
background: linear-gradient(180deg, #ebf2fe 0%, #f3f7fe 6%, #fafbfc 12%, #fafbfc 100%);
|
||||
border-radius: 16rpx;
|
||||
margin-top: -20rpx;
|
||||
z-index: 2;
|
||||
box-shadow: 0 0 6rpx #fafbfc;
|
||||
border: 4rpx solid #FFFFFF;
|
||||
|
||||
}
|
||||
|
||||
.main_div {
|
||||
background-image: url('@/static/images/learningTasks/learningTasksBg.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% calc(420rpx + var(--status-bar-height)); /* 宽度充满,高度自适应比例 */
|
||||
background-position: top;
|
||||
background-color: #fff;
|
||||
}
|
||||
.body-title {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
height: 120rpx;
|
||||
line-height: 60rpx;
|
||||
font-family: PingFangSC;
|
||||
font-weight: 600;
|
||||
font-size: 32rpx;
|
||||
color: #000000;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.detail_div {
|
||||
margin-top: -20rpx;
|
||||
height: 250rpx;
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
padding: 36rpx 40rpx 20rpx 40rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 16rpx 16rpx 0 0;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
|
||||
.subscript {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 102rpx;
|
||||
height: 42rpx;
|
||||
font-family: PingFangSC;
|
||||
font-weight: 400;
|
||||
font-size: 24rpx;
|
||||
line-height: 42rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 0 0 0 28rpx;
|
||||
}
|
||||
.left > .img {
|
||||
width: 225rpx;
|
||||
height: 169rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
.right {
|
||||
margin-left: 24rpx;
|
||||
.title_div {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex: 1;
|
||||
.title {
|
||||
font-family: PingFangSC;
|
||||
font-weight: 600;
|
||||
color: #000000;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
font-size: 28rpx; /* 字体大小30rpx */
|
||||
display: -webkit-box; /* 启用弹性盒模型 */
|
||||
-webkit-box-orient: vertical; /* 设置盒子内子元素的排列方向为垂直 */
|
||||
-webkit-line-clamp: 2; /* 限制最多显示2行 */
|
||||
overflow: hidden; /* 超出部分隐藏 */
|
||||
text-overflow: ellipsis; /* 超出部分显示省略号(多行时可能不显示,但建议保留) */
|
||||
line-height: 1.5; /* 可选:设置行高,优化多行显示效果 */
|
||||
}
|
||||
}
|
||||
|
||||
.time {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
line-height: 30rpx;
|
||||
font-family: Arial;
|
||||
font-weight: 400;
|
||||
color: #666666;
|
||||
margin-top: 12rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.num_div {
|
||||
font-family: PingFangSC;
|
||||
font-weight: 400;
|
||||
font-size: 24rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: nowrap;
|
||||
overflow: hidden;
|
||||
height: 28rpx;
|
||||
.num_div_item {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
line-height: 28rpx;
|
||||
height: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.color_1 {
|
||||
color: #d70c18;
|
||||
}
|
||||
|
||||
.color_2 {
|
||||
color: #111111;
|
||||
}
|
||||
|
||||
.color_3 {
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.incomplete {
|
||||
// 进行中
|
||||
.subscript {
|
||||
color: #ffffff;
|
||||
background-color: #ef5705;
|
||||
}
|
||||
|
||||
.color_class {
|
||||
color: #d70c18;
|
||||
}
|
||||
}
|
||||
|
||||
.completed {
|
||||
// 已完成
|
||||
.subscript {
|
||||
color: #ffffff;
|
||||
background-color: #33c583;
|
||||
}
|
||||
|
||||
.color_class {
|
||||
color: #0066ff;
|
||||
}
|
||||
}
|
||||
|
||||
.back_div {
|
||||
position: absolute;
|
||||
left: 26rpx;
|
||||
height: 100%;
|
||||
top: -30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.back-icon {
|
||||
position: relative;
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.back-icon::before,
|
||||
.back-icon::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.back-icon::after {
|
||||
top: 25%;
|
||||
left: 25%;
|
||||
width: 40%;
|
||||
height: 40%;
|
||||
border-top: 4rpx solid #000000;
|
||||
border-left: 4rpx solid #000000;
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
:refresher-triggered="triggered"
|
||||
refresher-default-style="none"
|
||||
>
|
||||
<view class="item" v-for="(item, index) in data_list" @click="readMessage(item)">
|
||||
<view class="item" v-for="(item, index) in data_list" @click="readMessageOpen(item)">
|
||||
<view class="icon">
|
||||
<image
|
||||
v-if="item.noticeTyp == '01'"
|
||||
@@ -74,13 +74,13 @@
|
||||
<uv-load-more v-if="total != 0" :status="status" loadmore-text="轻轻上拉加载" :height="30"></uv-load-more>
|
||||
</scroll-view>
|
||||
<uni-popup ref="popup" type="bottom">
|
||||
<view class="popup" @click.stop="getCode">
|
||||
<view class="popup">
|
||||
<view class="message_popup_div">
|
||||
<view class="title">
|
||||
{{ popup_info.title }}
|
||||
</view>
|
||||
<view class="text">消正息内容正文,消息内容正文</view>
|
||||
<view class="button_div" @click.stop="getCode">
|
||||
<view class="button_div" @click.stop="readMessage">
|
||||
<uv-button class="button">我知道了</uv-button>
|
||||
</view>
|
||||
</view>
|
||||
@@ -92,7 +92,7 @@
|
||||
<script setup>
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import { queryTraPersonalMessageNoticePaging } from '@/api/messageNotification.js';
|
||||
import { queryTraPersonalMessageNoticePaging, readNotice } from '@/api/messageNotification.js';
|
||||
|
||||
const customStyle = {
|
||||
backgroundColor: '#ffffff',
|
||||
@@ -106,14 +106,6 @@
|
||||
color: '#2c8ef2',
|
||||
fontSize: '50rpx'
|
||||
};
|
||||
const options = [
|
||||
{
|
||||
text: '删除',
|
||||
style: {
|
||||
backgroundColor: '#f56c6c'
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const status = ref('loadmore'); // loadmore - 加载前,loading - 加载中,nomore - 没有数据
|
||||
const limit = 15;
|
||||
@@ -181,39 +173,36 @@
|
||||
});
|
||||
};
|
||||
|
||||
const readMessage = () => {
|
||||
readNotice({ noticeId: popup_info.id }).then(() => {
|
||||
// todo
|
||||
popup.value.close();
|
||||
});
|
||||
};
|
||||
// 读取消息
|
||||
const readMessage = (item) => {
|
||||
console.log('readMessage', item);
|
||||
const readMessageOpen = (item) => {
|
||||
popup_info.id = item.noticeId;
|
||||
popup_info.title = item.noticeTitle;
|
||||
popup_info.text = item.noticeContent;
|
||||
// popup_info.id = '';
|
||||
// popup_info.title = '课程提醒';
|
||||
// popup_info.text = '这里是水水哈斯滴撒的撒嗲是对赛道';
|
||||
popup.value.open();
|
||||
};
|
||||
const scrolltolower = (item) => {
|
||||
getData();
|
||||
};
|
||||
onMounted(() => {
|
||||
// triggered.value = true;
|
||||
getData();
|
||||
// setTimeout(() => {
|
||||
// triggered.value = true
|
||||
// message_list.value.push(...[1, 2, 3, 4, 5])
|
||||
// }, 1000)
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.popup{
|
||||
.popup {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
position: relative;
|
||||
}
|
||||
.message_popup_div {
|
||||
width: 580rpx;
|
||||
border-radius: 38px;
|
||||
border-radius: 38rpx;
|
||||
background: #ffffff url('@/static/images/messageNotification/popup_bg.png') no-repeat center -4rpx;
|
||||
background-size: auto 50%;
|
||||
background-color: #ffffff;
|
||||
@@ -226,7 +215,7 @@
|
||||
padding: 0 40rpx;
|
||||
width: 100%;
|
||||
height: 90rpx;
|
||||
line-height: 90rpx;
|
||||
line-height: 110rpx;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -239,7 +228,7 @@
|
||||
line-height: 48rpx;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
min-height: 240rpx;
|
||||
min-height: 300rpx;
|
||||
max-height: 650rpx;
|
||||
overflow: auto;
|
||||
}
|
||||
@@ -423,4 +412,4 @@
|
||||
margin: 20rpx auto;
|
||||
height: 78rpx;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<view class="main_div max_page">
|
||||
<nav-bar backgroundColor="red"></nav-bar>
|
||||
<view class="body-title">
|
||||
<view class="back_div" @click="common.navigateBack()">
|
||||
<view class="back-icon"></view>
|
||||
@@ -25,7 +26,7 @@
|
||||
<view class="paper">
|
||||
<!-- 试卷信息 -->
|
||||
<view class="paper_title_div">
|
||||
<image src="@/static/images/testingHall/testing.png" mode="heightFix" class="img"></image>
|
||||
<image src="@/static/images/testingHall/testing.png" class="img"></image>
|
||||
<view class="title">
|
||||
试卷信息
|
||||
</view>
|
||||
@@ -262,8 +263,6 @@
|
||||
flex: 1;
|
||||
|
||||
.paper {
|
||||
// width: 100%;
|
||||
background-color: red;
|
||||
height: 100%;
|
||||
margin: 24rpx 30rpx 0 30rpx;
|
||||
border-radius: 20rpx;
|
||||
@@ -283,7 +282,8 @@
|
||||
align-items: center;
|
||||
|
||||
.img {
|
||||
height: 32rpx;
|
||||
width: 32rpx;
|
||||
height: 28rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
@@ -356,27 +356,26 @@
|
||||
}
|
||||
|
||||
.main_div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding-top: var(--status-bar-height);
|
||||
overflow: hidden;
|
||||
// display: flex;
|
||||
// flex-direction: column;
|
||||
// align-items: center;
|
||||
// overflow: hidden;
|
||||
|
||||
}
|
||||
|
||||
.body-title {
|
||||
|
||||
background-color: #337FFF;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
// position: relative;
|
||||
text-align: center;
|
||||
height: 140rpx;
|
||||
line-height: 140rpx;
|
||||
height: 120rpx;
|
||||
line-height: 100rpx;
|
||||
font-family: PingFangSC;
|
||||
font-weight: 500;
|
||||
font-size: 38rpx;
|
||||
color: #FFFFFF;
|
||||
font-style: normal;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.detail_div {
|
||||
@@ -485,7 +484,7 @@
|
||||
position: absolute;
|
||||
left: 26rpx;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
top: -10rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 315 KiB |
Reference in New Issue
Block a user