From 2c1ae41c3e2f40b4cd3ba7941398048e96c524ff Mon Sep 17 00:00:00 2001 From: Phoenix <64720302+Concur-max@users.noreply.github.com> Date: Wed, 28 May 2025 11:29:13 +0800 Subject: [PATCH] =?UTF-8?q?feat(theme):=20=E5=B0=86=E4=B8=BB=E8=89=B2?= =?UTF-8?q?=E8=B0=83=E4=BB=8E#1890ff=E6=9B=B4=E6=94=B9=E4=B8=BA#462AA0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 统一修改多处UI组件的主色调,从蓝色(#1890ff)变更为紫色(#462AA0),以保持视觉一致性。同时优化了文件上传逻辑和滚动到底部功能。 refactor(dom): 提取滚动相关操作为工具函数 将滚动到底部逻辑封装为可复用的工具函数,并在多处调用位置进行替换,提高代码复用性。 fix(upload): 修复上传中文件点击打开问题 增加上传状态判断,避免在上传过程中点击文件时打开新窗口。 chore(deps): 更新依赖包版本 升级@types/node和watchpack等依赖包版本。 --- pnpm-lock.yaml | 24 +++++++++--------- src/assets/css/define/theme.less | 2 +- src/assets/css/dropsize.less | 2 +- src/components/base/Loading.vue | 4 +-- src/components/editor/Editor.vue | 1 + src/components/group/GroupPanel.vue | 2 +- src/components/talk/message/FileMessage.vue | 6 +++-- src/components/talk/message/LinkMessage.vue | 2 +- src/components/talk/message/TextMessage.vue | 2 +- src/components/talk/message/VoteMessage.vue | 2 +- .../talk/message/system/sys-message.less | 2 +- .../x-naive-ui/x-n-upload/index.vue | 2 +- src/directive/inner/loading.vue | 4 +-- src/event/talk.js | 7 +++--- src/hooks/useTalkRecord.ts | 14 +++-------- src/layout/component/Menu.vue | 2 +- src/utils/auth.js | 2 +- src/utils/common.js | 7 +++++- src/utils/dom.ts | 25 +++++++++++++++++++ .../message/inner/panel/PanelContent.vue | 5 ++-- src/views/message/inner/panel/PanelFooter.vue | 15 ++++++++--- src/views/message/inner/panel/PanelHeader.vue | 6 ++--- src/views/message/inner/panel/SkipBottom.vue | 12 +++------ vite.config.ts | 2 +- 24 files changed, 90 insertions(+), 62 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eb00edc..168cebb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -883,8 +883,8 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@18.19.101': - resolution: {integrity: sha512-Ykg7fcE3+cOQlLUv2Ds3zil6DVjriGQaSN/kEpl5HQ3DIGM6W0F2n9+GkWV4bRt7KjLymgzNdTnSKCbFUUJ7Kw==} + '@types/node@18.19.103': + resolution: {integrity: sha512-hHTHp+sEz6SxFsp+SA+Tqrua3AbmlAw+Y//aEwdHrdZkYVRWdvWD3y5uPZ0flYOkgskaFWqZ/YGFm3FaFQ0pRw==} '@types/node@18.19.99': resolution: {integrity: sha512-tNGqoGjjI4vY5jfm3lnqgR6yS8wyT76SfsWefLWRyh/cEK4UHmPVyqHZdafI/SNu1PQzfo2JLBWfG8eMmD7KrQ==} @@ -3517,8 +3517,8 @@ packages: warning@4.0.3: resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==} - watchpack@2.4.3: - resolution: {integrity: sha512-adBYQLivcg1jbdKEJeqScJJFvgm4qY9+3tXw+jdG6lkVeqRJEtiQmSWjmth8GKmDZuX7sYM4YFxQsf0AzMfGGw==} + watchpack@2.4.4: + resolution: {integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==} engines: {node: '>=10.13.0'} web-worker@1.5.0: @@ -3528,8 +3528,8 @@ packages: resolution: {integrity: sha512-BCfKo2YkDe2ByqkEWe1Rw+zko4LsyS75LVr29C6xIrxAg9JHJ4pl8kaIZ396SUSNp6b4815dRZPSTAS8LlURRQ==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - webpack-sources@3.2.3: - resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + webpack-sources@3.3.0: + resolution: {integrity: sha512-77R0RDmJfj9dyv5p3bM5pOHa+X8/ZkO9c7kpDstigkC4nIDobadsfSGCwB4bKhMVxqAok8tajaoR8rirM7+VFQ==} engines: {node: '>=10.13.0'} webpack-virtual-modules@0.6.2: @@ -4228,7 +4228,7 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node@18.19.101': + '@types/node@18.19.103': dependencies: undici-types: 5.26.5 @@ -5895,7 +5895,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 18.19.101 + '@types/node': 18.19.103 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -7244,7 +7244,7 @@ snapshots: dependencies: loose-envify: 1.4.0 - watchpack@2.4.3: + watchpack@2.4.4: dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 @@ -7256,7 +7256,7 @@ snapshots: deepmerge: 1.5.2 javascript-stringify: 1.6.0 - webpack-sources@3.2.3: {} + webpack-sources@3.3.0: {} webpack-virtual-modules@0.6.2: {} @@ -7284,8 +7284,8 @@ snapshots: schema-utils: 4.3.2 tapable: 2.2.2 terser-webpack-plugin: 5.3.14(webpack@5.99.8) - watchpack: 2.4.3 - webpack-sources: 3.2.3 + watchpack: 2.4.4 + webpack-sources: 3.3.0 transitivePeerDependencies: - '@swc/core' - esbuild diff --git a/src/assets/css/define/theme.less b/src/assets/css/define/theme.less index ac0e32e..07e3c33 100644 --- a/src/assets/css/define/theme.less +++ b/src/assets/css/define/theme.less @@ -29,7 +29,7 @@ html { // 黑色主题 html[theme-mode='dark'] { - --im-primary-color: #1890ff; + --im-primary-color: #462AA0; --im-bg-color: #202124; --line-border-color: rgb(255 255 255 / 9%); --border-color: rgb(255 255 255 / 9%); diff --git a/src/assets/css/dropsize.less b/src/assets/css/dropsize.less index ceb4074..fb6b1d1 100644 --- a/src/assets/css/dropsize.less +++ b/src/assets/css/dropsize.less @@ -12,7 +12,7 @@ &:hover, &.dropsize-resizing { - background-color: #1890ff; + background-color: #462AA0; } &.dropsize-line-top { diff --git a/src/components/base/Loading.vue b/src/components/base/Loading.vue index 63ee6e7..970ee4e 100644 --- a/src/components/base/Loading.vue +++ b/src/components/base/Loading.vue @@ -44,7 +44,7 @@ font-feature-settings: 'tnum'; position: absolute; display: none; - color: #1890ff; + color: #462AA0; text-align: center; vertical-align: middle; opacity: 0; @@ -177,7 +177,7 @@ display: block; width: 9px; height: 9px; - background-color: #1890ff; + background-color: #462AA0; border-radius: 100%; -webkit-transform: scale(0.75); transform: scale(0.75); diff --git a/src/components/editor/Editor.vue b/src/components/editor/Editor.vue index 4a5db01..fef3e47 100644 --- a/src/components/editor/Editor.vue +++ b/src/components/editor/Editor.vue @@ -143,6 +143,7 @@ const editorOption = { }, // 数据源函数,过滤匹配的用户 source: function (searchTerm: string, renderList: any) { + console.log("source") if (!props.members.length) { return renderList([]) } diff --git a/src/components/group/GroupPanel.vue b/src/components/group/GroupPanel.vue index 2642fd5..3d85ee1 100644 --- a/src/components/group/GroupPanel.vue +++ b/src/components/group/GroupPanel.vue @@ -990,7 +990,7 @@ const handleEditGroupNameConfirm = () => { margin: 3px 0; &:hover { .nickname { - color: #1890ff; + color: #462AA0; } } } diff --git a/src/components/talk/message/FileMessage.vue b/src/components/talk/message/FileMessage.vue index 6b9c8b7..9653726 100644 --- a/src/components/talk/message/FileMessage.vue +++ b/src/components/talk/message/FileMessage.vue @@ -86,12 +86,14 @@ const strokeDashoffset = computed(() => // 处理文件点击事件 const handleClick = () => { - console.log('handleClick') - window.open( + if(!props.extra.is_uploading){ + window.open( `${window.location.origin}/office?url=${props.extra.path}`, '_blank', 'width=1200,height=900,left=200,top=200,toolbar=no,menubar=no,scrollbars=yes,resizable=yes,location=no,status=no' ); + } + } function downloadFileWithProgress(resourceUrl, filename) { diff --git a/src/components/talk/message/LinkMessage.vue b/src/components/talk/message/LinkMessage.vue index f58c82e..8ab7e03 100644 --- a/src/components/talk/message/LinkMessage.vue +++ b/src/components/talk/message/LinkMessage.vue @@ -27,7 +27,7 @@ let textContent = props.extra?.content || '' textContent = textReplaceLink(textContent) if (props.data.talk_type == 2) { - textContent = textReplaceMention(textContent, '#1890ff') + textContent = textReplaceMention(textContent, '#462AA0') } textContent = textReplaceEmoji(textContent) diff --git a/src/components/talk/message/TextMessage.vue b/src/components/talk/message/TextMessage.vue index 49895dc..3798dac 100644 --- a/src/components/talk/message/TextMessage.vue +++ b/src/components/talk/message/TextMessage.vue @@ -17,7 +17,7 @@ let textContent = props.extra?.content || '' textContent = textReplaceLink(textContent) if (props.data.talk_type == 2) { - textContent = textReplaceMention(textContent, '#1890ff') + textContent = textReplaceMention(textContent, '#462AA0') } textContent = textReplaceEmoji(textContent) diff --git a/src/components/talk/message/VoteMessage.vue b/src/components/talk/message/VoteMessage.vue index c856fd5..794dca5 100644 --- a/src/components/talk/message/VoteMessage.vue +++ b/src/components/talk/message/VoteMessage.vue @@ -121,7 +121,7 @@ onMounted(() => { :height="5" :show-indicator="false" :percentage="parseInt(option.progress)" - color="#1890ff" + color="#462AA0" />

