更新了多个文件以优化样式和功能,包括在UnoCSS配置中添加预设,调整了主题颜色和消息组件的样式,更新了环境变量,修复了头像组件的尺寸,并在消息面板中添加了多选功能。
@ -5,4 +5,4 @@
|
||||
"singleQuote": true,
|
||||
"printWidth": 100,
|
||||
"trailingComma": "none"
|
||||
}
|
||||
}
|
4
env/.env.test
vendored
@ -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"
|
@ -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"
|
||||
},
|
||||
|
@ -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))
|
||||
|
@ -1,6 +1,7 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box!important;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
// 黑色主题
|
||||
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.1 KiB |
BIN
src/assets/image/pcyyb_2100100012_installer.exe
Normal file
BIN
src/assets/image/zu6299@2x.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
src/assets/image/zu6300@2x.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
src/assets/image/zu6302@2x.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
src/assets/image/zu6306@2x.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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%;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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' })
|
||||
|
@ -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 的别名
|
||||
},
|
||||
})
|
@ -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
|
||||
|