index.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. "use strict";
  2. const common_vendor = require("../../common/vendor.js");
  3. const common_assets = require("../../common/assets.js");
  4. const _sfc_main = {
  5. data() {
  6. return {
  7. inputMessage: "",
  8. chatMessages: [
  9. {
  10. sender: "ai",
  11. content: "您好!我是农小禹,您的智能农业助手🌱 我可以帮您解答农业种植、病虫害防治、农产品管理等方面的问题。有什么可以帮助您的吗?",
  12. time: this.getFormattedTime(new Date(Date.now() - 36e5)),
  13. // 1小时前
  14. timestamp: Date.now() - 36e5,
  15. isWelcome: true
  16. },
  17. {
  18. sender: "user",
  19. content: "南方现在适合种什么蔬菜?",
  20. time: this.getFormattedTime(new Date(Date.now() - 6e4)),
  21. // 1分钟前
  22. timestamp: Date.now() - 6e4
  23. },
  24. {
  25. sender: "ai",
  26. content: "您可以考虑种植以下蔬菜:\n\n1. 空心菜:耐热耐湿,生长快速\n2. 丝瓜:适应性强,产量高\n3. 茄子:耐热性好,病虫害较少\n4. 辣椒:喜温喜光,南方气候适宜\n5. 秋葵:抗病性强,营养价值高\n\n记得注意排水和通风,南方雨水多,做好防涝措施。建议早晚浇水,避开中午高温时段。",
  27. time: this.getFormattedTime(/* @__PURE__ */ new Date()),
  28. timestamp: Date.now()
  29. }
  30. ],
  31. scrollTop: 0,
  32. inputHeight: 120,
  33. // 单位px
  34. scrollTimer: null,
  35. isProcessing: false,
  36. // 是否正在处理请求
  37. suggestedQuestions: [
  38. "水稻插秧后如何管理?",
  39. "果树夏季修剪技巧?",
  40. "如何防治蔬菜常见病虫害?",
  41. "农药使用注意事项?",
  42. "有机肥和化肥怎么搭配使用?"
  43. ],
  44. statusBarHeight: 20,
  45. // 默认值,会在mounted中获取真实值
  46. safeAreaBottom: 34,
  47. // 默认值,会在mounted中获取真实值
  48. isIOS: false,
  49. // 是否是iOS设备
  50. lastMessageDate: ""
  51. // 上一条消息的日期,用于判断是否显示日期分割线
  52. };
  53. },
  54. // 设置页面标题
  55. onNavigationBarButtonTap(e) {
  56. common_vendor.index.__f__("log", "at pages/ai-chat/index.vue:150", "导航栏按钮点击:", e);
  57. },
  58. mounted() {
  59. const systemInfo = common_vendor.index.getSystemInfoSync();
  60. this.statusBarHeight = systemInfo.statusBarHeight || 20;
  61. this.isIOS = systemInfo.platform === "ios";
  62. this.safeAreaBottom = systemInfo.safeAreaInsets ? systemInfo.safeAreaInsets.bottom || 0 : 0;
  63. this.initMessages();
  64. this.$nextTick(() => {
  65. this.scrollToBottom();
  66. });
  67. },
  68. methods: {
  69. onInputFocus() {
  70. this.$nextTick(() => {
  71. this.scrollToBottom();
  72. });
  73. },
  74. scrollToBottom() {
  75. this.$nextTick(() => {
  76. const query = common_vendor.index.createSelectorQuery().in(this);
  77. query.select(".chat-list").boundingClientRect((data) => {
  78. if (data) {
  79. this.scrollTop = data.height + 1e3;
  80. if (this.isH5) {
  81. setTimeout(() => {
  82. const scrollEl = document.querySelector(".chat-container");
  83. if (scrollEl) {
  84. scrollEl.scrollTop = scrollEl.scrollHeight;
  85. }
  86. }, 100);
  87. }
  88. }
  89. }).exec();
  90. });
  91. },
  92. onScroll(e) {
  93. },
  94. getCurrentTime() {
  95. return this.getFormattedTime(/* @__PURE__ */ new Date());
  96. },
  97. getFormattedTime(date) {
  98. const hours = date.getHours().toString().padStart(2, "0");
  99. const minutes = date.getMinutes().toString().padStart(2, "0");
  100. return `${hours}:${minutes}`;
  101. },
  102. submitQuestion() {
  103. if (!this.inputMessage.trim() || this.isProcessing)
  104. return;
  105. this.isProcessing = true;
  106. this.chatMessages.push({
  107. sender: "user",
  108. content: this.inputMessage,
  109. time: this.getCurrentTime()
  110. });
  111. const userQuestion = this.inputMessage;
  112. this.inputMessage = "";
  113. this.scrollToBottom();
  114. this.chatMessages.push({
  115. sender: "ai",
  116. content: "正在思考...",
  117. time: this.getCurrentTime(),
  118. isTyping: true
  119. });
  120. setTimeout(() => {
  121. this.chatMessages.pop();
  122. let aiResponse = "感谢您的提问!作为您的农技助理,我很高兴能帮助您解决农业相关问题。您询问的内容我已收到,我们团队正在研究适合的解决方案。";
  123. if (userQuestion.includes("水稻")) {
  124. aiResponse = "水稻种植需要注意水肥管理和病虫害防治。目前南方地区水稻插秧时间已到,建议您选择抗病性强的品种,如'中优84'。插秧后7天开始浅水促根,分蘖期保持3-5cm水层。";
  125. } else if (userQuestion.includes("蔬菜")) {
  126. aiResponse = "夏季蔬菜种植需注意遮阳和水分管理。建议种植耐热品种如空心菜、苋菜、茄子等。可以采用遮阳网减少强光照射,早晚浇水避开高温时段。";
  127. } else if (userQuestion.includes("果树")) {
  128. aiResponse = "果树现在应注意夏季修剪和病虫害防治。柑橘类果树可以进行夏季修剪,去除徒长枝和内膛枝。同时注意柑橘黄龙病和炭疽病的预防,建议定期喷施药剂保护。";
  129. }
  130. this.chatMessages.push({
  131. sender: "ai",
  132. content: aiResponse,
  133. time: this.getCurrentTime()
  134. });
  135. this.scrollToBottom();
  136. this.isProcessing = false;
  137. }, 2e3);
  138. },
  139. useQuestion(question) {
  140. this.inputMessage = question;
  141. },
  142. containsKeywords(text) {
  143. const keywords = ["水稻", "小麦", "玉米", "病虫害", "农药", "化肥", "有机肥", "种植技术"];
  144. return keywords.some((keyword) => text.includes(keyword));
  145. },
  146. formatMessage(text) {
  147. return text.replace(/\n/g, "<br>");
  148. },
  149. initMessages() {
  150. this.chatMessages.forEach((msg) => {
  151. if (!msg.timestamp) {
  152. msg.timestamp = (/* @__PURE__ */ new Date()).getTime();
  153. }
  154. });
  155. this.chatMessages.sort((a, b) => a.timestamp - b.timestamp);
  156. },
  157. showDateSeparator(index) {
  158. if (index === 0)
  159. return true;
  160. const currentMsg = this.chatMessages[index];
  161. const prevMsg = this.chatMessages[index - 1];
  162. return this.isDifferentDay(currentMsg.timestamp, prevMsg.timestamp) || currentMsg.timestamp - prevMsg.timestamp > 30 * 60 * 1e3;
  163. },
  164. isDifferentDay(timestamp1, timestamp2) {
  165. const date1 = new Date(timestamp1);
  166. const date2 = new Date(timestamp2);
  167. return date1.getDate() !== date2.getDate() || date1.getMonth() !== date2.getMonth() || date1.getFullYear() !== date2.getFullYear();
  168. },
  169. formatDateSeparator(timestamp) {
  170. const now = /* @__PURE__ */ new Date();
  171. const msgDate = new Date(timestamp);
  172. if (this.isSameDay(msgDate, now)) {
  173. return "今天 " + this.getFormattedTime(msgDate);
  174. }
  175. const yesterday = new Date(now);
  176. yesterday.setDate(now.getDate() - 1);
  177. if (this.isSameDay(msgDate, yesterday)) {
  178. return "昨天 " + this.getFormattedTime(msgDate);
  179. }
  180. const oneWeekAgo = new Date(now);
  181. oneWeekAgo.setDate(now.getDate() - 7);
  182. if (msgDate >= oneWeekAgo) {
  183. const weekdays = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
  184. return weekdays[msgDate.getDay()] + " " + this.getFormattedTime(msgDate);
  185. }
  186. return msgDate.getFullYear() + "年" + (msgDate.getMonth() + 1) + "月" + msgDate.getDate() + "日 " + this.getFormattedTime(msgDate);
  187. },
  188. isSameDay(date1, date2) {
  189. return date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear();
  190. }
  191. }
  192. };
  193. function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  194. return common_vendor.e({
  195. a: common_vendor.f($data.chatMessages, (message, index, i0) => {
  196. return common_vendor.e({
  197. a: message.sender === "ai"
  198. }, message.sender === "ai" ? common_vendor.e({
  199. b: common_assets._imports_0,
  200. c: message.isTyping
  201. }, message.isTyping ? {} : {
  202. d: common_vendor.t(message.content),
  203. e: $options.containsKeywords(message.content) ? 1 : ""
  204. }, {
  205. f: message.isTyping ? 1 : "",
  206. g: message.isWelcome || index === 0 ? 1 : "",
  207. h: common_vendor.t(message.time)
  208. }) : {
  209. i: common_vendor.t(message.time),
  210. j: common_vendor.t(message.content),
  211. k: common_assets._imports_1
  212. }, {
  213. l: index,
  214. m: message.sender === "ai" ? 1 : "",
  215. n: message.sender === "user" ? 1 : ""
  216. });
  217. }),
  218. b: $data.scrollTop,
  219. c: common_vendor.o((...args) => $options.onScroll && $options.onScroll(...args)),
  220. d: `calc(100vh - ${$data.inputHeight}px)`,
  221. e: $data.chatMessages.length <= 3 && !$data.inputMessage
  222. }, $data.chatMessages.length <= 3 && !$data.inputMessage ? {
  223. f: common_vendor.f($data.suggestedQuestions, (question, index, i0) => {
  224. return {
  225. a: common_vendor.t(question),
  226. b: index,
  227. c: common_vendor.o(($event) => $options.useQuestion(question), index)
  228. };
  229. })
  230. } : {}, {
  231. g: common_vendor.o((...args) => $options.submitQuestion && $options.submitQuestion(...args)),
  232. h: common_vendor.o((...args) => $options.onInputFocus && $options.onInputFocus(...args)),
  233. i: $data.isProcessing,
  234. j: $data.inputMessage,
  235. k: common_vendor.o(($event) => $data.inputMessage = $event.detail.value),
  236. l: $data.inputMessage.trim() && !$data.isProcessing ? "/static/icons/chat.png" : "/static/icons/chat_off.png",
  237. m: !$data.inputMessage.trim() || $data.isProcessing ? 1 : "",
  238. n: common_vendor.o((...args) => $options.submitQuestion && $options.submitQuestion(...args)),
  239. o: `${$data.isIOS ? $data.safeAreaBottom : 20}rpx`
  240. });
  241. }
  242. const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
  243. wx.createPage(MiniProgramPage);
  244. //# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/ai-chat/index.js.map