人工智能+GPT微信小程序聊天机器人(deepSeek)

一 . 项目功能:

      1.智能问答(实时聊天+流畅打字机效果+自动滚动)
      2.语音输入
      3.停止生成(中断请求)、重新生成
      4.复制功能、分页功能

二 . 效果展示:

   人工智能+GPT微信小程序聊天机器人(deepSeek)_第1张图片人工智能+GPT微信小程序聊天机器人(deepSeek)_第2张图片

三 . 技术分析:

    1. RequestTask请求:  小程序中wx.request 默认不支持流式数据请求。但是设置enableChunked为true,可以在onChunkReceived中分块接收数据,实现响应内容实时输出。停止请求时,调用requestTask.abort()即可。

data: {
   requestTask: null as WechatMiniprogram.RequestTask | null
},

//发送请求
requestFn(){
   var that = this;
   const requestTask = wx.request({
      url: `https://XXXX?message=${inputStr}`,
      responseType: "arraybuffer",
      method: "GET",
      enableChunked: true,
    });

    //接口响应成功,但此时无内容响应,相当于fetchEventSource的open阶段
    requestTask.onHeadersReceived(function (res: any) {});

    //持续内容响应,相当于fetchEventSource的onmessage阶段
    requestTask.onChunkReceived(function (r) {});

    that.setData({
      requestTask: requestTask,
    });
}

 //停止生成
stopFn() {
  if (this.data.requestTask) {
     this.data.requestTask.abort();
     this.setData({
        requestTask: null, 
     });
  }
}


    2. marked将markdown转为wxml: 接口响应的数据是markdown格式,需要借助marked第三方包转化为wxml,然后通过rich-text渲染。

import { marked } from "../../../miniprogram_npm/marked/lib/marked.esm";

// 使用marked将markdown格式转化为Html格式
markdownToHtml(markdown: string) {
   return marked(markdown)
}


    3. wx.setClipboardData复制功能: 使用微信小程序官网提供的API setClipboardData实现。

copyFn(copyText: string) {
    wx.setClipboardData({
      data: copyText,
      success: function () {
        wx.showToast({
          title: "复制成功",
          icon: "none",
        });
      },
      fail: function () {
        wx.showToast({
          title: "复制失败",
          icon: "none",
        });
      },
    });
  },


    4. recordRecoManager微信语音识别功能: 使用微信小程序官方提供的插件,使用步骤如下:

1、在微信公众平台设置---第三方设置---插件管理添加同声传译插件

2、注册插件
在app.json中注册插件
  “plugins”: {
    “WechatSI”: {
       “version”: “0.3.5”,
       “provider”: “wx069ba97219f66d99”
     }
   },

3、在页面中引入插件并获取语音识别管理器
//引入微信同声传译插件
const plugin = requirePlugin(‘WechatSI’);
//获取全局唯一的语音识别管理器recordRecoManager
const manager = plugin.getRecordRecognitionManager();

4、识别语音 – 初始化
 lifetimes: {
    ready() {
      let that = this;
      //识别结束事件
      manager.onStop = function (res) {
           that.setData({
              question: that.data.question + res.result || "",
           });
      };
      // 正常开始录音识别时会调用此事件
      manager.onStart = function (res) {};
      //识别错误事件
      manager.onError = function (res) {
        wx.showToast({
          title: "没有听清,请重试~",
          icon: "none",
        });
      };
    },
  },

5、绑定语音识别事件
speakFn() {
     if (!this.data.isSpeaking) {
        manager.start({ duration: 60000, lang: "zh_CN" });
     } else {
        manager.stop();
     }
}


    5. 置顶/置底/自动滚动功能: 在scroll-view标签监听滚动事件bindscroll,当scrollHeight - scrollTop - offsetHeight < 20时,说明滚动到屏幕底部,显示向上滚动按钮,并通过设置scrollTop=0实现置顶功能;当scrollTop < 5时,说明到顶部,显示向下滚动按钮,并通过设置scrollTop=999999(设置一个足够大的值,确保滚动到底部)实现置底功能;同时在enableChunked持续接收消息中设置scrollTop=999999实现触底自动滚动。

index.wxml页面:




index.ts页面:

 //滚动事件
