Notice 第二阶段
This commit is contained in:
@@ -72,5 +72,10 @@ namespace Ewide.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Comment("状态")]
|
[Comment("状态")]
|
||||||
public int Status { get; set; }
|
public int Status { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 上传文件ids
|
||||||
|
/// </summary>
|
||||||
|
[Comment("上传文件id集合")]
|
||||||
|
public string Attachments { set; get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1223,6 +1223,11 @@
|
|||||||
状态(字典 0草稿 1发布 2撤回 3删除)
|
状态(字典 0草稿 1发布 2撤回 3删除)
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="P:Ewide.Core.SysNotice.Attachments">
|
||||||
|
<summary>
|
||||||
|
上传文件ids
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="T:Ewide.Core.SysNoticeUser">
|
<member name="T:Ewide.Core.SysNoticeUser">
|
||||||
<summary>
|
<summary>
|
||||||
通知公告用户表
|
通知公告用户表
|
||||||
@@ -5332,6 +5337,11 @@
|
|||||||
通知公告参数
|
通知公告参数
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="P:Ewide.Core.Service.NoticeBase.Id">
|
||||||
|
<summary>
|
||||||
|
ID
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="P:Ewide.Core.Service.NoticeBase.Title">
|
<member name="P:Ewide.Core.Service.NoticeBase.Title">
|
||||||
<summary>
|
<summary>
|
||||||
标题
|
标题
|
||||||
@@ -5397,6 +5407,11 @@
|
|||||||
通知到的用户阅读信息集合
|
通知到的用户阅读信息集合
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="P:Ewide.Core.Service.NoticeDetailOutput.Attachments">
|
||||||
|
<summary>
|
||||||
|
上传文件Id集合
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="P:Ewide.Core.Service.NoticeUserRead.UserId">
|
<member name="P:Ewide.Core.Service.NoticeUserRead.UserId">
|
||||||
<summary>
|
<summary>
|
||||||
用户Id
|
用户Id
|
||||||
@@ -5472,6 +5487,11 @@
|
|||||||
通知到的人
|
通知到的人
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="P:Ewide.Core.Service.AddNoticeInput.Attachments">
|
||||||
|
<summary>
|
||||||
|
上传文件集合
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="P:Ewide.Core.Service.DeleteNoticeInput.Id">
|
<member name="P:Ewide.Core.Service.DeleteNoticeInput.Id">
|
||||||
<summary>
|
<summary>
|
||||||
Id
|
Id
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ namespace Ewide.Core.Service
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class NoticeBase
|
public class NoticeBase
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// ID
|
||||||
|
/// </summary>
|
||||||
|
public string Id { set; get; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 标题
|
/// 标题
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ namespace Ewide.Core.Service
|
|||||||
/// 通知到的用户阅读信息集合
|
/// 通知到的用户阅读信息集合
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<NoticeUserRead> NoticeUserReadInfoList { get; set; }
|
public List<NoticeUserRead> NoticeUserReadInfoList { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上传文件Id集合
|
||||||
|
/// </summary>
|
||||||
|
public string Attachments { set; get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NoticeUserRead
|
public class NoticeUserRead
|
||||||
|
|||||||
@@ -65,6 +65,11 @@ namespace Ewide.Core.Service
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Required(ErrorMessage = "通知到的人不能为空")]
|
[Required(ErrorMessage = "通知到的人不能为空")]
|
||||||
public override List<string> NoticeUserIdList { get; set; }
|
public override List<string> NoticeUserIdList { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上传文件集合
|
||||||
|
/// </summary>
|
||||||
|
public List<string> Attachments { set; get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DeleteNoticeInput
|
public class DeleteNoticeInput
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ namespace Ewide.Core.Service.Notice
|
|||||||
var notice = input.Adapt<SysNotice>();
|
var notice = input.Adapt<SysNotice>();
|
||||||
var id = System.Guid.NewGuid().ToString().ToLower();
|
var id = System.Guid.NewGuid().ToString().ToLower();
|
||||||
notice.Id = id;
|
notice.Id = id;
|
||||||
|
if (input.Attachments!=null)
|
||||||
|
notice.Attachments = string.Join(",", input.Attachments);
|
||||||
await UpdatePublicInfo(notice);
|
await UpdatePublicInfo(notice);
|
||||||
// 如果是发布,则设置发布时间
|
// 如果是发布,则设置发布时间
|
||||||
if (input.Status == (int)NoticeStatus.PUBLIC)
|
if (input.Status == (int)NoticeStatus.PUBLIC)
|
||||||
@@ -123,12 +125,14 @@ namespace Ewide.Core.Service.Notice
|
|||||||
throw Oops.Oh(ErrorCode.D7002);
|
throw Oops.Oh(ErrorCode.D7002);
|
||||||
|
|
||||||
var notice = input.Adapt<SysNotice>();
|
var notice = input.Adapt<SysNotice>();
|
||||||
|
if (input.Attachments != null)
|
||||||
|
notice.Attachments = string.Join(",", input.Attachments);
|
||||||
if (input.Status == (int)NoticeStatus.PUBLIC)
|
if (input.Status == (int)NoticeStatus.PUBLIC)
|
||||||
{
|
{
|
||||||
notice.PublicTime = DateTime.Now;
|
notice.PublicTime = DateTime.Now;
|
||||||
await UpdatePublicInfo(notice);
|
await UpdatePublicInfo(notice);
|
||||||
}
|
}
|
||||||
await notice.UpdateAsync();
|
await notice.UpdateAsync(true);
|
||||||
|
|
||||||
// 通知到的人
|
// 通知到的人
|
||||||
var noticeUserIdList = input.NoticeUserIdList;
|
var noticeUserIdList = input.NoticeUserIdList;
|
||||||
@@ -212,11 +216,11 @@ namespace Ewide.Core.Service.Notice
|
|||||||
{
|
{
|
||||||
var sql = @"SELECT
|
var sql = @"SELECT
|
||||||
SN.*,
|
SN.*,
|
||||||
SU.Avatar
|
SU.Avatar,SNU.ReadStatus
|
||||||
FROM sys_notice SN
|
FROM sys_notice SN
|
||||||
LEFT JOIN sys_notice_user SNU ON SN.Id = SNU.NoticeId
|
LEFT JOIN sys_notice_user SNU ON SN.Id = SNU.NoticeId
|
||||||
LEFT JOIN sys_user SU ON SN.PublicUserId = SU.Id
|
LEFT JOIN sys_user SU ON SN.PublicUserId = SU.Id
|
||||||
WHERE SNU.UserId = @UserId AND SN.Status <> @Status";
|
WHERE SNU.UserId = @UserId AND SN.Status = @Status";
|
||||||
|
|
||||||
var data = await _dapperRepository.QueryPageDataDynamic(
|
var data = await _dapperRepository.QueryPageDataDynamic(
|
||||||
sql,
|
sql,
|
||||||
@@ -224,11 +228,16 @@ WHERE SNU.UserId = @UserId AND SN.Status <> @Status";
|
|||||||
new
|
new
|
||||||
{
|
{
|
||||||
_userManager.UserId,
|
_userManager.UserId,
|
||||||
Status = (int)NoticeStatus.DELETED
|
Status = (int)NoticeStatus.PUBLIC
|
||||||
|
},
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
"Type","Title"
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
data.Items = data.Items.Select(p => {
|
data.Items = data.Items.Select(p =>
|
||||||
|
{
|
||||||
var r = p.Adapt<dynamic>();
|
var r = p.Adapt<dynamic>();
|
||||||
r.Content = Regex.Replace(r.Content, @"<\/?.+?\/?>", "").Replace("\r\n", "");
|
r.Content = Regex.Replace(r.Content, @"<\/?.+?\/?>", "").Replace("\r\n", "");
|
||||||
return r;
|
return r;
|
||||||
@@ -245,7 +254,8 @@ WHERE SNU.UserId = @UserId AND SN.Status <> @Status";
|
|||||||
[HttpGet("/sysNotice/unread")]
|
[HttpGet("/sysNotice/unread")]
|
||||||
public async Task<int> GetUnreadCount()
|
public async Task<int> GetUnreadCount()
|
||||||
{
|
{
|
||||||
return await _sysNoticeUserRep.Where(u => u.UserId == _userManager.UserId && u.ReadStatus == (int)NoticeUserStatus.UNREAD).CountAsync();
|
var noticeList = await _sysNoticeRep.Where(u => u.Status != (int)NoticeStatus.DELETED).Select(s => s.Id).ToListAsync();
|
||||||
|
return await _sysNoticeUserRep.Where(u => u.UserId == _userManager.UserId && noticeList.Contains(u.NoticeId) && u.ReadStatus == (int)NoticeUserStatus.UNREAD).CountAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Col, Input, InputNumber, Row } from 'antd'
|
|
||||||
import { AntIcon } from 'components'
|
|
||||||
import BraftEditor from 'braft-editor'
|
import BraftEditor from 'braft-editor'
|
||||||
import 'braft-editor/dist/index.css'
|
import 'braft-editor/dist/index.css'
|
||||||
|
|
||||||
export default class index extends Component {
|
export default class index extends Component {
|
||||||
state = {
|
state = {
|
||||||
editorState: BraftEditor.createEditorState(this.props.value), // 设置编辑器初始内容
|
editorState: '',
|
||||||
outputHTML: '',
|
outputHTML: '',
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mount后回调
|
* mount后回调
|
||||||
*/
|
*/
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// 3秒后更改编辑器内容
|
this.isLivinig = true
|
||||||
setTimeout(this.setEditorContentAsync, 2000)
|
this.toParent()
|
||||||
}
|
}
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.isLivinig = false
|
this.isLivinig = false
|
||||||
@@ -33,23 +32,26 @@ export default class index extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setEditorContentAsync = () => {
|
setEditorContentAsync = () => {
|
||||||
const { placeholder, value, onChange } = this.props
|
|
||||||
this.isLivinig &&
|
this.isLivinig &&
|
||||||
this.setState({
|
this.setState({
|
||||||
editorState: BraftEditor.createEditorState(value),
|
editorState: BraftEditor.createEditorState(this.props.value),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
render() {
|
|
||||||
const { editorState, outputHTML } = this.state
|
|
||||||
|
|
||||||
//localStorage.setItem('props', JSON.stringify(this.props))
|
//给父控件 调用这个方法 因为只有父控件才能掌握页面加载完的时间
|
||||||
|
toParent = () => {
|
||||||
|
this.props.parent.getChildrenMsg(this.setEditorContentAsync)
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
const { editorState } = this.state
|
||||||
const controls = ['bold', 'italic', 'underline', 'text-color', 'separator']
|
const controls = ['bold', 'italic', 'underline', 'text-color', 'separator']
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BraftEditor
|
<BraftEditor
|
||||||
value={editorState}
|
value={editorState}
|
||||||
controls={controls}
|
controls={controls}
|
||||||
onChange={this.handleChange}
|
onChange={this.handleChange}
|
||||||
placeholder={'输入内容'}
|
placeholder={'请输入内容'}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Form, Spin, Input, Radio, Select } from 'antd'
|
import { Form, Spin, Input, Radio, Select, Upload, Button } from 'antd'
|
||||||
import { api } from 'common/api'
|
import { api } from 'common/api'
|
||||||
import { AntIcon, BraftEditor } from 'components'
|
import { AntIcon, BraftEditor } from 'components'
|
||||||
import getDictData from 'util/dic'
|
import getDictData from 'util/dic'
|
||||||
|
import { BlobToBase64, GetFileName, PreviewFile } from 'util/file'
|
||||||
import { cloneDeep } from 'lodash'
|
import { cloneDeep } from 'lodash'
|
||||||
// import BraftEditor from 'braft-editor'
|
|
||||||
// import 'braft-editor/dist/index.css'
|
|
||||||
const initialValues = {}
|
const initialValues = {}
|
||||||
|
|
||||||
export default class form extends Component {
|
export default class form extends Component {
|
||||||
@@ -19,6 +19,7 @@ export default class form extends Component {
|
|||||||
noticeType: [],
|
noticeType: [],
|
||||||
noticeStatus: [],
|
noticeStatus: [],
|
||||||
},
|
},
|
||||||
|
funloader: Object,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 表单实例
|
// 表单实例
|
||||||
@@ -32,8 +33,6 @@ export default class form extends Component {
|
|||||||
*/
|
*/
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.created && this.props.created(this)
|
this.props.created && this.props.created(this)
|
||||||
this.isLivinig = true
|
|
||||||
// 3秒后更改编辑器内容
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,6 +42,7 @@ export default class form extends Component {
|
|||||||
* @param {*} params
|
* @param {*} params
|
||||||
*/
|
*/
|
||||||
async fillData(params) {
|
async fillData(params) {
|
||||||
|
this.record = cloneDeep(params.record)
|
||||||
//#region 从后端转换成前段所需格式,也可以在此处调用获取详细数据接口
|
//#region 从后端转换成前段所需格式,也可以在此处调用获取详细数据接口
|
||||||
if (params.id) {
|
if (params.id) {
|
||||||
this.record = (await api.sysNoticeDetail({ id: params.id })).data
|
this.record = (await api.sysNoticeDetail({ id: params.id })).data
|
||||||
@@ -51,6 +51,36 @@ export default class form extends Component {
|
|||||||
data: { items: userList },
|
data: { items: userList },
|
||||||
} = await this.onLoadUser()
|
} = await this.onLoadUser()
|
||||||
const codes = await getDictData('notice_status', 'notice_type')
|
const codes = await getDictData('notice_status', 'notice_type')
|
||||||
|
|
||||||
|
if (this.record) {
|
||||||
|
const { attachments } = this.record
|
||||||
|
if (attachments) {
|
||||||
|
const fileValue = []
|
||||||
|
const fileList = attachments.split(',')
|
||||||
|
for (const fileId of fileList) {
|
||||||
|
try {
|
||||||
|
const file = await PreviewFile(fileId)
|
||||||
|
const base64 = await BlobToBase64(file)
|
||||||
|
fileValue.push({
|
||||||
|
uid: fileId,
|
||||||
|
response: fileId,
|
||||||
|
name: file.name,
|
||||||
|
url: base64,
|
||||||
|
status: 'done',
|
||||||
|
})
|
||||||
|
} catch {
|
||||||
|
const { data: file } = await api.sysFileInfoDetail({ id: fileId })
|
||||||
|
fileValue.push({
|
||||||
|
uid: fileId,
|
||||||
|
response: '文件已丢失',
|
||||||
|
name: file.fileOriginName,
|
||||||
|
status: 'error',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.record.Attachments = fileValue
|
||||||
|
}
|
||||||
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
this.form.current.setFieldsValue(this.record)
|
this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
@@ -61,11 +91,46 @@ export default class form extends Component {
|
|||||||
},
|
},
|
||||||
codes,
|
codes,
|
||||||
})
|
})
|
||||||
|
//加载 BraftEditor 富文本插件
|
||||||
|
this.state.funloader()
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 接受子组件传过来的方法
|
||||||
|
* 等页面加载完毕后调用
|
||||||
|
*/
|
||||||
|
getChildrenMsg = funLoad => {
|
||||||
|
this.setState({
|
||||||
|
funloader: funLoad,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
async onLoadUser() {
|
async onLoadUser() {
|
||||||
const data = await api.getUserPage()
|
const data = await api.getUserPage()
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
async onFileUpload({ file, onProgress, onSuccess, onError }) {
|
||||||
|
onProgress({
|
||||||
|
percent: 0,
|
||||||
|
})
|
||||||
|
const fd = new FormData()
|
||||||
|
fd.append('file', file)
|
||||||
|
try {
|
||||||
|
const { data: fileId } = await api.sysFileInfoUpload(fd)
|
||||||
|
onSuccess(fileId)
|
||||||
|
} catch {
|
||||||
|
onError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async onFileDownload(file) {
|
||||||
|
const { data, headers } = await api.sysFileInfoDownload({ id: file.response })
|
||||||
|
const url = window.URL.createObjectURL(data)
|
||||||
|
const fileName = GetFileName(headers['content-disposition'])
|
||||||
|
const a = document.createElement('a')
|
||||||
|
a.href = url
|
||||||
|
a.download = fileName
|
||||||
|
a.click()
|
||||||
|
window.URL.revokeObjectURL(url)
|
||||||
|
a.remove()
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 获取数据
|
* 获取数据
|
||||||
* 可以对postData进行数据结构调整
|
* 可以对postData进行数据结构调整
|
||||||
@@ -74,14 +139,21 @@ export default class form extends Component {
|
|||||||
*/
|
*/
|
||||||
async getData() {
|
async getData() {
|
||||||
const form = this.form.current
|
const form = this.form.current
|
||||||
|
console.log(this.record)
|
||||||
const valid = await form.validateFields()
|
const valid = await form.validateFields()
|
||||||
if (valid) {
|
if (valid) {
|
||||||
const postData = form.getFieldsValue()
|
const postData = form.getFieldsValue()
|
||||||
if (this.record) {
|
if (this.record) {
|
||||||
postData.id = this.record.id
|
postData.id = this.record.id
|
||||||
|
postData.status = 0
|
||||||
|
} else {
|
||||||
|
postData.status = 1
|
||||||
}
|
}
|
||||||
//#region 从前段转换后端所需格式
|
//#region 从前段转换后端所需格式
|
||||||
|
const { Attachments } = postData
|
||||||
|
for (const key in Attachments) {
|
||||||
|
Attachments[key] = Attachments[key].response
|
||||||
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
return postData
|
return postData
|
||||||
}
|
}
|
||||||
@@ -132,9 +204,33 @@ export default class form extends Component {
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<BraftEditor />
|
<BraftEditor parent={this} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="上传附件"
|
||||||
|
name="Attachments"
|
||||||
|
valuePropName="fileList"
|
||||||
|
getValueFromEvent={e => {
|
||||||
|
if (Array.isArray(e)) {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
return e && e.fileList
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Upload
|
||||||
|
customRequest={e => this.onFileUpload(e)}
|
||||||
|
showUploadList={{
|
||||||
|
showRemoveIcon: true,
|
||||||
|
showDownloadIcon: true,
|
||||||
|
}}
|
||||||
|
onPreview={() => false}
|
||||||
|
onDownload={file => this.onFileDownload(file)}
|
||||||
|
>
|
||||||
|
<Button type="dashed" icon={<AntIcon type="upload" />}>
|
||||||
|
上传附件
|
||||||
|
</Button>
|
||||||
|
</Upload>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item label="通知到的人" name="noticeUserIdList">
|
<Form.Item label="通知到的人" name="noticeUserIdList">
|
||||||
<Select
|
<Select
|
||||||
mode="tags"
|
mode="tags"
|
||||||
|
|||||||
@@ -57,6 +57,19 @@ export default class index extends Component {
|
|||||||
title: '标题',
|
title: '标题',
|
||||||
dataIndex: 'title',
|
dataIndex: 'title',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '发布人',
|
||||||
|
dataIndex: 'publicUserName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '发布时间',
|
||||||
|
dataIndex: 'createdTime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '发布单位',
|
||||||
|
dataIndex: 'publicOrgName',
|
||||||
|
width: 200,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '类型',
|
title: '类型',
|
||||||
dataIndex: 'type',
|
dataIndex: 'type',
|
||||||
@@ -76,7 +89,7 @@ export default class index extends Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
const flag = auth({ [authName]: [['edit'], ['delete']] })
|
const flag = auth({ [authName]: [['edit'], ['goBack'], ['publish'], ['delete']] })
|
||||||
|
|
||||||
if (flag) {
|
if (flag) {
|
||||||
this.columns.push({
|
this.columns.push({
|
||||||
@@ -85,18 +98,55 @@ export default class index extends Component {
|
|||||||
dataIndex: 'actions',
|
dataIndex: 'actions',
|
||||||
render: (text, record) => (
|
render: (text, record) => (
|
||||||
<QueryTableActions>
|
<QueryTableActions>
|
||||||
<Auth auth={{ [authName]: 'edit' }}>
|
{record.status === 1 ? (
|
||||||
<a onClick={() => this.onOpen(this.editForm, record.id)}>编辑</a>
|
<Auth
|
||||||
</Auth>
|
key={this.subUniqueKey(record.id, 1)}
|
||||||
<Auth auth={{ [authName]: 'delete' }}>
|
auth={{ [authName]: 'goBack' }}
|
||||||
<Popconfirm
|
|
||||||
placement="topRight"
|
|
||||||
title="是否确认删除"
|
|
||||||
onConfirm={() => this.onDelete(record.id)}
|
|
||||||
>
|
>
|
||||||
<a>删除</a>
|
<Popconfirm
|
||||||
</Popconfirm>
|
placement="topRight"
|
||||||
</Auth>
|
title="是否确认撤回"
|
||||||
|
onConfirm={() => this.onGoBack(record.id)}
|
||||||
|
>
|
||||||
|
<a>撤回</a>
|
||||||
|
</Popconfirm>
|
||||||
|
</Auth>
|
||||||
|
) : (
|
||||||
|
[
|
||||||
|
<Auth
|
||||||
|
key={this.subUniqueKey(record.id, 2)}
|
||||||
|
auth={{ [authName]: 'edit' }}
|
||||||
|
>
|
||||||
|
<a onClick={() => this.onOpen(this.editForm, record.id)}>
|
||||||
|
编辑
|
||||||
|
</a>
|
||||||
|
</Auth>,
|
||||||
|
<Auth
|
||||||
|
key={this.subUniqueKey(record.id, 3)}
|
||||||
|
auth={{ [authName]: 'publish' }}
|
||||||
|
>
|
||||||
|
<Popconfirm
|
||||||
|
placement="topRight"
|
||||||
|
title="是否确认发布"
|
||||||
|
onConfirm={() => this.onPublish(record.id)}
|
||||||
|
>
|
||||||
|
<a>发布</a>
|
||||||
|
</Popconfirm>
|
||||||
|
</Auth>,
|
||||||
|
<Auth
|
||||||
|
key={this.subUniqueKey(record.id, 4)}
|
||||||
|
auth={{ [authName]: 'delete' }}
|
||||||
|
>
|
||||||
|
<Popconfirm
|
||||||
|
placement="topRight"
|
||||||
|
title="是否确认删除"
|
||||||
|
onConfirm={() => this.onDelete(record.id)}
|
||||||
|
>
|
||||||
|
<a>删除</a>
|
||||||
|
</Popconfirm>
|
||||||
|
</Auth>,
|
||||||
|
]
|
||||||
|
)}
|
||||||
</QueryTableActions>
|
</QueryTableActions>
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
@@ -128,7 +178,9 @@ export default class index extends Component {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
subUniqueKey(text, index) {
|
||||||
|
return text.substr(index, 5)
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 调用加载数据接口,可在调用前对query进行处理
|
* 调用加载数据接口,可在调用前对query进行处理
|
||||||
* [异步,必要]
|
* [异步,必要]
|
||||||
@@ -200,8 +252,22 @@ export default class index extends Component {
|
|||||||
* @param {*} id
|
* @param {*} id
|
||||||
*/
|
*/
|
||||||
onDelete(id) {
|
onDelete(id) {
|
||||||
this.onAction(apiAction.delete({ id }), '删除成功')
|
this.onAction(apiAction.Status({ id, Status: 3 }), '删除成功')
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 发布
|
||||||
|
* @param {*} id
|
||||||
|
*/
|
||||||
|
onPublish(id) {
|
||||||
|
this.onAction(apiAction.Status({ id, Status: 1 }), '发布成功')
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 撤回
|
||||||
|
* @param {*} id
|
||||||
|
*/
|
||||||
|
onGoBack(id) {
|
||||||
|
this.onAction(apiAction.Status({ id, Status: 2 }), '撤回成功')
|
||||||
|
} //
|
||||||
|
|
||||||
//#region 自定义方法
|
//#region 自定义方法
|
||||||
//#endregion
|
//#endregion
|
||||||
@@ -214,6 +280,7 @@ export default class index extends Component {
|
|||||||
<Card bordered={false}>
|
<Card bordered={false}>
|
||||||
<QueryTable
|
<QueryTable
|
||||||
ref={this.table}
|
ref={this.table}
|
||||||
|
rowkey={record => record.id}
|
||||||
autoLoad={false}
|
autoLoad={false}
|
||||||
loadData={this.loadData}
|
loadData={this.loadData}
|
||||||
columns={this.columns}
|
columns={this.columns}
|
||||||
@@ -223,11 +290,11 @@ export default class index extends Component {
|
|||||||
<Input
|
<Input
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
placeholder="请输入标题、内容"
|
placeholder="请输入标题、内容"
|
||||||
className="w-400"
|
className="w-200"
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="类型" name="type">
|
<Form.Item label="类型" name="type">
|
||||||
<Select placeholder="请选择类型" className="w-400" allowClear>
|
<Select placeholder="请选择类型" className="w-200" allowClear>
|
||||||
{codes.noticeType.map(item => (
|
{codes.noticeType.map(item => (
|
||||||
<Select.Option key={item.code} value={item.code}>
|
<Select.Option key={item.code} value={item.code}>
|
||||||
{item.value}
|
{item.value}
|
||||||
@@ -238,7 +305,7 @@ export default class index extends Component {
|
|||||||
</Auth>
|
</Auth>
|
||||||
}
|
}
|
||||||
operator={
|
operator={
|
||||||
<Auth auth={{ [authName]: 'add' }}>
|
<Auth key={record => record.id} auth={{ [authName]: 'add' }}>
|
||||||
<Button
|
<Button
|
||||||
icon={<AntIcon type="plus" />}
|
icon={<AntIcon type="plus" />}
|
||||||
onClick={() => this.onOpen(this.addForm)}
|
onClick={() => this.onOpen(this.addForm)}
|
||||||
@@ -255,6 +322,25 @@ export default class index extends Component {
|
|||||||
title={`新增${name}`}
|
title={`新增${name}`}
|
||||||
width={800}
|
width={800}
|
||||||
action={apiAction.add}
|
action={apiAction.add}
|
||||||
|
buttons={[
|
||||||
|
{
|
||||||
|
index: 1,
|
||||||
|
button: (getData, close) => (
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
key="111"
|
||||||
|
onClick={async () => {
|
||||||
|
const data = await getData()
|
||||||
|
data.status = 0 //草稿状态
|
||||||
|
this.onAction(api.sysNoticeAdd(data))
|
||||||
|
close()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
保存草稿
|
||||||
|
</Button>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
ref={this.addForm}
|
ref={this.addForm}
|
||||||
onSuccess={() => this.table.current.onReloadData()}
|
onSuccess={() => this.table.current.onReloadData()}
|
||||||
>
|
>
|
||||||
|
|||||||
54
web-react/src/pages/system/noticeReceived/form.jsx
Normal file
54
web-react/src/pages/system/noticeReceived/form.jsx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Spin, Divider, Modal, Row } from 'antd'
|
||||||
|
import { api } from 'common/api'
|
||||||
|
import { AntIcon } from 'components'
|
||||||
|
|
||||||
|
export default class form extends Component {
|
||||||
|
state = {
|
||||||
|
detailVisible: false,
|
||||||
|
detailLoading: false,
|
||||||
|
detailData: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mount后回调
|
||||||
|
*/
|
||||||
|
componentDidMount() {
|
||||||
|
this.props.created && this.props.created(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
async onOpenDetail(id) {
|
||||||
|
this.setState({ detailLoading: true, detailVisible: true })
|
||||||
|
const { data } = await api.sysNoticeDetail({ id })
|
||||||
|
this.setState({
|
||||||
|
detailLoading: false,
|
||||||
|
detailData: data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { detailLoading, detailVisible, detailData } = this.state
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
width={1000}
|
||||||
|
footer={false}
|
||||||
|
visible={detailVisible}
|
||||||
|
onCancel={() => this.setState({ detailVisible: false, detailData: {} })}
|
||||||
|
>
|
||||||
|
<Spin spinning={detailLoading} indicator={<AntIcon type="loading" />}>
|
||||||
|
<div className="h3 mt-lg">{detailData.title}</div>
|
||||||
|
<Divider />
|
||||||
|
<div
|
||||||
|
className="pt-lg pb-lg"
|
||||||
|
dangerouslySetInnerHTML={{ __html: detailData.content }}
|
||||||
|
></div>
|
||||||
|
<Divider />
|
||||||
|
<Row justify="space-between" className="text-gray">
|
||||||
|
<span>发布人:{detailData.publicUserName}</span>
|
||||||
|
<span>发布时间:{detailData.publicTime} </span>
|
||||||
|
</Row>
|
||||||
|
</Spin>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
211
web-react/src/pages/system/noticeReceived/index.jsx
Normal file
211
web-react/src/pages/system/noticeReceived/index.jsx
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Card, Form, message as Message, Input, Select } from 'antd'
|
||||||
|
import { Auth, Container, QueryTable } from 'components'
|
||||||
|
import { api } from 'common/api'
|
||||||
|
import auth from 'components/authorized/handler'
|
||||||
|
import { isEqual } from 'lodash'
|
||||||
|
import getDictData from 'util/dic'
|
||||||
|
import { toCamelCase } from 'util/format'
|
||||||
|
import FormBody from './form'
|
||||||
|
import { getSearchInfo, QueryType } from 'util/query'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一配置权限标识
|
||||||
|
* [必要]
|
||||||
|
*/
|
||||||
|
const authName = '/**/'
|
||||||
|
|
||||||
|
export default class index extends Component {
|
||||||
|
state = {
|
||||||
|
codes: {
|
||||||
|
noticeStatus: [],
|
||||||
|
noticeType: [],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表格实例
|
||||||
|
table = React.createRef()
|
||||||
|
|
||||||
|
// 编辑窗口实例
|
||||||
|
editForm = React.createRef()
|
||||||
|
|
||||||
|
columns = [
|
||||||
|
{
|
||||||
|
title: '标题',
|
||||||
|
dataIndex: 'title',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '发布人',
|
||||||
|
dataIndex: 'publicUserName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '发布时间',
|
||||||
|
dataIndex: 'createdTime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '发布单位',
|
||||||
|
dataIndex: 'publicOrgName',
|
||||||
|
width: 200,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '类型',
|
||||||
|
dataIndex: 'type',
|
||||||
|
render: text => this.bindCodeValue(text, 'notice_type'),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造函数,在渲染前动态添加操作字段等
|
||||||
|
* @param {*} props
|
||||||
|
*/
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
const flag = auth({ [authName]: [['show']] })
|
||||||
|
if (flag) {
|
||||||
|
this.columns.push({
|
||||||
|
title: '操作',
|
||||||
|
width: 150,
|
||||||
|
dataIndex: 'actions',
|
||||||
|
render: (text, record) => (
|
||||||
|
<Auth auth={{ [authName]: 'show' }}>
|
||||||
|
<a onClick={() => this.onOpen(this.editForm, record.id)}>查看</a>
|
||||||
|
</Auth>
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止外部组件引发的渲染,提升性能
|
||||||
|
* 可自行添加渲染条件
|
||||||
|
* [必要]
|
||||||
|
* @param {*} props
|
||||||
|
* @param {*} state
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载字典数据,之后开始加载表格数据
|
||||||
|
* 如果必须要加载字典数据,可直接对表格设置autoLoad=true
|
||||||
|
*/
|
||||||
|
componentDidMount() {
|
||||||
|
const { onLoading, onLoadData } = this.table.current
|
||||||
|
onLoading()
|
||||||
|
getDictData('notice_status', 'notice_type').then(codes => {
|
||||||
|
this.setState({ codes }, () => {
|
||||||
|
onLoadData()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 对表格上的操作进行统一处理
|
||||||
|
* [异步]
|
||||||
|
* @param {*} action
|
||||||
|
* @param {*} successMessage
|
||||||
|
*/
|
||||||
|
async onAction(action, successMessage) {
|
||||||
|
const { onLoading, onLoaded, onReloadData } = this.table.current
|
||||||
|
onLoading()
|
||||||
|
try {
|
||||||
|
if (action) {
|
||||||
|
await action
|
||||||
|
}
|
||||||
|
if (successMessage) {
|
||||||
|
Message.success(successMessage)
|
||||||
|
}
|
||||||
|
onReloadData()
|
||||||
|
} catch {
|
||||||
|
onLoaded()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 调用加载数据接口,可在调用前对query进行处理
|
||||||
|
* [异步,必要]
|
||||||
|
* @param {*} params
|
||||||
|
* @param {*} query
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
loadData = async (params, query) => {
|
||||||
|
const searchInfo = getSearchInfo({
|
||||||
|
query,
|
||||||
|
queryType: {
|
||||||
|
type: QueryType.Equal,
|
||||||
|
title: QueryType.Like,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data } = await api.sysNoticeReceived({
|
||||||
|
...params,
|
||||||
|
searchInfo,
|
||||||
|
})
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定字典数据
|
||||||
|
* @param {*} code
|
||||||
|
* @param {*} name
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
bindCodeValue(code, name) {
|
||||||
|
name = toCamelCase(name)
|
||||||
|
const codes = this.state.codes[name]
|
||||||
|
if (codes) {
|
||||||
|
const c = codes.find(p => p.code == code)
|
||||||
|
if (c) {
|
||||||
|
return c.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开新增/编辑弹窗
|
||||||
|
* @param {*} modal
|
||||||
|
* @param {*} id
|
||||||
|
*/
|
||||||
|
onOpen(modal, id) {
|
||||||
|
modal.current.onOpenDetail(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { codes } = this.state
|
||||||
|
return (
|
||||||
|
<Container mode="fluid">
|
||||||
|
<br />
|
||||||
|
<Card bordered={false}>
|
||||||
|
<QueryTable
|
||||||
|
ref={this.table}
|
||||||
|
autoLoad={false}
|
||||||
|
loadData={this.loadData}
|
||||||
|
columns={this.columns}
|
||||||
|
query={
|
||||||
|
<Auth auth={{ [authName]: 'page' }}>
|
||||||
|
<Form.Item label="关键字" name="title">
|
||||||
|
<Input
|
||||||
|
autoComplete="off"
|
||||||
|
placeholder="请输入标题"
|
||||||
|
className="w-200"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="类型" name="type">
|
||||||
|
<Select placeholder="请选择类型" className="w-200" allowClear>
|
||||||
|
{codes.noticeType.map(item => (
|
||||||
|
<Select.Option key={item.code} value={item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
</Auth>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
<FormBody ref={this.editForm} />
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user