v3.9.0【优化】typescript版本;【优化】App端消息;【优化】弹出层z-index;

This commit is contained in:
zhuoda
2024-11-04 20:21:05 +08:00
parent c3d267e83c
commit 472d059453
1376 changed files with 10373 additions and 9712 deletions
@@ -0,0 +1,307 @@
<!--
* 通知 表单
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-08-21 19:52:43
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
-->
<template>
<a-drawer
:title="formData.noticeId ? '编辑' : '新建'"
:open="visibleFlag"
:width="1000"
:footerStyle="{ textAlign: 'right' }"
@close="onClose"
:destroyOnClose="true"
>
<a-form ref="formRef" :model="formData" :rules="formRules" :label-col="{ span: 3 }" :wrapper-col="{ span: 20 }">
<a-form-item label="公告标题" name="title">
<a-input v-model:value="formData.title" placeholder="请输入公告标题" />
</a-form-item>
<a-form-item label="分类" name="noticeTypeId">
<a-select v-model:value="formData.noticeTypeId" style="width: 100%" :showSearch="true" :allowClear="true">
<a-select-option v-for="item in noticeTypeList" :key="item.noticeTypeId" :value="item.noticeTypeId">
{{ item.noticeTypeName }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="文号">
<a-input v-model:value="formData.documentNumber" placeholder="文号,如:1024创新实验室发〔2022〕字第36号" />
</a-form-item>
<a-form-item label="作者" name="author">
<a-input v-model:value="formData.author" placeholder="请输入作者" />
</a-form-item>
<a-form-item label="来源" name="source">
<a-input v-model:value="formData.source" placeholder="请输入来源" />
</a-form-item>
<a-form-item label="可见范围" name="allVisibleFlag">
<a-select v-model:value="formData.allVisibleFlag" placeholder="请选择可见范围">
<a-select-option :value="1">全部可见</a-select-option>
<a-select-option :value="0">部分可见</a-select-option>
</a-select>
</a-form-item>
<a-form-item v-show="!formData.allVisibleFlag" label="可见员工/部门">
<a-button type="primary" @click="showNoticeVisibleModal">选择</a-button>
<div class="visible-list">
<div class="visible-item" v-for="(item, index) in formData.visibleRangeList" :key="item.dataId">
<a-tag>
<span>{{ item.dataName }}</span>
<close-outlined @click="removeVisibleItem(index)" />
</a-tag>
</div>
</div>
</a-form-item>
<a-form-item label="定时发布">
<a-switch
v-model:checked="formData.scheduledPublishFlag"
checked-children=""
un-checked-children=""
@change="changesSheduledPublishFlag"
/>
</a-form-item>
<a-form-item v-show="formData.scheduledPublishFlag" label="发布时间">
<a-date-picker
v-model:value="releaseTime"
:format="timeFormat"
showTime
:allowClear="false"
placeholder="请选择发布时间"
style="width: 200px"
@change="changeTime"
/>
</a-form-item>
<a-form-item label="公告内容" name="contentHtml">
<SmartWangeditor ref="contentRef" :modelValue="formData.contentHtml" :height="300" />
</a-form-item>
<a-form-item label="附件">
<Upload
:defaultFileList="defaultFileList"
:maxUploadSize="10"
:folder="FILE_FOLDER_TYPE_ENUM.NOTICE.value"
buttonText="上传附件"
listType="text"
extraMsg="最多上传10个附件"
@change="changeAttachment"
/>
</a-form-item>
</a-form>
<template #footer>
<a-space>
<a-button @click="onClose">取消</a-button>
<a-button type="primary" @click="onSubmit">保存</a-button>
</a-space>
</template>
</a-drawer>
<!-- 选择可见范围弹窗 -->
<NoticeFormVisibleModal ref="noticeFormVisibleModal" @selectedFinish="finishCanSelectedVisibleRange" />
</template>
<script setup>
import { reactive, ref, onMounted, watch, computed, nextTick } from 'vue';
import { message, Modal } from 'ant-design-vue';
import _ from 'lodash';
import dayjs, { Dayjs } from 'dayjs';
import { SmartLoading } from '/@/components/framework/smart-loading';
import { FILE_FOLDER_TYPE_ENUM } from '/@/constants/support/file-const';
import { noticeApi } from '/@/api/business/oa/notice-api';
import SmartWangeditor from '/@/components/framework/wangeditor/index.vue';
import Upload from '/@/components/support/file-upload/index.vue';
import NoticeFormVisibleModal from './notice-form-visible-modal.vue';
import { smartSentry } from '/@/lib/smart-sentry';
const emits = defineEmits(['reloadList']);
// ------------------ 显示,关闭 ------------------
// 显示
const visibleFlag = ref(false);
function showModal(noticeId) {
Object.assign(formData, defaultFormData);
releaseTime.value = null;
defaultFileList.value = [];
queryNoticeTypeList();
if (noticeId) {
getNoticeUpdate(noticeId);
}
visibleFlag.value = true;
nextTick(() => {
formRef.value.clearValidate();
});
}
// 关闭
function onClose() {
visibleFlag.value = false;
}
// ------------------ 表单 ------------------
const formRef = ref();
const contentRef = ref();
const noticeFormVisibleModal = ref();
const defaultFormData = {
noticeId: undefined,
noticeTypeId: undefined,
title: undefined, // 标题
categoryId: undefined, // 分类
source: undefined, // 来源
documentNumber: undefined, // 文号
author: undefined, // 作者
allVisibleFlag: 1, // 是否全部可见
visibleRangeList: [], // 可见范围
scheduledPublishFlag: false, // 是否定时发布
publishTime: undefined, // 发布时间
attachment: [], // 附件
contentHtml: '', // html内容
contentText: '', // 纯文本内容
};
const formData = reactive({ ...defaultFormData });
const formRules = {
title: [{ required: true, message: '请输入' }],
noticeTypeId: [{ required: true, message: '请选择分类' }],
allVisibleFlag: [{ required: true, message: '请选择' }],
source: [{ required: true, message: '请输入来源' }],
author: [{ required: true, message: '请输入作者' }],
contentHtml: [{ required: true, message: '请输入内容' }],
};
// 查询详情
async function getNoticeUpdate(noticeId) {
try {
SmartLoading.show();
const result = await noticeApi.getUpdateNoticeInfo(noticeId);
const attachment = result.data.attachment;
if (!_.isEmpty(attachment)) {
defaultFileList.value = attachment;
} else {
defaultFileList.value = [];
}
Object.assign(formData, result.data);
formData.allVisibleFlag = formData.allVisibleFlag ? 1 : 0;
releaseTime.value = dayjs(result.data.publishTime);
visibleFlag.value = true;
} catch (err) {
smartSentry.captureError(err);
} finally {
SmartLoading.hide();
}
}
// 点击确定,验证表单
async function onSubmit() {
try {
formData.contentHtml = contentRef.value.getHtml();
formData.contentText = contentRef.value.getText();
await formRef.value.validateFields();
save();
} catch (err) {
message.error('参数验证错误,请仔细填写表单数据!');
}
}
// 新建、编辑API
async function save() {
try {
SmartLoading.show();
if (formData.allVisibleFlag) {
formData.visibleRangeList = [];
}
if (!formData.publishTime) {
formData.publishTime = dayjs().format(timeFormat);
}
if (formData.noticeId) {
await noticeApi.updateNotice(formData);
} else {
await noticeApi.addNotice(formData);
}
message.success('保存成功');
emits('reloadList');
onClose();
} catch (err) {
smartSentry.captureError(err);
} finally {
SmartLoading.hide();
}
}
// ------------------ 通知分类 ------------------
// 查询分类列表
const noticeTypeList = ref([]);
async function queryNoticeTypeList() {
try {
const result = await noticeApi.getAllNoticeTypeList();
noticeTypeList.value = result.data;
if (noticeTypeList.value.length > 0 && !formData.noticeId) {
formData.noticeTypeId = noticeTypeList.value[0].noticeTypeId;
}
} catch (err) {
smartSentry.captureError(err);
}
}
// ----------------------- 可见员工/部门 ----------------------------
// 点击显示选择可见员工/部门
function showNoticeVisibleModal() {
const visibleRangeList = formData.visibleRangeList || [];
noticeFormVisibleModal.value.showModal(visibleRangeList);
}
// 选择完成回调
function finishCanSelectedVisibleRange(selectedList) {
formData.visibleRangeList = selectedList;
}
// 移除某个员工/部门
function removeVisibleItem(index) {
Modal.confirm({
title: '提示',
content: '确定移除吗?',
onOk() {
formData.visibleRangeList.splice(index, 1);
},
});
}
// ----------------------- 发布时间 ----------------------------
const timeFormat = 'YYYY-MM-DD HH:mm:ss';
const releaseTime = ref(null);
function changeTime(date, dateString) {
formData.publishTime = dateString;
}
function changesSheduledPublishFlag(checked) {
releaseTime.value = checked ? dayjs() : null;
formData.publishTime = checked ? dayjs().format(timeFormat) : null;
}
// ----------------------- 上传附件 ----------------------------
// 已上传的附件列表
const defaultFileList = ref([]);
function changeAttachment(fileList) {
defaultFileList.value = fileList;
formData.attachment = _.isEmpty(fileList) ? [] : fileList;
}
// ----------------------- 以下是暴露的方法内容 ------------------------
defineExpose({
showModal,
});
</script>
<style lang="less" scoped>
.visible-list {
display: flex;
flex-wrap: wrap;
.visible-item {
padding-top: 8px;
}
}
</style>
@@ -0,0 +1,71 @@
<!--
* 通知 可见范围
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-08-21 19:52:43
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
-->
<template>
<a-modal title="选择部门" v-model:open="visibleFlag" :maskClosable="false" :width="768" @ok="onSubmit" @cancel="onClose">
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane :key="1" tab="选择员工">
<NoticeFormVisibleTransferEmployee :employeeList="employeeList" @onChange="onChangeEmployee" />
</a-tab-pane>
<a-tab-pane :key="2" tab="选择部门">
<NoticeFormVisibleTransferDepartment :departmentList="departmentList" @onChange="onChangeDepartment" />
</a-tab-pane>
</a-tabs>
</a-modal>
</template>
<script setup>
import { reactive, ref, onMounted, watch } from 'vue';
import { NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM } from '/@/constants/business/oa/notice-const';
import NoticeFormVisibleTransferDepartment from './notice-form-visible-transfer-department.vue';
import NoticeFormVisibleTransferEmployee from './notice-form-visible-transfer-employee.vue';
const emits = defineEmits('selectedFinish');
const visibleFlag = ref(false);
function onClose() {
visibleFlag.value = false;
}
const activeKey = ref(1);
// 已选的员工列表
const employeeList = ref([]);
// 已选的部门列表
const departmentList = ref([]);
// 显示弹窗
function showModal(visibleRangeList = []) {
employeeList.value = visibleRangeList.filter((item) => item.dataType === NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.EMPLOYEE.value);
departmentList.value = visibleRangeList.filter((item) => item.dataType === NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.DEPARTMENT.value);
activeKey.value = 1;
visibleFlag.value = true;
}
function onSubmit() {
const selectedList = [...employeeList.value, ...departmentList.value];
emits('selectedFinish', selectedList);
onClose();
}
// 选择员工改变
function onChangeEmployee({ selectedList }) {
employeeList.value = selectedList;
}
// 选择部门改变
function onChangeDepartment({ selectedList }) {
departmentList.value = selectedList;
}
// ----------------------- 以下是暴露的方法内容 ------------------------
defineExpose({
showModal,
});
</script>
<style lang="less" scoped></style>
@@ -0,0 +1,204 @@
<!--
* 通知 可见范围 选择部门
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-08-21 19:52:43
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
-->
<template>
<div class="wrapper">
<div class="sider-fl">
<a-tree :tree-data="treeData" :fieldNames="{ title: 'name', key: 'departmentId' }" :selectable="false" v-model:expandedKeys="expandedKeys">
<template #switcherIcon="{ switcherCls }">
<caret-down-outlined :class="switcherCls" />
</template>
<template #title="{ name, departmentId }">
<div class="list-item" :class="{ active: checkExists(departmentId) }">
<div class="list-item-title">{{ name }}</div>
<check-circle-filled class="check-icon-style" @click="onSelectAdd(name, departmentId)" />
</div>
</template>
</a-tree>
</div>
<div class="sider-fr">
<div class="selected-list">
<div class="list-item" v-for="(item, index) in selectedList" :key="item.dataId">
<div class="list-item-title">{{ item.dataName }}</div>
<close-circle-two-tone @click="onRemove(index)" />
</div>
</div>
</div>
</div>
</template>
<script setup>
import { reactive, ref, onMounted, watch, computed, nextTick } from 'vue';
import _ from 'lodash';
import { NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM } from '/@/constants/business/oa/notice-const';
import { departmentApi } from '/@/api/system/department-api';
import { smartSentry } from '/@/lib/smart-sentry';
const props = defineProps({
// 已选择的部门数据列表
departmentList: {
type: Array,
default: () => [],
},
});
const emits = defineEmits(['onChange']);
const treeData = ref([]);
async function queryDepartmentTree() {
try {
const result = await departmentApi.queryDepartmentTree();
if (!_.isEmpty(result.data)) {
treeData.value = result.data;
setExpanded();
}
} catch (err) {
smartSentry.captureError(err);
}
}
// 设置默认展开的节点
const expandedKeys = ref([]);
function setExpanded() {
expandedKeys.value = [treeData.value[0].departmentId];
}
// 选择的部门列表数据
const selectedList = ref([]);
// 选择的部门列表Ids
const selectedIds = computed(() => {
return selectedList.value.map((item) => item.dataId);
});
watch(
() => props.departmentList,
(newVal) => {
selectedList.value = newVal;
},
{ immediate: true }
);
// 检查是否已选
function checkExists(dataId) {
return selectedIds.value.includes(dataId);
}
// 点击左边添加
function onSelectAdd(name, departmentId) {
if (checkExists(departmentId)) {
return;
}
selectedList.value.push({
dataName: name,
dataId: departmentId,
dataType: NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.DEPARTMENT.value,
});
onChangeEmit();
}
// 点击右边移除
function onRemove(index) {
selectedList.value.splice(index, 1);
onChangeEmit();
}
function onChangeEmit() {
emits('onChange', { selectedList: selectedList.value, selectedIds: selectedIds.value });
}
onMounted(() => {
queryDepartmentTree();
});
</script>
<style lang="less" scoped>
:deep(.ant-tree-list-holder-inner) {
display: block !important;
.ant-tree-treenode {
align-items: center;
padding-bottom: 0;
&:hover {
background-color: #f9f9f9;
}
.ant-tree-switcher {
display: flex;
align-items: center;
justify-content: center;
.ant-tree-switcher-icon {
font-size: 12px;
}
}
.ant-tree-node-content-wrapper {
display: block;
flex: 1;
&:hover {
cursor: auto;
}
.ant-tree-title {
display: block;
}
}
}
}
.wrapper {
display: flex;
.sider-fl,
.sider-fr {
flex: 1;
height: 500px;
border: 1px solid #d9d9d9;
overflow: hidden;
overflow-y: auto;
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-track-piece {
background-color: #ededed;
}
&::-webkit-scrollbar-thumb {
height: 50px;
background-color: #a1a1a1;
border-radius: 4px;
}
}
.sider-fr {
margin-left: 15px;
.list-item {
padding-left: 14px;
}
}
}
.list-item {
display: flex;
align-items: center;
padding: 0 14px 0 0;
height: 32px;
&:hover {
background-color: #f9f9f9;
}
&.active {
.check-icon-style {
cursor: auto;
color: @primary-color;
}
}
.list-item-title {
flex: 1;
margin-right: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.check-icon-style {
color: #d9d9d9;
}
}
</style>
@@ -0,0 +1,252 @@
<!--
* 通知 可见范围 选择员工
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-08-21 19:52:43
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
-->
<template>
<div class="wrapper">
<div class="sider-left">
<a-tree :tree-data="treeData" :fieldNames="{ title: 'name' }" :selectable="false" v-model:expandedKeys="expandedKeys">
<template #switcherIcon="{ switcherCls }">
<caret-down-outlined :class="switcherCls" />
</template>
<template #title="{ name, id, dataType }">
<div class="list-item" :class="{ active: checkExists(id) }">
<div class="list-item-title">
<user-outlined v-if="dataType === NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.EMPLOYEE.value" />
{{ name }}
</div>
<check-circle-filled
v-if="dataType === NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.EMPLOYEE.value"
class="check-icon-style"
@click="onSelectAdd(name, id, dataType)"
/>
</div>
</template>
</a-tree>
</div>
<div class="sider-right">
<div class="selected-list">
<div class="list-item" v-for="(item, index) in selectedList" :key="item.id">
<div class="list-item-title">{{ item.dataName }}</div>
<close-circle-two-tone @click="onRemove(index)" />
</div>
</div>
</div>
</div>
</template>
<script setup>
import { computed, nextTick, onMounted, ref, watch } from 'vue';
import _ from 'lodash';
import { NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM } from '/@/constants/business/oa/notice-const';
import { departmentApi } from '/@/api/system/department-api';
import { employeeApi } from '/@/api/system/employee-api';
import { smartSentry } from '/@/lib/smart-sentry';
const props = defineProps({
// 已选择的员工数据列表
employeeList: {
type: Array,
default: () => [],
},
});
const emits = defineEmits(['onChange']);
const treeData = ref([]);
// 查询部门树形
async function queryDepartmentTree() {
try {
const departmentResult = await departmentApi.queryDepartmentTree();
const employeeResult = await employeeApi.queryAll();
const departmentTree = departmentResult.data;
buildDepartmentEmployeeTree(departmentTree, employeeResult.data);
if (!_.isEmpty(departmentTree)) {
treeData.value = departmentTree;
console.log(treeData.value);
nextTick(() => {
setExpanded();
});
}
} catch (err) {
smartSentry.captureError(err);
}
}
// 递归构建部门员工树
function buildDepartmentEmployeeTree(departmentTree, employeeList) {
for (const department of departmentTree) {
if (department.dataType && department.dataType === NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.EMPLOYEE.value) {
continue;
}
department.id = department.departmentId;
department.key = 'department_' + department.departmentId;
department.dataType = NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.DEPARTMENT.value;
let employeeChildren = employeeList
.filter((e) => e.departmentId === department.departmentId)
.map((e) =>
Object.assign(
{},
{
id: e.employeeId,
key: 'employee_' + e.employeeId,
name: e.actualName,
dataType: NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.EMPLOYEE.value,
}
)
);
if (!department.children) {
department.children = [];
}
department.children.push(...employeeChildren);
buildDepartmentEmployeeTree(department.children, employeeList);
}
}
// 设置默认展开的节点
const expandedKeys = ref([]);
function setExpanded() {
expandedKeys.value = [treeData.value[0].key];
}
// 选择的员工列表数据
const selectedList = ref([]);
// 选择的员工列表Ids
const selectedIds = computed(() => {
return selectedList.value.map((item) => item.dataId);
});
watch(
() => props.employeeList,
(newVal) => {
selectedList.value = newVal;
},
{ immediate: true }
);
// 检查是否已选
function checkExists(id) {
return selectedIds.value.includes(id);
}
// 点击左边添加
function onSelectAdd(name, id, dataType) {
if (checkExists(id)) {
return;
}
selectedList.value.push({
dataName: name,
dataId: id,
dataType: NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.EMPLOYEE.value,
});
onChangeEmit();
}
// 点击右边移除
function onRemove(index) {
selectedList.value.splice(index, 1);
onChangeEmit();
}
function onChangeEmit() {
emits('onChange', { selectedList: selectedList.value, selectedIds: selectedIds.value });
}
onMounted(() => {
queryDepartmentTree();
});
</script>
<style lang="less" scoped>
:deep(.ant-tree-list-holder-inner) {
display: block !important;
.ant-tree-treenode {
align-items: center;
padding-bottom: 0;
&:hover {
background-color: #f9f9f9;
}
.ant-tree-switcher {
display: flex;
align-items: center;
justify-content: center;
.ant-tree-switcher-icon {
font-size: 12px;
}
}
.ant-tree-node-content-wrapper {
display: block;
flex: 1;
&:hover {
cursor: auto;
}
.ant-tree-title {
display: block;
}
}
}
}
.wrapper {
display: flex;
.sider-left,
.sider-right {
flex: 1;
height: 500px;
border: 1px solid #d9d9d9;
overflow: hidden;
overflow-y: auto;
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-track-piece {
background-color: #ededed;
}
&::-webkit-scrollbar-thumb {
height: 50px;
background-color: #a1a1a1;
border-radius: 4px;
}
}
.sider-right {
margin-left: 15px;
.list-item {
padding-left: 14px;
}
}
}
.list-item {
display: flex;
align-items: center;
padding: 0 14px 0 0;
height: 32px;
&:hover {
background-color: #f9f9f9;
}
&.active {
.check-icon-style {
cursor: auto;
color: @primary-color;
}
}
.list-item-title {
flex: 1;
margin-right: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.check-icon-style {
color: #d9d9d9;
}
}
</style>
@@ -0,0 +1,161 @@
<!--
* 通知 查看记录
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-08-21 19:52:43
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
-->
<template>
<div>
<a-form class="smart-query-form">
<a-row class="smart-query-form-row">
<a-form-item label="部门" class="smart-query-form-item" style="width: 280px; margin-right: 20px">
<DepartmentTreeSelect v-model:value="queryForm.departmentId" width="100%" />
</a-form-item>
<a-form-item label="关键字" class="smart-query-form-item" style="width: 280px">
<a-input v-model:value="queryForm.keywords" placeholder="姓名/IP/设备" />
</a-form-item>
<a-form-item class="smart-query-form-item smart-margin-left10">
<a-button-group>
<a-button type="primary" @click="onSearch">
<template #icon>
<SearchOutlined />
</template>
查询
</a-button>
<a-button @click="resetQuery">
<template #icon>
<ReloadOutlined />
</template>
重置
</a-button>
</a-button-group>
</a-form-item>
</a-row>
</a-form>
<a-table rowKey="employeeId" :columns="tableColumns" :dataSource="tableData" :pagination="false" :loading="tableLoading" size="small" bordered>
<template #bodyCell="{ column, record, text }">
<template v-if="column.dataIndex === 'employeeName'"> {{ text }}({{ record.departmentName }}) </template>
<template v-if="column.dataIndex === 'firstIp'"> {{ text }} ({{ record.firstDevice }}) </template>
<template v-if="column.dataIndex === 'lastIp'"> {{ text }} ({{ record.lastDevice }}) </template>
</template>
</a-table>
<div class="smart-query-table-page">
<a-pagination
showSizeChanger
showQuickJumper
show-less-items
:pageSizeOptions="PAGE_SIZE_OPTIONS"
:defaultPageSize="queryForm.pageSize"
v-model:current="queryForm.pageNum"
v-model:pageSize="queryForm.pageSize"
:total="total"
@change="queryViewRecord"
@showSizeChange="queryViewRecord"
:show-total="(total) => `${total}`"
/>
</div>
</div>
</template>
<script setup>
import { reactive, ref } from 'vue';
import { noticeApi } from '/@/api/business/oa/notice-api';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue';
import uaparser from 'ua-parser-js';
const props = defineProps({
noticeId: {
type: [Number, String],
},
});
defineExpose({
onSearch,
});
const tableColumns = [
{
title: '姓名',
dataIndex: 'employeeName',
},
{
title: '查看次数',
dataIndex: 'pageViewCount',
},
{
title: '首次查看设备',
dataIndex: 'firstIp',
},
{
title: '首次查看时间',
dataIndex: 'createTime',
},
{
title: '最后一次查看设备',
dataIndex: 'lastIp',
},
{
title: '最后一次查看时间',
dataIndex: 'updateTime',
with: 80,
},
];
const tableData = ref([]);
const total = ref(0);
const tableLoading = ref(false);
const defaultQueryForm = {
noticeId: props.noticeId,
departmentId: null,
keywords: '',
pageNum: 1,
pageSize: PAGE_SIZE,
};
const queryForm = reactive({ ...defaultQueryForm });
function buildDeviceInfo(userAgent) {
if (!userAgent) {
return '';
}
let ua = uaparser(userAgent);
let browser = ua.browser.name;
let os = ua.os.name;
return browser + '/' + os + '/' + (ua.device.vendor ? ua.device.vendor + ua.device.model : '');
}
async function queryViewRecord() {
try {
tableLoading.value = true;
const result = await noticeApi.queryViewRecord(queryForm);
for (const e of result.data.list) {
e.firstDevice = buildDeviceInfo(e.firstUserAgent);
e.lastDevice = buildDeviceInfo(e.lastUserAgent);
}
tableData.value = result.data.list;
total.value = result.data.total;
} catch (err) {
console.log(err);
} finally {
tableLoading.value = false;
}
}
// 点击查询
function onSearch() {
queryForm.pageNum = 1;
queryViewRecord();
}
// 点击重置
function resetQuery() {
Object.assign(queryForm, defaultQueryForm);
queryViewRecord();
}
</script>
@@ -0,0 +1,144 @@
<!--
* 通知 详情
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-08-21 19:52:43
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
-->
<template>
<a-card style="margin-bottom: 15px" size="small">
<a-descriptions :title="noticeDetail.title" :column="4" size="small">
<template #extra>
<a-button v-if="!noticeDetail.publishFlag" type="primary" size="small" @click="onEdit">编辑</a-button>
</template>
<a-descriptions-item label="分类">{{ noticeDetail.noticeTypeName }}</a-descriptions-item>
<a-descriptions-item label="文号">{{ noticeDetail.documentNumber }}</a-descriptions-item>
<a-descriptions-item label="来源">{{ noticeDetail.source }}</a-descriptions-item>
<a-descriptions-item label="作者">{{ noticeDetail.author }}</a-descriptions-item>
<a-descriptions-item label="页面浏览量">{{ noticeDetail.pageViewCount }}</a-descriptions-item>
<a-descriptions-item label="用户浏览量">{{ noticeDetail.userViewCount }}</a-descriptions-item>
<a-descriptions-item label="创建时间">{{ noticeDetail.createTime }}</a-descriptions-item>
<a-descriptions-item label="发布时间">{{ noticeDetail.publishTime }}</a-descriptions-item>
<a-descriptions-item label="定时发布">{{ noticeDetail.publishFlag ? '已发布' : '待发布' }}</a-descriptions-item>
<a-descriptions-item label="删除状态">{{ noticeDetail.deletedFlag ? '已删除' : '未删除' }}</a-descriptions-item>
<a-descriptions-item v-if="!$lodash.isEmpty(noticeDetail.attachment)" label="附件">
<div class="file-list">
<a class="file-item" v-for="item in noticeDetail.attachment" :key="item.fileId" @click="onPrevFile(item)">{{ item.fileName }}</a>
</div>
</a-descriptions-item>
<a-descriptions-item label="可见范围">
<template v-if="noticeDetail.allVisibleFlag">全部可见</template>
<div class="visible-list">
<div class="visible-item" v-for="item in noticeDetail.visibleRangeList" :key="item.dataId">
{{ item.dataName }}
</div>
</div>
</a-descriptions-item>
</a-descriptions>
</a-card>
<a-card size="small">
<a-tabs v-model:activeKey="activeKey" size="small">
<a-tab-pane :key="1" tab="内容">
<div class="content-html" v-html="noticeDetail.contentHtml"></div>
</a-tab-pane>
<a-tab-pane :key="2" tab="查看记录" force-render>
<NoticeViewRecordList ref="noticeViewRecordList" :noticeId="route.query.noticeId" />
</a-tab-pane>
<a-tab-pane :key="3" tab="操作记录" />
</a-tabs>
</a-card>
<!-- 编辑 -->
<NoticeFormDrawer ref="noticeFormDrawerRef" @reloadList="queryNoticeDetail" />
<!-- 预览附件 -->
<FilePreviewModal ref="filePreviewRef" />
</template>
<script setup>
import { onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';
import NoticeFormDrawer from './components/notice-form-drawer.vue';
import NoticeViewRecordList from './components/notice-view-record-list.vue';
import { noticeApi } from '/@/api/business/oa/notice-api';
import { SmartLoading } from '/@/components/framework/smart-loading';
import FilePreviewModal from '/@/components/support/file-preview-modal/index.vue';
import { smartSentry } from '/@/lib/smart-sentry';
const route = useRoute();
const props = defineProps({
newsType: {
type: Number,
},
});
const activeKey = ref(1);
const noticeDetail = ref({});
const noticeViewRecordList = ref();
onMounted(() => {
if (route.query.noticeId) {
queryNoticeDetail();
noticeViewRecordList.value.onSearch();
}
});
// 查询详情
async function queryNoticeDetail() {
try {
SmartLoading.show();
const result = await noticeApi.getUpdateNoticeInfo(route.query.noticeId);
noticeDetail.value = result.data;
} catch (err) {
smartSentry.captureError(err);
} finally {
SmartLoading.hide();
}
}
// 点击编辑
const noticeFormDrawerRef = ref();
function onEdit() {
noticeFormDrawerRef.value.showModal(noticeDetail.value.noticeId);
}
// 预览附件
const filePreviewRef = ref();
function onPrevFile(fileItem) {
filePreviewRef.value.showPreview(fileItem);
}
</script>
<style lang="less" scoped>
:deep(.ant-descriptions-item-content) {
flex: 1;
overflow: hidden;
}
.file-list {
width: 100%;
display: flex;
flex-wrap: wrap;
.file-item {
display: block;
margin-right: 10px;
}
}
.visible-list {
display: flex;
flex-wrap: wrap;
.visible-item {
margin-right: 10px;
color: #666;
}
}
.content-html {
img {
max-width: 100%;
}
}
</style>
@@ -0,0 +1,145 @@
<!--
* 通知 详情 员工
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-08-21 19:52:43
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
-->
<template>
<a-card size="small">
<div>
<div class="content-header">
<!--startprint-->
<div class="content-header-title">
{{ noticeDetail.title }}
</div>
<div class="content-header-info">
<span v-show="noticeDetail.author">作者{{ noticeDetail.author }}</span>
<span v-show="noticeDetail.source">来源{{ noticeDetail.source }}</span>
<span>发布时间{{ noticeDetail.publishTime }}</span>
<span>阅读量{{ noticeDetail.pageViewCount }}</span>
<span @click="print">打印本页</span>
</div>
</div>
<div class="content-html" v-html="noticeDetail.contentHtml"></div>
<!--endprint-->
</div>
<a-divider />
<div>
附件
<file-preview v-if="!$lodash.isEmpty(noticeDetail.attachment)" :fileList="noticeDetail.attachment" />
<span v-else></span>
</div>
</a-card>
<a-card title="记录" size="small" class="smart-margin-top10">
<NoticeViewRecordList ref="noticeViewRecordList" :noticeId="route.query.noticeId" />
</a-card>
</template>
<script setup>
import { onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';
import NoticeViewRecordList from './components/notice-view-record-list.vue';
import { noticeApi } from '/@/api/business/oa/notice-api';
import { SmartLoading } from '/@/components/framework/smart-loading';
import FilePreview from '/@/components/support/file-preview/index.vue';
import { smartSentry } from '/@/lib/smart-sentry';
const route = useRoute();
const noticeDetail = ref({});
onMounted(() => {
if (route.query.noticeId) {
queryNoticeDetail();
}
});
const noticeViewRecordList = ref();
// 查询详情
async function queryNoticeDetail() {
try {
SmartLoading.show();
const result = await noticeApi.view(route.query.noticeId);
noticeDetail.value = result.data;
noticeViewRecordList.value.onSearch();
} catch (err) {
smartSentry.captureError(err);
} finally {
SmartLoading.hide();
}
}
// 点击编辑
const noticeFormDrawerRef = ref();
function onEdit() {
noticeFormDrawerRef.value.showModal(noticeDetail.value.noticeId);
}
// 打印
function print() {
let bdhtml = window.document.body.innerHTML;
let sprnstr = '<!--startprint-->'; //必须在页面添加<!--startprint-->和<!--endprint-->而且需要打印的内容必须在它们之间
let eprnstr = '<!--endprint-->';
let prnhtml = bdhtml.substr(bdhtml.indexOf(sprnstr));
prnhtml = prnhtml.substring(0, prnhtml.indexOf(eprnstr));
let newWin = window.open(''); //新打开一个空窗口
newWin.document.body.innerHTML = prnhtml;
newWin.document.close(); //在IE浏览器中使用必须添加这一句
newWin.focus(); //在IE浏览器中使用必须添加这一句
newWin.print(); //打印
newWin.close(); //关闭窗口
}
</script>
<style lang="less" scoped>
:deep(.ant-descriptions-item-content) {
flex: 1;
overflow: hidden;
}
.file-list {
width: 100%;
display: flex;
flex-wrap: wrap;
.file-item {
display: block;
margin-right: 10px;
}
}
.visible-list {
display: flex;
flex-wrap: wrap;
.visible-item {
margin-right: 10px;
color: #666;
}
}
.content-header {
.content-header-title {
margin: 10px 0px;
font-size: 18px;
font-weight: bold;
text-align: center;
}
.content-header-info {
margin: 10px 0px;
font-size: 14px;
color: #888;
text-align: center;
span {
margin: 0 10px;
cursor: pointer;
}
}
}
.content-html {
img {
max-width: 100%;
}
}
</style>
@@ -0,0 +1,212 @@
<!--
* 通知 详情 员工列表
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-08-21 19:52:43
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
-->
<template>
<a-form class="smart-query-form">
<a-row class="smart-query-form-row">
<a-form-item label="关键字" class="smart-query-form-item">
<a-input style="width: 200px" v-model:value="queryForm.keywords" placeholder="标题、作者、来源、文号" />
</a-form-item>
<a-form-item label="发布时间" class="smart-query-form-item">
<a-range-picker v-model:value="publishDate" @change="publishDateChange" style="width: 220px" />
</a-form-item>
<a-form-item class="smart-query-form-item smart-margin-left10">
<a-button-group>
<a-button type="primary" @click="onSearch">
<template #icon>
<SearchOutlined />
</template>
查询
</a-button>
<a-button @click="onReload">
<template #icon>
<ReloadOutlined />
</template>
重置
</a-button>
</a-button-group>
</a-form-item>
</a-row>
<a-row class="smart-query-form-row"> </a-row>
</a-form>
<a-card size="small" :bordered="false">
<a-tabs @change="changeNotViewFlag" size="small">
<a-tab-pane :key="0" tab="全部" />
<a-tab-pane :key="1" tab="未读" />
</a-tabs>
<a-table rowKey="noticeId" :columns="tableColumns" :dataSource="tableData" :pagination="false" :loading="tableLoading" bordered size="small">
<template #bodyCell="{ column, record, text }">
<template v-if="column.dataIndex === 'title'">
<span v-show="record.viewFlag">
<a @click="toDetail(record.noticeId)" style="color: #8c8c8c">{{ record.noticeTypeName }}{{ text }}已读</a>
</span>
<span v-show="!record.viewFlag">
<a @click="toDetail(record.noticeId)"
>{{ record.noticeTypeName }}{{ text }}
<span style="color: red">未读</span>
</a>
</span>
</template>
<template v-if="column.dataIndex === 'pageViewCount'"> {{ record.userViewCount }} / {{ record.pageViewCount }} </template>
</template>
</a-table>
<div class="smart-query-table-page">
<a-pagination
showSizeChanger
showQuickJumper
show-less-items
:pageSizeOptions="PAGE_SIZE_OPTIONS"
:defaultPageSize="queryForm.pageSize"
v-model:current="queryForm.pageNum"
v-model:pageSize="queryForm.pageSize"
:total="total"
@change="queryNoticeList"
@showSizeChange="queryNoticeList"
:show-total="(total) => `${total}`"
/>
</div>
</a-card>
</template>
<script setup>
import { onMounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
import { noticeApi } from '/@/api/business/oa/notice-api';
import { smartSentry } from '/@/lib/smart-sentry';
const tableColumns = reactive([
{
title: `标题`,
dataIndex: 'title',
ellipsis: true,
},
{
title: '访问量',
dataIndex: 'pageViewCount',
width: 90,
},
{
title: `来源`,
dataIndex: 'source',
width: 150,
ellipsis: true,
},
{
title: `作者`,
dataIndex: 'author',
width: 80,
ellipsis: true,
},
{
title: '发布时间',
dataIndex: 'publishTime',
width: 150,
},
]);
// ------------------ 通知分类 ------------------
// 查询分类列表
const noticeTypeList = ref([]);
async function queryNoticeTypeList() {
try {
const result = await noticeApi.getAllNoticeTypeList();
noticeTypeList.value = result.data;
} catch (err) {
smartSentry.captureError(err);
}
}
// ------------------ 查询相关 ------------------
const queryFormState = {
noticeTypeId: undefined, //分类
keywords: '', //标题、作者、来源
publishTimeBegin: null, //发布-开始时间
publishTimeEnd: null, //发布-截止时间
notViewFlag: false, //未读
pageNum: 1,
pageSize: PAGE_SIZE,
};
const queryForm = reactive({ ...queryFormState });
const tableData = ref([]);
const total = ref(0);
const tableLoading = ref(false);
onMounted(() => {
queryNoticeTypeList();
queryNoticeList();
});
function changeNotViewFlag(value) {
queryForm.notViewFlag = value === 0 ? null : true;
onSearch();
}
// 查询列表
async function queryNoticeList() {
try {
tableLoading.value = true;
const result = await noticeApi.queryEmployeeNotice(queryForm);
tableData.value = result.data.list;
total.value = result.data.total;
} catch (err) {
smartSentry.captureError(err);
} finally {
tableLoading.value = false;
}
}
// 点击查询
function onSearch() {
queryForm.pageNum = 1;
queryNoticeList();
}
// 点击重置
function onReload() {
Object.assign(queryForm, queryFormState);
publishDate.value = [];
createDate.value = [];
queryNoticeList();
}
// 发布日期选择
const publishDate = ref([]);
function publishDateChange(dates, dateStrings) {
queryForm.publishTimeBegin = dateStrings[0];
queryForm.publishTimeEnd = dateStrings[1];
}
// 创建日期选择
const createDate = ref([]);
function createDateChange(dates, dateStrings) {
queryForm.createTimeBegin = dateStrings[0];
queryForm.createTimeEnd = dateStrings[1];
}
// ------------------ 详情 ------------------
// 进入详情
const router = useRouter();
function toDetail(noticeId) {
router.push({
path: '/oa/notice/notice-employee-detail',
query: { noticeId },
});
}
</script>
<style lang="less" scoped></style>
@@ -0,0 +1,352 @@
<!--
* 通知 管理列表
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-08-21 19:52:43
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net ),Since 2012
-->
<template>
<a-form class="smart-query-form" v-privilege="'oa:notice:query'">
<a-row class="smart-query-form-row">
<a-form-item label="分类" class="smart-query-form-item">
<a-select v-model:value="queryForm.noticeTypeId" style="width: 100px" :showSearch="true" :allowClear="true" placeholder="分类">
<a-select-option v-for="item in noticeTypeList" :key="item.noticeTypeId" :value="item.noticeTypeId">
{{ item.noticeTypeName }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="关键字" class="smart-query-form-item">
<a-input style="width: 300px" v-model:value="queryForm.keywords" placeholder="标题、作者、来源" />
</a-form-item>
<a-form-item label="文号" class="smart-query-form-item">
<a-input style="width: 150px" v-model:value="queryForm.documentNumber" placeholder="文号" />
</a-form-item>
<a-form-item label="创建人" class="smart-query-form-item">
<a-input style="width: 100px" v-model:value="queryForm.createUserId" placeholder="创建人" />
</a-form-item>
<a-form-item label="是否删除" class="smart-query-form-item">
<SmartBooleanSelect v-model:value="queryForm.deletedFlag" style="width: 70px" />
</a-form-item>
<a-form-item label="发布时间" class="smart-query-form-item">
<a-range-picker v-model:value="publishDate" :presets="defaultTimeRanges" @change="publishDateChange" style="width: 220px" />
</a-form-item>
<a-form-item label="创建时间" class="smart-query-form-item">
<a-range-picker v-model:value="createDate" :presets="defaultTimeRanges" @change="createDateChange" style="width: 220px" />
</a-form-item>
<a-form-item class="smart-query-form-item smart-margin-left10">
<a-button-group>
<a-button type="primary" @click="onSearch">
<template #icon>
<SearchOutlined />
</template>
查询
</a-button>
<a-button @click="onReload">
<template #icon>
<ReloadOutlined />
</template>
重置
</a-button>
</a-button-group>
</a-form-item>
</a-row>
</a-form>
<a-card size="small" :bordered="false">
<a-row class="smart-table-btn-block">
<div class="smart-table-operate-block">
<a-button type="primary" @click="addOrUpdate()" v-privilege="'oa:notice:add'">
<template #icon>
<PlusOutlined />
</template>
新建
</a-button>
</div>
<div class="smart-table-setting-block">
<TableOperator v-model="tableColumns" :tableId="TABLE_ID_CONST.BUSINESS.OA.NOTICE" :refresh="queryNoticeList" />
</div>
</a-row>
<a-table
rowKey="noticeId"
:columns="tableColumns"
:dataSource="tableData"
:scroll="{ x: 1510 }"
:pagination="false"
:loading="tableLoading"
size="small"
bordered
>
<template #bodyCell="{ column, record, text }">
<template v-if="column.dataIndex === 'title'">
<a @click="toDetail(record.noticeId)">{{ text }}</a>
</template>
<template v-else-if="column.dataIndex === 'allVisibleFlag'"> {{ text ? '全部可见' : '部分可见' }} </template>
<template v-else-if="column.dataIndex === 'publishFlag'">
{{ text ? '已发布' : '待发布' }}
</template>
<template v-else-if="column.dataIndex === 'deletedFlag'">
<a-tag v-show="text" color="error">已删除</a-tag>
<a-tag v-show="!text" color="success">未删除</a-tag>
</template>
<template v-else-if="column.dataIndex === 'action'">
<div class="smart-table-operate">
<a-button type="link" @click="addOrUpdate(record.noticeId)" v-privilege="'oa:notice:update'">编辑</a-button>
<a-button type="link" @click="onDelete(record.noticeId)" v-privilege="'oa:notice:delete'" danger>删除</a-button>
</div>
</template>
</template>
</a-table>
<div class="smart-query-table-page">
<a-pagination
showSizeChanger
showQuickJumper
show-less-items
:pageSizeOptions="PAGE_SIZE_OPTIONS"
:defaultPageSize="queryForm.pageSize"
v-model:current="queryForm.pageNum"
v-model:pageSize="queryForm.pageSize"
:total="total"
@change="queryNoticeList"
@showSizeChange="queryNoticeList"
:show-total="(total) => `${total}`"
/>
</div>
</a-card>
<NoticeFormDrawer ref="noticeFormDrawer" @reloadList="queryNoticeList" />
</template>
<script setup>
import { reactive, ref, onMounted } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { useRouter } from 'vue-router';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
import SmartBooleanSelect from '/@/components/framework/boolean-select/index.vue';
import { noticeApi } from '/@/api/business/oa/notice-api';
import NoticeFormDrawer from './components/notice-form-drawer.vue';
import { defaultTimeRanges } from '/@/lib/default-time-ranges';
import { smartSentry } from '/@/lib/smart-sentry';
import TableOperator from '/@/components/support/table-operator/index.vue';
import { TABLE_ID_CONST } from '/@/constants/support/table-id-const';
const queryFormState = {
noticeTypeId: undefined, //分类
keywords: '', //标题、作者、来源
documentNumber: '', //文号
createUserId: undefined, //创建人
deletedFlag: undefined, //删除标识
createTimeBegin: null, //创建-开始时间
createTimeEnd: null, //创建-截止时间
publishTimeBegin: null, //发布-开始时间
publishTimeEnd: null, //发布-截止时间
pageNum: 1,
pageSize: PAGE_SIZE,
};
const queryForm = reactive({ ...queryFormState });
const tableColumns = ref([
{
title: `标题`,
dataIndex: 'title',
width: 300,
ellipsis: true,
},
{
title: `文号`,
dataIndex: 'documentNumber',
width: 100,
ellipsis: true,
},
{
title: '分类',
dataIndex: 'noticeTypeName',
width: 60,
ellipsis: true,
},
{
title: `作者`,
dataIndex: 'author',
width: 80,
ellipsis: true,
},
{
title: `来源`,
dataIndex: 'source',
width: 90,
ellipsis: true,
},
{
title: '可见范围',
dataIndex: 'allVisibleFlag',
width: 90,
ellipsis: true,
},
{
title: '发布',
dataIndex: 'publishFlag',
width: 80,
},
{
title: '删除',
dataIndex: 'deletedFlag',
width: 80,
},
{
title: '发布时间',
dataIndex: 'publishTime',
width: 150,
},
{
title: '页面浏览量',
dataIndex: 'pageViewCount',
width: 90,
},
{
title: '用户浏览量',
dataIndex: 'userViewCount',
width: 90,
},
{
title: '创建人',
dataIndex: 'createUserName',
width: 80,
},
{
title: '创建时间',
dataIndex: 'createTime',
width: 150,
},
{
title: '操作',
dataIndex: 'action',
fixed: 'right',
width: 90,
},
]);
// ------------------ 通知分类 ------------------
// 查询分类列表
const noticeTypeList = ref([]);
async function queryNoticeTypeList() {
try {
const result = await noticeApi.getAllNoticeTypeList();
noticeTypeList.value = result.data;
} catch (err) {
smartSentry.captureError(err);
}
}
// ------------------ 查询相关 ------------------
const tableData = ref([]);
const total = ref(0);
const tableLoading = ref(false);
onMounted(() => {
queryNoticeTypeList();
queryNoticeList();
});
// 查询列表
async function queryNoticeList() {
try {
tableLoading.value = true;
const result = await noticeApi.queryNotice(queryForm);
tableData.value = result.data.list;
total.value = result.data.total;
} catch (err) {
smartSentry.captureError(err);
} finally {
tableLoading.value = false;
}
}
// 点击查询
function onSearch() {
queryForm.pageNum = 1;
queryNoticeList();
}
// 点击重置
function onReload() {
Object.assign(queryForm, queryFormState);
publishDate.value = [];
createDate.value = [];
queryNoticeList();
}
// 发布日期选择
const publishDate = ref([]);
function publishDateChange(dates, dateStrings) {
queryForm.publishTimeBegin = dateStrings[0];
queryForm.publishTimeEnd = dateStrings[1];
}
// 创建日期选择
const createDate = ref([]);
function createDateChange(dates, dateStrings) {
queryForm.createTimeBegin = dateStrings[0];
queryForm.createTimeEnd = dateStrings[1];
}
// ------------------ 新建、编辑 ------------------
// 新建、编辑
const noticeFormDrawer = ref();
function addOrUpdate(noticeId) {
noticeFormDrawer.value.showModal(noticeId);
}
// ------------------ 删除 ------------------
// 删除
function onDelete(noticeId) {
Modal.confirm({
title: '提示',
content: '确认删除此数据吗?',
onOk() {
deleteNotice(noticeId);
},
});
}
// 删除API
async function deleteNotice(noticeId) {
try {
tableLoading.value = true;
await noticeApi.deleteNotice(noticeId);
message.success('删除成功');
queryNoticeList();
} catch (err) {
smartSentry.captureError(err);
} finally {
tableLoading.value = false;
}
}
// ------------------ 详情 ------------------
// 进入详情
const router = useRouter();
function toDetail(noticeId) {
router.push({
path: '/oa/notice/notice-detail',
query: { noticeId },
});
}
</script>
<style lang="less" scoped></style>