onScroll(e: any) {
    const query = wx.createSelectorQuery();
    query.select("#scrollElement").boundingClientRect();
    query.exec((res) => {
      if (res && res[0]) {
        const offsetHeight = res[0].height; // 获取元素的高度(相当于 offsetHeight)
        if (e.detail.scrollHeight - e.detail.scrollTop - offsetHeight < 20) {
          this.setData({
            isBottom: true,
            scrollBottomShow: false,
          });
        } else {
          this.setData({
            isBottom: false,
            scrollBottomShow: true,
          });
        }
      }
    });
    if (e.detail.scrollTop < 5) {
      this.setData({
        scrollTopShow: false,
      });
    } else {
      this.setData({
        scrollTopShow: true,
      });
    }
  },

scrollTopFn() {
    this.setData({
      scrollTop: 0,
      scrollTopShow: false,
    });
},

scrollBottomFn() {
    this.setData({
      scrollTop: 999999,    // 设置一个足够大的值,确保滚动到底部
      scrollBottomShow: false, 
    });
},

requestFn(){
  ......
  requestTask.onChunkReceived(function (r) {
  ......
  that.setData({
      scrollTop: 999999, // 设置一个足够大的值,确保滚动到底部
   });
 })
}

四 . 疑难点及解决方案:

   1.RequestTask.abort()中断请求时,在微信开发者工具中不生效,在真机中可正常使用,建议该功能直接在真机上调试;
   2.requestTask.onChunkReceived有可能同时接收两条信息,所以需将响应数据转化为数组,然后再进行下一步处理:

//判断是否json字符串
const isJSON = (str) => {
  if (typeof str == 'string') {
    try {
      var obj = JSON.parse(str);
      if (typeof obj == 'object' && obj) {
        return true;
      } else {
        return false;
      }
    } catch (e) {
      return false;
    }
  }

}
//request响应数据处理
export const arrayBufferToString = (buffer) => {
  const decoder = new TextDecoder("utf-8"); 
  let text = decoder.decode(buffer)
  let arr = text.split("data:")
  let newArr = []
  arr.forEach(item => {
    if (item && isJSON(item)) {
      newArr.push(JSON.parse(item))
    }
  })
  return newArr
}


  3.在分包中引入marked第三方包报错,原因分析:有时即使按照官方文档操作仍然会出现找不到模块的情况,特别是涉及到不同类型的 JavaScript 模块标准 (ESM vs CJS) 。可考虑采用兼容性的写法导入模块,比如直接引用 dist 版本下的 UMD 格式的 js 文件而不是 src 中源码形式的 esm 或 cjs 文件2。解决方案:将import marked from "../../../miniprogram_npm/marked";改为import { marked } from "../../../miniprogram_npm/marked/lib/marked.esm";

人工智能+GPT微信小程序聊天机器人(deepSeek)_第3张图片

4.使用marked转换markdown为wxml时,部分样式丢失,如table表格丢失行列线及背景色,可手动补充,代码如下:

