Merge branch 'master' of http://118.178.224.202:3000/ewide/ewide_core
This commit is contained in:
@@ -7189,6 +7189,13 @@
|
|||||||
检验验证码并且绑定
|
检验验证码并且绑定
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:Ewide.Core.Service.SysUserService.GetPwdRule">
|
||||||
|
<summary>
|
||||||
|
获取密码强度配置
|
||||||
|
</summary>
|
||||||
|
<param name="input"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="F:Ewide.Core.Util.CodeHelper.code_Countdown">
|
<member name="F:Ewide.Core.Util.CodeHelper.code_Countdown">
|
||||||
<summary>
|
<summary>
|
||||||
发送验证码间隔时间(秒)
|
发送验证码间隔时间(秒)
|
||||||
@@ -7271,6 +7278,13 @@
|
|||||||
<param name="length"></param>
|
<param name="length"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:Ewide.Core.Util.CodeHelper.CheckRepeat(System.String)">
|
||||||
|
<summary>
|
||||||
|
检测是否重复
|
||||||
|
</summary>
|
||||||
|
<param name="Target"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:Ewide.Core.Util.MailHelper.#ctor(System.String,System.String)">
|
<member name="M:Ewide.Core.Util.MailHelper.#ctor(System.String,System.String)">
|
||||||
<summary>
|
<summary>
|
||||||
邮箱类
|
邮箱类
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ namespace Ewide.Core.Extension.DataFilter.Entity
|
|||||||
/// <param name="filterFields"></param>
|
/// <param name="filterFields"></param>
|
||||||
public void SetSearchInfo(SearchInfo[] searchInfo, IEnumerable<string> filterFields)
|
public void SetSearchInfo(SearchInfo[] searchInfo, IEnumerable<string> filterFields)
|
||||||
{
|
{
|
||||||
|
if (searchInfo == null) return;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
foreach (var elem in searchInfo)
|
foreach (var elem in searchInfo)
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ WHERE SNU.UserId = @UserId AND SN.Status = @Status";
|
|||||||
},
|
},
|
||||||
new[]
|
new[]
|
||||||
{
|
{
|
||||||
"Type","Title"
|
"Type","Title","ReadStatus"
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -254,8 +254,10 @@ WHERE SNU.UserId = @UserId AND SN.Status = @Status";
|
|||||||
[HttpGet("/sysNotice/unread")]
|
[HttpGet("/sysNotice/unread")]
|
||||||
public async Task<int> GetUnreadCount()
|
public async Task<int> GetUnreadCount()
|
||||||
{
|
{
|
||||||
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();
|
var noticeList = await _sysNoticeRep.Where(u => u.Status != (int)NoticeStatus.DELETED&& u.Status != (int)NoticeStatus.DRAFT).Select(s => s.Id).ToListAsync();
|
||||||
|
var noticeUserList = await _sysNoticeUserRep.Where(u => u.UserId == _userManager.UserId && noticeList.Contains(u.NoticeId) && u.ReadStatus == (int)NoticeUserStatus.UNREAD).ToListAsync();
|
||||||
|
return noticeUserList.Count();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -128,7 +128,6 @@ namespace Ewide.Core.Service
|
|||||||
/// 新密码
|
/// 新密码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required(ErrorMessage = "新密码不能为空")]
|
[Required(ErrorMessage = "新密码不能为空")]
|
||||||
[StringLength(32, MinimumLength = 5, ErrorMessage = "密码需要大于5个字符")]
|
|
||||||
public string NewPassword { get; set; }
|
public string NewPassword { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace Ewide.Core.Service
|
|||||||
|
|
||||||
Task<dynamic> SendCode(Usermailphone input);
|
Task<dynamic> SendCode(Usermailphone input);
|
||||||
Task<dynamic> CheckBindcode(Usermailphone input);
|
Task<dynamic> CheckBindcode(Usermailphone input);
|
||||||
|
Task<dynamic> GetPwdRule();
|
||||||
Task<dynamic> GetOrgUserTree(OrgUserInput input);
|
Task<dynamic> GetOrgUserTree(OrgUserInput input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using Ewide.Core.Service.Role;
|
using Ewide.Core.Service.Role;
|
||||||
using Ewide.Core.Service.User.Dto;
|
using Ewide.Core.Service.User.Dto;
|
||||||
using Ewide.Core.Util;
|
using Ewide.Core.Util;
|
||||||
|
using Furion;
|
||||||
using Furion.DatabaseAccessor;
|
using Furion.DatabaseAccessor;
|
||||||
using Furion.DatabaseAccessor.Extensions;
|
using Furion.DatabaseAccessor.Extensions;
|
||||||
using Furion.DataEncryption;
|
using Furion.DataEncryption;
|
||||||
@@ -312,11 +313,26 @@ namespace Ewide.Core.Service
|
|||||||
public async Task UpdateUserPwd(ChangePasswordUserInput input)
|
public async Task UpdateUserPwd(ChangePasswordUserInput input)
|
||||||
{
|
{
|
||||||
var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == _userManager.UserId);
|
var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == _userManager.UserId);
|
||||||
if (MD5Encryption.Encrypt(input.Password) != user.Password)
|
var Password = RSAHandler.RSADecrypt(input.Password);
|
||||||
throw Oops.Oh(ErrorCode.D1004);
|
Password = MD5Encryption.Encrypt(Password);
|
||||||
if (MD5Encryption.Encrypt(input.NewPassword).Equals(user.Password))
|
if (Password != user.Password)
|
||||||
|
{
|
||||||
|
throw Oops.Oh("旧密码不正确");
|
||||||
|
}
|
||||||
|
var newPassword = RSAHandler.RSADecrypt(input.NewPassword);
|
||||||
|
// 验证新密码强度
|
||||||
|
var pattern = App.Configuration.GetSection("SimplePassword:Pattern").Value;
|
||||||
|
if (!Regex.Match(newPassword, pattern).Success)
|
||||||
|
{
|
||||||
|
throw Oops.Oh("新密码强度不符合规则");
|
||||||
|
}
|
||||||
|
|
||||||
|
newPassword = MD5Encryption.Encrypt(newPassword);
|
||||||
|
if (newPassword.Equals(user.Password))
|
||||||
throw Oops.Oh(ErrorCode.D10041);
|
throw Oops.Oh(ErrorCode.D10041);
|
||||||
user.Password = MD5Encryption.Encrypt(input.NewPassword);
|
|
||||||
|
user.Password = newPassword;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -467,7 +483,7 @@ namespace Ewide.Core.Service
|
|||||||
var Mailcode_Key = "ewide_mailcode";
|
var Mailcode_Key = "ewide_mailcode";
|
||||||
var Regex_phone = @"^((13[0-9])|(14[5,7])|(15[^4,\\D])|(17[0,1,3,6-8])|(18[0-9])|(19[8,9])|(166))[0-9]{8}$";
|
var Regex_phone = @"^((13[0-9])|(14[5,7])|(15[^4,\\D])|(17[0,1,3,6-8])|(18[0-9])|(19[8,9])|(166))[0-9]{8}$";
|
||||||
var Regex_Email = @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$";
|
var Regex_Email = @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$";
|
||||||
CodeHelper ch = new CodeHelper(_iMemoryCache);
|
CodeHelper ch = new CodeHelper(_iMemoryCache, _sysUserRep, _userManager);
|
||||||
//Type为1时,给原手机号发送验证码
|
//Type为1时,给原手机号发送验证码
|
||||||
if (input.Type == 1)
|
if (input.Type == 1)
|
||||||
{
|
{
|
||||||
@@ -484,7 +500,7 @@ namespace Ewide.Core.Service
|
|||||||
//Type为2时,给原邮箱发送验证码
|
//Type为2时,给原邮箱发送验证码
|
||||||
else if (input.Type == 2)
|
else if (input.Type == 2)
|
||||||
{
|
{
|
||||||
if (new Regex(@"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$").IsMatch(_userManager.User.Email))
|
if (new Regex(Regex_Email).IsMatch(_userManager.User.Email))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -500,6 +516,7 @@ namespace Ewide.Core.Service
|
|||||||
//Type为null时,则发验证码
|
//Type为null时,则发验证码
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
await ch.CheckRepeat(input.Target);
|
||||||
//通过正则判断绑定类型
|
//通过正则判断绑定类型
|
||||||
if (new Regex(Regex_phone).IsMatch(input.Target))
|
if (new Regex(Regex_phone).IsMatch(input.Target))
|
||||||
{
|
{
|
||||||
@@ -542,7 +559,7 @@ namespace Ewide.Core.Service
|
|||||||
var Regex_phone = @"^((13[0-9])|(14[5,7])|(15[^4,\\D])|(17[0,1,3,6-8])|(18[0-9])|(19[8,9])|(166))[0-9]{8}$";
|
var Regex_phone = @"^((13[0-9])|(14[5,7])|(15[^4,\\D])|(17[0,1,3,6-8])|(18[0-9])|(19[8,9])|(166))[0-9]{8}$";
|
||||||
var Regex_Email = @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$";
|
var Regex_Email = @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$";
|
||||||
var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == _userManager.UserId);
|
var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == _userManager.UserId);
|
||||||
CodeHelper ch = new CodeHelper(_iMemoryCache);
|
CodeHelper ch = new CodeHelper(_iMemoryCache, _sysUserRep,_userManager);
|
||||||
if (input.Type == 1)
|
if (input.Type == 1)
|
||||||
{
|
{
|
||||||
if (ch.Checkcode(_userManager.User.Phone, input.Orgcode, Orgcode_Key))
|
if (ch.Checkcode(_userManager.User.Phone, input.Orgcode, Orgcode_Key))
|
||||||
@@ -655,6 +672,23 @@ namespace Ewide.Core.Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取密码强度配置
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("/sysUser/getPwdRule")]
|
||||||
|
public async Task<dynamic> GetPwdRule()
|
||||||
|
{
|
||||||
|
return new LoginOutput
|
||||||
|
{
|
||||||
|
Pattern = App.Configuration.GetSection("SimplePassword:Pattern").Value,
|
||||||
|
Descriptions = App.Configuration.GetSection("SimplePassword:Descriptions").Value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[HttpPost("/sysUser/GetOrgUserTree")]
|
[HttpPost("/sysUser/GetOrgUserTree")]
|
||||||
public async Task<dynamic> GetOrgUserTree(OrgUserInput input)
|
public async Task<dynamic> GetOrgUserTree(OrgUserInput input)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
using Aliyun.Acs.Core.Exceptions;
|
using Aliyun.Acs.Core.Exceptions;
|
||||||
using Aliyun.Acs.Core.Profile;
|
using Aliyun.Acs.Core.Profile;
|
||||||
using Furion;
|
using Furion;
|
||||||
|
using Furion.DatabaseAccessor;
|
||||||
using Furion.FriendlyException;
|
using Furion.FriendlyException;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
@@ -19,9 +21,17 @@ namespace Ewide.Core.Util
|
|||||||
public class CodeHelper
|
public class CodeHelper
|
||||||
{
|
{
|
||||||
private readonly IMemoryCache _IMemoryCache;
|
private readonly IMemoryCache _IMemoryCache;
|
||||||
public CodeHelper(IMemoryCache IMemoryCache)
|
private readonly IRepository<SysUser> _sysUserRep; // 用户表仓储
|
||||||
{
|
private readonly IUserManager _userManager;
|
||||||
|
|
||||||
|
public CodeHelper(
|
||||||
|
IMemoryCache IMemoryCache,
|
||||||
|
IRepository<SysUser> sysUserRep,
|
||||||
|
IUserManager userManager
|
||||||
|
){
|
||||||
_IMemoryCache = IMemoryCache;
|
_IMemoryCache = IMemoryCache;
|
||||||
|
_sysUserRep = sysUserRep;
|
||||||
|
_userManager = userManager;
|
||||||
}
|
}
|
||||||
public static string Aliyun_AccessKey = App.Configuration["SmsHelper:Aliyun_AccessKey"];
|
public static string Aliyun_AccessKey = App.Configuration["SmsHelper:Aliyun_AccessKey"];
|
||||||
public static string Aliyun_AccessSecret = App.Configuration["SmsHelper:Aliyun_AccessSecret"];
|
public static string Aliyun_AccessSecret = App.Configuration["SmsHelper:Aliyun_AccessSecret"];
|
||||||
@@ -247,6 +257,24 @@ namespace Ewide.Core.Util
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检测是否重复
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Target"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<bool> CheckRepeat(string Target)
|
||||||
|
{
|
||||||
|
var Regex_phone = @"^((13[0-9])|(14[5,7])|(15[^4,\\D])|(17[0,1,3,6-8])|(18[0-9])|(19[8,9])|(166))[0-9]{8}$";
|
||||||
|
var Regex_Email = @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$";
|
||||||
|
if(new Regex(Regex_phone).IsMatch(Target)){
|
||||||
|
var isExist = await _sysUserRep.DetachedEntities.AnyAsync(u => (u.Id != _userManager.UserId ) && (u.Account == Target || u.Phone == Target));
|
||||||
|
if (isExist) throw Oops.Oh("手机号与他人账号或者手机号重复");
|
||||||
|
}else if(new Regex(Regex_Email).IsMatch(Target))
|
||||||
|
{
|
||||||
|
var isExist3 = await _sysUserRep.DetachedEntities.AnyAsync(u => (u.Id != _userManager.UserId) && (u.Account == Target || u.Email == Target));
|
||||||
|
if (isExist3) throw Oops.Oh("邮箱与他人账号或者邮箱重复");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,6 +85,11 @@ const urls = {
|
|||||||
*/
|
*/
|
||||||
sysUserCheckBindcode: ['/sysUser/checkBindcode', 'post'],
|
sysUserCheckBindcode: ['/sysUser/checkBindcode', 'post'],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取密码验证配置
|
||||||
|
*/
|
||||||
|
getPwdRule: ['/sysUser/getPwdRule', 'post'],
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default urls
|
export default urls
|
||||||
@@ -78,7 +78,15 @@ export default class base extends Component {
|
|||||||
<Descriptions.Item label="用户名">{user.name}</Descriptions.Item>
|
<Descriptions.Item label="用户名">{user.name}</Descriptions.Item>
|
||||||
<Descriptions.Item label="昵称">{user.nickName}</Descriptions.Item>
|
<Descriptions.Item label="昵称">{user.nickName}</Descriptions.Item>
|
||||||
<Descriptions.Item label="帐号">{user.account}</Descriptions.Item>
|
<Descriptions.Item label="帐号">{user.account}</Descriptions.Item>
|
||||||
<Descriptions.Item label="性别">{user.sex}</Descriptions.Item>
|
<Descriptions.Item label="性别">
|
||||||
|
{user.sex === 0
|
||||||
|
? '保密'
|
||||||
|
: user.sex === 1
|
||||||
|
? '男性'
|
||||||
|
: user.sex === 2
|
||||||
|
? '女性'
|
||||||
|
: '保密'}
|
||||||
|
</Descriptions.Item>
|
||||||
<Descriptions.Item label="生日">
|
<Descriptions.Item label="生日">
|
||||||
{user.birthday &&
|
{user.birthday &&
|
||||||
(typeof user.birthday === 'string'
|
(typeof user.birthday === 'string'
|
||||||
|
|||||||
@@ -115,9 +115,9 @@ export default class form extends Component {
|
|||||||
</List.Item>
|
</List.Item>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<ModalForm title={`更新密码`} action={apiAction.updatePwd} ref={this.updatePwdForm}>
|
{/* <ModalForm title={`更新密码`} action={apiAction.updatePwd} ref={this.updatePwdForm}> */}
|
||||||
<PasswordForm loadData={loadData} />
|
<PasswordForm ref={this.updatePwdForm} loadData={loadData} />
|
||||||
</ModalForm>
|
{/* </ModalForm> */}
|
||||||
<Phone ref={this.mhoneForm} loadData={loadData} />
|
<Phone ref={this.mhoneForm} loadData={loadData} />
|
||||||
<Mail ref={this.mailForm} loadData={loadData} />
|
<Mail ref={this.mailForm} loadData={loadData} />
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ export default class form extends Component {
|
|||||||
const data = form.getFieldsValue()
|
const data = form.getFieldsValue()
|
||||||
try {
|
try {
|
||||||
await api.sysUserSendCode(data)
|
await api.sysUserSendCode(data)
|
||||||
const typeName = data.type ? [, '手机', '邮箱'][data.type] : '手机'
|
const typeName = data.type ? [, '手机', '邮箱'][data.type] : '邮箱'
|
||||||
Message.success(`已发送验证码到${typeName},请注意查收`)
|
Message.success(`已发送验证码到${typeName},请注意查收`)
|
||||||
this.addTime()
|
this.addTime()
|
||||||
this.showCountDown()
|
this.showCountDown()
|
||||||
|
|||||||
@@ -1,24 +1,68 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Form, Input } from 'antd'
|
import { Form, Input, message as Message, Modal } from 'antd'
|
||||||
|
import { api } from 'common/api'
|
||||||
|
import { RSA_PUBLIC_KEY } from 'util/global'
|
||||||
|
import { cloneDeep } from 'lodash'
|
||||||
|
import { Button } from 'antd/lib/radio'
|
||||||
|
import { encryptByRSA } from 'util/rsa'
|
||||||
|
|
||||||
|
const initData = {
|
||||||
|
exist: false,
|
||||||
|
pattern: '',
|
||||||
|
descriptions: '',
|
||||||
|
visible: false,
|
||||||
|
}
|
||||||
|
|
||||||
export default class form extends Component {
|
export default class form extends Component {
|
||||||
state = {
|
state = cloneDeep(initData)
|
||||||
// 加载状态
|
|
||||||
exist: false,
|
|
||||||
}
|
|
||||||
// 表单实例
|
// 表单实例
|
||||||
form = React.createRef()
|
form = React.createRef()
|
||||||
|
|
||||||
// 初始化数据
|
// 初始化数据
|
||||||
record = {}
|
record = {}
|
||||||
|
|
||||||
|
open = () => {
|
||||||
|
this.setState({ visible: true })
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mount后回调
|
* mount后回调
|
||||||
*/
|
*/
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.created && this.props.created(this)
|
this.props.created && this.props.created(this)
|
||||||
|
api.getPwdRule({}).then(({ success, data, message }) => {
|
||||||
|
if (success) {
|
||||||
|
const { pattern, descriptions } = data
|
||||||
|
this.setState({
|
||||||
|
pattern,
|
||||||
|
descriptions,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Message.Error(message)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updatePwd(values) {
|
||||||
|
let { password, newPassword } = values.current.getFieldsValue()
|
||||||
|
password = encryptByRSA(password, RSA_PUBLIC_KEY)
|
||||||
|
newPassword = encryptByRSA(newPassword, RSA_PUBLIC_KEY)
|
||||||
|
const confirm = newPassword
|
||||||
|
api.sysUserUpdatePwd({ password, newPassword, confirm }).then(
|
||||||
|
({ success, data, message }) => {
|
||||||
|
if (success) {
|
||||||
|
Message.success('密码修改完成')
|
||||||
|
this.close()
|
||||||
|
} else {
|
||||||
|
Message.warn(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.setState(cloneDeep(initData))
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 填充数据
|
* 填充数据
|
||||||
* 可以在设置this.record之后对其作出数据结构调整
|
* 可以在设置this.record之后对其作出数据结构调整
|
||||||
@@ -46,42 +90,56 @@ export default class form extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { pattern, descriptions, visible } = this.state
|
||||||
return (
|
return (
|
||||||
<Form className="yo-form" ref={this.form}>
|
<Modal
|
||||||
<div className="yo-form-group">
|
destroyOnClose
|
||||||
<Form.Item
|
onCancel={() => this.close()}
|
||||||
label="旧密码"
|
onOk={() => this.updatePwd(this.form)}
|
||||||
rules={[{ required: true, message: '请输入旧密码' }]}
|
visible={visible}
|
||||||
name="password"
|
className="yo-modal-form"
|
||||||
>
|
title="更新密码"
|
||||||
<Input.Password autoComplete="off" placeholder="请输入旧密码" />
|
>
|
||||||
</Form.Item>
|
<Form className="yo-form" ref={this.form}>
|
||||||
<Form.Item
|
<div className="yo-form-group">
|
||||||
label="新密码"
|
<Form.Item
|
||||||
rules={[{ required: true, message: '请输入新密码' }]}
|
label="旧密码"
|
||||||
name="newPassword"
|
rules={[{ required: true, message: '请输入旧密码' }]}
|
||||||
>
|
name="password"
|
||||||
<Input.Password autoComplete="off" placeholder="请输入新密码" />
|
>
|
||||||
</Form.Item>
|
<Input.Password autoComplete="off" placeholder="请输入旧密码" />
|
||||||
<Form.Item
|
</Form.Item>
|
||||||
label="确认新密码"
|
<Form.Item
|
||||||
rules={[
|
label="新密码"
|
||||||
{ required: true, message: '请确认新密码' },
|
rules={[
|
||||||
({ getFieldValue }) => ({
|
{ required: true, message: '请输入新密码' },
|
||||||
validator(_, value) {
|
{ pattern, message: '密码格式错误' },
|
||||||
if (!value || getFieldValue('newPassword') === value) {
|
]}
|
||||||
return Promise.resolve()
|
name="newPassword"
|
||||||
}
|
tooltip={descriptions}
|
||||||
return Promise.reject(new Error('确认新密码不匹配'))
|
>
|
||||||
},
|
<Input.Password autoComplete="off" placeholder="请输入新密码" />
|
||||||
}),
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
name="confirm"
|
label="确认新密码"
|
||||||
>
|
rules={[
|
||||||
<Input.Password autoComplete="off" placeholder="请确认新密码" />
|
{ required: true, message: '请确认新密码' },
|
||||||
</Form.Item>
|
({ getFieldValue }) => ({
|
||||||
</div>
|
validator(_, value) {
|
||||||
</Form>
|
if (!value || getFieldValue('newPassword') === value) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error('确认新密码不匹配'))
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
]}
|
||||||
|
name="confirm"
|
||||||
|
>
|
||||||
|
<Input.Password autoComplete="off" placeholder="请确认新密码" />
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,7 +139,6 @@ 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()
|
||||||
|
|||||||
@@ -56,28 +56,38 @@ export default class index extends Component {
|
|||||||
{
|
{
|
||||||
title: '标题',
|
title: '标题',
|
||||||
dataIndex: 'title',
|
dataIndex: 'title',
|
||||||
|
width: 300,
|
||||||
|
sorter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '发布人',
|
title: '发布人',
|
||||||
dataIndex: 'publicUserName',
|
dataIndex: 'publicUserName',
|
||||||
|
width: 120,
|
||||||
|
sorter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '发布时间',
|
title: '发布时间',
|
||||||
dataIndex: 'createdTime',
|
dataIndex: 'createdTime',
|
||||||
|
width: 150,
|
||||||
|
sorter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '发布单位',
|
title: '发布单位',
|
||||||
dataIndex: 'publicOrgName',
|
dataIndex: 'publicOrgName',
|
||||||
width: 200,
|
width: 150,
|
||||||
|
sorter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '类型',
|
title: '类型',
|
||||||
dataIndex: 'type',
|
dataIndex: 'type',
|
||||||
|
width: 120,
|
||||||
|
sorter: true,
|
||||||
render: text => this.bindCodeValue(text, 'notice_type'),
|
render: text => this.bindCodeValue(text, 'notice_type'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '状态',
|
title: '状态',
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
|
width: 120,
|
||||||
render: text => this.bindCodeValue(text, 'notice_status'),
|
render: text => this.bindCodeValue(text, 'notice_status'),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -94,7 +104,7 @@ export default class index extends Component {
|
|||||||
if (flag) {
|
if (flag) {
|
||||||
this.columns.push({
|
this.columns.push({
|
||||||
title: '操作',
|
title: '操作',
|
||||||
width: 150,
|
width: 200,
|
||||||
dataIndex: 'actions',
|
dataIndex: 'actions',
|
||||||
render: (text, record) => (
|
render: (text, record) => (
|
||||||
<QueryTableActions>
|
<QueryTableActions>
|
||||||
@@ -178,6 +188,7 @@ export default class index extends Component {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
subUniqueKey(text, index) {
|
subUniqueKey(text, index) {
|
||||||
return text.substr(index, 5)
|
return text.substr(index, 5)
|
||||||
}
|
}
|
||||||
@@ -252,26 +263,23 @@ export default class index extends Component {
|
|||||||
* @param {*} id
|
* @param {*} id
|
||||||
*/
|
*/
|
||||||
onDelete(id) {
|
onDelete(id) {
|
||||||
this.onAction(apiAction.Status({ id, Status: 3 }), '删除成功')
|
this.onAction(apiAction.Status({ id, status: 3 }), '删除成功')
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 发布
|
* 发布
|
||||||
* @param {*} id
|
* @param {*} id
|
||||||
*/
|
*/
|
||||||
onPublish(id) {
|
onPublish(id) {
|
||||||
this.onAction(apiAction.Status({ id, Status: 1 }), '发布成功')
|
this.onAction(apiAction.Status({ id, status: 1 }), '发布成功')
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 撤回
|
* 撤回
|
||||||
* @param {*} id
|
* @param {*} id
|
||||||
*/
|
*/
|
||||||
onGoBack(id) {
|
onGoBack(id) {
|
||||||
this.onAction(apiAction.Status({ id, Status: 2 }), '撤回成功')
|
this.onAction(apiAction.Status({ id, status: 2 }), '撤回成功')
|
||||||
} //
|
} //
|
||||||
|
|
||||||
//#region 自定义方法
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { codes } = this.state
|
const { codes } = this.state
|
||||||
return (
|
return (
|
||||||
@@ -280,7 +288,6 @@ 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}
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Spin, Divider, Modal, Row } from 'antd'
|
import { Spin, Divider, Modal, Row, Form, Upload } from 'antd'
|
||||||
import { api } from 'common/api'
|
import { api } from 'common/api'
|
||||||
import { AntIcon } from 'components'
|
import { AntIcon } from 'components'
|
||||||
|
import { BlobToBase64, GetFileName, PreviewFile } from 'util/file'
|
||||||
|
|
||||||
export default class form extends Component {
|
export default class form extends Component {
|
||||||
state = {
|
state = {
|
||||||
detailVisible: false,
|
detailVisible: false,
|
||||||
detailLoading: false,
|
detailLoading: false,
|
||||||
detailData: {},
|
detailData: {},
|
||||||
|
fileValue: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filedu = React.createRef()
|
||||||
/**
|
/**
|
||||||
* mount后回调
|
* mount后回调
|
||||||
*/
|
*/
|
||||||
@@ -20,12 +23,57 @@ export default class form extends Component {
|
|||||||
async onOpenDetail(id) {
|
async onOpenDetail(id) {
|
||||||
this.setState({ detailLoading: true, detailVisible: true })
|
this.setState({ detailLoading: true, detailVisible: true })
|
||||||
const { data } = await api.sysNoticeDetail({ id })
|
const { data } = await api.sysNoticeDetail({ id })
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
detailLoading: false,
|
detailLoading: false,
|
||||||
detailData: data,
|
detailData: data,
|
||||||
|
fileValue: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
const { attachments } = data
|
||||||
|
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.setState({
|
||||||
|
fileValue,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
render() {
|
render() {
|
||||||
const { detailLoading, detailVisible, detailData } = this.state
|
const { detailLoading, detailVisible, detailData } = this.state
|
||||||
return (
|
return (
|
||||||
@@ -43,6 +91,21 @@ export default class form extends Component {
|
|||||||
dangerouslySetInnerHTML={{ __html: detailData.content }}
|
dangerouslySetInnerHTML={{ __html: detailData.content }}
|
||||||
></div>
|
></div>
|
||||||
<Divider />
|
<Divider />
|
||||||
|
{this.state.fileValue && (
|
||||||
|
<Row>
|
||||||
|
<span>
|
||||||
|
查看附件
|
||||||
|
<Upload
|
||||||
|
fileList={this.state.fileValue}
|
||||||
|
showUploadList={{
|
||||||
|
showDownloadIcon: true,
|
||||||
|
}}
|
||||||
|
onDownload={file => this.onFileDownload(file)}
|
||||||
|
></Upload>
|
||||||
|
</span>
|
||||||
|
</Row>
|
||||||
|
)}
|
||||||
|
<Divider />
|
||||||
<Row justify="space-between" className="text-gray">
|
<Row justify="space-between" className="text-gray">
|
||||||
<span>发布人:{detailData.publicUserName}</span>
|
<span>发布人:{detailData.publicUserName}</span>
|
||||||
<span>发布时间:{detailData.publicTime} </span>
|
<span>发布时间:{detailData.publicTime} </span>
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ export default class index extends Component {
|
|||||||
codes: {
|
codes: {
|
||||||
noticeStatus: [],
|
noticeStatus: [],
|
||||||
noticeType: [],
|
noticeType: [],
|
||||||
|
readStatus: [],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,25 +34,39 @@ export default class index extends Component {
|
|||||||
{
|
{
|
||||||
title: '标题',
|
title: '标题',
|
||||||
dataIndex: 'title',
|
dataIndex: 'title',
|
||||||
|
width: 300,
|
||||||
|
sorter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '发布人',
|
title: '发布人',
|
||||||
dataIndex: 'publicUserName',
|
dataIndex: 'publicUserName',
|
||||||
|
width: 150,
|
||||||
|
sorter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '发布时间',
|
title: '发布时间',
|
||||||
dataIndex: 'createdTime',
|
dataIndex: 'createdTime',
|
||||||
|
width: 200,
|
||||||
|
sorter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '发布单位',
|
title: '发布单位',
|
||||||
dataIndex: 'publicOrgName',
|
dataIndex: 'publicOrgName',
|
||||||
width: 200,
|
width: 200,
|
||||||
|
sorter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '类型',
|
title: '类型',
|
||||||
dataIndex: 'type',
|
dataIndex: 'type',
|
||||||
|
width: 120,
|
||||||
render: text => this.bindCodeValue(text, 'notice_type'),
|
render: text => this.bindCodeValue(text, 'notice_type'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '已读未读',
|
||||||
|
dataIndex: 'readStatus',
|
||||||
|
width: 120,
|
||||||
|
render: text => this.bindCodeValue(text, 'read_status'),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -94,33 +109,13 @@ export default class index extends Component {
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { onLoading, onLoadData } = this.table.current
|
const { onLoading, onLoadData } = this.table.current
|
||||||
onLoading()
|
onLoading()
|
||||||
getDictData('notice_status', 'notice_type').then(codes => {
|
getDictData('notice_status', 'notice_type', 'read_status').then(codes => {
|
||||||
this.setState({ codes }, () => {
|
this.setState({ codes }, () => {
|
||||||
onLoadData()
|
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进行处理
|
* 调用加载数据接口,可在调用前对query进行处理
|
||||||
* [异步,必要]
|
* [异步,必要]
|
||||||
@@ -134,6 +129,7 @@ export default class index extends Component {
|
|||||||
queryType: {
|
queryType: {
|
||||||
type: QueryType.Equal,
|
type: QueryType.Equal,
|
||||||
title: QueryType.Like,
|
title: QueryType.Like,
|
||||||
|
readStatus: QueryType.Equal,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -200,6 +196,19 @@ export default class index extends Component {
|
|||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item label="已读未读" name="readStatus">
|
||||||
|
<Select
|
||||||
|
placeholder="请选择是否已读"
|
||||||
|
className="w-200"
|
||||||
|
allowClear
|
||||||
|
>
|
||||||
|
{codes.readStatus.map(item => (
|
||||||
|
<Select.Option key={item.code} value={item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
</Auth>
|
</Auth>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Badge, Button, Divider, List, Menu, Modal, Popover, Row, Spin } from 'antd'
|
import { Badge, Button, Divider, List, Menu, Modal, Popover, Row, Spin, Upload, Tag } from 'antd'
|
||||||
import { AntIcon, Image } from 'components'
|
import { AntIcon, Image } from 'components'
|
||||||
import { api } from 'common/api'
|
import { api } from 'common/api'
|
||||||
import InfiniteScroll from 'react-infinite-scroller'
|
import InfiniteScroll from 'react-infinite-scroller'
|
||||||
|
import { BlobToBase64, GetFileName, PreviewFile } from 'util/file'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
|
|
||||||
export default class notice extends Component {
|
export default class notice extends Component {
|
||||||
@@ -16,6 +17,7 @@ export default class notice extends Component {
|
|||||||
detailVisible: false,
|
detailVisible: false,
|
||||||
detailLoading: false,
|
detailLoading: false,
|
||||||
detailData: {},
|
detailData: {},
|
||||||
|
fileValue: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
@@ -42,7 +44,6 @@ export default class notice extends Component {
|
|||||||
sortField: 'createdTime',
|
sortField: 'createdTime',
|
||||||
sortOrder: 'descend',
|
sortOrder: 'descend',
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!items.length) {
|
if (!items.length) {
|
||||||
return this.finish()
|
return this.finish()
|
||||||
}
|
}
|
||||||
@@ -59,7 +60,51 @@ export default class notice extends Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
detailLoading: false,
|
detailLoading: false,
|
||||||
detailData: data,
|
detailData: data,
|
||||||
|
fileValue: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
const { attachments } = data
|
||||||
|
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.setState({
|
||||||
|
fileValue,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
renderList() {
|
renderList() {
|
||||||
@@ -88,6 +133,13 @@ export default class notice extends Component {
|
|||||||
</small>
|
</small>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
description={
|
||||||
|
item.readStatus == 0 ? (
|
||||||
|
<Tag color="#f50">未读</Tag>
|
||||||
|
) : (
|
||||||
|
<Tag color="#2db7f5">已读</Tag>
|
||||||
|
)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<div className="ellipsis-3 text-gray">{item.content}</div>
|
<div className="ellipsis-3 text-gray">{item.content}</div>
|
||||||
</List.Item>
|
</List.Item>
|
||||||
@@ -140,6 +192,21 @@ export default class notice extends Component {
|
|||||||
dangerouslySetInnerHTML={{ __html: detailData.content }}
|
dangerouslySetInnerHTML={{ __html: detailData.content }}
|
||||||
></div>
|
></div>
|
||||||
<Divider />
|
<Divider />
|
||||||
|
{this.state.fileValue && (
|
||||||
|
<Row className="text-gray">
|
||||||
|
<span>
|
||||||
|
查看附件
|
||||||
|
<Upload
|
||||||
|
fileList={this.state.fileValue}
|
||||||
|
showUploadList={{
|
||||||
|
showDownloadIcon: true,
|
||||||
|
}}
|
||||||
|
onDownload={file => this.onFileDownload(file)}
|
||||||
|
></Upload>
|
||||||
|
</span>
|
||||||
|
</Row>
|
||||||
|
)}
|
||||||
|
<Divider />
|
||||||
<Row justify="space-between" className="text-gray">
|
<Row justify="space-between" className="text-gray">
|
||||||
<span>发布人:{detailData.publicUserName}</span>
|
<span>发布人:{detailData.publicUserName}</span>
|
||||||
<span>发布时间:{detailData.publicTime} </span>
|
<span>发布时间:{detailData.publicTime} </span>
|
||||||
|
|||||||
Reference in New Issue
Block a user