diff --git a/tra-app/.env.development b/tra-app/.env.development index f235ef7..27b8fd6 100644 --- a/tra-app/.env.development +++ b/tra-app/.env.development @@ -3,9 +3,11 @@ ENV = 'development' # 'development' + # VITE_APP_BASE_API_Url = 'https://aits.jlbank.com.cn:7001' -VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7001' +VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7002' + # VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7002' # VITE_APP_BASE_API_Url = 'http://192.168.247.200' @@ -17,6 +19,7 @@ VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7001' #VITE_APP_BASE_API_Url = 'http://25.18.122.91:9786' + # UAT # VITE_APP_BASE_API_Url = 'http://25.18.122.78:9786' @@ -30,6 +33,17 @@ VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7001' # h5专用地址x2 # VITE_APP_BASE_H5_API_Url_TRAAPP = 'http://25.64.32.150:9601' # dev -# VITE_APP_BASE_H5_API_Url = 'http://25.18.122.65:7001' +#VITE_APP_BASE_H5_API_Url = 'http://25.18.122.65:7001' + # sit -#VITE_APP_BASE_H5_API_Url = 'http://25.18.122.91:9786' \ No newline at end of file +# 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_TRAAPP = 'http://25.64.16.130: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' +#VITE_APP_BASE_H5_API_Url_TRAEXAM = 'http://25.64.16.139:9604' + + diff --git a/tra-app/.env.development.yh b/tra-app/.env.development.yh index 193ce29..95d4857 100644 --- a/tra-app/.env.development.yh +++ b/tra-app/.env.development.yh @@ -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' diff --git a/tra-app/.npmrc b/tra-app/.npmrc new file mode 100644 index 0000000..0c65878 --- /dev/null +++ b/tra-app/.npmrc @@ -0,0 +1,14 @@ +# 启用严格模式,确保依赖版本一致 +strict-peer-dependencies=false + +# 配置依赖安装目录(pnpm 特有,节省磁盘空间) +store-dir=~/.pnpm-store + +# 兼容 uniapp 对依赖的查找逻辑 +node-linker=hoisted + +# 忽略废弃依赖警告 +ignore-deprecations=all + +# 忽略对等依赖警告 +strict-peer-dependencies=false \ No newline at end of file diff --git a/tra-app/src/App.vue b/tra-app/src/App.vue index 63d8caf..df02f78 100644 --- a/tra-app/src/App.vue +++ b/tra-app/src/App.vue @@ -1,31 +1,34 @@ + \ No newline at end of file diff --git a/tra-app/src/api/socket.js b/tra-app/src/api/socket.js index 0869f8d..2b304f9 100644 --- a/tra-app/src/api/socket.js +++ b/tra-app/src/api/socket.js @@ -86,7 +86,7 @@ export default class WebSocketUtil { // console.log('WebSocket连接已关闭', res); clearInterval(this.heartbeatTimer); // 清除心跳计时器 this.triggerEvent('close', res); // 触发连接关闭事件 - this.tryReconnect(); // 尝试重连 + // this.tryReconnect(); // 尝试重连 }); // 监听WebSocket错误事件 @@ -106,7 +106,7 @@ export default class WebSocketUtil { */ on(event, callback) { if (this.callbacks[event]) { - this.callbacks[event].push(callback); + this.callbacks[event] = [callback]; } return this; } diff --git a/tra-app/src/api/sparring.js b/tra-app/src/api/sparring.js index 2b9c8f0..d34cc3e 100644 --- a/tra-app/src/api/sparring.js +++ b/tra-app/src/api/sparring.js @@ -62,6 +62,7 @@ export const partnerChatReportTrigger = (data) => { export const partnerChatPrompt = (data) => { return request({ url: base_url + '/traPartnerChat/partnerChatPrompt', + timeout: 60000, method: 'post', data }); diff --git a/tra-app/src/common/app-permission.js b/tra-app/src/common/app-permission.js new file mode 100644 index 0000000..954263c --- /dev/null +++ b/tra-app/src/common/app-permission.js @@ -0,0 +1,306 @@ +let popupView = null // 窗口实例 +export function showModal(info) { + const title = info && info.title ? info.title : '标题' + const content = info && info.content ? info.content : '请输入内容' + let screenWidth = plus.screen.resolutionWidth + let screenHeight = plus.screen.resolutionHeight + const popupViewWidth = screenWidth * 0.85 + const viewContentPadding = 20 // 减小内边距 + const viewContentWidth = parseInt(popupViewWidth - (viewContentPadding * 2)) + const descriptionList = drawtext(content, viewContentWidth) + let popupViewHeight = 60 + 20 + 20 // 减小整体高度 + let popupViewContentList = [{ + tag: 'font', + id: 'title', + text: title, + textStyles: { + size: '18px', + color: "#333333", + weight: "bold", + whiteSpace: "normal" + }, + position: { + top: '25px', // 调整标题位置 + left: viewContentPadding + "px", + width: viewContentWidth + "px", + height: "25px", + } + }] + + const textHeight = 24 // 调整行高 + let contentTop = 60 // 调整内容起始位置 + + descriptionList.forEach((item, index) => { + if (index > 0) { + popupViewHeight += textHeight; + contentTop += textHeight; + } + popupViewContentList.push({ + tag: 'font', + id: 'content' + index + 1, + text: item.content, + textStyles: { + size: '15px', + color: "#666666", + lineSpacing: "50%", // 调整行间距 + align: "left" + }, + position: { + top: contentTop + "px", + left: viewContentPadding + "px", + width: viewContentWidth + "px", + height: textHeight + "px", + } + }); + if (item.type == "break") { + contentTop += 8; // 减小段落间距 + popupViewHeight += 8; + } + }) + + popupView = new plus.nativeObj.View("popupView", { + tag: "rect", + top: "80px", // 固定在靠近顶部的位置 + left: (screenWidth - popupViewWidth) / 2 + "px", + height: popupViewHeight + "px", + width: popupViewWidth + "px" + }) + + // 绘制主体背景 + popupView.drawRect({ + color: "#FFFFFF", + radius: "12px", + borderWidth: "1px", + borderColor: "#E5E5E5" + }, { + top: "0px", + height: popupViewHeight + "px", + }) + + popupView.draw(popupViewContentList) + popupView.show() +} + + +function closeModal() { + // 在不再需要 popupView 时关闭它 + popupView && popupView.close(); + popupView = null; +} + +// 文字换行 +function drawtext(text, maxWidth) { + let textArr = text.split(""); + let len = textArr.length; + // 上个节点 + let previousNode = 0; + // 记录节点宽度 + let nodeWidth = 0; + // 文本换行数组 + let rowText = []; + // 如果是字母,侧保存长度 + let letterWidth = 0; + // 汉字宽度 + let chineseWidth = 14; + // otherFont宽度 + let otherWidth = 7; + for (let i = 0; i < len; i++) { + if (/[\u4e00-\u9fa5]|[\uFE30-\uFFA0]/g.test(textArr[i])) { + if (letterWidth > 0) { + if (nodeWidth + chineseWidth + letterWidth * otherWidth > maxWidth) { + rowText.push({ + type: "text", + content: text.substring(previousNode, i) + }); + previousNode = i + nodeWidth = chineseWidth + letterWidth = 0 + } else { + nodeWidth += chineseWidth + letterWidth * otherWidth + letterWidth = 0 + } + } else { + if (nodeWidth + chineseWidth > maxWidth) { + rowText.push({ + type: "text", + content: text.substring(previousNode, i) + }) + previousNode = i + nodeWidth = chineseWidth + } else { + nodeWidth += chineseWidth + } + } + } else { + if (/\n/g.test(textArr[i])) { + rowText.push({ + type: "break", + content: text.substring(previousNode, i) + }) + previousNode = i + 1 + nodeWidth = 0 + letterWidth = 0 + } else if (textArr[i] == "\\" && textArr[i + 1] == "n") { + rowText.push({ + type: "break", + content: text.substring(previousNode, i) + }) + previousNode = i + 2 + nodeWidth = 0 + letterWidth = 0 + } else if (/[a-zA-Z0-9]/g.test(textArr[i])) { + letterWidth += 1; + if (nodeWidth + letterWidth * otherWidth > maxWidth) { + rowText.push({ + type: "text", + content: text.substring(previousNode, i + 1 - letterWidth) + }) + previousNode = i + 1 - letterWidth + nodeWidth = letterWidth * otherWidth + letterWidth = 0 + } + } else { + if (nodeWidth + otherWidth > maxWidth) { + rowText.push({ + type: "text", + content: text.substring(previousNode, i) + }); + previousNode = i + nodeWidth = otherWidth + } else { + nodeWidth += otherWidth + } + } + } + } + if (previousNode < len) { + rowText.push({ + type: "text", + content: text.substring(previousNode, len) + }) + } + return rowText +} + + + +//权限检测 +export function requestPermissions(info) { + const permissionID = info.permissionID + console.log(info,permissionID) + return new Promise((rev, jec) => { + if (!permissionID) { + rev({ + isSuc: false, + msg: "缺少permissionID" + }) + return false + } + //判断安卓与ios设备 + if (plus.os.name == 'Android') { + let _permissionID = 'android.permission.' + permissionID; + plus.android.checkPermission(_permissionID, + granted => { + console.log(granted) + if (granted.checkResult == 0) { + rev({ + isSuc: true + }) + } + if (granted.checkResult == -1) { + //还未授权当前查询的权限,打开权限申请目的自定义弹框 + closeModal() // 先关闭再弹窗 + showModal(info) + plus.android.requestPermissions([_permissionID], + (e) => { + console.log(e) + //关闭权限申请目的自定义弹框 + if (e.granted.length > 0) { + closeModal() + //当前查询权限已授权,此时可以通知页面执行接下来的操作 + rev({ + isSuc: true + }) + } + if (e.deniedPresent.length > 0) { + closeModal() + //当前查询权限已授权,此时可以通知页面执行接下来的操作 + rev({ + isSuc: false, + msg: "用户已拒绝" + }) + } + if (e.deniedAlways.length > 0) { + //当前查询权限已被永久禁用,此时需要引导用户跳转手机系统设置去开启 + uni.showModal({ + title: '温馨提示', + content: '还没有该权限,立即去设置开启?', + cancelText: "取消", + confirmText: "去设置", + showCancel: true, + confirmColor: '#000', + cancelColor: '#666', + success: (res) => { + if (res.confirm) { + goSetting(); + } + if (res.cancel) { + rev({ + isSuc: false, + msg: "取消前往权限设置页面" + }) + } + }, + fail(e) { + rev({ + isSuc: false, + msg: e.message || "弹窗失败" + }) + }, + complete() { + closeModal() + } + }) + } + }) + } + }, + error => { + rev({ + isSuc: false, + mes: error.message || '检查权限失败' + }) + } + ); + + } else { + //IOS不需要添加自定义弹框来描述权限目的,因为在配置文件的隐私信息访问的许可描述里可添加 + rev({ + isSuc: true + }) + } + }) +} +//跳转手机系统设置 +export function goSetting() { + if (plus.os.name == "iOS") { + var UIApplication = plus.ios.import("UIApplication"); + var application2 = UIApplication.sharedApplication(); + var NSURL2 = plus.ios.import("NSURL"); + var setting2 = NSURL2.URLWithString("app-settings:"); + application2.openURL(setting2); + plus.ios.deleteObject(setting2); + plus.ios.deleteObject(NSURL2); + plus.ios.deleteObject(application2); + } else { + var Intent = plus.android.importClass("android.content.Intent"); + var Settings = plus.android.importClass("android.provider.Settings"); + var Uri = plus.android.importClass("android.net.Uri"); + var mainActivity = plus.android.runtimeMainActivity(); + var intent = new Intent(); + intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + var uri = Uri.fromParts("package", mainActivity.getPackageName(), null); + intent.setData(uri); + mainActivity.startActivity(intent); + } +} \ No newline at end of file diff --git a/tra-app/src/common/permission.js b/tra-app/src/common/permission.js index 6716429..70571bd 100644 --- a/tra-app/src/common/permission.js +++ b/tra-app/src/common/permission.js @@ -2,7 +2,13 @@ * 本模块封装了Android、iOS的应用权限判断、打开应用权限设置界面、以及位置系统服务是否开启 */ -var isIos +import common from '@/common/common.js' +import { + getPhoneEnvBool +} from '@/common/common.js' +const IsAndEnv = getPhoneEnvBool('AND') + +let isIos // #ifdef APP-PLUS isIos = (plus.os.name == "iOS") // #endif @@ -63,35 +69,90 @@ function judgeIosPermissionLocation() { // 判断麦克风权限是否开启 function judgeIosPermissionRecord() { - var result = false; - var avaudiosession = plus.ios.import("AVAudioSession"); - var avaudio = avaudiosession.sharedInstance(); - var permissionStatus = avaudio.recordPermission(); - console.log("permissionStatus:" + permissionStatus); - if (permissionStatus == 1684369017 || permissionStatus == 1970168948) { - console.log("麦克风权限没有开启"); - } else { - result = true; - console.log("麦克风权限已经开启"); - } - plus.ios.deleteObject(avaudiosession); - return result; + return new Promise(async (resolve, reject) => { + const authSetting = uni.getAppAuthorizeSetting(); + const state = authSetting.microphoneAuthorized; + console.log('麦克风state', state); + switch (state) { + case 'authorized': + console.log("麦克风权限是否开启"); + resolve() + break; + case 'denied': // ios拒绝,安卓拒绝或者未授权都是这个 + if (IsAndEnv) { // 安卓二次判定 + const result = await requestAndroidPermission('android.permission.RECORD_AUDIO') + if (result === 1) { + resolve() + break; + } + } + const resultT = await common.show( + '提示信息', + '当前页面需要使用录音权限,是否前往开启?' + ) + if (resultT) { + // 前往权限设置页面 + uni.openAppAuthorizeSetting(); + } + reject() + break; + case 'not determined': // 表示尚未请求授权,仅 iOS 会出现。此种情况下引导用户打开系统设置,不展示开关 + resolve() + break; + case 'config error': // 只有在 App 端时返回 + resolve() + break; + default: + resolve() + break; + } + }) } + // 判断相机权限是否开启 function judgeIosPermissionCamera() { - var result = false; - var AVCaptureDevice = plus.ios.import("AVCaptureDevice"); - var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide'); - console.log("authStatus:" + authStatus); - if (authStatus == 3) { - result = true; - console.log("相机权限已经开启"); - } else { - console.log("相机权限没有开启"); - } - plus.ios.deleteObject(AVCaptureDevice); - return result; + + return new Promise(async (resolve, reject) => { + const authSetting = uni.getAppAuthorizeSetting(); + const state = authSetting.cameraAuthorized; + console.log('相机权限', state); + switch (state) { + case 'authorized': + console.log("相机权限已经开启"); + resolve() + break; + case 'denied': // ios拒绝,安卓拒绝或者未授权都是这个 + console.log('IsAndEnv', IsAndEnv); + if (IsAndEnv) { // 安卓二次判定 + const result = await requestAndroidPermission('android.permission.CAMERA') + console.log('安卓二次判定', result); + if (result === 1) { + resolve() + break; + } + } + const resultT = await common.show( + '提示信息', + '当前页面需要使用相机权限,是否前往开启?' + ) + if (resultT) { + // 前往权限设置页面 + uni.openAppAuthorizeSetting(); + } + reject() + break; + case 'not determined': // 表示尚未请求授权,仅 iOS 会出现。此种情况下引导用户打开系统设置,不展示开关 + resolve() + break; + case 'config error': // 只有在 App 端时返回 + resolve() + break; + default: + resolve() + break; + } + }) } // 判断相册权限是否开启 @@ -264,9 +325,11 @@ function checkSystemEnableLocation() { } } -export default ({ - judgeIosPermission: judgeIosPermission, - requestAndroidPermission: requestAndroidPermission, - checkSystemEnableLocation: checkSystemEnableLocation, - gotoAppPermissionSetting: gotoAppPermissionSetting -}) + + +export default { + judgeIosPermission, + requestAndroidPermission, + checkSystemEnableLocation, + gotoAppPermissionSetting +} \ No newline at end of file diff --git a/tra-app/src/components/examination/subject.vue b/tra-app/src/components/examination/subject.vue index f193d26..392a171 100644 --- a/tra-app/src/components/examination/subject.vue +++ b/tra-app/src/components/examination/subject.vue @@ -194,19 +194,11 @@ watch( () => props.modelValue, (newVal) => { - console.log('modelValue', newVal); + // console.log('modelValue', newVal); item_answer.value = typeof newVal === 'string' ? newVal.split(',') : newVal; }, { deep: true } ); - // watch( - // item_answer, - // (newVal) => { - // console.log('item_answer', newVal); - // emit('update:modelValue', newVal); - // }, - // { deep: true } - // ); const feedback_click = () => { emit('subject_click', 'feedback', props.item); diff --git a/tra-app/src/components/markdown-preview/markdown-preview.vue b/tra-app/src/components/markdown-preview/markdown-preview.vue index 0ce9ed5..27615af 100644 --- a/tra-app/src/components/markdown-preview/markdown-preview.vue +++ b/tra-app/src/components/markdown-preview/markdown-preview.vue @@ -24,7 +24,8 @@ watch:{ mdString: { handler(val){ - this.contentHtml = this.parseContent(val) + let _text = val.replace(//g,'>') + this.contentHtml = this.parseContent(_text) }, deep: true, immediate: true diff --git a/tra-app/src/manifest.json b/tra-app/src/manifest.json index 0a4b6c0..686c854 100644 --- a/tra-app/src/manifest.json +++ b/tra-app/src/manifest.json @@ -32,7 +32,9 @@ }, /* 模块配置 */ "modules" : { - "Camera" : {}, + "Camera" : { + "description" : "用于访问摄像头进行实时预览" + }, "Barcode" : {}, "Record" : {}, "VideoPlayer" : {}, @@ -57,12 +59,23 @@ "", "", "", - "" + "", + "" ] }, /* ios打包配置 */ "ios" : { - "dSYMs" : false + "dSYMs" : false, + "deploymentTarget" : "11.0", + "privacyDescription" : { + "NSCameraUsageDescription" : "此应用需要访问您的摄像头来进行视频录制和拍照功能", + "NSMicrophoneUsageDescription" : "此应用需要访问您的麦克风来录制音频" + }, + "capabilities" : { + "entitlements" : { + "com.apple.developer.avfoundation.multitasking-camera-access" : true + } + } }, /* SDK配置 */ "sdkConfigs" : {}, diff --git a/tra-app/src/pages.json b/tra-app/src/pages.json index 68ecbeb..690c298 100644 --- a/tra-app/src/pages.json +++ b/tra-app/src/pages.json @@ -590,6 +590,7 @@ "navigationBarBackgroundColor": "#F8F8F8", "backgroundColor": "#F8F8F8", "navigationStyle": "custom", + "screenOrientation": "portrait", "app-plus": { "titleView": false, "bounce": "none", diff --git a/tra-app/src/pages/analytics/study.vue b/tra-app/src/pages/analytics/study.vue index 42a3cf6..cd94d9d 100644 --- a/tra-app/src/pages/analytics/study.vue +++ b/tra-app/src/pages/analytics/study.vue @@ -16,6 +16,8 @@ :current="currentTab" class="font_pf my_tabs" :inactive-style="{ color: '#333333', fontSize: '28rpx', fontWeight: '500' }" :activeStyle="{ color: '#333333', fontSize: '28rpx', fontWeight: '600' }"> + + @@ -107,36 +109,36 @@ - + - + {{item.title}} {{item.content}} - + - + {{item.title}} {{item.content}} - + - - + + {{suggestObj.content}} - + - + 暂无数据 @@ -225,26 +227,57 @@ } } const loading = ref(false) + const loading1 = ref(false) + const loading2 = ref(false) + const loading3 = ref(false) + const loading4 = ref(false) + const overLoading = computed(()=>{ + return !loading.value && !loading1.value && !loading2.value && !loading3.value && !loading4.value + }) + const showToast = () => { + common.msg('学习分析生成中,请稍后再试!') + } const getInfoNow = async (params) => { + statisticsObj.value = [] + dimesionList.value =[] loading.value = true - try { - let _res1 = await queryStudyStatistics(params) + loading2.value = true + loading1.value = true + loading3.value = true + queryStudyStatistics(params).then(_res1 => { statisticsObj.value = { ..._res1.body } - let _res2 = await queryDimesionInfo(params) + loading.value = false + }).catch(() => { + loading.value = false + }) + queryDimesionInfo(params).then(_res2 => { dimesionList.value = [..._res2.body] - let _res3 = await queryHabitInfo(params) + loading1.value = false + }).catch(() => { + loading1.value = false + }) + queryHabitInfo(params).then(_res3 => { studyList.value = [..._res3.body] - let _res4 = await querySuggestInfo(params) + loading2.value = false + }).catch(() => { + loading2.value = false + }) + querySuggestInfo(params).then(_res4 => { if (_res4.body && _res4.body.length > 0) { suggestObj.value = { ..._res4.body[0] } + }else{ + suggestObj.value = { + content: '' + } } - } catch {} finally { - loading.value = false - } + loading3.value = false + }).catch(() => { + loading3.value = false + }) } // 跳转 课程详情 const toCourseDetail = item => { @@ -263,9 +296,12 @@ } const getCrsListNow = () => { + loading4.value = true queryRecmdCrsInfo().then(res => { - console.log(res) courseList.value = res.body || [] + loading4.value = false + }).catch(() => { + loading4.value = false }) } onMounted(() => { @@ -377,8 +413,9 @@ backdrop-filter: blur(10rpx); z-index: 1; - &.loading-box-cont{ + &.loading-box-cont { background: #ddeafa; + &::before { content: ''; display: block; @@ -417,6 +454,17 @@ .tabs-box { width: 600rpx; + height: 88rpx; + position: relative; + .tab-btn{ + position: absolute; + width: 600rpx; + height: 88rpx; + top: 0; + left: 0; + z-index: 23; + // background-color: #ccc; + } } .analytics-items { diff --git a/tra-app/src/pages/competition/pk.vue b/tra-app/src/pages/competition/pk.vue index d7807f7..8efad33 100644 --- a/tra-app/src/pages/competition/pk.vue +++ b/tra-app/src/pages/competition/pk.vue @@ -147,6 +147,7 @@ const pkData = reactive({ comLimit: 0, crsId: '', + comId: '', name: '', // 名称 orgId: '', papersId: '', @@ -247,7 +248,7 @@ traQnsInfoVo = res.body.traQnsInfoVo; } topic.value.isPreview = true; // 不能在点击了,打开预览模式 - console.log('给出来的traQnsInfoVo', traQnsInfoVo); + // console.log('给出来的traQnsInfoVo', traQnsInfoVo); common.hideLoading(); topic.value.clearResult = false; // 不清除正确答案 topic.value.analyContent = traQnsInfoVo.analyContent; // 答案解析 @@ -257,7 +258,6 @@ topic.value.judgeResult = traQnsInfoVo.judgeResult; // 正确答案字符串分割 if (questionNumber.value >= topicList.length - 1) { - console.log('pk页答完了,带走的数据', pkData); common.setPageCache('competition_pk_to_resulf', pkData); nextTick(() => { common.redirectTo( @@ -418,7 +418,7 @@ } nextTick(() => { common.redirectTo( - `/pages/competition/result?mode=${mode}&execId=${pkData.execId}&orgId=${pkData.orgId}&papersId=${pkData.papersId}&autoSub=01` + `/pages/competition/result?mode=${mode}&execId=${pkData.execId}&orgId=${pkData.orgId}&papersId=${pkData.papersId}&autoSub=01&comId=${pkData.comId}` ); }); diff --git a/tra-app/src/pages/course/components/talkingItem.vue b/tra-app/src/pages/course/components/talkingItem.vue index 5cced8f..b5899af 100644 --- a/tra-app/src/pages/course/components/talkingItem.vue +++ b/tra-app/src/pages/course/components/talkingItem.vue @@ -694,7 +694,7 @@ voiceTime.value = (Math.ceil(talkVoiceObj.value.duration) || 0) + 's'; } else { if (sum === 100) { - voiceTime.value = 0 + 's'; + voiceTime.value = (unref(dataInfo).voiceTime || 0) + 's'; return; } setTimeout(() => { diff --git a/tra-app/src/pages/course/components/touchBtn.vue b/tra-app/src/pages/course/components/touchBtn.vue index 3d1a24b..3bd0a45 100644 --- a/tra-app/src/pages/course/components/touchBtn.vue +++ b/tra-app/src/pages/course/components/touchBtn.vue @@ -174,6 +174,7 @@ const initRecord = () => { recordObjCom.value = uni.getRecorderManager(); unref(recordObjCom)?.onStop((res, duration) => { + isRecording.value = false if(isGettingPermission.value){ isGettingPermission.value = false return @@ -196,13 +197,20 @@ }); } else { closeModel(); - emit('uploadVoice', audioPath.value); + emit('uploadVoice', audioPath.value, recordTime.value); } } else { closeModel(); } }); unref(recordObjCom).onStart(() => { + isRecording.value = true + recordTime.value = 0 + setRecordTime() + if(isGettingPermission.value){ + isGettingPermission.value = false + return + } startFlag.value = 1; setTimeout(() => { startFlag.value = 2; @@ -219,6 +227,16 @@ } }); }; + const setRecordTime = () => { + setTimeout(()=>{ + if(isRecording.value){ + recordTime.value += 1 + setRecordTime() + } + },1000) + } + const isRecording = ref(false) + const recordTime = ref(0) const startFlag = ref(1); // const canStart = ref(true) const startRecord = () => { diff --git a/tra-app/src/pages/course/study.vue b/tra-app/src/pages/course/study.vue index 9413450..62073b7 100644 --- a/tra-app/src/pages/course/study.vue +++ b/tra-app/src/pages/course/study.vue @@ -839,7 +839,7 @@ const testAnswer = computed(() => { let _num = _arr.map(t => [1, 2, 6].indexOf(Number(t.type)) >= 0).filter(t => !!t) return _num.length < 5 }) -const uploadRecordNow = voicePath => { +const uploadRecordNow = (voicePath, voiceTime) => { if (!testAnswer.value) { common.msg('每个问题最多连续发送五次答案!') return @@ -911,7 +911,8 @@ const uploadRecordNow = voicePath => { userInfo: { ...choiceTeacherInfo.value }, - id: _id + id: _id, + voiceTime: voiceTime } } else { return t diff --git a/tra-app/src/pages/index/components/class_scroll.vue b/tra-app/src/pages/index/components/class_scroll.vue index 10ea912..3925fac 100644 --- a/tra-app/src/pages/index/components/class_scroll.vue +++ b/tra-app/src/pages/index/components/class_scroll.vue @@ -1,4 +1,4 @@ -