ChatGPT微信小程序

ChatGPT微信小程序_第1张图片

ChatGPT是人工智能研究实验室OpenAI在2022年11月30日发布的全新聊天机器人模型。

准备工作

1.ChatGPT账户:上某宝5软妹币一个,账户有18刀的余额(接口请求要收费的,所以后面放弃了)。
2.梯子:没有梯子访问官网会被提示 OpenAI's services are not available in your country.
3.apiKey:通过梯子账户登上ChatGPT官网, 再前往apiKeys管理页面进行申请。

后端

因为采用的是简单的接口访问ChatGPT接口,再返回给小程序,所以只需要一个简单的node应用。

代码与注释

const express = require('express')
const axios = require('axios')
const app = express()

app.use(express.urlencoded({ extended: false }))

// ChatGPT官网申请的apiKey,我的第二天就失效了,要重新申请
const apiKey = 'sk-HySXDJmHfsadkkaslkdjaslkdjasldkjasdkljasd'

// 定义前端请求接口路径
app.post('/message', async (req, res) => {
    const { message, type} = req.body
    // 模型
    const model = type === 'code' ? 'code-davinci-002' : 'text-davinci-003'
    const data = {  
      model,
      prompt: message,  // 发送的消息
      max_tokens: 2000,  
      temperature: 0.5  //  可以简单理解为精准度, 0最精准~1最灵动
    }  

    try {
      // 通过axios请求
      const result = await axios.post('https://api.openai.com/v1/completions', data, {  
        timeout: 300000,
        headers: { Authorization: `Bearer ${apiKey}` }
      })
      //  判断是否有回答
      if(result.data.choices && result.data.choices[0].text){
        res.status(200).send(result.data.choices[0].text)
      }else{
      // 没有回答内容
        res.status(200).send('下次一定会~')
      }
    } catch (error) {
      // token过期或其他报错
      console.error(error)
      res.status(400).send('出错了哦~')
    }
})

var server = app.listen(8002, () => {
  var host = server.address().address;
  var port = server.address().port;
  console.log('Example app listening at http://%s:%s', host, port);
})

小程序端

vue3与uniapp开发

页面代码

<template>
  <view class="page-container">
    <u-navbar :is-fixed="false" :back-text-style="{color: '#56B6C2'}" :title-width="320" :back-icon-size="0" back-text="About" :title-bold="true" :custom-back="goAbout" class="navbar" :title="navTitle">u-navbar>
    <view class="box">
      <scroll-view class="chat-box" scroll-y :style="{height: `${winHeight - navbarHeight}px`}" :scrollIntoView="scrollIntoView" :scroll-with-animation="true" :show-scrollbar="false" :enhanced="true">
        <view v-for="(item, index) in chatHistory" :key="index">
          <view class="pop" :class="{'is-Q': item.type === 'Q'}">
            <view class="info">
              <text>{{item.type === 'A' ? 'A :' : ': Q'}}text>
            view>
            <view class="content">
              <uParse :content="item.value">uParse>
            view>
          view>
        view>
        <view style="height: 220rpx" id="btm">view>
      scroll-view>
      <view class="input-wrap" :class="{'is-hidekeyboard': keyboardHeight === 0}"
      :style="{bottom: `${keyboardHeight}px`}"
      >
        <textarea
          v-model="text"
          class="input"
          type="text"
          :fixed="true"
          :show-confirm-bar="false"
          :disable-default-padding="true"
          :autoHeight="true"
          :adjust-position="false"
          @keyboardheightchange="keyboardheightchange"
          @confirm="sendData"
        />
        <view class="btn" @click="sendData">发送view>
      view>
    view>

    <view class="about">
     About
    view>
  view>
template>

<script setup lang="ts">
import { ref, getCurrentInstance, nextTick, watch } from "vue";
import { onReady } from "@dcloudio/uni-app";
import uParse from "@/components/u-parse/u-parse.vue";
import * as marked from "marked";
type chatItem = {
  type: "A" | "Q";
  value: string;
};

const _this = getCurrentInstance();
const loading = ref(false);
const text = ref("");
const scrollIntoView = ref("")
const winHeight = uni.getSystemInfoSync().windowHeight
const keyboardHeight = ref(0)
const navbarHeight = ref(uni.upx2px(100))
const navTitle = ref('ChatGPT Openai')

