feat(ContactModal): 新增通讯录功能并重构转发联系人界面
- 添加@vicons/tabler图标库依赖 - 启用vueDevTools插件 - 重构ContactModal组件,增加通讯录功能 - 实现部门树形结构展示和员工搜索 - 添加群聊列表展示功能 - 优化界面样式和交互体验
This commit is contained in:
parent
b484bc0823
commit
1946ef8e9c
@ -68,6 +68,7 @@
|
||||
"@types/node": "^18.18.5",
|
||||
"@types/vue": "^2.0.0",
|
||||
"@unocss/reset": "^66.1.1",
|
||||
"@vicons/tabler": "^0.13.0",
|
||||
"@vitejs/plugin-vue": "^4.4.0",
|
||||
"@vitejs/plugin-vue-jsx": "^3.0.2",
|
||||
"@vue/tsconfig": "^0.4.0",
|
||||
|
@ -159,6 +159,9 @@ importers:
|
||||
'@unocss/reset':
|
||||
specifier: ^66.1.1
|
||||
version: 66.3.0
|
||||
'@vicons/tabler':
|
||||
specifier: ^0.13.0
|
||||
version: 0.13.0
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^4.4.0
|
||||
version: 4.6.2(vite@6.3.5(@types/node@18.19.112)(jiti@1.21.7)(less@4.3.0)(sass@1.89.2)(terser@5.43.1))(vue@3.5.17(typescript@5.2.2))
|
||||
@ -1250,6 +1253,9 @@ packages:
|
||||
'@vicons/ionicons5@0.13.0':
|
||||
resolution: {integrity: sha512-zvZKBPjEXKN7AXNo2Na2uy+nvuv6SP4KAMQxpKL2vfHMj0fSvuw7JZcOPCjQC3e7ayssKnaoFVAhbYcW6v41qQ==}
|
||||
|
||||
'@vicons/tabler@0.13.0':
|
||||
resolution: {integrity: sha512-AykuhiqjszkIoAL/7knIFm6RDOBS1ZmQdJfQ+RNLEah0fVsxykUFCfMBSNZh8lOzC85EtdD1k5g/sv5GYk0Ohg==}
|
||||
|
||||
'@vitejs/plugin-vue-jsx@3.1.0':
|
||||
resolution: {integrity: sha512-w9M6F3LSEU5kszVb9An2/MmXNxocAnUb3WhRr8bHlimhDrXNt6n6D2nJQR3UXpGlZHh/EsgouOHCsM8V3Ln+WA==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
@ -5009,6 +5015,8 @@ snapshots:
|
||||
|
||||
'@vicons/ionicons5@0.13.0': {}
|
||||
|
||||
'@vicons/tabler@0.13.0': {}
|
||||
|
||||
'@vitejs/plugin-vue-jsx@3.1.0(vite@6.3.5(@types/node@18.19.112)(jiti@1.21.7)(less@4.3.0)(sass@1.89.2)(terser@5.43.1))(vue@3.5.17(typescript@5.2.2))':
|
||||
dependencies:
|
||||
'@babel/core': 7.27.4
|
||||
|
@ -1,46 +1,164 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, onMounted, watch } from 'vue'
|
||||
<script lang="js" setup>
|
||||
import { ref, computed, onMounted, watch, reactive, nextTick, getCurrentInstance, h } from 'vue'
|
||||
import { ServeGetTalkList } from '@/api/chat.js'
|
||||
import { ServeGetGroups } from '@/api/group'
|
||||
import XNModal from '@/components/x-naive-ui/x-n-modal/index.vue'
|
||||
const emit = defineEmits(['close', 'on-submit'])
|
||||
import { Plus } from '@vicons/tabler'
|
||||
import { CloseCircle } from '@vicons/ionicons5'
|
||||
interface Item {
|
||||
id: number
|
||||
type: number
|
||||
name: string
|
||||
avatar: string
|
||||
remark: string
|
||||
checked: boolean
|
||||
keyword: string
|
||||
}
|
||||
import customModal from '@/components/common/customModal.vue'
|
||||
import xSearchForm from '@/components/x-naive-ui/x-search-form/index.vue'
|
||||
import xNDataTable from '@/components/x-naive-ui/x-n-data-table/index.vue'
|
||||
import flTree from '@/components/flnlayout/tree/flnindex.vue'
|
||||
import { processError, processSuccess } from '@/utils/helper/message.js'
|
||||
import { ServeUserGroupChatList } from '@/api/search'
|
||||
import { GetContactFriendList } from '@/api/chat'
|
||||
import { getUserInfoByERPUserId } from '@/api/user'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useUtil } from '@/hooks/useUtil'
|
||||
import { NButton } from 'naive-ui'
|
||||
|
||||
const emit = defineEmits(['close', 'on-submit'])
|
||||
|
||||
const { useMessage } = useUtil()
|
||||
const router = useRouter()
|
||||
|
||||
const currentInstance = getCurrentInstance()
|
||||
const $request = currentInstance?.appContext.config.globalProperties?.$request
|
||||
|
||||
const isShowBox = defineModel('show')
|
||||
const loading = ref(true)
|
||||
const items = ref<Item[]>([])
|
||||
const items = ref([])
|
||||
const keywords = ref('')
|
||||
const loadGroupStatus = ref(false)
|
||||
defineProps<{
|
||||
forwardMode: number
|
||||
}>()
|
||||
// 搜索过滤器:不再按类型过滤,将好友和群组融合在一起
|
||||
const forwardMode = defineProps(['forwardMode'])
|
||||
|
||||
// 通讯录弹窗相关状态
|
||||
const state = reactive({
|
||||
isShowAddressBookModal: false,
|
||||
customModalStyle: {
|
||||
width: '1288px',
|
||||
height: '846px',
|
||||
backgroundColor: '#F9F9FD'
|
||||
},
|
||||
addressBookSearchConfig: [
|
||||
{
|
||||
label: '姓名',
|
||||
key: 'nickName',
|
||||
type: 'input',
|
||||
valueType: 'string'
|
||||
}
|
||||
],
|
||||
groupChatListSearchConfig: [
|
||||
{
|
||||
label: '群聊名称',
|
||||
key: 'groupName',
|
||||
type: 'input',
|
||||
valueType: 'string'
|
||||
}
|
||||
],
|
||||
treeData: [],
|
||||
expandedKeys: [],
|
||||
clickKey: 3,
|
||||
treeRefreshCount: 0,
|
||||
treeSelectData: {},
|
||||
addressBookColumns: [
|
||||
{
|
||||
type: 'selection'
|
||||
},
|
||||
{
|
||||
title: '姓名 【工号】',
|
||||
field: 'nickname',
|
||||
width: 200,
|
||||
ellipsis: {
|
||||
tooltip: true
|
||||
},
|
||||
render(row, index) {
|
||||
return row.nickName + '【' + row.jobNum + '】'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '岗位名称',
|
||||
field: 'user_position',
|
||||
width: 400,
|
||||
ellipsis: {
|
||||
tooltip: true
|
||||
},
|
||||
render(row, index) {
|
||||
let positionNames = Array.isArray(row.depPositions)
|
||||
? row.depPositions.flatMap((dep) =>
|
||||
Array.isArray(dep.positions) ? dep.positions.map((pos) => pos.name) : []
|
||||
)
|
||||
: []
|
||||
return positionNames.join(' , ')
|
||||
}
|
||||
}
|
||||
],
|
||||
groupChatListColumns: [
|
||||
{
|
||||
title: '群聊名称',
|
||||
field: 'groupName',
|
||||
width: 400,
|
||||
ellipsis: {
|
||||
tooltip: true
|
||||
},
|
||||
render(row, index) {
|
||||
return row.group_name
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '群类型',
|
||||
field: 'groupType',
|
||||
width: 200,
|
||||
ellipsis: true,
|
||||
render(row, index) {
|
||||
let groupType = row.group_type
|
||||
if (groupType == 1) {
|
||||
return '普通群'
|
||||
} else if (groupType == 2) {
|
||||
return '部门群'
|
||||
} else if (groupType == 3) {
|
||||
return '项目群'
|
||||
} else if (groupType == 4) {
|
||||
return '公司群'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
addressBookData: [],
|
||||
company_name: '',
|
||||
groupChatListData: [],
|
||||
addressBookTableHeight: 524,
|
||||
addressBookTableWidth: 800,
|
||||
addressBookPage: 1,
|
||||
addressBookPageSize: 10,
|
||||
addressBookTotal: 0,
|
||||
addressBookSearchNickName: '',
|
||||
addressBookCurrentTab: 'employeeAddressBook',
|
||||
groupChatListPage: 1,
|
||||
groupChatListPageSize: 10,
|
||||
groupChatListTotal: 0,
|
||||
groupChatListSearchGroupName: '',
|
||||
selectedRowKeys: []
|
||||
})
|
||||
|
||||
// 原有转发功能的过滤器
|
||||
const searchFilter = computed(() => {
|
||||
return items.value.filter((item: Item) => {
|
||||
return items.value.filter((item) => {
|
||||
return item.name.toLowerCase().includes(keywords.value.toLowerCase())
|
||||
})
|
||||
})
|
||||
|
||||
const checkedFilter = computed(() => {
|
||||
return items.value.filter((item: Item) => item.checked)
|
||||
return items.value.filter((item) => item.checked)
|
||||
})
|
||||
|
||||
const isCanSubmit = computed(() => {
|
||||
return !checkedFilter.value.length
|
||||
})
|
||||
|
||||
// 原有加载数据函数
|
||||
const onLoad = () => {
|
||||
onLoadContact()
|
||||
// onLoadGroup()
|
||||
}
|
||||
|
||||
const onLoadContact = () => {
|
||||
@ -50,7 +168,7 @@ const onLoadContact = () => {
|
||||
if (res.code == 200) {
|
||||
let list = res.data.items || []
|
||||
|
||||
items.value = list.filter((item: any) => ((item.talk_type === 1 && item.receiver_id !== 2) || item.talk_type !== 1)).map((item: any) => {
|
||||
items.value = list.filter((item) => ((item.talk_type === 1 && item.receiver_id !== 2) || item.talk_type !== 1)).map((item) => {
|
||||
return {
|
||||
...item,
|
||||
checked: false
|
||||
@ -63,57 +181,29 @@ const onLoadContact = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// const onLoadGroup = async () => {
|
||||
// if (loadGroupStatus.value) {
|
||||
// return
|
||||
// }
|
||||
|
||||
// loading.value = true
|
||||
// let { code, data } = await ServeGetGroups()
|
||||
// if (code != 200) {
|
||||
// loading.value = false
|
||||
// return
|
||||
// }
|
||||
|
||||
// let list = data.items.map((item: any) => {
|
||||
// return {
|
||||
// id: item.id,
|
||||
// avatar: item.avatar,
|
||||
// type: 2,
|
||||
// name: item.group_name,
|
||||
// keyword: item.group_name,
|
||||
// remark: '',
|
||||
// checked: false
|
||||
// }
|
||||
// })
|
||||
|
||||
// items.value.push(...list)
|
||||
|
||||
// loading.value = false
|
||||
// loadGroupStatus.value = true
|
||||
// }
|
||||
|
||||
// 原有转发功能函数
|
||||
const onMaskClick = () => {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
const onTriggerContact = (item: any) => {
|
||||
// 如果是单选模式,先取消所有选中
|
||||
const selectType = ref(2)
|
||||
|
||||
const onTriggerContact = (item) => {
|
||||
if (selectType.value === 1) {
|
||||
items.value.forEach(contact => {
|
||||
contact.checked = false
|
||||
})
|
||||
}
|
||||
|
||||
let data = items.value.find((val: any) => val.id === item.id)
|
||||
let data = items.value.find((val) => val.id === item.id)
|
||||
|
||||
if (data) {
|
||||
data.checked = !data.checked
|
||||
}
|
||||
}
|
||||
|
||||
const onRemoveContact = (item: any) => {
|
||||
let data = items.value.find((val: any) => val.id === item.id)
|
||||
const onRemoveContact = (item) => {
|
||||
let data = items.value.find((val) => val.id === item.id)
|
||||
|
||||
if (data) {
|
||||
data.checked = false
|
||||
@ -125,7 +215,7 @@ const onCancel = () => {
|
||||
}
|
||||
|
||||
const onSubmit = () => {
|
||||
let data = checkedFilter.value.map((item: any) => {
|
||||
let data = checkedFilter.value.map((item) => {
|
||||
return {
|
||||
receiver_id: item.receiver_id,
|
||||
talk_type: item.talk_type
|
||||
@ -134,30 +224,208 @@ const onSubmit = () => {
|
||||
emit('on-submit', data)
|
||||
}
|
||||
|
||||
// 1 单选 2 多选
|
||||
const selectType = ref(1)
|
||||
const changeSelectType = () => {
|
||||
selectType.value = selectType.value == 1 ? 2 : 1
|
||||
|
||||
// 切换选择模式时清空已选择的联系人
|
||||
items.value.forEach(item => {
|
||||
item.checked = false
|
||||
// 通讯录弹窗功能函数
|
||||
const onCreateContact = () => {
|
||||
state.isShowAddressBookModal = true
|
||||
getTreeData()
|
||||
getDepPoisUser()
|
||||
getUserGroupChatList()
|
||||
}
|
||||
|
||||
const closeAddressBookModal = () => {
|
||||
state.isShowAddressBookModal = false
|
||||
resetAddressBookModal()
|
||||
}
|
||||
|
||||
const calcTreeData = (data) => {
|
||||
for (let item of data) {
|
||||
item.key = item.ID
|
||||
item.label = item.name
|
||||
item.title = item.name
|
||||
if (item.sons) {
|
||||
item.children = item.sons
|
||||
calcTreeData(item.children)
|
||||
}
|
||||
delete item.ID
|
||||
delete item.name
|
||||
delete item.sons
|
||||
}
|
||||
}
|
||||
|
||||
const getTreeData = () => {
|
||||
let url = '/department/v2/tree/filter'
|
||||
let params = {}
|
||||
$request.HTTP.components.postDataByParams(url, params).then(
|
||||
(res) => {
|
||||
if (res.status === 0 && Array.isArray(res.data.nodes)) {
|
||||
let data = res.data.nodes
|
||||
calcTreeData(data)
|
||||
state.treeData = data
|
||||
state.treeRefreshCount++
|
||||
getDepPoisUser()
|
||||
} else {
|
||||
processError(res.msg || '获取失败!')
|
||||
}
|
||||
},
|
||||
() => {
|
||||
processError('获取失败!')
|
||||
},
|
||||
() => {
|
||||
processError('获取失败!')
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
const getDepPoisUser = () => {
|
||||
let url = '/user/v2/list'
|
||||
let params = {
|
||||
departmentId: state.addressBookSearchNickName ? undefined : state.clickKey,
|
||||
page: state.addressBookPage,
|
||||
pageSize: state.addressBookPageSize,
|
||||
status: 'notactive',
|
||||
nickName: state.addressBookSearchNickName
|
||||
}
|
||||
$request.HTTP.components.postDataByParams(url, params).then((res) => {
|
||||
if (res.code === 200) {
|
||||
state.addressBookData = res?.data?.data || []
|
||||
state.addressBookTotal = res?.data?.count || 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
watch(()=>{
|
||||
return isShowBox.value
|
||||
},(newVal)=>{
|
||||
if(newVal){
|
||||
onLoad()
|
||||
const getUserGroupChatList = () => {
|
||||
let params = {
|
||||
page: state.groupChatListPage,
|
||||
page_size: state.groupChatListPageSize,
|
||||
group_name: state.groupChatListSearchGroupName
|
||||
}
|
||||
ServeUserGroupChatList(params).then((res) => {
|
||||
if (res.code === 200) {
|
||||
state.groupChatListData = res?.data?.items || []
|
||||
state.groupChatListTotal = res?.data?.total || 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleTreeClick = ({ selectedKey, tree }) => {
|
||||
state.clickKey = tree.key
|
||||
state.treeSelectData = tree
|
||||
state.addressBookPage = 1
|
||||
getDepPoisUser()
|
||||
}
|
||||
|
||||
const resetAddressBookModal = () => {
|
||||
nextTick(() => {
|
||||
state.addressBookCurrentTab = 'employeeAddressBook'
|
||||
state.addressBookSearchNickName = ''
|
||||
state.groupChatListSearchGroupName = ''
|
||||
state.addressBookTableWidth = 800
|
||||
state.clickKey = 3
|
||||
state.treeRefreshCount++
|
||||
state.addressBookPage = 1
|
||||
state.addressBookPageSize = 10
|
||||
state.groupChatListPage = 1
|
||||
state.groupChatListPageSize = 10
|
||||
state.selectedRowKeys = []
|
||||
getDepPoisUser()
|
||||
getUserGroupChatList()
|
||||
})
|
||||
}
|
||||
|
||||
const handleAddressBookPagination = (page) => {
|
||||
state.addressBookPage = page
|
||||
getDepPoisUser()
|
||||
}
|
||||
|
||||
const handleAddressBookPaginationSize = (pageSize) => {
|
||||
state.addressBookPageSize = pageSize
|
||||
state.addressBookPage = 1
|
||||
getDepPoisUser()
|
||||
}
|
||||
|
||||
const changeAddressBookSearch = (value) => {
|
||||
if (!value.nickName?.trim()) {
|
||||
state.addressBookSearchNickName = ''
|
||||
} else {
|
||||
state.addressBookSearchNickName = value.nickName
|
||||
}
|
||||
}
|
||||
|
||||
const handleAddressBookTabChange = (value) => {
|
||||
state.addressBookCurrentTab = value
|
||||
}
|
||||
|
||||
const changeGroupChatListSearch = (value) => {
|
||||
if (!value.groupName?.trim()) {
|
||||
state.groupChatListSearchGroupName = ''
|
||||
} else {
|
||||
state.groupChatListSearchGroupName = value.groupName
|
||||
}
|
||||
}
|
||||
|
||||
const handleGroupChatListPagination = (page) => {
|
||||
state.groupChatListPage = page
|
||||
getUserGroupChatList()
|
||||
}
|
||||
|
||||
const handleGroupChatListPaginationSize = (pageSize) => {
|
||||
state.groupChatListPageSize = pageSize
|
||||
state.groupChatListPage = 1
|
||||
getUserGroupChatList()
|
||||
}
|
||||
|
||||
const onAddressBookCancel = () => {
|
||||
state.isShowAddressBookModal = false
|
||||
}
|
||||
|
||||
const onAddressBookSubmit = () => {
|
||||
// 用户可自行实现提交逻辑
|
||||
console.log('选中的联系人:', state.selectedRowKeys)
|
||||
}
|
||||
|
||||
watch(() => {
|
||||
return isShowBox.value
|
||||
}, (newVal) => {
|
||||
if (newVal) {
|
||||
onLoad()
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => state.addressBookSearchNickName, (newValue, oldValue) => {
|
||||
if (newValue) {
|
||||
state.addressBookTableWidth = 1142
|
||||
state.addressBookPage = 1
|
||||
} else {
|
||||
state.addressBookTableWidth = 800
|
||||
state.clickKey = 3
|
||||
state.treeRefreshCount++
|
||||
state.addressBookPage = 1
|
||||
}
|
||||
getDepPoisUser()
|
||||
})
|
||||
|
||||
watch(() => state.groupChatListSearchGroupName, (newValue, oldValue) => {
|
||||
if (newValue) {
|
||||
state.groupChatListPage = 1
|
||||
} else {
|
||||
state.groupChatListPage = 1
|
||||
}
|
||||
getUserGroupChatList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<x-n-modal v-model:show="isShowBox" :title="forwardMode === 2 ? '合并转发' : '逐条转发'" style="width: 997px; height: 740px;background-color: #F9F9FD"
|
||||
:on-after-leave="onMaskClick" content-style="display: flex; justify-content: center; align-items: center;">
|
||||
<div class="w-927px h-627px bg-#fff rounded-3px px-35px py-20px">
|
||||
<div class="w-927px h-627px bg-#fff rounded-3px px-35px pb-20px pt-10px">
|
||||
<div class="w-100% flex justify-end mb-5px">
|
||||
<n-button text type="primary" @click="onCreateContact">
|
||||
<template #icon>
|
||||
<Plus />
|
||||
</template>
|
||||
创建新聊天
|
||||
</n-button>
|
||||
</div>
|
||||
<div class="flex items-center justify-between mb-28px">
|
||||
<div class="text-#333639">搜索</div>
|
||||
<div class="w-779px h-34px">
|
||||
@ -168,11 +436,11 @@ if(newVal){
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<div class="w-260px h-517px rounded-4px border-1px border-solid border-#E5E5E5 px-12px">
|
||||
<div class="border-b-2px border-b-solid border-b-#FBFBFB h-35px flex items-center justify-end">
|
||||
<!-- <div class="border-b-2px border-b-solid border-b-#FBFBFB h-35px flex items-center justify-end">
|
||||
<n-button text color="#46299D" class="text-14px" @click="changeSelectType">
|
||||
{{ selectType === 1 ? '多选' : '取消多选' }}
|
||||
</n-button>
|
||||
</div>
|
||||
</div> -->
|
||||
<div>
|
||||
<n-virtual-list v-if="!loading" style="max-height: 470px" :item-size="65" :items="searchFilter">
|
||||
<template #default="{ item }">
|
||||
@ -259,5 +527,173 @@ if(newVal){
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</x-n-modal>
|
||||
|
||||
<!-- 通讯录弹窗 -->
|
||||
<customModal
|
||||
v-model:show="state.isShowAddressBookModal"
|
||||
title="通讯录"
|
||||
:style="state.customModalStyle"
|
||||
:customCloseBtn="true"
|
||||
:closable="false"
|
||||
:customCloseEvent="true"
|
||||
@customCloseModal="closeAddressBookModal"
|
||||
>
|
||||
<template #content>
|
||||
<div class="custom-modal-content">
|
||||
<n-card style="padding: 0 12px">
|
||||
<n-tabs
|
||||
type="line"
|
||||
@update:value="handleAddressBookTabChange"
|
||||
tab-style="font-size: 16px; font-weight: 600;color: #8B8B8B;"
|
||||
>
|
||||
<n-tab name="employeeAddressBook">员工通讯录</n-tab>
|
||||
<n-tab name="groupChatList">群聊列表</n-tab>
|
||||
</n-tabs>
|
||||
<xSearchForm
|
||||
v-if="state.addressBookCurrentTab == 'employeeAddressBook'"
|
||||
:search-config="state.addressBookSearchConfig"
|
||||
customInputPlaceholder="请输入姓名"
|
||||
@change="changeAddressBookSearch"
|
||||
:cols="3"
|
||||
></xSearchForm>
|
||||
<xSearchForm
|
||||
v-if="state.addressBookCurrentTab == 'groupChatList'"
|
||||
:search-config="state.groupChatListSearchConfig"
|
||||
customInputPlaceholder="请输入群聊名称"
|
||||
@change="changeGroupChatListSearch"
|
||||
:cols="3"
|
||||
></xSearchForm>
|
||||
|
||||
<div class="addressBook-content" v-if="state.addressBookCurrentTab == 'employeeAddressBook'">
|
||||
<div class="addressBook-tree" v-if="!state.addressBookSearchNickName">
|
||||
<fl-tree
|
||||
:data="state.treeData"
|
||||
:expandedKeys="state.expandedKeys"
|
||||
:refreshCount="state.treeRefreshCount"
|
||||
:clickKey="state.clickKey"
|
||||
@triggerTreeClick="handleTreeClick"
|
||||
></fl-tree>
|
||||
</div>
|
||||
<div class="addressBook-table">
|
||||
<xNDataTable
|
||||
:columns="state.addressBookColumns"
|
||||
:data="state.addressBookData"
|
||||
:style="{
|
||||
height: `${state.addressBookTableHeight}px`,
|
||||
width: `${state.addressBookTableWidth}px`
|
||||
}"
|
||||
:row-key="row => row.ID"
|
||||
v-model:checked-row-keys="state.selectedRowKeys"
|
||||
flex-height
|
||||
></xNDataTable>
|
||||
<div class="addressBook-pagination">
|
||||
<n-pagination
|
||||
v-model:page="state.addressBookPage"
|
||||
v-model:page-size="state.addressBookPageSize"
|
||||
:item-count="state.addressBookTotal"
|
||||
show-quick-jumper
|
||||
show-size-picker
|
||||
:page-sizes="[10, 20, 50]"
|
||||
:on-update:page="handleAddressBookPagination"
|
||||
:on-update:page-size="handleAddressBookPaginationSize"
|
||||
>
|
||||
<template #prefix="{ itemCount }"> 共 {{ itemCount }} 条记录 </template>
|
||||
</n-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="groupChatList-content" v-if="state.addressBookCurrentTab == 'groupChatList'">
|
||||
<div class="groupChatList-table">
|
||||
<xNDataTable
|
||||
:columns="state.groupChatListColumns"
|
||||
:data="state.groupChatListData"
|
||||
:style="{
|
||||
height: '523px',
|
||||
width: '1148px'
|
||||
}"
|
||||
flex-height
|
||||
></xNDataTable>
|
||||
<div class="groupChatList-pagination">
|
||||
<n-pagination
|
||||
v-model:page="state.groupChatListPage"
|
||||
v-model:page-size="state.groupChatListPageSize"
|
||||
:item-count="state.groupChatListTotal"
|
||||
show-quick-jumper
|
||||
show-size-picker
|
||||
:page-sizes="[10, 20, 50]"
|
||||
:on-update:page="handleGroupChatListPagination"
|
||||
:on-update:page-size="handleGroupChatListPaginationSize"
|
||||
>
|
||||
<template #prefix="{ itemCount }"> 共 {{ itemCount }} 条记录 </template>
|
||||
</n-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部操作按钮,仅保留展示 -->
|
||||
<div style="display: flex; justify-content: center; align-items: center; padding: 16px 0;">
|
||||
<n-button color="#C7C7C9" class="w-250px h-34px text-14px text-#fff mr-10px" @click="onAddressBookCancel">取消</n-button>
|
||||
<n-button color="#46299D" class="w-250px h-34px text-14px text-#fff" @click="onAddressBookSubmit">发送</n-button>
|
||||
</div>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
</customModal>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.custom-modal-content {
|
||||
.addressBook-content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 20px;
|
||||
|
||||
.addressBook-tree {
|
||||
width: 328px;
|
||||
height: 524px;
|
||||
overflow: auto;
|
||||
border: 1px solid #efeff5;
|
||||
border-radius: 4px;
|
||||
padding: 12px 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.addressBook-table {
|
||||
:deep(.n-data-table-th) {
|
||||
background-color: #46299d;
|
||||
color: #fff;
|
||||
}
|
||||
.addressBook-pagination {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding: 22px 0 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.groupChatList-content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 20px;
|
||||
|
||||
.groupChatList-table {
|
||||
:deep(.n-data-table-th) {
|
||||
background-color: #46299d;
|
||||
color: #fff;
|
||||
}
|
||||
.groupChatList-pagination {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding: 22px 0 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -18,7 +18,7 @@ export function isLoggedIn() {
|
||||
*/
|
||||
export function getAccessToken() {
|
||||
// return storage.get(AccessToken) || ''
|
||||
return JSON.parse(localStorage.getItem('token'))||''
|
||||
return JSON.parse(localStorage.getItem('token'))||'46d71a72d8d845ad7ed23eba9bdde260e635407190c2ce1bf7fd22088e41682ea07773ec65cae8946d2003f264d55961f96e0fc5da10eb96d3a348c1664e9644ce2108c311309f398ae8ea1b8200bfd490e5cb6e8c52c9e5d493cbabb163368f8351420451a631dbfa749829ee4cda49b77b5ed2d3dced5d0f2b7dd9ee76ba5465c84a17c23af040cd92b6b2a4ea48befbb5c729dcdad0a9c9668befe84074cc24f78899c1d947f8e7f94c7eda5325b8ed698df729e76febb98549ef3482ae942fb4f4a1c92d21836fa784728f0c5483aab2760a991b6b36e6b10c84f840a6433a6ecc31dee36e8f1c6158818bc89d22184be97f604c74931ddd023225ae1a2ab29c0eb046e9a20174f1110532e4af8498ab46f4375f2e210bae827a6146183f385fdee154fd7bee38deb6ac4c00ae82c77150d5663288f78d678db028bfb7db'
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,9 +46,9 @@ export default defineConfig(({ mode }) => {
|
||||
vueJsx({}),
|
||||
compressPlugin(),
|
||||
UnoCSS(),
|
||||
// vueDevTools({
|
||||
// launchEditor: 'trae',
|
||||
// })
|
||||
vueDevTools({
|
||||
launchEditor: 'trae',
|
||||
})
|
||||
],
|
||||
define: {
|
||||
__APP_ENV__: env.APP_ENV
|
||||
|
Loading…
Reference in New Issue
Block a user