markdownToHtml(markdown: string) {
    return marked(markdown)
      .replaceAll(
        "",
        '
' ) .replaceAll( "
", '' ) .replaceAll( "", '' ); }

五 . 完整代码:

report.wxml:



  
    
      
      
    
    {{titleStr}}
  
  
    
      
        
          {{ item.message[0] }}
        
        
          
            
              
                
                  
                
                
                  
                  
                
              
            
            
              
                {{lt}}
                 {{ item.answerIndex + 1 }} / {{ item.message.length}}
                {{gt}}
              
              
                
                
                
              
            
          
        
      
    
    正在思考 !
  
  
    
      
        
          
            
          
          停止生成
        
      
      
        

          
        
        
          
        
      
    
    
    内容由AI生成,仅供参考。更专业解答可咨询客服
  
  

report.ts:

// pages/shiye/subpages/report/report.ts
import type { ChatList } from "../../../../typings/types/shiye/index";
import { arrayBufferToString } from "../../../utils/baseutf";
import { marked } from "../../../miniprogram_npm/marked/lib/marked.esm";
Page({
  /**
   * 页面的初始数据
   */
  data: {
    visible: false, //设置菜单弹框是否显示
    inputValue: "", //当前输入框输入的问题
    chatList: [] as ChatList,
    contentItems: "", 当前正在输出的数据流(markdown格式)
    isRegenerate: false, //是否重新生成
    preInputValue: "", //上一次查询输入内容,用于重新生成使用
    isLoading: false, //节流loading
    loadingStatus: false, //加载状态显示loading,当loadingStatus为true,不用展示"正在思考"状态
    requestTask: null as WechatMiniprogram.RequestTask | null,
    scrollTopShow: false,
    scrollBottomShow: false,
    lt: "<",
    gt: ">",
    copyIndex: 0, //复制的索引(chatList中的index)
    copyText: "",
    currentHTML: "",
    scrollTop: 0,
    isRolling: false, //鼠标滚轮是否滚动
    isBottom: true, //滚动参数
    titleStr: "尽调报告",
  },
  //滚动事件
  onScroll(e: any) {
    const query = wx.createSelectorQuery();
    // 选择元素
    query.select("#scrollElement").boundingClientRect();

    // 执行查询
    query.exec((res) => {
      if (res && res[0]) {
        const offsetHeight = res[0].height; // 获取元素的高度(相当于 offsetHeight)
        if (e.detail.scrollHeight - e.detail.scrollTop - offsetHeight < 20) {
          this.setData({
            isBottom: true,
            scrollBottomShow: false,
          });
        } else {
          this.setData({
            isBottom: false,
            scrollBottomShow: true,
          });
        }
      }
    });
    if (e.detail.scrollTop < 5) {
      this.setData({
        scrollTopShow: false,
      });
    } else {
      this.setData({
        scrollTopShow: true,
      });
    }
  },
  //下载尽调报告
  downloadReport(e: any) {
    const url = e.target.dataset.url;
    // const url =
    //   "https://files.bczcc.com/prompt/尽调报告_江苏省建筑工程集团有限公司_55_20250208_170139.docx";
    wx.downloadFile({
      url: url,
      success: function (res) {
        if (res.statusCode === 200) {
          const filePath = res.tempFilePath;
          wx.openDocument({
            filePath: filePath,
            showMenu: true, //默认是false,为true的时候,右上角有三个点
            success: function () {
              console.log("打开文档成功");
            },
            fail: function (err) {
              console.log("打开文档失败", err);
            },
          });
        }
      },
      fail: function (err) {
        console.log("下载文件失败", err);
      },
    });
  },
  //复制
  copyFn(e: any) {
    const index = e.target.dataset.index;
    const answerIndex = e.target.dataset.answerindex;
    this.setData({
      copyIndex: index,
      copyText: this.data.chatList[index].downMessage[answerIndex],
    });
    wx.setClipboardData({
      data: this.data.copyText,
      success: function () {
        wx.showToast({
          title: "复制成功",
          icon: "none",
        });
      },
      fail: function () {
        wx.showToast({
          title: "复制失败",
          icon: "none",
        });
      },
    });
  },
  //重新生成
  regenerateFn() {
    this.setData({
      isRegenerate: true,
    });
    this.requestFn();
  },
  //上一页
  preFn(e: any) {
    const index = e.target.dataset.index;
    const answerIndex = e.target.dataset.answerindex;
    if (this.data.isLoading)
      return wx.showToast({
        title: "正在生成内容,请勿切换。",
        icon: "none",
      });
    const curAnswerIndex = "chatList[" + index + "].answerIndex";
    if (answerIndex === 0) {
      this.setData({
        [curAnswerIndex]: this.data.chatList[index].message.length - 1,
      });
    } else {
      this.setData({
        [curAnswerIndex]: this.data.chatList[index].answerIndex - 1,
      });
    }
  },
  //下一页
  nextFn(e: any) {
    const index = e.target.dataset.index;
    const answerIndex = e.target.dataset.answerindex;
    if (this.data.isLoading)
      return wx.showToast({
        title: "正在生成内容,请勿切换。",
        icon: "none",
      });
    const curAnswerIndex = "chatList[" + index + "].answerIndex";
    if (answerIndex === this.data.chatList[index].message.length - 1) {
      this.setData({
        [curAnswerIndex]: 0,
      });
    } else {
      this.setData({
        [curAnswerIndex]: this.data.chatList[index].answerIndex + 1,
      });
    }
  },
  onChanged(e: any) {
    this.setData({ inputValue: e.detail });
  },
  //停止生成
  stopFn() {
    if (this.data.requestTask) {
      this.data.requestTask.abort();
      this.setData({
        requestTask: null, // 清空 requestTask
      });
      const lastIndex = this.data.chatList.length - 1;
      const lastItem = this.data.chatList[lastIndex];

      if (this.data.isRegenerate) {
        //重新生成
        const messageLast =
          "chatList[" +
          lastIndex +
          "].message[" +
          (lastItem.message.length - 1 + "]");
        const downMessageLast =
          "chatList[" +
          lastIndex +
          "].downMessage[" +
          (lastItem.message.length - 1 + "]");
        const answerIndex = "chatList[" + lastIndex + "].answerIndex";
        this.setData({
          [messageLast]:
            this.data.currentHTML +
            "
停止生成
", [downMessageLast]: this.data.contentItems + "\n" + "\n" + "停止生成" + "\n", [answerIndex]: lastItem.message.length - 1, }); } else { //第一次生成 const curLastIndex = this.data.chatList.length - 1; const lastMessage = "chatList[" + curLastIndex + "].message"; const lastDownMessage = "chatList[" + curLastIndex + "].downMessage"; const lastIsLoading = "chatList[" + curLastIndex + "].isLoading"; this.setData({ [lastMessage]: [ this.data.currentHTML + "
停止生成
", ], [lastDownMessage]: [ this.data.contentItems + "\n" + "\n" + "停止生成" + "\n", ], [lastIsLoading]: false, }); } } }, //置顶 handleScrollToUpper() { this.setData({ scrollBottomShow: true, }); }, //置底 handleScrollToLower() { this.setData({ scrollTopShow: true, }); }, scrollTopFn() { this.setData({ scrollTop: 0, scrollTopShow: false, }); }, scrollBottomFn() { this.setData({ scrollTop: 999999, scrollBottomShow: false, // 设置一个足够大的值,确保滚动到底部 }); }, //设置菜单 setMenu() { this.setData({ visible: true }); }, //返回 backFn() { wx.navigateBack(); }, //跳转人工客服 gotoService() { wx.navigateTo({ url: "/pages/mine/subpages/contactus/contactus", }); }, // 使用 marked markdownToHtml(markdown: string) { return marked(markdown) .replaceAll( "", '
' ) .replaceAll( "
", '' ) .replaceAll( "", '' ); }, //重置操作,接口响应成功后重置数据 resetFn() { const lastIsLoading = "chatList[" + (this.data.chatList.length - 1) + "].isLoading"; this.setData({ [lastIsLoading]: false, contentItems: "", isLoading: false, loadingStatus: false, }); }, requestFn() { var that = this; //先判断inputStr有没有值,isRegenerate表示是否重新生成 const inputStr = that.data.isRegenerate ? that.data.preInputValue : that.data.inputValue; if (!inputStr) return wx.showToast({ title: "请输入要查询的问题。", icon: "none", }); if (that.data.isLoading) return wx.showToast({ title: "正在生成内容,请稍后。", icon: "none", }); that.setData({ isLoading: true }); if (!that.data.isRegenerate) { let curChatList = that.data.chatList; //第一次生成 that.setData({ chatList: curChatList.concat([ { type: "user", message: [inputStr], answerIndex: 0, isLoading: false, downMessage: [inputStr], }, ]), }); that.setData({ scrollTop: 999999, // 设置一个足够大的值,确保滚动到底部 titleStr: that.data.chatList[0].message[0], }); } that.setData({ loadingStatus: true }); const requestTask = wx.request({ url: `https://xxxx?message=${inputStr}`, responseType: "arraybuffer", method: "GET", enableChunked: true, //接口响应结束后执行 success: () => { that.resetFn(); }, //响应失败后执行 fail: () => { that.resetFn(); }, //接口响应结束后执行,晚于success阶段 complete: () => { that.resetFn(); }, }); //接口响应成功,但此时无内容响应,相当于fetchEventSource的open阶段 requestTask.onHeadersReceived(function (res: any) { if (res.statusCode !== 200) return wx.showToast({ title: "服务器忙,请稍后再试。", icon: "none", }); //判断是否重新生成,如果重新生成向最后chatList最后一项中的message中追加,如果不是重新生成向chatList中追加一条 if (that.data.isRegenerate) { const lastIndex = that.data.chatList.length - 1; const lastMessage = "chatList[" + lastIndex + "].message"; const lastDownMessage = "chatList[" + lastIndex + "].downMessage"; const lastAnswerIndex = "chatList[" + lastIndex + "].answerIndex"; that.setData({ [lastMessage]: that.data.chatList[lastIndex].message.concat([""]), [lastDownMessage]: that.data.chatList[lastIndex].downMessage.concat([ "", ]), [lastAnswerIndex]: that.data.chatList[lastIndex].answerIndex + 1, }); } else { let curChatList = that.data.chatList.concat([ { type: "ai", message: [], answerIndex: 0, isLoading: true, downMessage: [], reportUrl: "", }, ]); that.setData({ chatList: curChatList, preInputValue: that.data.inputValue, }); } const lastIsLoading = "chatList[" + (that.data.chatList.length - 1) + "].isLoading"; that.setData({ inputValue: "", isLoading: true, // loadingStatus: false, [lastIsLoading]: true, }); }); //持续内容响应,相当于fetchEventSource的onmessage阶段 requestTask.onChunkReceived(function (r) { that.setData({ loadingStatus: false, }); // onChunkReceived 有可能同时接收两条信息,所以需将响应数据转化为数组 let arr = arrayBufferToString(r.data); arr.forEach((item) => { if (item) { const content = item.content; that.setData( { contentItems: that.data.contentItems + content, }, () => { if (that.data.isBottom) { that.setData({ scrollTop: 999999, // 设置一个足够大的值,确保滚动到底部 }); } if (that.data.contentItems) { if (that.data.contentItems.includes("")) { const list = that.data.contentItems.split(""); const thinkStr = `

师爷模型深度思考中...

${list[0].replace( "", "" )}
`; that.setData({ currentHTML: thinkStr + that.markdownToHtml(list[1]), }); } else { const thinkStr = `

师爷模型深度思考中...

${that.data.contentItems.replace( "", "" )}
`; that.setData({ currentHTML: thinkStr, }); } } else { that.setData({ currentHTML: "", }); } } ); if (item.status === "end") { const lastIndex = that.data.chatList.length - 1; const lastItem = that.data.chatList[lastIndex]; if (that.data.isRegenerate) { //重新生成 const messageLast = "chatList[" + lastIndex + "].message[" + (lastItem.message.length - 1 + "]"); const downMessageLast = "chatList[" + lastIndex + "].downMessage[" + (lastItem.message.length - 1 + "]"); const answerIndex = "chatList[" + lastIndex + "].answerIndex"; that.setData({ [messageLast]: that.data.currentHTML, [downMessageLast]: that.data.contentItems, [answerIndex]: lastItem.message.length - 1, }); } else { //第一次生成 const curLastIndex = that.data.chatList.length - 1; const lastMessage = "chatList[" + curLastIndex + "].message"; const lastDownMessage = "chatList[" + curLastIndex + "].downMessage"; const lastIsLoading = "chatList[" + curLastIndex + "].isLoading"; that.setData({ [lastMessage]: [that.data.currentHTML], [lastDownMessage]: [that.data.contentItems], [lastIsLoading]: false, }); } // if (item.reportUrl) { // const lastReportUrl = "chatList[" + lastIndex + "].reportUrl"; // that.setData({ // [lastReportUrl]: item.reportUrl, // }); // } that.resetFn(); } } }); }); that.setData({ requestTask: requestTask, }); }, //发送问题 sendFn() { this.setData({ isRegenerate: false, }); this.requestFn(); }, /** * 生命周期函数--监听页面加载 */ onLoad(options: any) { if (options && options.question) { this.setData({ inputValue: options.question, }); this.requestFn(); } }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady() {}, /** * 生命周期函数--监听页面显示 */ onShow() {}, /** * 生命周期函数--监听页面隐藏 */ onHide() {}, /** * 生命周期函数--监听页面卸载 */ onUnload() {}, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh() {}, /** * 页面上拉触底事件的处理函数 */ onReachBottom() {}, /** * 用户点击右上角分享 */ onShareAppMessage() {}, });

report.scss:

/* pages/shiye/subpages/report/report.wxss */
.page-container {
  background-color: #fff;
  position: relative;
  .left-btn {
    width: 178rpx;
    height: 60rpx;
    border-radius: 60rpx;
    border: 2rpx solid #e3e6eb;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;

    .back {
      margin-right: 24rpx;
    }

    .btn {
      width: 40rpx;
      height: 40rpx;
    }
  }
  .navigation-center {
    width: calc(100vw - 400rpx);
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-size: 34rpx;
    font-weight: 400;
  }

  .report-container {
    padding: 10rpx 0rpx;
    width: 100%;
    height: calc(100vh - 462rpx);
    box-sizing: border-box;
    box-sizing: border-box;
    .chat-list-container {
      margin: 0 30rpx;
      .chat-item {
        display: flex;

        .question {
          display: flex;
          margin-bottom: 40rpx;

          .message {
            padding: 20rpx 24rpx 16rpx 24rpx;
            border-radius: 32rpx 32rpx 0 32rpx;
            background-color: #4d80f0;
            font-size: 28rpx;
            color: #fff;
            font-weight: 400;
            line-height: 44rpx;
          }
        }

        .answer-container {
          margin-bottom: 90rpx;
          .answer {
            .answer-message {
              padding: 40rpx 20rpx;
              border-radius: 28rpx 28rpx 28rpx 0;
              min-width: 300rpx;
              background-color: #f6f6f6;
              .download-btn {
                color: #333;
                text-align: center;
                font-family: "PingFang SC";
                font-size: 28rpx;
                font-style: normal;
                font-weight: 400;
                line-height: 68rpx;
                height: 68rpx;
                margin-top: 40rpx;
                border-radius: 12rpx;
                border-color: transparent;
                .icon-img {
                  width: 34rpx;
                  height: 34rpx;
                  margin-right: 10rpx;
                }
                &:hover {
                  background: linear-gradient(
                    128deg,
                    #4672ff -1.27%,
                    #7daafc 109.62%
                  );
                  color: #fff;
                }
              }
            }
          }
          .btn-container {
            margin-top: 20rpx;
            display: flex;
            justify-content: flex-end;
            align-items: center;
            width: 100%;
            .page-container {
              color: #000;
              font-family: "PingFang SC";
              font-size: 28rpx;
              font-style: normal;
              font-weight: 400;
              margin-right: 20rpx;
              height: 80rpx;
              width: 150rpx;
              display: flex;
              flex-direction: row;
              justify-content: space-around;
              align-items: center;
              .pre-page {
                margin-right: 2rpx;
                cursor: pointer;
              }
              .next-page {
                margin-left: 2rpx;
                cursor: pointer;
              }
            }
            .tool-container {
              background-color: #f6f6f6;
              padding: 0 30rpx;
              height: 80rpx;
              border-radius: 40rpx;
              // min-width: 60rpx;
              text-align: center;
              display: flex;
              flex-direction: row;
              position: relative;
              .line {
                border-left: 2rpx solid #ddd;
                height: 38rpx;
                position: absolute;
                left: 98rpx;
                top: 23rpx;
              }
              .tool-img {
                width: 48rpx;
                height: 48rpx;
                margin-top: 16rpx;
                cursor: pointer;
              }
              .copy-acive {
                color: #5577ff;
              }
              .refresh {
                margin-right: 40rpx;
              }
            }
          }
        }
      }

      .user {
        flex-direction: row-reverse;
      }
    }

    .thinking {
      margin: 0 30rpx;
      max-width: 140rpx;
      background-color: #f6f6f6;
      color: #666;
      padding: 20rpx;
      font-family: "PingFang SC";
      font-size: 28rpx;
      font-style: normal;
      font-weight: 400;
      line-height: 48rpx;
      border-radius: 28rpx 28rpx 28rpx 0;
    }
    &::-webkit-scrollbar {
      display: none;
    }
  }

  .input-box {
    padding: 10rpx 30rpx 16rpx;
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    box-sizing: border-box;
    .stop-container {
      position: absolute;
      top: -20rpx;
      left: 30rpx;
      height: 47px;
      width: calc(100% - 60rpx);
      margin-bottom: 10px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      z-index: 100;
      .stop {
        width: 104px;
        height: 36px;
        border-radius: 18px;
        background-color: #f6f6f6;
        color: #5863ff;
        display: flex;
        justify-content: center;
        align-items: center;
        font-family: "PingFang SC";
        font-size: 14px;
        font-style: normal;
        font-weight: 400;
        .stop-img {
          width: 22px;
          height: 22px;
          margin-right: 5px;
        }
      }
      .preNext-btn {
        display: flex;
        .scroll {
          width: 32px;
          height: 32px;
          border-radius: 45px;
          background: #fff;
          margin-left: 10px;
          box-shadow: 0px 0px 8.857px 0px rgba(51, 117, 245, 0.25);
          .scroll-img {
            width: 16px;
            height: 16px;
            margin: 8px;
          }
        }
      }
    }
    .tip {
      margin: 24rpx 0 50rpx;
      color: #999;
      font-family: "PingFang SC";
      font-size: 20rpx;
      font-style: normal;
      font-weight: 400;
      line-height: 20rpx;
      text-align: center;

      .service {
        color: #3375f5;
      }
    }
  }
}

你可能感兴趣的:(微信小程序,小程序,chatgpt,文心一言)