版本预发布

This commit is contained in:
孟帅
2023-02-08 20:29:34 +08:00
parent f11c7c5bf2
commit 2068d05c93
269 changed files with 16122 additions and 12075 deletions

View File

@@ -1,6 +1,11 @@
<template>
<div>
<n-card :bordered="false" class="proCard" title="公告管理">
<div class="n-layout-page-header">
<n-card :bordered="false" title="通知公告">
在这里你可以发送通知公告私信到平台中的用户
</n-card>
</div>
<n-card :bordered="false" class="proCard">
<BasicForm
@register="register"
@submit="handleSubmit"
@@ -25,16 +30,55 @@
:resizeHeightOffset="-10000"
>
<template #tableTitle>
<n-button type="primary" @click="addTable">
<n-button
type="warning"
@click="addTable(1)"
class="min-left-space"
v-if="hasPermission(['/notice/editNotify'])"
>
<template #icon>
<n-icon>
<PlusOutlined />
<NotificationOutlined />
</n-icon>
</template>
添加
发通知
</n-button>
&nbsp;
<n-button type="error" @click="batchDelete" :disabled="batchDeleteDisabled">
<n-button
type="error"
@click="addTable(2)"
class="min-left-space"
v-if="hasPermission(['/notice/editNotice'])"
>
<template #icon>
<n-icon>
<BellOutlined />
</n-icon>
</template>
发公告
</n-button>
<n-button
type="info"
@click="addTable(3)"
class="min-left-space"
v-if="hasPermission(['/notice/editLetter'])"
>
<template #icon>
<n-icon>
<SendOutlined />
</n-icon>
</template>
发私信
</n-button>
<n-button
type="error"
@click="batchDelete"
:disabled="batchDeleteDisabled"
class="min-left-space"
v-if="hasPermission(['/notice/delete'])"
>
<template #icon>
<n-icon>
<DeleteOutlined />
@@ -45,7 +89,24 @@
</template>
</BasicTable>
<n-modal v-model:show="showModal" :show-icon="false" preset="dialog" title="添加">
<n-modal
v-model:show="showModal"
:show-icon="false"
:block-scroll="false"
:mask-closable="false"
preset="dialog"
:title="
formParams.id > 0
? '编辑' + getOptionLabel(noticeTypeOptions, formParams.type) + ' #' + formParams.id
: '发送' + getOptionLabel(noticeTypeOptions, formParams.type)
"
:style="{
width: dialogWidth,
}"
>
<n-alert :show-icon="false" type="info">
消息发送成功后如果接收人在线会立即收到一条消息通知,编辑已发送的消息不会再次通知
</n-alert>
<n-form
:model="formParams"
:rules="rules"
@@ -54,37 +115,53 @@
:label-width="80"
class="py-4"
>
<n-form-item label="公告标题" path="title">
<n-input placeholder="请输入公告标题" v-model:value="formParams.title" />
<n-form-item label="消息标题" path="title">
<n-input placeholder="请输入消息标题" v-model:value="formParams.title" />
</n-form-item>
<n-form-item label="公告类型" path="type">
<n-radio-group v-model:value="formParams.type" name="type">
<n-radio-button
v-for="type in typeOptions"
:key="type.value"
:value="type.value"
:label="type.label"
/>
</n-radio-group>
</n-form-item>
<n-form-item label="公告内容" path="content">
<n-input type="textarea" placeholder="请输入内容" v-model:value="formParams.content" />
</n-form-item>
<n-form-item label="接收人" path="receiver">
<n-input
type="textarea"
placeholder="多个用户ID用,隔开 不填则全部接收"
<n-form-item label="接收人" path="receiver" v-if="formParams.type === 3">
<n-select
multiple
:options="options"
:render-label="renderLabel"
:render-tag="renderMultipleSelectTag"
v-model:value="formParams.receiver"
filterable
/>
</n-form-item>
<n-form-item label="排序" path="sort">
<n-input-number v-model:value="formParams.sort" clearable />
<n-form-item label="消息内容" path="content">
<template v-if="formParams.type === 1">
<n-input
type="textarea"
placeholder="请输入通知内容"
v-model:value="formParams.content"
/>
</template>
<template v-else>
<Editor style="height: 450px" v-model:value="formParams.content" />
</template>
</n-form-item>
<n-grid x-gap="24" :cols="2">
<n-gi>
<n-form-item label="标签" path="tag">
<n-select
clearable
placeholder="可以不填"
:render-tag="renderTag"
v-model:value="formParams.tag"
:options="noticeTagOptions"
/>
</n-form-item>
</n-gi>
<n-gi>
<n-form-item label="排序" path="sort">
<n-input-number style="width: 100%" v-model:value="formParams.sort" clearable />
</n-form-item>
</n-gi>
</n-grid>
<n-form-item label="状态" path="status">
<n-radio-group v-model:value="formParams.status" name="status">
<n-radio-button
@@ -97,14 +174,18 @@
</n-form-item>
<n-form-item label="备注" path="remark">
<n-input type="textarea" placeholder="请输入备注" v-model:value="formParams.remark" />
<n-input
type="textarea"
placeholder="请输入备注没有可以不填"
v-model:value="formParams.remark"
/>
</n-form-item>
</n-form>
<template #action>
<n-space>
<n-button @click="() => (showModal = false)">取消</n-button>
<n-button type="info" :loading="formBtnLoading" @click="confirmForm">确定</n-button>
<n-button type="info" :loading="formBtnLoading" @click="confirmForm">立即发送</n-button>
</n-space>
</template>
</n-modal>
@@ -113,61 +194,76 @@
</template>
<script lang="ts" setup>
import { h, reactive, ref } from 'vue';
import { h, onMounted, reactive, ref } from 'vue';
import { useDialog, useMessage } from 'naive-ui';
import { BasicTable, TableAction } from '@/components/Table';
import { BasicForm, FormSchema, useForm } from '@/components/Form/index';
import { Delete, Edit, List, Status } from '@/api/apply/notice';
import {
Delete,
EditNotify,
EditLetter,
EditNotice,
List,
MaxSort,
Status,
} from '@/api/apply/notice';
import { columns } from './columns';
import { DeleteOutlined, PlusOutlined } from '@vicons/antd';
import { statusActions, statusOptions } from '@/enums/optionsiEnum';
const typeOptions = [
{
value: 1,
label: '通知',
},
{
value: 2,
label: '公告',
},
].map((s) => {
return s;
});
const params = ref<any>({
pageSize: 10,
title: '',
content: '',
status: null,
});
import { BellOutlined, DeleteOutlined, NotificationOutlined, SendOutlined } from '@vicons/antd';
import { statusOptions } from '@/enums/optionsiEnum';
import {
noticeTagOptions,
noticeTypeOptions,
personOption,
renderLabel,
renderMultipleSelectTag,
} from '@/enums/systemMessageEnum';
import { adaModalWidth, getOptionLabel, renderTag } from '@/utils/hotgo';
import Editor from '@/components/Editor/editor.vue';
import { cloneDeep } from 'lodash-es';
import { GetMemberOption } from '@/api/org/user';
import { usePermission } from '@/hooks/web/usePermission';
const { hasPermission } = usePermission();
const rules = {
title: {
// required: true,
required: true,
trigger: ['blur', 'input'],
message: '请输入标题',
message: '请输入消息标题',
},
};
const schemas: FormSchema[] = [
{
field: 'title',
component: 'NInput',
label: '公告标题',
field: 'type',
component: 'NSelect',
label: '消息类型',
defaultValue: null,
componentProps: {
placeholder: '请输入公告标题',
placeholder: '请选择消息类型',
options: noticeTypeOptions,
onUpdateValue: (e: any) => {
console.log(e);
},
},
rules: [{ message: '请输入公告标题', trigger: ['blur'] }],
},
{
field: 'title',
component: 'NInput',
label: '消息标题',
componentProps: {
placeholder: '请输入消息标题',
onUpdateValue: (e: any) => {
console.log(e);
},
},
rules: [{ message: '请输入消息标题', trigger: ['blur'] }],
},
{
field: 'content',
component: 'NInput',
label: '内容',
label: '消息内容',
componentProps: {
placeholder: '请输入内容关键词',
placeholder: '请输入消息内容关键词',
showButton: false,
onUpdateValue: (e: any) => {
console.log(e);
@@ -198,43 +294,59 @@
const formRef = ref<any>({});
const batchDeleteDisabled = ref(true);
const checkedIds = ref([]);
const dialogWidth = ref('75%');
const options = ref<personOption[]>();
const resetFormParams = {
id: 0,
title: '',
name: '',
type: 1,
receiver: '',
tag: 0,
content: '',
receiver: null,
remark: '',
sort: 0,
status: 1,
created_at: '',
updated_at: '',
};
let formParams = ref<any>(resetFormParams);
let formParams = ref<any>(cloneDeep(resetFormParams));
const actionColumn = reactive({
width: 220,
title: '操作',
key: 'action',
fixed: 'right',
// fixed: 'right',
render(record) {
return h(TableAction as any, {
style: 'button',
actions: [
{
label: '已启用',
onClick: handleStatus.bind(null, record, 2),
ifShow: () => {
return record.status === 1;
},
auth: ['/notice/status'],
},
{
label: '已禁用',
onClick: handleStatus.bind(null, record, 1),
ifShow: () => {
return record.status === 2;
},
auth: ['/notice/status'],
},
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: ['/notice/edit'],
type: 'primary',
},
{
label: '删除',
onClick: handleDelete.bind(null, record),
auth: ['/notice/delete'],
},
],
dropDownActions: statusActions,
select: (key) => {
updateStatus(record.id, key);
},
});
},
});
@@ -245,22 +357,21 @@
schemas,
});
function addTable() {
function addTable(type) {
showModal.value = true;
formParams.value = resetFormParams;
formParams.value = cloneDeep(resetFormParams);
formParams.value.type = type;
MaxSort().then((res) => {
formParams.value.sort = res.sort;
});
}
const loadDataTable = async (res) => {
return await List({ ...params.value, ...res, ...searchFormRef.value?.formModel });
return await List({ ...res, ...searchFormRef.value?.formModel });
};
function onCheckedRow(rowKeys) {
if (rowKeys.length > 0) {
batchDeleteDisabled.value = false;
} else {
batchDeleteDisabled.value = true;
}
batchDeleteDisabled.value = rowKeys.length <= 0;
checkedIds.value = rowKeys;
}
@@ -273,14 +384,37 @@
formBtnLoading.value = true;
formRef.value.validate((errors) => {
if (!errors) {
Edit(formParams.value).then((_res) => {
message.success('操作成功');
setTimeout(() => {
showModal.value = false;
reloadTable();
formParams.value = ref(resetFormParams);
});
});
switch (formParams.value.type) {
case 1:
EditNotify(formParams.value).then((_res) => {
message.success('操作成功');
setTimeout(() => {
showModal.value = false;
reloadTable();
});
});
break;
case 2:
EditNotice(formParams.value).then((_res) => {
message.success('操作成功');
setTimeout(() => {
showModal.value = false;
reloadTable();
});
});
break;
case 3:
EditLetter(formParams.value).then((_res) => {
message.success('操作成功');
setTimeout(() => {
showModal.value = false;
reloadTable();
});
});
break;
default:
message.error('公告类型不支持');
}
} else {
message.error('请填写完整信息');
}
@@ -290,7 +424,7 @@
function handleEdit(record: Recordable) {
showModal.value = true;
formParams.value = record;
formParams.value = cloneDeep(record);
}
function handleDelete(record: Recordable) {
@@ -329,24 +463,31 @@
});
}
function handleSubmit(values: Recordable) {
params.value = values;
function handleSubmit(_values: Recordable) {
reloadTable();
}
function handleReset(values: Recordable) {
params.value = values;
function handleReset(_values: Recordable) {
reloadTable();
}
function updateStatus(id, status) {
Status({ id: id, status: status }).then((_res) => {
function handleStatus(record: Recordable, status: number) {
Status({ id: record.id, status: status }).then((_res) => {
message.success('操作成功');
setTimeout(() => {
reloadTable();
});
});
}
async function getMemberOption() {
options.value = await GetMemberOption();
}
onMounted(async () => {
adaModalWidth(dialogWidth);
await getMemberOption();
});
</script>
<style lang="less" scoped></style>