const chatHistory = ref<chatItem[]>([
]);

onReady(() => {
  uni.createSelectorQuery().in(_this).select('.navbar').boundingClientRect(rect => {
    rect = rect as UniApp.NodeInfo
    navbarHeight.value = rect.height!
  }).exec()
})

const sendData = () => {
  if (loading.value || text.value === "") return;
  loading.value = true;
  scrollIntoView.value = 'btm'

  chatHistory.value.push({
    type: "Q",
    value: text.value,
  });
  nextTick(() => {
    text.value = "";
  })
  setTimeout(() => {
    scrollIntoView.value = ''
  }, 500)
  uni.request({
    url: 'http://localhost:8002/message',
    method: "POST",
    data: {
      message: text.value,
    },
    header: {
      "content-type": "application/x-www-form-urlencoded",
    },
    success: (res) => {
      let v: string
      if(res.data){
        v = marked.marked(res.data as string);
      }else{
        v = '暂时想不出来,下次一定会哈~'
      }
      
      chatHistory.value.push({
        type: "A",
        value: v,
      });
      nextTick(() => {
        scrollIntoView.value = 'btm'
        setTimeout(() => {
          scrollIntoView.value = ''
        }, 500)
      })
    },
    complete: () => {
      loading.value = false;
    },
  });
};

const keyboardheightchange = (e: any) => {
  keyboardHeight.value = e.detail.height
}

const goAbout = () => {
  uni.navigateTo({
    url: '/pages/about/index'
  })
}


watch(() => loading.value, (v) => {
  if(v){
    navTitle.value = '正在输入聊天内容...'
  }else{
    navTitle.value = 'ChatGPT Openai'
  }
})
script>

<style lang="scss">
.page-container {
  font-size: 26rpx;
  line-height: 52rpx;
  view,
  input,
  text,
  scroll-view,
  textarea {
    box-sizing: border-box;
    font-size: 32rpx;
  }
  .box {
    background-color: #f5f6fb;
  }
  .chat-box {
    height: 100vh;
    padding: 50rpx 30rpx 0rpx;
  }
  .pop {
    margin-bottom: 50rpx;
    &.is-Q{
      text-align: right;
      .info{
        flex-direction: row-reverse;
        .avatar{
          margin-left: 20rpx;
        }
      }
      
    }
  }
  .info{
    display: flex;
    margin-bottom: 20rpx;
    color: #666;
  }
  .avatar {
    height: 80rpx;
    width: 80rpx;
    margin-right: 20rpx;
    border-radius: 50%;
  }
  .content{
    display: inline-block;
    width: auto;
    max-width: calc(100%);
    word-wrap: break-word;
    word-break: break-all;
    background-color: #fff;
    border-radius: 18rpx;
    padding: 20rpx;
    text-align: left;
  }
}
.code {
  display: block;
  overflow-x: auto;
  padding: 30rpx;
}

.code {
  color: #abb2bf;
  background: #282c34;
}
.input {
  min-height: 70rpx;
  width: 100%;
  margin-right: 20rpx;
  padding: 15rpx 20rpx;
  background-color: #f7f7f7;
}
.input-wrap {
  position: fixed;
  bottom: 0;
  left: 0;
  background-color: #fff;
  padding: 10rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-radius: 10rpx;
  width: 100%;
  &.is-hidekeyboard{
    padding-bottom: var(--safe-area-inset-bottom);
  }
}
.btn {
  height: 70rpx;
  line-height: 70rpx;
  background-color: #56b6c2;
  padding: 0 30rpx;
  border-radius: 6rpx;
  color: #fff;
  font-weight: 500;
  white-space: nowrap;
  &:active {
    opacity: 0.7;
  }
  &::after {
    background-color: none;
  }
}
.text {
  font-size: 30rpx;
}

.about{
  position: fixed;
  left: 30rpx;
  top: 0rpx;
  font-size: 28rpx;
  // font-weight: bold;
  width: 120rpx;
  border-radius: 8rpx;
  background-color: #56b6c2;
  text-align: center;
  line-height: 66rpx;
  color: #fff;
}
style>

运行效果

ChatGPT微信小程序_第2张图片

Tips: 开发测试共两天,18美金就用(好)完(贵)了。有趣的东西也尝尝鲜~

你可能感兴趣的:(uniapp,chatgpt,微信小程序,微信小程序,chatgpt,小程序)