Files
phone-app------test1-/unpackage/dist/dev/app-plus/app-service.js

8595 lines
314 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
if (typeof Promise !== "undefined" && !Promise.prototype.finally) {
Promise.prototype.finally = function(callback) {
const promise = this.constructor;
return this.then(
(value) => promise.resolve(callback()).then(() => value),
(reason) => promise.resolve(callback()).then(() => {
throw reason;
})
);
};
}
;
if (typeof uni !== "undefined" && uni && uni.requireGlobal) {
const global2 = uni.requireGlobal();
ArrayBuffer = global2.ArrayBuffer;
Int8Array = global2.Int8Array;
Uint8Array = global2.Uint8Array;
Uint8ClampedArray = global2.Uint8ClampedArray;
Int16Array = global2.Int16Array;
Uint16Array = global2.Uint16Array;
Int32Array = global2.Int32Array;
Uint32Array = global2.Uint32Array;
Float32Array = global2.Float32Array;
Float64Array = global2.Float64Array;
BigInt64Array = global2.BigInt64Array;
BigUint64Array = global2.BigUint64Array;
}
;
if (uni.restoreGlobal) {
uni.restoreGlobal(Vue, weex, plus, setTimeout, clearTimeout, setInterval, clearInterval);
}
(function(vue) {
"use strict";
const ON_SHOW = "onShow";
function formatAppLog(type, filename, ...args) {
if (uni.__log__) {
uni.__log__(type, filename, ...args);
} else {
console[type].apply(console, [...args, filename]);
}
}
function resolveEasycom(component, easycom) {
return typeof component === "string" ? easycom : component;
}
const createLifeCycleHook = (lifecycle, flag = 0) => (hook, target = vue.getCurrentInstance()) => {
!vue.isInSSRComponentSetup && vue.injectHook(lifecycle, hook, target);
};
const onShow = /* @__PURE__ */ createLifeCycleHook(
ON_SHOW,
1 | 2
/* HookFlags.PAGE */
);
const BASE_URL = "https://cloudtest.yuxindazhineng.com";
const login = async (username, password) => {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_URL}/login`,
method: "POST",
data: {
"username": username,
"password": password,
"login_type": "phone"
},
header: {
"Content-Type": "application/json"
},
success: (res) => {
if (res.statusCode === 200) {
const token = res.data.access_token;
if (token) {
uni.setStorageSync("token", token);
resolve(token);
} else {
const msg = res.data.error || "检查用户名和密码";
reject(msg);
}
} else {
reject(`请求失败:${res.statusCode}`);
}
},
fail: (err) => {
const msg = err.errMsg || "网络错误";
reject(msg);
}
});
});
};
const getUserConversations = async (token) => {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_URL}/get_user_conversations`,
method: "POST",
data: {
"access_token": token
},
header: {
"Content-Type": "application/json"
},
success: (res) => {
if (res.statusCode === 200) {
const conversations = res.data.conversations;
resolve(conversations);
} else {
reject(`请求失败:${res.statusCode}`);
}
},
fail: (err) => {
const msg = err.errMsg || "网络错误";
reject(msg);
}
});
});
};
const getConversationMessages = async (token, conversatio_id) => {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_URL}/get_conversation_messages`,
method: "POST",
data: {
"access_token": token,
"conversation_id": conversatio_id
},
header: {
"Content-Type": "application/json"
},
success: (res) => {
if (res.statusCode === 200) {
const messagesInfo = res.data;
if (messagesInfo) {
formatAppLog("log", "at utils/cloud-api.js:88", "工作区id为", messagesInfo.workspace_id);
uni.setStorageSync("workspace_id", messagesInfo.workspace_id);
resolve(messagesInfo.messages);
} else {
const msg = res.data.error || "获取消息出错啦";
reject(msg);
}
} else {
reject(`请求失败:${res.statusCode}`);
}
},
fail: (err) => {
const msg = err.errMsg || "网络错误";
reject(msg);
}
});
});
};
const addMessageDict = async (token, role, conversation_id, message) => {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_URL}/add_message_dict`,
method: "POST",
data: {
"access_token": token,
"conversation_id": conversation_id,
"message": {
"role": role,
"content": message
}
},
header: {
"Content-Type": "application/json"
},
success: (res) => {
if (res.statusCode === 200) {
const message_id = res.data.message_id;
if (message_id) {
resolve(message_id);
} else {
const msg = res.data.error || "用户发送消息出错啦";
reject(msg);
}
} else {
reject(`用户发送失败:${res.statusCode}`);
}
},
fail: (err) => {
const msg = err.errMsg || "网络错误";
reject(msg);
}
});
});
};
const createWorkspace = async (token, name2) => {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_URL}/create_workspace`,
method: "POST",
data: {
"access_token": token,
"name": name2
},
header: {
"Content-Type": "application/json"
},
success: (res) => {
if (res.statusCode === 200) {
const workspaceId = res.data.workspace_id;
if (workspaceId) {
resolve(workspaceId);
} else {
const msg = res.data.error || "创建工作区id出错啦";
reject(msg);
}
} else {
reject(`创建工作区id失败${res.statusCode}`);
}
},
fail: (err) => {
const msg = err.errMsg || "网络错误";
reject(msg);
}
});
});
};
const createConversation = async (token, workspaceId, title, sender) => {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_URL}/create_conversation`,
method: "POST",
data: {
"access_token": token,
"workspace_id": workspaceId,
"title": title,
"sender": sender
},
header: {
"Content-Type": "application/json"
},
success: (res) => {
if (res.statusCode === 200) {
const conversationId = res.data.conversation_id;
if (conversationId) {
resolve(conversationId);
} else {
const msg = res.data.error || "创建新对话id出错啦";
reject(msg);
}
} else {
reject(`创建新对话失败:${res.statusCode}`);
}
}
});
});
};
const deleteConversation = async (token, conversation_ids) => {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_URL}/delete_conversation`,
method: "POST",
data: {
"access_token": token,
"conversation_ids": conversation_ids
},
header: {
"Content-Type": "application/json"
},
success: (res) => {
if (res.statusCode === 200) {
const respond = res.data;
if (respond == null ? void 0 : respond.success) {
resolve(respond.message);
} else {
const msg = respond.failed_ids.error || "删除对话出错啦";
reject(msg);
}
} else {
reject(`删除对话失败:${res.statusCode}`);
}
},
fail: (err) => {
const msg = err.errMsg || "网络错误";
reject(msg);
}
});
});
};
const getUserInfo = async (token) => {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_URL}/get_user_info`,
method: "POST",
header: {
"Content-Type": "application/json"
},
data: {
"access_token": token
},
success: (res) => {
var _a, _b;
if (res.statusCode === 200) {
const respond = res.data;
if (respond == null ? void 0 : respond._id) {
uni.setStorageSync("userId", respond._id);
resolve(respond);
} else {
const msg = ((_b = (_a = respond == null ? void 0 : respond.detail) == null ? void 0 : _a[0]) == null ? void 0 : _b.msg) || "获取用户信息出错啦";
reject(msg);
}
} else {
reject(`获取用户信息失败:${res.statusCode}`);
}
},
fail: (err) => {
const msg = err.errMsg || "网络错误";
reject(msg);
}
});
});
};
const getUserAvatar = (token, userIds) => {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_URL}/cloud_api/get_user_avatar`,
method: "POST",
header: {
"Content-Type": "application/json"
},
data: {
"access_token": token,
"user_ids": userIds
},
success: (res) => {
if (res.statusCode === 200) {
const respond = res.data;
if (respond.success) {
resolve(respond.users);
} else {
const msg = (respond == null ? void 0 : respond.error) || "获取用户头像出错啦";
reject(msg);
}
} else {
reject(`获取用户头像失败:${res.statusCode}`);
}
},
fail: (err) => {
const msg = err.errMsg || "网络错误";
reject(msg);
}
});
});
};
const searchUsers = (token, keyword) => {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_URL}/cloud_api/search_users`,
method: "POST",
header: {
"Content-Type": "application/json"
},
data: {
"access_token": token,
"keyword": keyword
},
success: (res) => {
if (res.statusCode === 200) {
const respond = res.data;
if (respond.success) {
resolve(respond.users);
} else {
const msg = (respond == null ? void 0 : respond.error) || "通过用户名或邮箱来去查询用户出错啦";
reject(msg);
}
} else {
reject(`通过用户名或邮箱来去查询用户失败:${res.statusCode}`);
}
},
fail: (err) => {
const msg = err.errMsg || "网络错误";
reject(msg);
}
});
});
};
const getWorkspaceList = (token, workspacesId) => {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_URL}/cloud_api/phone/workspace/list`,
method: "POST",
header: {
"Content-Type": "application/json"
},
data: {
"access_token": token,
"workspaces_id": workspacesId,
"format": "tree",
"parent_path": "",
"filter_type": ""
},
success: (res) => {
if (res.statusCode === 200) {
const respond = res.data;
if (respond.success) {
resolve(respond.data);
} else {
const msg = (respond == null ? void 0 : respond.error) || "获取工作区文件目录出错啦";
reject(msg);
}
} else {
reject(`获取工作区文件目录失败:${res.statusCode}`);
}
},
fail: (err) => {
const msg = err.errMsg || "网络错误";
reject(msg);
}
});
});
};
const daleteWorkspace = (token, workspacesId, path) => {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_URL}/cloud_api/phone/workspace/delete`,
method: "POST",
header: {
"Content-Type": "application/json"
},
data: {
"access_token": token,
"workspaces_id": workspacesId,
"file_path": path
},
success: (res) => {
if (res.statusCode === 200) {
const respond = res.data;
if (respond.success) {
resolve(respond.message);
} else {
const msg = (respond == null ? void 0 : respond.error) || "删除工作区文件出错啦";
reject(msg);
}
} else {
reject(`删除工作区文件失败:${res.statusCode}`);
}
}
});
});
};
const createWorkspaceFolder = (token, workspacesId, path) => {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_URL}/cloud_api/phone/workspace/create`,
method: "POST",
header: {
"Content-Type": "application/json"
},
data: {
"access_token": token,
"workspaces_id": workspacesId,
"dir_path": path
},
success: (res) => {
if (res.statusCode === 200) {
const respond = res.data;
if (respond.success) {
resolve(respond.message);
} else {
const msg = (respond == null ? void 0 : respond.error) || "创建工作区文件夹出错啦";
reject(msg);
}
} else {
reject(`创建工作区文件夹失败:${res.statusCode}`);
}
}
});
});
};
const getWorkspaceFileURL = (token, workspacesId, path) => {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_URL}/cloud_api/phone/workspace/downloadFile`,
method: "POST",
header: {
"Content-Type": "application/json"
},
data: {
"access_token": token,
"workspaces_id": workspacesId,
"file_path": path
},
success: (res) => {
if (res.statusCode === 200) {
const respond = res.data;
if (respond.success) {
resolve(respond.message || respond.data);
} else if (Array.isArray(respond)) {
resolve(respond);
} else {
const msg = (respond == null ? void 0 : respond.error) || "获取工作区文URL出错啦";
reject(msg);
}
} else {
reject(`获取工作区文URL失败${res.statusCode}`);
}
}
});
});
};
const _export_sfc = (sfc, props) => {
const target = sfc.__vccOpts || sfc;
for (const [key, val] of props) {
target[key] = val;
}
return target;
};
const _sfc_main$a = {
__name: "Login",
setup(__props, { expose: __expose }) {
__expose();
const UsernameValue = vue.ref("");
const isUsernameFocused = vue.ref(false);
const isUsernameError = vue.ref(false);
const usernameFocused = () => {
isUsernameFocused.value = true;
formDataHasNull.value = false;
};
const handleUsernameBlur = () => {
isUsernameFocused.value = false;
};
const validateUsername = () => {
};
const PasswordValue = vue.ref("");
const isPasswordFocused = vue.ref(false);
const isPasswordError = vue.ref(false);
const passwordFocused = () => {
isPasswordFocused.value = true;
formDataHasNull.value = false;
};
const handlePasswordBlur = () => {
isPasswordFocused.value = false;
};
const form = vue.reactive({
username: vue.computed(() => UsernameValue.value),
password: vue.computed(() => PasswordValue.value),
remember: true
});
const loading = vue.ref(false);
const formDataHasNull = vue.ref(false);
const handleLogin = async () => {
checkFormData();
if (formDataHasNull.value)
return;
loading.value = true;
try {
const token = await login(UsernameValue.value, PasswordValue.value);
saveLoginInfo();
uni.reLaunch({
url: "/pages/Chat/Chat"
});
} catch (err) {
formatAppLog("log", "at pages/Login/Login.vue:124", "登录失败", err);
uni.showToast({
title: err || "失败",
icon: "error"
});
} finally {
loading.value = false;
}
};
const checkFormData = () => {
if (!UsernameValue.value || !PasswordValue.value) {
formDataHasNull.value = true;
}
};
const saveLoginInfo = () => {
if (form.remember) {
const loginInfo = {
username: form.username,
password: form.password,
remember: true
};
uni.setStorageSync("login_info", loginInfo);
uni.setStorageSync("chatType", 0);
} else {
uni.removeStorageSync("login_info");
}
};
const loadLoginInfo = () => {
try {
const loginInfo = uni.getStorageSync("login_info");
if (loginInfo) {
UsernameValue.value = loginInfo.username || "";
PasswordValue.value = loginInfo.password || "";
form.remember = loginInfo.remember ?? true;
}
} catch (e2) {
formatAppLog("error", "at pages/Login/Login.vue:168", "读取登录信息失败", e2);
}
};
vue.onMounted(() => {
loadLoginInfo();
});
const __returned__ = { UsernameValue, isUsernameFocused, isUsernameError, usernameFocused, handleUsernameBlur, validateUsername, PasswordValue, isPasswordFocused, isPasswordError, passwordFocused, handlePasswordBlur, form, loading, formDataHasNull, handleLogin, checkFormData, saveLoginInfo, loadLoginInfo, reactive: vue.reactive, ref: vue.ref, computed: vue.computed, onMounted: vue.onMounted, get login() {
return login;
} };
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
return __returned__;
}
};
function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
return vue.openBlock(), vue.createElementBlock(
vue.Fragment,
null,
[
vue.createElementVNode("view", { class: "status-bar" }),
vue.createElementVNode("view", { class: "login-container page-container" }, [
vue.createElementVNode("view", { class: "login-card" }, [
vue.createElementVNode("view", { class: "login-header" }, [
vue.createElementVNode("view", { class: "login-header-logo" }, [
vue.createElementVNode("view", { class: "icon-wrapper" }, [
vue.createElementVNode("view", { class: "iconfont icon-brain-2-fill danao-style" })
]),
vue.createElementVNode("text", null, "YXD")
]),
vue.createElementVNode("view", { class: "sub-title" }, "File Handling Chat")
]),
vue.createElementVNode("view", { class: "form-wrapper" }, [
vue.createElementVNode("view", { class: "form-item" }, [
vue.createElementVNode("view", { class: "form-label" }, [
vue.createElementVNode("text", null, "用户名")
]),
vue.withDirectives(vue.createElementVNode(
"input",
{
class: vue.normalizeClass(["form-input", { focused: $setup.isUsernameFocused, error: $setup.isUsernameError }]),
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.UsernameValue = $event),
onFocus: $setup.usernameFocused,
onBlur: $setup.handleUsernameBlur,
onInput: $setup.validateUsername,
placeholder: "请输入用户名"
},
null,
34
/* CLASS, NEED_HYDRATION */
), [
[vue.vModelText, $setup.UsernameValue]
])
]),
vue.createElementVNode("view", { class: "form-item" }, [
vue.createElementVNode("view", { class: "form-label" }, [
vue.createElementVNode("text", null, "密码")
]),
vue.withDirectives(vue.createElementVNode(
"input",
{
type: "password",
class: vue.normalizeClass(["form-input", { focused: $setup.isPasswordFocused, error: $setup.isPasswordError }]),
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $setup.PasswordValue = $event),
onFocus: $setup.passwordFocused,
onBlur: $setup.handlePasswordBlur,
placeholder: "请输入密码"
},
null,
34
/* CLASS, NEED_HYDRATION */
), [
[vue.vModelText, $setup.PasswordValue]
])
]),
$setup.formDataHasNull ? (vue.openBlock(), vue.createElementBlock("text", {
key: 0,
class: "error-info"
}, "用户名或密码不能为空")) : vue.createCommentVNode("v-if", true),
vue.createElementVNode("view", { class: "form-option" }, [
vue.createElementVNode("view", {
class: "checkbox-wrapper",
onClick: _cache[2] || (_cache[2] = ($event) => $setup.form.remember = !$setup.form.remember)
}, [
vue.createElementVNode(
"view",
{
class: vue.normalizeClass(["checkbox", { checked: $setup.form.remember }])
},
[
$setup.form.remember ? (vue.openBlock(), vue.createElementBlock("text", { key: 0 }, "✓")) : vue.createCommentVNode("v-if", true)
],
2
/* CLASS */
),
vue.createElementVNode("text", { class: "checkbox-text" }, "记住密码")
]),
vue.createElementVNode("text", { class: "forget-pwd" }, "忘记密码?")
]),
vue.createElementVNode("button", {
class: "login-btn",
disabled: $setup.loading,
loading: $setup.loading,
onClick: $setup.handleLogin
}, vue.toDisplayString($setup.loading ? "Loading..." : "登录"), 9, ["disabled", "loading"])
])
])
])
],
64
/* STABLE_FRAGMENT */
);
}
const PagesLoginLogin = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$9], ["__scopeId", "data-v-461d1d79"], ["__file", "D:/Projects/uniapp/app-test/test1/pages/Login/Login.vue"]]);
const fontData = [
{
"font_class": "arrow-down",
"unicode": ""
},
{
"font_class": "arrow-left",
"unicode": ""
},
{
"font_class": "arrow-right",
"unicode": ""
},
{
"font_class": "arrow-up",
"unicode": ""
},
{
"font_class": "auth",
"unicode": ""
},
{
"font_class": "auth-filled",
"unicode": ""
},
{
"font_class": "back",
"unicode": ""
},
{
"font_class": "bars",
"unicode": ""
},
{
"font_class": "calendar",
"unicode": ""
},
{
"font_class": "calendar-filled",
"unicode": ""
},
{
"font_class": "camera",
"unicode": ""
},
{
"font_class": "camera-filled",
"unicode": ""
},
{
"font_class": "cart",
"unicode": ""
},
{
"font_class": "cart-filled",
"unicode": ""
},
{
"font_class": "chat",
"unicode": ""
},
{
"font_class": "chat-filled",
"unicode": ""
},
{
"font_class": "chatboxes",
"unicode": ""
},
{
"font_class": "chatboxes-filled",
"unicode": ""
},
{
"font_class": "chatbubble",
"unicode": ""
},
{
"font_class": "chatbubble-filled",
"unicode": ""
},
{
"font_class": "checkbox",
"unicode": ""
},
{
"font_class": "checkbox-filled",
"unicode": ""
},
{
"font_class": "checkmarkempty",
"unicode": ""
},
{
"font_class": "circle",
"unicode": ""
},
{
"font_class": "circle-filled",
"unicode": ""
},
{
"font_class": "clear",
"unicode": ""
},
{
"font_class": "close",
"unicode": ""
},
{
"font_class": "closeempty",
"unicode": ""
},
{
"font_class": "cloud-download",
"unicode": ""
},
{
"font_class": "cloud-download-filled",
"unicode": ""
},
{
"font_class": "cloud-upload",
"unicode": ""
},
{
"font_class": "cloud-upload-filled",
"unicode": ""
},
{
"font_class": "color",
"unicode": ""
},
{
"font_class": "color-filled",
"unicode": ""
},
{
"font_class": "compose",
"unicode": ""
},
{
"font_class": "contact",
"unicode": ""
},
{
"font_class": "contact-filled",
"unicode": ""
},
{
"font_class": "down",
"unicode": ""
},
{
"font_class": "bottom",
"unicode": ""
},
{
"font_class": "download",
"unicode": ""
},
{
"font_class": "download-filled",
"unicode": ""
},
{
"font_class": "email",
"unicode": ""
},
{
"font_class": "email-filled",
"unicode": ""
},
{
"font_class": "eye",
"unicode": ""
},
{
"font_class": "eye-filled",
"unicode": ""
},
{
"font_class": "eye-slash",
"unicode": ""
},
{
"font_class": "eye-slash-filled",
"unicode": ""
},
{
"font_class": "fire",
"unicode": ""
},
{
"font_class": "fire-filled",
"unicode": ""
},
{
"font_class": "flag",
"unicode": ""
},
{
"font_class": "flag-filled",
"unicode": ""
},
{
"font_class": "folder-add",
"unicode": ""
},
{
"font_class": "folder-add-filled",
"unicode": ""
},
{
"font_class": "font",
"unicode": ""
},
{
"font_class": "forward",
"unicode": ""
},
{
"font_class": "gear",
"unicode": ""
},
{
"font_class": "gear-filled",
"unicode": ""
},
{
"font_class": "gift",
"unicode": ""
},
{
"font_class": "gift-filled",
"unicode": ""
},
{
"font_class": "hand-down",
"unicode": ""
},
{
"font_class": "hand-down-filled",
"unicode": ""
},
{
"font_class": "hand-up",
"unicode": ""
},
{
"font_class": "hand-up-filled",
"unicode": ""
},
{
"font_class": "headphones",
"unicode": ""
},
{
"font_class": "heart",
"unicode": ""
},
{
"font_class": "heart-filled",
"unicode": ""
},
{
"font_class": "help",
"unicode": ""
},
{
"font_class": "help-filled",
"unicode": ""
},
{
"font_class": "home",
"unicode": ""
},
{
"font_class": "home-filled",
"unicode": ""
},
{
"font_class": "image",
"unicode": ""
},
{
"font_class": "image-filled",
"unicode": ""
},
{
"font_class": "images",
"unicode": ""
},
{
"font_class": "images-filled",
"unicode": ""
},
{
"font_class": "info",
"unicode": ""
},
{
"font_class": "info-filled",
"unicode": ""
},
{
"font_class": "left",
"unicode": ""
},
{
"font_class": "link",
"unicode": ""
},
{
"font_class": "list",
"unicode": ""
},
{
"font_class": "location",
"unicode": ""
},
{
"font_class": "location-filled",
"unicode": ""
},
{
"font_class": "locked",
"unicode": ""
},
{
"font_class": "locked-filled",
"unicode": ""
},
{
"font_class": "loop",
"unicode": ""
},
{
"font_class": "mail-open",
"unicode": ""
},
{
"font_class": "mail-open-filled",
"unicode": ""
},
{
"font_class": "map",
"unicode": ""
},
{
"font_class": "map-filled",
"unicode": ""
},
{
"font_class": "map-pin",
"unicode": ""
},
{
"font_class": "map-pin-ellipse",
"unicode": ""
},
{
"font_class": "medal",
"unicode": ""
},
{
"font_class": "medal-filled",
"unicode": ""
},
{
"font_class": "mic",
"unicode": ""
},
{
"font_class": "mic-filled",
"unicode": ""
},
{
"font_class": "micoff",
"unicode": ""
},
{
"font_class": "micoff-filled",
"unicode": ""
},
{
"font_class": "minus",
"unicode": ""
},
{
"font_class": "minus-filled",
"unicode": ""
},
{
"font_class": "more",
"unicode": ""
},
{
"font_class": "more-filled",
"unicode": ""
},
{
"font_class": "navigate",
"unicode": ""
},
{
"font_class": "navigate-filled",
"unicode": ""
},
{
"font_class": "notification",
"unicode": ""
},
{
"font_class": "notification-filled",
"unicode": ""
},
{
"font_class": "paperclip",
"unicode": ""
},
{
"font_class": "paperplane",
"unicode": ""
},
{
"font_class": "paperplane-filled",
"unicode": ""
},
{
"font_class": "person",
"unicode": ""
},
{
"font_class": "person-filled",
"unicode": ""
},
{
"font_class": "personadd",
"unicode": ""
},
{
"font_class": "personadd-filled",
"unicode": ""
},
{
"font_class": "personadd-filled-copy",
"unicode": ""
},
{
"font_class": "phone",
"unicode": ""
},
{
"font_class": "phone-filled",
"unicode": ""
},
{
"font_class": "plus",
"unicode": ""
},
{
"font_class": "plus-filled",
"unicode": ""
},
{
"font_class": "plusempty",
"unicode": ""
},
{
"font_class": "pulldown",
"unicode": ""
},
{
"font_class": "pyq",
"unicode": ""
},
{
"font_class": "qq",
"unicode": ""
},
{
"font_class": "redo",
"unicode": ""
},
{
"font_class": "redo-filled",
"unicode": ""
},
{
"font_class": "refresh",
"unicode": ""
},
{
"font_class": "refresh-filled",
"unicode": ""
},
{
"font_class": "refreshempty",
"unicode": ""
},
{
"font_class": "reload",
"unicode": ""
},
{
"font_class": "right",
"unicode": ""
},
{
"font_class": "scan",
"unicode": ""
},
{
"font_class": "search",
"unicode": ""
},
{
"font_class": "settings",
"unicode": ""
},
{
"font_class": "settings-filled",
"unicode": ""
},
{
"font_class": "shop",
"unicode": ""
},
{
"font_class": "shop-filled",
"unicode": ""
},
{
"font_class": "smallcircle",
"unicode": ""
},
{
"font_class": "smallcircle-filled",
"unicode": ""
},
{
"font_class": "sound",
"unicode": ""
},
{
"font_class": "sound-filled",
"unicode": ""
},
{
"font_class": "spinner-cycle",
"unicode": ""
},
{
"font_class": "staff",
"unicode": ""
},
{
"font_class": "staff-filled",
"unicode": ""
},
{
"font_class": "star",
"unicode": ""
},
{
"font_class": "star-filled",
"unicode": ""
},
{
"font_class": "starhalf",
"unicode": ""
},
{
"font_class": "trash",
"unicode": ""
},
{
"font_class": "trash-filled",
"unicode": ""
},
{
"font_class": "tune",
"unicode": ""
},
{
"font_class": "tune-filled",
"unicode": ""
},
{
"font_class": "undo",
"unicode": ""
},
{
"font_class": "undo-filled",
"unicode": ""
},
{
"font_class": "up",
"unicode": ""
},
{
"font_class": "top",
"unicode": ""
},
{
"font_class": "upload",
"unicode": ""
},
{
"font_class": "upload-filled",
"unicode": ""
},
{
"font_class": "videocam",
"unicode": ""
},
{
"font_class": "videocam-filled",
"unicode": ""
},
{
"font_class": "vip",
"unicode": ""
},
{
"font_class": "vip-filled",
"unicode": ""
},
{
"font_class": "wallet",
"unicode": ""
},
{
"font_class": "wallet-filled",
"unicode": ""
},
{
"font_class": "weibo",
"unicode": ""
},
{
"font_class": "weixin",
"unicode": ""
}
];
const getVal = (val) => {
const reg = /^[0-9]*$/g;
return typeof val === "number" || reg.test(val) ? val + "px" : val;
};
const _sfc_main$9 = {
name: "UniIcons",
emits: ["click"],
props: {
type: {
type: String,
default: ""
},
color: {
type: String,
default: "#333333"
},
size: {
type: [Number, String],
default: 16
},
customPrefix: {
type: String,
default: ""
},
fontFamily: {
type: String,
default: ""
}
},
data() {
return {
icons: fontData
};
},
computed: {
unicode() {
let code = this.icons.find((v) => v.font_class === this.type);
if (code) {
return code.unicode;
}
return "";
},
iconSize() {
return getVal(this.size);
},
styleObj() {
if (this.fontFamily !== "") {
return `color: ${this.color}; font-size: ${this.iconSize}; font-family: ${this.fontFamily};`;
}
return `color: ${this.color}; font-size: ${this.iconSize};`;
}
},
methods: {
_onClick(e2) {
this.$emit("click", e2);
}
}
};
function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
return vue.openBlock(), vue.createElementBlock(
"text",
{
style: vue.normalizeStyle($options.styleObj),
class: vue.normalizeClass(["uni-icons", ["uniui-" + $props.type, $props.customPrefix, $props.customPrefix ? $props.type : ""]]),
onClick: _cache[0] || (_cache[0] = (...args) => $options._onClick && $options._onClick(...args))
},
[
vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
],
6
/* CLASS, STYLE */
);
}
const __easycom_0 = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$8], ["__scopeId", "data-v-d31e1c47"], ["__file", "D:/Projects/uniapp/app-test/test1/uni_modules/uni-icons/components/uni-icons/uni-icons.vue"]]);
const getToken = () => {
return uni.getStorageSync("token");
};
const getCurrentSessionId = () => {
const sessionId = uni.getStorageSync("currentSessionId");
if (!isNaN(Number(sessionId))) {
return sessionId;
}
return sessionId.replace(/-/g, "");
};
const getTaskCallId = () => {
return uni.getStorageSync("taskCallId");
};
const getUserId = () => {
formatAppLog("log", "at utils/user-info.js:50", "用户IdUserId", uni.getStorageSync("userId"));
return uni.getStorageSync("userId");
};
const getChatType = () => {
return uni.getStorageSync("chatType");
};
const getReceiverId = () => {
return uni.getStorageSync("receiverId");
};
const getWorkspaceId = () => {
return uni.getStorageSync("workspace_id");
};
const _sfc_main$8 = /* @__PURE__ */ Object.assign({
name: "ChatSidebar"
}, {
__name: "ChatSidebar",
props: {
chatList: {
type: Array,
required: true
},
showNewChatModal: {
type: Boolean,
default: false
},
currentSessionId: {
type: [String, Number],
required: true
},
chatType: {
type: Number,
required: true
}
},
emits: [
"update:showNewChatModal",
"update:currentSessionId",
"refresh-conversations",
"update:chatType"
],
setup(__props, { expose: __expose, emit: __emit }) {
__expose();
const props = __props;
const emit = __emit;
const UserConversations = vue.toRef(props, "chatList");
const showNewChatModal = vue.toRef(props, "showNewChatModal");
const chatType = vue.toRef(props, "chatType");
const openUserCardVisible = () => {
uni.navigateTo({
url: "/pages/UserProfileModal/UserProfileModal"
});
};
const isSelectMode = vue.ref(false);
const selectedHistoryIds = vue.ref([]);
const deleteConversations = () => {
if (selectedHistoryIds.value.length === 0)
return;
uni.showModal({
title: "确认删除",
content: `确定要删除全部 ${selectedHistoryIds.value.length} 个对话吗?此操作不可恢复。`,
confirmText: "确认删除",
confirmColor: "#ff0000",
success: async (res) => {
if (res.confirm) {
try {
const userToken = getToken();
await deleteConversation(userToken, selectedHistoryIds.value);
uni.showToast({
title: "删除成功",
icon: "success"
});
selectedHistoryIds.value = [];
isSelectMode.value = false;
emit("refresh-conversations");
} catch (error) {
formatAppLog("error", "at components/ChatSidebar.vue:209", "删除会话失败:", error);
uni.showToast({
title: "删除失败,请重试",
icon: "none"
});
}
}
}
});
};
const clearAllConversations = () => {
if (!UserConversations.value.length) {
uni.showToast({ title: "没有可删除的会话", icon: "none" });
return;
}
uni.showModal({
title: "确认删除",
content: `确定要删除全部 ${UserConversations.value.length} 个对话吗?此操作不可恢复。`,
confirmText: "删除全部",
confirmColor: "#ff0000",
success: async (res) => {
if (res.confirm) {
try {
const userToken = getToken();
const allIds = UserConversations.value.map((item) => item._id);
await deleteConversation(userToken, allIds);
uni.showToast({ title: "已删除全部对话", icon: "success" });
emit("refresh-conversations");
} catch (error) {
formatAppLog("error", "at components/ChatSidebar.vue:241", "清空全部对话失败:", error);
uni.showToast({ title: "删除失败,请重试", icon: "none" });
}
}
}
});
};
const isAllHistorySelected = vue.computed(() => {
return UserConversations.value.length > 0 && selectedHistoryIds.value.length === UserConversations.value.length;
});
const currentChatId = vue.toRef(props, "currentSessionId");
const selectChat = (chatId, receiverId = "") => {
formatAppLog("log", "at components/ChatSidebar.vue:259", "选择的id是", chatId);
if (receiverId) {
uni.setStorageSync("receiverId", receiverId);
}
uni.setStorageSync("currentSessionId", chatId);
emit("update:currentSessionId", chatId);
};
const openNewChatModal = () => {
formatAppLog("log", "at components/ChatSidebar.vue:270", "点击了新建会话");
emit("update:showNewChatModal", true);
};
const goContactPages = () => {
uni.navigateTo({
url: "/pages/ContactPages/ContactPages"
});
};
const chatHistoryQuery = vue.ref("");
const isHistorySearchFocused = vue.ref(false);
const toggleSelectMode = () => {
isSelectMode.value = !isSelectMode.value;
if (!isSelectMode.value) {
selectedHistoryIds.value = [];
}
};
const toggleHistorySelect = (chatId) => {
const index = selectedHistoryIds.value.indexOf(chatId);
if (index === -1) {
selectedHistoryIds.value.push(chatId);
} else {
selectedHistoryIds.value.splice(index, 1);
}
};
const toggleSelectAllHistory = () => {
if (isAllHistorySelected.value) {
selectedHistoryIds.value = [];
} else {
selectedHistoryIds.value = UserConversations.value.map((chat) => chat._id);
}
};
const UserToken = vue.ref("");
const UserAvatar = vue.ref("");
const UserName = vue.ref("");
vue.onMounted(async () => {
UserToken.value = getToken();
const UserInfo = await getUserInfo(UserToken.value);
UserAvatar.value = UserInfo.avatar || "";
UserName.value = UserInfo.username || "";
formatAppLog("log", "at components/ChatSidebar.vue:320", "菜单收到的会话列表:", UserConversations.value);
});
const __returned__ = { props, emit, UserConversations, showNewChatModal, chatType, openUserCardVisible, isSelectMode, selectedHistoryIds, deleteConversations, clearAllConversations, isAllHistorySelected, currentChatId, selectChat, openNewChatModal, goContactPages, chatHistoryQuery, isHistorySearchFocused, toggleSelectMode, toggleHistorySelect, toggleSelectAllHistory, UserToken, UserAvatar, UserName, computed: vue.computed, onMounted: vue.onMounted, onUnmounted: vue.onUnmounted, ref: vue.ref, toRef: vue.toRef, get deleteConversation() {
return deleteConversation;
}, get getToken() {
return getToken;
}, get getUserInfo() {
return getUserInfo;
} };
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
return __returned__;
}
});
function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
const _component_uni_icons = resolveEasycom(vue.resolveDynamicComponent("uni-icons"), __easycom_0);
return vue.openBlock(), vue.createElementBlock("view", { class: "chat-sidebar-container" }, [
vue.createElementVNode("view", { class: "status-bar" }),
vue.createElementVNode("view", { class: "sidebar-header" }, [
vue.createElementVNode("view", {
class: "user-profile-card",
onClick: $setup.openUserCardVisible
}, [
vue.createElementVNode("view", { class: "left" }, [
$setup.UserAvatar ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "avatar-preview"
}, [
vue.createElementVNode("image", {
src: $setup.UserAvatar,
mode: "aspectFill"
}, null, 8, ["src"])
])) : (vue.openBlock(), vue.createElementBlock("view", {
key: 1,
class: "avatar-placeholder"
}, [
vue.createVNode(_component_uni_icons, {
type: "contact-filled",
size: "50",
color: "#007aff"
})
]))
]),
vue.createElementVNode("view", { class: "center" }, [
vue.createElementVNode("text", null, "欢迎回来"),
vue.createElementVNode(
"text",
null,
vue.toDisplayString($setup.UserName),
1
/* TEXT */
)
]),
vue.createElementVNode("view", { class: "right" }, [
vue.createElementVNode("view", { class: "status-dot" }),
vue.createElementVNode("view", { class: "status-text" }, [
vue.createElementVNode("text", null, "在线")
])
])
]),
vue.createElementVNode("view", {
class: "new-chat-btn",
onClick: $setup.goContactPages
}, [
vue.createElementVNode("text", null, "+ 聊天列表")
])
]),
vue.createElementVNode("view", { class: "chat-history" }, [
vue.createElementVNode("view", { class: "history-header" }, [
vue.createElementVNode("view", { class: "history-title-section" }, [
vue.createElementVNode("text", null, "历史会话"),
vue.createElementVNode(
"text",
null,
vue.toDisplayString($setup.UserConversations.length) + "个对话",
1
/* TEXT */
)
]),
vue.createElementVNode("view", { class: "history-management" }, [
!$setup.isSelectMode ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "history-management-btn iconfont icon-jia icon-jia-style",
onClick: $setup.openNewChatModal
})) : vue.createCommentVNode("v-if", true),
!$setup.isSelectMode ? (vue.openBlock(), vue.createElementBlock("view", {
key: 1,
class: "history-management-btn iconfont icon-duoxuan icon-duoxuan-style",
onClick: $setup.toggleSelectMode
})) : vue.createCommentVNode("v-if", true),
!$setup.isSelectMode ? (vue.openBlock(), vue.createElementBlock("view", {
key: 2,
class: "history-management-btn iconfont icon-saochu icon-saochu-style",
onClick: $setup.clearAllConversations
})) : vue.createCommentVNode("v-if", true),
$setup.isSelectMode && $setup.selectedHistoryIds.length > 0 ? (vue.openBlock(), vue.createElementBlock("view", {
key: 3,
class: "history-management-btn iconfont icon-shanchu icon-shanchu-style",
onClick: $setup.deleteConversations
})) : vue.createCommentVNode("v-if", true),
$setup.isSelectMode ? (vue.openBlock(), vue.createElementBlock(
"view",
{
key: 4,
class: vue.normalizeClass(["history-management-btn iconfont icon-total_selection icon-total_selection-style", { active: $setup.isAllHistorySelected }]),
onClick: $setup.toggleSelectAllHistory
},
null,
2
/* CLASS */
)) : vue.createCommentVNode("v-if", true),
$setup.isSelectMode ? (vue.openBlock(), vue.createElementBlock("view", {
key: 5,
class: "history-management-btn iconfont icon-quxiao icon-quxiao-style",
onClick: $setup.toggleSelectMode
})) : vue.createCommentVNode("v-if", true)
])
]),
!$setup.isSelectMode ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "history-search-wrap"
}, [
vue.createElementVNode(
"view",
{
class: vue.normalizeClass(["history-search-inner", { "has-value": $setup.chatHistoryQuery || $setup.isHistorySearchFocused }])
},
[
vue.createVNode(_component_uni_icons, {
type: "search",
class: vue.normalizeClass([$setup.chatHistoryQuery || $setup.isHistorySearchFocused ? "chat-search-icon" : "search-icon"])
}, null, 8, ["class"]),
vue.withDirectives(vue.createElementVNode(
"input",
{
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.chatHistoryQuery = $event),
onFocus: _cache[1] || (_cache[1] = ($event) => $setup.isHistorySearchFocused = true),
onBlur: _cache[2] || (_cache[2] = ($event) => $setup.isHistorySearchFocused = false),
type: "text",
placeholder: "搜索会话..."
},
null,
544
/* NEED_HYDRATION, NEED_PATCH */
), [
[vue.vModelText, $setup.chatHistoryQuery]
])
],
2
/* CLASS */
)
])) : vue.createCommentVNode("v-if", true),
vue.createElementVNode("view", { class: "chat-history-list" }, [
$setup.chatType === 0 ? (vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
{ key: 0 },
vue.renderList($setup.UserConversations, (chat) => {
return vue.openBlock(), vue.createElementBlock("view", {
key: chat._id,
"data-chat-id": chat._id,
class: vue.normalizeClass(["chat-history-card", { "is-select-chat": $setup.currentChatId === chat._id || $setup.selectedHistoryIds.includes(chat._id) }]),
onClick: ($event) => $setup.isSelectMode ? $setup.toggleHistorySelect(chat._id) : $setup.selectChat(chat._id)
}, [
$setup.isSelectMode ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "history-chat-checkbox"
}, [
$setup.selectedHistoryIds.includes(chat._id) ? (vue.openBlock(), vue.createBlock(_component_uni_icons, {
key: 0,
type: "checkmarkempty",
size: "20",
color: "#007aff"
})) : vue.createCommentVNode("v-if", true)
])) : vue.createCommentVNode("v-if", true),
vue.createElementVNode("view", { class: "history-chat-avatar" }, [
vue.createVNode(_component_uni_icons, {
type: "chat-filled",
size: "26",
color: "#007aff"
})
]),
chat.agent_id ? (vue.openBlock(), vue.createElementBlock(
"view",
{ key: 1 },
vue.toDisplayString(chat.agent_data.title),
1
/* TEXT */
)) : (vue.openBlock(), vue.createElementBlock(
"view",
{ key: 2 },
vue.toDisplayString(chat.title),
1
/* TEXT */
))
], 10, ["data-chat-id", "onClick"]);
}),
128
/* KEYED_FRAGMENT */
)) : vue.createCommentVNode("v-if", true),
$setup.chatType === 1 ? (vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
{ key: 1 },
vue.renderList($setup.UserConversations, (chat) => {
return vue.openBlock(), vue.createElementBlock("view", {
key: chat.sessionId,
"data-chat-id": chat.sessionId,
class: vue.normalizeClass(["chat-history-card", { "is-select-chat": $setup.currentChatId === chat.sessionId || $setup.selectedHistoryIds.includes(chat.sessionId) }]),
onClick: ($event) => $setup.isSelectMode ? $setup.toggleHistorySelect(chat.sessionId) : $setup.selectChat(chat.sessionId, chat.receiver)
}, [
$setup.isSelectMode ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "history-chat-checkbox"
}, [
$setup.selectedHistoryIds.includes(chat.sessionId) ? (vue.openBlock(), vue.createBlock(_component_uni_icons, {
key: 0,
type: "checkmarkempty",
size: "20",
color: "#007aff"
})) : vue.createCommentVNode("v-if", true)
])) : vue.createCommentVNode("v-if", true),
vue.createElementVNode("view", { class: "history-chat-avatar" }, [
chat.avatar ? (vue.openBlock(), vue.createElementBlock("image", {
key: 0,
src: chat.avatar,
class: "friend-avatar",
mode: "aspectFill"
}, null, 8, ["src"])) : vue.createCommentVNode("v-if", true)
]),
vue.createElementVNode(
"view",
null,
vue.toDisplayString(chat.friendNickName),
1
/* TEXT */
)
], 10, ["data-chat-id", "onClick"]);
}),
128
/* KEYED_FRAGMENT */
)) : vue.createCommentVNode("v-if", true),
$setup.chatType === 2 ? (vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
{ key: 2 },
vue.renderList($setup.UserConversations, (chat) => {
return vue.openBlock(), vue.createElementBlock("view", {
key: chat.id,
"data-chat-id": chat.id,
class: vue.normalizeClass(["chat-history-card", { "is-select-chat": $setup.currentChatId === chat.id || $setup.selectedHistoryIds.includes(chat.id) }]),
onClick: ($event) => $setup.isSelectMode ? $setup.toggleHistorySelect(chat.id) : $setup.selectChat(chat.id)
}, [
$setup.isSelectMode ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "history-chat-checkbox"
}, [
$setup.selectedHistoryIds.includes(chat.id) ? (vue.openBlock(), vue.createBlock(_component_uni_icons, {
key: 0,
type: "checkmarkempty",
size: "20",
color: "#007aff"
})) : vue.createCommentVNode("v-if", true)
])) : vue.createCommentVNode("v-if", true),
vue.createElementVNode("view", { class: "history-chat-avatar" }, [
vue.createElementVNode("view", {
class: "iconfont icon-qunliao",
style: { "font-size": "80rpx", "color": "#fff" }
})
]),
vue.createElementVNode(
"view",
null,
vue.toDisplayString(chat.name),
1
/* TEXT */
)
], 10, ["data-chat-id", "onClick"]);
}),
128
/* KEYED_FRAGMENT */
)) : vue.createCommentVNode("v-if", true)
])
])
]);
}
const ChatSidebar = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$7], ["__scopeId", "data-v-0c6c7315"], ["__file", "D:/Projects/uniapp/app-test/test1/components/ChatSidebar.vue"]]);
var e = { "": ["<em>", "</em>"], _: ["<strong>", "</strong>"], "*": ["<strong>", "</strong>"], "~": ["<s>", "</s>"], "\n": ["<br />"], " ": ["<br />"], "-": ["<hr />"] };
function n(e2) {
return e2.replace(RegExp("^" + (e2.match(/^(\t| )+/) || "")[0], "gm"), "");
}
function r(e2) {
return (e2 + "").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
}
function t(a, c) {
var o, l, g, s, p, u = /((?:^|\n+)(?:\n---+|\* \*(?: \*)+)\n)|(?:^``` *(\w*)\n([\s\S]*?)\n```$)|((?:(?:^|\n+)(?:\t| {2,}).+)+\n*)|((?:(?:^|\n)([>*+-]|\d+\.)\s+.*)+)|(?:!\[([^\]]*?)\]\(([^)]+?)\))|(\[)|(\](?:\(([^)]+?)\))?)|(?:(?:^|\n+)([^\s].*)\n(-{3,}|={3,})(?:\n+|$))|(?:(?:^|\n+)(#{1,6})\s*(.+)(?:\n+|$))|(?:`([^`].*?)`)|( \n\n*|\n{2,}|__|\*\*|[_*]|~~)/gm, m = [], h = "", i = c || {}, d = 0;
function f(n2) {
var r2 = e[n2[1] || ""], t2 = m[m.length - 1] == n2;
return r2 ? r2[1] ? (t2 ? m.pop() : m.push(n2), r2[0 | t2]) : r2[0] : n2;
}
function $() {
for (var e2 = ""; m.length; )
e2 += f(m[m.length - 1]);
return e2;
}
for (a = a.replace(/^\[(.+?)\]:\s*(.+)$/gm, function(e2, n2, r2) {
return i[n2.toLowerCase()] = r2, "";
}).replace(/^\n+|\n+$/g, ""); g = u.exec(a); )
l = a.substring(d, g.index), d = u.lastIndex, o = g[0], l.match(/[^\\](\\\\)*\\$/) || ((p = g[3] || g[4]) ? o = '<pre class="code ' + (g[4] ? "poetry" : g[2].toLowerCase()) + '"><code' + (g[2] ? ' class="language-' + g[2].toLowerCase() + '"' : "") + ">" + n(r(p).replace(/^\n+|\n+$/g, "")) + "</code></pre>" : (p = g[6]) ? (p.match(/\./) && (g[5] = g[5].replace(/^\d+/gm, "")), s = t(n(g[5].replace(/^\s*[>*+.-]/gm, ""))), ">" == p ? p = "blockquote" : (p = p.match(/\./) ? "ol" : "ul", s = s.replace(/^(.*)(\n|$)/gm, "<li>$1</li>")), o = "<" + p + ">" + s + "</" + p + ">") : g[8] ? o = '<img src="' + r(g[8]) + '" alt="' + r(g[7]) + '">' : g[10] ? (h = h.replace("<a>", '<a href="' + r(g[11] || i[l.toLowerCase()]) + '">'), o = $() + "</a>") : g[9] ? o = "<a>" : g[12] || g[14] ? o = "<" + (p = "h" + (g[14] ? g[14].length : g[13] > "=" ? 1 : 2)) + ">" + t(g[12] || g[15], i) + "</" + p + ">" : g[16] ? o = "<code>" + r(g[16]) + "</code>" : (g[17] || g[1]) && (o = f(g[17] || "--"))), h += l, h += o;
return (h + a.substring(d) + $()).replace(/^\n+|\n+$/g, "");
}
var isVue2 = false;
function set(target, key, val) {
if (Array.isArray(target)) {
target.length = Math.max(target.length, key);
target.splice(key, 1, val);
return val;
}
target[key] = val;
return val;
}
function del(target, key) {
if (Array.isArray(target)) {
target.splice(key, 1);
return;
}
delete target[key];
}
function getDevtoolsGlobalHook() {
return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__;
}
function getTarget() {
return typeof navigator !== "undefined" && typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {};
}
const isProxyAvailable = typeof Proxy === "function";
const HOOK_SETUP = "devtools-plugin:setup";
const HOOK_PLUGIN_SETTINGS_SET = "plugin:settings:set";
let supported;
let perf;
function isPerformanceSupported() {
var _a;
if (supported !== void 0) {
return supported;
}
if (typeof window !== "undefined" && window.performance) {
supported = true;
perf = window.performance;
} else if (typeof global !== "undefined" && ((_a = global.perf_hooks) === null || _a === void 0 ? void 0 : _a.performance)) {
supported = true;
perf = global.perf_hooks.performance;
} else {
supported = false;
}
return supported;
}
function now() {
return isPerformanceSupported() ? perf.now() : Date.now();
}
class ApiProxy {
constructor(plugin, hook) {
this.target = null;
this.targetQueue = [];
this.onQueue = [];
this.plugin = plugin;
this.hook = hook;
const defaultSettings = {};
if (plugin.settings) {
for (const id in plugin.settings) {
const item = plugin.settings[id];
defaultSettings[id] = item.defaultValue;
}
}
const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`;
let currentSettings = Object.assign({}, defaultSettings);
try {
const raw = localStorage.getItem(localSettingsSaveId);
const data = JSON.parse(raw);
Object.assign(currentSettings, data);
} catch (e2) {
}
this.fallbacks = {
getSettings() {
return currentSettings;
},
setSettings(value) {
try {
localStorage.setItem(localSettingsSaveId, JSON.stringify(value));
} catch (e2) {
}
currentSettings = value;
},
now() {
return now();
}
};
if (hook) {
hook.on(HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => {
if (pluginId === this.plugin.id) {
this.fallbacks.setSettings(value);
}
});
}
this.proxiedOn = new Proxy({}, {
get: (_target, prop) => {
if (this.target) {
return this.target.on[prop];
} else {
return (...args) => {
this.onQueue.push({
method: prop,
args
});
};
}
}
});
this.proxiedTarget = new Proxy({}, {
get: (_target, prop) => {
if (this.target) {
return this.target[prop];
} else if (prop === "on") {
return this.proxiedOn;
} else if (Object.keys(this.fallbacks).includes(prop)) {
return (...args) => {
this.targetQueue.push({
method: prop,
args,
resolve: () => {
}
});
return this.fallbacks[prop](...args);
};
} else {
return (...args) => {
return new Promise((resolve) => {
this.targetQueue.push({
method: prop,
args,
resolve
});
});
};
}
}
});
}
async setRealTarget(target) {
this.target = target;
for (const item of this.onQueue) {
this.target.on[item.method](...item.args);
}
for (const item of this.targetQueue) {
item.resolve(await this.target[item.method](...item.args));
}
}
}
function setupDevtoolsPlugin(pluginDescriptor, setupFn) {
const descriptor = pluginDescriptor;
const target = getTarget();
const hook = getDevtoolsGlobalHook();
const enableProxy = isProxyAvailable && descriptor.enableEarlyProxy;
if (hook && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) {
hook.emit(HOOK_SETUP, pluginDescriptor, setupFn);
} else {
const proxy = enableProxy ? new ApiProxy(descriptor, hook) : null;
const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || [];
list.push({
pluginDescriptor: descriptor,
setupFn,
proxy
});
if (proxy)
setupFn(proxy.proxiedTarget);
}
}
/*!
* pinia v2.1.7
* (c) 2023 Eduardo San Martin Morote
* @license MIT
*/
let activePinia;
const setActivePinia = (pinia) => activePinia = pinia;
const piniaSymbol = Symbol("pinia");
function isPlainObject(o) {
return o && typeof o === "object" && Object.prototype.toString.call(o) === "[object Object]" && typeof o.toJSON !== "function";
}
var MutationType;
(function(MutationType2) {
MutationType2["direct"] = "direct";
MutationType2["patchObject"] = "patch object";
MutationType2["patchFunction"] = "patch function";
})(MutationType || (MutationType = {}));
const IS_CLIENT = typeof window !== "undefined";
const USE_DEVTOOLS = IS_CLIENT;
const _global = /* @__PURE__ */ (() => typeof window === "object" && window.window === window ? window : typeof self === "object" && self.self === self ? self : typeof global === "object" && global.global === global ? global : typeof globalThis === "object" ? globalThis : { HTMLElement: null })();
function bom(blob, { autoBom = false } = {}) {
if (autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
return new Blob([String.fromCharCode(65279), blob], { type: blob.type });
}
return blob;
}
function download(url, name2, opts) {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.responseType = "blob";
xhr.onload = function() {
saveAs(xhr.response, name2, opts);
};
xhr.onerror = function() {
console.error("could not download file");
};
xhr.send();
}
function corsEnabled(url) {
const xhr = new XMLHttpRequest();
xhr.open("HEAD", url, false);
try {
xhr.send();
} catch (e2) {
}
return xhr.status >= 200 && xhr.status <= 299;
}
function click(node) {
try {
node.dispatchEvent(new MouseEvent("click"));
} catch (e2) {
const evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
node.dispatchEvent(evt);
}
}
const _navigator = typeof navigator === "object" ? navigator : { userAgent: "" };
const isMacOSWebView = /* @__PURE__ */ (() => /Macintosh/.test(_navigator.userAgent) && /AppleWebKit/.test(_navigator.userAgent) && !/Safari/.test(_navigator.userAgent))();
const saveAs = !IS_CLIENT ? () => {
} : (
// Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView or mini program
typeof HTMLAnchorElement !== "undefined" && "download" in HTMLAnchorElement.prototype && !isMacOSWebView ? downloadSaveAs : (
// Use msSaveOrOpenBlob as a second approach
"msSaveOrOpenBlob" in _navigator ? msSaveAs : (
// Fallback to using FileReader and a popup
fileSaverSaveAs
)
)
);
function downloadSaveAs(blob, name2 = "download", opts) {
const a = document.createElement("a");
a.download = name2;
a.rel = "noopener";
if (typeof blob === "string") {
a.href = blob;
if (a.origin !== location.origin) {
if (corsEnabled(a.href)) {
download(blob, name2, opts);
} else {
a.target = "_blank";
click(a);
}
} else {
click(a);
}
} else {
a.href = URL.createObjectURL(blob);
setTimeout(function() {
URL.revokeObjectURL(a.href);
}, 4e4);
setTimeout(function() {
click(a);
}, 0);
}
}
function msSaveAs(blob, name2 = "download", opts) {
if (typeof blob === "string") {
if (corsEnabled(blob)) {
download(blob, name2, opts);
} else {
const a = document.createElement("a");
a.href = blob;
a.target = "_blank";
setTimeout(function() {
click(a);
});
}
} else {
navigator.msSaveOrOpenBlob(bom(blob, opts), name2);
}
}
function fileSaverSaveAs(blob, name2, opts, popup) {
popup = popup || open("", "_blank");
if (popup) {
popup.document.title = popup.document.body.innerText = "downloading...";
}
if (typeof blob === "string")
return download(blob, name2, opts);
const force = blob.type === "application/octet-stream";
const isSafari = /constructor/i.test(String(_global.HTMLElement)) || "safari" in _global;
const isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);
if ((isChromeIOS || force && isSafari || isMacOSWebView) && typeof FileReader !== "undefined") {
const reader = new FileReader();
reader.onloadend = function() {
let url = reader.result;
if (typeof url !== "string") {
popup = null;
throw new Error("Wrong reader.result type");
}
url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, "data:attachment/file;");
if (popup) {
popup.location.href = url;
} else {
location.assign(url);
}
popup = null;
};
reader.readAsDataURL(blob);
} else {
const url = URL.createObjectURL(blob);
if (popup)
popup.location.assign(url);
else
location.href = url;
popup = null;
setTimeout(function() {
URL.revokeObjectURL(url);
}, 4e4);
}
}
function toastMessage(message, type) {
const piniaMessage = "🍍 " + message;
if (typeof __VUE_DEVTOOLS_TOAST__ === "function") {
__VUE_DEVTOOLS_TOAST__(piniaMessage, type);
} else if (type === "error") {
console.error(piniaMessage);
} else if (type === "warn") {
console.warn(piniaMessage);
} else {
console.log(piniaMessage);
}
}
function isPinia(o) {
return "_a" in o && "install" in o;
}
function checkClipboardAccess() {
if (!("clipboard" in navigator)) {
toastMessage(`Your browser doesn't support the Clipboard API`, "error");
return true;
}
}
function checkNotFocusedError(error) {
if (error instanceof Error && error.message.toLowerCase().includes("document is not focused")) {
toastMessage('You need to activate the "Emulate a focused page" setting in the "Rendering" panel of devtools.', "warn");
return true;
}
return false;
}
async function actionGlobalCopyState(pinia) {
if (checkClipboardAccess())
return;
try {
await navigator.clipboard.writeText(JSON.stringify(pinia.state.value));
toastMessage("Global state copied to clipboard.");
} catch (error) {
if (checkNotFocusedError(error))
return;
toastMessage(`Failed to serialize the state. Check the console for more details.`, "error");
console.error(error);
}
}
async function actionGlobalPasteState(pinia) {
if (checkClipboardAccess())
return;
try {
loadStoresState(pinia, JSON.parse(await navigator.clipboard.readText()));
toastMessage("Global state pasted from clipboard.");
} catch (error) {
if (checkNotFocusedError(error))
return;
toastMessage(`Failed to deserialize the state from clipboard. Check the console for more details.`, "error");
console.error(error);
}
}
async function actionGlobalSaveState(pinia) {
try {
saveAs(new Blob([JSON.stringify(pinia.state.value)], {
type: "text/plain;charset=utf-8"
}), "pinia-state.json");
} catch (error) {
toastMessage(`Failed to export the state as JSON. Check the console for more details.`, "error");
console.error(error);
}
}
let fileInput;
function getFileOpener() {
if (!fileInput) {
fileInput = document.createElement("input");
fileInput.type = "file";
fileInput.accept = ".json";
}
function openFile() {
return new Promise((resolve, reject) => {
fileInput.onchange = async () => {
const files = fileInput.files;
if (!files)
return resolve(null);
const file = files.item(0);
if (!file)
return resolve(null);
return resolve({ text: await file.text(), file });
};
fileInput.oncancel = () => resolve(null);
fileInput.onerror = reject;
fileInput.click();
});
}
return openFile;
}
async function actionGlobalOpenStateFile(pinia) {
try {
const open2 = getFileOpener();
const result = await open2();
if (!result)
return;
const { text, file } = result;
loadStoresState(pinia, JSON.parse(text));
toastMessage(`Global state imported from "${file.name}".`);
} catch (error) {
toastMessage(`Failed to import the state from JSON. Check the console for more details.`, "error");
console.error(error);
}
}
function loadStoresState(pinia, state) {
for (const key in state) {
const storeState = pinia.state.value[key];
if (storeState) {
Object.assign(storeState, state[key]);
} else {
pinia.state.value[key] = state[key];
}
}
}
function formatDisplay(display) {
return {
_custom: {
display
}
};
}
const PINIA_ROOT_LABEL = "🍍 Pinia (root)";
const PINIA_ROOT_ID = "_root";
function formatStoreForInspectorTree(store) {
return isPinia(store) ? {
id: PINIA_ROOT_ID,
label: PINIA_ROOT_LABEL
} : {
id: store.$id,
label: store.$id
};
}
function formatStoreForInspectorState(store) {
if (isPinia(store)) {
const storeNames = Array.from(store._s.keys());
const storeMap = store._s;
const state2 = {
state: storeNames.map((storeId) => ({
editable: true,
key: storeId,
value: store.state.value[storeId]
})),
getters: storeNames.filter((id) => storeMap.get(id)._getters).map((id) => {
const store2 = storeMap.get(id);
return {
editable: false,
key: id,
value: store2._getters.reduce((getters, key) => {
getters[key] = store2[key];
return getters;
}, {})
};
})
};
return state2;
}
const state = {
state: Object.keys(store.$state).map((key) => ({
editable: true,
key,
value: store.$state[key]
}))
};
if (store._getters && store._getters.length) {
state.getters = store._getters.map((getterName) => ({
editable: false,
key: getterName,
value: store[getterName]
}));
}
if (store._customProperties.size) {
state.customProperties = Array.from(store._customProperties).map((key) => ({
editable: true,
key,
value: store[key]
}));
}
return state;
}
function formatEventData(events) {
if (!events)
return {};
if (Array.isArray(events)) {
return events.reduce((data, event) => {
data.keys.push(event.key);
data.operations.push(event.type);
data.oldValue[event.key] = event.oldValue;
data.newValue[event.key] = event.newValue;
return data;
}, {
oldValue: {},
keys: [],
operations: [],
newValue: {}
});
} else {
return {
operation: formatDisplay(events.type),
key: formatDisplay(events.key),
oldValue: events.oldValue,
newValue: events.newValue
};
}
}
function formatMutationType(type) {
switch (type) {
case MutationType.direct:
return "mutation";
case MutationType.patchFunction:
return "$patch";
case MutationType.patchObject:
return "$patch";
default:
return "unknown";
}
}
let isTimelineActive = true;
const componentStateTypes = [];
const MUTATIONS_LAYER_ID = "pinia:mutations";
const INSPECTOR_ID = "pinia";
const { assign: assign$1 } = Object;
const getStoreType = (id) => "🍍 " + id;
function registerPiniaDevtools(app, pinia) {
setupDevtoolsPlugin({
id: "dev.esm.pinia",
label: "Pinia 🍍",
logo: "https://pinia.vuejs.org/logo.svg",
packageName: "pinia",
homepage: "https://pinia.vuejs.org",
componentStateTypes,
app
}, (api) => {
if (typeof api.now !== "function") {
toastMessage("You seem to be using an outdated version of Vue Devtools. Are you still using the Beta release instead of the stable one? You can find the links at https://devtools.vuejs.org/guide/installation.html.");
}
api.addTimelineLayer({
id: MUTATIONS_LAYER_ID,
label: `Pinia 🍍`,
color: 15064968
});
api.addInspector({
id: INSPECTOR_ID,
label: "Pinia 🍍",
icon: "storage",
treeFilterPlaceholder: "Search stores",
actions: [
{
icon: "content_copy",
action: () => {
actionGlobalCopyState(pinia);
},
tooltip: "Serialize and copy the state"
},
{
icon: "content_paste",
action: async () => {
await actionGlobalPasteState(pinia);
api.sendInspectorTree(INSPECTOR_ID);
api.sendInspectorState(INSPECTOR_ID);
},
tooltip: "Replace the state with the content of your clipboard"
},
{
icon: "save",
action: () => {
actionGlobalSaveState(pinia);
},
tooltip: "Save the state as a JSON file"
},
{
icon: "folder_open",
action: async () => {
await actionGlobalOpenStateFile(pinia);
api.sendInspectorTree(INSPECTOR_ID);
api.sendInspectorState(INSPECTOR_ID);
},
tooltip: "Import the state from a JSON file"
}
],
nodeActions: [
{
icon: "restore",
tooltip: 'Reset the state (with "$reset")',
action: (nodeId) => {
const store = pinia._s.get(nodeId);
if (!store) {
toastMessage(`Cannot reset "${nodeId}" store because it wasn't found.`, "warn");
} else if (typeof store.$reset !== "function") {
toastMessage(`Cannot reset "${nodeId}" store because it doesn't have a "$reset" method implemented.`, "warn");
} else {
store.$reset();
toastMessage(`Store "${nodeId}" reset.`);
}
}
}
]
});
api.on.inspectComponent((payload, ctx) => {
const proxy = payload.componentInstance && payload.componentInstance.proxy;
if (proxy && proxy._pStores) {
const piniaStores = payload.componentInstance.proxy._pStores;
Object.values(piniaStores).forEach((store) => {
payload.instanceData.state.push({
type: getStoreType(store.$id),
key: "state",
editable: true,
value: store._isOptionsAPI ? {
_custom: {
value: vue.toRaw(store.$state),
actions: [
{
icon: "restore",
tooltip: "Reset the state of this store",
action: () => store.$reset()
}
]
}
} : (
// NOTE: workaround to unwrap transferred refs
Object.keys(store.$state).reduce((state, key) => {
state[key] = store.$state[key];
return state;
}, {})
)
});
if (store._getters && store._getters.length) {
payload.instanceData.state.push({
type: getStoreType(store.$id),
key: "getters",
editable: false,
value: store._getters.reduce((getters, key) => {
try {
getters[key] = store[key];
} catch (error) {
getters[key] = error;
}
return getters;
}, {})
});
}
});
}
});
api.on.getInspectorTree((payload) => {
if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
let stores = [pinia];
stores = stores.concat(Array.from(pinia._s.values()));
payload.rootNodes = (payload.filter ? stores.filter((store) => "$id" in store ? store.$id.toLowerCase().includes(payload.filter.toLowerCase()) : PINIA_ROOT_LABEL.toLowerCase().includes(payload.filter.toLowerCase())) : stores).map(formatStoreForInspectorTree);
}
});
api.on.getInspectorState((payload) => {
if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
const inspectedStore = payload.nodeId === PINIA_ROOT_ID ? pinia : pinia._s.get(payload.nodeId);
if (!inspectedStore) {
return;
}
if (inspectedStore) {
payload.state = formatStoreForInspectorState(inspectedStore);
}
}
});
api.on.editInspectorState((payload, ctx) => {
if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
const inspectedStore = payload.nodeId === PINIA_ROOT_ID ? pinia : pinia._s.get(payload.nodeId);
if (!inspectedStore) {
return toastMessage(`store "${payload.nodeId}" not found`, "error");
}
const { path } = payload;
if (!isPinia(inspectedStore)) {
if (path.length !== 1 || !inspectedStore._customProperties.has(path[0]) || path[0] in inspectedStore.$state) {
path.unshift("$state");
}
} else {
path.unshift("state");
}
isTimelineActive = false;
payload.set(inspectedStore, path, payload.state.value);
isTimelineActive = true;
}
});
api.on.editComponentState((payload) => {
if (payload.type.startsWith("🍍")) {
const storeId = payload.type.replace(/^🍍\s*/, "");
const store = pinia._s.get(storeId);
if (!store) {
return toastMessage(`store "${storeId}" not found`, "error");
}
const { path } = payload;
if (path[0] !== "state") {
return toastMessage(`Invalid path for store "${storeId}":
${path}
Only state can be modified.`);
}
path[0] = "$state";
isTimelineActive = false;
payload.set(store, path, payload.state.value);
isTimelineActive = true;
}
});
});
}
function addStoreToDevtools(app, store) {
if (!componentStateTypes.includes(getStoreType(store.$id))) {
componentStateTypes.push(getStoreType(store.$id));
}
setupDevtoolsPlugin({
id: "dev.esm.pinia",
label: "Pinia 🍍",
logo: "https://pinia.vuejs.org/logo.svg",
packageName: "pinia",
homepage: "https://pinia.vuejs.org",
componentStateTypes,
app,
settings: {
logStoreChanges: {
label: "Notify about new/deleted stores",
type: "boolean",
defaultValue: true
}
// useEmojis: {
// label: 'Use emojis in messages ⚡️',
// type: 'boolean',
// defaultValue: true,
// },
}
}, (api) => {
const now2 = typeof api.now === "function" ? api.now.bind(api) : Date.now;
store.$onAction(({ after, onError, name: name2, args }) => {
const groupId = runningActionId++;
api.addTimelineEvent({
layerId: MUTATIONS_LAYER_ID,
event: {
time: now2(),
title: "🛫 " + name2,
subtitle: "start",
data: {
store: formatDisplay(store.$id),
action: formatDisplay(name2),
args
},
groupId
}
});
after((result) => {
activeAction = void 0;
api.addTimelineEvent({
layerId: MUTATIONS_LAYER_ID,
event: {
time: now2(),
title: "🛬 " + name2,
subtitle: "end",
data: {
store: formatDisplay(store.$id),
action: formatDisplay(name2),
args,
result
},
groupId
}
});
});
onError((error) => {
activeAction = void 0;
api.addTimelineEvent({
layerId: MUTATIONS_LAYER_ID,
event: {
time: now2(),
logType: "error",
title: "💥 " + name2,
subtitle: "end",
data: {
store: formatDisplay(store.$id),
action: formatDisplay(name2),
args,
error
},
groupId
}
});
});
}, true);
store._customProperties.forEach((name2) => {
vue.watch(() => vue.unref(store[name2]), (newValue, oldValue) => {
api.notifyComponentUpdate();
api.sendInspectorState(INSPECTOR_ID);
if (isTimelineActive) {
api.addTimelineEvent({
layerId: MUTATIONS_LAYER_ID,
event: {
time: now2(),
title: "Change",
subtitle: name2,
data: {
newValue,
oldValue
},
groupId: activeAction
}
});
}
}, { deep: true });
});
store.$subscribe(({ events, type }, state) => {
api.notifyComponentUpdate();
api.sendInspectorState(INSPECTOR_ID);
if (!isTimelineActive)
return;
const eventData = {
time: now2(),
title: formatMutationType(type),
data: assign$1({ store: formatDisplay(store.$id) }, formatEventData(events)),
groupId: activeAction
};
if (type === MutationType.patchFunction) {
eventData.subtitle = "⤵️";
} else if (type === MutationType.patchObject) {
eventData.subtitle = "🧩";
} else if (events && !Array.isArray(events)) {
eventData.subtitle = events.type;
}
if (events) {
eventData.data["rawEvent(s)"] = {
_custom: {
display: "DebuggerEvent",
type: "object",
tooltip: "raw DebuggerEvent[]",
value: events
}
};
}
api.addTimelineEvent({
layerId: MUTATIONS_LAYER_ID,
event: eventData
});
}, { detached: true, flush: "sync" });
const hotUpdate = store._hotUpdate;
store._hotUpdate = vue.markRaw((newStore) => {
hotUpdate(newStore);
api.addTimelineEvent({
layerId: MUTATIONS_LAYER_ID,
event: {
time: now2(),
title: "🔥 " + store.$id,
subtitle: "HMR update",
data: {
store: formatDisplay(store.$id),
info: formatDisplay(`HMR update`)
}
}
});
api.notifyComponentUpdate();
api.sendInspectorTree(INSPECTOR_ID);
api.sendInspectorState(INSPECTOR_ID);
});
const { $dispose } = store;
store.$dispose = () => {
$dispose();
api.notifyComponentUpdate();
api.sendInspectorTree(INSPECTOR_ID);
api.sendInspectorState(INSPECTOR_ID);
api.getSettings().logStoreChanges && toastMessage(`Disposed "${store.$id}" store 🗑`);
};
api.notifyComponentUpdate();
api.sendInspectorTree(INSPECTOR_ID);
api.sendInspectorState(INSPECTOR_ID);
api.getSettings().logStoreChanges && toastMessage(`"${store.$id}" store installed 🆕`);
});
}
let runningActionId = 0;
let activeAction;
function patchActionForGrouping(store, actionNames, wrapWithProxy) {
const actions = actionNames.reduce((storeActions, actionName) => {
storeActions[actionName] = vue.toRaw(store)[actionName];
return storeActions;
}, {});
for (const actionName in actions) {
store[actionName] = function() {
const _actionId = runningActionId;
const trackedStore = wrapWithProxy ? new Proxy(store, {
get(...args) {
activeAction = _actionId;
return Reflect.get(...args);
},
set(...args) {
activeAction = _actionId;
return Reflect.set(...args);
}
}) : store;
activeAction = _actionId;
const retValue = actions[actionName].apply(trackedStore, arguments);
activeAction = void 0;
return retValue;
};
}
}
function devtoolsPlugin({ app, store, options }) {
if (store.$id.startsWith("__hot:")) {
return;
}
store._isOptionsAPI = !!options.state;
patchActionForGrouping(store, Object.keys(options.actions), store._isOptionsAPI);
const originalHotUpdate = store._hotUpdate;
vue.toRaw(store)._hotUpdate = function(newStore) {
originalHotUpdate.apply(this, arguments);
patchActionForGrouping(store, Object.keys(newStore._hmrPayload.actions), !!store._isOptionsAPI);
};
addStoreToDevtools(
app,
// FIXME: is there a way to allow the assignment from Store<Id, S, G, A> to StoreGeneric?
store
);
}
function createPinia() {
const scope = vue.effectScope(true);
const state = scope.run(() => vue.ref({}));
let _p = [];
let toBeInstalled = [];
const pinia = vue.markRaw({
install(app) {
setActivePinia(pinia);
{
pinia._a = app;
app.provide(piniaSymbol, pinia);
app.config.globalProperties.$pinia = pinia;
if (USE_DEVTOOLS) {
registerPiniaDevtools(app, pinia);
}
toBeInstalled.forEach((plugin) => _p.push(plugin));
toBeInstalled = [];
}
},
use(plugin) {
if (!this._a && !isVue2) {
toBeInstalled.push(plugin);
} else {
_p.push(plugin);
}
return this;
},
_p,
// it's actually undefined here
// @ts-expect-error
_a: null,
_e: scope,
_s: /* @__PURE__ */ new Map(),
state
});
if (USE_DEVTOOLS && typeof Proxy !== "undefined") {
pinia.use(devtoolsPlugin);
}
return pinia;
}
function patchObject(newState, oldState) {
for (const key in oldState) {
const subPatch = oldState[key];
if (!(key in newState)) {
continue;
}
const targetValue = newState[key];
if (isPlainObject(targetValue) && isPlainObject(subPatch) && !vue.isRef(subPatch) && !vue.isReactive(subPatch)) {
newState[key] = patchObject(targetValue, subPatch);
} else {
{
newState[key] = subPatch;
}
}
}
return newState;
}
const noop = () => {
};
function addSubscription(subscriptions, callback, detached, onCleanup = noop) {
subscriptions.push(callback);
const removeSubscription = () => {
const idx = subscriptions.indexOf(callback);
if (idx > -1) {
subscriptions.splice(idx, 1);
onCleanup();
}
};
if (!detached && vue.getCurrentScope()) {
vue.onScopeDispose(removeSubscription);
}
return removeSubscription;
}
function triggerSubscriptions(subscriptions, ...args) {
subscriptions.slice().forEach((callback) => {
callback(...args);
});
}
const fallbackRunWithContext = (fn) => fn();
function mergeReactiveObjects(target, patchToApply) {
if (target instanceof Map && patchToApply instanceof Map) {
patchToApply.forEach((value, key) => target.set(key, value));
}
if (target instanceof Set && patchToApply instanceof Set) {
patchToApply.forEach(target.add, target);
}
for (const key in patchToApply) {
if (!patchToApply.hasOwnProperty(key))
continue;
const subPatch = patchToApply[key];
const targetValue = target[key];
if (isPlainObject(targetValue) && isPlainObject(subPatch) && target.hasOwnProperty(key) && !vue.isRef(subPatch) && !vue.isReactive(subPatch)) {
target[key] = mergeReactiveObjects(targetValue, subPatch);
} else {
target[key] = subPatch;
}
}
return target;
}
const skipHydrateSymbol = Symbol("pinia:skipHydration");
function shouldHydrate(obj) {
return !isPlainObject(obj) || !obj.hasOwnProperty(skipHydrateSymbol);
}
const { assign } = Object;
function isComputed(o) {
return !!(vue.isRef(o) && o.effect);
}
function createOptionsStore(id, options, pinia, hot) {
const { state, actions, getters } = options;
const initialState = pinia.state.value[id];
let store;
function setup() {
if (!initialState && !hot) {
{
pinia.state.value[id] = state ? state() : {};
}
}
const localState = hot ? (
// use ref() to unwrap refs inside state TODO: check if this is still necessary
vue.toRefs(vue.ref(state ? state() : {}).value)
) : vue.toRefs(pinia.state.value[id]);
return assign(localState, actions, Object.keys(getters || {}).reduce((computedGetters, name2) => {
if (name2 in localState) {
console.warn(`[🍍]: A getter cannot have the same name as another state property. Rename one of them. Found with "${name2}" in store "${id}".`);
}
computedGetters[name2] = vue.markRaw(vue.computed(() => {
setActivePinia(pinia);
const store2 = pinia._s.get(id);
return getters[name2].call(store2, store2);
}));
return computedGetters;
}, {}));
}
store = createSetupStore(id, setup, options, pinia, hot, true);
return store;
}
function createSetupStore($id, setup, options = {}, pinia, hot, isOptionsStore) {
let scope;
const optionsForPlugin = assign({ actions: {} }, options);
if (!pinia._e.active) {
throw new Error("Pinia destroyed");
}
const $subscribeOptions = {
deep: true
// flush: 'post',
};
{
$subscribeOptions.onTrigger = (event) => {
if (isListening) {
debuggerEvents = event;
} else if (isListening == false && !store._hotUpdating) {
if (Array.isArray(debuggerEvents)) {
debuggerEvents.push(event);
} else {
console.error("🍍 debuggerEvents should be an array. This is most likely an internal Pinia bug.");
}
}
};
}
let isListening;
let isSyncListening;
let subscriptions = [];
let actionSubscriptions = [];
let debuggerEvents;
const initialState = pinia.state.value[$id];
if (!isOptionsStore && !initialState && !hot) {
{
pinia.state.value[$id] = {};
}
}
const hotState = vue.ref({});
let activeListener;
function $patch(partialStateOrMutator) {
let subscriptionMutation;
isListening = isSyncListening = false;
{
debuggerEvents = [];
}
if (typeof partialStateOrMutator === "function") {
partialStateOrMutator(pinia.state.value[$id]);
subscriptionMutation = {
type: MutationType.patchFunction,
storeId: $id,
events: debuggerEvents
};
} else {
mergeReactiveObjects(pinia.state.value[$id], partialStateOrMutator);
subscriptionMutation = {
type: MutationType.patchObject,
payload: partialStateOrMutator,
storeId: $id,
events: debuggerEvents
};
}
const myListenerId = activeListener = Symbol();
vue.nextTick().then(() => {
if (activeListener === myListenerId) {
isListening = true;
}
});
isSyncListening = true;
triggerSubscriptions(subscriptions, subscriptionMutation, pinia.state.value[$id]);
}
const $reset = isOptionsStore ? function $reset2() {
const { state } = options;
const newState = state ? state() : {};
this.$patch(($state) => {
assign($state, newState);
});
} : (
/* istanbul ignore next */
() => {
throw new Error(`🍍: Store "${$id}" is built using the setup syntax and does not implement $reset().`);
}
);
function $dispose() {
scope.stop();
subscriptions = [];
actionSubscriptions = [];
pinia._s.delete($id);
}
function wrapAction(name2, action) {
return function() {
setActivePinia(pinia);
const args = Array.from(arguments);
const afterCallbackList = [];
const onErrorCallbackList = [];
function after(callback) {
afterCallbackList.push(callback);
}
function onError(callback) {
onErrorCallbackList.push(callback);
}
triggerSubscriptions(actionSubscriptions, {
args,
name: name2,
store,
after,
onError
});
let ret;
try {
ret = action.apply(this && this.$id === $id ? this : store, args);
} catch (error) {
triggerSubscriptions(onErrorCallbackList, error);
throw error;
}
if (ret instanceof Promise) {
return ret.then((value) => {
triggerSubscriptions(afterCallbackList, value);
return value;
}).catch((error) => {
triggerSubscriptions(onErrorCallbackList, error);
return Promise.reject(error);
});
}
triggerSubscriptions(afterCallbackList, ret);
return ret;
};
}
const _hmrPayload = /* @__PURE__ */ vue.markRaw({
actions: {},
getters: {},
state: [],
hotState
});
const partialStore = {
_p: pinia,
// _s: scope,
$id,
$onAction: addSubscription.bind(null, actionSubscriptions),
$patch,
$reset,
$subscribe(callback, options2 = {}) {
const removeSubscription = addSubscription(subscriptions, callback, options2.detached, () => stopWatcher());
const stopWatcher = scope.run(() => vue.watch(() => pinia.state.value[$id], (state) => {
if (options2.flush === "sync" ? isSyncListening : isListening) {
callback({
storeId: $id,
type: MutationType.direct,
events: debuggerEvents
}, state);
}
}, assign({}, $subscribeOptions, options2)));
return removeSubscription;
},
$dispose
};
const store = vue.reactive(assign(
{
_hmrPayload,
_customProperties: vue.markRaw(/* @__PURE__ */ new Set())
// devtools custom properties
},
partialStore
// must be added later
// setupStore
));
pinia._s.set($id, store);
const runWithContext = pinia._a && pinia._a.runWithContext || fallbackRunWithContext;
const setupStore = runWithContext(() => pinia._e.run(() => (scope = vue.effectScope()).run(setup)));
for (const key in setupStore) {
const prop = setupStore[key];
if (vue.isRef(prop) && !isComputed(prop) || vue.isReactive(prop)) {
if (hot) {
set(hotState.value, key, vue.toRef(setupStore, key));
} else if (!isOptionsStore) {
if (initialState && shouldHydrate(prop)) {
if (vue.isRef(prop)) {
prop.value = initialState[key];
} else {
mergeReactiveObjects(prop, initialState[key]);
}
}
{
pinia.state.value[$id][key] = prop;
}
}
{
_hmrPayload.state.push(key);
}
} else if (typeof prop === "function") {
const actionValue = hot ? prop : wrapAction(key, prop);
{
setupStore[key] = actionValue;
}
{
_hmrPayload.actions[key] = prop;
}
optionsForPlugin.actions[key] = prop;
} else {
if (isComputed(prop)) {
_hmrPayload.getters[key] = isOptionsStore ? (
// @ts-expect-error
options.getters[key]
) : prop;
if (IS_CLIENT) {
const getters = setupStore._getters || // @ts-expect-error: same
(setupStore._getters = vue.markRaw([]));
getters.push(key);
}
}
}
}
{
assign(store, setupStore);
assign(vue.toRaw(store), setupStore);
}
Object.defineProperty(store, "$state", {
get: () => hot ? hotState.value : pinia.state.value[$id],
set: (state) => {
if (hot) {
throw new Error("cannot set hotState");
}
$patch(($state) => {
assign($state, state);
});
}
});
{
store._hotUpdate = vue.markRaw((newStore) => {
store._hotUpdating = true;
newStore._hmrPayload.state.forEach((stateKey) => {
if (stateKey in store.$state) {
const newStateTarget = newStore.$state[stateKey];
const oldStateSource = store.$state[stateKey];
if (typeof newStateTarget === "object" && isPlainObject(newStateTarget) && isPlainObject(oldStateSource)) {
patchObject(newStateTarget, oldStateSource);
} else {
newStore.$state[stateKey] = oldStateSource;
}
}
set(store, stateKey, vue.toRef(newStore.$state, stateKey));
});
Object.keys(store.$state).forEach((stateKey) => {
if (!(stateKey in newStore.$state)) {
del(store, stateKey);
}
});
isListening = false;
isSyncListening = false;
pinia.state.value[$id] = vue.toRef(newStore._hmrPayload, "hotState");
isSyncListening = true;
vue.nextTick().then(() => {
isListening = true;
});
for (const actionName in newStore._hmrPayload.actions) {
const action = newStore[actionName];
set(store, actionName, wrapAction(actionName, action));
}
for (const getterName in newStore._hmrPayload.getters) {
const getter = newStore._hmrPayload.getters[getterName];
const getterValue = isOptionsStore ? (
// special handling of options api
vue.computed(() => {
setActivePinia(pinia);
return getter.call(store, store);
})
) : getter;
set(store, getterName, getterValue);
}
Object.keys(store._hmrPayload.getters).forEach((key) => {
if (!(key in newStore._hmrPayload.getters)) {
del(store, key);
}
});
Object.keys(store._hmrPayload.actions).forEach((key) => {
if (!(key in newStore._hmrPayload.actions)) {
del(store, key);
}
});
store._hmrPayload = newStore._hmrPayload;
store._getters = newStore._getters;
store._hotUpdating = false;
});
}
if (USE_DEVTOOLS) {
const nonEnumerable = {
writable: true,
configurable: true,
// avoid warning on devtools trying to display this property
enumerable: false
};
["_p", "_hmrPayload", "_getters", "_customProperties"].forEach((p) => {
Object.defineProperty(store, p, assign({ value: store[p] }, nonEnumerable));
});
}
pinia._p.forEach((extender) => {
if (USE_DEVTOOLS) {
const extensions = scope.run(() => extender({
store,
app: pinia._a,
pinia,
options: optionsForPlugin
}));
Object.keys(extensions || {}).forEach((key) => store._customProperties.add(key));
assign(store, extensions);
} else {
assign(store, scope.run(() => extender({
store,
app: pinia._a,
pinia,
options: optionsForPlugin
})));
}
});
if (store.$state && typeof store.$state === "object" && typeof store.$state.constructor === "function" && !store.$state.constructor.toString().includes("[native code]")) {
console.warn(`[🍍]: The "state" must be a plain object. It cannot be
state: () => new MyClass()
Found in store "${store.$id}".`);
}
if (initialState && isOptionsStore && options.hydrate) {
options.hydrate(store.$state, initialState);
}
isListening = true;
isSyncListening = true;
return store;
}
function defineStore(idOrOptions, setup, setupOptions) {
let id;
let options;
const isSetupStore = typeof setup === "function";
if (typeof idOrOptions === "string") {
id = idOrOptions;
options = isSetupStore ? setupOptions : setup;
} else {
options = idOrOptions;
id = idOrOptions.id;
if (typeof id !== "string") {
throw new Error(`[🍍]: "defineStore()" must be passed a store id as its first argument.`);
}
}
function useStore(pinia, hot) {
const hasContext = vue.hasInjectionContext();
pinia = // in test mode, ignore the argument provided as we can always retrieve a
// pinia instance with getActivePinia()
pinia || (hasContext ? vue.inject(piniaSymbol, null) : null);
if (pinia)
setActivePinia(pinia);
if (!activePinia) {
throw new Error(`[🍍]: "getActivePinia()" was called but there was no active Pinia. Are you trying to use a store before calling "app.use(pinia)"?
See https://pinia.vuejs.org/core-concepts/outside-component-usage.html for help.
This will fail in production.`);
}
pinia = activePinia;
if (!pinia._s.has(id)) {
if (isSetupStore) {
createSetupStore(id, setup, options, pinia);
} else {
createOptionsStore(id, options, pinia);
}
{
useStore._pinia = pinia;
}
}
const store = pinia._s.get(id);
if (hot) {
const hotId = "__hot:" + id;
const newStore = isSetupStore ? createSetupStore(hotId, setup, options, pinia, true) : createOptionsStore(hotId, assign({}, options), pinia, true);
hot._hotUpdate(newStore);
delete pinia.state.value[hotId];
pinia._s.delete(hotId);
}
if (IS_CLIENT) {
const currentInstance = vue.getCurrentInstance();
if (currentInstance && currentInstance.proxy && // avoid adding stores that are just built for hot module replacement
!hot) {
const vm = currentInstance.proxy;
const cache = "_pStores" in vm ? vm._pStores : vm._pStores = {};
cache[id] = store;
}
}
return store;
}
useStore.$id = id;
return useStore;
}
const WS_APP_URL = "ws://cloud_test.yuxindazhineng.com";
let WebSocketManager$1 = class WebSocketManager {
constructor() {
this.ws = null;
this.url = `${WS_APP_URL}/cloud_api/phone/app_ws`;
this.options = {
token: "",
conversationId: "",
onMessage: null,
onError: null,
onReconnect: null,
onOpen: null,
onClose: null
};
this.reconnectAttempts = 0;
this.maxReconnectAttempts = 5;
this.reconnectDelay = 3e3;
this.reconnectTimer = null;
this.heartbeatTimer = null;
this.isManualClose = false;
}
/**
* 初始化连接
* @param {string} url WebSocket URL
* @param {Object} options 配置选项
*/
connect(options = {}) {
this.options = {
...this.options,
...options
};
this.isManualClose = false;
if (this.ws) {
this.close();
}
try {
this.ws = uni.connectSocket({
url: this.url,
success: () => {
formatAppLog("log", "at utils/socket.js:43", "WebSocket 连接请求已发送");
},
fail: (err) => {
formatAppLog("error", "at utils/socket.js:46", "WebSocket 连接失败:", err);
this.handleError(err);
}
});
this.initEventHandlers();
} catch (err) {
this.handleError(err);
}
}
/**
* 初始化事件处理
*/
initEventHandlers() {
if (!this.ws)
return;
this.ws.onOpen((event) => {
var _a, _b, _c, _d;
formatAppLog("log", "at utils/socket.js:73", "WebSocket 已连接");
if (this.reconnectAttempts > 0) {
(_b = (_a = this.options).onReconnect) == null ? void 0 : _b.call(_a);
}
(_d = (_c = this.options).onOpen) == null ? void 0 : _d.call(_c, event);
this.reconnectAttempts = 0;
});
this.ws.onMessage((event) => {
try {
const data = JSON.parse(event.data);
formatAppLog("log", "at utils/socket.js:86", "收到了返回消息:", data);
this.handleMessage(data);
} catch (err) {
formatAppLog("error", "at utils/socket.js:90", "消息解析失败:", err);
uni.setStorageSync("currentSessionId", event.data.task_call_id);
}
});
this.ws.onError((err) => {
formatAppLog("error", "at utils/socket.js:95", "WebSocket 错误:", err);
this.handleError(err);
});
this.ws.onClose((event) => {
var _a, _b;
formatAppLog("log", "at utils/socket.js:99", "WebSocket 已关闭:", event.code, event.reason);
(_b = (_a = this.options).onClose) == null ? void 0 : _b.call(_a, event);
this.stopHeartbeat();
if (!this.isManualClose && this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnect();
}
});
}
/**
* 处理服务端推送的消息
* @param {Object} msg - 服务端返回的原始消息对象
*/
handleMessage(msg) {
var _a, _b;
(_b = (_a = this.options).onMessage) == null ? void 0 : _b.call(_a, msg);
const type = msg.type;
if (type === "auth_ok") {
formatAppLog("log", "at utils/socket.js:161", "认证成功socket连接成功");
return;
}
if (type === "auth_fail") {
if ((msg == null ? void 0 : msg.reason) === "pc offline")
formatAppLog("log", "at utils/socket.js:168", "pc端不在线不可聊天");
this.isManualClose = true;
this.close();
return;
}
}
/**
* 统一发送消息方法
* 兼容 APP / 微信小程序 环境
* @param {Object} data - 要发送的消息对象
* @returns {Promise} 发送结果
*/
send(data) {
return new Promise((resolve, reject) => {
if (!this.isConnected()) {
reject(new Error("WebSocket 未连接"));
return;
}
const msg = JSON.stringify(data);
formatAppLog("log", "at utils/socket.js:192", "发送的消息是:", msg);
this.ws.send({
data: msg,
success: () => resolve(),
fail: (err) => {
formatAppLog("error", "at utils/socket.js:200", "发送消息失败:", err);
reject(err);
}
});
});
}
/**
* 自动重连机制
* 指数退避重连,避免频繁重连
*/
reconnect() {
if (this.reconnectTimer)
return;
this.reconnectAttempts++;
formatAppLog("log", "at utils/socket.js:226", `尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);
this.reconnectTimer = setTimeout(() => {
this.reconnectTimer = null;
if (!this.isManualClose) {
this.connect(this.options);
}
}, this.reconnectDelay * this.reconnectAttempts);
}
/**
* 启动心跳定时器
* 每30秒发送一次 ping 保持连接
*/
startHeartbeat() {
this.stopHeartbeat();
this.heartbeatTimer = setInterval(() => {
if (this.isConnected()) {
this.send({
ws_event: "ping"
}).catch(() => {
formatAppLog("log", "at utils/socket.js:248", "心跳发送失败,准备重连");
if (!this.reconnectTimer && !this.isManualClose) {
this.reconnect();
}
});
} else if (!this.isManualClose && this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnect();
}
}, 3e4);
}
/**
* 停止心跳定时器
*/
stopHeartbeat() {
if (this.heartbeatTimer) {
clearInterval(this.heartbeatTimer);
this.heartbeatTimer = null;
}
}
/**
* 统一错误处理
* @param {Error} error - 错误对象
*/
handleError(error) {
var _a, _b;
formatAppLog("error", "at utils/socket.js:276", "WebSocket 错误处理:", JSON.stringify(error));
(_b = (_a = this.options).onError) == null ? void 0 : _b.call(_a, error);
}
/**
* 判断 WebSocket 是否处于已连接状态
* @returns {boolean}
*/
isConnected() {
if (!this.ws)
return false;
return this.ws.readyState === 1;
}
/**
* 方便外部获取连接状态码
* @returns {number} 0:连接中,1:已连接,2:关闭中,3:已关闭
*/
getReadyState() {
if (!this.ws)
return 3;
return this.ws.readyState;
}
/**
* 手动关闭 WebSocket 连接
* 清理所有定时器、标记手动关闭、停止重连
*/
close() {
formatAppLog("log", "at utils/socket.js:312", "手动关闭 WebSocket 连接");
this.isManualClose = true;
this.stopHeartbeat();
if (this.reconnectTimer) {
clearTimeout(this.reconnectTimer);
this.reconnectTimer = null;
}
if (this.ws) {
if (this.ws.onOpen)
this.ws.onOpen(null);
if (this.ws.onMessage)
this.ws.onMessage(null);
if (this.ws.onError)
this.ws.onError(null);
if (this.ws.onClose)
this.ws.onClose(null);
try {
this.ws.close({
success: () => formatAppLog("log", "at utils/socket.js:334", "连接已关闭"),
fail: (err) => formatAppLog("error", "at utils/socket.js:335", "关闭失败:", err)
});
} catch (error) {
formatAppLog("error", "at utils/socket.js:343", "关闭连接出错:", error);
}
this.ws = null;
}
this.reconnectAttempts = 0;
}
/**
* 更新配置项
* 合并新配置,不覆盖原有配置
* @param {Object} options - 新配置
*/
updateOptions(options) {
this.options = {
...this.options,
...options
};
}
};
const socketManager = new WebSocketManager$1();
const useSocketStore = defineStore("socket", () => {
const connectionStatus = vue.ref("disconnected");
const messages = vue.ref([]);
const messageString = vue.ref("");
const isThinking = vue.ref(false);
const config = vue.ref({
token: "",
conversationId: ""
});
vue.ref("");
const logs = vue.ref([]);
const maxLogCount = vue.ref(20);
const isConnected = vue.computed(() => connectionStatus.value === "connected");
const isConnecting = vue.computed(() => connectionStatus.value === "connecting");
const isDisconnected = vue.computed(() => connectionStatus.value === "disconnected");
const isError = vue.computed(() => connectionStatus.value === "error");
const lastMessage = vue.computed(() => messages.value[messages.value.length - 1]);
function addLog(type, connect2) {
const now2 = /* @__PURE__ */ new Date();
const time = `${now2.getHours().toString().padStart(2, "0")}:${now2.getMinutes().toString().padStart(2, "0")}:${now2.getSeconds().toString().padStart(2, "0")}`;
logs.value.push({
type,
connect: connect2,
time
});
if (logs.value.length > maxLogCount.value) {
logs.value = logs.value.slice(-maxLogCount.value);
}
formatAppLog("log", "at stores/socket.js:52", `[${type.toUpperCase()}] ${connect2}`);
}
function clearLogs() {
logs.value = [];
}
function connect(options = {}) {
messages.value = [];
messageString.value = "";
config.value = {
...config.value,
...options
};
addLog(
"info",
`准备连接WebSocket。Token:${config.value.token || "未设置"}。ConversationId: ${config.value.conversationId || "未设置"}`
);
if (!config.value.token || !config.value.conversationId) {
addLog("error", "Token和ConversationId都不能为空");
return;
}
connectionStatus.value = "connecting";
socketManager.connect({
token: config.value.token,
conversationId: config.value.conversationId,
onMessage: handleMessage,
onError: handleError,
onOpen: handleOpen,
onClose: handleClose,
onReconnect: handleReconnecting
});
setConnectionTimeout();
}
function disconnect() {
socketManager.close();
connectionStatus.value = "disconnected";
addLog("warn", "已主动断开连接");
}
async function send(message) {
formatAppLog("log", "at stores/socket.js:96", "检查到要发生消息为:", message);
if (!isConnected.value) {
addLog("error", "发送失败: 连接未建立");
throw new Error("连接未建立");
}
try {
await socketManager.send(message);
addLog("send", typeof message === "string" ? message : JSON.stringify(message));
return true;
} catch (error) {
addLog("error", `发送失败: ${error.message || error}`);
throw error;
}
}
function handleOpen() {
connectionStatus.value = "connected";
addLog("success", "连接成功!发送auth");
formatAppLog("log", "at stores/socket.js:115", "连接成功!发送auth");
sendAuth();
}
function handleClose() {
if (connectionStatus.value !== "disconnected") {
connectionStatus.value = "disconnected";
addLog("warn", "连接已断开");
}
}
function handleError(error) {
addLog("error", `Socket错误: ${JSON.stringify(error)}`);
connectionStatus.value = "error";
}
function handleReconnecting(attempts) {
connectionStatus.value = "connecting";
addLog("warn", `重连中... (${attempts}/5)`);
}
function setConnectionTimeout() {
const timer = setTimeout(() => {
if (connectionStatus.value === "connecting") {
connectionStatus.value = "error";
addLog("error", "连接超时(10s)");
}
}, 1e4);
return timer;
}
function handleMessage(messageData) {
addLog("receive", `收到: ${JSON.stringify(messageData)}`);
const {
type,
conversation_id,
message_id,
data
} = messageData || {};
formatAppLog("log", "at stores/socket.js:160", "[handleMessage] type =", type, ", data =", JSON.stringify(data));
switch (type) {
case "auth_ok":
addLog("success", "连接成功");
break;
case "chat_ack":
addLog("warn", "AI成功收到用户发送的消息");
break;
case "render":
addLog("warn", "AI正在回复信息");
handleBusinessMessage(data);
break;
default:
addLog("info", `未知事件类型: ${type}`);
}
}
function sendAuth() {
config.value.token;
socketManager.send({
"type": "auth",
"access_token": config.value.token
});
}
function handleBusinessMessage(data) {
if (data === "exit") {
formatAppLog("log", "at stores/socket.js:212", "ai结束思考");
isThinking.value = false;
return;
}
if (!data || typeof data !== "object")
return;
const {
role,
chunk,
message_role,
meaasge_uuid,
message_type,
task_call_id
} = data;
if (!isThinking.value && (chunk || message_role === "assistant")) {
formatAppLog("log", "at stores/socket.js:233", "ai开始思考");
messageString.value = "";
isThinking.value = true;
}
if (chunk) {
messageString.value += chunk;
}
}
function getStatusText() {
const statusMap = {
connecting: "连接中",
connected: "已连接",
disconnected: "未连接",
error: "连接错误"
};
return statusMap[connectionStatus.value] || "未知状态";
}
return {
// 状态
connectionStatus,
messageString,
isThinking,
logs,
config,
// 计算属性
isConnected,
isConnecting,
isDisconnected,
isError,
lastMessage,
// 方法
connect,
disconnect,
send,
addLog,
clearLogs,
getStatusText
};
});
const BASE_Friend_URL = "http://chat.yuxindazhineng.com";
const getChatFriend = async (sendId) => {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_Friend_URL}/api/chatList/getChatFriend`,
method: "POST",
header: {
"Content-Type": "application/json"
},
data: {
size: 500,
current: 1,
sendId
},
success: (res) => {
var _a;
if (res.statusCode === 200) {
const respond = res.data;
formatAppLog("log", "at utils/friend-api.js:20", "获取到的好友列表消息", respond);
if ((respond == null ? void 0 : respond.code) === 0 || (respond == null ? void 0 : respond.msg) === "成功") {
const friendList = (_a = respond.data) == null ? void 0 : _a.records;
if (friendList.length > 0) {
const receiverId = friendList[0].receiver;
if (receiverId) {
uni.setStorageSync("receiverId", receiverId);
}
}
resolve(friendList);
} else {
const msg = res.data.error || "获取好友列表出错啦";
reject(msg);
}
} else {
reject(`获取好友列表失败:${res.statusCode}`);
}
},
fail: (err) => {
const msg = err.errMsg || "网络错误";
reject(msg);
}
});
});
};
const getGroup = async (sendId) => {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_Friend_URL}/api/group/getGroup`,
method: "POST",
header: {
"Content-Type": "application/json"
},
data: {
size: 500,
current: 1,
contactId: sendId
},
success: (res) => {
var _a;
if (res.statusCode === 200) {
const respond = res.data;
if ((respond == null ? void 0 : respond.code) === 0 || (respond == null ? void 0 : respond.msg) === "成功") {
const groupList = (_a = respond.data) == null ? void 0 : _a.records;
resolve(groupList);
} else {
const msg = res.data.error || "获取群聊列表出错啦";
reject(msg);
}
} else {
reject(`获取群聊列表失败:${res.statusCode}`);
}
},
fail: (err) => {
const msg = err.errMsg || "网络错误";
reject(msg);
}
});
});
};
const getFriendMessages = async (sessionId, current = 1) => {
formatAppLog("log", "at utils/friend-api.js:88", "请求的好友消息id", sessionId);
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_Friend_URL}/api/message/list`,
method: "POST",
data: {
"sessionId": sessionId,
"size": 100,
"current": current,
"beginTime": "",
"endTime": ""
},
header: {
"Content-Type": "application/json"
},
success: (res) => {
var _a;
if (res.statusCode === 200) {
const messagesInfo = res.data;
if (messagesInfo.code === 0) {
const messageList = ((_a = messagesInfo == null ? void 0 : messagesInfo.data) == null ? void 0 : _a.records) || [];
const reversedList = messageList.reverse();
resolve(reversedList);
} else {
const msg = res.data.error || "获取好友消息出错啦";
reject(msg);
}
} else {
reject(`请求失败:${res.statusCode}`);
}
},
fail: (err) => {
const msg = err.errMsg || "网络错误";
reject(msg);
}
});
});
};
const getGroupMessages = async (groupId, current = 1) => {
formatAppLog("log", "at utils/friend-api.js:134", "请求的群聊消息id", groupId);
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_Friend_URL}/api/group/getGroupList`,
method: "POST",
data: {
"current": current,
"size": 100,
"groupId": groupId,
"beginTime": "",
"endTime": ""
},
header: {
"Content-Type": "application/json"
},
success: (res) => {
var _a;
if (res.statusCode === 200) {
const messagesInfo = res.data;
formatAppLog("log", "at utils/friend-api.js:152", "获取到的群聊信息:", messagesInfo);
if (messagesInfo.code === 0) {
const messageList = ((_a = messagesInfo == null ? void 0 : messagesInfo.data) == null ? void 0 : _a.records) || [];
const reversedList = messageList.reverse();
resolve(reversedList);
} else {
const msg = res.data.error || "获取群聊消息出错啦";
reject(msg);
}
} else {
reject(`请求失败:${res.statusCode}`);
}
},
fail: (err) => {
const msg = err.errMsg || "网络错误";
reject(msg);
}
});
});
};
const getGroupMemberList = async (groupId) => {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_Friend_URL}/api/group/getGroupMemberList`,
method: "POST",
header: {
"Content-Type": "application/json"
},
data: {
"groupId": groupId,
"current": 1,
"size": 100
},
success: (res) => {
if (res.statusCode === 200) {
const respond = res.data;
if (respond.code === 0) {
const groupMemberList = respond.data.records;
resolve(groupMemberList);
} else {
const msg = res.data.error || "获取群成员出错啦";
reject(msg);
}
} else {
reject(`请求群成员失败:${res.statusCode}`);
}
},
fail: (err) => {
const msg = err.errMsg || "网络错误";
reject(msg);
}
});
});
};
const uploadFileToServer = (filePath) => {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: `${BASE_Friend_URL}/api/file/upload`,
filePath,
name: "file",
success: (res) => {
const data = JSON.parse(res.data);
if (data.code === 0) {
resolve(data.data);
} else {
reject(data.msg || "上传失败");
}
},
fail: (err) => {
reject(err.errMsg || "网络错误");
}
});
});
};
const WS_Friend_URL = "wss://wss.yuxindazhineng.com";
class WebSocketManager {
constructor() {
this.ws = null;
this.url = `${WS_Friend_URL}/ws`;
this.options = {
token: "",
UserId: "",
onMessage: null,
onError: null,
onReconnect: null,
onOpen: null,
onClose: null
};
this.reconnectAttempts = 0;
this.maxReconnectAttempts = 5;
this.reconnectDelay = 3e3;
this.reconnectTimer = null;
this.heartbeatTimer = null;
this.isManualClose = false;
}
/**
* 初始化连接
* @param {string} url WebSocket URL
* @param {Object} options 配置选项
*/
connect(options = {}) {
this.options = {
...this.options,
...options
};
this.isManualClose = false;
if (this.ws) {
this.close();
}
try {
this.ws = uni.connectSocket({
url: this.url,
success: () => {
formatAppLog("log", "at utils/friend-socket.js:44", "WebSocket 连接请求已发送");
},
fail: (err) => {
formatAppLog("error", "at utils/friend-socket.js:47", "WebSocket 连接失败:", err);
this.handleError(err);
}
});
this.initEventHandlers();
} catch (err) {
this.handleError(err);
}
}
/**
* 初始化事件处理
*/
initEventHandlers() {
if (!this.ws)
return;
this.ws.onOpen((event) => {
var _a, _b, _c, _d;
formatAppLog("log", "at utils/friend-socket.js:74", "WebSocket 已连接");
if (this.reconnectAttempts > 0) {
(_b = (_a = this.options).onReconnect) == null ? void 0 : _b.call(_a);
}
(_d = (_c = this.options).onOpen) == null ? void 0 : _d.call(_c, event);
this.reconnectAttempts = 0;
});
this.ws.onMessage((event) => {
try {
const data = JSON.parse(event.data);
formatAppLog("log", "at utils/friend-socket.js:87", "收到了返回消息:", data);
this.handleMessage(data);
} catch (err) {
formatAppLog("error", "at utils/friend-socket.js:90", "消息解析失败:", err);
uni.setStorageSync("currentSessionId", event.data.task_call_id);
}
});
this.ws.onError((err) => {
formatAppLog("error", "at utils/friend-socket.js:95", "WebSocket 错误:", err);
this.handleError(err);
});
this.ws.onClose((event) => {
var _a, _b;
formatAppLog("log", "at utils/friend-socket.js:99", "WebSocket 已关闭:", event.code, event.reason);
(_b = (_a = this.options).onClose) == null ? void 0 : _b.call(_a, event);
if (!this.isManualClose && this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnect();
}
});
}
/**
* 处理服务端推送的消息
* @param {Object} msg - 服务端返回的原始消息对象
*/
handleMessage(msg) {
var _a, _b;
(_b = (_a = this.options).onMessage) == null ? void 0 : _b.call(_a, msg);
}
/**
* 统一发送消息方法
* 兼容 APP / 微信小程序 环境
* @param {Object} data - 要发送的消息对象
* @returns {Promise} 发送结果
*/
send(data) {
return new Promise((resolve, reject) => {
if (!this.isConnected()) {
reject(new Error("WebSocket 未连接"));
return;
}
const msg = JSON.stringify(data);
formatAppLog("log", "at utils/friend-socket.js:170", "发送的消息是:", msg);
this.ws.send({
data: msg,
success: () => resolve(),
fail: (err) => {
formatAppLog("error", "at utils/friend-socket.js:178", "发送消息失败:", err);
reject(err);
}
});
});
}
/**
* 自动重连机制
* 指数退避重连,避免频繁重连
*/
reconnect() {
if (this.reconnectTimer)
return;
this.reconnectAttempts++;
formatAppLog("log", "at utils/friend-socket.js:204", `尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);
this.reconnectTimer = setTimeout(() => {
this.reconnectTimer = null;
if (!this.isManualClose) {
this.connect(this.options);
}
}, this.reconnectDelay * this.reconnectAttempts);
}
/**
* 启动心跳定时器
* 每30秒发送一次 ping 保持连接
*/
startHeartbeat() {
this.stopHeartbeat();
this.heartbeatTimer = setInterval(() => {
if (this.isConnected()) {
this.send({
ws_event: "ping"
}).catch(() => {
formatAppLog("log", "at utils/friend-socket.js:226", "心跳发送失败,准备重连");
if (!this.reconnectTimer && !this.isManualClose) {
this.reconnect();
}
});
} else if (!this.isManualClose && this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnect();
}
}, 3e4);
}
/**
* 停止心跳定时器
*/
stopHeartbeat() {
if (this.heartbeatTimer) {
clearInterval(this.heartbeatTimer);
this.heartbeatTimer = null;
}
}
/**
* 统一错误处理
* @param {Error} error - 错误对象
*/
handleError(error) {
var _a, _b;
formatAppLog("error", "at utils/friend-socket.js:254", "WebSocket 错误处理:", JSON.stringify(error));
(_b = (_a = this.options).onError) == null ? void 0 : _b.call(_a, error);
}
/**
* 判断 WebSocket 是否处于已连接状态
* @returns {boolean}
*/
isConnected() {
if (!this.ws)
return false;
return this.ws.readyState === 1;
}
/**
* 方便外部获取连接状态码
* @returns {number} 0:连接中,1:已连接,2:关闭中,3:已关闭
*/
getReadyState() {
if (!this.ws)
return 3;
return this.ws.readyState;
}
/**
* 手动关闭 WebSocket 连接
* 清理所有定时器、标记手动关闭、停止重连
*/
close() {
formatAppLog("log", "at utils/friend-socket.js:290", "手动关闭 WebSocket 连接");
this.isManualClose = true;
this.stopHeartbeat();
if (this.reconnectTimer) {
clearTimeout(this.reconnectTimer);
this.reconnectTimer = null;
}
if (this.ws) {
if (this.ws.onOpen)
this.ws.onOpen(null);
if (this.ws.onMessage)
this.ws.onMessage(null);
if (this.ws.onError)
this.ws.onError(null);
if (this.ws.onClose)
this.ws.onClose(null);
try {
this.ws.close({
success: () => formatAppLog("log", "at utils/friend-socket.js:312", "连接已关闭"),
fail: (err) => formatAppLog("error", "at utils/friend-socket.js:313", "关闭失败:", err)
});
} catch (error) {
formatAppLog("error", "at utils/friend-socket.js:321", "关闭连接出错:", error);
}
this.ws = null;
}
this.reconnectAttempts = 0;
}
/**
* 更新配置项
* 合并新配置,不覆盖原有配置
* @param {Object} options - 新配置
*/
updateOptions(options) {
this.options = {
...this.options,
...options
};
}
}
const friendSocketManager = new WebSocketManager();
const useFriendSocketStore = defineStore("friendSocket", () => {
const connectionStatus = vue.ref("disconnected");
const messages = vue.ref([]);
const messageString = vue.ref("");
const config = vue.ref({
token: "",
UserId: ""
});
vue.ref("");
const command = vue.ref(null);
const groupId = vue.ref(null);
const MessageReceived = vue.ref(false);
const logs = vue.ref([]);
const maxLogCount = vue.ref(20);
const isConnected = vue.computed(() => connectionStatus.value === "connected");
const isConnecting = vue.computed(() => connectionStatus.value === "connecting");
const isDisconnected = vue.computed(() => connectionStatus.value === "disconnected");
const isError = vue.computed(() => connectionStatus.value === "error");
const lastMessage = vue.computed(() => messages.value[messages.value.length - 1]);
function addLog(type, connect2) {
const now2 = /* @__PURE__ */ new Date();
const time = `${now2.getHours().toString().padStart(2, "0")}:${now2.getMinutes().toString().padStart(2, "0")}:${now2.getSeconds().toString().padStart(2, "0")}`;
logs.value.push({
type,
connect: connect2,
time
});
if (logs.value.length > maxLogCount.value) {
logs.value = logs.value.slice(-maxLogCount.value);
}
formatAppLog("log", "at stores/friend-socket.js:57", `[${type.toUpperCase()}] ${connect2}`);
}
function clearLogs() {
logs.value = [];
}
function connect(options = {}) {
messages.value = [];
messageString.value = "";
config.value = {
...config.value,
...options
};
addLog(
"info",
`准备连接FriendsWebSocket。Token:${config.value.token || "未设置"}。UserId: ${config.value.UserId || "未设置"}`
);
if (!config.value.token || !config.value.UserId) {
addLog("error", "Token和UserId都不能为空");
return;
}
connectionStatus.value = "connecting";
friendSocketManager.connect({
token: config.value.token,
UserId: config.value.UserId,
onMessage: handleMessage,
onError: handleError,
onOpen: handleOpen,
onClose: handleClose,
onReconnect: handleReconnecting
});
setConnectionTimeout();
}
function disconnect() {
friendSocketManager.close();
connectionStatus.value = "disconnected";
addLog("warn", "已主动断开连接");
}
async function send(message) {
if (!isConnected.value) {
addLog("error", "发送失败: 连接未建立");
throw new Error("连接未建立");
}
try {
await friendSocketManager.send(message);
addLog("send", typeof message === "string" ? message : JSON.stringify(message));
return true;
} catch (error) {
addLog("error", `发送失败: ${error.message || error}`);
throw error;
}
}
async function sendAuthData() {
const userId = getUserId();
const authData = {
"version": "1.1",
"body": {
"command": 7,
"sender": userId,
"avatar": "",
"sessionId": "",
"message": "",
"callBackMessage": false
}
};
try {
await friendSocketManager.send(authData);
addLog("send", typeof authData === "string" ? authData : JSON.stringify(authData));
return true;
} catch (error) {
addLog("error", `发送验证失败: ${error.message || error}`);
throw error;
}
}
function handleOpen() {
connectionStatus.value = "connected";
addLog("success", "连接成功!");
sendAuthData();
}
function handleClose() {
if (connectionStatus.value !== "disconnected") {
connectionStatus.value = "disconnected";
addLog("warn", "连接已断开");
}
}
function handleError(error) {
addLog("error", `Socket错误: ${JSON.stringify(error)}`);
connectionStatus.value = "error";
}
function handleReconnecting(attempts) {
connectionStatus.value = "connecting";
addLog("warn", `重连中... (${attempts}/5)`);
}
function setConnectionTimeout() {
const timer = setTimeout(() => {
if (connectionStatus.value === "connecting") {
connectionStatus.value = "error";
addLog("error", "连接超时(10s)");
}
}, 1e4);
return timer;
}
function handleMessage(messageData) {
addLog("receive", `收到: ${JSON.stringify(messageData)}`);
const msgBody = messageData.body || messageData;
const {
callBackMessage,
groupName,
command: msgCommand,
groupId: msgGroupId
} = msgBody || {};
switch (msgCommand) {
case 3:
command.value = msgCommand;
groupId.value = msgGroupId;
break;
case 7:
command.value = msgCommand;
break;
case 1:
formatAppLog("log", "at stores/friend-socket.js:199", "有好友消息");
MessageReceived.value = true;
break;
case 9:
formatAppLog("log", "at stores/friend-socket.js:204", "群消息发送成功/有新群消息");
MessageReceived.value = true;
break;
default:
addLog("info", `未知事件类型`);
}
}
function getStatusText() {
const statusMap = {
connecting: "连接中",
connected: "已连接",
disconnected: "未连接",
error: "连接错误"
};
return statusMap[connectionStatus.value] || "未知状态";
}
return {
// 状态
connectionStatus,
//属性变量
messageString,
logs,
config,
command,
groupId,
MessageReceived,
// 计算属性
isConnected,
isConnecting,
isDisconnected,
isError,
lastMessage,
// 方法
connect,
disconnect,
send,
addLog,
clearLogs,
getStatusText
};
});
const { registerUTSInterface, initUTSProxyClass, initUTSProxyFunction, initUTSPackageName, initUTSIndexClassName, initUTSClassName } = uni;
const name = "limeChooseFile";
const moduleName = "lime-choose-file 文件选择";
const moduleType = "";
const errMsg = ``;
const is_uni_modules = true;
const pkg = /* @__PURE__ */ initUTSPackageName(name, is_uni_modules);
const cls = /* @__PURE__ */ initUTSIndexClassName(name, is_uni_modules);
const exports$1 = { __esModule: true };
exports$1.chooseFile = /* @__PURE__ */ initUTSProxyFunction(false, { moduleName, moduleType, errMsg, main: true, package: pkg, class: cls, name: "chooseFileByJs", keepAlive: false, params: [{ "name": "options", "type": "UTSSDKModulesLimeChooseFileChooseFileOptionJSONObject" }], return: "" });
uni.registerUTSPlugin("uni_modules/lime-choose-file", exports$1);
const limeChooseFile_utsProxy = uni.requireUTSPlugin("uni_modules/lime-choose-file");
const pageInfoNumber = 100;
const _sfc_main$7 = {
__name: "Chat",
setup(__props, { expose: __expose }) {
__expose();
const friendSocketStore = useFriendSocketStore();
const handleFriendConnect = () => {
if (friendSocketStore.isConnected)
return;
if (!userToken.value || !UserId.value) {
formatAppLog("warn", "at pages/Chat/Chat.vue:265", "Token或UserId未准备好");
return;
}
friendSocketStore.connect({
token: userToken.value,
UserId: UserId.value
});
};
const socketStore = useSocketStore();
const ChatType = vue.ref(0);
const convertMarkdownTable = (text) => {
const lines = text.split("\n");
let result = [];
let inTable = false;
let tableRows = [];
let alignments = [];
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
const isTableLine = /^\|.+|$/.test(line) && line.includes("|");
if (isTableLine) {
if (/^\|[\s\-:]+\|[\s\-:|]+\|$/.test(line)) {
alignments = line.split("|").filter((c) => c.trim()).map((c) => {
if (c.trim().startsWith(":") && c.trim().endsWith(":"))
return "center";
if (c.trim().endsWith(":"))
return "right";
return "left";
});
continue;
}
tableRows.push(line);
inTable = true;
} else {
if (inTable && tableRows.length > 0) {
result.push(renderTable(tableRows, alignments));
tableRows = [];
alignments = [];
inTable = false;
}
result.push(line);
}
}
if (inTable && tableRows.length > 0) {
result.push(renderTable(tableRows, alignments));
}
return result.join("\n");
};
const renderTable = (rows, alignments) => {
let html = '<table border="1" style="border-collapse:collapse;width:100%;margin:8px 0">';
rows.forEach((row, index) => {
const tag = index === 0 ? "th" : "td";
const cells = row.split("|").filter((c) => c.trim() !== "");
html += "<tr>";
cells.forEach((cell, ci) => {
const align = alignments[ci] ? ` style="text-align:${alignments[ci]}"` : "";
html += `<${tag}${align} style="padding:6px 10px;border:1px solid #ddd">${cell.trim()}</${tag}>`;
});
html += "</tr>";
});
html += "</table>";
return html;
};
const pareseMarkdown = (content) => {
if (!content)
return "";
content = sanitizeContent(content);
try {
content = convertMarkdownTable(content);
const html = t(content);
return html;
} catch (e2) {
formatAppLog("error", "at pages/Chat/Chat.vue:363", "解析失败", e2);
return content;
}
};
const sanitizeContent = (str) => {
const hasScript = /<script\b[^>]*>([\s\S]*?)<\/script>/i.test(str);
const hasFormTags = /<(form|input|select|textarea|button)\b[^>]*>/i.test(str);
let cleanedStr = str.replace(/<script\b[^>]*>([\s\S]*?)<\/script>/gi, "");
cleanedStr = cleanedStr.replace(/<\/?minimax:tool_call>/g, (m) => m.replace(/</g, "&lt;").replace(/>/g, "&gt;")).replace(/<\|[\w]+?\|>/g, (m) => m.replace(/</g, "&lt;").replace(/>/g, "&gt;"));
if (hasScript || hasFormTags) {
const warningHtml = '<h2 style="color: red; font-weight: bold;">表单仅预览,不可操作!!!</h2>';
return warningHtml + cleanedStr;
}
return cleanedStr;
};
const previewImage = (url) => {
uni.previewImage({
urls: [url]
});
};
const openFile = (url) => {
uni.downloadFile({
url,
success: (res) => {
uni.openDocument({
filePath: res.tempFilePath,
showMenu: true
});
}
});
};
const formatFileSize = (size) => {
if (!size)
return "0KB";
if (size < 1) {
return (size * 1024).toFixed(0) + "KB";
}
return size.toFixed(2) + "MB";
};
const selectNormalChat = async () => {
try {
const chars = "0123456789abcdef";
let name2 = "";
for (let i = 0; i < 24; i++) {
name2 += chars[Math.floor(Math.random() * chars.length)];
}
const workspaceId = await createWorkspace(userToken.value, name2);
if (!workspaceId) {
uni.showToast({
title: "工作区创建失败",
icon: "none"
});
return;
}
const loginInfo = uni.getStorageSync("yxd_login_info");
let userName = "";
if (loginInfo) {
userName = loginInfo.username || "";
}
const conversationId = await createConversation(userToken.value, workspaceId, "新会话", userName);
if (!conversationId) {
uni.showToast({
title: "新会话创建失败",
icon: "none"
});
return;
}
takeUserConversations();
} catch (error) {
formatAppLog("error", "at pages/Chat/Chat.vue:457", "新建普通会话失败:", error);
uni.showToast({
title: "创建会话失败,请重试",
icon: "none"
});
}
};
const showNewChatModal = vue.ref(false);
const closeNewChatModal = () => {
showNewChatModal.value = false;
};
const isChatSidebar = vue.ref(false);
const handleChatSidebar = () => {
isChatSidebar.value = !isChatSidebar.value;
};
const goWorkSpace = () => {
if (currentSessionId.value) {
uni.setStorageSync("currentSessionId", currentSessionId.value);
}
uni.navigateTo({
url: "/pages/WorkSpace/WorkSpace"
});
};
const logOut = () => {
uni.reLaunch({
url: "/pages/Login/Login"
});
};
const previewFileArray = vue.ref([]);
const uploadPhoto = () => {
formatAppLog("log", "at pages/Chat/Chat.vue:495", "点击了拍照上传");
uni.chooseImage({
count: 1,
sourceType: ["camera", "album"],
success: (res) => {
const tempFiles = res.tempFiles;
const tempFilePaths = res.tempFilePaths;
tempFiles.forEach((file, index) => {
previewFileArray.value.push({
path: tempFilePaths[index],
// 图片路径(用于显示)
name: file.name || `photo_${Date.now()}_${index}.jpg`,
// 文件名
size: file.size,
// 文件大小
type: "image",
// 文件类型标识
tempFile: file
// 原始文件对象
});
});
},
fail: (err) => {
formatAppLog("error", "at pages/Chat/Chat.vue:513", "选择图片失败", err);
}
});
};
const deleteImage = (index) => {
uni.showModal({
title: "提示",
content: "确定要删除这张图片吗?",
success: (res) => {
if (res.confirm) {
previewFileArray.value.splice(index, 1);
uni.showToast({
title: "删除成功",
icon: "success"
});
}
}
});
};
const fileList = vue.ref([]);
const uploadFile = () => {
formatAppLog("log", "at pages/Chat/Chat.vue:536", "点击了上传文件");
limeChooseFile_utsProxy.chooseFile({
count: 5,
type: "all",
success: (res) => {
formatAppLog("log", "at pages/Chat/Chat.vue:541", "成功了");
fileList.value = res.tempFiles;
previewFileArray.value.push(...res.tempFiles);
uni.showToast({
title: `已选择 ${res.tempFiles.length} 个文件`,
icon: "success"
});
},
fail: (err) => {
formatAppLog("error", "at pages/Chat/Chat.vue:552", "选择失败:", err);
uni.showToast({
title: "选择失败",
icon: "error"
});
}
});
};
const handleConnect = () => {
return new Promise((resolve, reject) => {
if (socketStore.isConnected)
return resolve();
const unwatch = vue.watch(() => socketStore.isConnected, (connected) => {
if (connected) {
unwatch();
resolve();
}
});
const unwatchError = vue.watch(() => socketStore.connectionStatus, (status) => {
if (status === "error") {
unwatch();
unwatchError();
reject(new Error("连接失败"));
}
});
socketStore.connect({
token: userToken.value,
conversationId: currentSessionId.value
});
});
};
const isThinking = vue.ref(false);
const isUploading = vue.ref(false);
const uploadedFiles = vue.ref([]);
const sendMessage = async () => {
const message = textMessage.value.trim();
if (!message && previewFileArray.value.length === 0)
return;
if (previewFileArray.value.length > 0) {
isUploading.value = true;
uni.showLoading({
title: "上传文件中...",
mask: true
});
try {
const results = [];
for (const item of previewFileArray.value) {
const result = await uploadFileToServer(item.path);
results.push(result);
}
uploadedFiles.value = results;
previewFileArray.value = [];
} catch (err) {
uni.hideLoading();
formatAppLog("error", "at pages/Chat/Chat.vue:619", "文件上传失败:", err);
uni.showToast({
title: "文件上传失败,请重试",
icon: "error"
});
isUploading.value = false;
return;
}
uni.hideLoading();
isUploading.value = false;
}
if (ChatType.value === 0)
sendAIMessage();
if (ChatType.value === 1)
sendFriendMessage();
if (ChatType.value === 2)
sendGroupMessage();
};
const sendFriendMessage = async () => {
if (!friendSocketStore.isConnecting)
await handleFriendConnect();
const receiverId = getReceiverId();
const hasFiles = uploadedFiles.value.length > 0;
const body = {
"command": 1,
"sender": UserId.value,
"receiver": receiverId,
"avatar": "",
"sessionId": currentSessionId.value,
"message": textMessage.value,
"callBackMessage": false
};
if (hasFiles) {
body.contentType = 1;
body.uploadVos = uploadedFiles.value;
}
const data = {
"version": "1.1",
"body": body
};
friendSocketStore.send(data);
const newMessageData = {
"sender": UserId.value,
"receiver": receiverId,
"content": textMessage.value,
"taskId": null,
"avatar": null,
"createTime": "",
"messageType": "null",
"contentJson": hasFiles ? JSON.stringify(uploadedFiles.value) : "null"
};
allmessages.value = [...allmessages.value, newMessageData];
textMessage.value = "";
uploadedFiles.value = [];
setTimeout(() => {
takeFriendMessages();
}, 1e3);
};
const sendGroupMessage = async () => {
if (!friendSocketStore.isConnecting)
await handleFriendConnect();
const hasFiles = uploadedFiles.value.length > 0;
const body = {
"command": 9,
"groupId": currentSessionId.value,
"message": textMessage.value || "",
"callBackMessage": hasFiles ? false : true,
"messageType": hasFiles ? 1 : 0,
"sender": UserId.value
};
if (hasFiles) {
body.uploadVos = uploadedFiles.value;
}
const data = {
"version": "1.1",
"body": body
};
friendSocketStore.send(data);
const newMessageData = {
"id": allmessages.value.length + 1,
"message": textMessage.value,
"messageType": hasFiles ? 1 : 0,
"groupId": null,
"createTime": "",
"contentJson": hasFiles ? JSON.stringify(uploadedFiles.value) : "",
"sender": UserId.value
};
allmessages.value = [...allmessages.value, newMessageData];
textMessage.value = "";
uploadedFiles.value = [];
setTimeout(() => {
takeGroupMessages();
}, 1e3);
};
let aiResponseTimer = null;
const sendAIMessage = async () => {
try {
await handleConnect();
let messageContent = textMessage.value;
if (uploadedFiles.value.length) {
const fileJson = JSON.stringify(uploadedFiles.value);
messageContent = messageContent ? `${messageContent}
[文件信息:${fileJson}]` : `[文件信息:${fileJson}]`;
}
const data = {
"type": "chat",
"conversation_id": currentSessionId.value,
"content": messageContent
};
socketStore.send(data);
isThinking.value = true;
aiResponseTimer = setTimeout(() => {
uni.showToast({
title: "AI回复超时请重试",
icon: "none"
});
isThinking.value = false;
textMessage.value = "";
uploadedFiles.value = [];
}, 18e4);
} catch (error) {
isThinking.value = false;
uni.showToast({
title: `用户发送消息失败${error}`,
icon: "error"
});
}
};
vue.watch(() => socketStore.isThinking, (newVal, oldVal) => {
formatAppLog("log", "at pages/Chat/Chat.vue:781", "isThinking 变化:", oldVal, "→", newVal);
if (oldVal && !newVal && socketStore.messageString) {
clearTimeout(aiResponseTimer);
formatAppLog("log", "at pages/Chat/Chat.vue:785", "ai返回的消息", socketStore.messageString);
formatAppLog("log", "at pages/Chat/Chat.vue:786", "AI回复结束刷新消息列表");
takeConversationMessages();
isThinking.value = false;
textMessage.value = "";
uploadedFiles.value = [];
}
});
const textMessage = vue.ref("");
const UserConversations = vue.ref([]);
const currentSessionId = vue.ref("");
const userToken = vue.ref("");
const UserId = vue.ref("");
const UserAvatar = vue.ref("");
const UserData = vue.ref(null);
const takeUserInfo = async () => {
try {
userToken.value = getToken();
UserData.value = await getUserInfo(userToken.value);
UserId.value = UserData.value._id;
UserAvatar.value = UserData.value.avatar || "";
formatAppLog("log", "at pages/Chat/Chat.vue:812", "用户信息已加载:", UserId.value, UserAvatar.value);
} catch (error) {
formatAppLog("error", "at pages/Chat/Chat.vue:814", "获取用户信息失败:", error);
}
};
const takeUserConversations = async () => {
try {
userToken.value = getToken();
formatAppLog("log", "at pages/Chat/Chat.vue:822", "token:", userToken.value);
UserConversations.value = await getUserConversations(userToken.value) || [];
formatAppLog("log", "at pages/Chat/Chat.vue:824", "UserConversations:", UserConversations.value);
const savedSessionId = getCurrentSessionId();
if (savedSessionId && UserConversations.value.some((c) => c._id === savedSessionId)) {
currentSessionId.value = savedSessionId;
} else if (UserConversations.value.length > 0) {
currentSessionId.value = UserConversations.value[0]._id;
} else {
currentSessionId.value = "";
}
formatAppLog("log", "at pages/Chat/Chat.vue:834", "保存会话id", currentSessionId.value);
uni.setStorageSync("currentSessionId", currentSessionId.value);
} catch (error) {
uni.showToast({
title: `获取会话列表失败${error}`,
icon: "error"
});
}
};
const FriendInfoList = vue.ref([]);
const takeFriendList = async () => {
try {
formatAppLog("log", "at pages/Chat/Chat.vue:849", "开始获取好友列表");
const friendList = await getChatFriend(UserId.value);
formatAppLog("log", "at pages/Chat/Chat.vue:852", "friendList:", friendList);
if (friendList && friendList.length) {
FriendInfoList.value = await takeUserAvatar(friendList);
} else {
FriendInfoList.value = [];
formatAppLog("log", "at pages/Chat/Chat.vue:857", "好友列表为空");
}
} catch (error) {
formatAppLog("error", "at pages/Chat/Chat.vue:860", "获取好友列表失败:", error);
FriendInfoList.value = [];
} finally {
UserConversations.value = FriendInfoList.value;
}
};
const takeTalkUserAvatar = (userId) => {
if (!userId)
return null;
const user = FriendInfoList.value.find((item) => item.receiver === userId);
return (user == null ? void 0 : user.avatar) || null;
};
const takeUserAvatar = async (friendList) => {
if (!(friendList == null ? void 0 : friendList.length))
return [];
try {
const friendIds = friendList.map((item) => item.receiver);
const friendAvatarList = await getUserAvatar(userToken.value, friendIds);
const userMap = new Map(friendAvatarList.map((user) => [user.user_id, user]) || []);
return friendList.map((friend) => {
const userInfo = userMap.get(friend.receiver);
return {
...friend,
avatar: (userInfo == null ? void 0 : userInfo.avatar) || null
};
});
} catch (err) {
formatAppLog("error", "at pages/Chat/Chat.vue:890", "获取好友头像失败", err);
return friendList;
}
};
const GroupList = vue.ref([]);
const takeGroupList = async () => {
try {
formatAppLog("log", "at pages/Chat/Chat.vue:900", "开始获取群聊列表");
GroupList.value = await getGroup(UserId.value);
} catch (error) {
formatAppLog("error", "at pages/Chat/Chat.vue:905", "获取群聊列表失败:", error);
GroupList.value = [];
} finally {
UserConversations.value = GroupList.value;
}
};
const groupMemberList = vue.ref([]);
const takeGroupMemberAvatar = async (memberList) => {
if (!(memberList == null ? void 0 : memberList.length))
return [];
try {
const memberIds = memberList.map((item) => item.groupContactId);
formatAppLog("log", "at pages/Chat/Chat.vue:919", "请求头像的ID列表:", memberIds);
const memberAvatarList = await getUserAvatar(userToken.value, memberIds);
formatAppLog("log", "at pages/Chat/Chat.vue:921", "头像接口返回数据:", memberAvatarList);
const userMap = new Map(memberAvatarList.map((user) => [user.user_id, user]) || []);
formatAppLog("log", "at pages/Chat/Chat.vue:924", "userMap的keys:", Array.from(userMap.keys()));
return memberList.map((member) => {
const memberId = member.groupContactId;
const userInfo = userMap.get(memberId);
formatAppLog("log", "at pages/Chat/Chat.vue:929", `查找 ${memberId} 的头像:`, userInfo);
return {
...member,
avatar: (userInfo == null ? void 0 : userInfo.avatar) || null
};
});
} catch (err) {
formatAppLog("error", "at pages/Chat/Chat.vue:936", "获取群成员头像失败", err);
return memberList;
}
};
const getGroupMemberAvatarById = (userId) => {
if (!userId)
return null;
const member = groupMemberList.value.find((item) => item.groupContactId === userId);
return (member == null ? void 0 : member.avatar) || null;
};
const allmessages = vue.ref([]);
const scrollToView = vue.ref("");
const isLoadingMore = vue.ref(false);
const currentPage = vue.ref(1);
const currentMessages = vue.computed(() => {
return allmessages.value.slice(-pageInfoNumber);
});
const takeConversationMessages = async () => {
try {
allmessages.value = await getConversationMessages(userToken.value, currentSessionId.value) || [];
scrollToBottom();
} catch (error) {
uni.showToast({
title: `获取ai会话内容失败${error}`,
icon: "none"
});
}
};
const takeFriendMessages = async () => {
try {
allmessages.value = await getFriendMessages(currentSessionId.value) || [];
formatAppLog("log", "at pages/Chat/Chat.vue:981", "好友消息:", JSON.stringify(allmessages.value));
scrollToBottom();
} catch (error) {
uni.showToast({
title: `获取好友会话消息失败${error}`,
icon: "none"
});
}
};
const takeGroupMessages = async () => {
try {
allmessages.value = await getGroupMessages(currentSessionId.value) || [];
formatAppLog("log", "at pages/Chat/Chat.vue:994", "群聊消息:", allmessages.value);
const memberList = await getGroupMemberList(currentSessionId.value);
formatAppLog("log", "at pages/Chat/Chat.vue:997", "获取到的群成员列表:", memberList);
if (memberList && memberList.length) {
groupMemberList.value = await takeGroupMemberAvatar(memberList);
formatAppLog("log", "at pages/Chat/Chat.vue:1000", "群成员列表(带头像):", groupMemberList.value);
} else {
groupMemberList.value = [];
}
scrollToBottom();
} catch (error) {
uni.showToast({
title: `获取群聊会话失败${error}`,
icon: "none"
});
}
};
const loadMoreMessages = async () => {
formatAppLog("log", "at pages/Chat/Chat.vue:1015", "加载更多信息");
if (allmessages.value.length > pageInfoNumber * currentPage.value) {
currentPage.value += 1;
const newMessages = allmessages.value.slice(-pageInfoNumber * currentPage.value);
const addMessage = newMessages.length - currentMessages.value.length;
currentMessages.value = newMessages;
await vue.nextTick();
scrollToView.value = "msg-" + (addMessage + 1);
}
};
const onScroll = (e2) => {
};
const scrollToBottom = async () => {
await vue.nextTick();
if (currentMessages.value.length > 0) {
scrollToView.value = "msg-" + (currentMessages.value.length - 1);
}
};
vue.watch(() => friendSocketStore.MessageReceived, (newId) => {
formatAppLog("log", "at pages/Chat/Chat.vue:1043", "收到了好友消息");
if (newId) {
formatAppLog("log", "at pages/Chat/Chat.vue:1045", "ChatType:", ChatType.value);
switch (ChatType.value) {
case 0:
takeConversationMessages();
friendSocketStore.MessageReceived = false;
break;
case 1:
takeFriendMessages();
friendSocketStore.MessageReceived = false;
break;
case 2:
takeGroupMessages();
friendSocketStore.MessageReceived = false;
break;
default:
formatAppLog("log", "at pages/Chat/Chat.vue:1061", "default 分支");
friendSocketStore.MessageReceived = false;
break;
}
}
}, {
immediate: true
});
vue.watch(currentSessionId, (newId) => {
if (newId) {
uni.setStorageSync("currentSessionId", currentSessionId.value);
switch (ChatType.value) {
case 0:
takeConversationMessages();
break;
case 1:
takeFriendMessages();
break;
case 2:
takeGroupMessages();
break;
default:
takeConversationMessages();
break;
}
}
}, {
immediate: true
});
vue.onMounted(() => {
});
onShow(async () => {
await takeUserInfo();
const chatType = getChatType();
ChatType.value = chatType;
const sessionId = getCurrentSessionId();
if (sessionId) {
currentSessionId.value = sessionId;
}
if (chatType === 0) {
await takeUserConversations();
if (currentSessionId.value) {
takeConversationMessages();
}
} else if (chatType === 1) {
await takeFriendList();
takeFriendMessages();
handleFriendConnect();
} else if (chatType === 2) {
await takeGroupList();
await handleFriendConnect();
await takeGroupMessages();
}
});
const __returned__ = { friendSocketStore, handleFriendConnect, socketStore, ChatType, convertMarkdownTable, renderTable, pareseMarkdown, sanitizeContent, previewImage, openFile, formatFileSize, selectNormalChat, showNewChatModal, closeNewChatModal, isChatSidebar, handleChatSidebar, goWorkSpace, logOut, previewFileArray, uploadPhoto, deleteImage, fileList, uploadFile, handleConnect, isThinking, isUploading, uploadedFiles, sendMessage, sendFriendMessage, sendGroupMessage, get aiResponseTimer() {
return aiResponseTimer;
}, set aiResponseTimer(v) {
aiResponseTimer = v;
}, sendAIMessage, textMessage, UserConversations, currentSessionId, userToken, UserId, UserAvatar, UserData, takeUserInfo, takeUserConversations, FriendInfoList, takeFriendList, takeTalkUserAvatar, takeUserAvatar, GroupList, takeGroupList, groupMemberList, takeGroupMemberAvatar, getGroupMemberAvatarById, allmessages, pageInfoNumber, scrollToView, isLoadingMore, currentPage, currentMessages, takeConversationMessages, takeFriendMessages, takeGroupMessages, loadMoreMessages, onScroll, scrollToBottom, computed: vue.computed, getCurrentInstance: vue.getCurrentInstance, nextTick: vue.nextTick, onMounted: vue.onMounted, ref: vue.ref, watch: vue.watch, get onShow() {
return onShow;
}, ChatSidebar, get getUserConversations() {
return getUserConversations;
}, get getConversationMessages() {
return getConversationMessages;
}, get addMessageDict() {
return addMessageDict;
}, get createWorkspace() {
return createWorkspace;
}, get createConversation() {
return createConversation;
}, get getUserInfo() {
return getUserInfo;
}, get getUserAvatar() {
return getUserAvatar;
}, get getToken() {
return getToken;
}, get getCurrentSessionId() {
return getCurrentSessionId;
}, get getTaskCallId() {
return getTaskCallId;
}, get getChatType() {
return getChatType;
}, get getReceiverId() {
return getReceiverId;
}, get snarkdown() {
return t;
}, get useSocketStore() {
return useSocketStore;
}, get getChatFriend() {
return getChatFriend;
}, get getGroup() {
return getGroup;
}, get getFriendMessages() {
return getFriendMessages;
}, get getGroupMessages() {
return getGroupMessages;
}, get getGroupMemberList() {
return getGroupMemberList;
}, get uploadFileToServer() {
return uploadFileToServer;
}, get useFriendSocketStore() {
return useFriendSocketStore;
}, get chooseFile() {
return limeChooseFile_utsProxy.chooseFile;
}, get socketManager() {
return socketManager;
} };
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
return __returned__;
}
};
function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
const _component_uni_icons = resolveEasycom(vue.resolveDynamicComponent("uni-icons"), __easycom_0);
return vue.openBlock(), vue.createElementBlock(
vue.Fragment,
null,
[
vue.createElementVNode("view", { class: "status-bar" }),
$setup.showNewChatModal ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "ncd-overlay",
onClick: $setup.closeNewChatModal
}, [
vue.createElementVNode("view", {
class: "ncd-card",
onClick: _cache[0] || (_cache[0] = vue.withModifiers(() => {
}, ["stop"]))
}, [
vue.createElementVNode("view", { class: "ncd-header" }, [
vue.createElementVNode("view", { class: "ncd-title-eng" }, [
vue.createElementVNode("text", null, "NEW")
]),
vue.createElementVNode("text", { class: "ncd-title-zh" }, "创建对话"),
vue.createVNode(_component_uni_icons, {
type: "closeempty",
color: "#ff0000",
size: "24",
onClick: $setup.closeNewChatModal
})
]),
vue.createElementVNode("text", null, "选择对话类型,开启全新会话体验"),
vue.createElementVNode("view", { class: "ncd-options" }, [
vue.createElementVNode("view", { class: "ncd-option ncd-normal" }, [
vue.createElementVNode("view", { class: "ncd-opt-icon" }, [
vue.createVNode(_component_uni_icons, {
type: "chat",
color: "#000000",
size: "30"
})
]),
vue.createElementVNode("view", {
class: "ncd-opt-title",
onClick: $setup.selectNormalChat
}, [
vue.createElementVNode("view", { class: "ncd-opt-title-1" }, "普通会话"),
vue.createElementVNode("view", { class: "ncd-opt-title-2" }, "与AI自由对话,探索任何话题")
]),
vue.createVNode(_component_uni_icons, {
type: "arrow-right",
class: "arrow-right-style"
})
]),
vue.createElementVNode("view", { class: "ncd-option ncd-intelligence" }, [
vue.createElementVNode("view", { class: "ncd-opt-icon" }, [
vue.createVNode(_component_uni_icons, {
type: "star",
color: "#ffffff",
size: "30"
})
]),
vue.createElementVNode("view", { class: "ncd-opt-title" }, [
vue.createElementVNode("view", { class: "ncd-opt-title-1" }, "智能体会话"),
vue.createElementVNode("view", { class: "ncd-opt-title-2" }, "选择专属智能体,获得精准专业服务")
]),
vue.createVNode(_component_uni_icons, {
type: "arrow-right",
class: "arrow-right-style"
})
])
])
])
])) : vue.createCommentVNode("v-if", true),
$setup.isThinking ? (vue.openBlock(), vue.createElementBlock("view", {
key: 1,
class: "ncd-overlay",
onClick: $setup.closeNewChatModal
}, [
vue.createElementVNode("view", {
class: "ncd-card ai-card",
onClick: _cache[1] || (_cache[1] = vue.withModifiers(() => {
}, ["stop"]))
}, [
vue.createElementVNode("view", { class: "thinking-content" }, [
vue.createElementVNode("view", { class: "loading-dots" }, [
vue.createElementVNode("view", { class: "dot" }),
vue.createElementVNode("view", { class: "dot" }),
vue.createElementVNode("view", { class: "dot" })
]),
vue.createElementVNode("text", { class: "thinking-text" }, "AI 正在思考中...")
])
])
])) : vue.createCommentVNode("v-if", true),
vue.createElementVNode("view", { class: "chat-page page-container" }, [
$setup.isChatSidebar ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "mask",
onClick: $setup.handleChatSidebar
})) : vue.createCommentVNode("v-if", true),
vue.createElementVNode(
"view",
{
class: vue.normalizeClass(["chat-sidebar", { "sidebar-show": $setup.isChatSidebar }])
},
[
vue.createVNode($setup["ChatSidebar"], {
chatList: $setup.UserConversations,
showNewChatModal: $setup.showNewChatModal,
"onUpdate:showNewChatModal": _cache[2] || (_cache[2] = ($event) => $setup.showNewChatModal = $event),
currentSessionId: $setup.currentSessionId,
"onUpdate:currentSessionId": _cache[3] || (_cache[3] = ($event) => $setup.currentSessionId = $event),
chatType: $setup.ChatType,
"onUpdate:chatType": _cache[4] || (_cache[4] = ($event) => $setup.ChatType = $event),
onRefreshConversations: $setup.takeUserConversations
}, null, 8, ["chatList", "showNewChatModal", "currentSessionId", "chatType"])
],
2
/* CLASS */
),
vue.createElementVNode("view", { class: "chat-wrapper" }, [
vue.createElementVNode("view", { class: "chat-hearder" }, [
vue.createElementVNode("view", { class: "chat-btn-group" }, [
vue.createElementVNode("view", {
class: "head-btn",
onClick: $setup.handleChatSidebar
}, [
vue.createElementVNode("view", { class: "iconfont icon-caidan" })
]),
vue.createElementVNode("view", {
class: "head-btn",
onClick: $setup.goWorkSpace
}, [
vue.createElementVNode("view", { class: "iconfont icon-wenjianjia" })
]),
vue.createElementVNode("view", {
class: "head-btn log-out",
onClick: $setup.logOut
}, [
vue.createElementVNode("view", { class: "iconfont icon-tuichu" })
])
])
]),
vue.createElementVNode("view", { class: "main-chat" }, [
vue.createElementVNode("scroll-view", {
class: "chat-messages",
direction: "vertical",
"scroll-y": "",
"scroll-into-view": $setup.scrollToView,
onScrolltoupper: $setup.loadMoreMessages,
"upper-threshold": 0,
"scroll-with-animation": true,
onScroll: $setup.onScroll
}, [
$setup.ChatType === 0 ? (vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
{ key: 0 },
vue.renderList($setup.currentMessages, (message, index) => {
var _a;
return vue.openBlock(), vue.createElementBlock("view", {
class: vue.normalizeClass(["chat-message", { "message-user": message.role === "user" }]),
key: index,
id: "msg-" + index
}, [
message.role === "user" ? (vue.openBlock(), vue.createElementBlock(
"view",
{
key: 0,
class: vue.normalizeClass(["chat-avatar", { "chat-avatar-user": message.role === "user" }])
},
[
message.role === "user" && ((_a = $setup.UserData) == null ? void 0 : _a.avatar) ? (vue.openBlock(), vue.createElementBlock("image", {
key: 0,
src: $setup.UserData.avatar,
class: "friend-avatar",
mode: "aspectFill"
}, null, 8, ["src"])) : (vue.openBlock(), vue.createElementBlock("view", {
key: 1,
class: "iconfont icon-yonghuziliao"
}))
],
2
/* CLASS */
)) : vue.createCommentVNode("v-if", true),
message.content && String(message.content).trim() !== "" ? (vue.openBlock(), vue.createElementBlock(
"view",
{
key: 1,
class: vue.normalizeClass(["chat-content", { "chat-content-user": message.role === "user" }])
},
[
vue.createElementVNode("view", {
innerHTML: $setup.pareseMarkdown(message.content)
}, null, 8, ["innerHTML"])
],
2
/* CLASS */
)) : vue.createCommentVNode("v-if", true)
], 10, ["id"]);
}),
128
/* KEYED_FRAGMENT */
)) : vue.createCommentVNode("v-if", true),
$setup.ChatType === 1 ? (vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
{ key: 1 },
vue.renderList($setup.currentMessages, (message, index) => {
var _a;
return vue.openBlock(), vue.createElementBlock("view", {
class: vue.normalizeClass(["chat-message", { "message-user": message.sender === $setup.UserId }]),
key: index,
id: "msg-" + index
}, [
vue.createElementVNode(
"view",
{
class: vue.normalizeClass(["chat-avatar", { "chat-avatar-user": message.sender === $setup.UserId }])
},
[
message.sender === $setup.UserId && ((_a = $setup.UserData) == null ? void 0 : _a.avatar) ? (vue.openBlock(), vue.createElementBlock("image", {
key: 0,
src: $setup.UserData.avatar,
class: "friend-avatar",
mode: "aspectFill"
}, null, 8, ["src"])) : $setup.takeTalkUserAvatar(message.sender) ? (vue.openBlock(), vue.createElementBlock("image", {
key: 1,
src: $setup.takeTalkUserAvatar(message.sender),
class: "friend-avatar",
mode: "aspectFill"
}, null, 8, ["src"])) : (vue.openBlock(), vue.createElementBlock("view", {
key: 2,
class: "iconfont icon-yonghuziliao"
}))
],
2
/* CLASS */
),
vue.createElementVNode(
"view",
{
class: vue.normalizeClass(["chat-content", { "chat-content-user": message.sender === $setup.UserId }])
},
[
message.content && String(message.content).trim() !== "" ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
innerHTML: $setup.pareseMarkdown(message.content)
}, null, 8, ["innerHTML"])) : vue.createCommentVNode("v-if", true),
message.contentJson ? (vue.openBlock(), vue.createElementBlock("view", {
key: 1,
class: "message-file-list"
}, [
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList(JSON.parse(message.contentJson), (file, idx) => {
return vue.openBlock(), vue.createElementBlock("view", {
key: idx,
class: "file-item"
}, [
["jpg", "jpeg", "png", "gif", "webp", "bmp"].includes(file.extendName.toLowerCase()) ? (vue.openBlock(), vue.createElementBlock("image", {
key: 0,
src: file.url,
mode: "widthFix",
class: "message-image",
onClick: ($event) => $setup.previewImage(file.url)
}, null, 8, ["src", "onClick"])) : (vue.openBlock(), vue.createElementBlock("view", {
key: 1,
class: "message-file",
onClick: ($event) => $setup.openFile(file.url)
}, [
vue.createElementVNode("view", { class: "file-icon" }, "📄"),
vue.createElementVNode(
"view",
{ class: "file-name" },
vue.toDisplayString(file.name),
1
/* TEXT */
),
vue.createElementVNode(
"view",
{ class: "file-size" },
vue.toDisplayString($setup.formatFileSize(file.fileSize)),
1
/* TEXT */
)
], 8, ["onClick"]))
]);
}),
128
/* KEYED_FRAGMENT */
))
])) : vue.createCommentVNode("v-if", true)
],
2
/* CLASS */
)
], 10, ["id"]);
}),
128
/* KEYED_FRAGMENT */
)) : vue.createCommentVNode("v-if", true),
$setup.ChatType === 2 ? (vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
{ key: 2 },
vue.renderList($setup.currentMessages, (message, index) => {
var _a;
return vue.openBlock(), vue.createElementBlock("view", {
class: vue.normalizeClass(["chat-message", { "message-user": message.sender === $setup.UserId }]),
key: index,
id: "msg-" + index
}, [
vue.createElementVNode(
"view",
{
class: vue.normalizeClass(["chat-avatar", { "chat-avatar-user": message.sender === $setup.UserId }])
},
[
message.sender === $setup.UserId && ((_a = $setup.UserData) == null ? void 0 : _a.avatar) ? (vue.openBlock(), vue.createElementBlock("image", {
key: 0,
src: $setup.UserData.avatar,
class: "friend-avatar",
mode: "aspectFill"
}, null, 8, ["src"])) : $setup.groupMemberList.length > 0 && $setup.getGroupMemberAvatarById(message.sender) ? (vue.openBlock(), vue.createElementBlock("image", {
key: 1,
src: $setup.getGroupMemberAvatarById(message.sender),
class: "friend-avatar",
mode: "aspectFill"
}, null, 8, ["src"])) : (vue.openBlock(), vue.createElementBlock("view", {
key: 2,
class: "iconfont icon-yonghuziliao"
}))
],
2
/* CLASS */
),
vue.createElementVNode(
"view",
{
class: vue.normalizeClass(["chat-content", { "chat-content-user": message.sender === $setup.UserId }])
},
[
message.message && String(message.message).trim() !== "" ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
innerHTML: $setup.pareseMarkdown(message.message)
}, null, 8, ["innerHTML"])) : vue.createCommentVNode("v-if", true),
message.contentJson ? (vue.openBlock(), vue.createElementBlock("view", {
key: 1,
class: "message-file-list"
}, [
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList(JSON.parse(message.contentJson), (file, idx) => {
return vue.openBlock(), vue.createElementBlock("view", {
key: idx,
class: "file-item"
}, [
["jpg", "jpeg", "png", "gif", "webp", "bmp"].includes(file.extendName.toLowerCase()) ? (vue.openBlock(), vue.createElementBlock("image", {
key: 0,
src: file.url,
mode: "widthFix",
class: "message-image",
onClick: ($event) => $setup.previewImage(file.url)
}, null, 8, ["src", "onClick"])) : (vue.openBlock(), vue.createElementBlock("view", {
key: 1,
class: "message-file",
onClick: ($event) => $setup.openFile(file.url)
}, [
vue.createElementVNode("view", { class: "file-icon" }, "📄"),
vue.createElementVNode(
"view",
{ class: "file-name" },
vue.toDisplayString(file.name),
1
/* TEXT */
),
vue.createElementVNode(
"view",
{ class: "file-size" },
vue.toDisplayString($setup.formatFileSize(file.fileSize)),
1
/* TEXT */
)
], 8, ["onClick"]))
]);
}),
128
/* KEYED_FRAGMENT */
))
])) : vue.createCommentVNode("v-if", true)
],
2
/* CLASS */
)
], 10, ["id"]);
}),
128
/* KEYED_FRAGMENT */
)) : vue.createCommentVNode("v-if", true)
], 40, ["scroll-into-view"]),
vue.createElementVNode("view", { class: "chat-interactive-container" }, [
vue.createElementVNode("view", { class: "chat-interactive-group" }, [
vue.createElementVNode("view", {
class: "chat-interactive-btn",
onClick: $setup.uploadPhoto
}, "拍照上传"),
vue.createElementVNode("view", {
class: "chat-interactive-btn",
onClick: _cache[5] || (_cache[5] = ($event) => $setup.uploadFile())
}, "上传文件")
]),
$setup.previewFileArray.length > 0 ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "image-list"
}, [
vue.createElementVNode(
"view",
{ class: "image-title" },
"已选择: (" + vue.toDisplayString($setup.previewFileArray.length) + ")",
1
/* TEXT */
),
vue.createElementVNode("view", { class: "image-grid" }, [
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList($setup.previewFileArray, (item, index) => {
return vue.openBlock(), vue.createElementBlock("view", {
class: "image-item",
key: index
}, [
vue.createElementVNode("view", { class: "image-info" }, [
vue.createElementVNode(
"text",
{ class: "image-name" },
vue.toDisplayString(item.name),
1
/* TEXT */
),
vue.createElementVNode("text", {
class: "delete-btn",
onClick: vue.withModifiers(($event) => $setup.deleteImage(index), ["stop"])
}, "删除", 8, ["onClick"])
])
]);
}),
128
/* KEYED_FRAGMENT */
))
])
])) : vue.createCommentVNode("v-if", true),
vue.createElementVNode("view", { class: "chat-input-container" }, [
vue.withDirectives(vue.createElementVNode(
"textarea",
{
class: "message-input",
placeholder: "输入消息...",
onConfirm: $setup.sendMessage,
"confirm-type": "send",
"onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => $setup.textMessage = $event),
"auto-height": ""
},
null,
544
/* NEED_HYDRATION, NEED_PATCH */
), [
[vue.vModelText, $setup.textMessage]
]),
vue.createElementVNode("view", { class: "input-btn-group" }, [
vue.createElementVNode("view", { class: "iconfont icon-tingzhi icon-btn" })
])
])
])
])
])
])
],
64
/* STABLE_FRAGMENT */
);
}
const PagesChatChat = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$6], ["__scopeId", "data-v-5eb7b895"], ["__file", "D:/Projects/uniapp/app-test/test1/pages/Chat/Chat.vue"]]);
const _sfc_main$6 = {
__name: "WorkSpace",
setup(__props, { expose: __expose }) {
__expose();
const UserToken = vue.ref("");
const workspaceId = vue.ref("");
const navbarBeforeTitle = vue.ref("");
const navbarTitle = vue.ref("工作区");
const isSelectFolder = vue.ref(false);
const selectFileList = vue.ref([]);
const handleSelectFolder = () => {
if (isSelectFolder.value) {
selectFileList.value = [];
}
isSelectFolder.value = !isSelectFolder.value;
};
const selectFolder = (id) => {
const index = selectFileList.value.indexOf(id);
if (index !== -1) {
selectFileList.value.splice(index, 1);
} else {
selectFileList.value.push(id);
}
};
const showNewFolder = vue.ref(false);
const isNFNFocused = vue.ref(false);
const newFolderName = vue.ref("");
const closeNewFolderModal = () => {
showNewFolder.value = false;
newFolderName.value = "";
};
const newWorkspaceFolder = () => {
showNewFolder.value = true;
};
const currentFolderPath = vue.computed(() => {
if (folderStack.value.length === 0)
return "根目录";
return "/" + folderStack.value.map((f) => f.name).join("/");
});
const folderPathPreview = vue.computed(() => {
const folderPath = folderStack.value.map((f) => f.name).join("/");
const name2 = newFolderName.value.trim();
if (name2) {
return folderPath ? `./${folderPath}/${name2}` : `./${name2}`;
}
return folderPath ? `./${folderPath}/` : "./";
});
const confirmCreateFolder = async () => {
const name2 = newFolderName.value.trim();
if (!name2) {
uni.showToast({ title: "请输入目录名称", icon: "none" });
return;
}
try {
const folderPath = folderStack.value.map((f) => f.name).join("/");
const dirPath = folderPath ? `./${folderPath}/${name2}` : `./${name2}`;
await createWorkspaceFolder(UserToken.value, workspaceId.value, dirPath);
uni.showToast({ title: "创建成功", icon: "success" });
closeNewFolderModal();
initCurrentFolderList();
} catch (error) {
formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:183", "创建文件夹失败:", error);
uni.showToast({ title: "创建失败,请重试", icon: "error" });
}
};
const handleLongPress = (folder) => {
if (isSelectFolder.value)
return;
uni.showActionSheet({
itemList: ["重命名", "删除", "下载", "压缩"],
success: (res) => {
switch (res.tapIndex) {
case 0:
handleRename(folder);
break;
case 1:
handleDelete(folder);
break;
case 2:
handleDownload(folder);
break;
case 3:
handleDownload(folder);
break;
}
}
});
};
const handleRename = (folder) => {
uni.showModal({
title: "重命名",
content: "请输入新名称",
editable: true,
placeholderText: folder.name,
success: (res) => {
if (res.confirm && res.content) {
updateFolderName(folder.id, res.content);
}
}
});
};
const handleDownload = async (folder) => {
if (folder.type === "directory") {
uni.showToast({ title: "暂不支持下载目录", icon: "none" });
return;
}
try {
uni.showLoading({ title: "获取下载链接..." });
const filePath = folder.path.startsWith("./") ? folder.path.slice(2) : folder.path;
const result = await getWorkspaceFileURL(UserToken.value, workspaceId.value, filePath);
uni.hideLoading();
const fileInfo = Array.isArray(result) ? result[0] : result;
if (!fileInfo || !fileInfo.url) {
uni.showToast({ title: "获取下载链接失败", icon: "error" });
return;
}
const downloadUrl = fileInfo.url;
const fileName = folder.name;
uni.showLoading({ title: "下载中..." });
uni.downloadFile({
url: downloadUrl,
name: fileName,
// 重要:指定文件名,保证打开正常
success: (downloadRes) => {
uni.hideLoading();
if (downloadRes.statusCode === 200) {
uni.openDocument({
filePath: downloadRes.tempFilePath,
showMenu: true,
// 右上角显示 分享/保存 按钮
success: () => {
uni.showToast({
title: "打开成功",
icon: "success"
});
},
fail: (err) => {
formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:335", "打开失败:", err);
uni.showToast({
title: "无法打开此文件",
icon: "error"
});
}
});
} else {
uni.showToast({ title: "下载失败", icon: "error" });
}
},
fail: (err) => {
uni.hideLoading();
formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:348", "下载文件失败:", err);
uni.showToast({ title: "下载失败,请重试", icon: "error" });
}
});
} catch (error) {
uni.hideLoading();
formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:354", "获取下载链接失败:", error);
uni.showToast({ title: "获取下载链接失败,请重试", icon: "error" });
}
};
const handleDelete = (folder) => {
uni.showModal({
title: "提示",
content: `确定要删除"${folder.name}"吗?`,
success: async (res) => {
if (res.confirm) {
try {
const filePath = `./${folder.path}`;
formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:369", "删除的是:", filePath);
await daleteWorkspace(UserToken.value, workspaceId.value, filePath);
uni.showToast({ title: "删除成功", icon: "success" });
initCurrentFolderList();
} catch (error) {
formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:374", "删除失败:", error);
uni.showToast({ title: "删除失败,请重试", icon: "error" });
}
}
}
});
};
const isMenuOpen = vue.ref(false);
const handleMenu = () => {
isMenuOpen.value = !isMenuOpen.value;
};
const searchKeyword = vue.ref("");
const isSearchFocus = vue.ref(false);
const handleSearchFocus = () => {
isSearchFocus.value = !isSearchFocus.value;
};
const getFileIcon = (ext) => {
const iconMap = {
".png": "icon-wenjiantupian",
".jpg": "icon-wenjiantupian",
".jpeg": "icon-wenjiantupian",
".gif": "icon-wenjiantupian",
".svg": "icon-SVG",
".bmp": "icon-wenjiantupian",
".webp": "icon-wenjiantupian",
".mp4": "icon-wenjianshipin",
".avi": "icon-wenjianshipin",
".mov": "icon-wenjianshipin",
".wmv": "icon-wenjianshipin",
".flv": "icon-wenjianshipin",
".mkv": "icon-wenjianshipin",
".mp3": "icon-wenjianyinpin",
".wav": "icon-wenjianyinpin",
".flac": "icon-wenjianyinpin",
".aac": "icon-wenjianyinpin",
".pdf": "icon-PDF",
".doc": "icon-DOC",
".docx": "icon-DOC",
".xls": "icon-XLS",
".xlsx": "icon-XLS",
".ppt": "icon-PPT",
".pptx": "icon-PPT",
".txt": "icon-TXT",
".md": "icon-file-markdown-fill",
".zip": "icon-wenjianyasuo",
".rar": "icon-wenjianyasuo",
".7z": "icon-wenjianyasuo",
".tar": "icon-wenjianyasuo",
".gz": "icon-wenjianyasuo",
".js": "icon-JS",
".ts": "icon-daimawenjia",
".vue": "icon-daimawenjia",
".html": "icon-HTML",
".css": "icon-CSS",
".py": "icon-daimawenjian",
".java": "icon-daimawenjian",
".json": "icon-JSON"
};
return iconMap[ext == null ? void 0 : ext.toLowerCase()] || "icon-qitawenjian";
};
const allFoldersData = vue.ref({});
const folderStack = vue.ref([]);
const currentFolderList = vue.ref([]);
const getCurrentFolderList = () => {
var _a, _b;
formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:452", "当前路径为:", JSON.stringify(folderStack.value));
const currentPath = folderStack.value.length > 0 ? folderStack.value[folderStack.value.length - 1].path : ".";
if (currentPath === ".") {
return ((_a = allFoldersData.value) == null ? void 0 : _a.children) || [];
}
const findFolderByPath = (list, targetPath) => {
var _a2;
for (const item of list) {
if (item.path === targetPath)
return item;
if (item.type === "directory" && ((_a2 = item.children) == null ? void 0 : _a2.length)) {
const res = findFolderByPath(item.children, targetPath);
if (res)
return res;
}
}
return null;
};
const currentFolder = findFolderByPath(((_b = allFoldersData.value) == null ? void 0 : _b.children) || [], currentPath);
return currentFolder ? currentFolder.children : [];
};
const initCurrentFolderList = async () => {
workspaceId.value = getWorkspaceId();
UserToken.value = getToken();
formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:479", "getWorkspaceId:", workspaceId.value);
allFoldersData.value = await getWorkspaceList(UserToken.value, workspaceId.value);
currentFolderList.value = getCurrentFolderList();
};
const handleFolderClick = (folder) => {
if (folder.type !== "directory")
return;
folderStack.value.push({
path: folder.path,
name: folder.name
});
navbarTitle.value = folder.name;
navbarBeforeTitle.value = folderStack.value.length > 1 ? folderStack.value[folderStack.value.length - 2].name : "工作区";
currentFolderList.value = getCurrentFolderList();
searchKeyword.value = "";
isSearchFocus.value = false;
};
const handleSelectAll = () => {
if (selectFileList.value.length === currentFolderList.value.length) {
selectFileList.value = [];
} else {
selectFileList.value = currentFolderList.value.map((f) => f.path);
}
};
const handleBackOrCheck = () => {
if (isSelectFolder.value) {
handleSelectAll();
return;
}
if (folderStack.value.length > 0) {
folderStack.value.pop();
if (folderStack.value.length === 0) {
navbarTitle.value = "工作区";
navbarBeforeTitle.value = null;
} else {
navbarTitle.value = folderStack.value[folderStack.value.length - 1].name;
navbarBeforeTitle.value = folderStack.value.length > 1 ? folderStack.value[folderStack.value.length - 2].name : "工作区";
}
initCurrentFolderList();
searchKeyword.value = "";
isSearchFocus.value = false;
} else {
uni.navigateBack({
delta: 1,
fail() {
formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:536", "返回失败,进入兜底跳转");
uni.reLaunch({
url: "/pages/Chat/Chat"
});
}
});
}
};
vue.onMounted(() => {
initCurrentFolderList();
});
const __returned__ = { UserToken, workspaceId, navbarBeforeTitle, navbarTitle, isSelectFolder, selectFileList, handleSelectFolder, selectFolder, showNewFolder, isNFNFocused, newFolderName, closeNewFolderModal, newWorkspaceFolder, currentFolderPath, folderPathPreview, confirmCreateFolder, handleLongPress, handleRename, handleDownload, handleDelete, isMenuOpen, handleMenu, searchKeyword, isSearchFocus, handleSearchFocus, getFileIcon, allFoldersData, folderStack, currentFolderList, getCurrentFolderList, initCurrentFolderList, handleFolderClick, handleSelectAll, handleBackOrCheck, onMounted: vue.onMounted, ref: vue.ref, computed: vue.computed, get getWorkspaceId() {
return getWorkspaceId;
}, get getToken() {
return getToken;
}, get getWorkspaceList() {
return getWorkspaceList;
}, get createWorkspaceFolder() {
return createWorkspaceFolder;
}, get daleteWorkspace() {
return daleteWorkspace;
}, get getWorkspaceFileURL() {
return getWorkspaceFileURL;
} };
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
return __returned__;
}
};
function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
const _component_uni_icons = resolveEasycom(vue.resolveDynamicComponent("uni-icons"), __easycom_0);
return vue.openBlock(), vue.createElementBlock(
vue.Fragment,
null,
[
vue.createElementVNode("view", { class: "status-bar" }),
$setup.showNewFolder ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "popup-overlay",
onClick: $setup.closeNewFolderModal
}, [
vue.createElementVNode("view", {
class: "popup-card",
onClick: _cache[3] || (_cache[3] = vue.withModifiers(() => {
}, ["stop"]))
}, [
vue.createElementVNode("view", {
class: "close-popup-card",
onClick: $setup.closeNewFolderModal
}, [
vue.createElementVNode("view", { class: "iconfont icon-quxiao" })
]),
vue.createElementVNode("view", { class: "popup-title" }, "新建工作区目录"),
vue.createElementVNode("view", { class: "new-folder-name" }, "目录名称"),
vue.createElementVNode(
"view",
{
class: vue.normalizeClass(["create-folder-name", { "has-value": $setup.isNFNFocused || $setup.newFolderName }])
},
[
vue.withDirectives(vue.createElementVNode(
"input",
{
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.newFolderName = $event),
onFocus: _cache[1] || (_cache[1] = ($event) => $setup.isNFNFocused = true),
onBlur: _cache[2] || (_cache[2] = ($event) => $setup.isNFNFocused = false),
type: "text",
placeholder: "输入目录名称,如:项目资料/设计图"
},
null,
544
/* NEED_HYDRATION, NEED_PATCH */
), [
[vue.vModelText, $setup.newFolderName]
])
],
2
/* CLASS */
),
vue.createElementVNode("view", { class: "nf-path-label" }, "当前路径"),
vue.createElementVNode(
"view",
{ class: "nf-path-display" },
vue.toDisplayString($setup.currentFolderPath),
1
/* TEXT */
),
vue.createElementVNode("view", { class: "nf-path-label" }, "路径预览"),
vue.createElementVNode(
"view",
{ class: "nf-path-preview" },
vue.toDisplayString($setup.folderPathPreview),
1
/* TEXT */
),
vue.createElementVNode("view", { class: "option-wrapper" }, [
vue.createElementVNode("view", {
class: "opt-btn opt-cancel",
onClick: $setup.closeNewFolderModal
}, "取消"),
vue.createElementVNode("view", {
class: "opt-btn opt-confirm",
onClick: $setup.confirmCreateFolder
}, "确认")
])
])
])) : vue.createCommentVNode("v-if", true),
vue.createElementVNode("view", { class: "workspace-container page-container" }, [
vue.createElementVNode("view", { class: "workspace-header" }, [
vue.createElementVNode("view", { class: "custom-navbar" }, [
vue.createElementVNode("view", {
class: "navbar-left",
onClick: _cache[4] || (_cache[4] = (...args) => $setup.handleBackOrCheck && $setup.handleBackOrCheck(...args))
}, [
vue.createElementVNode("view", { class: "iconfont icon-fanhui custom-navbar-icon" }),
vue.createElementVNode(
"view",
{ class: "navbar-before-title workspace-text" },
vue.toDisplayString($setup.isSelectFolder ? "全选" : $setup.navbarBeforeTitle),
1
/* TEXT */
)
]),
vue.createElementVNode(
"view",
{ class: "navbar-title workspace-text" },
vue.toDisplayString($setup.navbarTitle),
1
/* TEXT */
),
vue.createElementVNode("view", { class: "navbar-right" }, [
$setup.isSelectFolder ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "navbar-right-text workspace-text",
onClick: _cache[5] || (_cache[5] = ($event) => $setup.handleSelectFolder())
}, " 完成")) : (vue.openBlock(), vue.createElementBlock(
"view",
{
key: 1,
class: vue.normalizeClass(["iconfont icon-gengduo", $setup.isMenuOpen ? "menu-open" : "custom-navbar-icon"]),
onClick: $setup.handleMenu
},
null,
2
/* CLASS */
))
]),
$setup.isMenuOpen ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "menu-card"
}, [
vue.createElementVNode("view", {
class: "menu-card-item",
onClick: _cache[6] || (_cache[6] = ($event) => {
$setup.handleSelectFolder();
$setup.handleMenu();
})
}, "选择"),
vue.createElementVNode("view", { class: "solid-line" }),
vue.createElementVNode("view", {
class: "menu-card-item",
onClick: _cache[7] || (_cache[7] = ($event) => {
$setup.newWorkspaceFolder();
$setup.handleMenu();
})
}, "新建文件夹")
])) : vue.createCommentVNode("v-if", true)
]),
vue.createElementVNode("view", { class: "search-file-warpper" }, [
vue.createElementVNode("view", { class: "search-file" }, [
vue.createElementVNode("view", { class: "iconfont icon-sousuo" }),
vue.withDirectives(vue.createElementVNode(
"input",
{
class: "search-file-input",
placeholder: "搜索",
onFocus: $setup.handleSearchFocus,
"onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => $setup.searchKeyword = $event)
},
null,
544
/* NEED_HYDRATION, NEED_PATCH */
), [
[vue.vModelText, $setup.searchKeyword]
])
]),
$setup.isSearchFocus ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "cancel-search",
onClick: $setup.handleSearchFocus
}, "取消")) : vue.createCommentVNode("v-if", true)
])
]),
vue.createElementVNode("view", { class: "workspace-content" }, [
$setup.currentFolderList.length === 0 ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "folder-null"
}, [
vue.createElementVNode("view", { class: "iconfont icon-wenjianjia" }),
vue.createTextVNode(" 文件夹为空 ")
])) : vue.createCommentVNode("v-if", true),
$setup.currentFolderList.length > 0 ? (vue.openBlock(), vue.createElementBlock("view", {
key: 1,
class: "folder-grid"
}, [
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList($setup.currentFolderList, (folder) => {
return vue.openBlock(), vue.createElementBlock("view", {
class: vue.normalizeClass(["folder-item", { "select-folder": $setup.selectFileList.includes(folder.path) }]),
key: folder.path,
onClick: ($event) => $setup.isSelectFolder ? $setup.selectFolder(folder.path) : $setup.handleFolderClick(folder),
onLongpress: ($event) => $setup.handleLongPress(folder)
}, [
folder.type === "directory" ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "iconfont icon-a-wenjianjiawenjian folder-item-style"
})) : (vue.openBlock(), vue.createElementBlock(
"view",
{
key: 1,
class: vue.normalizeClass(["iconfont folder-item-style", $setup.getFileIcon(folder.extension)])
},
null,
2
/* CLASS */
)),
vue.createElementVNode(
"view",
{ class: "folder-name" },
vue.toDisplayString(folder.name),
1
/* TEXT */
),
$setup.isSelectFolder ? (vue.openBlock(), vue.createElementBlock(
"view",
{
key: 2,
class: vue.normalizeClass(["folder-checkbox", { "select-folder": $setup.selectFileList.includes(folder.path) }])
},
[
$setup.selectFileList.includes(folder.path) ? (vue.openBlock(), vue.createBlock(_component_uni_icons, {
key: 0,
type: "checkmarkempty",
color: "#fff"
})) : vue.createCommentVNode("v-if", true)
],
2
/* CLASS */
)) : vue.createCommentVNode("v-if", true)
], 42, ["onClick", "onLongpress"]);
}),
128
/* KEYED_FRAGMENT */
))
])) : vue.createCommentVNode("v-if", true)
]),
$setup.isSelectFolder ? (vue.openBlock(), vue.createElementBlock(
"view",
{
key: 0,
class: vue.normalizeClass(["workspace-footer", { "folder-actions": $setup.selectFileList.length > 0 }])
},
[
vue.createElementVNode("view", { class: "iconfont icon-shangchuan" }),
vue.createElementVNode("view", { class: "iconfont icon-fuzhi" }),
vue.createElementVNode("view", { class: "iconfont icon-wenjian" }),
vue.createElementVNode("view", { class: "iconfont icon-del" }),
vue.createElementVNode("view", { class: "iconfont icon-gengduo" })
],
2
/* CLASS */
)) : vue.createCommentVNode("v-if", true)
])
],
64
/* STABLE_FRAGMENT */
);
}
const PagesWorkSpaceWorkSpace = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render$5], ["__scopeId", "data-v-c1a60359"], ["__file", "D:/Projects/uniapp/app-test/test1/pages/WorkSpace/WorkSpace.vue"]]);
const _sfc_main$5 = {
__name: "UserProfileModal",
setup(__props, { expose: __expose }) {
__expose();
const closeUserCard = () => {
formatAppLog("log", "at pages/UserProfileModal/UserProfileModal.vue:55", "点击了返回");
uni.navigateBack({
delta: 1,
fail() {
uni.reLaunch({
url: "/pages/Chat/Chat"
});
}
});
};
const saveUpdate = () => {
uni.navigateBack({
url: "/pages/Chat/Chat"
});
};
const editUserAvatar = vue.ref("");
const editUsername = vue.ref("");
const editEmail = vue.ref("");
const isNameFocus = vue.ref(false);
const isEmailFocus = vue.ref(false);
const triggerAvatarUpload = () => {
uni.chooseImage({
count: 1,
sizeType: ["compressed"],
sourceType: ["album", "camera"],
success: (res) => {
const tempFilePath = res.tempFilePaths[0];
handlrImageSelected(tempFilePath);
},
fail: (err) => {
formatAppLog("log", "at pages/UserProfileModal/UserProfileModal.vue:90", "选择图片失败", err);
}
});
};
const handlrImageSelected = (filePath) => {
editUserAvatar.value = filePath;
};
vue.onMounted(async () => {
const token = getToken();
const UserInfo = await getUserInfo(token);
editUserAvatar.value = UserInfo.avatar || "";
editUsername.value = UserInfo.username || "";
editEmail.value = UserInfo.email || "";
});
const __returned__ = { closeUserCard, saveUpdate, editUserAvatar, editUsername, editEmail, isNameFocus, isEmailFocus, triggerAvatarUpload, handlrImageSelected, onMounted: vue.onMounted, ref: vue.ref, get getUserInfo() {
return getUserInfo;
}, get getToken() {
return getToken;
} };
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
return __returned__;
}
};
function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
const _component_uni_icons = resolveEasycom(vue.resolveDynamicComponent("uni-icons"), __easycom_0);
return vue.openBlock(), vue.createElementBlock(
vue.Fragment,
null,
[
vue.createElementVNode("view", { class: "status-bar" }),
vue.createElementVNode("view", { class: "user-profile page-container" }, [
vue.createElementVNode("view", { class: "modal-header" }, [
vue.createElementVNode("view", {
class: "modal-left",
onClick: $setup.closeUserCard
}, [
vue.createElementVNode("view", { class: "iconfont icon-fanhui custom-navbar-icon" })
]),
vue.createElementVNode("view", { class: "modal-title" }, [
vue.createElementVNode("view", { class: "title-text" }, "编辑资料")
]),
vue.createElementVNode("view", {
class: "modal-right",
onClick: $setup.saveUpdate
}, [
vue.createElementVNode("view", { class: "save-btn" }, "保存")
])
]),
vue.createElementVNode("view", { class: "modal-body" }, [
vue.createElementVNode("view", {
class: "avatar-upload-section",
onClick: $setup.triggerAvatarUpload
}, [
vue.createElementVNode("view", { class: "avatar-upload-container" }, [
$setup.editUserAvatar ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "avatar-preview"
}, [
vue.createElementVNode("image", {
src: $setup.editUserAvatar,
mode: "aspectFill"
}, null, 8, ["src"])
])) : (vue.openBlock(), vue.createElementBlock("view", {
key: 1,
class: "avatar-placeholder"
}, [
vue.createVNode(_component_uni_icons, {
type: "person-filled",
size: "100rpx",
color: "#ffffff"
})
]))
])
]),
vue.createElementVNode("view", { class: "form-card" }, [
vue.createElementVNode("view", { class: "form-field" }, [
vue.createElementVNode("view", { class: "form-text" }, "用户名"),
vue.withDirectives(vue.createElementVNode(
"input",
{
"adjust-position": "false",
class: vue.normalizeClass(["form-field-input form-field-username", { "edit-input-focus": $setup.isNameFocus }]),
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.editUsername = $event),
onFocus: _cache[1] || (_cache[1] = ($event) => $setup.isNameFocus = true),
onBlur: _cache[2] || (_cache[2] = ($event) => $setup.isNameFocus = false)
},
null,
34
/* CLASS, NEED_HYDRATION */
), [
[vue.vModelText, $setup.editUsername]
])
]),
vue.createElementVNode("view", { class: "solid-line" }),
vue.createElementVNode("view", { class: "form-field" }, [
vue.createElementVNode("view", { class: "form-text" }, "邮箱"),
vue.withDirectives(vue.createElementVNode(
"input",
{
"adjust-position": "false",
class: vue.normalizeClass(["form-field-input form-field-emile", { "edit-input-focus": $setup.isEmailFocus }]),
"onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => $setup.editEmail = $event),
onFocus: _cache[4] || (_cache[4] = ($event) => $setup.isEmailFocus = true),
onBlur: _cache[5] || (_cache[5] = ($event) => $setup.isEmailFocus = false)
},
null,
34
/* CLASS, NEED_HYDRATION */
), [
[vue.vModelText, $setup.editEmail]
])
])
]),
vue.createElementVNode("view", { class: "prompt-content" }, "*保存后再返回哟")
])
])
],
64
/* STABLE_FRAGMENT */
);
}
const PagesUserProfileModalUserProfileModal = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$4], ["__scopeId", "data-v-d2908b51"], ["__file", "D:/Projects/uniapp/app-test/test1/pages/UserProfileModal/UserProfileModal.vue"]]);
const _sfc_main$4 = {
__name: "ContactPages",
setup(__props, { expose: __expose }) {
__expose();
const friendSocketStore = useFriendSocketStore();
const handleFriendConnect = () => {
if (friendSocketStore.isConnected)
return;
if (!userToken.value || !UserId.value) {
formatAppLog("warn", "at pages/ContactPages/ContactPages.vue:325", "Token或UserId未准备好");
return;
}
friendSocketStore.connect({
token: userToken.value,
UserId: UserId.value
});
};
const handleBack = () => {
uni.navigateBack({
delta: 1,
fail() {
uni.reLaunch({
url: "/pages/Chat/Chat"
});
}
});
};
const changeChatType = (type, sessionId = "") => {
uni.setStorageSync("chatType", type);
if (sessionId) {
uni.setStorageSync("currentSessionId", sessionId);
}
uni.reLaunch({
url: "/pages/Chat/Chat"
});
};
const currentTab = vue.ref(0);
const tabList = vue.reactive([
{
name: "contacts",
label: "通讯录",
icon: "📞"
},
{
name: "createGroup",
label: "新建群聊",
icon: "👥"
},
{
name: "addFriend",
label: "添加好友",
icon: ""
},
{
name: "videoCall",
label: "视频会议",
icon: "📹"
},
{
name: "friendRequest",
label: "好友申请",
icon: "📨"
}
]);
const onSwiperChange = (e2) => {
currentTab.value = e2.detail.current;
};
const switchTab = (index) => {
currentTab.value = index;
};
const userToken = vue.ref("");
const UserId = vue.ref("");
const FriendAI = {
id: "ai_robot",
name: "宇恒一号",
avatar: "",
type: "ai",
description: "AI智能助手",
lastMessage: null
};
const FriendInfoList = vue.ref([]);
const takeFriendList = async () => {
try {
formatAppLog("log", "at pages/ContactPages/ContactPages.vue:426", "开始获取好友列表");
userToken.value = getToken();
const userInfo = await getUserInfo(userToken.value);
UserId.value = userInfo._id;
formatAppLog("log", "at pages/ContactPages/ContactPages.vue:430", "UserId.value", UserId.value);
const friendList = await getChatFriend(UserId.value);
formatAppLog("log", "at pages/ContactPages/ContactPages.vue:432", "friendList:", friendList);
if (friendList && friendList.length) {
FriendInfoList.value = await takeUserAvatar(friendList);
} else {
FriendInfoList.value = [];
formatAppLog("log", "at pages/ContactPages/ContactPages.vue:437", "好友列表为空");
}
} catch (error) {
formatAppLog("error", "at pages/ContactPages/ContactPages.vue:440", "获取好友列表失败:", error);
FriendInfoList.value = [];
}
};
const takeUserAvatar = async (friendList) => {
if (!(friendList == null ? void 0 : friendList.length))
return [];
try {
const friendIds = friendList.map((item) => item.receiver);
const friendAvatarList = await getUserAvatar(userToken.value, friendIds);
const userMap = new Map(friendAvatarList.map((user) => [user.user_id, user]) || []);
return friendList.map((friend) => {
const userInfo = userMap.get(friend.receiver);
return {
...friend,
avatar: (userInfo == null ? void 0 : userInfo.avatar) || null
};
});
} catch (err) {
formatAppLog("error", "at pages/ContactPages/ContactPages.vue:461", "获取好友头像失败", err);
return friendList;
}
};
vue.onMounted(async () => {
await takeFriendList();
await takeGroupList();
handleFriendConnect();
});
const GroupList = vue.ref([]);
const takeGroupList = async () => {
try {
formatAppLog("log", "at pages/ContactPages/ContactPages.vue:477", "开始获取群聊列表");
userToken.value = getToken();
const userInfo = await getUserInfo(userToken.value);
UserId.value = userInfo._id;
formatAppLog("log", "at pages/ContactPages/ContactPages.vue:481", "UserId.value", UserId.value);
GroupList.value = await getGroup(UserId.value);
} catch (error) {
formatAppLog("error", "at pages/ContactPages/ContactPages.vue:484", "获取群聊列表失败:", error);
GroupList.value = [];
}
};
const createGroupName = vue.ref("");
const createGroupData = vue.ref();
const ensureFriendSocketConnected = () => {
return new Promise((resolve, reject) => {
if (friendSocketStore.isConnected) {
resolve();
return;
}
if (!userToken.value || !UserId.value) {
reject(new Error("Token或UserId未准备好"));
return;
}
formatAppLog("log", "at pages/ContactPages/ContactPages.vue:505", "friendSocket 未连接,正在建立连接...");
friendSocketStore.connect({
token: userToken.value,
UserId: UserId.value
});
const checkInterval = setInterval(() => {
if (friendSocketStore.isConnected) {
clearInterval(checkInterval);
formatAppLog("log", "at pages/ContactPages/ContactPages.vue:514", "friendSocket 连接已建立");
resolve();
}
}, 100);
setTimeout(() => {
clearInterval(checkInterval);
if (!friendSocketStore.isConnected) {
reject(new Error("连接超时"));
}
}, 1e4);
});
};
const createGroup = async () => {
try {
if (!createGroupName.value) {
uni.showToast({
title: "群名称不能为空",
icon: "none"
});
return;
}
if (selectGroupMember.value.length === 0) {
uni.showToast({
title: "请选择群成员",
icon: "none"
});
return;
}
await ensureFriendSocketConnected();
const memberIds = selectGroupMember.value.map((member) => member.id);
createGroupData.value = {
"version": "1.1",
"body": {
"command": 3,
"userIds": memberIds,
"message": "我来邀请你们了",
"sender": UserId.value,
"callBackMessage": true,
"groupName": createGroupName.value,
"teamCreateReq": {
"access_token": userToken.value
}
}
};
const isSend = await friendSocketStore.send(createGroupData.value);
if (isSend) {
await sendCreateGroup();
} else {
formatAppLog("log", "at pages/ContactPages/ContactPages.vue:570", "发送新建群聊消息失败");
}
} catch (err) {
formatAppLog("log", "at pages/ContactPages/ContactPages.vue:573", err);
uni.showToast({
title: `新建群聊失败${err}`,
icon: "none"
});
}
};
const sendCreateGroup = () => {
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
reject(new Error("超时未返回群聊创建结果"));
}, 18e4);
const unwatch = vue.watch(() => friendSocketStore.command, async (newVal) => {
formatAppLog("log", "at pages/ContactPages/ContactPages.vue:592", "创建一个一次性监听器");
if (newVal && friendSocketStore.command === 3) {
formatAppLog("log", "at pages/ContactPages/ContactPages.vue:594", "监听到command的值是3,检查群聊是否创建成功", friendSocketStore.command);
try {
await takeGroupList();
const newGroup = GroupList.value.find((g) => g.id === friendSocketStore.groupId);
if (newGroup) {
formatAppLog("log", "at pages/ContactPages/ContactPages.vue:601", "✅ 新建群聊成功", newGroup);
selectGroupMember.value = [];
currentTab.value = 0;
} else {
formatAppLog("log", "at pages/ContactPages/ContactPages.vue:606", "❌ 新建群聊失败 / 群组不存在");
}
} catch (error) {
formatAppLog("error", "at pages/ContactPages/ContactPages.vue:610", "保存AI回复失败", error);
reject(error);
} finally {
friendSocketStore.command = null;
friendSocketStore.groupId = null;
unwatch();
clearTimeout(timeout);
}
}
});
});
};
const selectGroupMember = vue.ref([]);
const handlCreateEmember = (id) => {
formatAppLog("log", "at pages/ContactPages/ContactPages.vue:631", "选择的好友id", id);
formatAppLog("log", "at pages/ContactPages/ContactPages.vue:632", "selectGroupMember.value=", JSON.stringify(selectGroupMember.value));
const index = selectGroupMember.value.findIndex((item) => item.id === id);
if (index === -1) {
const friendItem = FriendInfoList.value.find((item) => item.receiver === id);
if (friendItem) {
selectGroupMember.value.push({
id: friendItem.receiver,
friendNickName: friendItem.friendNickName
});
}
} else {
selectGroupMember.value.splice(index, 1);
}
};
const isSearchFriend = vue.ref(false);
const searchFriendName = vue.ref("");
const searchResultList = vue.ref([]);
const searchFriend = async () => {
if (!searchFriendName.value.trim()) {
searchResultList.value = [];
return;
}
const keyword = searchFriendName.value.toLowerCase().trim();
searchResultList.value = await searchUsers(userToken.value, keyword);
formatAppLog("log", "at pages/ContactPages/ContactPages.vue:659", "searchResultList.value", searchResultList.value);
};
const handleFriendSearchFocus = () => {
isSearchFriend.value = !isSearchFriend.value;
};
const currentAddFriend = vue.ref(null);
const addNewFriend = (id) => {
const friend = mockFriendDB.value.find((friend2) => friend2.id === id);
if (friend) {
currentAddFriend.value = {
...friend
};
} else {
formatAppLog("warn", "at pages/ContactPages/ContactPages.vue:680", "未找到该好友");
currentAddFriend.value = null;
}
};
const closeAddFriendCard = () => {
currentAddFriend.value = null;
isAgreeBeFriend.value = false;
};
const isVoice = vue.ref(false);
const isCamera = vue.ref(false);
const togglesVoice = () => {
isVoice.value = !isVoice.value;
};
const togglesCamera = () => {
isCamera.value = !isCamera.value;
};
const isAgreeBeFriend = vue.ref(false);
const refuseBeFriend = (friend) => {
};
const agreeBeFriend = (friend) => {
isAgreeBeFriend.value = true;
currentAddFriend.value = {
...friend
};
};
const mockFriendDB = vue.ref([
{
id: 1,
nickname: "张三",
username: "zhangsan",
email: "zhangsan@example.com",
avatar: "👤"
},
{
id: 2,
nickname: "李四",
username: "lisi",
email: "lisi@example.com",
avatar: "👥"
},
{
id: 3,
nickname: "王小明",
username: "wangxm",
email: "wang@example.com",
avatar: "👪"
},
{
id: 4,
nickname: "赵磊",
username: "zhaolei",
email: "zhao@example.com",
avatar: "🗣️"
},
{
id: 5,
nickname: "张三2",
username: "zhangsan",
email: "zhangsan@example.com",
avatar: "👤"
},
{
id: 6,
nickname: "李四2",
username: "lisi",
email: "lisi@example.com",
avatar: "👥"
},
{
id: 7,
nickname: "王小明2",
username: "wangxm",
email: "wang@example.com",
avatar: "👪"
},
{
id: 8,
nickname: "赵磊2",
username: "zhaolei",
email: "zhao@example.com",
avatar: "🗣️"
}
]);
const __returned__ = { friendSocketStore, handleFriendConnect, handleBack, changeChatType, currentTab, tabList, onSwiperChange, switchTab, userToken, UserId, FriendAI, FriendInfoList, takeFriendList, takeUserAvatar, GroupList, takeGroupList, createGroupName, createGroupData, ensureFriendSocketConnected, createGroup, sendCreateGroup, selectGroupMember, handlCreateEmember, isSearchFriend, searchFriendName, searchResultList, searchFriend, handleFriendSearchFocus, currentAddFriend, addNewFriend, closeAddFriendCard, isVoice, isCamera, togglesVoice, togglesCamera, isAgreeBeFriend, refuseBeFriend, agreeBeFriend, mockFriendDB, onMounted: vue.onMounted, reactive: vue.reactive, ref: vue.ref, watch: vue.watch, get getToken() {
return getToken;
}, get getChatFriend() {
return getChatFriend;
}, get getGroup() {
return getGroup;
}, get getUserInfo() {
return getUserInfo;
}, get getUserAvatar() {
return getUserAvatar;
}, get searchUsers() {
return searchUsers;
}, get useFriendSocketStore() {
return useFriendSocketStore;
} };
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
return __returned__;
}
};
function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
const _component_uni_icons = resolveEasycom(vue.resolveDynamicComponent("uni-icons"), __easycom_0);
return vue.openBlock(), vue.createElementBlock(
vue.Fragment,
null,
[
vue.createElementVNode("view", { class: "status-bar" }),
$setup.currentAddFriend ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "popup-overlay"
}, [
vue.createElementVNode("view", { class: "popup-card" }, [
vue.createElementVNode("view", {
class: "close-popup-card",
onClick: $setup.closeAddFriendCard
}, [
vue.createElementVNode("view", { class: "iconfont icon-quxiao" })
]),
vue.createElementVNode(
"view",
{ class: "popup-title" },
vue.toDisplayString($setup.isAgreeBeFriend ? "通过好友申请" : "申请添加朋友"),
1
/* TEXT */
),
vue.createElementVNode("view", { class: "friend-card" }, [
vue.createElementVNode("view", { class: "friend-card-left" }, [
vue.createElementVNode(
"view",
{ class: "friend-avatar" },
vue.toDisplayString($setup.currentAddFriend.avatar),
1
/* TEXT */
)
]),
vue.createElementVNode("view", { class: "friend-card-middle" }, [
vue.createElementVNode(
"view",
{ class: "friend-name" },
vue.toDisplayString($setup.currentAddFriend.username),
1
/* TEXT */
),
vue.createElementVNode(
"view",
{ class: "friend-label" },
vue.toDisplayString($setup.currentAddFriend.sessionId),
1
/* TEXT */
)
])
]),
vue.createElementVNode("view", { class: "nickname-wrapper" }, [
vue.createElementVNode("view", null, "好友备注"),
vue.createElementVNode("input", {
class: "input-nickname",
placeholder: "请输入好友名称"
})
]),
vue.createElementVNode(
"view",
{ class: "text-btn confirm-btn" },
vue.toDisplayString($setup.isAgreeBeFriend ? "确认通过" : "发送申请"),
1
/* TEXT */
)
])
])) : vue.createCommentVNode("v-if", true),
vue.createElementVNode("view", { class: "tabbar-page page-container" }, [
vue.createElementVNode("swiper", {
class: "content-swiper",
current: $setup.currentTab,
duration: 300,
onChange: $setup.onSwiperChange
}, [
vue.createElementVNode("swiper-item", { class: "content-swiper-item" }, [
vue.createElementVNode("view", { class: "tabpage-containner" }, [
vue.createElementVNode("view", { class: "tabpage-header" }, [
vue.createElementVNode("view", {
class: "iconfont icon-fanhui",
onClick: $setup.handleBack
}),
vue.createElementVNode("view", { class: "tabpage-title" }, "通讯录")
]),
vue.createElementVNode("view", { class: "tabpage-body" }, [
vue.createElementVNode("scroll-view", {
class: "group-member",
direction: "vertical",
"scroll-y": "true"
}, [
vue.createElementVNode("view", { class: "friend-list" }, [
vue.createElementVNode("view", {
class: "friend-card",
onClick: _cache[0] || (_cache[0] = ($event) => $setup.changeChatType(0))
}, [
vue.createElementVNode("view", { class: "friend-card-left" }, [
vue.createElementVNode("view", {
class: "friend-avatar",
style: { "background-color": "#38bdf8" }
}, [
vue.createElementVNode("view", {
class: "iconfont icon-Robot",
style: { "font-size": "80rpx", "color": "#fff" }
})
])
]),
vue.createElementVNode("view", { class: "friend-card-middle" }, [
vue.createElementVNode(
"view",
{ class: "friend-name" },
vue.toDisplayString($setup.FriendAI.name),
1
/* TEXT */
),
vue.createElementVNode("view", { class: "friend-label" })
]),
vue.createElementVNode("view", { class: "friend-card-right" }, [
vue.createVNode(_component_uni_icons, { type: "right" })
])
]),
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList($setup.FriendInfoList, (friend) => {
return vue.openBlock(), vue.createElementBlock("view", {
class: "friend-card",
key: friend.sessionId,
onClick: ($event) => $setup.changeChatType(friend.type, friend.sessionId)
}, [
vue.createElementVNode("view", { class: "friend-card-left" }, [
friend.avatar ? (vue.openBlock(), vue.createElementBlock("image", {
key: 0,
src: friend.avatar,
class: "friend-avatar",
mode: "aspectFill"
}, null, 8, ["src"])) : (vue.openBlock(), vue.createElementBlock("view", {
key: 1,
class: "friend-avatar"
}, [
vue.createVNode(_component_uni_icons, {
type: "person-filled",
size: "100rpx",
color: "#ffffff"
})
]))
]),
vue.createElementVNode("view", { class: "friend-card-middle" }, [
vue.createElementVNode(
"view",
{ class: "friend-name" },
vue.toDisplayString(friend.friendNickName),
1
/* TEXT */
),
vue.createElementVNode(
"view",
{ class: "friend-label" },
vue.toDisplayString(friend.sessionId),
1
/* TEXT */
)
]),
vue.createElementVNode("view", { class: "friend-card-right" }, [
vue.createVNode(_component_uni_icons, { type: "right" })
])
], 8, ["onClick"]);
}),
128
/* KEYED_FRAGMENT */
)),
vue.createElementVNode("view", null, "群聊"),
vue.createElementVNode("view", { class: "solid-line" }),
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList($setup.GroupList, (group) => {
return vue.openBlock(), vue.createElementBlock("view", {
class: "friend-card",
key: group.id,
onClick: ($event) => $setup.changeChatType(group.type, group.id)
}, [
vue.createElementVNode("view", { class: "friend-card-left" }, [
vue.createElementVNode("view", {
class: "friend-avatar",
style: { "background-color": "#ffaaff" }
}, [
vue.createElementVNode("view", {
class: "iconfont icon-qunliao",
style: { "font-size": "80rpx", "color": "#fff" }
})
])
]),
vue.createElementVNode("view", { class: "friend-card-middle" }, [
vue.createElementVNode(
"view",
{ class: "friend-name" },
vue.toDisplayString(group.name),
1
/* TEXT */
),
vue.createElementVNode(
"view",
{ class: "friend-label" },
vue.toDisplayString(group.createTime),
1
/* TEXT */
)
]),
vue.createElementVNode("view", { class: "friend-card-right" }, [
vue.createVNode(_component_uni_icons, { type: "right" })
])
], 8, ["onClick"]);
}),
128
/* KEYED_FRAGMENT */
))
])
])
])
])
]),
vue.createElementVNode("swiper-item", { class: "content-swiper-item" }, [
vue.createElementVNode("view", { class: "tabpage-containner" }, [
vue.createElementVNode("view", { class: "tabpage-header" }, [
vue.createElementVNode("view", {
class: "iconfont icon-fanhui",
onClick: $setup.handleBack
}),
vue.createElementVNode("view", { class: "tabpage-title" }, "新建群聊")
]),
vue.createElementVNode("view", { class: "tabpage-body" }, [
vue.createElementVNode("view", { class: "group-info" }, [
vue.createElementVNode("view", { class: "group-name" }, [
vue.createElementVNode("view", null, "群名称"),
vue.withDirectives(vue.createElementVNode(
"input",
{
class: "input",
placeholder: "请输入群名称",
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $setup.createGroupName = $event)
},
null,
512
/* NEED_PATCH */
), [
[vue.vModelText, $setup.createGroupName]
])
]),
vue.createElementVNode("view", { class: "group-member-wrapper" }, [
vue.createElementVNode("view", { class: "member-title" }, "群成员"),
vue.createElementVNode("view", { class: "group-ismember-list" }, [
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList($setup.selectGroupMember, (item, index) => {
return vue.openBlock(), vue.createElementBlock("view", {
class: "group-ismember-info",
key: index
}, [
vue.createElementVNode(
"view",
{ class: "group-ismember-name" },
vue.toDisplayString(item.friendNickName),
1
/* TEXT */
)
]);
}),
128
/* KEYED_FRAGMENT */
))
])
]),
vue.createElementVNode("view", {
class: "create-group-btn",
onClick: $setup.createGroup
}, "创建群聊")
]),
vue.createElementVNode("view", { class: "solid-line" }),
vue.createElementVNode("scroll-view", {
class: "group-member",
direction: "vertical",
"scroll-y": "true"
}, [
vue.createElementVNode("view", { class: "friend-list" }, [
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList($setup.FriendInfoList, (friend) => {
var _a;
return vue.openBlock(), vue.createElementBlock("view", {
class: "friend-card",
key: friend.receiver
}, [
vue.createElementVNode("view", { class: "friend-card-left" }, [
friend.avatar ? (vue.openBlock(), vue.createElementBlock("image", {
key: 0,
src: friend.avatar,
class: "friend-avatar",
mode: "aspectFill"
}, null, 8, ["src"])) : (vue.openBlock(), vue.createElementBlock("view", {
key: 1,
class: "friend-avatar"
}, [
vue.createVNode(_component_uni_icons, {
type: "person-filled",
size: "100rpx",
color: "#ffffff"
})
]))
]),
vue.createElementVNode("view", { class: "friend-card-middle" }, [
vue.createElementVNode(
"view",
{ class: "friend-name" },
vue.toDisplayString(friend.friendNickName),
1
/* TEXT */
),
vue.createElementVNode(
"view",
{ class: "friend-label" },
vue.toDisplayString(friend.email),
1
/* TEXT */
)
]),
vue.createElementVNode("view", {
class: "friend-card-right",
onClick: ($event) => $setup.handlCreateEmember(friend.receiver)
}, [
vue.createElementVNode("view", { class: "friend-checkbox" }, [
((_a = $setup.selectGroupMember) == null ? void 0 : _a.find((item) => item.id === friend.receiver)) ? (vue.openBlock(), vue.createBlock(_component_uni_icons, {
key: 0,
type: "checkmarkempty"
})) : vue.createCommentVNode("v-if", true)
])
], 8, ["onClick"])
]);
}),
128
/* KEYED_FRAGMENT */
))
])
])
])
])
]),
vue.createElementVNode("swiper-item", { class: "content-swiper-item" }, [
vue.createElementVNode("view", { class: "tabpage-containner" }, [
vue.createElementVNode("view", { class: "tabpage-header" }, [
vue.createElementVNode("view", {
class: "iconfont icon-fanhui",
onClick: $setup.handleBack
}),
vue.createElementVNode("view", { class: "tabpage-title" }, "添加好友")
]),
vue.createElementVNode("view", { class: "tabpage-body" }, [
vue.createElementVNode("view", { class: "search-warpper" }, [
vue.withDirectives(vue.createElementVNode(
"input",
{
class: vue.normalizeClass(["search-file-input", { active: $setup.isSearchFriend }]),
onFocus: $setup.handleFriendSearchFocus,
onBlur: $setup.handleFriendSearchFocus,
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => $setup.searchFriendName = $event)
},
null,
34
/* CLASS, NEED_HYDRATION */
), [
[vue.vModelText, $setup.searchFriendName]
]),
vue.createElementVNode("view", {
class: "iconfont icon-sousuo",
onClick: $setup.searchFriend
})
]),
!$setup.searchFriendName ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "search-tip"
}, "请输入用户名或邮箱进行搜索")) : $setup.searchResultList.length ? (vue.openBlock(), vue.createElementBlock("view", {
key: 1,
class: "search-result"
}, [
vue.createElementVNode("scroll-view", {
class: "group-member",
direction: "vertical",
"scroll-y": "true"
}, [
vue.createElementVNode("view", { class: "friend-list" }, [
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList($setup.searchResultList, (friend) => {
return vue.openBlock(), vue.createElementBlock("view", {
class: "friend-card",
key: friend.id
}, [
vue.createElementVNode("view", { class: "friend-card-left" }, [
vue.createElementVNode(
"view",
{ class: "friend-avatar" },
vue.toDisplayString(friend.avatar),
1
/* TEXT */
)
]),
vue.createElementVNode("view", { class: "friend-card-middle" }, [
vue.createElementVNode(
"view",
{ class: "friend-name" },
vue.toDisplayString(friend.nickname),
1
/* TEXT */
),
vue.createElementVNode(
"view",
{ class: "friend-label" },
vue.toDisplayString(friend.email),
1
/* TEXT */
)
]),
vue.createElementVNode("view", {
class: "friend-card-right",
onClick: ($event) => $setup.addNewFriend(friend.id)
}, [
vue.createElementVNode("view", { class: "add-btn text-btn" }, "添加")
], 8, ["onClick"])
]);
}),
128
/* KEYED_FRAGMENT */
))
])
])
])) : (vue.openBlock(), vue.createElementBlock("view", {
key: 2,
class: "no-result"
}, "未找到相关用户,请尝试其他关键词"))
])
])
]),
vue.createElementVNode("swiper-item", { class: "content-swiper-item" }, [
vue.createElementVNode("view", { class: "tabpage-containner" }, [
vue.createElementVNode("view", { class: "tabpage-header" }, [
vue.createElementVNode("view", {
class: "iconfont icon-fanhui",
onClick: $setup.handleBack
}),
vue.createElementVNode("view", { class: "tabpage-title" }, "视频会议")
]),
vue.createElementVNode("view", { class: "tabpage-body" }, [
vue.createElementVNode("view", { class: "join-meeting-wrapper" }, [
vue.createElementVNode("view", null, "加入会议"),
vue.createElementVNode("input", {
class: "input-meeting",
placeholder: "请输入会议号"
}),
vue.createElementVNode("view", { class: "meeting-btn text-btn" }, "加入会议")
]),
vue.createElementVNode("view", { class: "solid-line" }),
vue.createElementVNode("view", { class: "create-meeting-wrapper" }, [
vue.createElementVNode("view", null, "创建会议"),
vue.createElementVNode("view", { class: "meeting-field" }, [
vue.createElementVNode("view", { class: "meeting-label" }, "会议主题"),
vue.createElementVNode("input", {
class: "input-meeting",
placeholder: "例如XXX"
})
]),
vue.createElementVNode("view", { class: "meeting-field" }, [
vue.createElementVNode("view", { class: "meeting-label" }, "会议密码"),
vue.createElementVNode("input", {
class: "input-meeting",
placeholder: "留空则无密码"
})
]),
vue.createElementVNode("view", { class: "meeting-field" }, [
vue.createElementVNode("view", { class: "meeting-label" }, "邀请好友"),
vue.createElementVNode("view", { class: "friend-card" }, [
vue.createElementVNode("view", { class: "friend-card-left" }, [
vue.createElementVNode("view", { class: "friend-avatar" }, "avatar")
]),
vue.createElementVNode("view", { class: "friend-card-middle" }, [
vue.createElementVNode("view", { class: "friend-name" }, "friend.nickname"),
vue.createElementVNode("view", { class: "friend-label" }, "friend.email")
]),
vue.createElementVNode("view", {
class: "friend-card-right",
onClick: _cache[3] || (_cache[3] = ($event) => $setup.addNewFriend(_ctx.friend.id))
}, [
vue.createElementVNode("view", { class: "add-btn text-btn" }, "添加")
])
])
]),
vue.createElementVNode("view", { class: "meeting-toggles" }, [
vue.createElementVNode("view", { class: "meeting-toggles-item" }, [
vue.createElementVNode("view", { class: "meeting-toggles-icon icon-btn" }, [
vue.createVNode(_component_uni_icons, { type: "mic-filled" }),
vue.createTextVNode("开启麦克风入会 ")
]),
vue.createElementVNode("view", {
class: "meeting-toggles-switch",
onClick: $setup.togglesVoice
}, [
vue.createElementVNode(
"view",
{
class: vue.normalizeClass(["switch-box", { active: $setup.isVoice }])
},
[
vue.createElementVNode("view", { class: "switch-track" })
],
2
/* CLASS */
)
])
]),
vue.createElementVNode("view", { class: "meeting-toggles-item" }, [
vue.createElementVNode("view", { class: "meeting-toggles-icon icon-btn" }, [
vue.createVNode(_component_uni_icons, { type: "eye-filled" }),
vue.createTextVNode("开启摄像头入会 ")
]),
vue.createElementVNode("view", {
class: "meeting-toggles-switch",
onClick: $setup.togglesCamera
}, [
vue.createElementVNode(
"view",
{
class: vue.normalizeClass(["switch-box", { active: $setup.isCamera }])
},
[
vue.createElementVNode("view", { class: "switch-track" })
],
2
/* CLASS */
)
])
])
]),
vue.createElementVNode("view", { class: "meeting-btn text-btn" }, "加入会议")
])
])
])
]),
vue.createElementVNode("swiper-item", { class: "content-swiper-item" }, [
vue.createElementVNode("view", { class: "tabpage-containner" }, [
vue.createElementVNode("view", { class: "tabpage-header" }, [
vue.createElementVNode("view", {
class: "iconfont icon-fanhui",
onClick: $setup.handleBack
}),
vue.createElementVNode("view", { class: "tabpage-title" }, "好友申请")
]),
vue.createElementVNode("view", { class: "tabpage-body" }, [
vue.createElementVNode("scroll-view", {
class: "group-member",
direction: "vertical",
"scroll-y": "true"
}, [
vue.createElementVNode("view", { class: "friend-list" }, [
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList($setup.mockFriendDB, (friend) => {
return vue.openBlock(), vue.createElementBlock("view", {
class: "friend-card",
key: friend.id
}, [
vue.createElementVNode("view", { class: "friend-card-left" }, [
vue.createElementVNode(
"view",
{ class: "friend-avatar" },
vue.toDisplayString(friend.avatar),
1
/* TEXT */
)
]),
vue.createElementVNode("view", { class: "friend-card-middle" }, [
vue.createElementVNode(
"view",
{ class: "friend-name" },
vue.toDisplayString(friend.nickname),
1
/* TEXT */
),
vue.createElementVNode(
"view",
{ class: "friend-label" },
vue.toDisplayString(friend.email),
1
/* TEXT */
)
]),
vue.createElementVNode("view", { class: "friend-card-right" }, [
vue.createElementVNode("view", { class: "friend-option" }, [
vue.createElementVNode("view", {
class: "refuse-btn text-btn",
onClick: ($event) => $setup.refuseBeFriend(friend)
}, "拒绝", 8, ["onClick"]),
vue.createElementVNode("view", {
class: "agree-btn text-btn",
onClick: ($event) => $setup.agreeBeFriend(friend)
}, "同意", 8, ["onClick"])
])
])
]);
}),
128
/* KEYED_FRAGMENT */
))
])
])
])
])
])
], 40, ["current"]),
vue.createElementVNode("view", { class: "bottom-tabbar" }, [
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList($setup.tabList, (tab, index) => {
return vue.openBlock(), vue.createElementBlock("view", {
key: tab.name,
onClick: ($event) => $setup.switchTab(index),
class: "tab-item"
}, [
vue.createElementVNode(
"view",
{ class: "tab-icon" },
vue.toDisplayString(tab.icon),
1
/* TEXT */
),
vue.createElementVNode(
"view",
{ class: "tab-label" },
vue.toDisplayString(tab.label),
1
/* TEXT */
)
], 8, ["onClick"]);
}),
128
/* KEYED_FRAGMENT */
))
])
])
],
64
/* STABLE_FRAGMENT */
);
}
const PagesContactPagesContactPages = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$3], ["__scopeId", "data-v-976117c3"], ["__file", "D:/Projects/uniapp/app-test/test1/pages/ContactPages/ContactPages.vue"]]);
const _sfc_main$3 = {
__name: "TemplateSpace",
setup(__props, { expose: __expose }) {
__expose();
const formatTime = (timestamp) => {
if (!timestamp)
return "";
const seconds = Math.floor(timestamp);
const date = new Date(seconds * 1e3);
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, "0");
const day = date.getDate().toString().padStart(2, "0");
const hours = date.getHours().toString().padStart(2, "0");
const minutes = date.getMinutes().toString().padStart(2, "0");
const seconds_part = date.getSeconds().toString().padStart(2, "0");
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds_part}`;
};
const formatSize = (bytes) => {
if (!bytes || bytes === 0)
return "0 B";
const units = ["B", "KB", "MB", "GB", "TB"];
let size = bytes;
let unitIndex = 0;
while (size >= 1024 && unitIndex < units.length - 1) {
size /= 1024;
unitIndex++;
}
return `${size.toFixed(1)} ${units[unitIndex]}`;
};
const handleLikeTemplate = (index) => {
let targetItem;
if (checkTemplate.value === "all") {
targetItem = allTemplate.value[index];
} else if (checkTemplate.value === "like") {
const favoriteList = allTemplate.value.filter((item) => item.is_favorite);
targetItem = favoriteList[index];
}
if (targetItem) {
targetItem.is_favorite = !targetItem.is_favorite;
}
if (checkTemplate.value === "all") {
currentTemplateList.value = [...allTemplate.value];
} else {
currentTemplateList.value = allTemplate.value.filter((item) => item.is_favorite);
}
};
const templateName = vue.ref("aaa");
const editTemplate = () => {
formatAppLog("log", "at pages/WorkSpace/TemplateSpace/TemplateSpace.vue:188", "点击了编辑模板");
};
const checkTemplate = vue.ref("");
const currentTemplateList = vue.ref([]);
const checkShowTemplate = (type) => {
checkTemplate.value = type;
if (type === "all") {
navbarTitle.value = "全部模板";
currentTemplateList.value = allTemplate.value;
}
if (type === "like") {
navbarTitle.value = "收藏模板";
currentTemplateList.value = allTemplate.value.filter((item) => item.is_favorite === true);
}
};
const navbarBeforeTitle = vue.ref("");
const navbarTitle = vue.ref("模板区");
const isSelectFolder = vue.ref(false);
const selectFileList = vue.ref([]);
const handleSelectFolder = () => {
if (isSelectFolder.value) {
selectFileList.value = [];
}
isSelectFolder.value = !isSelectFolder.value;
};
const selectFolder = (id) => {
const index = selectFileList.value.indexOf(id);
if (index !== -1) {
selectFileList.value.splice(index, 1);
} else {
selectFileList.value.push(id);
}
};
const handleLongPress = (folder) => {
if (isSelectFolder.value)
return;
uni.showActionSheet({
itemList: ["重命名", "删除", "下载", "压缩"],
success: (res) => {
switch (res.tapIndex) {
case 0:
handleRename(folder);
break;
case 1:
handleDelete(folder);
break;
case 2:
handleDownload();
break;
case 3:
handleDownload();
break;
}
}
});
};
const handleRename = (folder) => {
uni.showModal({
title: "重命名",
content: "请输入新名称",
editable: true,
placeholderText: folder.name,
success: (res) => {
if (res.confirm && res.content) {
updateFolderName(folder.id, res.content);
}
}
});
};
const handleDownload = (folder) => {
uni.showToast({
title: "移动功能开发中",
icon: "none"
});
};
const handleDelete = (folder) => {
uni.showModal({
title: "提示",
content: `确定要删除文件夹"${folder.name}"吗?`,
success: (res) => {
if (res.confirm) {
formatAppLog("log", "at pages/WorkSpace/TemplateSpace/TemplateSpace.vue:283", "确认删除文件夹");
}
}
});
};
const isMenuOpen = vue.ref(false);
const handleMenu = () => {
isMenuOpen.value = !isMenuOpen.value;
};
const searchKeyword = vue.ref("");
const isSearchFocus = vue.ref(false);
const handleSearchFocus = () => {
isSearchFocus.value = !isSearchFocus.value;
};
const allTemplate = vue.ref([
{
"name": "SKILL.md",
"type": "file",
"path": "SKILL.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 4768,
"modified_time": 17768273619123552e-7,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": "khgvshbbthvgbihepiubjhrviifdhiuhrviuehrviuawhiuvrhy"
},
{
"name": "222.md",
"type": "file",
"path": "222.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 5558,
"modified_time": 17768276669123552e-7,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": "khgvshbbthvgbihepiubjhiuvrhy"
},
{
"name": "222.md",
"type": "file",
"path": "222.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 5558,
"modified_time": 17768276669123552e-7,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": "该回家看了的法国红酒看来法帝国海军快来尝尝v吧给v复仇计划曝光vi计划日方提供与i哦的风格和健康"
},
{
"name": "222.md",
"type": "file",
"path": "222.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 5558,
"modified_time": 17768276669123552e-7,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": "的法国红酒看来法帝国海军快来尝尝v吧给"
},
{
"name": "222.md",
"type": "file",
"path": "222.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 5558,
"modified_time": 17768276669123552e-7,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": ""
},
{
"name": "222.md",
"type": "file",
"path": "222.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 5558,
"modified_time": 17768276669123552e-7,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": "khgvshbbthvgbihepiubjhrviifdhiuhrviuehrviuawhiuvrhy"
},
{
"name": "222.md",
"type": "file",
"path": "222.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 5558,
"modified_time": 17768276669123552e-7,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": "khgvshbbthvgbihepiubjhrviifdhiuhrviuehrviuawhiuvrhy"
},
{
"name": "222.md",
"type": "file",
"path": "222.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 5558,
"modified_time": 17768276669123552e-7,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": "khgvshbbthvgbihepiubjhrviifdhiuhrviuehrviuawhiuvrhy"
},
{
"name": "222.md",
"type": "file",
"path": "222.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 5558,
"modified_time": 17768276669123552e-7,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": "khgvshbbthvgbihepiubjhrviifdhiuhrviuehrviuawhiuvrhy"
}
]);
const handleSelectAll = () => {
if (selectFileList.value.length === currentTemplateList.value.length) {
selectFileList.value = [];
} else {
selectFileList.value = currentTemplateList.value.map((f) => f.id);
}
};
const handleBackOrCheck = () => {
if (isSelectFolder.value) {
handleSelectAll();
return;
}
if (!isSelectFolder.value && currentTemplateList.value) {
currentTemplateList.value = [];
checkTemplate.value = "";
navbarTitle.value = "模板区";
}
if (!isSelectFolder.value && !currentTemplateList.value) {
uni.navigateBack({
delta: 1,
fail() {
formatAppLog("log", "at pages/WorkSpace/TemplateSpace/TemplateSpace.vue:468", "返回失败,进入兜底跳转");
uni.reLaunch({
url: "/pages/Chat/Chat"
});
}
});
}
};
const __returned__ = { formatTime, formatSize, handleLikeTemplate, templateName, editTemplate, checkTemplate, currentTemplateList, checkShowTemplate, navbarBeforeTitle, navbarTitle, isSelectFolder, selectFileList, handleSelectFolder, selectFolder, handleLongPress, handleRename, handleDownload, handleDelete, isMenuOpen, handleMenu, searchKeyword, isSearchFocus, handleSearchFocus, allTemplate, handleSelectAll, handleBackOrCheck, onMounted: vue.onMounted, ref: vue.ref };
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
return __returned__;
}
};
function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
return vue.openBlock(), vue.createElementBlock(
vue.Fragment,
null,
[
vue.createElementVNode("view", { class: "status-bar" }),
vue.createElementVNode("view", { class: "popup-overlay" }, [
vue.createElementVNode("view", { class: "popup-card" }, [
vue.createElementVNode("view", { class: "close-popup-card" }, [
vue.createElementVNode("view", { class: "iconfont icon-quxiao" })
]),
vue.createElementVNode("view", { class: "popup-title" }, "编辑模板"),
vue.createElementVNode("view", { class: "edit-template-wrapper" }, [
vue.createElementVNode("view", { class: "edit-template-name" }, [
vue.createElementVNode("view", null, "模板名称"),
vue.withDirectives(vue.createElementVNode(
"input",
{
"placeholder-style": "请输入模板名称",
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.templateName = $event)
},
null,
512
/* NEED_PATCH */
), [
[vue.vModelText, $setup.templateName]
])
]),
vue.createElementVNode("view", { class: "edit-template-name" }, [
vue.createElementVNode("view", null, "模板内容"),
vue.createElementVNode("view", { class: "markdown-editor-pane" }, [
vue.createElementVNode("view", { class: "markdown-pane-header" }, " 编辑 "),
vue.createElementVNode("textarea")
]),
vue.createElementVNode("view", { class: "markdown-preview-pane" }, [
vue.createElementVNode("view", { class: "markdown-pane-header" }, " 预览 "),
vue.createElementVNode("view")
])
])
])
])
]),
vue.createElementVNode("view", { class: "workspace-container page-container" }, [
vue.createElementVNode("view", { class: "workspace-header" }, [
vue.createElementVNode("view", { class: "custom-navbar" }, [
vue.createElementVNode("view", {
class: "navbar-left",
onClick: _cache[1] || (_cache[1] = (...args) => $setup.handleBackOrCheck && $setup.handleBackOrCheck(...args))
}, [
vue.createElementVNode("view", { class: "iconfont icon-fanhui custom-navbar-icon" }),
vue.createElementVNode(
"view",
{ class: "navbar-before-title workspace-text" },
vue.toDisplayString($setup.isSelectFolder ? "全选" : $setup.navbarBeforeTitle),
1
/* TEXT */
)
]),
vue.createElementVNode(
"view",
{ class: "navbar-title workspace-text" },
vue.toDisplayString($setup.navbarTitle),
1
/* TEXT */
),
$setup.checkTemplate ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "navbar-right"
}, [
$setup.isSelectFolder ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "navbar-right-text workspace-text",
onClick: _cache[2] || (_cache[2] = ($event) => $setup.handleSelectFolder())
}, " 完成")) : (vue.openBlock(), vue.createElementBlock(
"view",
{
key: 1,
class: vue.normalizeClass(["iconfont icon-gengduo", $setup.isMenuOpen ? "menu-open" : "custom-navbar-icon"]),
onClick: $setup.handleMenu
},
null,
2
/* CLASS */
))
])) : vue.createCommentVNode("v-if", true),
$setup.isMenuOpen ? (vue.openBlock(), vue.createElementBlock("view", {
key: 1,
class: "menu-card"
}, [
vue.createElementVNode("view", {
class: "menu-card-item",
onClick: _cache[3] || (_cache[3] = ($event) => {
$setup.handleSelectFolder();
$setup.handleMenu();
})
}, "选择"),
vue.createElementVNode("view", { class: "solid-line" }),
vue.createElementVNode("view", { class: "menu-card-item" }, "新建模板"),
vue.createElementVNode("view", { class: "solid-line" }),
vue.createElementVNode("view", { class: "menu-card-item" }, "上传模板")
])) : vue.createCommentVNode("v-if", true)
]),
vue.createElementVNode("view", { class: "search-file-warpper" }, [
vue.createElementVNode("view", { class: "search-file" }, [
vue.createElementVNode("view", { class: "iconfont icon-sousuo" }),
vue.withDirectives(vue.createElementVNode(
"input",
{
class: "search-file-input",
placeholder: "搜索",
onFocus: $setup.handleSearchFocus,
"onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => $setup.searchKeyword = $event)
},
null,
544
/* NEED_HYDRATION, NEED_PATCH */
), [
[vue.vModelText, $setup.searchKeyword]
])
]),
$setup.isSearchFocus ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "cancel-search",
onClick: $setup.handleSearchFocus
}, "取消")) : vue.createCommentVNode("v-if", true)
])
]),
!$setup.checkTemplate ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "folder-grid"
}, [
vue.createElementVNode("view", {
class: "folder-item",
onClick: _cache[5] || (_cache[5] = ($event) => $setup.checkShowTemplate("all"))
}, [
vue.createElementVNode("view", { class: "iconfont icon-a-wenjianjiawenjian folder-item-style" }),
vue.createElementVNode("view", { class: "folder-name" }, "全部模板")
]),
vue.createElementVNode("view", {
class: "folder-item",
onClick: _cache[6] || (_cache[6] = ($event) => $setup.checkShowTemplate("like"))
}, [
vue.createElementVNode("view", { class: "iconfont icon-a-wenjianjiawenjian folder-item-style" }),
vue.createElementVNode("view", { class: "folder-name" }, "收藏模板")
])
])) : vue.createCommentVNode("v-if", true),
$setup.checkTemplate ? (vue.openBlock(), vue.createElementBlock("view", {
key: 1,
class: "workspace-content"
}, [
$setup.currentTemplateList.length === 0 ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "folder-null"
}, [
vue.createElementVNode("view", { class: "iconfont icon-wenjianjia" }),
vue.createTextVNode(" 暂无模板 ")
])) : vue.createCommentVNode("v-if", true),
$setup.currentTemplateList.length > 0 ? (vue.openBlock(), vue.createElementBlock("view", {
key: 1,
class: "template-grid"
}, [
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList($setup.currentTemplateList, (item, index) => {
return vue.openBlock(), vue.createElementBlock("view", {
class: "template-card",
key: index
}, [
vue.createElementVNode(
"view",
{ class: "template-name" },
vue.toDisplayString(item.name),
1
/* TEXT */
),
vue.createElementVNode("view", { class: "template-content" }, [
vue.createElementVNode(
"view",
{ class: "template-content-text" },
vue.toDisplayString(item.content),
1
/* TEXT */
)
]),
vue.createElementVNode("view", { class: "template-info-wrapper" }, [
vue.createElementVNode("view", { class: "template-item" }, [
vue.createElementVNode(
"view",
{ class: "template-time background-style" },
vue.toDisplayString($setup.formatTime(item.modified_time)),
1
/* TEXT */
),
vue.createElementVNode(
"view",
{ class: "template-cache background-style" },
vue.toDisplayString($setup.formatSize(item.size)),
1
/* TEXT */
)
]),
vue.createElementVNode("view", { class: "template-option" }, [
vue.createElementVNode("view", {
class: vue.normalizeClass(["iconfont", item.is_favorite ? "icon-favorite-fill" : "icon-favorite"]),
onClick: ($event) => $setup.handleLikeTemplate(index)
}, null, 10, ["onClick"]),
vue.createElementVNode("view", {
class: "iconfont icon-edit-fill",
onClick: $setup.editTemplate
}),
vue.createElementVNode("view", { class: "iconfont icon-choose-fill" })
])
])
]);
}),
128
/* KEYED_FRAGMENT */
))
])) : vue.createCommentVNode("v-if", true)
])) : vue.createCommentVNode("v-if", true),
$setup.isSelectFolder ? (vue.openBlock(), vue.createElementBlock(
"view",
{
key: 2,
class: vue.normalizeClass(["workspace-footer", { "folder-actions": $setup.selectFileList.length > 0 }])
},
[
vue.createElementVNode("view", { class: "iconfont icon-shangchuan" }),
vue.createElementVNode("view", { class: "iconfont icon-fuzhi" }),
vue.createElementVNode("view", { class: "iconfont icon-wenjian" }),
vue.createElementVNode("view", { class: "iconfont icon-del" }),
vue.createElementVNode("view", { class: "iconfont icon-gengduo" })
],
2
/* CLASS */
)) : vue.createCommentVNode("v-if", true)
])
],
64
/* STABLE_FRAGMENT */
);
}
const PagesWorkSpaceTemplateSpaceTemplateSpace = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$2], ["__scopeId", "data-v-769edd25"], ["__file", "D:/Projects/uniapp/app-test/test1/pages/WorkSpace/TemplateSpace/TemplateSpace.vue"]]);
const _sfc_main$2 = {
__name: "text",
setup(__props, { expose: __expose }) {
__expose();
const formHtml = vue.ref("");
const sanitizeContent = (str) => {
return str.replace(/<\/?script>/gi, (match) => {
let result = "";
for (let i = 0; i < match.length; i++) {
result += "\\u" + match.charCodeAt(i).toString(16).padStart(4, "0");
}
return result;
});
};
vue.onMounted(() => {
formHtml.value = `
明白了!您希望在我的回复中直接嵌入可编辑的表单卡片。让我试试:
---
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 20px; padding: 28px; color: white; font-family: 'Microsoft YaHei', sans-serif; box-shadow: 0 10px 40px rgba(0,0,0,0.25); margin: 20px 0;">
<h2 style="margin: 0 0 20px 0; font-size: 20px; display: flex; align-items: center; gap: 12px;">
<span style="font-size: 26px;">✏️</span> 直接在下方编辑任务
</h2>
<form id="inlineTaskForm" style="background: rgba(255,255,255,0.1); border-radius: 16px; padding: 24px;">
<div style="margin-bottom: 18px;">
<label style="display: block; font-size: 12px; opacity: 0.8; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 1px;">任务名称</label>
<input type="text" id="inlineTitle" placeholder="输入任务名称..." style="width: 100%; padding: 14px 16px; background: #1e1e2e; border: 2px solid rgba(255,255,255,0.2); border-radius: 10px; color: #fff; font-size: 15px;">
</div>
<div style="margin-bottom: 18px;">
<label style="display: block; font-size: 12px; opacity: 0.8; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 1px;">任务描述</label>
<textarea id="inlineDesc" placeholder="输入详细描述..." style="width: 100%; padding: 14px 16px; background: #1e1e2e; border: 2px solid rgba(255,255,255,0.2); border-radius: 10px; color: #fff; font-size: 14px; resize: vertical; min-height: 60px;"></textarea>
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px; margin-bottom: 18px;">
<div>
<label style="display: block; font-size: 12px; opacity: 0.8; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 1px;">开始日期</label>
<input type="date" id="inlineStart" style="width: 100%; padding: 14px 16px; background: #1e1e2e; border: 2px solid rgba(255,255,255,0.2); border-radius: 10px; color: #fff; font-size: 15px;">
</div>
<div>
<label style="display: block; font-size: 12px; opacity: 0.8; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 1px;">截止日期</label>
<input type="date" id="inlineEnd" style="width: 100%; padding: 14px 16px; background: #1e1e2e; border: 2px solid rgba(255,255,255,0.2); border-radius: 10px; color: #fff; font-size: 15px;">
</div>
</div>
<div style="margin-bottom: 18px;">
<label style="display: block; font-size: 12px; opacity: 0.8; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 1px;">时间</label>
<input type="time" id="inlineTime" value="09:00" style="width: 100%; padding: 14px 16px; background: #1e1e2e; border: 2px solid rgba(255,255,255,0.2); border-radius: 10px; color: #fff; font-size: 15px;">
</div>
<div style="margin-bottom: 18px;">
<label style="display: block; font-size: 12px; opacity: 0.8; margin-bottom: 10px; text-transform: uppercase; letter-spacing: 1px;">优先级</label>
<div style="display: flex; gap: 10px;">
<label style="flex: 1; text-align: center; padding: 12px; background: rgba(254, 215, 215, 0.2); border: 2px solid transparent; border-radius: 10px; cursor: pointer; transition: all 0.3s;" onclick="selectPriority(this, 'high')">
🔴 高
<input type="radio" name="priority" value="high" checked style="display: none;">
</label>
<label style="flex: 1; text-align: center; padding: 12px; background: rgba(254, 235, 200, 0.2); border: 2px solid transparent; border-radius: 10px; cursor: pointer; transition: all 0.3s;" onclick="selectPriority(this, 'medium')">
🟡 中
<input type="radio" name="priority" value="medium" style="display: none;">
</label>
<label style="flex: 1; text-align: center; padding: 12px; background: rgba(198, 246, 213, 0.2); border: 2px solid transparent; border-radius: 10px; cursor: pointer; transition: all 0.3s;" onclick="selectPriority(this, 'low')">
🟢 低
<input type="radio" name="priority" value="low" style="display: none;">
</label>
</div>
</div>
<div style="margin-bottom: 20px;">
<label style="display: block; font-size: 12px; opacity: 0.8; margin-bottom: 10px; text-transform: uppercase; letter-spacing: 1px;">分类</label>
<div style="display: flex; gap: 10px; flex-wrap: wrap;">
<label style="padding: 10px 16px; background: rgba(233, 216, 253, 0.2); border: 2px solid #667eea; border-radius: 20px; cursor: pointer; font-size: 13px;" onclick="selectCategory(this, 'work')">
💼 工作
<input type="radio" name="category" value="work" checked style="display: none;">
</label>
<label style="padding: 10px 16px; background: rgba(190, 227, 248, 0.2); border: 2px solid transparent; border-radius: 20px; cursor: pointer; font-size: 13px;" onclick="selectCategory(this, 'life')">
🏠 生活
<input type="radio" name="category" value="life" style="display: none;">
</label>
<label style="padding: 10px 16px; background: rgba(254, 215, 226, 0.2); border: 2px solid transparent; border-radius: 20px; cursor: pointer; font-size: 13px;" onclick="selectCategory(this, 'study')">
📚 学习
<input type="radio" name="category" value="study" style="display: none;">
</label>
<label style="padding: 10px 16px; background: rgba(198, 246, 213, 0.2); border: 2px solid transparent; border-radius: 20px; cursor: pointer; font-size: 13px;" onclick="selectCategory(this, 'health')">
💪 健康
<input type="radio" name="category" value="health" style="display: none;">
</label>
</div>
</div>
<div style="display: flex; gap: 12px;">
<button type="button" onclick="clearInlineForm()" style="flex: 1; padding: 14px; background: rgba(255,255,255,0.2); border: none; border-radius: 12px; color: white; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.3s;">
清空
</button>
<button type="button" onclick="submitInlineForm()" style="flex: 2; padding: 14px; background: white; border: none; border-radius: 12px; color: #667eea; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.3s;">
✅ 添加任务
</button>
</div>
</form>
</div>
---
**✅ 您现在可以直接在上方的卡片中填写任务信息,点击"添加任务"即可!**
填写完成后告诉我"已填好"或"添加",我会帮您确认是否成功!
`;
});
const initForm = () => {
setTimeout(() => {
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
const startInput = document.getElementById("inlineStart");
const endInput = document.getElementById("inlineEnd");
if (startInput)
startInput.value = today;
if (endInput)
endInput.value = today;
const clearBtn = document.getElementById("clearBtn");
const submitBtn = document.getElementById("submitBtn");
if (clearBtn) {
clearBtn.onclick = () => {
const titleInput = document.getElementById("inlineTitle");
const descInput = document.getElementById("inlineDesc");
if (titleInput)
titleInput.value = "";
if (descInput)
descInput.value = "";
};
}
if (submitBtn) {
submitBtn.onclick = () => {
const titleInput = document.getElementById("inlineTitle");
const title = titleInput == null ? void 0 : titleInput.value.trim();
if (!title) {
alert("请输入任务名称");
return;
}
alert(`任务已添加:${title}`);
if (titleInput)
titleInput.value = "";
if (document.getElementById("inlineDesc"))
document.getElementById("inlineDesc").value = "";
};
}
}, 100);
};
const __returned__ = { formHtml, sanitizeContent, initForm, ref: vue.ref, onMounted: vue.onMounted };
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
return __returned__;
}
};
function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
return vue.openBlock(), vue.createElementBlock("view", null, [
vue.createElementVNode("view", {
innerHTML: $setup.sanitizeContent($setup.formHtml)
}, null, 8, ["innerHTML"])
]);
}
const PagesTextText = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$1], ["__file", "D:/Projects/uniapp/app-test/test1/pages/text/text.vue"]]);
const _sfc_main$1 = {
__name: "text2",
setup(__props, { expose: __expose }) {
__expose();
const socketStore = useSocketStore();
const config = vue.ref({
token: getToken(),
conversationId: getCurrentSessionId()
});
const sendMessage = vue.ref("");
const quickMessages = vue.ref([
{
label: "Ping",
data: {
ws_event: "ping"
}
},
{
label: "认证",
data: {
ws_event: "auth",
data: {
token: "",
conversation_id: ""
}
}
},
{
label: "测试消息",
data: {
ws_event: "message",
data: {
task_call_id: getTaskCallId(),
token: getToken(),
conversation_id: getCurrentSessionId()
}
}
}
]);
const connectionStatusClass = vue.computed(() => {
const status = socketStore.connectionStatus;
return {
"status-connected": status === "connected",
"status-connecting": status === "connecting",
"status-error": status === "error",
"status-disconnected": status === "disconnected"
};
});
const handleConnect = () => {
if (!config.value.token) {
uni.showToast({
title: "请输入Token",
icon: "none"
});
return;
}
socketStore.connect({
token: config.value.token,
conversationId: getCurrentSessionId()
});
};
const handleDisconnect = () => {
socketStore.disconnect();
};
const handleSendPing = async () => {
try {
await socketStore.sendPing();
} catch (e2) {
uni.showToast({
title: "发送失败",
icon: "none"
});
}
};
const handleSend = async () => {
if (!sendMessage.value.trim())
return;
try {
const messageData = {
ws_event: "message",
data: {
task_call_id: getTaskCallId(),
result: {
tools: []
}
}
};
await socketStore.send(messageData);
sendMessage.value = "";
} catch (e2) {
uni.showToast({
title: "发送失败",
icon: "none"
});
}
};
const sendQuickMessage = async (template) => {
const messageData = {
ws_event: "message",
data: {
task_call_id: getTaskCallId(),
token: getToken(),
conversation_id: getCurrentSessionId()
}
};
try {
await socketStore.send(messageData);
} catch (e2) {
uni.showToast({
title: "发送失败",
icon: "none"
});
}
};
const formatJson = () => {
if (!sendMessage.value.trim())
return;
try {
const obj = JSON.parse(sendMessage.value);
sendMessage.value = JSON.stringify(obj, null, 2);
} catch {
uni.showToast({
title: "不是有效的JSON",
icon: "none"
});
}
};
const loadMoreLogs = () => {
};
vue.watch(() => socketStore.isDisconnected, (newVal) => {
if (newVal && socketStore.messageString) {
formatAppLog("log", "at pages/text/text2.vue:253", socketStore.messageString);
}
});
vue.onMounted(() => {
socketStore.addLog("info", "=== Socket测试页面 ===");
socketStore.addLog("info", "页面已加载");
if (socketStore.isConnected) {
socketStore.addLog("info", "当前已处于连接状态");
}
});
vue.onUnmounted(() => {
socketStore.addLog("info", "页面卸载");
});
const __returned__ = { socketStore, config, sendMessage, quickMessages, connectionStatusClass, handleConnect, handleDisconnect, handleSendPing, handleSend, sendQuickMessage, formatJson, loadMoreLogs, ref: vue.ref, computed: vue.computed, onMounted: vue.onMounted, onUnmounted: vue.onUnmounted, watch: vue.watch, get useSocketStore() {
return useSocketStore;
}, get getToken() {
return getToken;
}, get getTaskCallId() {
return getTaskCallId;
}, get getCurrentSessionId() {
return getCurrentSessionId;
} };
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
return __returned__;
}
};
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [
vue.createElementVNode("view", { class: "status-card" }, [
vue.createElementVNode("text", { class: "status-label" }, "连接状态"),
vue.createElementVNode(
"view",
{
class: vue.normalizeClass(["status-value", $setup.connectionStatusClass])
},
[
vue.createElementVNode(
"text",
null,
vue.toDisplayString($setup.socketStore.getStatusText()),
1
/* TEXT */
)
],
2
/* CLASS */
),
$setup.socketStore.reconnectAttempts > 0 ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "status-info"
}, [
vue.createElementVNode(
"text",
{ class: "reconnect-info" },
"重连次数: " + vue.toDisplayString($setup.socketStore.reconnectAttempts),
1
/* TEXT */
)
])) : vue.createCommentVNode("v-if", true)
]),
vue.createElementVNode("view", { class: "config-card" }, [
vue.createElementVNode("text", { class: "section-title" }, "连接配置"),
vue.createElementVNode("view", { class: "input-group" }, [
vue.createElementVNode("text", { class: "input-label" }, "Token"),
vue.withDirectives(vue.createElementVNode(
"input",
{
class: "input-field",
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.config.token = $event),
placeholder: "请输入Token"
},
null,
512
/* NEED_PATCH */
), [
[vue.vModelText, $setup.config.token]
])
]),
vue.createElementVNode("view", { class: "input-group" }, [
vue.createElementVNode("text", { class: "input-label" }, "Conversation ID"),
vue.withDirectives(vue.createElementVNode(
"input",
{
class: "input-field",
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $setup.config.conversationId = $event),
placeholder: "请输入会话ID(可选)"
},
null,
512
/* NEED_PATCH */
), [
[vue.vModelText, $setup.config.conversationId]
])
])
]),
vue.createElementVNode("view", { class: "control-card" }, [
vue.createElementVNode("button", {
class: "btn btn-primary",
disabled: $setup.socketStore.isConnected || $setup.socketStore.isConnecting,
onClick: $setup.handleConnect
}, vue.toDisplayString($setup.socketStore.isConnecting ? "连接中..." : "连接"), 9, ["disabled"]),
vue.createElementVNode("button", {
class: "btn btn-danger",
disabled: !$setup.socketStore.isConnected,
onClick: $setup.handleDisconnect
}, " 断开 ", 8, ["disabled"]),
vue.createElementVNode("button", {
class: "btn btn-secondary",
onClick: $setup.handleSendPing,
disabled: !$setup.socketStore.isConnected
}, " Ping ", 8, ["disabled"])
]),
vue.createElementVNode("view", { class: "send-card" }, [
vue.createElementVNode("text", { class: "section-title" }, "发送消息"),
vue.createElementVNode("view", { class: "send-input-wrapper" }, [
vue.withDirectives(vue.createElementVNode("textarea", {
class: "send-input",
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => $setup.sendMessage = $event),
placeholder: "输入要发送的消息(JSON格式)",
disabled: !$setup.socketStore.isConnected
}, null, 8, ["disabled"]), [
[vue.vModelText, $setup.sendMessage]
]),
vue.createElementVNode("view", { class: "send-buttons" }, [
vue.createElementVNode("button", {
class: "btn btn-primary btn-small",
disabled: !$setup.socketStore.isConnected || !$setup.sendMessage.trim(),
onClick: $setup.handleSend
}, " 发送 ", 8, ["disabled"]),
vue.createElementVNode("button", {
class: "btn btn-outline btn-small",
disabled: !$setup.sendMessage.trim(),
onClick: $setup.formatJson
}, " 格式化 ", 8, ["disabled"])
])
]),
vue.createElementVNode("view", { class: "quick-messages" }, [
vue.createElementVNode("text", { class: "quick-label" }, "快捷消息:"),
vue.createElementVNode("view", { class: "quick-btns" }, [
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList($setup.quickMessages, (item) => {
return vue.openBlock(), vue.createElementBlock("button", {
key: item.label,
class: "quick-btn",
disabled: !$setup.socketStore.isConnected,
onClick: ($event) => $setup.sendQuickMessage(item.data)
}, vue.toDisplayString(item.label), 9, ["disabled", "onClick"]);
}),
128
/* KEYED_FRAGMENT */
))
])
])
]),
vue.createElementVNode("view", { class: "log-card" }, [
vue.createElementVNode("view", { class: "log-header" }, [
vue.createElementVNode("view", { class: "log-title-wrapper" }, [
vue.createElementVNode("text", { class: "section-title" }, "日志"),
vue.createElementVNode(
"text",
{ class: "log-count" },
"(" + vue.toDisplayString($setup.socketStore.logs.length) + ")",
1
/* TEXT */
)
]),
vue.createElementVNode("view", { class: "log-actions" }, [
vue.createElementVNode("button", {
class: "btn btn-small btn-secondary",
onClick: _cache[3] || (_cache[3] = (...args) => $setup.socketStore.clearLogs && $setup.socketStore.clearLogs(...args))
}, "清空")
])
]),
vue.createElementVNode(
"scroll-view",
{
class: "log-list",
"scroll-y": "",
onScrolltoupper: $setup.loadMoreLogs
},
[
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList($setup.socketStore.logs, (log, index) => {
return vue.openBlock(), vue.createElementBlock(
"view",
{
key: index,
class: vue.normalizeClass(["log-item", "log-" + log.type])
},
[
vue.createElementVNode(
"text",
{ class: "log-time" },
vue.toDisplayString(log.time),
1
/* TEXT */
),
vue.createElementVNode(
"text",
{ class: "log-content" },
vue.toDisplayString(log.content),
1
/* TEXT */
)
],
2
/* CLASS */
);
}),
128
/* KEYED_FRAGMENT */
))
],
32
/* NEED_HYDRATION */
)
])
]);
}
const PagesTextText2 = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render], ["__scopeId", "data-v-cd5869b7"], ["__file", "D:/Projects/uniapp/app-test/test1/pages/text/text2.vue"]]);
__definePage("pages/Login/Login", PagesLoginLogin);
__definePage("pages/Chat/Chat", PagesChatChat);
__definePage("pages/WorkSpace/WorkSpace", PagesWorkSpaceWorkSpace);
__definePage("pages/UserProfileModal/UserProfileModal", PagesUserProfileModalUserProfileModal);
__definePage("pages/ContactPages/ContactPages", PagesContactPagesContactPages);
__definePage("pages/WorkSpace/TemplateSpace/TemplateSpace", PagesWorkSpaceTemplateSpaceTemplateSpace);
__definePage("pages/text/text", PagesTextText);
__definePage("pages/text/text2", PagesTextText2);
const _sfc_main = {
onLaunch: function() {
formatAppLog("log", "at App.vue:4", "App Launch");
},
onShow: function() {
formatAppLog("log", "at App.vue:7", "App Show");
},
onHide: function() {
formatAppLog("log", "at App.vue:10", "App Hide");
}
};
const App = /* @__PURE__ */ _export_sfc(_sfc_main, [["__file", "D:/Projects/uniapp/app-test/test1/App.vue"]]);
function createApp() {
const app = vue.createVueApp(App);
const pinia = createPinia();
app.use(pinia);
return {
app,
pinia
// 暴露pinia避免后续调用时丢失上下文
};
}
const { app: __app__, Vuex: __Vuex__, Pinia: __Pinia__ } = createApp();
uni.Vuex = __Vuex__;
uni.Pinia = __Pinia__;
__app__.provide("__globalStyles", __uniConfig.styles);
__app__._component.mpType = "app";
__app__._component.render = () => {
};
__app__.mount("#app");
})(Vue);