优化问题

This commit is contained in:
Leo_Ding 2025-08-12 09:33:22 +08:00
parent f8b3520e5d
commit 2a48964efb
11 changed files with 512 additions and 197 deletions

View File

@ -0,0 +1,150 @@
<template>
<!-- 自定义顶部返回栏 -->
<view class="custom-back-header" :style="headerStyle">
<!-- 返回按钮 -->
<view class="back-btn" @click="handleBack">
<slot name="icon">
<!-- 默认返回图标 -->
<view class="icon"></view>
</slot>
<text v-if="showText" class="text">{{ backText }}</text>
</view>
<!-- 标题插槽 -->
<view class="title">
<slot>{{ title }}</slot>
</view>
<!-- 右侧插槽 -->
<view class="right-slot">
<slot name="right"></slot>
</view>
</view>
</template>
<script>
export default {
props: {
//
title: {
type: String,
default: ''
},
//
showText: {
type: Boolean,
default: true
},
//
backText: {
type: String,
default: '返回'
},
//
bgColor: {
type: String,
default: '#ffffff'
},
//
color: {
type: String,
default: '#333333'
},
//
immersive: {
type: Boolean,
default: true
},
//
targetPath: {
type: String,
default: ''
}
},
computed: {
headerStyle() {
return {
backgroundColor: this.bgColor,
color: this.color,
paddingTop: this.immersive ? 'var(--status-bar-height)' : '0'
};
}
},
methods: {
handleBack() {
if (this.$listeners.back) {
// back
this.$emit('back');
return;
}
const pages = getCurrentPages();
//
if (this.targetPath) {
const target = pages.find(page =>
page.route === this.targetPath.replace(/^\//, '')
);
if (target) {
const delta = pages.length - pages.indexOf(target) - 1;
uni.navigateBack({ delta });
} else {
uni.redirectTo({ url: this.targetPath });
}
return;
}
//
if (pages.length >= 2) {
uni.navigateBack();
} else {
uni.switchTab({ url: '/pages/index/index' });
}
}
}
};
</script>
<style scoped>
.custom-back-header {
display: flex;
align-items: center;
height: 44px;
padding: 0 15px;
position: relative;
z-index: 999;
}
.back-btn {
display: flex;
align-items: center;
padding: 5px 10px 5px 0;
margin-right: 10px;
}
.icon {
font-size: 20px;
margin-right: 5px;
}
.text {
font-size: 16px;
}
.title {
flex: 1;
text-align: center;
font-size: 17px;
font-weight: bold;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.right-slot {
min-width: 60px;
display: flex;
justify-content: flex-end;
}
</style>

View File

@ -173,8 +173,9 @@
{ {
"path": "pages/meetingList/index", "path": "pages/meetingList/index",
"style": { "style": {
"navigationBarTitleText": "近山社区", "navigationStyle": "default",
"navigationStyle": "custom" // "navigationBarTitleText": "近山社区"
// "navigationStyle": "custom" //
} }
}, },
// //
@ -206,18 +207,21 @@
{ {
"path": "pages/sign/sign", "path": "pages/sign/sign",
"style": { "style": {
"navigationStyle": "default",
"navigationBarTitleText": "电子签名" "navigationBarTitleText": "电子签名"
} }
}, },
{ {
"path": "pages/docList/index", "path": "pages/docList/index",
"style": { "style": {
"navigationStyle": "default",
"navigationBarTitleText": "文件下载" "navigationBarTitleText": "文件下载"
} }
} }
], ],
"globalStyle": { "globalStyle": {
"navigationBarTextStyle": "black", "navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#F8F8F8", "navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8" "backgroundColor": "#F8F8F8"

View File

@ -84,19 +84,34 @@
</scroll-view> </scroll-view>
<!-- 输入区域 --> <!-- 输入区域 -->
<view class="chat-bottom">
<view class="" style="padding: 10px;">
<view class="aiTag" v-if="aiName==='生活咨询'" @click="sendMessageCeshi(0)">
最近雨季来了家里总是很潮湿有什么简单有效的除湿防霉小妙招吗
</view>
<view class="aiTag" v-if="aiName==='穿搭顾问'" @click="sendMessageCeshi(1)">
我下周要参加一个商务休闲风格的客户午餐会夏天户外庭院身高175cm体型偏瘦肤色偏白有什么搭配建议吗
</view>
<view class="aiTag" v-if="aiName==='膳食管家'" @click="sendMessageCeshi(2)">
我想开始减脂能为我设计一份适合上班族操作简单营养均衡的晚餐食谱吗
</view>
</view>
<view class="chat-input"> <view class="chat-input">
<view class="" style="flex: 1;"> <view class="" style="flex: 1;">
<input class="input-field" placeholder="输入消息..." v-model="inputMsg" @confirm="sendMessage" <input class="input-field" placeholder="输入消息..." v-model="inputMsg" @confirm="sendMessage"
confirm-type="send" /> confirm-type="send" />
</view> </view>
<view class="" style="width: 100px;"> <view class="" style="width: 100px;">
<u-button type="primary" :disabled="!inputMsg.trim()||isAnswering" @click="sendMessage" shape="circle"> <u-button type="primary" :disabled="!inputMsg.trim()||isAnswering" @click="sendMessage"
shape="circle">
发送 发送
</u-button> </u-button>
</view> </view>
</view> </view>
</view> </view>
</view>
</template> </template>
<script> <script>
@ -124,7 +139,14 @@
serviceUrl: '', serviceUrl: '',
currentAnswer: '', currentAnswer: '',
isAnswering: false, isAnswering: false,
isHandleClose:false isHandleClose: false,
connectNum: 0,
aiName: '',
aiDefaultList: [
'最近雨季来了,家里总是很潮湿,有什么简单有效的除湿防霉小妙招吗?',
'我下周要参加一个商务休闲风格的客户午餐会夏天户外庭院身高175cm体型偏瘦肤色偏白有什么搭配建议吗',
'我想开始减脂,能为我设计一份适合上班族、操作简单、营养均衡的晚餐食谱吗?'
]
} }
}, },
@ -132,11 +154,11 @@
this.serviceUrl = options.serviceUrl || ''; this.serviceUrl = options.serviceUrl || '';
this.apiKey = options.apiKey || ''; this.apiKey = options.apiKey || '';
this.botAvatar = options.icon || this.botAvatar; this.botAvatar = options.icon || this.botAvatar;
this.aiName = options.name
const userInfo = wx.getStorageSync('userInfo') || {}; const userInfo = wx.getStorageSync('userInfo') || {};
this.userId = userInfo.id || Date.now().toString(); this.userId = userInfo.id || Date.now().toString();
this.userName = userInfo.name || '默认用户'; this.userName = userInfo.name || '默认用户';
this.userAvatar = userInfo.avatar?`${IMAGE_BASE_URL+userInfo.avatar}`:this.userAvatar; this.userAvatar = userInfo.avatar ? `${IMAGE_BASE_URL+userInfo.avatar}` : this.userAvatar;
uni.setNavigationBarTitle({ uni.setNavigationBarTitle({
title: options.name || 'AI助手' title: options.name || 'AI助手'
@ -153,7 +175,7 @@
// WebSocket // WebSocket
initWebSocket() { initWebSocket() {
if (this.isConnected) return; if (this.isConnected) return;
console.log(WS_BASE_URL,'aiName===');
// 使 wx.connectSocket // 使 wx.connectSocket
this.socketTask = wx.connectSocket({ this.socketTask = wx.connectSocket({
url: `${WS_BASE_URL}/api/v1/ws/ai?apiUrl=${encodeURIComponent(this.serviceUrl)}&apiToken=${this.apiKey}&userName=${this.userName}`, url: `${WS_BASE_URL}/api/v1/ws/ai?apiUrl=${encodeURIComponent(this.serviceUrl)}&apiToken=${this.apiKey}&userName=${this.userName}`,
@ -170,7 +192,8 @@
this.socketTask.onOpen(() => { this.socketTask.onOpen(() => {
console.log('WebSocket连接已打开'); console.log('WebSocket连接已打开');
this.isConnected = true; this.isConnected = true;
this.reconnectAttempts = 0; // this.reconnectAttempts = 0;
if (this.reconnectAttempts === 0) {
const params = { const params = {
sender: 'bot', sender: 'bot',
thinkContent: '', thinkContent: '',
@ -181,6 +204,8 @@
answerType: 2 answerType: 2
} }
this.addMessage(params); this.addMessage(params);
}
}); });
this.socketTask.onMessage((res) => { this.socketTask.onMessage((res) => {
@ -207,7 +232,7 @@
this.socketTask.onClose(() => { this.socketTask.onClose(() => {
console.log('WebSocket连接已关闭'); console.log('WebSocket连接已关闭');
this.isConnected = false; this.isConnected = false;
if(!this.isHandleClose){ if (!this.isHandleClose) {
this.handleReconnect(); this.handleReconnect();
} }
}); });
@ -329,7 +354,9 @@
if (lastMsg.answerContent.includes('outfit')) { if (lastMsg.answerContent.includes('outfit')) {
const ls = lastMsg.answerContent.replace(/\n/g, '') const ls = lastMsg.answerContent.replace(/\n/g, '')
try { try {
console.log(lastMsg.answerContent)
const obj = JSON.parse(lastMsg.answerContent) const obj = JSON.parse(lastMsg.answerContent)
console.log(obj)
lastMsg.answerContent = obj lastMsg.answerContent = obj
} catch (error) { } catch (error) {
lastMsg.answerContent = '哎呀AI开小差了请重新提问' lastMsg.answerContent = '哎呀AI开小差了请重新提问'
@ -437,7 +464,54 @@
this.inputMsg = ''; this.inputMsg = '';
}, },
sendMessageCeshi(index) {
const content = this.aiDefaultList[index];
if (!content || !this.isConnected) return;
const params = {
sender: 'me',
thinkContent: '',
answerContent: '',
type: 'normal',
isTyping: false,
showAnswer: content,
answerType: 2
}
this.addMessage(params);
this.isAnswering = true
// 使 socketTask.send
this.socketTask.send({
data: content,
success: () => {
console.log('消息发送成功');
const params = {
sender: 'bot',
thinkContent: '思考中...',
answerContent: '',
type: 'normal',
isTyping: true,
showAnswer: '',
answerType: 2
}
//
this.addMessage(params);
},
fail: (err) => {
console.error('消息发送失败', err);
const params = {
sender: 'bot',
thinkContent: '',
answerContent: '',
type: 'normal',
isTyping: true,
showAnswer: '消息发送失败,请重试',
answerType: 2
}
this.addMessage(params);
}
});
this.inputMsg = '';
},
// //
handleReconnect() { handleReconnect() {
if (this.reconnectAttempts >= this.maxReconnectAttempts) { if (this.reconnectAttempts >= this.maxReconnectAttempts) {
@ -472,7 +546,7 @@
this.socketTask.onMessage = null; this.socketTask.onMessage = null;
this.socketTask.close(); this.socketTask.close();
this.socketTask = null; this.socketTask = null;
this.isHandleClose=true this.isHandleClose = true
} }
this.isConnected = false; this.isConnected = false;
}, },
@ -519,6 +593,14 @@
justify-content: flex-start; justify-content: flex-start;
} }
.aiTag {
padding: 5px;
font-size: 14px;
background: #f0f0f0;
border-radius: 10px;
color: #666;
}
.avatar { .avatar {
width: 36px; width: 36px;
height: 36px; height: 36px;
@ -544,13 +626,19 @@
color: #333333; color: #333333;
} }
.chat-input { .chat-bottom {
display: flex;
padding: 10px;
background-color: white; background-color: white;
border-top: 1px solid #ddd; border-top: 1px solid #ddd;
} }
.chat-input {
background-color: white;
border-top: 1px solid #ddd;
display: flex;
padding: 10px;
}
.input-field { .input-field {
flex: 1; flex: 1;
padding: 8px 15px; padding: 8px 15px;

View File

@ -50,6 +50,7 @@
}, },
methods: { methods: {
goAiType(item) { goAiType(item) {
console.log(item);
navigateTo({ navigateTo({
url: `/pages/chat/chatPage?serviceUrl=${item.serviceUrl}&apiKey=${item.apiKey}&id=${item.id}&name=${item.name}&icon=${item.icon}` url: `/pages/chat/chatPage?serviceUrl=${item.serviceUrl}&apiKey=${item.apiKey}&id=${item.id}&name=${item.name}&icon=${item.icon}`
}); });

View File

@ -1,5 +1,6 @@
<template> <template>
<view class="doc-page"> <view class="doc-page">
<view class="doc-content"> <view class="doc-content">
<view class="doc-file" v-for="item of docList" @click="downLoadFile(item)"> <view class="doc-file" v-for="item of docList" @click="downLoadFile(item)">
<image src="/static/imgs/word.png" alt="" srcset="" class="doc-img"/> <image src="/static/imgs/word.png" alt="" srcset="" class="doc-img"/>
@ -37,6 +38,12 @@
] ]
}, },
methods:{ methods:{
handleBack() {
//
uni.redirectTo({
url: `/pages/meetingList/index`
})
},
async downLoadFile(fileUrl){ async downLoadFile(fileUrl){
const result = await downloadPdfFiles(fileUrl); const result = await downloadPdfFiles(fileUrl);
if(result.success==true){ if(result.success==true){
@ -46,7 +53,7 @@
} }
}, },
reback(){ reback(){
uni.redirectTo({ uni.reLaunch({
url: `/pages/meetingList/index` url: `/pages/meetingList/index`
}) })
} }
@ -84,4 +91,25 @@
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
.nav-bar {
display: flex;
align-items: center;
padding: 15px;
// background-color: #fff;
border-bottom: 1px solid #f5f5f5;
margin-top: 84rpx;
}
.nav-left {
display: flex;
align-items: center;
margin-right: 10px;
}
.nav-title {
flex: 1;
text-align: center;
// font-weight: bold;
width: 100%;
}
</style> </style>

View File

@ -620,7 +620,7 @@
icon: 'success' icon: 'success'
}); });
if (res.success == true) { if (res.success == true) {
uni.navigateTo({ uni.redirectTo({
url: `/pages/docList/index?files=${JSON.stringify(res.data)}&&isSelfStudy=${this.isSelfStudy}` url: `/pages/docList/index?files=${JSON.stringify(res.data)}&&isSelfStudy=${this.isSelfStudy}`
}) })
} }

View File

@ -1,13 +1,13 @@
<template> <template>
<view class="container"> <view class="container">
<!-- 自定义导航栏 --> <!-- 自定义导航栏 -->
<view class="nav-bar"> <!-- <view class="nav-bar">
<view class="nav-left" @click="handleBack"> <view class="nav-left" @click="handleBack">
<u-icon name="arrow-left" size="44"></u-icon> <u-icon name="arrow-left" size="44"></u-icon>
<!-- <text>返回</text> --> <text>返回</text>
</view> </view>
<text class="nav-title">近山社区</text> <text class="nav-title">近山社区</text>
</view> </view> -->
<view v-if="tabsReady"> <view v-if="tabsReady">
<u-tabs :list="tabList" :current="currentTab" @change="handleTabChange" border="false" <u-tabs :list="tabList" :current="currentTab" @change="handleTabChange" border="false"
@ -397,13 +397,13 @@
padding: 15px; padding: 15px;
// background-color: #fff; // background-color: #fff;
border-bottom: 1px solid #f5f5f5; border-bottom: 1px solid #f5f5f5;
margin-top: 84rpx; padding-top: 60rpx;
} }
.nav-left { .nav-left {
display: flex; display: flex;
align-items: center; align-items: center;
margin-right: 10px; // margin-right: 10px;
} }
.nav-title { .nav-title {

View File

@ -93,6 +93,7 @@
uni.getLocation({ uni.getLocation({
type: 'wgs84', type: 'wgs84',
success: (res) => { success: (res) => {
console.log('=====>',res)
resolve({ resolve({
longitude: res.longitude, longitude: res.longitude,
latitude: res.latitude latitude: res.latitude

View File

@ -4,6 +4,13 @@
<!-- <view class="handRight"> <!-- <view class="handRight">
<view class="handTitle">请签名</view> <view class="handTitle">请签名</view>
</view> --> </view> -->
<!-- <view class="nav-bar">
<view class="nav-left" @click="handleBack">
<u-icon name="arrow-left" size="44"></u-icon>
<text>返回</text>
</view>
<text class="nav-title">签名</text>
</view> -->
<view class="handCenter"> <view class="handCenter">
<canvas class="handWriting" :disable-scroll="true" @touchstart="uploadScaleStart" <canvas class="handWriting" :disable-scroll="true" @touchstart="uploadScaleStart"
@touchmove="uploadScaleMove" @touchend="uploadScaleEnd" canvas-id="handWriting"></canvas> @touchmove="uploadScaleMove" @touchend="uploadScaleEnd" canvas-id="handWriting"></canvas>
@ -39,10 +46,17 @@
</template> </template>
<script> <script>
import { post } from "../../utils/request"; import {
import pickerColor from "./pickerColor.vue" post
import {IMAGE_BASE_URL,BASE_URL} from '@/utils/config'; } from "../../utils/request";
import {downloadPdfFiles} from '@/utils/download.js' import pickerColor from "./pickerColor.vue"
import {
IMAGE_BASE_URL,
BASE_URL
} from '@/utils/config';
import {
downloadPdfFiles
} from '@/utils/download.js'
import instructionVue from '../../components/instruction.vue'; import instructionVue from '../../components/instruction.vue';
export default { export default {
components: { components: {
@ -51,8 +65,8 @@ import pickerColor from "./pickerColor.vue"
}, },
data() { data() {
return { return {
readShow:false, readShow: false,
hasReaded:true, hasReaded: true,
showPickerColor: false, showPickerColor: false,
ctx: '', ctx: '',
canvasWidth: 0, canvasWidth: 0,
@ -74,8 +88,8 @@ import pickerColor from "./pickerColor.vue"
}, },
toDataURL: void 0, toDataURL: void 0,
requestAnimationFrame: void 0, requestAnimationFrame: void 0,
applyInfo:null, applyInfo: null,
isSelfStudy:true, isSelfStudy: true,
}; };
}, },
props: { //props props: { //props
@ -109,14 +123,14 @@ import pickerColor from "./pickerColor.vue"
}, },
}, },
onLoad(option) { onLoad(option) {
this.isSelfStudy=option.isSelfStudy this.isSelfStudy = option.isSelfStudy
// A // A
const app = getApp() const app = getApp()
if(app.globalData.applyInfo){ if (app.globalData.applyInfo) {
this.applyInfo=app.globalData.applyInfo this.applyInfo = app.globalData.applyInfo
}else{ } else {
uni.navigateTo({ uni.navigateTo({
url:'/pages/meetingList/index' url: '/pages/meetingList/index'
}) })
} }
this.ctx = uni.createCanvasContext("handWriting"); this.ctx = uni.createCanvasContext("handWriting");
@ -130,12 +144,16 @@ import pickerColor from "./pickerColor.vue"
}); });
}, },
methods: { methods: {
readChange(flag){ handleBack() {
this.hasReaded=flag //
uni.navigateBack()
},
readChange(flag) {
this.hasReaded = flag
}, },
postApply(){ postApply() {
this.readShow=false this.readShow = false
// API // API
this.subCanvas() this.subCanvas()
}, },
@ -461,15 +479,16 @@ import pickerColor from "./pickerColor.vue"
const uploadRes = await this.uploadSignature(res.tempFilePath); const uploadRes = await this.uploadSignature(res.tempFilePath);
uni.hideLoading(); uni.hideLoading();
this.applyInfo.applySign=uploadRes this.applyInfo.applySign = uploadRes
const response=await post('/api/v1/app_auth/metting-room/order/register', this.applyInfo) const response = await post('/api/v1/app_auth/metting-room/order/register', this
.applyInfo)
console.log("===response", response) console.log("===response", response)
if (!response || !response.success) { if (!response || !response.success) {
throw new Error('会议室预定失败'); throw new Error('会议室预定失败');
} }
if(response.success==true){ if (response.success == true) {
uni.navigateTo({ uni.redirectTo({
url:`/pages/docList/index?files=${JSON.stringify(response.data)}&&isSelfStudy=${this.isSelfStudy}` url: `/pages/docList/index?files=${JSON.stringify(response.data)}&&isSelfStudy=${this.isSelfStudy}`
}) })
} }
uni.showToast({ uni.showToast({
@ -535,7 +554,7 @@ import pickerColor from "./pickerColor.vue"
uploadSignature(tempFilePath) { uploadSignature(tempFilePath) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// //
const uploadUrl = IMAGE_BASE_URL+'/api/v1/upload'; const uploadUrl = IMAGE_BASE_URL + '/api/v1/upload';
uni.uploadFile({ uni.uploadFile({
url: uploadUrl, url: uploadUrl,
filePath: tempFilePath, filePath: tempFilePath,
@ -549,7 +568,10 @@ import pickerColor from "./pickerColor.vue"
console.log(uploadRes); console.log(uploadRes);
console.log(JSON.parse(uploadRes.data)) console.log(JSON.parse(uploadRes.data))
try { try {
const {success,data} = JSON.parse(uploadRes.data); const {
success,
data
} = JSON.parse(uploadRes.data);
if (success) { if (success) {
resolve(data); // URL resolve(data); // URL
} else { } else {
@ -616,11 +638,31 @@ import pickerColor from "./pickerColor.vue"
overflow: hidden; overflow: hidden;
display: flex; display: flex;
align-content: center; align-content: center;
flex-direction:column; flex-direction: column;
/* justify-content: center; */ /* justify-content: center; */
font-size: 28rpx; font-size: 28rpx;
} }
.nav-bar {
display: flex;
align-items: center;
padding: 15px;
// background-color: #fff;
border-bottom: 1px solid #f5f5f5;
padding-top: 60rpx;
}
.nav-left {
display: flex;
align-items: center;
/* margin-right: 10px; */
}
.nav-title {
flex: 1;
text-align: center;
// font-weight: bold;
width: 100%;
}
.handWriting { .handWriting {
background: #fff; background: #fff;
width: 95vw; width: 95vw;
@ -657,7 +699,7 @@ import pickerColor from "./pickerColor.vue"
display: flex; display: flex;
/* flex-direction: column; */ /* flex-direction: column; */
justify-content: space-between; justify-content: space-between;
align-content:center; align-content: center;
align-items: center; align-items: center;
/* flex: 1; */ /* flex: 1; */
} }

BIN
static/imgs/wechat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -3,6 +3,7 @@
export const BASE_URL = 'https://jinshan.nantong.info'; export const BASE_URL = 'https://jinshan.nantong.info';
export const IMAGE_BASE_URL = `https://jinshan.nantong.info`; export const IMAGE_BASE_URL = `https://jinshan.nantong.info`;
export const WS_BASE_URL = `wss://jinshan.nantong.info`; export const WS_BASE_URL = `wss://jinshan.nantong.info`;
// export const WS_BASE_URL = 'ws://10.10.1.6:8071';
// http://36.212.197.253:8071 // http://36.212.197.253:8071