From 36eff63b1044b79fb7759a9490d1020b77985838 Mon Sep 17 00:00:00 2001 From: Jafeng <2998840497@qq.com> Date: Thu, 28 May 2026 16:18:21 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=B8=B8?= =?UTF-8?q?=E7=94=A8=E8=AF=AD=E5=B1=82=E7=BA=A7=E6=98=BE=E7=A4=BA=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8F=91=E9=80=81=E6=95=88=E6=9E=9C=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=9B=9E=E8=AE=BF=E6=A8=A1=E6=9D=BF=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/case/plan-list.vue | 10 +-- pages/message/common-phrases.vue | 133 +++++++++++++++++++++++++++++-- pages/message/index.vue | 47 +++++------ 3 files changed, 147 insertions(+), 43 deletions(-) diff --git a/pages/case/plan-list.vue b/pages/case/plan-list.vue index cb9c3af..ccbe7e8 100644 --- a/pages/case/plan-list.vue +++ b/pages/case/plan-list.vue @@ -355,10 +355,8 @@ function preview(plan) { .category-text { width: 100%; - overflow: hidden; - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; + display: block; + overflow: visible; word-break: break-all; } @@ -430,9 +428,7 @@ function preview(plan) { color: #6b7280; font-size: 30rpx; line-height: 40rpx; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; + word-break: break-all; } .task-link { diff --git a/pages/message/common-phrases.vue b/pages/message/common-phrases.vue index cb08211..01ec86a 100644 --- a/pages/message/common-phrases.vue +++ b/pages/message/common-phrases.vue @@ -21,14 +21,23 @@ + + + {{ category.name }} { return activeTab.value === "more" ? corpCategories.value : myCategories.value; }); +const getCategorySortValue = (category) => { + return Number.isFinite(Number(category?.sort)) ? Number(category.sort) : 10000; +}; + +const sortCategorySiblings = (list) => { + return [...list].sort((a, b) => { + const sortDiff = getCategorySortValue(a) - getCategorySortValue(b); + if (sortDiff !== 0) return sortDiff; + return String(a.name || "").localeCompare(String(b.name || ""), "zh-Hans-CN"); + }); +}; + +const buildCategoryTree = (categories) => { + const nodeMap = new Map(); + const roots = []; + + categories.forEach((category) => { + nodeMap.set(category.id, { ...category, children: [], childrenIds: [] }); + }); + + nodeMap.forEach((node) => { + const parent = node.parentId ? nodeMap.get(node.parentId) : null; + if (parent) { + parent.children.push(node); + } else { + roots.push(node); + } + }); + + const normalizeNodes = (nodes) => { + return sortCategorySiblings(nodes).map((node) => { + const children = normalizeNodes(node.children || []); + const childrenIds = []; + children.forEach((child) => { + childrenIds.push(child.id); + if (Array.isArray(child.childrenIds)) { + childrenIds.push(...child.childrenIds); + } + }); + return { ...node, children, childrenIds }; + }); + }; + + return normalizeNodes(roots); +}; + +const flattenCategoryTree = (nodes, visibleOnly = false) => { + const list = []; + const walk = (items) => { + items.forEach((item) => { + const children = Array.isArray(item.children) ? item.children : []; + const expanded = expandedCategoryMap.value[item.id] !== false; + list.push({ ...item, hasChildren: children.length > 0, expanded }); + if (children.length > 0 && (!visibleOnly || expanded)) { + walk(item.children); + } + }); + }; + walk(nodes); + return list; +}; + +const currentCategoryTree = computed(() => buildCategoryTree(currentCategories.value)); + +const currentCategoryNodes = computed(() => flattenCategoryTree(currentCategoryTree.value, true)); + const currentCategoryName = computed(() => { const category = currentCategories.value.find((item) => item.id === currentCategory.value); return category ? category.name : "未选择"; }); const firstMyCategory = computed(() => { - return myCategories.value[0]; + return flattenCategoryTree(buildCategoryTree(myCategories.value))[0]; +}); + +const firstCorpCategory = computed(() => { + return flattenCategoryTree(buildCategoryTree(corpCategories.value))[0]; }); const defaultMyCategory = computed(() => { @@ -402,6 +482,10 @@ const normalizeCategory = (item, categoryType) => { }; }; +const sortFlatCategoriesByTree = (categories) => { + return flattenCategoryTree(buildCategoryTree(categories)).map(({ hasChildren, expanded, ...item }) => item); +}; + const normalizeFiles = (files) => { if (!Array.isArray(files)) return []; return files @@ -470,19 +554,37 @@ const switchTab = (tab) => { currentCategory.value = tab === "mine" ? defaultMyCategory.value?.id || firstMyCategory.value?.id || "" - : corpCategories.value[0]?.id || ""; + : firstCorpCategory.value?.id || ""; }; const toggleEditMode = () => { isEditMode.value = !isEditMode.value; }; +const getCategoryItemStyle = (category) => { + const level = Math.max(Number(category?.level || 1), 1); + return { + paddingLeft: `${8 + (level - 1) * 12}rpx`, + }; +}; + +const toggleCategoryExpand = (category) => { + if (!category?.hasChildren) return; + expandedCategoryMap.value = { + ...expandedCategoryMap.value, + [category.id]: !category.expanded, + }; +}; + const handleCategoryClick = (category) => { if (activeTab.value === "mine" && isEditMode.value && category.deletable) { editCategory(category); return; } currentCategory.value = category.id; + if (category.hasChildren) { + toggleCategoryExpand(category); + } }; const sendPhrase = (phrase) => { @@ -882,7 +984,8 @@ const loadMyCategories = async ({ ensureDefault = true } = {}) => { const result = await api("getUserCommonWordCate", { corpId, userId }); if (result.success) { const list = Array.isArray(result.list) ? result.list : []; - myCategories.value = list.map((item) => normalizeCategory(item, "user")).filter((item) => item.id); + const categories = list.map((item) => normalizeCategory(item, "user")).filter((item) => item.id); + myCategories.value = sortFlatCategoriesByTree(categories); if (ensureDefault && !defaultMyCategory.value) { await createDefaultMyCategory(); return; @@ -922,9 +1025,10 @@ const loadCorpCategories = async () => { const result = await api("getCorpCommonWordCate", { corpId, userId }, false); if (result.success) { const list = Array.isArray(result.list) ? result.list : []; - corpCategories.value = list.map((item) => normalizeCategory(item, "corp")).filter((item) => item.id); + const categories = list.map((item) => normalizeCategory(item, "corp")).filter((item) => item.id); + corpCategories.value = sortFlatCategoriesByTree(categories); if (activeTab.value === "more" && !currentCategory.value) { - currentCategory.value = corpCategories.value[0]?.id || ""; + currentCategory.value = firstCorpCategory.value?.id || ""; } } }; @@ -1051,7 +1155,7 @@ $border-color: #edf0f5; min-height: 88rpx; display: flex; align-items: center; - justify-content: center; + justify-content: flex-start; padding: 12rpx 16rpx; color: #344054; background: #fff; @@ -1080,15 +1184,28 @@ $border-color: #edf0f5; .category-content { position: relative; width: 100%; - text-align: center; + display: flex; + align-items: center; + min-width: 0; } .category-name { + flex: 1; + min-width: 0; font-size: 30rpx; line-height: 40rpx; word-break: break-all; } + .category-toggle { + width: 32rpx; + height: 40rpx; + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + } + .delete-badge { position: absolute; top: -22rpx; diff --git a/pages/message/index.vue b/pages/message/index.vue index 926aa1c..2c7231a 100644 --- a/pages/message/index.vue +++ b/pages/message/index.vue @@ -994,43 +994,34 @@ onHide(() => { const sendCommonPhrase = async (phraseOrContent) => { if (!chatInputRef.value) return; - - const content = - typeof phraseOrContent === "string" + + const content = + typeof phraseOrContent === "string" ? phraseOrContent : phraseOrContent?.content || ""; const files = Array.isArray(phraseOrContent?.files) ? phraseOrContent.files : []; + const hasContent = Boolean(content.trim()); - if (content.trim()) { - chatInputRef.value.setInputText(content); - } - - if (files.length === 0) { + if (!hasContent && files.length === 0) { return; } - const shouldSendImages = await new Promise((resolve) => { - uni.showModal({ - title: "提示", - content: `该常用语包含${files.length}张图片,是否发送图片?`, - cancelText: "取消", - confirmText: "发送", - success: (res) => { - resolve(Boolean(res.confirm)); - }, - fail: (error) => { - console.error("常用语图片发送确认失败:", error); - resolve(false); - }, - }); - }); - - if (!shouldSendImages) { - return; + if (files.length > 0) { + uni.showLoading({ title: "发送中...", mask: true }); } - for (const file of files) { - await chatInputRef.value.sendImageMessageFromPhrase(file); + try { + if (hasContent) { + await chatInputRef.value.sendTextMessageFromPhrase(content); + } + + for (const file of files) { + await chatInputRef.value.sendImageMessageFromPhrase(file); + } + } finally { + if (files.length > 0) { + uni.hideLoading(); + } } }; From 8eeea1742ad6225e5684f517a31c4edf12ff600f Mon Sep 17 00:00:00 2001 From: Jafeng <2998840497@qq.com> Date: Thu, 28 May 2026 18:56:44 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=88=A4?= =?UTF-8?q?=E6=96=AD=E7=94=A8=E6=88=B7=E6=98=AF=E5=90=A6=E4=B8=BA=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E8=80=85=E7=9A=84=E9=80=BB=E8=BE=91=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=94=B6=E8=97=8F=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/case/plan-list.vue | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pages/case/plan-list.vue b/pages/case/plan-list.vue index ccbe7e8..6df936a 100644 --- a/pages/case/plan-list.vue +++ b/pages/case/plan-list.vue @@ -240,10 +240,21 @@ function onSearchInput() { function canToggleFavorite(plan) { if (!plan || !plan._id) return false; + if (isCreatedByCurrentUser(plan)) return false; if (activeViewType.value !== 'my') return true; return Boolean(plan.isFavorite); } +function isCreatedByCurrentUser(plan = {}) { + const userId = getUserId(); + if (!userId) return false; + if (String(plan.createor || plan.creator || '') === userId) return true; + const signature = plan.creatorSignature && typeof plan.creatorSignature === 'object' + ? plan.creatorSignature + : null; + return signature?.type === 'personal' && String(signature.person?.userId || '') === userId; +} + async function toggleFavorite(plan) { const corpId = getCorpId(); const userId = getUserId(); From 904354e5a8f7a28f365dc11079f80438ed1a4745 Mon Sep 17 00:00:00 2001 From: Jafeng <2998840497@qq.com> Date: Fri, 29 May 2026 15:44:15 +0800 Subject: [PATCH 3/3] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E5=88=86?= =?UTF-8?q?=E7=B1=BB=E6=A0=91=E6=9E=84=E5=BB=BA=E9=80=BB=E8=BE=91=EF=BC=8C?= =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/message/common-phrases.vue | 60 +++++++++++++++----------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/pages/message/common-phrases.vue b/pages/message/common-phrases.vue index 01ec86a..9ce70ed 100644 --- a/pages/message/common-phrases.vue +++ b/pages/message/common-phrases.vue @@ -328,49 +328,47 @@ const currentCategories = computed(() => { }); const getCategorySortValue = (category) => { - return Number.isFinite(Number(category?.sort)) ? Number(category.sort) : 10000; -}; - -const sortCategorySiblings = (list) => { - return [...list].sort((a, b) => { - const sortDiff = getCategorySortValue(a) - getCategorySortValue(b); - if (sortDiff !== 0) return sortDiff; - return String(a.name || "").localeCompare(String(b.name || ""), "zh-Hans-CN"); - }); + return category?.sort >= 0 ? Number(category.sort) : 10000; }; const buildCategoryTree = (categories) => { - const nodeMap = new Map(); - const roots = []; + if (!Array.isArray(categories)) return []; - categories.forEach((category) => { - nodeMap.set(category.id, { ...category, children: [], childrenIds: [] }); - }); + const level3 = categories + .filter((item) => item.level === 3) + .map((item) => { + const children = categories.filter((child) => child.parentId === item.id).map((child) => ({ ...child })); + const childrenIds = children.map((child) => child.id); + return { ...item, children, childrenIds }; + }); - nodeMap.forEach((node) => { - const parent = node.parentId ? nodeMap.get(node.parentId) : null; - if (parent) { - parent.children.push(node); - } else { - roots.push(node); - } - }); - - const normalizeNodes = (nodes) => { - return sortCategorySiblings(nodes).map((node) => { - const children = normalizeNodes(node.children || []); - const childrenIds = []; + const level2 = categories + .filter((item) => item.level === 2) + .map((item) => { + const children = level3.filter((child) => child.parentId === item.id).map((child) => ({ ...child })); + const childrenIds = children.map((child) => child.id); children.forEach((child) => { childrenIds.push(child.id); if (Array.isArray(child.childrenIds)) { childrenIds.push(...child.childrenIds); } }); - return { ...node, children, childrenIds }; + return { ...item, children, childrenIds }; }); - }; - return normalizeNodes(roots); + return categories + .filter((item) => item.level === 1) + .map((item) => { + const children = level2.filter((child) => child.parentId === item.id); + const childrenIds = children.map((child) => child.id); + children.forEach((child) => { + if (Array.isArray(child.childrenIds) && child.childrenIds.length > 0) { + childrenIds.push(...child.childrenIds); + } + }); + return { ...item, children, childrenIds }; + }) + .sort((a, b) => getCategorySortValue(a) - getCategorySortValue(b)); }; const flattenCategoryTree = (nodes, visibleOnly = false) => { @@ -473,7 +471,7 @@ const normalizeCategory = (item, categoryType) => { return { id: item._id || item.id, name, - sort: item.sort || 0, + sort: item.sort, level: item.level || 1, parentId: item.parentId || "", type: categoryType,