更新了多个文件以优化样式和功能,包括在UnoCSS配置中添加预设,调整了主题颜色和消息组件的样式,更新了环境变量,修复了头像组件的尺寸,并在消息面板中添加了多选功能。

This commit is contained in:
Phoenix 2025-05-12 13:44:13 +08:00
parent d2c8de16bb
commit d413a6b9fe
26 changed files with 112 additions and 73 deletions

View File

@ -5,4 +5,4 @@
"singleQuote": true,
"printWidth": 100,
"trailingComma": "none"
}
}

4
env/.env.test vendored
View File

@ -2,7 +2,7 @@ ENV = 'development'
VITE_BASE=/
VUE_APP_PREVIEW=false
VITE_BASE_API=http://172.16.100.93:8503
VITE_BASE_API=http://114.218.158.24:8503
VITE_EPR_BASEURL=http://114.218.158.24:9020
VITE_SOCKET_API=ws://172.16.100.93:8504
VITE_SOCKET_API=ws://114.218.158.24:8504
VUE_APP_WEBSITE_NAME="Lumen IM"

View File

@ -34,11 +34,11 @@
"xgplayer": "^3.0.4"
},
"devDependencies": {
"vite-plugin-vue-devtools": "^7.7.6",
"@icon-park/vue-next": "^1.4.2",
"@tsconfig/node18": "^18.2.2",
"@types/node": "^18.18.5",
"@types/vue": "^2.0.0",
"@unocss/reset": "^66.1.1",
"@vitejs/plugin-vue": "^4.4.0",
"@vitejs/plugin-vue-jsx": "^3.0.2",
"@vue/tsconfig": "^0.4.0",
@ -53,6 +53,7 @@
"unocss": "^66.1.1",
"vite": "^4.5.1",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-vue-devtools": "^7.7.6",
"vue-tsc": "^1.8.25",
"wait-on": "^6.0.1"
},

View File

@ -75,6 +75,9 @@ importers:
'@types/vue':
specifier: ^2.0.0
version: 2.0.0(typescript@5.2.2)
'@unocss/reset':
specifier: ^66.1.1
version: 66.1.1
'@vitejs/plugin-vue':
specifier: ^4.4.0
version: 4.6.2(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0))(vue@3.5.13(typescript@5.2.2))

View File

