赞
踩
我用的是vue-cli命令行创建uniapp项目。
踩坑1:执行命令报错了
npm ERR! Darwin 20.6.0
npm ERR! argv "/Users/zhuzhu/.nvm/versions/node/v6.2.0/bin/node" "/Users/zhuzhu/.nvm/versions/node/v6.2.0/bin/npm" "install"
npm ERR! node v6.2.0
npm ERR! npm v3.8.9
npm ERR! This request requires auth credentials. Run `npm login` and repeat the request.
npm ERR!
npm ERR! If you need help, you may report this error at:
npm ERR! <https://github.com/npm/npm/issues>
npm ERR! Please include the following file with any support request:
npm ERR! /Users/zhuzhu/Downloads/uni-preset-vue-vite/npm-debug.log
解决:直接访问官网的gitee,下载模板,然后npm install,之后在npm run XX运行你想要的程序就好啦。
- <template>
- <view class="main-dislogue">
- <view class="header-suspension">
- <view class="record-btn">悬浮</view>
- </view>
- <view class="content" ref="QAContent">
- <scroll-view id="scrollpage" :scroll-top="scrollTop" :scroll-y="true">
- <view v-for="item in dest" :key="item.id" id="msglistview">
- <view class="ask" v-if="item.flag != 1">
- <view class="ask-text">
- <view class="ask-desc" style="word-break: break-all;">
- {{ item.content }}
- </view>
- </view>
- <text class="ask-bulge"></text>
- <view class="ask-avatar">
- <image class="ask-sex" v-if="sex == 1" src="/static/boy.png" fit="contain"></image>
- <image class="ask-sex" v-if="sex == 2" src="/static/girl.png" fit="contain"></image>
- </view>
- </view>
- <view class="answer">
- <view class="answer-avatar">
- <image class="answer-ai" src="/static/ai.png" fit="contain"></image>
- </view>
- <text class="answer-bulge"></text>
- <view class="answer-text">
- <view class="answer-desc" ref="copyAiContent">{{item.ai_content}}</view>
- </view>
- </view>
- </view>
- </scroll-view>
- </view>
- <view class="bottom">
- <input :cursorSpacing="20" class="bottom-input" name="name" placeholder="请输入" v-model="value"/>
- <button class="bottom-button" type="primary" :disabled="isSend" @click="handleSend">发送</button>
- </view>
- </view>
- </template>
- <style>
- .main-dislogue {
- height: calc(100vh - 70px);
- background: #f5f5f5;
- display: flex;
- flex-direction: column;
- }
-
- /* 头部悬浮 */
- .header-suspension {
- width: 100rpx;
- height: 300rpx;
- /* pointer-events: none; */
- z-index: 100;
- position: fixed;
- right: 10rpx;
- bottom: 300rpx;
- }
- .head-image {
- width: 74rpx;
- height: 74rpx;
- z-index: 99;
- background: #d4d4d4;
- border-radius: 50%;
- padding: 6rpx;
- box-shadow: 0px 2rpx 20rpx rgba(0, 0, 0, 0.5);
- }
- .record-btn {
- width: 74rpx;
- height: 74rpx;
- background: #FFFFFF;
- border-radius: 50%;
- font-size: 26rpx;
- text-align: center;
- padding: 6rpx;
- box-shadow: 0px 2rpx 20rpx rgba(0, 0, 0, 0.5);
- color: #4A90E2;
- margin-top: 29rpx;
- }
-
- /* 内容 */
- .content {
- padding: 12rpx;
- padding-bottom: 100px;
- background: #f5f5f5;
- }
- /* #scrollpage {
- } */
-
- /* 问 */
- .ask {
- display: flex;
- justify-content: flex-end;
- width: 100%;
- margin-top: 6rpx;
- }
- .ask-avatar {
- width: 120rpx;
- margin-top: 20rpx;
- }
- .ask-sex {
- width: 100rpx;
- height: 100rpx;
- }
- .ask-bulge {
- position: relative;
- top: 41rpx;
- right: 23rpx;
- display: block;
- width: 0;
- height: 0;
- border: 15rpx solid #38a579;
- transform: rotate(45deg);
- }
- .ask-text {
- z-index: 1;
- }
- .ask-desc {
- background: #38a579;
- border-radius: 13rpx;
- padding: 15rpx;
- line-height: 58rpx;
- margin-top: 27rpx;
- white-space: pre-line;
- word-break: break-all;
- color: #fff;
- margin-left: 124rpx;
- }
-
- /* 答 */
- .answer {
- display: flex;
- justify-content: flex-start;
- margin-top: 6rpx;
- }
- .answer-avatar {
- width: 120rpx;
- margin-top: 20rpx;
- }
- .answer-ai {
- width: 100rpx;
- height: 100rpx;
- }
- .answer-bulge {
- position: relative;
- top: 41rpx;
- left: 23rpx;
- display: block;
- width: 0;
- height: 0;
- border: 15rpx solid #ffffff;
- transform: rotate(45deg);
- }
- .answer-text {
- z-index: 1;
- }
- .answer-desc {
- margin-right: 88rpx;
- border-radius: 13rpx;
- line-height: 58rpx;
- background: #fff;
- margin-top: 27rpx;
- tab-size: 12rpx;
- padding: 15rpx;
- white-space: pre-wrap;
- box-shadow: 0rpx 5rpx 47rpx 0rpx #97979773;
- }
-
- /* 尾部 */
- .bottom {
- border-top: 2rpx solid #CCCCCC;
- background: #f5f5f5;
- display: flex;
- padding: 10rpx;
- padding-bottom: 50rpx;
-
-
- position: fixed;
- bottom: 0;
- z-index: 99;
- width: 100%;
- }
- .bottom-input {
- flex: 1;
- font-size: 35rpx;
- border-radius: 10rpx;
- background: #FFFFFF;
- padding: 17rpx;
-
- }
- .bottom-button {
- width: 190rpx;
- height: 80rpx;
- font-size: 14px;
- line-height: 80rpx;
- margin-left: 20rpx;
- background: #4A90E2 !important;
- }
- </style>
- <script>
- import Api from "@/utils/api.js";
- import base from '@/utils/base.js';
- const BASE_URL = base.baseUrl;
- const recorderManager = uni.getRecorderManager()
-
- export default {
- data() {
- return {
- sex: "",
- birthDate: "",
- generateRecordsFlag: false,
- dest: [],
- dialogue_code: "",
- value: "",
- isSend: false,
- scrollTop: 0,
- currentText: "",
- isSpeaking: false
- }
- },
- onLoad(option) {
- this.sex = option.sex;
- this.birthDate = option.birthDate;
- this.dialogue_code = option.dialogue_code;
- },
- onReady() {
- let _this = this;
- uni.getStorage({
- key: 'gpt_h5_dialogue',
- success: function (res) {
- let list = res.data || "";
- if (list.length) {
- this.dest = JSON.parse(list);
- if (this.dest.length >= 2) {
- this.generateRecordsFlag = true;
- }
- } else {
- setTimeout(() => {
- _this.handleSend();
-
- }, 500)
- }
- }
- });
- },
- methods: {
- // 年龄转换
- ageCalculation(date) {
- var today = new Date();
-
- // 获取出生日期
- var birthDate = new Date(date); // 假设出生日期为1990年1月1日
-
- // 计算年龄
- var age = today.getFullYear() - birthDate.getFullYear();
- var m = today.getMonth(), d = today.getDate();
- if (m < birthDate.getMonth()) {
- age--;
- } else if (m === birthDate.getMonth() && d < birthDate.getDate()) {
- age--;
- }
- return age;
- },
- // 发送聊天
- async handleSend() {
- this.preEventSource && this.preEventSource?.close();
-
- if (this.dest.length != 0 && !this.value) {
- return;
- }
-
- let _this = this;
- let { prompt, model } = await Api.getPromptList({ type: 1 });
- let sex = this.sex == 1 ? "男" : "女";
- let age = this.ageCalculation(this.birthDate);
- prompt = prompt.replace('{age}', `${age}岁`).replace('{sex}', `${sex}性`);
- let obj = {
- ai_content: "...",
- chat_model: model,
- content: prompt,
- create_time: "2024-01-05T06:55:29.000Z",
- dialogue_code: this.dialogue_code,
- id: 450,
- req_time: "2024-01-05T06:55:30.000Z",
- res_time: null,
- tags: null,
- user_code: "00468",
- flag: 1
- };
- const diaObj = {
- content: this.value,
- ai_content: "...",
- chat_model: model,
- create_time: new Date(),
- dialogue_code: this.dialogue_code,
- id: Date.now(),
- tags: null,
- user_code: "00468",
- loading: false,
- flag: 2
- };
- if (this.dest.length == 0) {
- // 第一次
- this.dest.push(obj);
- } else {
- this.dest.push(diaObj);
- }
- let params = {
- "dialogue_code": this.dialogue_code,
- "content": this.value || this.dest[0].content,
- "chat_model": model
- }
-
- this.isSend = true;
- _this.scrollToBottom();
-
- let ai_content = "", startFlag = false;
- this.value = ""; // 置空输入框
- // 从这往上可以忽略,这是我业务逻辑,不必关注。重点是uni.request success回调内容
-
- uni.request({
- url: `${BASE_URL}/hmgpt/dialogue`,
- data: params,
- method: "POST",
- headers: {
- "Content-Type": 'application/json',
- },
- success: (res) => {
- let str = JSON.stringify(res.data);
-
- // 将字符串按"data: ["分割,然后取最后一个部分
- const lastDataSection = str.split("data: [").pop();
-
- // 截取最后一个JSON对象的部分
- const lastJsonString = lastDataSection.split("]")[0].replace(/\\/g, '');
-
- // 解析JSON字符串
- const lastJsonObject = JSON.parse(lastJsonString);
-
- // 获取ai_content的值
- const lastAiContent = lastJsonObject.ai_content;
-
- console.log(lastAiContent, 'lastAiContent');
-
- ai_content = lastAiContent;
-
- if (lastAiContent == "") {
- // 返回空,则默认提示
- ai_content = "目前公司GPU服务器有限,会因为调试需要临时中断出现服务不可用,请稍后重试。";
- }
- _this.dest[_this.dest.length - 1].ai_content = "";
-
- if (!startFlag) {
- startFlag = true
- startTyping();
- }
- }
- });
-
-
- function startTyping() {
- let currentIndex = 0;
- const typingSpeed = 100; // 打字速度,单位:毫秒
-
- const timer = setInterval(() => {
- _this.dest[_this.dest.length - 1].ai_content += ai_content[currentIndex];
- currentIndex++;
- _this.scrollToBottom();
-
- if (currentIndex >= ai_content.length) {
- clearInterval(timer);
- _this.isSend = false;
- }
- }, typingSpeed);
-
-
- uni.setStorage({
- key: 'gpt_h5_dialogue',
- data: JSON.stringify(_this.dest),
- success: function () { }
- });
- }
- },
- // 滚动至聊天底部
- scrollToBottom() {
- this.$nextTick(() => {
- const query = uni.createSelectorQuery();
- query.select('#scrollpage').boundingClientRect();
- query.exec(res => {
- this.scrollTop = res[0].height;
- uni.pageScrollTo({
- scrollTop: res[0].height + 170, // 将滚动位置设置为顶部
- duration: 300 // 滚动到顶部的动画时长,单位为毫秒
- });
- })
- })
- }
- },
- }
- </script>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。