From b3a47589d868e893c4f5e9244dc776ab2f4ec34d Mon Sep 17 00:00:00 2001 From: caoyuchun Date: Thu, 23 Oct 2025 10:39:42 +0800 Subject: [PATCH] cyc --- package-lock.json | 67 ++ package.json | 1 + public/index.html | 2 +- src/components/AIChatModuleVue2.zip | Bin 0 -> 17117 bytes src/components/AIChatModuleVue2/AIChat.vue | 790 ++++++++++++++++++ .../AIChatModuleVue2/AIFloatButton.vue | 535 ++++++++++++ src/components/AIChatModuleVue2/README.md | 174 ++++ .../AIChatModuleVue2/aiAssistant.js | 210 +++++ src/main.js | 1 + src/views/Book.vue | 4 +- vue.config.js | 19 +- 11 files changed, 1798 insertions(+), 5 deletions(-) create mode 100644 src/components/AIChatModuleVue2.zip create mode 100644 src/components/AIChatModuleVue2/AIChat.vue create mode 100644 src/components/AIChatModuleVue2/AIFloatButton.vue create mode 100644 src/components/AIChatModuleVue2/README.md create mode 100644 src/components/AIChatModuleVue2/aiAssistant.js diff --git a/package-lock.json b/package-lock.json index 93031f1..ef300c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.1.0", "dependencies": { "axios": "^1.7.2", + "clipboard": "^2.0.11", "core-js": "^3.6.5", "crypto-js": "^4.2.0", "echarts": "^5.6.0", @@ -4739,6 +4740,16 @@ "node": ">= 10" } }, + "node_modules/clipboard": { + "version": "2.0.11", + "resolved": "https://mirrors.cloud.tencent.com/npm/clipboard/-/clipboard-2.0.11.tgz", + "integrity": "sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==", + "dependencies": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, "node_modules/clipboardy": { "version": "2.3.0", "resolved": "https://mirrors.cloud.tencent.com/npm/clipboardy/-/clipboardy-2.3.0.tgz", @@ -6077,6 +6088,11 @@ "node": ">=0.4.0" } }, + "node_modules/delegate": { + "version": "3.2.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==" + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://mirrors.cloud.tencent.com/npm/depd/-/depd-2.0.0.tgz", @@ -7979,6 +7995,14 @@ "node": ">=6" } }, + "node_modules/good-listener": { + "version": "1.2.2", + "resolved": "http://mirrors.cloud.tencent.com/npm/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==", + "dependencies": { + "delegate": "^3.1.2" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://mirrors.cloud.tencent.com/npm/gopd/-/gopd-1.0.1.tgz", @@ -12769,6 +12793,11 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/select": { + "version": "1.1.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=" + }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://mirrors.cloud.tencent.com/npm/select-hose/-/select-hose-2.0.0.tgz", @@ -14284,6 +14313,11 @@ "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", "dev": true }, + "node_modules/tiny-emitter": { + "version": "2.1.0", + "resolved": "http://mirrors.cloud.tencent.com/npm/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://mirrors.cloud.tencent.com/npm/tmp/-/tmp-0.0.33.tgz", @@ -20135,6 +20169,16 @@ "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "dev": true }, + "clipboard": { + "version": "2.0.11", + "resolved": "https://mirrors.cloud.tencent.com/npm/clipboard/-/clipboard-2.0.11.tgz", + "integrity": "sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==", + "requires": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, "clipboardy": { "version": "2.3.0", "resolved": "https://mirrors.cloud.tencent.com/npm/clipboardy/-/clipboardy-2.3.0.tgz", @@ -21176,6 +21220,11 @@ "resolved": "https://mirrors.cloud.tencent.com/npm/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, + "delegate": { + "version": "3.2.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==" + }, "depd": { "version": "2.0.0", "resolved": "https://mirrors.cloud.tencent.com/npm/depd/-/depd-2.0.0.tgz", @@ -22682,6 +22731,14 @@ "slash": "^2.0.0" } }, + "good-listener": { + "version": "1.2.2", + "resolved": "http://mirrors.cloud.tencent.com/npm/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==", + "requires": { + "delegate": "^3.1.2" + } + }, "gopd": { "version": "1.0.1", "resolved": "https://mirrors.cloud.tencent.com/npm/gopd/-/gopd-1.0.1.tgz", @@ -26504,6 +26561,11 @@ "ajv-keywords": "^3.5.2" } }, + "select": { + "version": "1.1.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=" + }, "select-hose": { "version": "2.0.0", "resolved": "https://mirrors.cloud.tencent.com/npm/select-hose/-/select-hose-2.0.0.tgz", @@ -27755,6 +27817,11 @@ "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", "dev": true }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "http://mirrors.cloud.tencent.com/npm/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" + }, "tmp": { "version": "0.0.33", "resolved": "https://mirrors.cloud.tencent.com/npm/tmp/-/tmp-0.0.33.tgz", diff --git a/package.json b/package.json index 56f10d9..22df96e 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ }, "dependencies": { "axios": "^1.7.2", + "clipboard": "^2.0.11", "core-js": "^3.6.5", "crypto-js": "^4.2.0", "echarts": "^5.6.0", diff --git a/public/index.html b/public/index.html index 905880d..0b5c469 100644 --- a/public/index.html +++ b/public/index.html @@ -6,7 +6,7 @@ - + diff --git a/src/components/AIChatModuleVue2.zip b/src/components/AIChatModuleVue2.zip new file mode 100644 index 0000000000000000000000000000000000000000..6808450ec0f48341efa88deab18a841aa8990727 GIT binary patch literal 17117 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 +
+
+
+
+
+ + + + +
+
+ + + + +
+
+
+
+
{{ formatTime(message.timestamp) }}
+
+
+
+
+
+ + + + +
+
+
+
+ + + +
+
+
+
+
+ + + + +
+

