chat.ts 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. interface Message {
  2. id: string;
  3. type: 'ai' | 'user' | 'reply';
  4. contentType: 'text' | 'image' | 'faq';
  5. content: string;
  6. questions?: string[];
  7. timestamp: number;
  8. }
  9. interface FAQItem {
  10. question: string;
  11. answer: string;
  12. }
  13. const FAQ_LIST: FAQItem[] = [
  14. { question: '产品价格是多少?', answer: '我们的产品价格根据不同的套餐有所不同。基础版¥99/月,专业版¥199/月,企业版¥499/月。您可以根据自己的需求选择合适的套餐。' },
  15. { question: '如何购买课程?', answer: '您可以通过以下步骤购买课程:1. 在首页浏览课程列表;2. 点击心仪的课程进入详情页;3. 点击"立即购买"按钮;4. 选择支付方式完成支付。' },
  16. { question: '支持哪些设备?', answer: '我们的产品支持多种设备:iOS设备(iPhone、iPad)、Android设备(手机、平板)、Windows电脑、Mac电脑,以及主流的智能电视。' },
  17. { question: '有没有试用版本?', answer: '有的!我们为所有新用户提供7天免费试用期。试用期间您可以体验全部专业版功能,无需绑定支付方式。试用期结束后,您可以选择是否订阅。' },
  18. { question: '售后服务政策', answer: '我们提供完善的售后服务:1. 7天无理由退款;2. 产品问题30天内免费换新;3. 终身技术支持;4. 专属客服一对一服务。如有任何问题,请随时联系我们。' },
  19. { question: '开具发票', answer: '我们可以为您开具增值税普通发票或专用发票。请在购买后30天内,在"我的订单"页面点击"申请开票",填写相关信息后,我们会在5个工作日内将发票发送至您的邮箱。' },
  20. ];
  21. Page({
  22. data: {
  23. messages: [] as Message[],
  24. inputValue: '',
  25. scrollToMessage: '',
  26. userAvatar: '',
  27. isLoading: false,
  28. },
  29. onLoad() {
  30. this.loadUserInfo();
  31. this.initWelcomeMessages();
  32. },
  33. // 加载用户信息
  34. loadUserInfo() {
  35. const userInfo = wx.getStorageSync('userInfo');
  36. if (userInfo) {
  37. this.setData({
  38. userAvatar: userInfo.avatarUrl || ''
  39. });
  40. }
  41. },
  42. // 初始化欢迎消息
  43. initWelcomeMessages() {
  44. const messages: Message[] = [];
  45. // 第一条欢迎消息
  46. messages.push({
  47. id: this.generateId(),
  48. type: 'ai',
  49. contentType: 'text',
  50. content: '您好!欢迎来到音乐数字AI客服中心。我是您的专属客服小助手,很高兴为您服务!请问有什么可以帮助您的吗?',
  51. timestamp: Date.now()
  52. });
  53. // 第二条常见问题卡片
  54. messages.push({
  55. id: this.generateId(),
  56. type: 'ai',
  57. contentType: 'faq',
  58. content: '常见问题',
  59. questions: FAQ_LIST.map(item => item.question),
  60. timestamp: Date.now() + 1
  61. });
  62. this.setData({ messages }, () => {
  63. this.scrollToBottom();
  64. });
  65. },
  66. // 生成唯一ID
  67. generateId(): string {
  68. return Date.now().toString(36) + Math.random().toString(36).substr(2);
  69. },
  70. // 滚动到底部
  71. scrollToBottom() {
  72. this.setData({
  73. scrollToMessage: 'last-message'
  74. });
  75. },
  76. // 输入框变化
  77. onInput(e: WechatMiniprogram.Input) {
  78. this.setData({
  79. inputValue: e.detail.value
  80. });
  81. },
  82. // 发送文字消息
  83. sendTextMessage() {
  84. const { inputValue, isLoading } = this.data;
  85. if (!inputValue.trim() || isLoading) return;
  86. const content = inputValue.trim();
  87. // 添加用户消息
  88. this.addUserMessage('text', content);
  89. // 清空输入框
  90. this.setData({ inputValue: '' });
  91. // 发送到服务器
  92. this.sendMessageToServer(content, 'text');
  93. },
  94. // 添加用户消息
  95. addUserMessage(contentType: 'text' | 'image', content: string) {
  96. const { messages } = this.data;
  97. const newMessage: Message = {
  98. id: this.generateId(),
  99. type: 'user',
  100. contentType,
  101. content,
  102. timestamp: Date.now()
  103. };
  104. this.setData({
  105. messages: [...messages, newMessage]
  106. }, () => {
  107. this.scrollToBottom();
  108. });
  109. },
  110. // 选择图片
  111. chooseImage() {
  112. wx.chooseMedia({
  113. count: 1,
  114. mediaType: ['image'],
  115. sourceType: ['album', 'camera'],
  116. success: (res) => {
  117. const tempFilePath = res.tempFiles[0].tempFilePath;
  118. this.uploadImage(tempFilePath);
  119. },
  120. fail: (err) => {
  121. console.error('选择图片失败:', err);
  122. wx.showToast({
  123. title: '选择图片失败',
  124. icon: 'none'
  125. });
  126. }
  127. });
  128. },
  129. // 上传图片
  130. uploadImage(filePath: string) {
  131. // 先显示本地图片
  132. this.addUserMessage('image', filePath);
  133. // 获取全局配置
  134. const app = getApp<IAppOption>();
  135. const baseUrl = app.globalData?.baseUrl || 'https://test.kt.colexiu.com';
  136. // 上传图片到服务器
  137. wx.uploadFile({
  138. url: `${baseUrl}/edu-app/ai/chat/upload`,
  139. filePath: filePath,
  140. name: 'file',
  141. header: {
  142. 'Authorization': wx.getStorageSync('token') || ''
  143. },
  144. success: (res) => {
  145. try {
  146. const data = JSON.parse(res.data);
  147. if (data.code === 200) {
  148. // 上传成功,发送图片URL到聊天
  149. this.sendMessageToServer(data.data.url, 'image');
  150. } else {
  151. throw new Error(data.msg || '上传失败');
  152. }
  153. } catch (err) {
  154. console.error('解析上传响应失败:', err);
  155. this.addReplyMessage('图片上传失败,请重试');
  156. }
  157. },
  158. fail: (err) => {
  159. console.error('上传图片失败:', err);
  160. // 模拟成功,直接回复
  161. setTimeout(() => {
  162. this.addReplyMessage('我已收到您的图片,请问有什么可以帮助您的吗?');
  163. }, 1000);
  164. }
  165. });
  166. },
  167. // 发送消息到服务器
  168. sendMessageToServer(content: string, contentType: 'text' | 'image') {
  169. this.setData({ isLoading: true });
  170. // 模拟API响应
  171. setTimeout(() => {
  172. let reply = '';
  173. if (contentType === 'image') {
  174. reply = '我已收到您的图片,请问有什么可以帮助您的吗?';
  175. } else {
  176. // 简单的关键词匹配回复
  177. const keyword = content.toLowerCase();
  178. if (keyword.includes('价格') || keyword.includes('多少钱')) {
  179. reply = '我们的产品价格根据不同的套餐有所不同。基础版¥99/月,专业版¥199/月,企业版¥499/月。您可以根据自己的需求选择合适的套餐。';
  180. } else if (keyword.includes('购买') || keyword.includes('怎么买')) {
  181. reply = '您可以通过以下步骤购买课程:1. 在首页浏览课程列表;2. 点击心仪的课程进入详情页;3. 点击"立即购买"按钮;4. 选择支付方式完成支付。';
  182. } else if (keyword.includes('设备') || keyword.includes('支持')) {
  183. reply = '我们的产品支持多种设备:iOS设备(iPhone、iPad)、Android设备(手机、平板)、Windows电脑、Mac电脑,以及主流的智能电视。';
  184. } else if (keyword.includes('试用') || keyword.includes('体验')) {
  185. reply = '有的!我们为所有新用户提供7天免费试用期。试用期间您可以体验全部专业版功能,无需绑定支付方式。试用期结束后,您可以选择是否订阅。';
  186. } else if (keyword.includes('发票')) {
  187. reply = '我们可以为您开具增值税普通发票或专用发票。请在购买后30天内,在"我的订单"页面点击"申请开票",填写相关信息后,我们会在5个工作日内将发票发送至您的邮箱。';
  188. } else if (keyword.includes('售后') || keyword.includes('退款')) {
  189. reply = '我们提供完善的售后服务:1. 7天无理由退款;2. 产品问题30天内免费换新;3. 终身技术支持;4. 专属客服一对一服务。如有任何问题,请随时联系我们。';
  190. } else {
  191. reply = '您好,我已经收到您的问题。我们的客服人员会尽快为您解答。如果您有其他问题,也可以继续提问。';
  192. }
  193. }
  194. this.addReplyMessage(reply);
  195. this.setData({ isLoading: false });
  196. }, 1500);
  197. },
  198. // 添加AI回复消息
  199. addReplyMessage(content: string) {
  200. const { messages } = this.data;
  201. const replyMessage: Message = {
  202. id: this.generateId(),
  203. type: 'reply',
  204. contentType: 'text',
  205. content,
  206. timestamp: Date.now()
  207. };
  208. this.setData({
  209. messages: [...messages, replyMessage]
  210. }, () => {
  211. this.scrollToBottom();
  212. });
  213. },
  214. // 点击常见问题
  215. onFaqTap(e: WechatMiniprogram.Tap) {
  216. const index = e.currentTarget.dataset.index;
  217. const faq = FAQ_LIST[index];
  218. if (faq) {
  219. // 添加用户选择的问题
  220. this.addUserMessage('text', faq.question);
  221. // 直接回复固定内容
  222. setTimeout(() => {
  223. this.addReplyMessage(faq.answer);
  224. }, 500);
  225. }
  226. }
  227. });