diff --git a/root/home/components/AiApply.vue b/root/home/components/AiApply.vue
new file mode 100644
index 0000000..fa68bfb
--- /dev/null
+++ b/root/home/components/AiApply.vue
@@ -0,0 +1,148 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/root/home/editTownsman.vue b/root/home/editTownsman.vue
index 380ab92..84f6fb1 100644
--- a/root/home/editTownsman.vue
+++ b/root/home/editTownsman.vue
@@ -1,9 +1,9 @@
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ ]" @updateFile="updateFile">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/root/home/quickApplication.vue b/root/home/quickApplication.vue
index 65d31c0..a9ab272 100644
--- a/root/home/quickApplication.vue
+++ b/root/home/quickApplication.vue
@@ -1,7 +1,9 @@
+
+
- 老乡信息
+ 老乡信息
-
+
@@ -102,8 +104,11 @@
diff --git a/uni_modules/gao-ChatSSEClient/changelog.md b/uni_modules/gao-ChatSSEClient/changelog.md
new file mode 100644
index 0000000..6266fbb
--- /dev/null
+++ b/uni_modules/gao-ChatSSEClient/changelog.md
@@ -0,0 +1,13 @@
+## 1.5.0(2025-04-01)
+返回完整的message、小程序解析逻辑优化,改为使用fetch-event-source的解析逻辑
+## 1.4.1(2025-03-28)
+onOepn回调方法返回sse请求的response对象、及返回err错误信息
+## 1.4.0(2025-03-24)
+解析微信小程序返回的数据
+## 1.3.2(2025-03-16)
+1. 示例项目添加了sse server供调试。
+2. 发生了错误接口会无限运行的问题解决,现在发生了错误会调用stop方法停止。
+## 1.3.1(2025-03-10)
+修复了get请求无法stop的bug
+## 1.3.0(2025-03-06)
+插件修改为 uni_modules 模式
diff --git a/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/children/ChatAppAndWeb.vue b/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/children/ChatAppAndWeb.vue
new file mode 100644
index 0000000..b496413
--- /dev/null
+++ b/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/children/ChatAppAndWeb.vue
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/children/ChatWxApplet.vue b/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/children/ChatWxApplet.vue
new file mode 100644
index 0000000..fec9c23
--- /dev/null
+++ b/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/children/ChatWxApplet.vue
@@ -0,0 +1,74 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/fetch-event-source/fetch.js b/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/fetch-event-source/fetch.js
new file mode 100644
index 0000000..175b639
--- /dev/null
+++ b/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/fetch-event-source/fetch.js
@@ -0,0 +1,89 @@
+var __rest = (this && this.__rest) || function (s, e) {
+ var t = {};
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
+ t[p] = s[p];
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
+ t[p[i]] = s[p[i]];
+ }
+ return t;
+};
+import { getBytes, getLines, getMessages } from './parse';
+export const EventStreamContentType = 'text/event-stream';
+const DefaultRetryInterval = 1000;
+const LastEventId = 'last-event-id';
+export function fetchEventSource(input, _a) {
+ var { signal: inputSignal, headers: inputHeaders, onopen: inputOnOpen, onmessage, onclose, onerror, openWhenHidden, fetch: inputFetch } = _a, rest = __rest(_a, ["signal", "headers", "onopen", "onmessage", "onclose", "onerror", "openWhenHidden", "fetch"]);
+ return new Promise((resolve, reject) => {
+ const headers = Object.assign({}, inputHeaders);
+ if (!headers.accept) {
+ headers.accept = EventStreamContentType;
+ }
+ let curRequestController;
+ function onVisibilityChange() {
+ curRequestController.abort();
+ if (!document.hidden) {
+ create();
+ }
+ }
+ if (!openWhenHidden) {
+ document.addEventListener('visibilitychange', onVisibilityChange);
+ }
+ let retryInterval = DefaultRetryInterval;
+ let retryTimer = 0;
+ function dispose() {
+ document.removeEventListener('visibilitychange', onVisibilityChange);
+ window.clearTimeout(retryTimer);
+ curRequestController.abort();
+ }
+ inputSignal === null || inputSignal === void 0 ? void 0 : inputSignal.addEventListener('abort', () => {
+ dispose();
+ resolve();
+ });
+ const fetch = inputFetch !== null && inputFetch !== void 0 ? inputFetch : window.fetch;
+ const onopen = inputOnOpen !== null && inputOnOpen !== void 0 ? inputOnOpen : defaultOnOpen;
+ async function create() {
+ var _a;
+ curRequestController = new AbortController();
+ try {
+ const response = await fetch(input, Object.assign(Object.assign({}, rest), { headers, signal: curRequestController.signal }));
+ await onopen(response);
+ await getBytes(response.body, getLines(getMessages(id => {
+ if (id) {
+ headers[LastEventId] = id;
+ }
+ else {
+ delete headers[LastEventId];
+ }
+ }, retry => {
+ retryInterval = retry;
+ }, onmessage)));
+ onclose === null || onclose === void 0 ? void 0 : onclose();
+ dispose();
+ resolve();
+ }
+ catch (err) {
+ if (!curRequestController.signal.aborted) {
+ try {
+ const interval = (_a = onerror === null || onerror === void 0 ? void 0 : onerror(err)) !== null && _a !== void 0 ? _a : retryInterval;
+ window.clearTimeout(retryTimer);
+ retryTimer = window.setTimeout(create, interval);
+ }
+ catch (innerErr) {
+ dispose();
+ reject(innerErr);
+ }
+ }
+ }
+ }
+ create();
+ });
+}
+function defaultOnOpen(response) {
+ const contentType = response.headers.get('content-type');
+ if (!(contentType === null || contentType === void 0 ? void 0 : contentType.startsWith(EventStreamContentType))) {
+ throw new Error(`Expected content-type to be ${EventStreamContentType}, Actual: ${contentType}`);
+ }
+}
+//# sourceMappingURL=fetch.js.map
\ No newline at end of file
diff --git a/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/fetch-event-source/index.js b/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/fetch-event-source/index.js
new file mode 100644
index 0000000..e40ec6f
--- /dev/null
+++ b/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/fetch-event-source/index.js
@@ -0,0 +1,2 @@
+export { fetchEventSource, EventStreamContentType } from './fetch';
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/fetch-event-source/parse.js b/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/fetch-event-source/parse.js
new file mode 100644
index 0000000..d51db34
--- /dev/null
+++ b/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/fetch-event-source/parse.js
@@ -0,0 +1,128 @@
+export async function getBytes(stream, onChunk) {
+ const reader = stream.getReader();
+ let result;
+ while (!(result = await reader.read()).done) {
+ onChunk(result.value);
+ }
+}
+export function getLines(onLine) {
+ let buffer;
+ let position;
+ let fieldLength;
+ let discardTrailingNewline = false;
+ return function onChunk(arr) {
+ if (buffer === undefined) {
+ buffer = arr;
+ position = 0;
+ fieldLength = -1;
+ }
+ else {
+ buffer = concat(buffer, arr);
+ }
+ const bufLength = buffer.length;
+ let lineStart = 0;
+ while (position < bufLength) {
+ if (discardTrailingNewline) {
+ if (buffer[position] === 10) {
+ lineStart = ++position;
+ }
+ discardTrailingNewline = false;
+ }
+ let lineEnd = -1;
+ for (; position < bufLength && lineEnd === -1; ++position) {
+ switch (buffer[position]) {
+ case 58:
+ if (fieldLength === -1) {
+ fieldLength = position - lineStart;
+ }
+ break;
+ case 13:
+ discardTrailingNewline = true;
+ case 10:
+ lineEnd = position;
+ break;
+ }
+ }
+ if (lineEnd === -1) {
+ break;
+ }
+ onLine(buffer.subarray(lineStart, lineEnd), fieldLength);
+ lineStart = position;
+ fieldLength = -1;
+ }
+ if (lineStart === bufLength) {
+ buffer = undefined;
+ }
+ else if (lineStart !== 0) {
+ buffer = buffer.subarray(lineStart);
+ position -= lineStart;
+ }
+ };
+}
+export function getMessages(onId, onRetry, onMessage) {
+ let message = newMessage();
+ let decoder;
+
+ // #ifdef MP-WEIXIN
+ decoder = {
+ decode(arraybuffer) {
+ return decodeURIComponent(escape(String.fromCharCode(...arraybuffer)))
+ }
+ };
+ // #endif
+
+ // #ifdef APP-PLUS || H5
+ decoder = new TextDecoder();
+ // #endif
+
+ return function onLine(line, fieldLength) {
+ if (line.length === 0) {
+ onMessage === null || onMessage === void 0 ? void 0 : onMessage(message);
+ message = newMessage();
+ }
+ else if (fieldLength > 0) {
+ const field = decoder.decode(line.subarray(0, fieldLength));
+ const valueOffset = fieldLength + (line[fieldLength + 1] === 32 ? 2 : 1);
+ const value = decoder.decode(line.subarray(valueOffset));
+ switch (field) {
+ case 'data':
+ message.data = message.data
+ ? message.data + '\n' + value
+ : value;
+ break;
+ case 'event':
+ message.event = value;
+ break;
+ case 'id':
+ onId(message.id = value);
+ break;
+ case 'retry':
+ const retry = parseInt(value, 10);
+ if (!isNaN(retry)) {
+ onRetry(message.retry = retry);
+ }
+ break;
+ default:
+ const msg = decoder.decode(line, { stream: true });
+ message.data = msg
+ onMessage(message);
+ break;
+ }
+ }
+ };
+}
+function concat(a, b) {
+ const res = new Uint8Array(a.length + b.length);
+ res.set(a);
+ res.set(b, a.length);
+ return res;
+}
+function newMessage() {
+ return {
+ data: '',
+ event: '',
+ id: '',
+ retry: undefined,
+ };
+}
+//# sourceMappingURL=parse.js.map
\ No newline at end of file
diff --git a/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/gao-ChatSSEClient.vue b/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/gao-ChatSSEClient.vue
new file mode 100644
index 0000000..4ae5b37
--- /dev/null
+++ b/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/gao-ChatSSEClient.vue
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/utils/index.js b/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/utils/index.js
new file mode 100644
index 0000000..455eccb
--- /dev/null
+++ b/uni_modules/gao-ChatSSEClient/components/gao-ChatSSEClient/utils/index.js
@@ -0,0 +1,45 @@
+// 检索字符,并且加上该字符的长度
+const indexOfLen = (str) => {
+ const startIndex = str.indexOf(str);
+
+ if (startIndex !== -1) {
+ return startIndex + str.length
+ }
+
+ return -1;
+}
+
+/**
+ * 解析SSE数据
+ * sse返回的数据可能会有多个消息相连,这里处理字符串,返回数组
+ * @param data sse字符串数据
+ * @returns {*} 处理过后的数组
+ */
+export const parseSseData = (data) => {
+ try {
+ let lines = data.split("\n");
+
+ lines = lines.map(v => {
+ if (!v) return null;
+ let startInd = -1;
+
+ for (const ind of [indexOfLen("data: "), v.indexOf("{")]) {
+ if (ind !== -1) {
+ startInd = ind;
+ break;
+ }
+ }
+
+ if (startInd === -1) {
+ return v;
+ } else {
+ return v.substring(startInd, v.length).trim();
+ }
+ }).filter(Boolean);
+
+ return lines;
+ } catch (e) {
+ console.warn("解析失败:", e);
+ return data;
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/gao-ChatSSEClient/package.json b/uni_modules/gao-ChatSSEClient/package.json
new file mode 100644
index 0000000..0833f93
--- /dev/null
+++ b/uni_modules/gao-ChatSSEClient/package.json
@@ -0,0 +1,65 @@
+{
+ "id": "gao-ChatSSEClient",
+ "name": "sse 客户端组件,支持兼容:v2、v3、安卓、ios、浏览器、微信小程序",
+ "displayName": "sse 客户端组件,支持兼容:v2、v3、安卓、ios、浏览器、微信小程序",
+ "version": "1.5.0",
+ "description": "sse 客户端组件,支持兼容:v2、v3、安卓、ios、浏览器、微信小程序",
+ "repository": "https://github.com/gaozhenqiang/uniapp-chatSSEClient",
+ "keywords": [
+ "sse",
+ "chat",
+ "微信小程序sse",
+ "流式接口",
+ "流式输出"
+ ],
+ "dcloudext": {
+ "declaration": {
+ "ads": "无",
+ "data": "插件不采集任何数据",
+ "permissions": "无"
+ },
+ "contact": {
+ "qq": "1933669775"
+ },
+ "type": "component-vue",
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ }
+ },
+ "uni_modules": {
+ "platforms": {
+ "client": {
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ },
+ "App": {
+ "app-vue": "y",
+ "app-harmony": "u",
+ "app-nvue": "u",
+ "app-uvue": "u"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/gao-ChatSSEClient/readme.md b/uni_modules/gao-ChatSSEClient/readme.md
new file mode 100644
index 0000000..8086ff1
--- /dev/null
+++ b/uni_modules/gao-ChatSSEClient/readme.md
@@ -0,0 +1,125 @@
+# sse 客户端组件,支持v2、v3、安卓、ios、浏览器、微信小程序
+
+## 使用说明
+
+### 导入组件
+
+点击右上角 `下载插件并导入HBuilderX`
+
+uniapp插件地址:https://ext.dcloud.net.cn/plugin?id=20971
+
+或者你可以参考我的示例
+
+### 示例代码
+
+```javascript
+
+
+
+
+ {{ openLoading ? "正在连接sse..." : '连接完成!' }}
+ {{ loading ? "加载中..." : '' }}
+
+
+
+ {{ responseText }}
+
+
+
+
+
+
+```
+
+# 温馨提示
+
+示例项目根目录的`sse-server.js`文件提供了一个简单的sse测试服务,使用 `node sse-server.js`运行
+
+**提出问题之前请先确保你的接口没有问题**
+
+---
+
+**请仔细阅读我提供的示例代码。**
+
+**如果你的程序有问题请先下载我提供的示例项目调试!**
+
+---
+
+如果想了解原理请看我掘金的文章: [点击前往](https://juejin.cn/post/7435632766375084082)
+
+本插件依赖于 `fetch-event-source` 库,将编辑后的js集成,因为我修改了原来库解析的逻辑,使其更适用于中国宝宝体质。
+
+---
+
+**如果这个组件解决了你的问题,麻烦去[github](https://github.com/gaozhenqiang/uniapp-chatSSEClient/) 帮我点个赞,谢谢大家**
+
+有新需求或者bug可以在github上提issues,或者加我q `1933669775`
+
+# 常见问题
+
+## ios报错:TypeError: Load failed
+
+后端接口处理一下跨域即可解决。
+