| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- interface Message {
- id: string;
- type: 'ai' | 'user' | 'reply';
- contentType: 'text' | 'image' | 'faq';
- content: string;
- questions?: string[];
- timestamp: number;
- }
- interface FAQItem {
- question: string;
- answer: string;
- }
- import { api_cozeAgent } from '../../api/login';
- const FAQ_LIST: FAQItem[] = [
- { question: '产品价格是多少?', answer: '我们的产品价格根据不同的套餐有所不同。基础版¥99/月,专业版¥199/月,企业版¥499/月。您可以根据自己的需求选择合适的套餐。' },
- { question: '如何购买课程?', answer: '您可以通过以下步骤购买课程:1. 在首页浏览课程列表;2. 点击心仪的课程进入详情页;3. 点击"立即购买"按钮;4. 选择支付方式完成支付。' },
- { question: '支持哪些设备?', answer: '我们的产品支持多种设备:iOS设备(iPhone、iPad)、Android设备(手机、平板)、Windows电脑、Mac电脑,以及主流的智能电视。' },
- { question: '有没有试用版本?', answer: '有的!我们为所有新用户提供7天免费试用期。试用期间您可以体验全部专业版功能,无需绑定支付方式。试用期结束后,您可以选择是否订阅。' },
- { question: '售后服务政策', answer: '我们提供完善的售后服务:1. 7天无理由退款;2. 产品问题30天内免费换新;3. 终身技术支持;4. 专属客服一对一服务。如有任何问题,请随时联系我们。' },
- { question: '开具发票', answer: '我们可以为您开具增值税普通发票或专用发票。请在购买后30天内,在"我的订单"页面点击"申请开票",填写相关信息后,我们会在5个工作日内将发票发送至您的邮箱。' },
- ];
- Page({
- data: {
- messages: [] as Message[],
- inputValue: '',
- scrollToMessage: '',
- userAvatar: '',
- isLoading: false,
- avatarError: false,
- keyboardHeight: 0,
- },
- onLoad() {
- this.loadUserInfo();
- this.initWelcomeMessages();
- },
- // 加载用户信息
- loadUserInfo() {
- const userInfo = wx.getStorageSync('userInfo');
- if (userInfo) {
- this.setData({
- userAvatar: userInfo.avatarUrl || ''
- });
- }
- },
- // 初始化欢迎消息
- initWelcomeMessages() {
- const messages: Message[] = [];
- // 第一条欢迎消息
- messages.push({
- id: this.generateId(),
- type: 'ai',
- contentType: 'text',
- content: '您好!欢迎来到音乐数字AI客服中心。我是您的专属客服小助手,很高兴为您服务!请问有什么可以帮助您的吗?',
- timestamp: Date.now()
- });
- // 第二条常见问题卡片
- messages.push({
- id: this.generateId(),
- type: 'ai',
- contentType: 'faq',
- content: '常见问题',
- questions: FAQ_LIST.map(item => item.question),
- timestamp: Date.now() + 1
- });
- this.setData({ messages }, () => {
- this.scrollToBottom();
- });
- },
- // 生成唯一ID
- generateId(): string {
- return Date.now().toString(36) + Math.random().toString(36).substr(2);
- },
- // 滚动到底部
- scrollToBottom() {
- this.setData({
- scrollToMessage: 'last-message'
- });
- },
- // 头像加载失败
- onAvatarError() {
- this.setData({ avatarError: true });
- },
- // 输入框变化
- onInput(e: WechatMiniprogram.Input) {
- this.setData({
- inputValue: e.detail.value
- });
- },
- onKeyboardHeightChange(e: WechatMiniprogram.InputKeyboardHeightChange) {
- const keyboardHeight = e.detail.height || 0;
- if (keyboardHeight === this.data.keyboardHeight) return;
- this.setData({ keyboardHeight }, () => {
- this.scrollToBottom();
- });
- },
- // 发送文字消息
- sendTextMessage() {
- const { inputValue, isLoading } = this.data;
- if (!inputValue.trim() || isLoading) return;
- const content = inputValue.trim();
- // 添加用户消息
- this.addUserMessage('text', content);
- // 清空输入框
- this.setData({ inputValue: '' });
- // 发送到服务器
- this.sendMessageToServer(content, 'text');
- },
- // 添加用户消息
- addUserMessage(contentType: 'text' | 'image', content: string) {
- const { messages } = this.data;
- const newMessage: Message = {
- id: this.generateId(),
- type: 'user',
- contentType,
- content,
- timestamp: Date.now()
- };
- this.setData({
- messages: [...messages, newMessage]
- }, () => {
- this.scrollToBottom();
- });
- },
- // 选择图片
- chooseImage() {
- wx.chooseMedia({
- count: 1,
- mediaType: ['image'],
- sourceType: ['album', 'camera'],
- success: (res) => {
- const tempFilePath = res.tempFiles[0].tempFilePath;
- this.uploadImage(tempFilePath);
- },
- fail: (err) => {
- console.error('选择图片失败:', err);
- wx.showToast({
- title: '选择图片失败',
- icon: 'none'
- });
- }
- });
- },
- // 上传图片
- uploadImage(filePath: string) {
- // 先显示本地图片
- this.addUserMessage('image', filePath);
- // 获取全局配置
- const app = getApp<IAppOption>();
- const baseUrl = app.globalData?.baseUrl || 'https://test.kt.colexiu.com';
- // 上传图片到服务器
- wx.uploadFile({
- url: `${baseUrl}/edu-app/ai/chat/upload`,
- filePath: filePath,
- name: 'file',
- header: {
- 'Authorization': wx.getStorageSync('token') || ''
- },
- success: (res) => {
- try {
- const data = JSON.parse(res.data);
- if (data.code === 200) {
- // 上传成功,发送图片URL到聊天
- this.sendMessageToServer(data.data.url, 'image');
- } else {
- throw new Error(data.msg || '上传失败');
- }
- } catch (err) {
- console.error('解析上传响应失败:', err);
- this.addReplyMessage('图片上传失败,请重试');
- }
- },
- fail: (err) => {
- console.error('上传图片失败:', err);
- // 模拟成功,直接回复
- setTimeout(() => {
- this.addReplyMessage('我已收到您的图片,请问有什么可以帮助您的吗?');
- }, 1000);
- }
- });
- },
- // 发送消息到服务器
- async sendMessageToServer(content: string, contentType: 'text' | 'image') {
- this.setData({ isLoading: true });
- // 获取用户ID(优先使用openid,其次使用token中的用户ID)
- const userInfo = wx.getStorageSync('userInfo') || {};
- const userId = userInfo.openId || userInfo.userId || wx.getStorageSync('openId');
- // 构建消息内容(图片发送固定提示语)
- const messageContent = contentType === 'image' ? '我发送了一张图片' : content;
- try {
- // 调用客服消息接口
- const {data}: any = await api_cozeAgent({
- message: messageContent,
- userId: userId
- });
- if (data.code === 200 && data.data) {
- // 使用接口返回的回复内容
- const reply =data.data || '您好,我已经收到您的问题。';
- this.addReplyMessage(reply);
- } else {
- // 接口返回错误,使用默认回复
- this.handleDefaultReply(contentType);
- }
- } catch (err) {
- console.error('客服接口调用失败:', err);
- // 接口调用失败,使用默认回复
- this.handleDefaultReply(contentType);
- } finally {
- this.setData({ isLoading: false });
- }
- },
- // 处理默认回复(当接口调用失败时使用)
- handleDefaultReply(contentType: 'text' | 'image') {
- let reply = '';
- if (contentType === 'image') {
- reply = '我已收到您的图片,请问有什么可以帮助您的吗?';
- } else {
- reply = '您好,我已经收到您的问题。我们的客服人员会尽快为您解答。如果您有其他问题,也可以继续提问。';
- }
- this.addReplyMessage(reply);
- },
- // 添加AI回复消息
- addReplyMessage(content: string) {
- const { messages } = this.data;
- const replyMessage: Message = {
- id: this.generateId(),
- type: 'reply',
- contentType: 'text',
- content,
- timestamp: Date.now()
- };
- this.setData({
- messages: [...messages, replyMessage]
- }, () => {
- this.scrollToBottom();
- });
- },
- // 点击常见问题
- onFaqTap(e: WechatMiniprogram.Tap) {
- const index = e.currentTarget.dataset.index;
- const faq = FAQ_LIST[index];
- if (faq) {
- // 添加用户选择的问题
- this.addUserMessage('text', faq.question);
- // 直接回复固定内容
- setTimeout(() => {
- this.addReplyMessage(faq.answer);
- }, 500);
- }
- },
- // 点击图片预览
- onImageTap(e: any) {
- const url = e.currentTarget.dataset.url;
- if (url) {
- wx.previewImage({
- urls: [url],
- current: url
- });
- }
- }
- });
|