123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- <template>
- <div class="counsel-container">
- <div class="counsel-header">
- <span>会话<i class="ai el-icon-chat-dot-round"></i></span>
- </div>
- <div class="counsel-chats">
- <div class="counsel-left flex">
- <div class="header-img">
- <img src="/static/images/aiModel/kefu.png" />
- </div>
- <div class="content">
- <span>Hi,有问题您可以这样问我:</span>
- <span class="high" @click="sendDefault">{{ defaultMsg }}</span>
- </div>
- </div>
- <!--右侧-->
- <div v-for="(item, index) in questionList" :key="index">
- <!--右侧-->
- <div class="counsel-right flex" v-if="item.type == 0">
- <i class="el-icon-loading" v-if="item.mstatus == 0"></i>
- <i
- class="el-icon-warning cursor"
- v-else-if="item.mstatus == 1"
- @click="sendToBackend(item.content, index)"
- ></i>
- <div class="content" v-if="item.content">
- <span>{{ item.content }}</span>
- </div>
- <audio v-else controls autoplay :src="item.mp3url"></audio>
- <div class="header-img">
- <img src="/static/images/aiModel/default.png" />
- </div>
- </div>
- <!--左侧-->
- <div class="counsel-left flex" v-else>
- <div class="header-img">
- <img src="/static/images/aiModel/kefu.png" />
- </div>
- <div class="content">
- <span v-if="item.type" class="tit">参考意见</span>
- <span :class="{ high: item.type }" @click="onClick(item)">
- {{ item.content }}
- </span>
- </div>
- </div>
- </div>
- </div>
- <div class="voice" v-if="spdisabled">
- <div>正在识别</div>
- <div class="noise"></div>
- </div>
- <div class="searchBtom">
- <div
- class="icon"
- :class="
- spdisabled ? 'el-icon-turn-off-microphone' : 'el-icon-microphone'
- "
- title="按住说话"
- :disabled="spdisabled"
- @click="voice"
- ></div>
- <el-input
- clearable
- v-model="sendContent"
- @input="change_witch"
- class="search"
- placeholder="请输入问题"
- ></el-input>
- <div
- class="el-icon-s-promotion icon sendIcon"
- :class="sendContent ? 'ok' : 'no'"
- @click="send"
- ></div>
- </div>
- </div>
- </template>
- <script>
- import { AddFzxz } from "../../api/ghss/ghxz.js";
- import record from "./record.js";
- let recognition = null;
- export default {
- props: {},
- data() {
- return {
- questionList: [
- { type: 0, mp3url: "" },
- {
- type: "selectLand",
- content: "sss",
- data: { rwbsm: "5f3d25e556374e78966feca5a64fa887" },
- },
- ],
- defaultMsg:
- "我要在抱坡区进行选址,用地面积30到50亩,选择居住用地,距离幼儿园200米,距离医院300米,距离火葬场大于5000米",
- sendContent: "",
- spdisabled: false,
- };
- },
- created() {},
- mounted() {},
- methods: {
- initSpeech() {
- // 检查浏览器是否支持SpeechRecognition
- const SpeechRecognition =
- window.SpeechRecognition || window.webkitSpeechRecognition;
- if (!SpeechRecognition) {
- alert(
- "你的浏览器不支持语音识别功能,请使用支持的浏览器,例如Google Chrome。"
- );
- } else {
- recognition = new SpeechRecognition();
- recognition.lang = "zh-CN"; // 设置识别语言为中文
- recognition.interimResults = false; // 不返回临时结果
- recognition.maxAlternatives = 1; // 返回的识别结果数量
- recognition.onstart = () => {
- this.$message.success("开始语音识别...");
- this.spdisabled = true;
- };
- recognition.onresult = (event) => {
- this.sendContent = event.results[0][0].transcript;
- // this.send(); // 将识别结果发送到后台
- };
- recognition.onerror = (event) => {
- this.$message.warning("语音识别出错: " + event.error);
- };
- recognition.onend = () => {
- // this.$message.success("语音识别结束:");
- console.log("语音识别结束");
- this.spdisabled = false;
- };
- }
- },
- /**初始化 */
- init() {
- let _this = this;
- record.getPermission(function (permiss) {
- if (permiss.status == "fail") {
- _this.$message.warning("语音识别出错: " + permiss.data);
- } else {
- record.startRecorder();
- _this.$message.success("开始语音识别...");
- _this.spdisabled = true;
- }
- });
- },
- /**结束录音 */
- stop() {
- let _this = this;
- record.stopRecorder(function (res) {
- console.log("-blob----", res);
- _this.questionList.push({
- type: 0,
- mp3url: (window.URL || webkitURL).createObjectURL(res.blob),
- mstatus: 0,
- });
- /**处理 */
- axios({
- method: "POST",
- url: `${window.aiURI}/upload`,
- data: res.formData,
- headers: {
- "Content-Type": "application/json",
- },
- })
- .then((mres) => {
- if (mres.status == 200) {
- } else {
- }
- })
- .catch(() => {});
- });
- this.spdisabled = false;
- },
- sendDefault() {
- this.sendContent = this.defaultMsg;
- // this.send();
- },
- send() {
- // 咨询问题
- if (this.sendContent) {
- this.questionList.push({
- type: 0,
- content: this.sendContent,
- mstatus: 0,
- });
- this.sendToBackend(this.sendContent, this.questionList.length - 1);
- this.sendContent = "";
- }
- },
- voice() {
- console.log("---this.spdisabled-", this.spdisabled);
- if (!this.spdisabled) {
- // if (!recognition) this.initSpeech();
- // recognition.start(); // 开始语音识别
- this.init();
- } else {
- this.stop();
- }
- },
- sendToBackend(msg, mindex) {
- this.questionList[mindex].mstatus = 0;
- axios({
- method: "POST",
- url: `${window.aiURI}/msg`,
- data: JSON.stringify({ msg }),
- headers: {
- "Content-Type": "application/json",
- },
- })
- .then((mres) => {
- if (mres.status == 200) {
- this.questionList[mindex].mstatus = 2;
- if (mres.data.type == "selectLand") {
- this.questionList.push({ content: "分析中...请稍等" });
- const loading = this.$loading({
- lock: true,
- text: "分析中",
- spinner: "el-icon-loading",
- background: "rgba(0, 0, 0, 0.7)",
- });
- AddFzxz(mres.data.data)
- .then((res) => {
- loading.close();
- this.questionList.push({
- type: mres.data.type,
- content: "查看智能选址结果",
- data: res.data,
- });
- this.$message({
- message: res.message,
- type: res.success ? "success" : "warning",
- });
- })
- .catch((error) => {
- loading.close();
- this.$message.error(error);
- });
- }
- } else {
- this.questionList[mindex].mstatus = 1;
- // this.$message.error("发送到后台时发生错误:");
- }
- })
- .catch(() => {
- this.questionList[mindex].mstatus = 1;
- // this.$message.error("发送到后台时发生错误:");
- });
- },
- onClick(item) {
- if (item.type == "selectLand") {
- this.$router.push({
- path: "/siteselection",
- query: { rwbsm: item.data.rwbsm },
- });
- this.$emit("close");
- }
- },
- },
- };
- </script>
- <style lang="less" scoped>
- .flex {
- display: flex;
- }
- //智能咨询
- .counsel-container {
- padding: 15px;
- width: 100%;
- height: 100%;
- position: absolute;
- background: #222;
- .counsel-header {
- display: flex;
- align-items: center;
- padding: 20px;
- font-size: 16px;
- color: #fff;
- border-bottom: 1px solid #1f4099;
- }
- .time {
- display: block;
- text-align: center;
- margin-bottom: 20px;
- color: #999999;
- line-height: 40px;
- }
- .counsel-chats {
- height: calc(100% - 150px);
- overflow-x: hidden;
- overflow-y: auto;
- .header-img {
- // flex: 0 0 50px;
- margin-left: 10px;
- width: 50px;
- height: 50px;
- border-radius: 50px;
- display: block;
- overflow: hidden;
- img {
- width: 50px;
- height: 50px;
- border-radius: 50px;
- object-fit: cover;
- }
- }
- .high {
- color: #b6e0ff !important;
- cursor: pointer;
- display: block;
- }
- .cursor {
- cursor: pointer;
- }
- .content {
- // flex: 1;
- margin-left: 10px;
- max-width: calc(100% - 100px);
- padding: 5px 20px;
- border-radius: 8px;
- background: #40a0ff6c;
- .tit {
- display: block;
- color: #f99f2b;
- margin-bottom: 10px;
- }
- span {
- color: #ffffff;
- line-height: 20px;
- }
- }
- .counsel-left {
- margin-bottom: 30px;
- align-items: flex-start;
- .content {
- background: #b6e1ff3b;
- }
- }
- .counsel-right {
- margin-bottom: 30px;
- justify-content: flex-end;
- align-items: flex-start;
- width: 100%;
- i {
- font-size: 20px;
- }
- }
- }
- audio {
- height: 40px;
- }
- audio::-webkit-media-controls-enclosure {
- background-color: #b6e1ff3b;
- color: #fff;
- }
- }
- .voice {
- width: 75%;
- // height: 100px;
- position: absolute;
- left: 15%;
- bottom: 92px;
- text-align: center;
- border-radius: 8px;
- background: #40a0ff6c;
- padding: 5px 20px;
- .noise {
- width: 110px;
- height: 40px;
- background-image: url("/static/images/aiModel/noise.png");
- background-size: 100% 100%;
- margin: 10px auto;
- }
- }
- .searchBtom {
- position: absolute;
- bottom: 20px;
- width: calc(100% - 20px);
- height: 70px;
- background: #44444e !important;
- border: 1px solid rgba(0, 0, 0, 0.12);
- box-shadow: #0003 0 0 10px;
- border-radius: 8px;
- display: flex;
- padding-top: 15px;
- .search {
- width: calc(100% - 120px);
- margin: 0 10px;
- }
- .icon {
- width: 40px;
- height: 40px;
- font-size: 40px;
- cursor: pointer;
- }
- .no {
- color: #2f2f39;
- }
- .ok {
- color: #0f7ac8;
- }
- }
- </style>
|