小助理

This commit is contained in:
liuye
2024-08-13 10:30:27 +08:00
parent 6baf49350c
commit bc5c1063ff
6 changed files with 67 additions and 1740 deletions

View File

@@ -1,758 +0,0 @@
<template>
<div class="AppAiDemo">
<div class="service-content">
<div class="text-content">
<div class="text-left">
<div>你好呀</div>
<p>我是您的<span>AI助手</span></p>
<p>有什么问题都可以问我哟~</p>
</div>
<img
src="https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/service.png"
alt=""
class="service-img"
/>
</div>
</div>
<!-- <scroll-view :scroll-top="scrollTop" scroll-y="true" class="scroll-Y" @scroll="scroll" v-if="messageList.length" :style="{height: scrollHeight+'px'}"> -->
<div class="list-content">
<div v-for="(item, index) in messageList" :key="index">
<div
:class="item.userType == 1 ? 'item-left' : 'item-right'"
v-if="item.userType != 2"
>
<div class="item" :class="'item' + index">
<div class="img-div" v-if="item.sdkFileUrl">
<u-icon
name="play-circle"
:color="item.userType == 0 ? '#fff' : '#A8ADAE'"
size="52"
v-if="!item.isPlay"
@click="play(item.sdkFileUrl, index)"
></u-icon>
<u-icon
name="pause-circle"
:color="item.userType == 0 ? '#fff' : '#A8ADAE'"
size="52"
v-else
@click="playStop(index)"
></u-icon>
<img
src="https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/recording-white.png"
alt=""
v-if="item.userType == 0"
/>
<img
src="https:yanshi//cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/recording-gray.png"
alt=""
v-else
/>
</div>
<p>{{ item.content || "" }}</p>
</div>
</div>
<div class="statistics-content" v-if="item.userType == 2">
<div class="title">巡查上报事件反馈</div>
<div class="item-info">
<span class="label">事件类型</span>矛盾调解
</div>
<div class="item-info"><span class="label">联系人</span>任志强</div>
<div class="item-info">
<span class="label">联系电话</span
><span style="color: #3975c6">13549358572</span>
</div>
<div class="item-info">
<span class="label">事件简介</span
>这户人家已经打架打了4天了越来越激烈怀疑存在家暴嫌疑需要社区介入进行调解
</div>
<div class="item-info">
<span class="label">事件状态</span>待处理
</div>
<div class="item-info">
<span class="label">上报人</span>油料所社区网格员张三
</div>
</div>
</div>
</div>
<u-modal v-model="showModel" :content="modelContent"></u-modal>
<!-- </scroll-view> -->
<div class="fixed-bottom">
<div class="type-text" v-if="type == 'text'">
<u-input
type="text"
placeholder="输入您的问题…"
height="80"
input-align="left"
:clearable="false"
:border="true"
placeholder-style="color:#666;"
v-model="content"
></u-input>
<img
src="https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/send.png"
alt=""
v-if="content.length"
@click="sendMsg"
/>
<img
src="https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/microphone-btn.png"
alt=""
v-else
@click="microPhone"
/>
</div>
<div class="type-record" v-else>
<img
src="https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/keyboard-btn.png"
alt=""
class="keyboard-btn"
@click="keyboardClick"
/>
<div v-if="!isStart" @click="startRecord">
<p>点击开始录音</p>
<img
src="https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/record-btn.png"
alt=""
class="record-btn"
/>
</div>
<div v-else @click="endRecord">
<p>正在录音中</p>
<div class="tips-text">点击下方停止录音</div>
<img
src="https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/shengbo.gif"
alt=""
class="recording"
/>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapState } from "vuex";
import Recorder from "recorder-core";
import "recorder-core/src/engine/mp3";
import "recorder-core/src/engine/mp3-engine";
const innerAudioContext = uni.createInnerAudioContext();
innerAudioContext.autoplay = true;
export default {
name: "AppAiDemo",
appName: "演示Ai助手",
data() {
return {
recorder: null,
type: "text",
isStart: false,
content: "",
isFlag: false,
voiceUrl:
"http://test87ftp.cunwuyun.cn/20240109/filename-20240109111547.mp3",
voiceId: "0678a73c50b74bdcb8398e14ffbb35e5",
messageList: [
// {
// userType: 0,
// sdkFileUrl: 'http://test87ftp.cunwuyun.cn/20240104/output.mp3',
// isPlay: false
// }
],
current: 1,
pages: 2,
scrollTop: 0,
scrollHeight: "",
preveHeight: "",
showMask: false,
tagList: [],
testMsgList: [
{
userType: 0,
sdkFileUrl: "http://test87ftp.cunwuyun.cn/20240104/output.mp3",
isPlay: false,
},
{
userType: 0,
content:
"户主姓名任志强户主性别男户主的联系电话13549358572户主的民族汉户主家有3口人我要上报近期巡查小区时发现这户人家已经打架打了4天了越来越激烈怀疑存在家暴嫌疑需要社区介入进行调解",
},
{
userType: 2,
},
],
};
},
computed: {
...mapState(["user"]),
},
onLoad() {
// this.scrollHeight = uni.getSystemInfoSync().windowHeight
// this.getHistoryList()
// var res = ["http://test87ftp.cunwuyun.cn/20240109/filename-20240109111547.mp3;0678a73c50b74bdcb8398e14ffbb35e5"]
// this.voiceUrl = res[0].split(';')[0]
// this.voiceId = res[0].split(';')[1]
// this.sendVoice()
},
onShow() {
document.title = "AI助手";
},
methods: {
back() {
uni.navigateBack();
},
startRecord() {
// this.isStart = true
// this.recorder = Recorder({
// type: 'mp3',
// sampleRate: 16000,
// bitRate: 16
// })
// this.recorder.open(() => {
// this.recorder.start()
// })
this.sendVoice();
},
endRecord() {
this.recorder.stop(
(blob) => {
var formData = new FormData();
formData.append("file", blob, "filename.mp3");
this.$http
.post("/admin/file/add", formData, {
withoutToken: true,
})
.then((res) => {
uni.hideLoading();
if (res?.data) {
this.voiceUrl = res.data[0].split(";")[0];
this.voiceId = res.data[0].split(";")[1];
this.isStart = false;
this.sendVoice();
}
})
.catch((res) => {
this.$u.toast(res);
uni.hideLoading();
});
this.recorder.close();
this.recorder = null;
},
(msg) => {
console.log("录音失败:" + msg);
this.recorder.close();
this.recorder = null;
}
);
},
microPhone() {
this.type = "voice";
this.isStart = false;
},
keyboardClick() {
if (this.isStart) return;
this.type = "text";
this.content = "";
},
scroll(e) {
if (e.detail.scrollTop == 0) {
if (this.current > this.pages) {
return this.$u.toast("已加载完成,没有更多数据");
} else {
this.current++;
this.getHistoryList();
}
}
},
sendMsg() {
this.$loading();
this.$http
.post(
"/app/appaigccopilotinfo/add2",
{ content: this.content, appType: 1 },
{ withoutToken: true }
)
.then((res) => {
if (res.code == 0) {
this.content = "";
this.messageList.push(res.data[0]);
this.messageList.push(res.data[1]);
this.$nextTick(() => {
uni
.createSelectorQuery()
.select(".list-content")
.boundingClientRect((res) => {
this.scrollTop = res.height - this.scrollHeight;
})
.exec();
});
this.$hideLoading();
}
});
},
sendVoice() {
this.$loading();
// this.$http.post("/app/appaigccopilotinfo/add2", {sdkFileUrl: this.voiceUrl, fileId: this.voiceId, appType: 1}, {withoutToken: true}).then(res => {
// if(res.code == 0) {
// this.voiceUrl = ''
// this.voiceId = ''
// res.data.map((item) => {
// if(item.sdkFileUrl) {
// item.isPlay = false
// }
// })
// this.messageList.push(res.data[0])
// this.messageList.push(res.data[1])
// this.$nextTick(() => {
// uni.createSelectorQuery().select(".list-content").boundingClientRect((res) => {
// this.scrollTop = res.height - this.scrollHeight
// }).exec();
// })
// this.$hideLoading()
// }
// })
setTimeout(() => {
this.messageList.push(this.testMsgList[0]);
setTimeout(() => {
this.messageList.push(this.testMsgList[1]);
this.type = "text";
this.$hideLoading();
setTimeout(() => {
this.messageList.push(this.testMsgList[2]);
}, 6000);
}, 4000);
}, 16000);
},
getHistoryList() {
this.$loading();
uni
.createSelectorQuery()
.select(".list-content")
.boundingClientRect((res) => {
this.preveHeight = res.height;
})
.exec();
this.$http
.post(`/app/appaigccopilotinfo/list?current=${this.current}&size=10`)
.then((res) => {
if (res.code == 0 && res.data.records.length) {
res.data.records.map((item) => {
if (item.sdkFileUrl) {
item.isPlay = false;
}
if (item.userType == 2) {
//统计数据
item.content = JSON.parse(item.content);
console.log(item.content);
}
});
this.messageList =
this.current == 1
? res.data.records
: [...res.data.records, ...this.messageList];
this.pages = res.data.pages;
this.$nextTick(() => {
uni
.createSelectorQuery()
.select(".list-content")
.boundingClientRect((res) => {
if (this.current == 1) {
this.scrollTop = res.height - this.scrollHeight;
} else {
this.scrollTop = res.height - this.preveHeight;
}
})
.exec();
});
this.$hideLoading();
}
});
},
play(src, index) {
innerAudioContext.stop();
this.messageList.map((item) => {
if (item.sdkFileUrl) {
item.isPlay = false;
}
});
this.messageList[index].isPlay = true;
innerAudioContext.src = src;
this.$nextTick(() => {
innerAudioContext.play();
});
innerAudioContext.onEnded(() => {
this.messageList[index].isPlay = false;
});
},
playStop(index) {
innerAudioContext.stop();
innerAudioContext.onStop(() => {
this.messageList[index].isPlay = false;
});
},
getTagList(tag) {
this.$http
.post(`/app/appmasssendingtaskbaidu/logsByTag?tag=${tag}`)
.then((res) => {
if (res.code == 0) {
this.tagList = res.data;
if (this.tagList.length) {
this.showMask = true;
} else {
this.$u.toast("暂未查询到热点话题信息");
}
}
});
},
},
};
</script>
<style lang="scss" scoped>
.AppAiDemo {
height: 100vh;
// padding-top: 32px;
background-color: #fff;
.service-content {
width: 100%;
height: 420px;
background-image: url("https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/content-top-bg.png");
background-size: 100vw;
background-repeat: no-repeat;
padding-top: 20px;
box-sizing: border-box;
.text-content {
margin: 0 0 0 32px;
width: 686px;
height: 260px;
background-image: url("https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/service-content-bg.png");
background-size: 100vw;
background-repeat: no-repeat;
padding: 32px;
box-sizing: border-box;
border-radius: 32px;
display: flex;
justify-content: space-between;
.text-left {
width: calc(100% - 192px);
div {
line-height: 54px;
font-family: SourceHanSansCN-Bold;
font-weight: 700;
font-size: 36px;
background: linear-gradient(to bottom, #2a6ee9, #58a5f7);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin-bottom: 16px;
}
p {
color: #222;
font-size: 28px;
font-family: SourceHanSansCN;
line-height: 44px;
span {
display: inline-block;
font-weight: 700;
}
}
}
.service-img {
display: inline-block;
width: 192px;
height: 170px;
}
}
}
.statistics-content {
width: 686px;
background: #f1f4f8;
border-radius: 12px 12px 12px 0;
padding: 32px;
box-sizing: border-box;
color: #222;
margin-bottom: 32px;
.title {
line-height: 44px;
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 32px;
margin-bottom: 24px;
}
.item-info {
font-size: 28px;
font-family: PingFangSC;
line-height: 48px;
color: #222;
margin-bottom: 8px;
.label {
color: #666;
}
}
.mini-title {
line-height: 44px;
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 32px;
margin-bottom: 16px;
span {
display: inline-block;
width: 8px;
height: 32px;
background: #3975c6;
border-radius: 4px;
margin-right: 16px;
vertical-align: middle;
}
}
.info {
font-size: 28px;
font-family: PingFangSC;
line-height: 48px;
margin-bottom: 20px;
span {
color: #0d63f2;
}
}
.mar-b12 {
margin-bottom: 12px;
}
.flex-info {
display: flex;
justify-content: space-between;
}
.down-flex {
display: block;
justify-content: normal;
.info {
display: inline-block;
width: 50%;
}
}
.flex-total {
display: flex;
justify-content: space-between;
margin-bottom: 32px;
.item-total {
p {
font-size: 28px;
font-family: PingFangSC;
line-height: 40px;
margin-bottom: 8px;
}
div {
line-height: 48px;
span {
color: #0d63f2;
}
}
}
}
.hot {
.item-hot {
display: inline-block;
width: 50%;
line-height: 60px;
font-family: PingFangSC-Regular;
font-size: 28px;
color: #0d63f2;
span {
display: inline-block;
margin-right: 16px;
font-family: fantasy;
}
.color0 {
color: #eabd2c;
}
.color1 {
color: #95a2a6;
}
.color2 {
color: #b89383;
}
.color3,
.color4 {
color: #666666;
}
}
}
}
.list-content {
padding: 32px 32px 364px;
overflow: hidden;
background-color: #fff;
.item {
max-width: 600px;
border-radius: 24px 24px 0 24px;
padding: 24px 32px;
box-sizing: border-box;
margin-bottom: 32px;
.img-div {
margin-bottom: 4px;
img {
width: 136px;
height: 28px;
margin-left: 26px;
}
}
p {
word-break: break-all;
line-height: 48px;
font-family: SourceHanSansCN-Regular;
font-size: 32px;
}
}
.item-right {
display: flex;
justify-content: flex-end;
.item {
background-image: linear-gradient(-76deg, #569ef0 0%, #276fec 100%);
}
p {
color: #fff;
}
}
.item-left {
.item {
background-color: #f1f4f8;
}
p {
color: #222;
}
}
}
.back-btn {
line-height: 64px;
background-color: #b8b8b8;
border-top-right-radius: 44px;
border-bottom-right-radius: 44px;
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 28px;
color: #fff;
padding: 0 32px 0 16px;
position: fixed;
left: 0;
bottom: 276px;
z-index: 99;
}
.fixed-bottom {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
padding-bottom: 64px;
border-top: 1px solid #eee;
background-color: #fff;
.type-text {
padding: 24px 0 24px 32px;
display: flex;
.u-input {
width: calc(100% - 112px);
height: 80px;
background: #f4f6fa;
border-radius: 40px;
padding-left: 32px;
border-radius: 40px;
box-sizing: border-box;
}
img {
width: 80px;
height: 80px;
padding: 0 16px;
}
}
.type-record {
position: relative;
text-align: center;
padding-top: 36px;
.keyboard-btn {
width: 48px;
height: 36px;
position: absolute;
top: 32px;
right: 32px;
}
p {
line-height: 58px;
font-family: SourceHanSansCN-Medium;
font-weight: 500;
font-size: 40px;
color: #222;
}
.record-btn {
width: 156px;
height: 156px;
margin-top: 24px;
}
.tips-text {
line-height: 40px;
font-family: SourceHanSansCN-Regular;
font-size: 28px;
color: #999;
margin-top: 16px;
}
.recording {
padding-top: 48px;
width: 204px;
height: 96px;
}
}
}
.mask-content {
padding: 32px 32px 8px 32px;
box-sizing: border-box;
.mini-title {
line-height: 44px;
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 32px;
margin-bottom: 16px;
span {
display: inline-block;
width: 8px;
height: 32px;
background: #3975c6;
border-radius: 4px;
margin-right: 16px;
vertical-align: middle;
}
}
.list-info {
max-height: 800px;
overflow-y: scroll;
}
.item {
font-family: PingFangSC-Regular;
margin-bottom: 32px;
padding-left: 20px;
.name {
font-size: 28px;
color: #222;
line-height: 40px;
margin-bottom: 8px;
}
.time {
line-height: 28px;
font-size: 20px;
color: #999;
margin-bottom: 8px;
}
.content {
display: inline-block;
line-height: 44px;
font-size: 32px;
color: #333;
background: #c7e7fe;
border-radius: 8px 8px 8px 0;
padding: 14px 12px 14px 20px;
}
}
}
}
</style>

View File

@@ -1,607 +0,0 @@
<template>
<div class="AiAuestions">
<div class="service-content">
<div class="text-content">
<div class="text-left">
<div>你好呀</div>
<p>我是您的<span>AI助手</span></p>
<p>有什么问题都可以问我哟~</p>
</div>
<img src="https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/service.png" alt="" class="service-img">
</div>
</div>
<!-- <scroll-view :scroll-top="scrollTop" scroll-y="true" class="scroll-Y" @scroll="scroll" v-if="messageList.length" :style="{height: scrollHeight+'px'}"> -->
<div class="list-content">
<div v-for="(item, index) in messageList" :key="index">
<div :class="item.userType == 1 ? 'item-left' : 'item-right'" v-if="item.userType != 2">
<div class="item" :class="'item'+index">
<div class="img-div" v-if="item.sdkFileUrl">
<u-icon name="play-circle" :color="item.userType == 0 ? '#fff' : '#A8ADAE'" size="52" v-if="!item.isPlay" @click="play(item.sdkFileUrl, index)"></u-icon>
<u-icon name="pause-circle" :color="item.userType == 0 ? '#fff' : '#A8ADAE'" size="52" v-else @click="playStop(index)"></u-icon>
<img src="https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/recording-white.png" alt="" v-if="item.userType == 0">
<img src="https:yanshi//cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/recording-gray.png" alt="" v-else>
</div>
<p>{{item.content || ''}}</p>
</div>
</div>
</div>
</div>
<!-- </scroll-view> -->
<div class="fixed-bottom">
<div class="type-text" v-if="type == 'text'">
<u-input type="text" placeholder="输入您的问题…" height="80" input-align="left" :clearable="false" :border="true" placeholder-style="color:#666;" v-model="content"></u-input>
<img src="https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/send.png" alt="" v-if="content.length" @click="sendMsg">
<img src="https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/microphone-btn.png" alt="" v-else @click="microPhone">
</div>
<div class="type-record" v-else>
<img src="https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/keyboard-btn.png" alt="" class="keyboard-btn" @click="keyboardClick">
<div v-if="!isStart" @click="startRecord">
<p>点击开始录音</p>
<img src="https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/record-btn.png" alt="" class="record-btn">
</div>
<div v-else @click="endRecord">
<p>正在录音中</p>
<div class="tips-text">点击下方停止录音</div>
<img src="https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/shengbo.gif" alt="" class="recording">
</div>
</div>
</div>
<div class="back-btn" @click="back()"><u-icon name="arrow-left" color="#fff" size="28"></u-icon>返回</div>
</div>
</template>
<script>
import {mapState} from "vuex";
import Recorder from 'recorder-core'
import 'recorder-core/src/engine/mp3'
import 'recorder-core/src/engine/mp3-engine'
const innerAudioContext = uni.createInnerAudioContext();
innerAudioContext.autoplay = true;
export default {
name: 'AiAuestions',
appName: 'Ai助手',
data() {
return {
recorder: null,
type: 'text',
isStart: false,
content: '',
isFlag: false,
voiceUrl: 'http://test87ftp.cunwuyun.cn/20240109/filename-20240109111547.mp3',
voiceId: '0678a73c50b74bdcb8398e14ffbb35e5',
messageList: [
// {
// userType: 0,
// sdkFileUrl: 'http://test87ftp.cunwuyun.cn/20240104/output.mp3',
// isPlay: false
// }
],
current: 1,
pages: 2,
scrollTop: 0,
scrollHeight: '',
preveHeight: '',
showMask: false,
tagList: []
}
},
computed: {
...mapState(['user']),
},
onLoad() {
// this.scrollHeight = uni.getSystemInfoSync().windowHeight
// this.getHistoryList()
// var res = ["http://test87ftp.cunwuyun.cn/20240109/filename-20240109111547.mp3;0678a73c50b74bdcb8398e14ffbb35e5"]
// this.voiceUrl = res[0].split(';')[0]
// this.voiceId = res[0].split(';')[1]
// this.sendVoice()
},
onShow() {
document.title = 'AI助手'
},
methods: {
back() {
uni.navigateBack()
},
startRecord() {
this.isStart = true
this.recorder = Recorder({
type: 'mp3',
sampleRate: 16000,
bitRate: 16
})
this.recorder.open(() => {
this.recorder.start()
})
},
endRecord() {
this.recorder.stop((blob) => {
var formData = new FormData();
formData.append('file', blob, 'filename.mp3');
this.$http.post('/admin/file/add', formData, {
withoutToken: true,
}).then((res) => {
uni.hideLoading()
if (res?.data) {
this.voiceUrl = res.data[0].split(';')[0]
this.voiceId = res.data[0].split(';')[1]
this.isStart = false
this.sendVoice()
}
}).catch(res => {
this.$u.toast(res)
uni.hideLoading()
})
this.recorder.close()
this.recorder = null
}, msg => {
console.log('录音失败:' + msg)
this.recorder.close()
this.recorder = null
})
},
microPhone() {
this.type = 'voice'
this.isStart = false
},
keyboardClick() {
if(this.isStart) return
this.type = 'text'
this.content = ''
},
scroll(e) {
if(e.detail.scrollTop == 0) {
if(this.current > this.pages) {
return this.$u.toast('已加载完成,没有更多数据')
}else {
this.current ++
this.getHistoryList()
}
}
},
sendMsg() {
this.$loading()
this.$http.post("/app/appaigccopilotinfo/add2", {content: this.content, appType: 1}, {withoutToken: true}).then(res => {
if(res.code == 0) {
this.content = ''
this.messageList.push(res.data[0])
this.messageList.push(res.data[1])
this.$nextTick(() => {
uni.createSelectorQuery().select(".list-content").boundingClientRect((res) => {
this.scrollTop = res.height - this.scrollHeight
}).exec();
})
this.$hideLoading()
}
})
},
sendVoice() {
this.$loading()
this.$http.post("/app/appaigccopilotinfo/add2", {sdkFileUrl: this.voiceUrl, fileId: this.voiceId, appType: 1}, {withoutToken: true}).then(res => {
if(res.code == 0) {
this.voiceUrl = ''
this.voiceId = ''
res.data.map((item) => {
if(item.sdkFileUrl) {
item.isPlay = false
}
})
this.messageList.push(res.data[0])
this.messageList.push(res.data[1])
this.$nextTick(() => {
uni.createSelectorQuery().select(".list-content").boundingClientRect((res) => {
this.scrollTop = res.height - this.scrollHeight
}).exec();
})
this.$hideLoading()
}
})
},
getHistoryList() {
this.$loading()
uni.createSelectorQuery().select(".list-content").boundingClientRect((res) => {
this.preveHeight = res.height
}).exec();
this.$http.post(`/app/appaigccopilotinfo/list?current=${this.current}&size=10`).then(res => {
if(res.code == 0 && res.data.records.length) {
res.data.records.map((item) => {
if(item.sdkFileUrl) {
item.isPlay = false
}
if(item.userType == 2) { //统计数据
item.content = JSON.parse(item.content)
console.log(item.content)
}
})
this.messageList = this.current == 1 ? res.data.records : [...res.data.records, ...this.messageList]
this.pages = res.data.pages
this.$nextTick(() => {
uni.createSelectorQuery().select(".list-content").boundingClientRect((res) => {
if(this.current == 1) {
this.scrollTop = res.height - this.scrollHeight
}else {
this.scrollTop = res.height - this.preveHeight
}
}).exec();
})
this.$hideLoading()
}
})
},
play(src, index) {
innerAudioContext.stop();
this.messageList.map((item) => {
if(item.sdkFileUrl) {
item.isPlay = false
}
})
this.messageList[index].isPlay = true
innerAudioContext.src = src;
this.$nextTick(() => {
innerAudioContext.play();
})
innerAudioContext.onEnded(() => {
this.messageList[index].isPlay = false
})
},
playStop(index) {
innerAudioContext.stop();
innerAudioContext.onStop(() => {
this.messageList[index].isPlay = false
})
},
getTagList(tag) {
this.$http.post(`/app/appmasssendingtaskbaidu/logsByTag?tag=${tag}`).then(res => {
if(res.code == 0) {
this.tagList = res.data
if(this.tagList.length) {
this.showMask = true
}else {
this.$u.toast('暂未查询到热点话题信息')
}
}
})
}
},
}
</script>
<style lang="scss" scoped>
.AiAuestions {
height: 100vh;
// padding-top: 32px;
background-color: #fff;
.service-content {
width: 100%;
height: 420px;
background-image: url("https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/content-top-bg.png");
background-size: 100vw;
background-repeat: no-repeat;
padding-top: 20px;
box-sizing: border-box;
.text-content {
margin: 0 0 0 32px;
width: 686px;
height: 260px;
background-image: url("https://cdn.cunwuyun.cn/wechat/biaopin/residentAssistant/service-content-bg.png");
background-size: 100vw;
background-repeat: no-repeat;
padding: 32px;
box-sizing: border-box;
border-radius: 32px;
display: flex;
justify-content: space-between;
.text-left {
width: calc(100% - 192px);
div {
line-height: 54px;
font-family: SourceHanSansCN-Bold;
font-weight: 700;
font-size: 36px;
background: linear-gradient(to bottom, #2A6EE9, #58A5F7);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin-bottom: 16px;
}
p {
color: #222;
font-size: 28px;
font-family: SourceHanSansCN;
line-height: 44px;
span {
display: inline-block;
font-weight: 700;
}
}
}
.service-img {
display: inline-block;
width: 192px;
height: 170px;
}
}
}
.statistics-content {
width: 686px;
background: #F1F4F8;
border-radius: 12px 12px 12px 0;
padding: 32px;
box-sizing: border-box;
color: #222;
margin-bottom: 32px;
.title {
line-height: 44px;
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 32px;
margin-bottom: 24px;
}
.mini-title {
line-height: 44px;
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 32px;
margin-bottom: 16px;
span {
display: inline-block;
width: 8px;
height: 32px;
background: #3975C6;
border-radius: 4px;
margin-right: 16px;
vertical-align: middle;
}
}
.info {
font-size: 28px;
font-family: PingFangSC;
line-height: 48px;
margin-bottom: 20px;
span {
color: #0D63F2;
}
}
.mar-b12 {
margin-bottom: 12px;
}
.flex-info {
display: flex;
justify-content: space-between;
}
.down-flex {
display: block;
justify-content: normal;
.info {
display: inline-block;
width: 50%;
}
}
.flex-total {
display: flex;
justify-content: space-between;
margin-bottom: 32px;
.item-total {
p {
font-size: 28px;
font-family: PingFangSC;
line-height: 40px;
margin-bottom: 8px;
}
div {
line-height: 48px;
span {
color: #0D63F2;
}
}
}
}
.hot {
.item-hot {
display: inline-block;
width: 50%;
line-height: 60px;
font-family: PingFangSC-Regular;
font-size: 28px;
color: #0D63F2;
span {
display: inline-block;
margin-right: 16px;
font-family: fantasy;
}
.color0{
color: #EABD2C;
}
.color1{
color: #95A2A6;
}
.color2{
color: #B89383;
}
.color3,
.color4{
color: #666666;
}
}
}
}
.list-content {
padding: 32px 32px 364px;
overflow: hidden;
background-color: #fff;
.item {
max-width: 600px;
border-radius: 24px 24px 0 24px;
padding: 24px 32px;
box-sizing: border-box;
margin-bottom: 32px;
.img-div {
margin-bottom: 4px;
img {
width: 136px;
height: 28px;
margin-left: 26px;
}
}
p {
word-break: break-all;
line-height: 48px;
font-family: SourceHanSansCN-Regular;
font-size: 32px;
}
}
.item-right {
display: flex;
justify-content: flex-end;
.item {
background-image: linear-gradient(-76deg, #569EF0 0%, #276FEC 100%);
}
p {
color: #fff;
}
}
.item-left {
.item {
background-color: #F1F4F8;
}
p {
color: #222;
}
}
}
.back-btn {
line-height: 64px;
background-color: #B8B8B8;
border-top-right-radius: 44px;
border-bottom-right-radius: 44px;
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 28px;
color: #FFF;
padding: 0 32px 0 16px;
position: fixed;
left: 0;
bottom: 276px;
z-index: 99;
}
.fixed-bottom {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
padding-bottom: 64px;
border-top: 1px solid #eee;
background-color: #fff;
.type-text {
padding: 24px 0 24px 32px;
display: flex;
.u-input {
width: calc(100% - 112px);
height: 80px;
background: #F4F6FA;
border-radius: 40px;
padding-left: 32px;
border-radius: 40px;
box-sizing: border-box;
}
img {
width: 80px;
height: 80px;
padding: 0 16px;
}
}
.type-record {
position: relative;
text-align: center;
padding-top: 36px;
.keyboard-btn {
width: 48px;
height: 36px;
position: absolute;
top: 32px;
right: 32px;
}
p {
line-height: 58px;
font-family: SourceHanSansCN-Medium;
font-weight: 500;
font-size: 40px;
color: #222;
}
.record-btn {
width: 156px;
height: 156px;
margin-top: 24px;
}
.tips-text {
line-height: 40px;
font-family: SourceHanSansCN-Regular;
font-size: 28px;
color: #999;
margin-top: 16px;
}
.recording {
padding-top: 48px;
width: 204px;
height: 96px;
}
}
}
.mask-content {
padding: 32px 32px 8px 32px;
box-sizing: border-box;
.mini-title {
line-height: 44px;
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 32px;
margin-bottom: 16px;
span {
display: inline-block;
width: 8px;
height: 32px;
background: #3975C6;
border-radius: 4px;
margin-right: 16px;
vertical-align: middle;
}
}
.list-info {
max-height: 800px;
overflow-y: scroll;
}
.item {
font-family: PingFangSC-Regular;
margin-bottom: 32px;
padding-left: 20px;
.name {
font-size: 28px;
color: #222;
line-height: 40px;
margin-bottom: 8px;
}
.time {
line-height: 28px;
font-size: 20px;
color: #999;
margin-bottom: 8px;
}
.content {
display: inline-block;
line-height: 44px;
font-size: 32px;
color: #333;
background: #C7E7FE;
border-radius: 8px 8px 8px 0;
padding: 14px 12px 14px 20px;
}
}
}
}
</style>

View File

@@ -1,228 +0,0 @@
<template>
<div class="AppTourismStrategy">
<div class="header-bg"></div>
<div class="tourism-content">
<div class="tab">
<div :class="tabIndex == index ? 'item active' : 'item'" v-for="(item, index) in tabList" :key="index" @click="tabClick(index)">{{ item }}</div>
<span :class="`slider`+tabIndex"></span>
</div>
<div class="list-content1" v-if="tabIndex == 0 || cityType == 1">
<div class="item" v-for="(item, index) in list" :key="index" @click="toDetail(item.id, item.input03)">
<img :src="item.imgList[item.imgIndex]" alt="">
<p>{{ item.input03 }}</p>
</div>
<div class="back-btn" v-if="cityType == 1" @click="backCity()">返回城市列表</div>
</div>
<div class="list-content2" v-if="tabIndex == 1 && cityType == 0">
<div class="item" v-for="(item, index) in list" :key="index" @click="getCity(item.input00)">
<img :src="item.imgList[item.imgIndex]" alt="">
<span>{{ item.input01 }}</span>
</div>
</div>
</div>
</div>
</template>
<script>
import {mapState} from "vuex";
export default {
name: 'AppTourismStrategy',
appName: '旅游攻略',
data() {
return {
tabList: [ '周边旅游', '国内旅游'],
tabIndex: 0,
list: [],
areaId: '411702000000',
cityType: 0, //0国内 1国内周边
cityAreaId: '', //国内周边城市ID
}
},
computed: {
...mapState(['user']),
},
onLoad(option) { //type 0周边、1国内
this.areaId = option.areaId
this.tabIndex = option.type || 0
// uni.$on('tourismBack', (res) => {
// this.cityAreaId = res.cityAreaId
// this.getList()
// })
this.getList()
},
onShow() {
document.title = '旅游攻略'
},
methods: {
tabClick(index) {
this.tabIndex = index;
this.cityType = 0
this.getList()
},
toDetail(id, title) {
uni.navigateTo({url: `./Detail?id=${id}&cityAreaId=${this.cityAreaId}&title=${title}`})
},
backCity() {
this.cityType = 0
this.cityAreaId = ''
this.getList()
},
getCity(areaId) {
this.cityAreaId = areaId
this.cityType = 1
this.getList()
},
getList() {
this.$http.post("/app/appapplicationinfo/list?appId=875e5087954e429d9ed14820e808aaa4&current=1&size=200",
{
"input00": this.tabIndex == 0 ? this.areaId : this.cityAreaId,
"radio06": this.tabIndex
},
{withoutToken: true}).then(res => {
res.data.records.map((item) => {
item.imgList = item.textarea05.split('|')
item.imgIndex = Math.floor(Math.random() * 4)
})
if(this.tabIndex == 1 && this.cityType == 0) {
const areas = {}
res.data.records.map(e=>{
if(!areas[e.input00]){
const {input00,input01,imgList,imgIndex} = e
areas[e.input00] = {input00,input01,imgList,imgIndex}
}
})
this.list = Object.values(areas)
}else {
this.list = res.data.records
}
})
}
}
}
</script>
<style lang="scss" scoped>
.AppTourismStrategy {
height: 100vh;
background-color:#EAEEF6;
position: relative;
.header-bg {
width: 100%;
height: 600px;
background-image: linear-gradient(180deg, #2067f3cc 1%, #2067f300 98%);
}
.tourism-content {
width: calc(100% - 64px);
min-height: calc(100% - 64px);
background: #FFF;
border-radius: 16px;
position: absolute;
top: 32px;
left: 32px;
padding: 32px 0;
box-sizing: border-box;
.tab {
padding: 0 144px 54px 144px;
display: flex;
position: relative;
.item {
flex: 1;
text-align: center;
width: 128px;
line-height: 48px;
font-family: PingFangSC-Regular;
font-size: 32px;
color: #666;
}
.active {
font-family: PingFangSC-SNaNpxibold;
font-weight: 600;
color: #000;
}
span {
position: absolute;
top: 64px;
width: 48px;
height: 6px;
background: #2066F3;
border-radius: 3px;
transition: left 0.3s ease;
}
.slider0 {
left: 218px;
}
.slider1 {
left: 418px;
}
}
.list-content1 {
padding-left: 32px;
.item {
display: inline-block;
margin: 0 32px 32px 0;
width: calc(50% - 32px);
vertical-align: text-top;
img {
width: 294px;
height: 220px;
}
p {
line-height: 40px;
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 28px;
color: #222;
text-align: center;
margin-top: 16px;
width: 100%;
word-break: break-all;
}
}
.item:nth-of-type(2n) {
margin-right: 0;
}
.back-btn {
width: calc(100% - 32px);
height: 88px;
background: #2067F4;
border-radius: 44px;
line-height: 88px;
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 34px;
color: #FFF;
text-align: center;
margin-top: 126px;
}
}
.list-content2 {
padding-left: 32px;
.item {
display: inline-block;
position: relative;
margin: 0 32px 32px 0;
img {
width: 186px;
height: 186px;
border-radius: 8px;
}
span {
line-height: 40px;
font-family: PingFangSC-SNaNpxibold;
font-weight: 600;
font-size: 28px;
color: #FFF;
position: absolute;
top: 16px;
left: 24px;
}
}
.item:nth-of-type(3n) {
margin-right: 0;
}
}
}
}
</style>

View File

@@ -1,138 +0,0 @@
<template>
<div class="Detail">
<div class="header-img">
<img :src="info.imgList[info.imgIndex]" alt="">
</div>
<div class="detail-content">
<div class="title">{{ info. input03 }}</div>
<div class="text-content" v-html="info.textarea04"></div>
<div class="ai-btn" @click="toAi()">更多旅游攻略来问问AI吧~<img src="./img/qa-icon.png" alt=""></div>
<div class="back-btn" @click="back()" v-if="cityAreaId">返回</div>
</div>
</div>
</template>
<script>
import {mapState} from "vuex";
export default {
name: 'Detail',
data() {
return {
id: '',
cityAreaId: '',
title: '',
info: {}
}
},
computed: {
...mapState(['user']),
},
onLoad(option) {
this.id = option.id
this.cityAreaId = option.cityAreaId
this.title = option.title
this.getDetail()
},
onShow() {
document.title = this.title
},
methods: {
toAi() {
uni.navigateTo({url: './AiAuestions'})
},
back() {
uni.$emit('tourismBack', {cityAreaId: this.cityAreaId})
uni.navigateBack()
},
getDetail() {
this.$http.post(`/app/appapplicationinfo/queryDetailById?appId=875e5087954e429d9ed14820e808aaa4&id=${this.id}`,
null, {withoutToken: true}).then(res => {
res.data.imgList = res.data.textarea05.split('|')
res.data.imgIndex = Math.floor(Math.random() * 4)
this.info = res.data
})
}
},
}
</script>
<style lang="scss" scoped>
.Detail {
height: 100vh;
background-color: #fff;
position: relative;
.header-img {
width: 100%;
img {
width: 100%;
height: 590px;
}
}
.detail-content {
width: 100%;
min-height: calc(100% - 540px);
background: #FFF;
border-radius: 32px 32px 0 0;
padding: 32px;
box-sizing: border-box;
position: absolute;
top: 540px;
left: 0;
z-index: 9;
.title {
line-height: 48px;
font-family: PingFangSC-SNaNpxibold;
font-weight: 600;
font-size: 36px;
color: #000;
word-break: break-all;
margin-bottom: 18px;
}
.text-content {
padding-bottom: 166px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 28px;
color: #000;
line-height: 48px;
}
.back-btn {
width: calc(100% - 64px);
line-height: 88px;
background: #2067F4;
border-radius: 44px;
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 34px;
color: #FFF;
text-align: center;
position: absolute;
bottom: 32px;
left: 32px;
}
}
.ai-btn {
height: 80px;
background-color: #F3F8FF;
border-radius: 44px 0 0 44px;
padding: 20px 40px;
box-sizing: border-box;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 28px;
color: #2066F3;
position: fixed;
right: 0;
bottom: 168px;
z-index: 99;
img {
display: inline-block;
margin-left: 10px;
width: 44px;
height: 40px;
vertical-align: middle;
}
}
}
</style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -79,6 +79,9 @@
</div>
</div>
</u-popup> -->
<div class="load-content" v-if="showLoad">
<img src="https://cdn.sinoecare.com/i/2024/08/07/66b2cfd4d220d.gif" alt="">
</div>
</div>
</template>
<script>
@@ -123,6 +126,8 @@ export default {
aiConfigName: '',
showType: false,
showPopup: true,
showLoad: false,
latLng: ''
}
},
computed: {
@@ -141,7 +146,7 @@ export default {
this.getHistoryList()
},
methods: {
...mapActions(['autoLogin', 'getUserInfo']),
...mapActions(['autoLogin', 'getUserInfo', 'injectJWeixin',]),
startRecord() {
this.isStart = true
this.recorder = Recorder({
@@ -193,8 +198,9 @@ export default {
if(!this.user.token) {
return this.$u.toast("请先进行登录")
}
this.$loading()
this.$http.post("/app/appaicopilotinfo/add", {content: this.content, appType: 0, areaId: this.areaId, aiConfigId: this.aiConfigId}).then(res => {
// this.$loading()
this.showLoad = true
this.$http.post("/app/appaicopilotinfo/add", {content: this.content, appType: 0, areaId: this.areaId, aiConfigId: this.aiConfigId, supplementContent: this.latLng}).then(res => {
if(res.code == 0) {
this.content = ''
this.messageList.push(res.data[0])
@@ -205,7 +211,8 @@ export default {
selector: `.item${this.messageList.length-1}`
});
})
this.$hideLoading()
// this.$hideLoading()
this.showLoad = false
}
})
},
@@ -213,7 +220,8 @@ export default {
if(!this.user.token) {
return this.$u.toast("请先进行登录")
}
this.$loading()
// this.$loading()
this.showLoad = true
this.$http.post("/app/appaicopilotinfo/add", {sdkFileUrl: this.voiceUrl, fileId: this.voiceId, appType: 0, aiConfigId: this.aiConfigId}).then(res => {
if(res.code == 0) {
this.voiceUrl = ''
@@ -229,7 +237,8 @@ export default {
duration: 300,
selector: `.item${this.messageList.length-1}`
});
this.$hideLoading()
// this.$hideLoading()
this.showLoad = false
}
})
},
@@ -237,7 +246,8 @@ export default {
if(!this.user.token) {
return this.$u.toast("请先进行登录")
}
this.$loading()
// this.$loading()
this.showLoad = true
this.$http.post(`/app/appaicopilotinfo/list?current=${this.current}&size=10&aiConfigId=${this.aiConfigId}`).then(res => {
if(res.code == 0 && res.data.records.length) {
res.data.records.map((item) => {
@@ -254,7 +264,8 @@ export default {
});
})
this.pages = res.data.pages
this.$hideLoading()
// this.$hideLoading()
this.showLoad = false
}
})
},
@@ -315,6 +326,15 @@ export default {
this.aiConfigId = val[0].value
this.aiConfigName = val[0].label
this.messageList = []
this.typeList.map((item) => {
if(item.dictValue == this.aiConfigId) {
if(item.ability == 1) {
this.getLocation()
}else {
this.latLng = ''
}
}
})
},
getAiTypeList() {
this.$http.post(`/app/appaiconfiginfo/list?status=1`).then(res => {
@@ -326,10 +346,30 @@ export default {
this.typeList = res.data.records
this.aiConfigId = this.typeList[0].dictValue
this.aiConfigName = this.typeList[0].dictName
if(this.typeList[0].ability == 1) {
this.getLocation()
}else {
this.latLng = ''
}
// this.getHistoryList()
}
})
}
},
getLocation() {
this.injectJWeixin(['getLocation']).then(() => {
wx.getLocation({
type: 'wgs84',
success: res => {
this.latLng = `${res.latitude},${res.longitude}`
},
error: res => {
console.log(res)
}
})
}).catch(e => {
})
},
},
}
</script>
@@ -666,5 +706,23 @@ page {
}
}
}
.load-content {
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, .8);
position: fixed;
top: 0;
left: 0;
z-index: 99;
text-align: center;
img {
width: 560px;
height: 560px;
position: relative;
top: 50%;
margin-top: -280px;
}
}
}
</style>