diff --git a/src/components/talk/message/system/sys-message.less b/src/components/talk/message/system/sys-message.less index 2443ed0..e29d894 100644 --- a/src/components/talk/message/system/sys-message.less +++ b/src/components/talk/message/system/sys-message.less @@ -28,7 +28,7 @@ font-weight: 400; &:hover { - color: #1890ff; + color: #462AA0; } } } diff --git a/src/components/x-naive-ui/x-n-upload/index.vue b/src/components/x-naive-ui/x-n-upload/index.vue index b06334c..b27942b 100644 --- a/src/components/x-naive-ui/x-n-upload/index.vue +++ b/src/components/x-naive-ui/x-n-upload/index.vue @@ -1514,7 +1514,7 @@ const numWidth = computed(() => { .x-upload-preview-button:hover { background-color: #e6f7ff; - color: #1890ff; + color: #462AA0; } .x-upload-download-button:hover { diff --git a/src/directive/inner/loading.vue b/src/directive/inner/loading.vue index 76b3d42..e38c7aa 100644 --- a/src/directive/inner/loading.vue +++ b/src/directive/inner/loading.vue @@ -45,7 +45,7 @@ font-feature-settings: 'tnum'; position: absolute; display: none; - color: #1890ff; + color: #462AA0; text-align: center; vertical-align: middle; opacity: 0; @@ -103,7 +103,7 @@ display: block; width: 9px; height: 9px; - background-color: #1890ff; + background-color: #462AA0; border-radius: 100%; transform: scale(0.75); transform-origin: 50% 50%; diff --git a/src/event/talk.js b/src/event/talk.js index 52a21d8..7826004 100644 --- a/src/event/talk.js +++ b/src/event/talk.js @@ -7,6 +7,7 @@ import { formatTalkItem, palyMusic, formatTalkRecord } from '@/utils/talk' import { isElectronMode } from '@/utils/common' import { ServeClearTalkUnreadNum, ServeCreateTalkList } from '@/api/chat' import { useTalkStore, useDialogueStore, useSettingsStore } from '@/store' +import { isScrollAtBottom, scrollToBottom } from '@/utils/dom' /** * 好友状态事件 @@ -189,12 +190,10 @@ class Talk extends Base { if (!el) return // 判断的滚动条是否在底部 - const isBottom = Math.ceil(el.scrollTop) + el.clientHeight >= el.scrollHeight + const isBottom = isScrollAtBottom(el) if (isBottom || record.user_id == this.getAccountId()) { - nextTick(() => { - el.scrollTop = el.scrollHeight + 1000 - }) + scrollToBottom() } else { useDialogueStore().setUnreadBubble() } diff --git a/src/hooks/useTalkRecord.ts b/src/hooks/useTalkRecord.ts index e2af558..aab6ab6 100644 --- a/src/hooks/useTalkRecord.ts +++ b/src/hooks/useTalkRecord.ts @@ -3,7 +3,7 @@ import { ServeTalkRecords } from '@/api/chat' import { useDialogueStore } from '@/store' import { ITalkRecord } from '@/types/chat' import { formatTalkRecord } from '@/utils/talk' -import { addClass, removeClass } from '@/utils/dom' +import { addClass, removeClass, scrollToBottom, isScrollAtBottom } from '@/utils/dom' interface Params { receiver_id: number @@ -137,16 +137,8 @@ export const useTalkRecord = (uid: number) => { if (el) { if (request.cursor == 0) { - el.scrollTop = el.scrollHeight - - setTimeout(() => { - console.log('el.scrollHeight',el.scrollHeight) - console.log('request.cursor == 0') - el.scrollTop = el.scrollHeight + 1000 - - }, 500) + scrollToBottom() } else { - console.log('request.cursor !== 0') el.scrollTop = el.scrollHeight - scrollHeight } } @@ -222,7 +214,7 @@ export const useTalkRecord = (uid: number) => { addClass(target, 'border') setTimeout(() => removeClass(target, 'border'), 3000) } else if (el) { - el.scrollTop = el.scrollHeight + scrollToBottom() } }, 50) }) diff --git a/src/layout/component/Menu.vue b/src/layout/component/Menu.vue index 2490f6f..679d7ca 100644 --- a/src/layout/component/Menu.vue +++ b/src/layout/component/Menu.vue @@ -119,7 +119,7 @@ const isActive = (menu) => { diff --git a/src/utils/auth.js b/src/utils/auth.js index 41b38a6..9a5803a 100644 --- a/src/utils/auth.js +++ b/src/utils/auth.js @@ -18,7 +18,7 @@ export function isLoggedIn() { */ export function getAccessToken() { // return storage.get(AccessToken) || '' - return JSON.parse(localStorage.getItem('token'))||'46d71a72d8d845ad7ed23eba9bdde260e635407190c2ce1bf7fd22088e41682ea07773ec65cae8946d2003f264d55961f96e0fc5da10eb96d3a348c1664e9644ce2108c311309f398ae8ea1b8200bfd490e5cb6e8c52c9e5d493cbabb163368f8351420451a631dbfa749829ee4cda49b77b5ed2d3dced5d0f2b7dd9ee76ba5465c84a17c23af040cd92b6b2a4ea48befbb5c729dcdad0a9c9668befe84074cc24f78899c1d947f8e7f94c7eda5325b8ed698df729e76febb98549ef3482ae942fb4f4a1c92d21836fa784728f0c5483aab2760a991b6b36e6b10c84f840a6433a6ecc31dee36e8f1c6158818bc89d22ab23a552e0c3f606946dcb914a52b692e10d823cc7f43027127359e7ee8555d956e7e095946931ceaa3877675584b0a0a4fc690c8018712b306050ebbdea92037aea31d66d65004be26d3c696abc4c29' + return JSON.parse(localStorage.getItem('token'))||'46d71a72d8d845ad7ed23eba9bdde260e635407190c2ce1bf7fd22088e41682ea07773ec65cae8946d2003f264d55961f96e0fc5da10eb96d3a348c1664e9644ce2108c311309f398ae8ea1b8200bfd490e5cb6e8c52c9e5d493cbabb163368f8351420451a631dbfa749829ee4cda49b77b5ed2d3dced5d0f2b7dd9ee76ba5465c84a17c23af040cd92b6b2a4ea48befbb5c729dcdad0a9c9668befe84074cc24f78899c1d947f8e7f94c7eda5325b8ed698df729e76febb98549ef3482ae942fb4f4a1c92d21836fa784728f0c5483aab2760a991b6b36e6b10c84f840a6433a6ecc31dee36e8f1c6158818bc89d227de310c4e6f5d7ff11a9e1ea73aba3f6c749f75a50a2aeaed07b14bc0d8b1db6428caf891f0a0b0c84a49697f4a4e7c8b87d972340ecbf02ddbc4d4f1e51b057c822f8351524e19d52a3ec5ce8c83e2f' } /** diff --git a/src/utils/common.js b/src/utils/common.js index 512ac2d..788490c 100644 --- a/src/utils/common.js +++ b/src/utils/common.js @@ -52,7 +52,12 @@ export function throttle(fn, delay, call = function () {}) { * @param {Function} callback 复制成功回调方法 */ export function clipboard(text, callback) { - navigator.clipboard + // 在wujie环境下使用主应用的clipboard + const clipboardObj = window.__POWERED_BY_WUJIE__ + ? window.parent.navigator.clipboard + : navigator.clipboard + + clipboardObj .writeText(text) .then(() => { callback && callback() diff --git a/src/utils/dom.ts b/src/utils/dom.ts index d16e443..cd13e78 100644 --- a/src/utils/dom.ts +++ b/src/utils/dom.ts @@ -1,3 +1,5 @@ +import { nextTick } from 'vue' + function trim(string: string) { return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, '') } @@ -54,3 +56,26 @@ export function removeClass(el: Element, cls: string) { el.className = trim(curClass) } } + +/** + * 判断容器是否已在底部 + * @param el DOM元素 + * @returns boolean + */ +export function isScrollAtBottom(el: HTMLElement): boolean { + return Math.ceil(el.scrollTop) + el.clientHeight >= el.scrollHeight +} + +/** + * 滚动指定容器到底部 + * @param id 容器的DOM id,默认 'imChatPanel' + * @param offset 偏移量,默认 0 + */ +export function scrollToBottom(id = 'imChatPanel', offset = 0) { + nextTick(() => { + const el = document.getElementById(id) + if (el) { + el.scrollTop = el.scrollHeight + offset + } + }) +} diff --git a/src/views/message/inner/panel/PanelContent.vue b/src/views/message/inner/panel/PanelContent.vue index f37fd7d..4c533d5 100644 --- a/src/views/message/inner/panel/PanelContent.vue +++ b/src/views/message/inner/panel/PanelContent.vue @@ -95,7 +95,6 @@ const onPanelScroll = (e: any) => { if (!skipBottom.value && dialogueStore.unreadBubble) { dialogueStore.setUnreadBubble(0) } - // 检测是否到达底部 if (skipBottom.value == false) { let len = dialogueStore.records.length @@ -232,7 +231,7 @@ const onClickNickname = (data: ITalkRecord) => { // 会话列表右键显示菜单 const onContextMenu = (e: any, item: ITalkRecord) => { - console.log('item',item) + if (!dialogueStore.isShowEditor || dialogueStore.isOpenMultiSelect) { return e.preventDefault() } @@ -243,7 +242,7 @@ const onContextMenu = (e: any, item: ITalkRecord) => { } const onConvertText = async (data: ITalkRecord) => { - console.log('data', data) + data.is_convert_text = 1 const res = await voiceToText({ msgId: data.msg_id, voiceUrl: data.extra.url }) if (res.code == 200) { diff --git a/src/views/message/inner/panel/PanelFooter.vue b/src/views/message/inner/panel/PanelFooter.vue index 4499aab..a8e5c52 100644 --- a/src/views/message/inner/panel/PanelFooter.vue +++ b/src/views/message/inner/panel/PanelFooter.vue @@ -1,5 +1,5 @@ @@ -35,7 +31,7 @@ const onSkipBottom = () => { min-width: 100px; height: 28px; font-size: 12px; - background-color: #1ebafc; + background-color: #462AA0; color: #ffffff; display: flex; align-items: center; diff --git a/vite.config.ts b/vite.config.ts index dd4857f..83a792e 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -47,7 +47,7 @@ export default defineConfig(({ mode }) => { compressPlugin(), UnoCSS(), vueDevTools({ - launchEditor: 'cursor', + launchEditor: 'trae', }) ], define: {