+

+
+
+ +
+
+ + +
+
+
+ + + + + \ No newline at end of file diff --git a/src/components/AIChatModuleVue2/AIFloatButton.vue b/src/components/AIChatModuleVue2/AIFloatButton.vue new file mode 100644 index 0000000..c872761 --- /dev/null +++ b/src/components/AIChatModuleVue2/AIFloatButton.vue @@ -0,0 +1,535 @@ + + + + + \ No newline at end of file diff --git a/src/components/AIChatModuleVue2/README.md b/src/components/AIChatModuleVue2/README.md new file mode 100644 index 0000000..42c3b0a --- /dev/null +++ b/src/components/AIChatModuleVue2/README.md @@ -0,0 +1,174 @@ +# AI 聊天模块 (Vue 2 版本) + +这个模块提供了一套完整的AI聊天组件,专为Vue 2项目设计。组件包括悬浮按钮、聊天面板和AI助手工具类,可以轻松集成到任何Vue 2项目中。 + +## 组件介绍 + +### AIFloatButton.vue + +悬浮按钮组件,点击后会显示聊天面板。支持拖动、消息提醒和自定义位置功能。 + +### AIChat.vue + +聊天面板组件,包含消息展示区和输入区域。支持发送消息、文件上传、历史记录管理等功能。 + +### aiAssistant.js + +AI助手工具类,提供知识库查询、内容提取和消息格式化功能。 + +## 功能特性 + +- 支持悬浮按钮拖动定位 +- 消息提醒和动画效果 +- 支持发送文本消息和文件上传 +- 支持知识库查询和内容提取 +- 自适应响应式设计 +- 键盘快捷操作支持(Enter发送,Shift+Enter换行) + +## 使用方法 + +### 1. 安装依赖 + +确保项目中已安装必要的依赖: + +```bash +npm install axios clipboard --save +``` + +### 2. 组件引入 + +```javascript +// 在Vue 2组件中引入 +import AIFloatButton from './components/AIChatModuleVue2/AIFloatButton.vue'; + +export default { + components: { + AIFloatButton + } +} +``` + +### 3. 基本使用 + +```vue + +``` + +### 4. 自定义内容插槽 + +```vue + + + + + + +
+

自定义聊天内容