@ -1,6 +1,7 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box!important;
}
@font-face {

View File

@ -4,7 +4,7 @@ html {
--im-bg-color: #ffffff;
--line-border-color: #f5f5f5;
--border-color: #eeeaea;
--im-text-color: #333;
--im-text-color: #BABABA;
--im-text-color-grey: #333;
--im-active-bg-color: #f5f5f5;
--im-hover-bg-color: #f5f5f5;
@ -21,10 +21,10 @@ html {
// message
--im-message-bg-color: #f7f7f7;
--im-message-border-color: #efeff5;
--im-message-left-bg-color: #eff0f1;
--im-message-left-bg-color: #F4F4FC;
--im-message-left-text-color: #333;
--im-message-right-bg-color: #daf3fd;
--im-message-right-text-color: #333;
--im-message-right-bg-color: #46299D;
--im-message-right-text-color: #fff;
}
// 黑色主题

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -87,8 +87,8 @@ const text_avatar = computed(() => {
background: linear-gradient(to right, #674bbc, #46299d);
flex-shrink: 0;
img {
width: 100%;
height: 100%;
width: 42px;
height: 42px;
object-fit: cover;
}
}

View File

@ -46,7 +46,8 @@ const img = (src: string, width = 200) => {
background: var(--im-message-left-bg-color);
min-width: 30px;
min-height: 30px;
max-width:240px;
max-height:300px
&.left {
background: var(--im-message-right-bg-color);
}

View File

@ -45,7 +45,7 @@ textContent = textReplaceEmoji(textContent)
color: var(--im-message-left-text-color);
background: var(--im-message-left-bg-color);
border-radius: 0px 10px 10px 10px;
font-size: 14px;
&.right {
background-color: var(--im-message-right-bg-color);
color: var(--im-message-right-text-color);

View File

@ -1,14 +1,28 @@
// 主题配置
const primaryColor='#46299D'
export const overrides = {
common: {
primaryColor: '#1890ff',
primaryColorHover: '#1890ff',
primaryColorPressed: '#1890ff',
primaryColorSuppl: '#1890ff',
bodyColor: '#ffffff'
DataTable: {
sorterIconColor:'#fff',
thColorHover: primaryColor,
thTextColor: "#fff",
thColor: primaryColor,
thBackgroundColor: primaryColor,
itemColorActive:primaryColor,
},
Dialog: {
borderRadius: '10px'
Button: {
textColor: primaryColor,
},
Dropdown:{
optionTextColorHover:'#46299D',
optionColorHover:'#EEE9F8'
},
common: {
primaryColorPressed: primaryColor,
primaryHover:primaryColor,
primaryDefault: primaryColor,
primaryActive: primaryColor,
primarySuppl: primaryColor,
primaryColor: primaryColor,
primaryColorHover: primaryColor
}
}

View File

@ -7,21 +7,21 @@ const settingsStore = useSettingsStore()
</script>
<template>
<section class="container flex-center">
<section class="top-container flex-center">
<section
class="el-container im-container"
:class="{
'small-screen': !settingsStore.isFullScreen
}"
>
<aside
<!-- <aside
class="el-aside"
:class="{
'pd-t15': isElectronMode()
}"
>
<Menu />
</aside>
</aside> -->
<main class="el-main">
<router-view />
</main>
@ -30,8 +30,8 @@ const settingsStore = useSettingsStore()
</template>
<style lang="less" scoped>
.container {
.top-container {
width: 100%;
background: url(@/assets/image/background.jpeg);
background-position: center center;
background-repeat: no-repeat;
@ -39,8 +39,8 @@ const settingsStore = useSettingsStore()
background-size: cover;
.im-container {
height: 80vh;
width: 100vw;
height: 85vh;
width: 100%;
overflow: hidden;
background-color: #fff;

View File

@ -5,7 +5,7 @@ import { createApp } from 'vue'
import router from './router'
import App from './App.vue'
import * as plugins from './plugins'
import 'uno.css'
async function bootstrap() {
const app = createApp(App)

View File

@ -125,7 +125,7 @@ onMounted(() => {
<n-input
placeholder="搜索好友 / 群聊"
v-model:value.trim="searchKeyword"
round
clearable
style="width: 78%"
>
@ -142,7 +142,7 @@ onMounted(() => {
</header>
<!-- 置顶栏目 -->
<header class="el-header header-top" v-show="loadStatus == 3 && topItems.length > 0">
<!-- <header class="el-header header-top" v-show="loadStatus == 3 && topItems.length > 0">
<n-popover v-for="item in topItems" :key="item.index_name" placement="bottom" trigger="hover">
<template #trigger>
<div
@ -165,10 +165,10 @@ onMounted(() => {
</template>
<span> {{ item.remark || item.name }} </span>
</n-popover>
</header>
</header> -->
<!-- 标题栏目 -->
<header
<!-- <header
v-show="loadStatus == 3 && talkStore.talkItems.length > 0"
class="el-header header-badge"
:class="{ shadow: false }"
@ -177,7 +177,7 @@ onMounted(() => {
<p>
<span class="badge unread" v-show="unreadNum">{{ unreadNum }}未读</span>
</p>
</header>
</header> -->
<main id="talk-session-list" class="el-main me-scrollbar me-scrollbar-thumb">
<template v-if="loadStatus == 2"><Skeleton /></template>

View File

@ -10,16 +10,23 @@ defineProps({
username: String,
active: Boolean
})
//1=2=3=4=/
const labelColor=[
{group_type:2,color:'#377EC6',label:'部门'},
{group_type:3,color:'#C1691C',label:'项目'},
{group_type:4,color:'#7A58DE',label:'公司'},
]
</script>
<template>
<div class="talk pointer" :class="{ actived: active }" @click="emit('tab-talk', data)">
<div class="avatar-box">
<div class="avatar-box relative">
<avatarModule :mode="data?.group_type === 0 ? 1 : 2"
:avatar="data?.avatar"
:groupType="data?.group_type"
:userName="data?.name" :customStyle="{width:'42px',height:'42px'}"></avatarModule>
<div v-if="[2,3,4].includes(data.group_type)" class="absolute w-32px h-18px border-2px border-solid rounded-3px top-28px bg-#fff text-10px flex justify-center items-center leading-none" :style="`color:${labelColor.find(x=>x.group_type===data.group_type)?.color};border-color:${labelColor.find(x=>x.group_type===data.group_type)?.color}`">{{ labelColor.find(x=>x.group_type===data.group_type)?.label }}</div>
<!-- <im-avatar :src="avatar" :size="34" :username="data.name" /> -->
<div class="top-mask" @click.stop="emit('top-talk', data)">
<n-icon :component="data.is_top == 1 ? ArrowDown : ArrowUp" />
@ -30,9 +37,9 @@ defineProps({
<div class="header">
<div class="title">
<span class="nickname">{{ username }}</span>
<span class="badge top" v-show="data.is_top"></span>
<!-- <span class="badge top" v-show="data.is_top"></span>
<span class="badge roboot" v-show="data.is_robot"></span>
<span class="badge group" v-show="data.talk_type == 2"></span>
<span class="badge group" v-show="data.talk_type == 2"></span> -->
</div>
<div class="datetime"><Xtime :time="data.updated_at" /></div>
</div>
@ -80,8 +87,8 @@ defineProps({
border-radius: 5px;
.avatar-box {
height: 34px;
width: 34px;
height: 42px;
width: 42px;
border-radius: 50%;
display: flex;
justify-content: center;
@ -90,7 +97,7 @@ defineProps({
user-select: none;
transition: ease 1s;
position: relative;
overflow: hidden;
.top-mask {
width: 100%;
@ -193,9 +200,9 @@ defineProps({
user-select: none;
.badge {
background-color: #f44336;
background-color: #D03050;
color: #ffffff;
border-radius: 3px;
border-radius: 50%;
transform-origin: right;
}
}

View File

@ -69,32 +69,42 @@ const onContactModal = (data: { id: number; type: number }[]) => {
<div class="multi-title">
<span>已选中{{ dialogueStore.selectItems.length }} 条消息</span>
</div>
<div class="multi-groups">
<div class="btn-group">
<div class="flex items-center relative">
<div class="multi-groups">
<div class="btn-group mr-156px">
<div class="multi-icon pointer flex-center" @click="onMergeForward">
<n-icon :size="22" :component="Share" />
<!-- <n-icon :size="22" :component="Share" /> -->
<img src="@/assets/image/zu6299@2x.png" class="w-72px h-72px" alt="">
</div>
<p>合并转发</p>
</div>
<div class="btn-group">
<div class="btn-group mr-156px">
<div class="multi-icon pointer flex-center" @click="onSingleForward">
<n-icon :size="22" :component="ShareThree" />
<!-- <n-icon :size="22" :component="ShareThree" /> -->
<img class="w-72px h-72px" src="@/assets/image/zu6300@2x.png">
</div>
<p>逐条转发</p>
</div>
<div class="btn-group">
<div class="btn-group ">
<div class="multi-icon pointer flex-center" @click="onMultiDelete">
<n-icon :size="22" :component="Delete" />
<!-- <n-icon :size="22" :component="Delete" /> -->
<img class="w-72px h-72px" src="@/assets/image/zu6302@2x.png">
</div>
<p>批量删除</p>
</div>
<div class="btn-group">
<!-- <div class="btn-group">
<div class="multi-icon pointer flex-center" @click="onClose">
<n-icon :size="22" :component="Close" />
</div>
<p>关闭</p>
</div>
</div> -->
</div>
<div class="pointer absolute right-150px top-50% translate-y-[-50%]" @click="onClose">
<img class="w-30px h-30px" src="@/assets/image/zu6306@2x.png" alt="">
</div>
</div>
</section>
<ContactModal
@ -126,13 +136,9 @@ const onContactModal = (data: { id: number; type: number }[]) => {
justify-content: center;
.btn-group {
width: 50px;
height: 80px;
margin: 0 15px;
.multi-icon {
width: 50px;
height: 50px;
width: 72px;
height: 72px;
background-color: var(--im-active-bg-color);
border-radius: 50%;

View File

@ -335,7 +335,7 @@ onMounted(() => {
<im-avatar
class="pointer"
:src="item.avatar"
:size="30"
:size="42"
:username="item.nickname"
@click="showUserInfoModal(item.user_id)"
/>
@ -351,7 +351,7 @@ onMounted(() => {
>
<span class="at">@</span>{{ item.nickname }}
</span>
<span>{{ parseTime(item.created_at, '{m}/{d} {h}:{i}') }}</span>
<span>{{ parseTime(item.created_at, '{y}/{m}/{d} {h}:{i}') }}</span>
</div>
<div
@ -420,6 +420,7 @@ onMounted(() => {
:show="dropdown.show"
:x="dropdown.x"
:y="dropdown.y"
style="width: 142px;"
:options="dropdown.options"
@select="onContextMenuHandle"
@clickoutside="closeDropdownMenu"
@ -489,7 +490,7 @@ onMounted(() => {
}
.avatar-column {
width: 35px;
width: 47px;
display: flex;
align-items: center;
order: 2;
@ -524,7 +525,7 @@ onMounted(() => {
.nickname {
color: var(--im-text-color);
margin-right: 5px;
font-size: 12px;
.at {
display: none;
}

View File

@ -37,14 +37,14 @@ export function useMenu() {
dropdown.options.push({ label: '复制', key: 'copy' })
}
dropdown.options.push({ label: '多选', key: 'multiSelect' })
dropdown.options.push({ label: '引用', key: 'quote' })
if (isRevoke(uid, item)) {
dropdown.options.push({ label: `撤回`, key: 'revoke' })
}
dropdown.options.push({ label: '回复', key: 'quote' })
dropdown.options.push({ label: '删除', key: 'delete' })
dropdown.options.push({ label: '多选', key: 'multiSelect' })
if ([3, 4, 5].includes(item.msg_type)) {
dropdown.options.push({ label: '下载', key: 'download' })

View File

@ -1,16 +1,22 @@
import { defineConfig } from 'unocss'
import { presetAttributify, presetIcons } from 'unocss'
import { presetUno, presetAttributify, presetIcons } from 'unocss'
export default defineConfig({
// 预设
presets: [
presetUno(),
presetAttributify(), // 启用属性模式
presetIcons(), // 启用图标
],
// 自定义规则
rules: [
// 通过自定义规则覆盖默认的 container 样式
['container', { 'max-width': 'none' }], // 或者根据需要设置其他样式
],
safelist: [
'container' // 确保 container 在 safelist 中,以便 UnoCSS 忽略它
],
// 快捷方式
shortcuts: {
'btn': 'px-4 py-2 rounded-lg bg-blue-500 text-white hover:bg-blue-600',
'uno-container': 'container' // 创建 container 的别名
},
})

View File

@ -25,11 +25,10 @@ export default defineConfig(({ mode }) => {
plugins: [
vue(),
vueJsx({}),
compressPlugin(),
UnoCSS(),
vueDevTools({
launchEditor: 'cursor',
})
// vueDevTools({
// launchEditor:'cursor'
// }),
UnoCSS()
],
define: {
__APP_ENV__: env.APP_ENV