310 lines
9.2 KiB
Vue
310 lines
9.2 KiB
Vue
|
|
<template>
|
|||
|
|
<div class="customer-page">
|
|||
|
|
<div class="customer-toolbar boxshadow">
|
|||
|
|
<div class="customer-search-group">
|
|||
|
|
<el-form-item label="关键字:" label-width="70px">
|
|||
|
|
<el-input style="min-width: 120px" v-model="keyword" placeholder="请输入关键字" />
|
|||
|
|
</el-form-item>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="boxshadow">
|
|||
|
|
<ElRow>
|
|||
|
|
<div style="width: 12px"></div>
|
|||
|
|
<ElCol :xs="24" :sm="12" :lg="6" class="el-col2">
|
|||
|
|
<ElButton @click="showDialog('add')" v-ripple v-if="hasAuth('system@notice_add')"
|
|||
|
|
>新增</ElButton
|
|||
|
|
>
|
|||
|
|
</ElCol>
|
|||
|
|
</ElRow>
|
|||
|
|
<ArtTable
|
|||
|
|
ref="tableRef"
|
|||
|
|
row-key="id"
|
|||
|
|
:loading="loading"
|
|||
|
|
:data="tableData"
|
|||
|
|
:currentPage="pagination.currentPage"
|
|||
|
|
:pageSize="pagination.pageSize"
|
|||
|
|
:total="pagination.total"
|
|||
|
|
@size-change="handleSizeChange"
|
|||
|
|
@current-change="handleCurrentChange"
|
|||
|
|
>
|
|||
|
|
<template #default>
|
|||
|
|
<ElTableColumn label="编号" prop="msg_no" width="240px" />
|
|||
|
|
<ElTableColumn label="通知标题" prop="title" />
|
|||
|
|
<el-table-column prop="id" label="通知内容">
|
|||
|
|
<template #default="scope">
|
|||
|
|
<span v-html="scope.row.content" style="white-space: pre-line"></span>
|
|||
|
|
</template>
|
|||
|
|
</el-table-column>
|
|||
|
|
<ElTableColumn label="推送类型" prop="push_method_name" />
|
|||
|
|
<ElTableColumn label="场景" prop="scene_name" />
|
|||
|
|
<ElTableColumn label="创建时间" prop="created_at" />
|
|||
|
|
<ElTableColumn fixed="right" label="操作" width="200px">
|
|||
|
|
<template #default="scope">
|
|||
|
|
<ElRow>
|
|||
|
|
<el-button link @click="showfn(scope.row)"> 详情 </el-button>
|
|||
|
|
<el-button
|
|||
|
|
type="danger"
|
|||
|
|
link
|
|||
|
|
@click="deleteRole(scope.row)"
|
|||
|
|
v-if="hasAuth('system@notice_destroy')"
|
|||
|
|
>
|
|||
|
|
删除
|
|||
|
|
</el-button>
|
|||
|
|
</ElRow>
|
|||
|
|
</template>
|
|||
|
|
</ElTableColumn>
|
|||
|
|
</template>
|
|||
|
|
</ArtTable>
|
|||
|
|
</div>
|
|||
|
|
<ElDialog v-model="dialogVisible" title="新增通知" align-center>
|
|||
|
|
<ElForm ref="formRef" :model="form" :rules="rules" label-width="80px" class="form">
|
|||
|
|
<ElFormItem label="通知标题" prop="title">
|
|||
|
|
<ElInput v-model="form.title" />
|
|||
|
|
</ElFormItem>
|
|||
|
|
<ElFormItem label="通知内容" prop="content">
|
|||
|
|
<ElInput v-model="form.content" type="textarea" :rows="3" placeholder="请输入通知内容" />
|
|||
|
|
</ElFormItem>
|
|||
|
|
<ElFormItem label="通知用户" prop="recipient">
|
|||
|
|
<el-select
|
|||
|
|
v-model="form.recipient"
|
|||
|
|
multiple
|
|||
|
|
filterable
|
|||
|
|
placeholder="请选择要通知的用户"
|
|||
|
|
style="width: 100%"
|
|||
|
|
>
|
|||
|
|
<el-option
|
|||
|
|
v-for="item in companyUserList"
|
|||
|
|
:key="item.id"
|
|||
|
|
:label="item.name"
|
|||
|
|
:value="item.id"
|
|||
|
|
/>
|
|||
|
|
</el-select>
|
|||
|
|
<el-text class="mx-1" type="warning">不选择用户,代表通知所有用户!</el-text>
|
|||
|
|
</ElFormItem>
|
|||
|
|
</ElForm>
|
|||
|
|
<template #footer>
|
|||
|
|
<div class="dialog-footer">
|
|||
|
|
<ElButton @click="dialogVisible = false">取消</ElButton>
|
|||
|
|
<ElButton type="primary" @click="handleSubmit(formRef)">提交</ElButton>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
</ElDialog>
|
|||
|
|
<ElDialog v-model="dialogVisiblexq" title="通知详情" align-center width="640px">
|
|||
|
|
<div class="detail-dialog">
|
|||
|
|
<div class="section">
|
|||
|
|
<div class="info-grid">
|
|||
|
|
<div class="label">发送人</div>
|
|||
|
|
<div class="value">{{ noticeDetail.sender_name || '-' }}</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="info-grid">
|
|||
|
|
<div class="label">通知标题</div>
|
|||
|
|
<div class="value">{{ noticeDetail.title || '-' }}</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="section">
|
|||
|
|
<div class="label" style="margin-bottom: 8px">通知内容</div>
|
|||
|
|
<div class="content-box">
|
|||
|
|
<div class="message-text" v-html="noticeDetail.content"></div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</ElDialog>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script setup lang="ts">
|
|||
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|||
|
|
import type { FormInstance, FormRules } from 'element-plus'
|
|||
|
|
import { systemService } from '@/api/systemApi'
|
|||
|
|
import { manageService } from '@/api/adminApi'
|
|||
|
|
import { useAuth } from '@/composables/useAuth'
|
|||
|
|
const { hasAuth } = useAuth()
|
|||
|
|
defineOptions({ name: 'AdminNotice' })
|
|||
|
|
const loading = ref(false)
|
|||
|
|
const dialogVisible = ref(false)
|
|||
|
|
const dialogVisiblexq = ref(false)
|
|||
|
|
const formRef = ref<FormInstance>()
|
|||
|
|
const { width } = useWindowSize()
|
|||
|
|
const keyword = ref<string>('')
|
|||
|
|
const isMobile = computed(() => width.value < 500)
|
|||
|
|
const rules = reactive<FormRules>({
|
|||
|
|
name: [{ required: true, message: '请输入公司名称', trigger: 'blur' }],
|
|||
|
|
abbr: [{ required: true, message: '请输入公司简称', trigger: 'blur' }]
|
|||
|
|
// tenant_key: [{ required: true, message: '请输入飞书标识', trigger: 'blur' }]
|
|||
|
|
})
|
|||
|
|
const companyUserList = ref<any>()
|
|||
|
|
// 获取用户列表
|
|||
|
|
const getCompanyUserList = async () => {
|
|||
|
|
const response = await manageService.presetusers()
|
|||
|
|
companyUserList.value = response || []
|
|||
|
|
}
|
|||
|
|
const form = reactive<any>({
|
|||
|
|
title: '',
|
|||
|
|
content: '',
|
|||
|
|
recipient: []
|
|||
|
|
})
|
|||
|
|
const pagination = reactive({
|
|||
|
|
currentPage: 1,
|
|||
|
|
pageSize: 10,
|
|||
|
|
total: 0
|
|||
|
|
})
|
|||
|
|
// 表格数据
|
|||
|
|
const tableData = ref<any[]>([])
|
|||
|
|
|
|||
|
|
// 表格实例引用
|
|||
|
|
const tableRef = ref()
|
|||
|
|
|
|||
|
|
onMounted(() => {
|
|||
|
|
getWorkList()
|
|||
|
|
})
|
|||
|
|
watch([keyword], () => {
|
|||
|
|
pagination.currentPage = 1
|
|||
|
|
getWorkList()
|
|||
|
|
})
|
|||
|
|
const noticeDetail = ref<any>({})
|
|||
|
|
const showfn = async (row: any) => {
|
|||
|
|
dialogVisiblexq.value = true
|
|||
|
|
await systemService.getNoticeDetail({ id: row.id }).then((res: any) => {
|
|||
|
|
noticeDetail.value = res
|
|||
|
|
console.log(res)
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
// 处理表格分页变化
|
|||
|
|
const handleSizeChange = (newPageSize: number) => {
|
|||
|
|
pagination.pageSize = newPageSize
|
|||
|
|
getWorkList()
|
|||
|
|
}
|
|||
|
|
const handleCurrentChange = (newCurrentPage: number) => {
|
|||
|
|
pagination.currentPage = newCurrentPage
|
|||
|
|
getWorkList()
|
|||
|
|
}
|
|||
|
|
// 获取列表数据
|
|||
|
|
const getWorkList = async () => {
|
|||
|
|
loading.value = true
|
|||
|
|
try {
|
|||
|
|
const { currentPage, pageSize } = pagination
|
|||
|
|
|
|||
|
|
const { records, current, size, total } = await systemService.getNoticeList({
|
|||
|
|
current: currentPage,
|
|||
|
|
size: pageSize
|
|||
|
|
})
|
|||
|
|
tableData.value = records.map((item: any) => ({
|
|||
|
|
...item
|
|||
|
|
}))
|
|||
|
|
Object.assign(pagination, { currentPage: current, pageSize: size, total })
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('获取列表失败:', error)
|
|||
|
|
} finally {
|
|||
|
|
loading.value = false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const dialogType = ref('add')
|
|||
|
|
|
|||
|
|
const showDialog = (type: string) => {
|
|||
|
|
getCompanyUserList()
|
|||
|
|
dialogVisible.value = true
|
|||
|
|
dialogType.value = type
|
|||
|
|
form.title = ''
|
|||
|
|
form.content = ''
|
|||
|
|
form.recipient = []
|
|||
|
|
}
|
|||
|
|
const deleteRole = (row?: any) => {
|
|||
|
|
ElMessageBox.confirm('确定删除吗?', '删除确认', {
|
|||
|
|
confirmButtonText: '确定',
|
|||
|
|
cancelButtonText: '取消',
|
|||
|
|
type: 'error'
|
|||
|
|
}).then(async () => {
|
|||
|
|
const { message } = await systemService.delNotice({
|
|||
|
|
id: row.id
|
|||
|
|
})
|
|||
|
|
ElMessage.success(message)
|
|||
|
|
getWorkList()
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const handleSubmit = async (formEl: FormInstance | undefined) => {
|
|||
|
|
if (!formEl) return
|
|||
|
|
const { message } = await systemService.sendNotice(form)
|
|||
|
|
ElMessage.success(message)
|
|||
|
|
dialogVisible.value = false
|
|||
|
|
getWorkList()
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style lang="scss" scoped>
|
|||
|
|
:deep(.el-table__empty-block) {
|
|||
|
|
height: 100% !important;
|
|||
|
|
min-height: 200px;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
}
|
|||
|
|
.customer-page {
|
|||
|
|
background: var(--art-main-bg-color);
|
|||
|
|
min-height: 100vh;
|
|||
|
|
}
|
|||
|
|
.page-content {
|
|||
|
|
.svg-icon {
|
|||
|
|
width: 1.8em;
|
|||
|
|
height: 1.8em;
|
|||
|
|
overflow: hidden;
|
|||
|
|
vertical-align: -8px;
|
|||
|
|
fill: currentcolor;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.customer-toolbar {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
align-items: center;
|
|||
|
|
margin-bottom: 16px;
|
|||
|
|
padding: 20px 20px;
|
|||
|
|
background: var(--art-main-bg-color);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.customer-search-group {
|
|||
|
|
display: flex;
|
|||
|
|
gap: 12px;
|
|||
|
|
}
|
|||
|
|
.message-text {
|
|||
|
|
padding: 10px 14px;
|
|||
|
|
line-height: 1.7;
|
|||
|
|
white-space: pre-line;
|
|||
|
|
word-break: break-word;
|
|||
|
|
}
|
|||
|
|
.detail-dialog {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
gap: 16px;
|
|||
|
|
}
|
|||
|
|
.section {
|
|||
|
|
background: var(--el-fill-color-blank);
|
|||
|
|
border: 1px solid var(--el-border-color-light);
|
|||
|
|
border-radius: 8px;
|
|||
|
|
padding: 12px 14px;
|
|||
|
|
}
|
|||
|
|
.info-grid {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: 96px 1fr;
|
|||
|
|
gap: 6px 12px;
|
|||
|
|
align-items: center;
|
|||
|
|
padding: 6px 0;
|
|||
|
|
}
|
|||
|
|
.label {
|
|||
|
|
color: var(--el-text-color-secondary);
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
.value {
|
|||
|
|
color: var(--el-text-color-primary);
|
|||
|
|
font-size: 14px;
|
|||
|
|
}
|
|||
|
|
.content-box {
|
|||
|
|
background: var(--el-fill-color-lighter);
|
|||
|
|
border: 1px dashed var(--el-border-color);
|
|||
|
|
border-radius: 8px;
|
|||
|
|
padding: 10px 12px;
|
|||
|
|
max-height: 320px;
|
|||
|
|
overflow: auto;
|
|||
|
|
}
|
|||
|
|
</style>
|