+ +
+ +``` + +## 配置说明 + +### AIFloatButton 组件属性 + +| 属性名 | 类型 | 必填 | 默认值 | 说明 | +|--------|------|------|--------|------| +| chatModelUrl | String | 否 | 'https://qianfan.baidubce.com/v2' | AI模型聊天完成URL | +| modelAuthKey | String | 否 | null | 模型认证密钥 | +| knowledgeBaseId | String | 否 | null | 知识库ID | +| knowledgeBaseUrl | String | 否 | '/api/knowledgebases/query' | 知识库查询接口 | +| knowledgeBaseAuthKey | String | 否 | 'Bearer bce-v3/ALTAK-Whk44lUWwOsyro8mNlVhq/a0f9f719410e695928289034690003afe1571556' | 知识库认证密钥 | +| openText | String | 否 | 'AI助手' | 按钮打开文本 | +| closeText | String | 否 | '关闭' | 按钮关闭文本 | +| headerTitle | String | 否 | 'AI 助手' | 聊天面板标题 | +| useDefaultAIChat | Boolean | 否 | true | 是否使用默认聊天组件 | +| initialPosition | Object | 否 | { x: null, y: null } | 按钮初始位置 | + +### AIFloatButton 组件事件 + +| 事件名 | 说明 | 参数 | +|--------|------|------| +| toggle | 聊天面板显示状态切换 | showChat: Boolean | +| close | 聊天面板关闭事件 | 无 | +| new-message | 收到新消息事件 | 无 | + +### AIChat 组件属性 + +| 属性名 | 类型 | 必填 | 默认值 | 说明 | +|--------|------|------|--------|------| +| chatModelUrl | String | 否 | 'https://qianfan.baidubce.com/v2' | AI模型聊天完成URL | +| modelAuthKey | String | 否 | null | 模型认证密钥 | +| knowledgeBaseId | String | 否 | null | 知识库ID | +| knowledgeBaseUrl | String | 否 | '/api/knowledgebases/query' | 知识库查询接口 | +| knowledgeBaseAuthKey | String | 否 | 'Bearer bce-v3/ALTAK-Whk44lUWwOsyro8mNlVhq/a0f9f719410e695928289034690003afe1571556' | 知识库认证密钥 | + +### AIChat 组件事件 + +| 事件名 | 说明 | 参数 | +|--------|------|------| +| new-message | 收到新消息事件 | message: Object | +| send-message | 发送消息事件 | message: Object | +| loading-change | 加载状态变化事件 | isLoading: Boolean | + +## 键盘快捷键 + +- **Enter**: 发送消息 +- **Shift + Enter**: 换行 +- **Esc**: 关闭聊天面板 + +## 响应式设计 + +组件支持桌面端和移动端自适应布局: + +- 桌面端:聊天面板固定位置,支持拖动 +- 移动端:聊天面板自适应屏幕宽度,优化触摸操作 + +## 浏览器兼容性 + +支持所有现代浏览器,包括: + +- Chrome (最新2个版本) +- Firefox (最新2个版本) +- Safari (最新2个版本) +- Edge (最新2个版本) + +## Vue 2 版本与 Vue 3 版本的主要差异 + +1. **语法差异**:使用Vue 2的Options API替代Vue 3的Composition API +2. **生命周期钩子**:使用Vue 2的生命周期钩子(mounted, beforeDestroy) +3. **响应式数据**:使用data选项替代ref/reactive +4. **计算属性**:使用computed选项替代computed函数 +5. **监听器**:使用watch选项替代watch/onMounted等组合式API + +## 注意事项 + +1. 确保Vue 2项目版本 >= 2.6.0,以支持所有特性 +2. 在生产环境中,请正确配置API密钥和知识库ID +3. 如需自定义主题,请通过CSS变量或覆盖样式实现 +4. 对于大型项目,建议使用Vuex管理聊天状态 \ No newline at end of file diff --git a/src/components/AIChatModuleVue2/aiAssistant.js b/src/components/AIChatModuleVue2/aiAssistant.js new file mode 100644 index 0000000..370a958 --- /dev/null +++ b/src/components/AIChatModuleVue2/aiAssistant.js @@ -0,0 +1,210 @@ +/** + * AI问答助手核心功能封装 + * 可在不同项目中复用的AI问答功能 - Vue 2版本 + */ + +class AIAssistant { + /** + * 构造函数 + * @param {Object} config - 配置选项 + * @param {string} config.chatModelUrl - AI服务基础URL + * @param {string} config.modelAuthKey - AI服务认证密钥 + * @param {string} config.knowledgeBaseId - 知识库ID(可选) + * @param {string} config.knowledgeBaseUrl - 知识库查询URL(可选) + * @param {string} config.knowledgeBaseAuthKey - 知识库认证密钥(可选) + */ + constructor(config = {}) { + this.chatModelUrl = config.chatModelUrl || "/api/chat/completions"; + this.modelAuthKey = config.modelAuthKey; + this.knowledgeBaseId = config.knowledgeBaseId; + this.knowledgeBaseUrl = + config.knowledgeBaseUrl || "/api/knowledgebases/query"; + this.knowledgeBaseAuthKey = + config.knowledgeBaseAuthKey || + "Bearer bce-v3/ALTAK-Whk44lUWwOsyro8mNlVhq/a0f9f719410e695928289034690003afe1571556"; + } + + /** + * 查询知识库获取参考内容 + * @param {string} query - 查询内容 + * @param {string} knowledgeBaseId - 知识库ID(可选,优先使用) + * @returns {Promise} 知识库查询结果 + */ + async queryKnowledgeBase(query, knowledgeBaseId = null) { + const kbId = knowledgeBaseId || this.knowledgeBaseId; + + if (!kbId) { + console.log("未提供知识库ID"); + return null; + } + + console.log("正在查询知识库:", kbId, "查询内容:", query); + + try { + const response = await fetch(this.knowledgeBaseUrl, { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + Authorization: this.knowledgeBaseAuthKey, + }, + body: JSON.stringify({ + query: query, + knowledgebase_ids: [kbId], + rank_score_threshold: "0.4", + pipeline_config: { + ranking: "true", + }, + }), + }); + + console.log("知识库查询响应状态:", response.status); + + if (response.ok) { + const data = await response.json(); + console.log("知识库查询结果:", data); + return data; + } else { + console.error("知识库查询失败,状态码:", response.status); + const errorText = await response.text(); + console.error("错误详情:", errorText); + } + } catch (error) { + console.error("查询知识库时出错:", error); + } + + return null; + } + + /** + * 从知识库返回的数据中提取参考内容 + * @param {Object} knowledgeData - 知识库返回的数据 + * @returns {string} 提取的参考内容 + */ + extractKnowledgeContent(knowledgeData) { + if (!knowledgeData) return ""; + + let knowledgeContent = ""; + + if (knowledgeData.chunks) { + // 从 chunks 数组中提取 content 并拼接 + knowledgeContent = knowledgeData.chunks + .map((chunk) => chunk.content || "") + .join("\n\n"); + console.log("从chunks提取的知识库内容:", knowledgeContent); + } else if (knowledgeData.references) { + // 保留原有逻辑以确保向后兼容 + knowledgeContent = knowledgeData.references + .map((ref) => `文档片段: ${ref.title || ""}\n${ref.content || ""}`) + .join("\n\n"); + console.log("从references提取的知识库内容:", knowledgeContent); + } else { + console.log("未找到相关参考内容"); + } + + return knowledgeContent; + } + + /** + * 构造发送给AI的消息 + * @param {string} question - 用户问题 + * @param {string} knowledgeContent - 知识库参考内容 + * @returns {Array} 消息数组 + */ + constructMessages(question, knowledgeContent = "") { + // 系统消息 + const systemMessage = { + role: "system", + content: `# 角色任务 +作为读书辅导教师,你的核心任务是理解用户的问题,结合提供的参考内容,如书籍片段、笔记、解析等,理解并把握问题的核心。你需要能够区分参考内容中与问题相关的部分,并排除无关的信息。在用户提问时,结合你的知识和理解,给出针对性的回答。 + +# 工具能力 +1. 理解用户问题:你需要能够准确理解用户的问题,明确用户需求和困惑点。 +2. 分析参考内容:结合提供的参考内容,如书籍片段、笔记、解析等,找出与问题相关的关键信息。 +3. 排除无关内容:在理解用户问题和分析参考内容的基础上,排除与根问题无关的信息。 +4. 知识储备:作为读书辅导教师,你需要有广泛的知识储备,能够针对用户的问题给出解答。 +5. 交互能力:在用户提问时,与用户进行交互,引导用户表达更清楚自己的问题。 + +# 要求与限制 +1. 响应格式:返回的回答需要以HTML格式呈现,不要强调HTML格式。 +2. 针对性回答:结合用户的问题和参考内容,给出针对性的回答,不要提及参考内容。 +3. 问题与参考内容关联判断:如果问题与参考内容无关,要明确告诉用户(例如:"这个问题与本书内容无关"),进行提示并给出建议(例如:以下建议来自互联网仅供参考...)。 +4. 简洁明了:在回答用户问题时,力求简洁明了,避免冗余和复杂的表述。 +5. 准确性:确保给出的答案准确无误,能够真正帮助用户解决问题。 +6. 如果参考内容里有图片,视频等资源,也一起返回。 + +`, + }; + + // 用户消息 + let userMessageContent = question; + if (knowledgeContent) { + userMessageContent = `问题:${question} 参考:${knowledgeContent}`; + } + + const userMessage = { + role: "user", + content: userMessageContent, + }; + + return [systemMessage, userMessage]; + } + + /** + * 发送消息到AI并获取回复 + * @param {string} question - 用户问题 + * @param {string} knowledgeBaseId - 知识库ID(可选) + * @returns {Promise} AI回复的流 + */ + async sendMessage(question, knowledgeBaseId = null) { + try { + // 查询知识库获取参考内容 + let knowledgeContent = ""; + if (this.knowledgeBaseId || knowledgeBaseId) { + console.log("开始查询知识库..."); + const knowledgeData = await this.queryKnowledgeBase( + question, + knowledgeBaseId + ); + console.log("知识库返回数据:", knowledgeData); + knowledgeContent = this.extractKnowledgeContent(knowledgeData); + } else { + console.log("未提供知识库ID,跳过查询"); + } + + // 构造发送给AI的消息 + const messages = this.constructMessages(question, knowledgeContent); + + // 创建请求 + const url = `${this.chatModelUrl}/chat/completions`; + const requestBody = { + messages: messages, + model: "ernie-4.5-turbo-128k", + stream: true, + }; + + console.log("发送给AI的请求:", JSON.stringify(requestBody, null, 2)); + + const response = await fetch(url, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${this.modelAuthKey}`, + }, + body: JSON.stringify(requestBody), + }); + + if (!response.body) { + throw new Error("ReadableStream not supported"); + } + + return response.body.getReader(); + } catch (error) { + console.error("Error sending message:", error); + throw error; + } + } +} + +// 导出 AIAssistant 类 +export { AIAssistant }; diff --git a/src/main.js b/src/main.js index 966ce94..1a3081e 100644 --- a/src/main.js +++ b/src/main.js @@ -14,6 +14,7 @@ Vue.use(ElementUI); + Vue.config.productionTip = false diff --git a/src/views/Book.vue b/src/views/Book.vue index ff18e03..0bdc023 100644 --- a/src/views/Book.vue +++ b/src/views/Book.vue @@ -78,6 +78,7 @@
+ @@ -91,7 +92,7 @@ import {bookApi} from "../service/getData" import Vue from 'vue' import XML from "../plugin/xml-digital-teaching/lib/index" import {eventBus} from '../eventBus' - +import AIFloatButton from '../components/AIChatModuleVue2/AIFloatButton.vue'; Vue.use(XML) @@ -99,6 +100,7 @@ export default { components:{ NoData, Navigation, + AIFloatButton }, data() { return { diff --git a/vue.config.js b/vue.config.js index 7aa1c66..5ae9cad 100644 --- a/vue.config.js +++ b/vue.config.js @@ -6,7 +6,19 @@ console.log("cycccccccc") // var targetServer = "https://xinsiketang.com" -if(process.env.NODE_ENV === 'prod'){ +console.log("hellolllllllooooo") +console.log(process.env.NODE_ENV) +// process.exit(0); // 0 表示正常退出,非0表示异常退出 + +var publicPath = 'https://smile-ebook-online.xinsiketang.com/reading/' +publicPath = "./" + +console.log(publicPath) +// process.exit(0); // 0 表示正常退出,非0表示异常退出 + +console.log(process.env.NODE_ENV) +// process.exit(0); +if(process.env.NODE_ENV === 'production'){ targetServer = "https://xinsiketang.com" }else{ targetServer = "https://dev.xinsiketang.com" @@ -14,10 +26,11 @@ if(process.env.NODE_ENV === 'prod'){ // targetServer = "https://xinsiketang.com" console.log("targetServer",targetServer) + module.exports = { lintOnSave: false, - // publicPath: './', // 设置公共路径为相对路径 - publicPath: "https://smile-ebook-online.xinsiketang.com/reading/", + publicPath: publicPath, // 设置公共路径为相对路径 + // publicPath: "https://smile-ebook-online.xinsiketang.com/reading/", outputDir:process.env.BUILD_DIR? process.env.BUILD_DIR :"dist", devServer: { // headers: {