From a2cf74f383c1236a74090ac3791e431a489eee4a Mon Sep 17 00:00:00 2001 From: Connor <9174814+connorxia618@user.noreply.gitee.com> Date: Thu, 1 Jul 2021 19:02:07 +0800 Subject: [PATCH 01/15] Notice Module Update --- Api/Ewide.Core/Entity/SysNotice.cs | 4 +- Api/Ewide.Core/Entity/SysNoticeUser.cs | 4 +- .../Service/Notice/Dto/NoticeBase.cs | 4 +- .../Service/Notice/Dto/NoticeDetailOutput.cs | 2 +- .../Service/Notice/SysNoticeService.cs | 14 +- .../Service/Notice/SysNoticeUserService.cs | 35 ++- web-react/package.json | 1 + .../common/api/requests/sys/noticeManage.js | 19 +- .../components/form/braft-editor/index.jsx | 56 ++++ web-react/src/components/index.js | 3 +- web-react/src/pages/system/notice/form.jsx | 146 +++++++++ web-react/src/pages/system/notice/index.jsx | 277 ++++++++++++++++++ .../src/views/main/_layout/header/index.jsx | 87 +++++- web-react/yarn.lock | 141 ++++++++- 14 files changed, 756 insertions(+), 37 deletions(-) create mode 100644 web-react/src/components/form/braft-editor/index.jsx create mode 100644 web-react/src/pages/system/notice/form.jsx create mode 100644 web-react/src/pages/system/notice/index.jsx diff --git a/Api/Ewide.Core/Entity/SysNotice.cs b/Api/Ewide.Core/Entity/SysNotice.cs index 75e3d58..b7e6e80 100644 --- a/Api/Ewide.Core/Entity/SysNotice.cs +++ b/Api/Ewide.Core/Entity/SysNotice.cs @@ -59,13 +59,13 @@ namespace Ewide.Core /// 发布时间 /// [Comment("发布时间")] - public DateTime PublicTime { get; set; } + public DateTime? PublicTime { get; set; } /// /// 撤回时间 /// [Comment("撤回时间")] - public DateTime CancelTime { get; set; } + public DateTime? CancelTime { get; set; } /// /// 状态(字典 0草稿 1发布 2撤回 3删除) diff --git a/Api/Ewide.Core/Entity/SysNoticeUser.cs b/Api/Ewide.Core/Entity/SysNoticeUser.cs index 84b6b4e..0f85e54 100644 --- a/Api/Ewide.Core/Entity/SysNoticeUser.cs +++ b/Api/Ewide.Core/Entity/SysNoticeUser.cs @@ -11,7 +11,7 @@ namespace Ewide.Core /// [Table("sys_notice_user")] [Comment("通知公告用户表")] - public class SysNoticeUser : IEntity, IEntityTypeBuilder + public class SysNoticeUser : DEntityBase { /// /// 通知公告Id @@ -31,7 +31,7 @@ namespace Ewide.Core /// 阅读时间 /// [Comment("阅读时间")] - public DateTime ReadTime { get; set; } + public DateTime? ReadTime { get; set; } /// /// 状态(字典 0未读 1已读) diff --git a/Api/Ewide.Core/Service/Notice/Dto/NoticeBase.cs b/Api/Ewide.Core/Service/Notice/Dto/NoticeBase.cs index e63b789..48e1985 100644 --- a/Api/Ewide.Core/Service/Notice/Dto/NoticeBase.cs +++ b/Api/Ewide.Core/Service/Notice/Dto/NoticeBase.cs @@ -25,7 +25,7 @@ namespace Ewide.Core.Service /// /// 发布人Id /// - public long PublicUserId { get; set; } + public string PublicUserId { get; set; } /// /// 发布人姓名 @@ -35,7 +35,7 @@ namespace Ewide.Core.Service /// /// 发布机构Id /// - public long PublicOrgId { get; set; } + public string PublicOrgId { get; set; } /// /// 发布机构名称 diff --git a/Api/Ewide.Core/Service/Notice/Dto/NoticeDetailOutput.cs b/Api/Ewide.Core/Service/Notice/Dto/NoticeDetailOutput.cs index 1bee47c..032e9ac 100644 --- a/Api/Ewide.Core/Service/Notice/Dto/NoticeDetailOutput.cs +++ b/Api/Ewide.Core/Service/Notice/Dto/NoticeDetailOutput.cs @@ -39,6 +39,6 @@ namespace Ewide.Core.Service /// /// 阅读时间 /// - public DateTime ReadTime { get; set; } + public DateTime? ReadTime { get; set; } } } diff --git a/Api/Ewide.Core/Service/Notice/SysNoticeService.cs b/Api/Ewide.Core/Service/Notice/SysNoticeService.cs index 13809e5..26e20ad 100644 --- a/Api/Ewide.Core/Service/Notice/SysNoticeService.cs +++ b/Api/Ewide.Core/Service/Notice/SysNoticeService.cs @@ -61,22 +61,26 @@ namespace Ewide.Core.Service.Notice /// /// [HttpPost("/sysNotice/add")] + [UnitOfWork] public async Task AddNotice(AddNoticeInput input) { + _sysNoticeRep.EnsureTransaction(); if (input.Status != (int)NoticeStatus.DRAFT && input.Status != (int)NoticeStatus.PUBLIC) throw Oops.Oh(ErrorCode.D7000); var notice = input.Adapt(); + var id = System.Guid.NewGuid().ToString().ToLower(); + notice.Id = id; await UpdatePublicInfo(notice); // 如果是发布,则设置发布时间 if (input.Status == (int)NoticeStatus.PUBLIC) notice.PublicTime = DateTime.Now; - var newItem = await notice.InsertNowAsync(); + var newItem = await notice.InsertAsync(); // 通知到的人 var noticeUserIdList = input.NoticeUserIdList; var noticeUserStatus = (int)NoticeUserStatus.UNREAD; - await _sysNoticeUserService.Add(newItem.Entity.Id, noticeUserIdList, noticeUserStatus); + await _sysNoticeUserService.Add(id, noticeUserIdList, noticeUserStatus); } /// @@ -161,7 +165,11 @@ namespace Ewide.Core.Service.Notice await _sysNoticeUserService.Read(notice.Id, _userManager.UserId, (int)NoticeUserStatus.READ); return noticeResult; } - + [HttpGet("/sysNotice/detailById")] + public async Task GetNotice(string id) + { + return await _sysNoticeRep.FirstOrDefaultAsync(u => u.Id == id); + } /// /// 修改通知公告状态 /// diff --git a/Api/Ewide.Core/Service/Notice/SysNoticeUserService.cs b/Api/Ewide.Core/Service/Notice/SysNoticeUserService.cs index 5e86d47..845a8e3 100644 --- a/Api/Ewide.Core/Service/Notice/SysNoticeUserService.cs +++ b/Api/Ewide.Core/Service/Notice/SysNoticeUserService.cs @@ -1,9 +1,12 @@ using Furion.DatabaseAccessor; using Furion.DatabaseAccessor.Extensions; using Furion.DependencyInjection; +using Furion.DynamicApiController; +using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; namespace Ewide.Core.Service.Notice @@ -11,13 +14,17 @@ namespace Ewide.Core.Service.Notice /// /// 通知公告用户 /// - public class SysNoticeUserService : ISysNoticeUserService, ITransient + [ApiDescriptionSettings(Name = "NoticeUser", Order = 100)] + public class SysNoticeUserService : ISysNoticeUserService, IDynamicApiController, ITransient { private readonly IRepository _sysNoticeUserRep; // 通知公告用户表仓储 - - public SysNoticeUserService(IRepository sysNoticeUserRep) + private readonly IUserManager _userManager; + private readonly IRepository _sysNoticeRep; + public SysNoticeUserService(IRepository sysNoticeUserRep, IUserManager userManager, IRepository sysNoticeRep) { _sysNoticeUserRep = sysNoticeUserRep; + _userManager = userManager; + _sysNoticeRep = sysNoticeRep; } /// @@ -27,20 +34,32 @@ namespace Ewide.Core.Service.Notice /// /// /// - public Task Add(string noticeId, List noticeUserIdList, int noticeUserStatus) + + public async Task Add(string noticeId, List noticeUserIdList, int noticeUserStatus) { - noticeUserIdList.ForEach(u => + foreach (var u in noticeUserIdList) { - new SysNoticeUser + await new SysNoticeUser { + Id = Guid.NewGuid().ToString(), NoticeId = noticeId, UserId = u, ReadStatus = noticeUserStatus }.InsertAsync(); - }); - return Task.CompletedTask; + } } + [HttpGet("/NoticeUser/getCount")] + public async Task GetCount() + { + return await _sysNoticeUserRep.Where(u => u.UserId == _userManager.UserId && u.ReadStatus == (int)NoticeUserStatus.UNREAD).CountAsync(); + } + [HttpGet("/NoticeUser/GetNoticeInfo")] + public async Task> GetNoticeInfo() + { + var noticeIdList = await _sysNoticeUserRep.Where(u => u.UserId == _userManager.UserId && u.ReadStatus == (int)NoticeUserStatus.UNREAD).Select(p => p.NoticeId).ToListAsync(); + return await _sysNoticeRep.Where(s => noticeIdList.Contains(s.Id)).ToListAsync(); + } /// /// 更新 /// diff --git a/web-react/package.json b/web-react/package.json index 3a99c4e..04d6bff 100644 --- a/web-react/package.json +++ b/web-react/package.json @@ -9,6 +9,7 @@ "@testing-library/user-event": "^12.1.10", "antd": "^4.16.2", "axios": "^0.21.1", + "braft-editor": "^2.3.9", "craco-less": "^1.17.1", "crypto-js": "^4.0.0", "echarts": "^5.1.2", diff --git a/web-react/src/common/api/requests/sys/noticeManage.js b/web-react/src/common/api/requests/sys/noticeManage.js index d04aeed..5b9e1fb 100644 --- a/web-react/src/common/api/requests/sys/noticeManage.js +++ b/web-react/src/common/api/requests/sys/noticeManage.js @@ -4,37 +4,44 @@ const urls = { */ sysNoticePage: ['/sysNotice/page', 'post'], - /** * 添加系统通知公告 */ sysNoticeAdd: ['/sysNotice/add', 'post'], - /** * 编辑系统通知公告 */ sysNoticeEdit: ['/sysNotice/edit', 'post'], - /** * 删除系统通知公告 */ sysNoticeDelete: ['/sysNotice/delete', 'post'], - /** * 通知公告详情 */ sysNoticeDetail: ['/sysNotice/detail', 'get'], - /** * 修改状态 */ sysNoticeChangeStatus: ['/sysNotice/changeStatus', 'post'], + /** + * 获取Notice总数 + */ + sysNoticeGetCount: ['/NoticeUser/getCount', 'get'], + /** + * 获取Notice详细 + */ + sysNoticeInfo: ['/NoticeUser/GetNoticeInfo', 'get'], + /** + * 获取Notice详细ByID + */ + sysNoticeShow: ['/sysNotice/detailById', 'get'], } -export default urls \ No newline at end of file +export default urls diff --git a/web-react/src/components/form/braft-editor/index.jsx b/web-react/src/components/form/braft-editor/index.jsx new file mode 100644 index 0000000..d6d09b0 --- /dev/null +++ b/web-react/src/components/form/braft-editor/index.jsx @@ -0,0 +1,56 @@ +import React, { Component } from 'react' +import { Col, Input, InputNumber, Row } from 'antd' +import { AntIcon } from 'components' +import BraftEditor from 'braft-editor' +import 'braft-editor/dist/index.css' + +export default class index extends Component { + state = { + editorState: BraftEditor.createEditorState(this.props.value), // 设置编辑器初始内容 + outputHTML: '

', + } + /** + * mount后回调 + */ + componentDidMount() { + // 3秒后更改编辑器内容 + setTimeout(this.setEditorContentAsync, 2000) + } + componentWillUnmount() { + this.isLivinig = false + } + handleChange = editorState => { + const outputHTML = editorState.toHTML() + + const { onChange } = this.props + + this.setState({ + editorState: editorState, + outputHTML, + }) + + onChange && onChange(outputHTML) + } + + setEditorContentAsync = () => { + const { placeholder, value, onChange } = this.props + this.isLivinig && + this.setState({ + editorState: BraftEditor.createEditorState(value), + }) + } + render() { + const { editorState, outputHTML } = this.state + + //localStorage.setItem('props', JSON.stringify(this.props)) + const controls = ['bold', 'italic', 'underline', 'text-color', 'separator', 'media'] + return ( + + ) + } +} diff --git a/web-react/src/components/index.js b/web-react/src/components/index.js index 6ed3ee0..a47dac5 100644 --- a/web-react/src/components/index.js +++ b/web-react/src/components/index.js @@ -12,4 +12,5 @@ export { default as PhotoPreview } from './photo-preview' export { default as QueryList } from './query-list' export { default as QueryTable } from './query-table' export { default as QueryTableActions } from './query-table-actions' -export { default as QueryTreeLayout } from './query-tree-layout' \ No newline at end of file +export { default as QueryTreeLayout } from './query-tree-layout' +export { default as BraftEditor } from './form/braft-editor' diff --git a/web-react/src/pages/system/notice/form.jsx b/web-react/src/pages/system/notice/form.jsx new file mode 100644 index 0000000..2635ba1 --- /dev/null +++ b/web-react/src/pages/system/notice/form.jsx @@ -0,0 +1,146 @@ +import React, { Component } from 'react' +import { Form, Spin, Input, Radio, Select } from 'antd' +import { api } from 'common/api' +import { AntIcon, BraftEditor } from 'components' +import getDictData from 'util/dic' +import { cloneDeep } from 'lodash' +// import BraftEditor from 'braft-editor' +// import 'braft-editor/dist/index.css' +const initialValues = {} + +export default class form extends Component { + state = { + // 加载状态 + loading: true, + options: { + userList: [], + }, + codes: { + noticeType: [], + noticeStatus: [], + }, + } + + // 表单实例 + form = React.createRef() + + // 初始化数据 + record = {} + + /** + * mount后回调 + */ + componentDidMount() { + this.props.created && this.props.created(this) + this.isLivinig = true + // 3秒后更改编辑器内容 + } + + /** + * 填充数据 + * 可以在设置this.record之后对其作出数据结构调整 + * [异步,必要] + * @param {*} params + */ + async fillData(params) { + //#region 从后端转换成前段所需格式,也可以在此处调用获取详细数据接口 + if (params.id) { + this.record = (await api.sysNoticeDetail({ id: params.id })).data + } + const { + data: { items: userList }, + } = await this.onLoadUser() + const codes = await getDictData('notice_status', 'notice_type') + //#endregion + this.form.current.setFieldsValue(this.record) + + this.setState({ + loading: false, + options: { + userList, + }, + codes, + }) + } + async onLoadUser() { + const data = await api.getUserPage() + return data + } + /** + * 获取数据 + * 可以对postData进行数据结构调整 + * [异步,必要] + * @returns + */ + async getData() { + const form = this.form.current + + const valid = await form.validateFields() + if (valid) { + const postData = form.getFieldsValue() + if (this.record) { + postData.id = this.record.id + } + //#region 从前段转换后端所需格式 + //#endregion + return postData + } + } + + //#region 自定义方法 + //#endregion + + render() { + const { options, codes } = this.state + + return ( +
+ }> +
+ + + + + + {codes.noticeType.map(item => ( + + {item.value} + + ))} + + + + + + + + + +
+
+
+ ) + } +} diff --git a/web-react/src/pages/system/notice/index.jsx b/web-react/src/pages/system/notice/index.jsx new file mode 100644 index 0000000..5a94045 --- /dev/null +++ b/web-react/src/pages/system/notice/index.jsx @@ -0,0 +1,277 @@ +import React, { Component } from 'react' +import { Button, Card, Form, Input, message as Message, Popconfirm, Select } from 'antd' +import { AntIcon, Auth, Container, ModalForm, QueryTable, QueryTableActions } 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' + +/** + * 注释段[\/**\/]为必须要改 + */ + +/** + * 配置页面所需接口函数 + */ +const apiAction = { + page: api.sysNoticePage, + add: api.sysNoticeAdd, + edit: api.sysNoticeEdit, + delete: api.sysNoticeDelete, + Detail: api.sysNoticeDetail, + Status: api.sysNoticeChangeStatus, +} + +/** + * 用于弹窗标题 + * [必要] + */ +const name = '啥玩意' + +/** + * 统一配置权限标识 + * [必要] + */ +const authName = '/**/' + +export default class index extends Component { + state = { + codes: { + noticeStatus: [], + noticeType: [], + }, + } + + // 表格实例 + table = React.createRef() + + // 新增窗口实例 + addForm = React.createRef() + // 编辑窗口实例 + editForm = React.createRef() + + columns = [ + { + title: '标题', + dataIndex: 'title', + }, + { + title: '类型', + dataIndex: 'type', + render: text => this.bindCodeValue(text, 'notice_type'), + }, + { + title: '状态', + dataIndex: 'status', + render: text => this.bindCodeValue(text, 'notice_status'), + }, + ] + + /** + * 构造函数,在渲染前动态添加操作字段等 + * @param {*} props + */ + constructor(props) { + super(props) + + const flag = auth({ [authName]: [['edit'], ['delete']] }) + + if (flag) { + this.columns.push({ + title: '操作', + width: 150, + dataIndex: 'actions', + render: (text, record) => ( + + + this.onOpen(this.editForm, record.id)}>编辑 + + + this.onDelete(record.id)} + > + 删除 + + + + ), + }) + } + } + + /** + * 阻止外部组件引发的渲染,提升性能 + * 可自行添加渲染条件 + * [必要] + * @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() + }) + }) + } + + /** + * 调用加载数据接口,可在调用前对query进行处理 + * [异步,必要] + * @param {*} params + * @param {*} query + * @returns + */ + loadData = async (params, query) => { + const { data } = await apiAction.page({ + ...params, + ...query, + }) + 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.open({ + id, + }) + } + + /** + * 对表格上的操作进行统一处理 + * [异步] + * @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() + } + } + + /** + * 删除 + * @param {*} id + */ + onDelete(id) { + this.onAction(apiAction.delete({ id }), '删除成功') + } + + //#region 自定义方法 + //#endregion + + render() { + const { codes } = this.state + return ( + +
+ + + + + + + + + + } + operator={ + + + + } + /> + + + + this.table.current.onReloadData()} + > + + + + + + this.table.current.onReloadData()} + > + + + +
+ ) + } +} diff --git a/web-react/src/views/main/_layout/header/index.jsx b/web-react/src/views/main/_layout/header/index.jsx index ccf9f9d..e289d28 100644 --- a/web-react/src/views/main/_layout/header/index.jsx +++ b/web-react/src/views/main/_layout/header/index.jsx @@ -1,16 +1,23 @@ -import React, { Component } from 'react' -import { Layout, Badge } from 'antd' +import React, { Component, useState } from 'react' +import { Layout, Badge, Popover, Menu, Modal } from 'antd' import { AntIcon, Container } from 'components' import Logo from '../logo' import User from './user' import Search from './search' import store from 'store' +import { api } from 'common/api' const { getState, subscribe, dispatch } = store export default class index extends Component { state = { ...getState('layout'), + notice: { + count: 0, + data: [], + }, + modalVisible: false, + currentNotice: {}, } constructor(props) { @@ -21,6 +28,10 @@ export default class index extends Component { }) } + componentDidMount() { + this.loadNotice() + } + componentWillUnmount() { this.unsubscribe() } @@ -32,9 +43,27 @@ export default class index extends Component { }) } - render() { - const { allowSiderCollapsed } = this.state + async loadNotice() { + const { data } = await api.sysNoticeGetCount() + const items = await api.sysNoticeInfo() + this.setState({ + notice: { + count: data, + data: items.data, + }, + }) + } + async showDetail(params, visible) { + this.setState({ currentNotice: params }) + if (visible) { + this.setState({ modalVisible: visible }) + } else { + this.setState({ modalVisible: visible }) + } + } + render() { + const { allowSiderCollapsed, notice, currentNotice } = this.state return ( @@ -57,11 +86,51 @@ export default class index extends Component { > - - - - - + + + {notice.data.map(item => ( + this.showDetail(item, true)} + key={item.id} + > + {item.title} + + ))} + + } + > + + + + + + + this.showDetail(false)} + onCancel={() => this.showDetail(false)} + style={{ zIndex: 1000 }} + > +
+
+
+
+ 发布人:{currentNotice.createdUserName} + {' '} + 发布时间:{currentNotice.createdTime} +
+
+
diff --git a/web-react/yarn.lock b/web-react/yarn.lock index 62e133f..963891e 100644 --- a/web-react/yarn.lock +++ b/web-react/yarn.lock @@ -1191,6 +1191,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.0.0": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" + integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.14.5" resolved "https://registry.nlark.com/@babel/runtime/download/@babel/runtime-7.14.5.tgz?cache=0&sync_timestamp=1623280395479&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fruntime%2Fdownload%2F%40babel%2Fruntime-7.14.5.tgz#665450911c6031af38f81db530f387ec04cd9a98" @@ -2996,6 +3003,39 @@ braces@^3.0.1, braces@~3.0.2: dependencies: fill-range "^7.0.1" +braft-convert@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/braft-convert/-/braft-convert-2.3.0.tgz#27d5905136c334903d083b7a2352a72045627888" + integrity sha512-5km+dLHk8iYDv2iEYDrDQ2ld/ZoUx66QLql0qdm5PqZEcNXc8dBHGLORfzeu3iMw1jLeAiHxtdY5+ypuIhczVg== + dependencies: + draft-convert "^2.0.0" + draft-js "^0.10.3" + +braft-editor@^2.3.9: + version "2.3.9" + resolved "https://registry.yarnpkg.com/braft-editor/-/braft-editor-2.3.9.tgz#fd2b8e23ea71191016579a1ed8231d16ad8f5b4a" + integrity sha512-mqdPk/zI2dhFK8tW/A4Qj/AkkARLh5L/niNw+iif5wFqb6zh15rMlrShgz1nWO/QXyAKr8XtDgxiBbR0zWwtRg== + dependencies: + "@babel/runtime" "^7.0.0" + braft-convert "^2.3.0" + braft-finder "^0.0.19" + braft-utils "^3.0.8" + draft-convert "^2.0.0" + draft-js "^0.10.3" + draft-js-multidecorators "^1.0.0" + draftjs-utils "^0.9.4" + immutable "~3.7.4" + +braft-finder@^0.0.19: + version "0.0.19" + resolved "https://registry.yarnpkg.com/braft-finder/-/braft-finder-0.0.19.tgz#c324d82526ed3476a93de86cc9b407f4e188bc8d" + integrity sha512-0kzI6/KbomJJhYX1hpjn4edCKhblyUyWdUrsgBmOrwy0vrj+pPkm69+Uf8Uj6KGAULM6LF0ooC++p7fqUGgFHw== + +braft-utils@^3.0.8: + version "3.0.12" + resolved "https://registry.yarnpkg.com/braft-utils/-/braft-utils-3.0.12.tgz#2b755ce1d8397d96b627b6767f74d07f25729d85" + integrity sha512-O2cKysURNC4HSEMKgNmQ2RluwcrxvYrztlEmyPN5SzktiNX3vaLFQoo0Ez3PlIhvjaGrIBSIT2Oyh2N6mn6TFg== + brorand@^1.0.1, brorand@^1.1.0: version "1.1.0" resolved "https://registry.npm.taobao.org/brorand/download/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" @@ -3676,6 +3716,11 @@ core-js-pure@^3.14.0: resolved "https://registry.nlark.com/core-js-pure/download/core-js-pure-3.14.0.tgz#72bcfacba74a65ffce04bf94ae91d966e80ee553" integrity sha1-crz6y6dKZf/OBL+UrpHZZugO5VM= +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= + core-js@^2.4.0: version "2.6.12" resolved "https://registry.nlark.com/core-js/download/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" @@ -4410,6 +4455,36 @@ dotenv@8.2.0: resolved "https://registry.nlark.com/dotenv/download/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" integrity sha1-l+YZJZradQ7qPk6j4mvO6lQksWo= +draft-convert@^2.0.0: + version "2.1.11" + resolved "https://registry.yarnpkg.com/draft-convert/-/draft-convert-2.1.11.tgz#09797151ac7ed9c8f7898d116ba9f36869997bdf" + integrity sha512-8jLuhXmx5h5jiGi7thqdqV8O3aOmT7D5Q4OvCmT5tJWyMXWhKcJCktgqnwvEVGrHGxYJwfkfU4F/3fhGP2Dljw== + dependencies: + "@babel/runtime" "^7.5.5" + immutable "~3.7.4" + invariant "^2.2.1" + +draft-js-multidecorators@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/draft-js-multidecorators/-/draft-js-multidecorators-1.0.0.tgz#6c4be8d7b78dd2b966ee51ee6cc179b9b535e612" + integrity sha1-bEvo17eN0rlm7lHubMF5ubU15hI= + dependencies: + immutable "*" + +draft-js@^0.10.3: + version "0.10.5" + resolved "https://registry.yarnpkg.com/draft-js/-/draft-js-0.10.5.tgz#bfa9beb018fe0533dbb08d6675c371a6b08fa742" + integrity sha512-LE6jSCV9nkPhfVX2ggcRLA4FKs6zWq9ceuO/88BpXdNCS7mjRTgs0NsV6piUCJX9YxMsB9An33wnkMmU2sD2Zg== + dependencies: + fbjs "^0.8.15" + immutable "~3.7.4" + object-assign "^4.1.0" + +draftjs-utils@^0.9.4: + version "0.9.4" + resolved "https://registry.yarnpkg.com/draftjs-utils/-/draftjs-utils-0.9.4.tgz#976c61aa133dbbbfedd65ae1dd6627d7b98c6f08" + integrity sha512-KYjABSbGpJrwrwmxVj5UhfV37MF/p0QRxKIyL+/+QOaJ8J9z1FBKxkblThbpR0nJi9lxPQWGg+gh+v0dAsSCCg== + duplexer@^0.1.1: version "0.1.2" resolved "https://registry.npm.taobao.org/duplexer/download/duplexer-0.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fduplexer%2Fdownload%2Fduplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" @@ -4496,6 +4571,13 @@ encodeurl@~1.0.2: resolved "https://registry.nlark.com/encodeurl/download/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= +encoding@^0.1.11: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.nlark.com/end-of-stream/download/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -5120,6 +5202,19 @@ fbjs-css-vars@^1.0.0: resolved "https://registry.npm.taobao.org/fbjs-css-vars/download/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8" integrity sha1-IWVRE2rgL+JVkyw+yHdfGOLAeLg= +fbjs@^0.8.15: + version "0.8.17" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" + integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.18" + fbjs@^3.0.0: version "3.0.0" resolved "https://registry.npm.taobao.org/fbjs/download/fbjs-3.0.0.tgz?cache=0&sync_timestamp=1602048886093&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffbjs%2Fdownload%2Ffbjs-3.0.0.tgz#0907067fb3f57a78f45d95f1eacffcacd623c165" @@ -5856,6 +5951,13 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + icss-utils@^4.0.0, icss-utils@^4.1.1: version "4.1.1" resolved "https://registry.nlark.com/icss-utils/download/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" @@ -5900,6 +6002,16 @@ immer@8.0.1: resolved "https://registry.nlark.com/immer/download/immer-8.0.1.tgz?cache=0&sync_timestamp=1623232631798&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fimmer%2Fdownload%2Fimmer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656" integrity sha1-nHPbaD4rOXXEJPsFcq9YiYd65lY= +immutable@*: + version "3.8.2" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" + integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM= + +immutable@~3.7.4: + version "3.7.6" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.7.6.tgz#13b4d3cb12befa15482a26fe1b2ebae640071e4b" + integrity sha1-E7TTyxK++hVIKib+Gy665kAHHks= + import-cwd@^2.0.0: version "2.1.0" resolved "https://registry.nlark.com/import-cwd/download/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" @@ -6011,6 +6123,13 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" +invariant@^2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + ip-regex@^2.1.0: version "2.1.0" resolved "https://registry.nlark.com/ip-regex/download/ip-regex-2.1.0.tgz?cache=0&sync_timestamp=1618846943469&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fip-regex%2Fdownload%2Fip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" @@ -6318,7 +6437,7 @@ is-root@2.1.0: resolved "https://registry.npm.taobao.org/is-root/download/is-root-2.1.0.tgz?cache=0&sync_timestamp=1617783382597&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-root%2Fdownload%2Fis-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" integrity sha1-gJ4YEpzxEpZEMCpPhUQDXVGYSpw= -is-stream@^1.1.0: +is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.npm.taobao.org/is-stream/download/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= @@ -6394,6 +6513,14 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.nlark.com/isobject/download/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + istanbul-lib-coverage@^3.0.0: version "3.0.0" resolved "https://registry.npm.taobao.org/istanbul-lib-coverage/download/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" @@ -7719,6 +7846,14 @@ node-fetch@2.6.1: resolved "https://registry.nlark.com/node-fetch/download/node-fetch-2.6.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fnode-fetch%2Fdownload%2Fnode-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha1-BFvTI2Mfdu0uK1VXM5RBa2OaAFI= +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + node-forge@^0.10.0: version "0.10.0" resolved "https://registry.npm.taobao.org/node-forge/download/node-forge-0.10.0.tgz?cache=0&sync_timestamp=1599010726129&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-forge%2Fdownload%2Fnode-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" @@ -10340,7 +10475,7 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.1.0: +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.1.0: version "2.1.2" resolved "https://registry.nlark.com/safer-buffer/download/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo= @@ -11972,7 +12107,7 @@ whatwg-encoding@^1.0.5: dependencies: iconv-lite "0.4.24" -whatwg-fetch@^3.4.1: +whatwg-fetch@>=0.10.0, whatwg-fetch@^3.4.1: version "3.6.2" resolved "https://registry.nlark.com/whatwg-fetch/download/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" integrity sha1-3O0k838mJO0CgXJdUdDi4/5nf4w= From 4436230c710a8e3b24df7e3b8b844b8f4cd6c313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=87=AA=E5=B8=A6=E5=A4=A7=E4=BD=AC=E6=B0=94=E5=9C=BA?= <188633308@qq.com> Date: Thu, 1 Jul 2021 19:08:15 +0800 Subject: [PATCH 02/15] =?UTF-8?q?update=20=E5=A4=9C=E9=97=B4=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web-react/craco.config.js | 3 +- web-react/src/App.js | 1 - web-react/src/assets/style/dark/extend.less | 6 + .../style/{app.less => dark/index.less} | 10 +- .../assets/style/{ => dark}/lib/align.less | 0 .../assets/style/{ => dark}/lib/anchor.less | 0 .../style/{ => dark}/lib/authority-view.less | 0 .../assets/style/{ => dark}/lib/button.less | 0 .../src/assets/style/{ => dark}/lib/card.less | 0 .../assets/style/{ => dark}/lib/cascader.less | 0 .../assets/style/{ => dark}/lib/checkbox.less | 0 .../assets/style/dark/lib/color-selector.less | 18 + .../style/{ => dark}/lib/container.less | 0 .../style/{ => dark}/lib/description.less | 2 +- .../assets/style/{ => dark}/lib/disabled.less | 0 .../assets/style/{ => dark}/lib/dropdown.less | 0 .../style/{ => dark}/lib/font-size.less | 0 .../style/{ => dark}/lib/font-weight.less | 0 .../style/{ => dark}/lib/form-page.less | 6 +- web-react/src/assets/style/dark/lib/form.less | 399 +++++++++++ .../style/{ => dark}/lib/icon-selector.less | 0 .../assets/style/{ => dark}/lib/input.less | 0 .../src/assets/style/{ => dark}/lib/list.less | 0 .../assets/style/{ => dark}/lib/margin.less | 0 .../assets/style/{ => dark}/lib/modal.less | 5 +- .../src/assets/style/{ => dark}/lib/page.less | 0 .../assets/style/{ => dark}/lib/radio.less | 0 .../src/assets/style/dark/lib/scrollbar.less | 14 + .../assets/style/{ => dark}/lib/select.less | 0 .../src/assets/style/dark/lib/table.less | 240 +++++++ .../style/{ => dark}/lib/text-color.less | 4 +- .../assets/style/dark/lib/tree-layout.less | 83 +++ .../assets/style/{ => dark}/lib/upload.less | 0 .../style/{ => dark}/lib/visibility.less | 0 .../style/{ => dark}/lib/width-height.less | 0 web-react/src/assets/style/dark/main.less | 658 ++++++++++++++++++ .../style/dark/pages/account-base.less} | 2 +- .../style/dark/pages/home.less} | 4 +- .../src/assets/style/dark/pages/index.less | 3 + .../style/dark/pages/login.less} | 5 +- .../src/assets/style/{ => dark}/public.less | 3 +- .../assets/style/{ => dark}/theme/README.md | 0 .../src/assets/style/dark/theme/primary.less | 5 + .../assets/style/{ => default}/extend.less | 0 web-react/src/assets/style/default/index.less | 35 + .../src/assets/style/default/lib/align.less | 9 + .../src/assets/style/default/lib/anchor.less | 11 + .../style/default/lib/authority-view.less | 53 ++ .../src/assets/style/default/lib/button.less | 4 + .../src/assets/style/default/lib/card.less | 4 + .../assets/style/default/lib/cascader.less | 6 + .../assets/style/default/lib/checkbox.less | 10 + .../{ => default}/lib/color-selector.less | 0 .../assets/style/default/lib/container.less | 43 ++ .../assets/style/default/lib/description.less | 10 + .../assets/style/default/lib/disabled.less | 59 ++ .../assets/style/default/lib/dropdown.less | 6 + .../assets/style/default/lib/font-size.less | 25 + .../assets/style/default/lib/font-weight.less | 24 + .../assets/style/default/lib/form-page.less | 169 +++++ .../assets/style/{ => default}/lib/form.less | 10 +- .../style/default/lib/icon-selector.less | 59 ++ .../src/assets/style/default/lib/input.less | 4 + .../src/assets/style/default/lib/list.less | 95 +++ .../src/assets/style/default/lib/margin.less | 68 ++ .../src/assets/style/default/lib/modal.less | 38 + .../src/assets/style/default/lib/page.less | 8 + .../src/assets/style/default/lib/radio.less | 7 + .../style/{ => default}/lib/scrollbar.less | 0 .../src/assets/style/default/lib/select.less | 6 + .../assets/style/{ => default}/lib/table.less | 2 +- .../assets/style/default/lib/text-color.less | 35 + .../style/{ => default}/lib/tree-layout.less | 9 +- .../src/assets/style/default/lib/upload.less | 29 + .../assets/style/default/lib/visibility.less | 46 ++ .../style/default/lib/width-height.less | 47 ++ web-react/src/assets/style/default/main.less | 618 ++++++++++++++++ .../style/default/pages/account-base.less | 51 ++ .../src/assets/style/default/pages/home.less | 42 ++ .../src/assets/style/default/pages/index.less | 3 + .../src/assets/style/default/pages/login.less | 86 +++ .../src/assets/style/default/public.less | 45 ++ .../src/assets/style/default/theme/README.md | 1 + .../style/{ => default}/theme/primary.less | 2 +- web-react/src/assets/style/frame/dark.less | 13 - web-react/src/assets/style/frame/light.less | 12 - web-react/src/assets/style/main.less | 628 ----------------- web-react/src/index.js | 17 +- web-react/src/pages/home/index.jsx | 29 +- web-react/src/pages/home/statistics.jsx | 6 +- web-react/src/pages/system/account/base.jsx | 1 - .../src/pages/system/dict/dictdata/form.jsx | 22 +- web-react/src/store/reducer/layout.js | 11 +- web-react/src/views/login/index.jsx | 1 - .../src/views/main/_layout/header/index.jsx | 17 +- 95 files changed, 3286 insertions(+), 721 deletions(-) create mode 100644 web-react/src/assets/style/dark/extend.less rename web-react/src/assets/style/{app.less => dark/index.less} (85%) rename web-react/src/assets/style/{ => dark}/lib/align.less (100%) rename web-react/src/assets/style/{ => dark}/lib/anchor.less (100%) rename web-react/src/assets/style/{ => dark}/lib/authority-view.less (100%) rename web-react/src/assets/style/{ => dark}/lib/button.less (100%) rename web-react/src/assets/style/{ => dark}/lib/card.less (100%) rename web-react/src/assets/style/{ => dark}/lib/cascader.less (100%) rename web-react/src/assets/style/{ => dark}/lib/checkbox.less (100%) create mode 100644 web-react/src/assets/style/dark/lib/color-selector.less rename web-react/src/assets/style/{ => dark}/lib/container.less (100%) rename web-react/src/assets/style/{ => dark}/lib/description.less (76%) rename web-react/src/assets/style/{ => dark}/lib/disabled.less (100%) rename web-react/src/assets/style/{ => dark}/lib/dropdown.less (100%) rename web-react/src/assets/style/{ => dark}/lib/font-size.less (100%) rename web-react/src/assets/style/{ => dark}/lib/font-weight.less (100%) rename web-react/src/assets/style/{ => dark}/lib/form-page.less (95%) create mode 100644 web-react/src/assets/style/dark/lib/form.less rename web-react/src/assets/style/{ => dark}/lib/icon-selector.less (100%) rename web-react/src/assets/style/{ => dark}/lib/input.less (100%) rename web-react/src/assets/style/{ => dark}/lib/list.less (100%) rename web-react/src/assets/style/{ => dark}/lib/margin.less (100%) rename web-react/src/assets/style/{ => dark}/lib/modal.less (83%) rename web-react/src/assets/style/{ => dark}/lib/page.less (100%) rename web-react/src/assets/style/{ => dark}/lib/radio.less (100%) create mode 100644 web-react/src/assets/style/dark/lib/scrollbar.less rename web-react/src/assets/style/{ => dark}/lib/select.less (100%) create mode 100644 web-react/src/assets/style/dark/lib/table.less rename web-react/src/assets/style/{ => dark}/lib/text-color.less (88%) create mode 100644 web-react/src/assets/style/dark/lib/tree-layout.less rename web-react/src/assets/style/{ => dark}/lib/upload.less (100%) rename web-react/src/assets/style/{ => dark}/lib/visibility.less (100%) rename web-react/src/assets/style/{ => dark}/lib/width-height.less (100%) create mode 100644 web-react/src/assets/style/dark/main.less rename web-react/src/{pages/system/account/base.less => assets/style/dark/pages/account-base.less} (94%) rename web-react/src/{pages/home/index.less => assets/style/dark/pages/home.less} (87%) create mode 100644 web-react/src/assets/style/dark/pages/index.less rename web-react/src/{views/login/index.less => assets/style/dark/pages/login.less} (94%) rename web-react/src/assets/style/{ => dark}/public.less (89%) rename web-react/src/assets/style/{ => dark}/theme/README.md (100%) create mode 100644 web-react/src/assets/style/dark/theme/primary.less rename web-react/src/assets/style/{ => default}/extend.less (100%) create mode 100644 web-react/src/assets/style/default/index.less create mode 100644 web-react/src/assets/style/default/lib/align.less create mode 100644 web-react/src/assets/style/default/lib/anchor.less create mode 100644 web-react/src/assets/style/default/lib/authority-view.less create mode 100644 web-react/src/assets/style/default/lib/button.less create mode 100644 web-react/src/assets/style/default/lib/card.less create mode 100644 web-react/src/assets/style/default/lib/cascader.less create mode 100644 web-react/src/assets/style/default/lib/checkbox.less rename web-react/src/assets/style/{ => default}/lib/color-selector.less (100%) create mode 100644 web-react/src/assets/style/default/lib/container.less create mode 100644 web-react/src/assets/style/default/lib/description.less create mode 100644 web-react/src/assets/style/default/lib/disabled.less create mode 100644 web-react/src/assets/style/default/lib/dropdown.less create mode 100644 web-react/src/assets/style/default/lib/font-size.less create mode 100644 web-react/src/assets/style/default/lib/font-weight.less create mode 100644 web-react/src/assets/style/default/lib/form-page.less rename web-react/src/assets/style/{ => default}/lib/form.less (96%) create mode 100644 web-react/src/assets/style/default/lib/icon-selector.less create mode 100644 web-react/src/assets/style/default/lib/input.less create mode 100644 web-react/src/assets/style/default/lib/list.less create mode 100644 web-react/src/assets/style/default/lib/margin.less create mode 100644 web-react/src/assets/style/default/lib/modal.less create mode 100644 web-react/src/assets/style/default/lib/page.less create mode 100644 web-react/src/assets/style/default/lib/radio.less rename web-react/src/assets/style/{ => default}/lib/scrollbar.less (100%) create mode 100644 web-react/src/assets/style/default/lib/select.less rename web-react/src/assets/style/{ => default}/lib/table.less (98%) create mode 100644 web-react/src/assets/style/default/lib/text-color.less rename web-react/src/assets/style/{ => default}/lib/tree-layout.less (87%) create mode 100644 web-react/src/assets/style/default/lib/upload.less create mode 100644 web-react/src/assets/style/default/lib/visibility.less create mode 100644 web-react/src/assets/style/default/lib/width-height.less create mode 100644 web-react/src/assets/style/default/main.less create mode 100644 web-react/src/assets/style/default/pages/account-base.less create mode 100644 web-react/src/assets/style/default/pages/home.less create mode 100644 web-react/src/assets/style/default/pages/index.less create mode 100644 web-react/src/assets/style/default/pages/login.less create mode 100644 web-react/src/assets/style/default/public.less create mode 100644 web-react/src/assets/style/default/theme/README.md rename web-react/src/assets/style/{ => default}/theme/primary.less (81%) delete mode 100644 web-react/src/assets/style/frame/dark.less delete mode 100644 web-react/src/assets/style/frame/light.less delete mode 100644 web-react/src/assets/style/main.less diff --git a/web-react/craco.config.js b/web-react/craco.config.js index a83f185..2cde7a0 100644 --- a/web-react/craco.config.js +++ b/web-react/craco.config.js @@ -23,12 +23,13 @@ module.exports = { javascriptEnabled: true, }, }, + importLoaders: 2 }, }, ], webpack: { plugins: [ - // new MonacoWebpackPlugin() + new MonacoWebpackPlugin() ] } } \ No newline at end of file diff --git a/web-react/src/App.js b/web-react/src/App.js index d98b1cf..77a1d96 100644 --- a/web-react/src/App.js +++ b/web-react/src/App.js @@ -3,7 +3,6 @@ import { ConfigProvider } from 'antd' import zhCN from 'antd/lib/locale/zh_CN' import moment from 'moment' import 'moment/locale/zh-cn' -import './assets/style/app.less' moment.locale('zh-cn') diff --git a/web-react/src/assets/style/dark/extend.less b/web-react/src/assets/style/dark/extend.less new file mode 100644 index 0000000..9bdd94f --- /dev/null +++ b/web-react/src/assets/style/dark/extend.less @@ -0,0 +1,6 @@ +@import '~antd/dist/antd.dark.less'; +@padding-xxs: 4px; +@padding-xl: 32px; +body { + line-height: 1.42857143; +} diff --git a/web-react/src/assets/style/app.less b/web-react/src/assets/style/dark/index.less similarity index 85% rename from web-react/src/assets/style/app.less rename to web-react/src/assets/style/dark/index.less index 1e27ce4..8697d9b 100644 --- a/web-react/src/assets/style/app.less +++ b/web-react/src/assets/style/dark/index.less @@ -8,14 +8,6 @@ @import './lib/width-height.less'; @import './lib/scrollbar.less'; @import './main.less'; -@import './frame/dark.less'; -@import './frame/light.less'; -.yo-nav-theme--dark { - .dark(); -} -.yo-nav-theme--light { - .light(); -} @import './lib/button.less'; @import './lib/card.less'; @import './lib/table.less'; @@ -39,5 +31,5 @@ @import './lib/anchor.less'; @import './lib/disabled.less'; @import './theme/primary.less'; -// @import './lib/font-weight.less'; @import './public.less'; +@import './pages/index.less'; diff --git a/web-react/src/assets/style/lib/align.less b/web-react/src/assets/style/dark/lib/align.less similarity index 100% rename from web-react/src/assets/style/lib/align.less rename to web-react/src/assets/style/dark/lib/align.less diff --git a/web-react/src/assets/style/lib/anchor.less b/web-react/src/assets/style/dark/lib/anchor.less similarity index 100% rename from web-react/src/assets/style/lib/anchor.less rename to web-react/src/assets/style/dark/lib/anchor.less diff --git a/web-react/src/assets/style/lib/authority-view.less b/web-react/src/assets/style/dark/lib/authority-view.less similarity index 100% rename from web-react/src/assets/style/lib/authority-view.less rename to web-react/src/assets/style/dark/lib/authority-view.less diff --git a/web-react/src/assets/style/lib/button.less b/web-react/src/assets/style/dark/lib/button.less similarity index 100% rename from web-react/src/assets/style/lib/button.less rename to web-react/src/assets/style/dark/lib/button.less diff --git a/web-react/src/assets/style/lib/card.less b/web-react/src/assets/style/dark/lib/card.less similarity index 100% rename from web-react/src/assets/style/lib/card.less rename to web-react/src/assets/style/dark/lib/card.less diff --git a/web-react/src/assets/style/lib/cascader.less b/web-react/src/assets/style/dark/lib/cascader.less similarity index 100% rename from web-react/src/assets/style/lib/cascader.less rename to web-react/src/assets/style/dark/lib/cascader.less diff --git a/web-react/src/assets/style/lib/checkbox.less b/web-react/src/assets/style/dark/lib/checkbox.less similarity index 100% rename from web-react/src/assets/style/lib/checkbox.less rename to web-react/src/assets/style/dark/lib/checkbox.less diff --git a/web-react/src/assets/style/dark/lib/color-selector.less b/web-react/src/assets/style/dark/lib/color-selector.less new file mode 100644 index 0000000..e7da66e --- /dev/null +++ b/web-react/src/assets/style/dark/lib/color-selector.less @@ -0,0 +1,18 @@ +@import (reference) '../extend.less'; +.ant-select-dropdown { + .chrome-picker { + width: auto !important; + margin: -@padding-xxs 0; + + border-radius: 0 !important; + background: transparent !important; + box-shadow: none !important; + } +} +.color-selector--palette { + width: 32px; + height: 32px; + + border-radius: @border-radius-base; + box-shadow: inset 0 0 0 @border-width-base @border-color-base, inset 0 0 0 3px @black; +} diff --git a/web-react/src/assets/style/lib/container.less b/web-react/src/assets/style/dark/lib/container.less similarity index 100% rename from web-react/src/assets/style/lib/container.less rename to web-react/src/assets/style/dark/lib/container.less diff --git a/web-react/src/assets/style/lib/description.less b/web-react/src/assets/style/dark/lib/description.less similarity index 76% rename from web-react/src/assets/style/lib/description.less rename to web-react/src/assets/style/dark/lib/description.less index 05bf783..cfe090a 100644 --- a/web-react/src/assets/style/lib/description.less +++ b/web-react/src/assets/style/dark/lib/description.less @@ -4,7 +4,7 @@ >table { border-collapse: collapse; - background-color: @white; + background-color: @component-background; } } } diff --git a/web-react/src/assets/style/lib/disabled.less b/web-react/src/assets/style/dark/lib/disabled.less similarity index 100% rename from web-react/src/assets/style/lib/disabled.less rename to web-react/src/assets/style/dark/lib/disabled.less diff --git a/web-react/src/assets/style/lib/dropdown.less b/web-react/src/assets/style/dark/lib/dropdown.less similarity index 100% rename from web-react/src/assets/style/lib/dropdown.less rename to web-react/src/assets/style/dark/lib/dropdown.less diff --git a/web-react/src/assets/style/lib/font-size.less b/web-react/src/assets/style/dark/lib/font-size.less similarity index 100% rename from web-react/src/assets/style/lib/font-size.less rename to web-react/src/assets/style/dark/lib/font-size.less diff --git a/web-react/src/assets/style/lib/font-weight.less b/web-react/src/assets/style/dark/lib/font-weight.less similarity index 100% rename from web-react/src/assets/style/lib/font-weight.less rename to web-react/src/assets/style/dark/lib/font-weight.less diff --git a/web-react/src/assets/style/lib/form-page.less b/web-react/src/assets/style/dark/lib/form-page.less similarity index 95% rename from web-react/src/assets/style/lib/form-page.less rename to web-react/src/assets/style/dark/lib/form-page.less index ae47a95..270d18a 100644 --- a/web-react/src/assets/style/lib/form-page.less +++ b/web-react/src/assets/style/dark/lib/form-page.less @@ -16,7 +16,7 @@ margin-bottom: 0; padding: 0 @padding-md; - background-color: @white; + background-color: @component-background; &.ant-tabs-card-bar { .ant-tabs-nav-container { @@ -121,7 +121,7 @@ padding: @padding-xs @padding-md; border: @border-width-base @border-style-base @border-color-split; - background-color: fade(@white, 80%); + background-color: fade(@component-background, 80%); backdrop-filter: blur(5px); @@ -164,6 +164,6 @@ &--header { padding: @padding-md 0; - background-color: @white; + background-color: @component-background; } } \ No newline at end of file diff --git a/web-react/src/assets/style/dark/lib/form.less b/web-react/src/assets/style/dark/lib/form.less new file mode 100644 index 0000000..e770583 --- /dev/null +++ b/web-react/src/assets/style/dark/lib/form.less @@ -0,0 +1,399 @@ +@import (reference) '../extend.less'; +.yo-form { + &--fixed { + width: 660px; + margin: 0 auto; + } + .h1, + .h2, + .h3, + .h4, + .h5, + .h6 { + color: darken(@white, 40%); + } + .h3 { + font-size: 16px; + } + .h4 { + font-size: 15px; + } + .yo-form-group { + margin-bottom: @padding-md; + } + .ant-form-item { + display: flex; + justify-content: space-between; + + margin-bottom: -1px; + padding: @padding-xs @padding-md; + + border: @border-width-base @border-style-base @border-color-split; + background-color: @component-background; + + @box-shadow-focused: 0 0 0 2px fade(@primary-color, 50%); + @control-background: darken(@white, 95%) !important; + &::before, + &::after { + content: none; + } + .ant-form-item-control { + text-align: right; + } + .ant-input, + .ant-input-number, + .ant-mentions, + .ant-select-selector, + .ant-input-group-addon, + .ant-cascader-picker, + .ant-input-affix-wrapper, + .ant-picker { + z-index: 1; + + text-align: left; + + color: darken(@white, 10%); + border: 0; + background-color: @control-background; + } + .ant-mentions { + textarea { + background-color: @control-background; + } + } + .focus { + z-index: 2 !important; + + box-shadow: @box-shadow-focused; + } + .unfoucs { + z-index: 1 !important; + + box-shadow: none; + } + .ant-input { + &:focus { + .focus(); + } + } + .ant-input-affix-wrapper { + >.ant-input { + &:focus { + .unfoucs(); + } + } + } + .ant-input-number-focused, + .ant-mentions-focused { + .focus(); + } + .ant-select-focused, + .ant-select-open { + z-index: 2; + .ant-select-selection { + .focus(); + } + } + .ant-cascader-picker:focus { + .ant-cascader-input { + .focus(); + } + } + .ant-input-affix-wrapper:focus, + .ant-input-affix-wrapper-focused { + .focus(); + } + .ant-select-focused:not(.ant-select-disabled).ant-select:not(.ant-select-customize-input) { + .ant-select-selector { + .focus(); + } + } + .ant-picker-focused { + .focus(); + } + .ant-input-group { + .ant-row-flex { + .ant-select { + width: 100%; + } + } + .ant-input-group-addon { + z-index: 0; + } + } + .ant-cascader-picker-clear { + background-color: @control-background; + } + } + .ant-form-item-label { + overflow: hidden; + flex: 1 1 auto; + + margin-right: @padding-md; + + text-align: left; + text-overflow: ellipsis; + >label { + color: darken(@white, 10%); + &::after { + content: none; + } + } + } + .ant-form-item-control { + flex: 0 0 61.8%; + + width: 61.8%; + min-width: 220px; + } + .yo-form--fluid { + .ant-form-item-control { + flex: 0 0 100%; + + width: 100%; + } + } + .yo-form--short { + .ant-form-item-control { + flex: 0 0 38.2%; + + width: 38.2%; + } + } + // 上下布局 + .yo-form--vertical { + display: block; + .ant-form-item-control { + text-align: left; + } + &-radio { + .ant-radio-wrapper { + line-height: @padding-lg; + + display: block; + + margin-right: 0; + +.ant-radio-wrapper { + margin-top: @padding-sm; + } + } + } + .ant-form-item-control-wrapper { + margin-left: @padding-lg; + } + .ant-form-explain { + margin-left: 0; + } + } + .yo-form-link { + display: flex; + align-items: center; + + margin-bottom: -1px; + padding: @padding-md; + + cursor: pointer; + + border: @border-width-base @border-style-base @border-color-split; + background-color: @component-background; + &:hover { + background-color: lighten(@black, 1%); + } + &:active { + background-color: lighten(@black, 3%); + } + &--title { + font-size: @font-size-base + 1px; + + flex: 1; + } + &--content { + flex: 1; + + text-align: right; + + color: fade(@black, 35%); + } + &--right-icon { + margin-left: @padding-xs; + + color: fade(@black, 50%); + } + } + &.yo-form--no-border { + .ant-form-item { + padding: @padding-md 0; + + border-right: 0; + border-left: 0; + &:first-child { + border-top: 0; + } + &:last-child { + border-bottom: 0; + } + } + .yo-form-group { + margin-bottom: 0; + } + } +} +.yo-modal-form { + .ant-modal-body { + padding: 0; + } + .yo-form { + h1, + h2, + h3, + h4, + h5 { + margin: 0; + padding: @padding-sm @padding-md @padding-xs; + } + .yo-form-group { + margin-bottom: 0; + } + .ant-form-item { + border-right: 0; + border-left: 0; + &:first-child { + margin-top: -1px; + } + } + } +} +.yo-drawer-form { + .ant-drawer-wrapper-body { + display: flex; + flex-direction: column; + } + .ant-drawer-header { + flex: 0 0 auto; + } + .ant-drawer-body { + position: relative; + + flex: 1 1 100%; + + padding: 0; + } + .yo-drawer-form--body { + position: absolute; + top: 0; + bottom: @border-width-base + 20px + @padding-md * 2; + + overflow: auto; + + width: 100%; + padding: @padding-lg; + } + .ant-drawer-footer { + position: absolute; + left: 0; + bottom: 0; + + width: 100%; + padding: 10px @padding-md; + + text-align: right; + + border-top: @border-width-base @border-style-base @border-color-split; + background: @component-background; + button+button { + margin-left: @padding-xs; + } + } +} +.ant-form { + fieldset { + margin-bottom: @padding-lg; + padding: @padding-md; + + border: @border-width-base @border-style-base @border-color-split; + } + legend { + display: inline-block; + + width: auto; + margin-bottom: 0; + padding: 0 @padding-md; + + border: 0; + border-radius: @border-radius-base; + } +} +.ant-form-horizontal { + .ant-form-item-label { + line-height: 1.5; + + margin-right: @padding-xs; + + white-space: normal; + } +} +.ant-form-vertical { + .ant-form-item-label { + >label { + font-weight: bold; + } + } +} +.ant-form-item-required { + &::before { + content: '' !important; + vertical-align: middle; + + border-top: 4px solid transparent; + border-bottom: 4px solid transparent; + border-left: 5px solid @highlight-color; + background: none; + } +} +.yo-form-page { + .ant-form { + .ant-radio-button-wrapper { + margin-right: @padding-xs; + margin-bottom: @padding-xs; + + border-left: @border-width-base @border-style-base @border-color-base; + &.ant-radio-button-wrapper-checked { + border-left-color: @primary-color; + } + &:not(:first-child) { + &::before { + content: none; + } + } + } + } +} +.yo-filter-item { + display: flex; + flex-flow: row wrap; + + margin-bottom: 0; + .ant-tag-checkable { + font-size: @font-size-base; + } + .ant-radio-button-wrapper { + border: 0 !important; + background-color: transparent; + &:hover { + color: @red-6; + } + } + .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled) { + border-color: @red-6; + background-color: @red-6; + &:hover { + border-color: @red-5; + background-color: @red-5; + } + &:active { + border-color: @red-7; + background-color: @red-7; + box-shadow: none; + } + } +} diff --git a/web-react/src/assets/style/lib/icon-selector.less b/web-react/src/assets/style/dark/lib/icon-selector.less similarity index 100% rename from web-react/src/assets/style/lib/icon-selector.less rename to web-react/src/assets/style/dark/lib/icon-selector.less diff --git a/web-react/src/assets/style/lib/input.less b/web-react/src/assets/style/dark/lib/input.less similarity index 100% rename from web-react/src/assets/style/lib/input.less rename to web-react/src/assets/style/dark/lib/input.less diff --git a/web-react/src/assets/style/lib/list.less b/web-react/src/assets/style/dark/lib/list.less similarity index 100% rename from web-react/src/assets/style/lib/list.less rename to web-react/src/assets/style/dark/lib/list.less diff --git a/web-react/src/assets/style/lib/margin.less b/web-react/src/assets/style/dark/lib/margin.less similarity index 100% rename from web-react/src/assets/style/lib/margin.less rename to web-react/src/assets/style/dark/lib/margin.less diff --git a/web-react/src/assets/style/lib/modal.less b/web-react/src/assets/style/dark/lib/modal.less similarity index 83% rename from web-react/src/assets/style/lib/modal.less rename to web-react/src/assets/style/dark/lib/modal.less index b066f86..8c9c850 100644 --- a/web-react/src/assets/style/lib/modal.less +++ b/web-react/src/assets/style/dark/lib/modal.less @@ -7,16 +7,17 @@ .ant-modal-header { padding: @padding-sm @padding-md; + border-bottom: 0; background-color: transparent; } .ant-modal-title { color: fade(@white, 85%); } .ant-modal-body { - background-color: @white; + background-color: @component-background; } .ant-modal-footer { - background-color: @white; + background-color: @component-background; } .ant-modal-close { top: 10px; diff --git a/web-react/src/assets/style/lib/page.less b/web-react/src/assets/style/dark/lib/page.less similarity index 100% rename from web-react/src/assets/style/lib/page.less rename to web-react/src/assets/style/dark/lib/page.less diff --git a/web-react/src/assets/style/lib/radio.less b/web-react/src/assets/style/dark/lib/radio.less similarity index 100% rename from web-react/src/assets/style/lib/radio.less rename to web-react/src/assets/style/dark/lib/radio.less diff --git a/web-react/src/assets/style/dark/lib/scrollbar.less b/web-react/src/assets/style/dark/lib/scrollbar.less new file mode 100644 index 0000000..84b7c04 --- /dev/null +++ b/web-react/src/assets/style/dark/lib/scrollbar.less @@ -0,0 +1,14 @@ +@import (reference) '../extend.less'; +::-webkit-scrollbar { + width: 7px; + height: 7px; + + background-color: fade(@white, 10%); +} +::-webkit-scrollbar-thumb { + border-radius: @border-radius-base; + background-color: fade(@white, 30%); +} +::-webkit-scrollbar-thumb:active { + background-color: fade(@white, 50%); +} diff --git a/web-react/src/assets/style/lib/select.less b/web-react/src/assets/style/dark/lib/select.less similarity index 100% rename from web-react/src/assets/style/lib/select.less rename to web-react/src/assets/style/dark/lib/select.less diff --git a/web-react/src/assets/style/dark/lib/table.less b/web-react/src/assets/style/dark/lib/table.less new file mode 100644 index 0000000..684a4ea --- /dev/null +++ b/web-react/src/assets/style/dark/lib/table.less @@ -0,0 +1,240 @@ +@import (reference) '../extend.less'; +.yo-query-bar { + margin-bottom: @padding-xs; + .ant-form-inline { + .ant-form-item { + margin-bottom: @padding-xs; + } + } +} +.yo-action-bar { + display: flex; + justify-content: space-between; + + margin-bottom: @padding-md; + &--actions { + >.ant-btn, + >.ant-btn-group { + +.ant-btn, + +.ant-btn-group { + margin-left: @padding-xs; + } + } + } +} +.ant-table { + .ant-table-container { + &::before, + &::after { + z-index: 3; + } + } +} +.ant-table-thead { + th.ant-table-column-has-sorters { + &:hover { + background-color: darken(@background-color-base, 5%); + } + } +} +.ant-table-tbody { + >tr { + >td { + transition-property: background, border-bottom-color; + } + } + >tr.ant-table-row:hover { + >td { + border-bottom-color: lighten(@primary-color, 30%); + } + } +} +.ant-table-small { + >.ant-table-content { + >.ant-table-body { + margin: 0; + >table { + >.ant-table-thead { + >tr { + >th { + background-color: @table-selected-row-bg; + } + } + } + } + } + } +} +.ant-table-thead { + >tr { + >th { + font-weight: bold; + } + } +} +.ant-table-sticky-scroll { + display: none; +} +.yo-table { + .ant-table { + margin: 0 !important; + } + .border-right-none { + border-right-width: 0 !important; + &:last-child { + border-right-width: 1px !important; + } + } + .ant-table-content { + .ant-table-body { + overflow-x: auto !important; + >table { + >.ant-table-thead { + >tr { + >th { + .border-right-none(); + } + } + } + >.ant-table-tbody { + >tr { + >td { + .border-right-none(); + } + } + } + } + } + .ant-table-fixed-left { + .ant-table-thead { + >tr { + >th { + border-right-width: 0 !important; + } + } + } + .ant-table-tbody { + >tr { + >td { + border-right-width: 0 !important; + } + } + } + } + .ant-table-fixed-right { + .ant-table-fixed { + border-left-width: 0 !important; + } + .ant-table-thead { + >tr { + >th { + .border-right-none(); + } + } + } + .ant-table-tbody { + >tr { + >td { + .border-right-none(); + } + } + } + } + } + .ant-table-bordered { + >.ant-table-container { + border-top: @border-width-base @border-style-base @table-border-color; + } + } + &--row-no { + width: 30px !important; + + background-color: @table-header-bg; + } +} +.yo-table-actions { + display: inline-block; + + vertical-align: middle; + &--inner { + display: flex; + align-items: center; + + height: 18px; + } +} +.yo-table--column-setting { + width: 240px; + .ant-dropdown-menu-item { + display: flex; + align-items: center; + justify-content: space-between; + } + .anticon-pushpin { + transition: @animation-duration-slow; + transform: rotate(45deg); + + color: darken(@white, 40%); + } + .yo-table--fixed { + transform: rotate(-45deg); + } +} +.yo-menu-table { + .ant-table { + .ant-table-expand-icon-col { + width: 28px; + } + .ant-table-row-expand-icon-cell { + z-index: 1; + + padding-right: 0 !important; + + border-right: none !important; + +.ant-table-cell { + padding-left: 0; + } + } + .ant-table-tbody { + >.ant-table-expanded-row-level-1>td { + padding: 0; + + border-right: none !important; + .ant-table-wrapper { + border: none; + .ant-table { + margin: 0 !important; + } + .ant-table-container { + border: none; + .ant-table-row-expand-icon-cell { + .ant-table-row-expand-icon { + left: @padding-md; + } + +.ant-table-cell { + padding-left: @padding-md; + } + } + .ant-table-expanded-row-level-1>td { + padding: @padding-sm @padding-xs @padding-sm @padding-xl; + + border-right: @border-width-base @border-style-base @table-border-color !important; + .ant-card { + max-width: fit-content; + margin-bottom: 0; + + background: none; + .ant-card-grid { + width: 300px; + padding: @padding-xs @padding-sm; + + background-color: @card-background; + } + } + } + } + } + } + } + } +} diff --git a/web-react/src/assets/style/lib/text-color.less b/web-react/src/assets/style/dark/lib/text-color.less similarity index 88% rename from web-react/src/assets/style/lib/text-color.less rename to web-react/src/assets/style/dark/lib/text-color.less index f1cd8ae..135d5a2 100644 --- a/web-react/src/assets/style/lib/text-color.less +++ b/web-react/src/assets/style/dark/lib/text-color.less @@ -22,10 +22,10 @@ color: @warning-color; } .text-gray { - color: gray; + color: fade(@white, 50%); } .text-normal { - color: @normal-color; + color: fade(@white, 30%); } .text-white { color: @white; diff --git a/web-react/src/assets/style/dark/lib/tree-layout.less b/web-react/src/assets/style/dark/lib/tree-layout.less new file mode 100644 index 0000000..5490376 --- /dev/null +++ b/web-react/src/assets/style/dark/lib/tree-layout.less @@ -0,0 +1,83 @@ +@import (reference) '../extend.less'; +@import (reference) './text-color.less'; +.yo-tree-layout { + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + .ant-layout-sider { + background-color: @component-background; + .ant-layout-header { + height: @layout-header-height - 20px; + + background-color: @component-background; + .header-actions { + .ant-input-search { + margin: (@layout-header-height - 20px - 32px) / 2 @padding-md; + } + } + } + } + &--collapsed { + position: absolute; + top: 0; + left: 0; + bottom: 0; + z-index: 4; + + transform: translateX(-100%); + &.open { + transform: translateX(0); + + box-shadow: 2px 0 8px fade(@black , 20%); + } + } + &--bar { + line-height: 20px; + + height: 20px; + padding: 0 @padding-md; + + text-align: right; + >.anticon { + margin-left: @padding-xs; + + cursor: pointer; + + color: fade(@white, 50%); + &:hover { + color: fade(@white, 80%); + } + } + } + &--content { + position: absolute; + top: @layout-header-height; + left: 0; + bottom: 0; + + overflow-y: auto; + + width: 100%; + &::-webkit-scrollbar { + width: 5px; + height: 5px; + + background-color: @component-background; + } + &::-webkit-scrollbar-thumb { + background-color: transparent; + } + &:hover::-webkit-scrollbar-thumb { + background-color: fade(@white, 30%); + } + &::-webkit-scrollbar-thumb:active { + background-color: fade(@white, 45%); + } + } + .ant-tree { + .text-gray(); + } +} diff --git a/web-react/src/assets/style/lib/upload.less b/web-react/src/assets/style/dark/lib/upload.less similarity index 100% rename from web-react/src/assets/style/lib/upload.less rename to web-react/src/assets/style/dark/lib/upload.less diff --git a/web-react/src/assets/style/lib/visibility.less b/web-react/src/assets/style/dark/lib/visibility.less similarity index 100% rename from web-react/src/assets/style/lib/visibility.less rename to web-react/src/assets/style/dark/lib/visibility.less diff --git a/web-react/src/assets/style/lib/width-height.less b/web-react/src/assets/style/dark/lib/width-height.less similarity index 100% rename from web-react/src/assets/style/lib/width-height.less rename to web-react/src/assets/style/dark/lib/width-height.less diff --git a/web-react/src/assets/style/dark/main.less b/web-react/src/assets/style/dark/main.less new file mode 100644 index 0000000..3ea8756 --- /dev/null +++ b/web-react/src/assets/style/dark/main.less @@ -0,0 +1,658 @@ +@import (reference) './extend.less'; +@import (reference) './lib/container.less'; +@import (reference) './lib/text-color.less'; +.yo-layout--spin { + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + + background-color: @layout-header-background; + >.ant-spin-nested-loading { + height: 100%; + >div>.ant-spin { + max-height: none; + @-webkit-keyframes borderScale { + 0% { + border: 5px solid white; + } + 50% { + border: 25px solid transparent; + } + 100% { + border: 5px solid white; + } + } + @keyframes borderScale { + 0% { + border: 5px solid white; + } + 50% { + border: 25px solid transparent; + } + 100% { + border: 5px solid white; + } + } + .loader-container { + position: absolute; + top: 50%; + left: 50%; + + box-sizing: content-box; + width: 200px; + height: 200px; + margin: 0 auto; + margin-right: -50%; + + transform: translate(-50%, -50%); + -webkit-animation: borderScale 1s infinite ease-in-out; + animation: borderScale 1s infinite ease-in-out; + + color: white; + border: 5px solid transparent; + border-radius: 50%; + >p { + font-family: 'Raleway', sans-serif; + font-size: 2em; + font-weight: bold; + + position: absolute; + top: 50%; + left: 50%; + + margin-right: -50%; + + transform: translate(-50%, -50%); + } + } + } + >.ant-spin-container { + width: 100%; + height: 100%; + &.ant-spin-blur { + opacity: 0; + } + } + } +} +.ant-layout-header { + .header-actions { + display: flex; + .header-action { + display: inline-block; + + padding: 0 @padding-md; + + cursor: pointer; + transition: @animation-duration-slow; + transition-property: background-color; + .anticon { + font-size: @font-size-base + 6px; + + transition: @animation-duration-slow; + transition-property: color; + // 特殊工具按钮 + .theme-toggle { + position: relative; + + overflow: hidden; + + width: 20px; + height: 20px; + margin: 7px 0; + + border-radius: 50%; + &--real { + width: 100%; + height: 100%; + + border-radius: 50%; + background-color: #fff; + } + &--imaginary { + position: absolute; + top: 6px; + left: -6px; + + width: 18px; + height: 18px; + + transform: @animation-duration-slow transform; + transform: rotate(45deg) scaleY(1); + transform-origin: top right; + + border-radius: 50%; + background-color: fade(@layout-header-background, 70%); + } + } + } + &:active { + box-shadow: inset 1px 1px 10px rgba(0, 0, 0, .05); + } + } + .ant-select-auto-complete { + margin: (@layout-header-height - 10px - 30px) / 2 @padding-md; + .ant-input-affix-wrapper { + border: 0; + background-color: fade(@white, 15%); + &:focus, + &-focused { + background-color: fade(@white, 30%); + } + .ant-input { + color: fade(@white, 85%); + background-color: transparent; + } + .ant-input-suffix { + .anticon { + color: fade(@white, 60%); + } + } + } + } + } + .user-container { + z-index: 10; + + width: 32px + @padding-sm * 2; + height: @layout-header-height - 24px; + margin: 2px 0; + + transition: @animation-duration-slow; + .user-container-inner { + position: relative; + + transition: @animation-duration-slow; + + border-radius: @border-radius-base; + } + .user { + &--base { + line-height: @layout-header-height - 24px; + + position: relative; + + display: flex; + overflow: hidden; + align-items: center; + + width: 100%; + height: @layout-header-height - 24px; + padding: 0 @padding-sm; + + transition: @animation-duration-slow; + } + &--avatar { + box-shadow: 0 0 0 2px @white; + } + } + } +} +.ant-layout-content { + position: relative; + + overflow-y: auto; + >.yo-tab-external-mount { + position: absolute; + top: 0; + left: 0; + bottom: 0; + + display: flex; + flex-direction: column; + + width: 100%; + >.ant-tabs { + z-index: 5; + + overflow: visible; + >.ant-tabs-nav { + margin-bottom: 0; + + border-bottom: 0; + background-color: @layout-header-background; + box-shadow: 0 2px 12px fade(@black, 8%); + &::before { + content: none; + } + .ant-tabs-nav-container { + height: 30px; + margin-bottom: 0; + } + .ant-tabs-tab { + line-height: 30px; + + height: 30px; + margin-right: 0; + padding: 0; + + transition: none; + + border: 0; + background-color: transparent; + &:hover { + color: @white; + } + .ant-tabs-tab-btn { + transition: none; + } + &.ant-tabs-tab-active { + border-color: darken(@primary-color, 10%); + background-color: @primary-color; + .ant-tabs-tab-btn { + color: @white; + } + .ant-tabs-tab-remove { + color: fade(@white, 70%); + &:hover { + color: @white; + } + } + } + .yo-layout-tab-subtitle { + line-height: 1; + + display: inline-block; + overflow: hidden; + + max-width: 150px; + + transform: translateY(1px); + white-space: nowrap; + text-overflow: ellipsis; + + opacity: .75; + } + +.ant-tabs-tab { + margin-left: 0; + &::before { + position: absolute; + left: -.5px; + + width: 1px; + height: 24px; + + content: ''; + transform: scaleX(.5); + + background: linear-gradient(transparent, fade(@black, 30%), transparent); + } + } + .ant-dropdown-trigger { + padding: 0 @padding-md * 2 0 @padding-md; + } + .ant-tabs-tab-unclosable { + .ant-dropdown-trigger { + padding: 0 @padding-lg 0 @padding-md; + } + } + .ant-tabs-tab-remove { + line-height: 28px; + + position: absolute; + top: 0; + right: 0; + + margin: 0; + + transition: none; + } + } + .ant-tabs-nav-more { + padding: 5px @padding-md; + } + } + } + >.yo-tab-external-mount-content { + position: relative; + + height: 100%; + >.yo-tab-external-tabpane { + position: absolute; + top: 0; + left: 0; + + overflow-x: hidden; + overflow-y: auto; + + width: 100%; + height: 100%; + &.yo-tab-external-tabpane-inactive { + pointer-events: none; + + opacity: 0; + } + >iframe { + display: block; + + width: 100%; + height: 100%; + + border: 0; + } + } + } + } +} +.ant-layout-sider { + .ant-menu-inline { + border-right: 0; + } +} +.yo-nav { + padding-top: @padding-lg; + padding-bottom: @padding-lg; + &--row { + padding: 1px 0; + + column-gap: @padding-md; + column-count: 3; + } + &--col { + break-inside: avoid; + } + &--sub-item { + } + &--item-group { + font-size: @font-size-base; + line-height: 1.5; + + margin-bottom: @padding-xs; + padding-top: @padding-xs * 2; + + color: fade(@black, 35%); + border: @border-width-base @border-style-base transparent; + } + &--item { + font-size: @font-size-base; + line-height: 1.5; + + position: relative; + + margin-bottom: @padding-xs; + padding: @padding-xs @padding-sm; + + cursor: pointer; + transition: @animation-duration-fast; + + border: @border-width-base @border-style-base @border-color-split; + border-radius: @border-radius-base; + background-color: @white; + &:hover { + color: @white; + border-color: @primary-color; + background-color: @primary-color; + } + } +} +.yo-layout-sider { + height: 100%; + + background-color: @layout-header-background; + .ant-layout-sider-children { + display: flex; + flex-direction: column; + } + .logo { + font-size: @font-size-lg * 1.5; + font-weight: 500; + line-height: @layout-header-height + 10px; + + z-index: 11; + + display: flex; + overflow: hidden; + align-items: center; + flex: 0 0 @layout-header-height + 10px; + + height: @layout-header-height + 10px; + padding: 0 @padding-md 0 @padding-lg; + + color: @white; + box-shadow: none; + img { + max-height: 100%; + } + span { + margin-left: @padding-sm; + + transition: @animation-duration-slow; + transition-property: opacity; + } + } + &.ant-layout-sider-collapsed { + .logo { + span { + opacity: 0; + } + } + } + .yo-sider-nav { + position: relative; + z-index: 10; + + flex: 1 1 100%; + + box-shadow: 2px 0 8px fade(@black, 25%); + &--app { + font-size: @font-size-sm; + + margin-top: @padding-sm; + padding: 0 @padding-md; + +.text-gray(); + } + .ant-menu { + background-color: @layout-header-background; + } + .ant-menu-sub.ant-menu-inline { + background-color: fade(@white, 4%); + } + } + .swiper-container { + position: absolute; + top: 0; + left: 0; + bottom: 0; + + width: 100%; + .swiper-scrollbar { + transition: @animation-duration-slow; + transition-property: opacity; + + opacity: 0; + } + .swiper-scrollbar-drag { + background-color: fade(@white, 30%); + } + &:hover { + .swiper-scrollbar { + opacity: 1; + } + } + } + .swiper-slide { + height: auto; + min-height: 100%; + >.ant-spin-nested-loading { + height: 100%; + .ant-spin-blur { + &::after { + opacity: 0; + } + } + } + } +} +.yo-layout--left-menu, +.yo-layout--right-menu { + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + .ant-layout-header { + line-height: @layout-header-height - 20px; + + z-index: 6; + + height: @layout-header-height - 20px; + padding: 0; + + background-color: @white; + >section { + display: flex; + justify-content: space-between; + } + .header-actions { + .header-action { + line-height: @layout-header-height - 16px; + + height: @layout-header-height - 20px; + .anticon { + color: fade(@black, 35%); + } + &:hover { + background-color: fade(@black, 5%); + .anticon { + color: @icon-color-hover; + } + } + } + } + } + >section { + >.ant-layout-sider { + .yo-layout-sider(); + } + } +} +.yo-layout--top-nav { + position: absolute; + top: 0; + left: 0; + + display: flex; + flex-direction: column; + + width: 100%; + height: 100%; + + @layout-header-height: 54px; + .ant-layout-header { + line-height: @layout-header-height; + + z-index: 11; + + flex: 0 0 @layout-header-height; + + height: @layout-header-height; + padding: 0; + + background-color: @layout-header-background; + section { + display: flex; + justify-content: space-between; + + height: 100%; + } + .header-actions { + .header-action { + .anticon { + color: fade(@white, 60%); + } + &:hover { + background-color: fade(@white, 20%); + .anticon { + color: @white; + } + } + } + } + .user-container { + margin: (@layout-header-height - 40px) / 2 0; + } + .logo { + font-size: @font-size-lg * 1.5; + font-weight: 500; + line-height: @layout-header-height - 10px; + + display: flex; + overflow: hidden; + align-items: center; + + height: @layout-header-height 10px; + margin: 5px @padding-lg 5px 0; + + color: @white; + img { + max-height: 100%; + } + span { + margin-left: @padding-sm; + } + } + .ant-menu-horizontal { + line-height: @layout-header-height; + + border-bottom: 0; + >.ant-menu-submenu { + top: 0; + + border-bottom: 0; + } + } + .header-actions { + .header-action { + line-height: @layout-header-height - 16px; + + margin: 10px 0; + } + } + } + &--container { + .ant-layout-header { + .ant-menu-horizontal { + width: 400px; + } + } + .ant-layout-content { + .yo-tab-external-mount { + >.ant-tabs { + >.ant-tabs-bar { + .ant-tabs-nav-container { + width: @container-width - @padding-md * 2; + margin: 0 auto; + } + } + } + } + } + } + &--container-fluid { + .ant-layout-header { + .ant-menu-horizontal { + width: 800px; + } + @media (max-width: 1400px) { + .ant-menu-horizontal { + width: 600px; + } + } + } + } +} +.yo-user-popover { + width: 280px; + padding-top: 0; + .ant-popover-arrow { + display: none; + } + .ant-popover-inner-content { + padding: 0; + } +} diff --git a/web-react/src/pages/system/account/base.less b/web-react/src/assets/style/dark/pages/account-base.less similarity index 94% rename from web-react/src/pages/system/account/base.less rename to web-react/src/assets/style/dark/pages/account-base.less index 1ee4118..6ec0db8 100644 --- a/web-react/src/pages/system/account/base.less +++ b/web-react/src/assets/style/dark/pages/account-base.less @@ -1,4 +1,4 @@ -@import (reference) '~assets/style/app.less'; +@import (reference) '../extend.less'; .yo-avatar-info { position: relative; diff --git a/web-react/src/pages/home/index.less b/web-react/src/assets/style/dark/pages/home.less similarity index 87% rename from web-react/src/pages/home/index.less rename to web-react/src/assets/style/dark/pages/home.less index ffd71ba..e6b1a5f 100644 --- a/web-react/src/pages/home/index.less +++ b/web-react/src/assets/style/dark/pages/home.less @@ -1,9 +1,9 @@ -@import (reference) 'assets/style/app.less'; +@import (reference) '../extend.less'; .home-header { margin-bottom: @padding-md; padding: @padding-lg 0; - background-color: @white; + background-color: @component-background; } .home-header-row { display: flex; diff --git a/web-react/src/assets/style/dark/pages/index.less b/web-react/src/assets/style/dark/pages/index.less new file mode 100644 index 0000000..7927e7a --- /dev/null +++ b/web-react/src/assets/style/dark/pages/index.less @@ -0,0 +1,3 @@ +@import './login.less'; +@import './home.less'; +@import './account-base.less'; diff --git a/web-react/src/views/login/index.less b/web-react/src/assets/style/dark/pages/login.less similarity index 94% rename from web-react/src/views/login/index.less rename to web-react/src/assets/style/dark/pages/login.less index 3fdfe6a..b2e8e8e 100644 --- a/web-react/src/views/login/index.less +++ b/web-react/src/assets/style/dark/pages/login.less @@ -1,4 +1,4 @@ -@import (reference) 'assets/style/app.less'; +@import (reference) '../extend.less'; .yo-login { position: fixed; top: 0; @@ -57,6 +57,8 @@ transition: @animation-duration-base; transform: translate(0); >label { + font-weight: normal !important; + color: fade(@black, 40%); } } @@ -67,6 +69,7 @@ } .ant-input, .ant-input-affix-wrapper { + color: fade(@black, 85%); border-width: 0 0 @border-width-base 0 !important; border-color: fade(@black, 10%); background-color: transparent; diff --git a/web-react/src/assets/style/public.less b/web-react/src/assets/style/dark/public.less similarity index 89% rename from web-react/src/assets/style/public.less rename to web-react/src/assets/style/dark/public.less index 7714511..16a4aed 100644 --- a/web-react/src/assets/style/public.less +++ b/web-react/src/assets/style/dark/public.less @@ -7,7 +7,7 @@ border: @border-width-base @border-style-base @border-color-split; border-radius: @border-radius-base; - background-color: @white; + background-color: @component-background; .amap-icon { img { width: 25px; @@ -23,6 +23,7 @@ width: 25%; min-width: 300px; + background-color: @component-background; box-shadow: @box-shadow-base; } } diff --git a/web-react/src/assets/style/theme/README.md b/web-react/src/assets/style/dark/theme/README.md similarity index 100% rename from web-react/src/assets/style/theme/README.md rename to web-react/src/assets/style/dark/theme/README.md diff --git a/web-react/src/assets/style/dark/theme/primary.less b/web-react/src/assets/style/dark/theme/primary.less new file mode 100644 index 0000000..01fb33e --- /dev/null +++ b/web-react/src/assets/style/dark/theme/primary.less @@ -0,0 +1,5 @@ +@import '../index.less'; +@primary-color: #00a091; +@error-color: @red-7; +@font-size-base: 13px; +@border-radius-base: 0; diff --git a/web-react/src/assets/style/extend.less b/web-react/src/assets/style/default/extend.less similarity index 100% rename from web-react/src/assets/style/extend.less rename to web-react/src/assets/style/default/extend.less diff --git a/web-react/src/assets/style/default/index.less b/web-react/src/assets/style/default/index.less new file mode 100644 index 0000000..8697d9b --- /dev/null +++ b/web-react/src/assets/style/default/index.less @@ -0,0 +1,35 @@ +@import './extend.less'; +@import './lib/visibility.less'; +@import './lib/container.less'; +@import './lib/align.less'; +@import './lib/font-size.less'; +@import './lib/text-color.less'; +@import './lib/margin.less'; +@import './lib/width-height.less'; +@import './lib/scrollbar.less'; +@import './main.less'; +@import './lib/button.less'; +@import './lib/card.less'; +@import './lib/table.less'; +@import './lib/list.less'; +@import './lib/form.less'; +@import './lib/form-page.less'; +@import './lib/page.less'; +@import './lib/description.less'; +@import './lib/input.less'; +@import './lib/select.less'; +@import './lib/checkbox.less'; +@import './lib/radio.less'; +@import './lib/cascader.less'; +@import './lib/upload.less'; +@import './lib/dropdown.less'; +@import './lib/modal.less'; +@import './lib/tree-layout.less'; +@import './lib/authority-view.less'; +@import './lib/icon-selector.less'; +@import './lib/color-selector.less'; +@import './lib/anchor.less'; +@import './lib/disabled.less'; +@import './theme/primary.less'; +@import './public.less'; +@import './pages/index.less'; diff --git a/web-react/src/assets/style/default/lib/align.less b/web-react/src/assets/style/default/lib/align.less new file mode 100644 index 0000000..50f0bda --- /dev/null +++ b/web-react/src/assets/style/default/lib/align.less @@ -0,0 +1,9 @@ +.text-left { + text-align: left !important; +} +.text-center { + text-align: center !important; +} +.text-right { + text-align: right !important; +} diff --git a/web-react/src/assets/style/default/lib/anchor.less b/web-react/src/assets/style/default/lib/anchor.less new file mode 100644 index 0000000..e37e90f --- /dev/null +++ b/web-react/src/assets/style/default/lib/anchor.less @@ -0,0 +1,11 @@ +@import (reference) '../extend.less'; +.ant-anchor-ink-ball { + width: 2px; + height: 28px; + + transform: translate(-50%, -10px); + + border: 0; + border-radius: 0; + background-color: @primary-color; +} diff --git a/web-react/src/assets/style/default/lib/authority-view.less b/web-react/src/assets/style/default/lib/authority-view.less new file mode 100644 index 0000000..94c2f71 --- /dev/null +++ b/web-react/src/assets/style/default/lib/authority-view.less @@ -0,0 +1,53 @@ +@import (reference) '../extend.less'; +.yo-authority-view { + &--container { + >.ant-descriptions-view { + border: 0; + } + } + .ant-descriptions-item-label { + width: 150px; + } + .ant-descriptions { + clear: both; + + margin-bottom: @padding-sm; + .ant-descriptions-view { + overflow: visible; + } + &:last-child { + margin-bottom: 0; + } + } + .ant-descriptions-item-content { + padding: @padding-sm @padding-md; + .yo-authority-view--checkbox { + display: inline-block; + + width: 150px; + margin: @padding-xxs 0; + .ant-checkbox-wrapper { + margin: 0; + } + } + } + .ant-card-grid { + width: 25%; + margin-bottom: @padding-sm; + padding: @padding-xs; + + cursor: pointer; + } + .ant-card { + margin-bottom: 0; + + background-color: transparent; + &-body { + margin: -1px 0 0 -1px; + padding: 0; + } + .ant-card-grid { + margin-bottom: 0; + } + } +} diff --git a/web-react/src/assets/style/default/lib/button.less b/web-react/src/assets/style/default/lib/button.less new file mode 100644 index 0000000..c14e462 --- /dev/null +++ b/web-react/src/assets/style/default/lib/button.less @@ -0,0 +1,4 @@ +@import (reference) '../extend.less'; +.ant-btn { + box-shadow: none; +} diff --git a/web-react/src/assets/style/default/lib/card.less b/web-react/src/assets/style/default/lib/card.less new file mode 100644 index 0000000..7ae210e --- /dev/null +++ b/web-react/src/assets/style/default/lib/card.less @@ -0,0 +1,4 @@ +@import (reference) '../extend.less'; +.ant-card { + margin-bottom: @padding-md; +} diff --git a/web-react/src/assets/style/default/lib/cascader.less b/web-react/src/assets/style/default/lib/cascader.less new file mode 100644 index 0000000..88e0aee --- /dev/null +++ b/web-react/src/assets/style/default/lib/cascader.less @@ -0,0 +1,6 @@ +@import (reference) '../extend.less'; +.ant-cascader-picker-arrow { + svg { + transform: scaleY(.75); + } +} diff --git a/web-react/src/assets/style/default/lib/checkbox.less b/web-react/src/assets/style/default/lib/checkbox.less new file mode 100644 index 0000000..be80e3e --- /dev/null +++ b/web-react/src/assets/style/default/lib/checkbox.less @@ -0,0 +1,10 @@ +@import (reference) '../extend.less'; +.ant-checkbox-wrapper { + margin-right: @padding-xs; + &:last-child { + margin-right: 0; + } + +.ant-checkbox-wrapper { + margin-left: 0; + } +} diff --git a/web-react/src/assets/style/lib/color-selector.less b/web-react/src/assets/style/default/lib/color-selector.less similarity index 100% rename from web-react/src/assets/style/lib/color-selector.less rename to web-react/src/assets/style/default/lib/color-selector.less diff --git a/web-react/src/assets/style/default/lib/container.less b/web-react/src/assets/style/default/lib/container.less new file mode 100644 index 0000000..fba352e --- /dev/null +++ b/web-react/src/assets/style/default/lib/container.less @@ -0,0 +1,43 @@ +@import (reference) '../extend.less'; +@container-width: 1400px; +.container-base { + margin: 0 auto; + padding: 0 @padding-md; +} +.container { + width: @container-width; + +.container-base(); +} +@media (max-width: 1400px) { + .container { + width: auto; + } +} +.container-md { + width: @container-width - 200px; + +.container-base(); +} +.container-sm { + width: @container-width - 400px; + +.container-base(); +} +.container-xs { + width: @container-width - 600px; + +.container-base(); +} +.container-xxs { + width: @container-width - 700px; + +.container-base(); +} +.container-fluid { + .container-base(); +} +.container-flex { + display: flex; + justify-content: space-between; +} diff --git a/web-react/src/assets/style/default/lib/description.less b/web-react/src/assets/style/default/lib/description.less new file mode 100644 index 0000000..cfe090a --- /dev/null +++ b/web-react/src/assets/style/default/lib/description.less @@ -0,0 +1,10 @@ +@import (reference) '../extend.less'; +.ant-descriptions-bordered { + .ant-descriptions-view { + >table { + border-collapse: collapse; + + background-color: @component-background; + } + } +} diff --git a/web-react/src/assets/style/default/lib/disabled.less b/web-react/src/assets/style/default/lib/disabled.less new file mode 100644 index 0000000..c975e17 --- /dev/null +++ b/web-react/src/assets/style/default/lib/disabled.less @@ -0,0 +1,59 @@ +@import (reference) '../extend.less'; +.ant-btn-primary-disabled, +.ant-btn-primary.disabled, +.ant-btn-primary[disabled], +.ant-btn-primary-disabled:hover, +.ant-btn-primary.disabled:hover, +.ant-btn-primary[disabled]:hover, +.ant-btn-primary-disabled:focus, +.ant-btn-primary.disabled:focus, +.ant-btn-primary[disabled]:focus, +.ant-btn-primary-disabled:active, +.ant-btn-primary.disabled:active, +.ant-btn-primary[disabled]:active, +.ant-btn-primary-disabled.active, +.ant-btn-primary.disabled.active, +.ant-btn-primary[disabled].active { + opacity: .5; + color: @btn-primary-color; + border-color: @btn-primary-bg; + background-color: @btn-primary-bg; + box-shadow: @btn-primary-shadow; + text-shadow: @btn-text-shadow; +} +.ant-btn-danger-disabled, +.ant-btn-danger.disabled, +.ant-btn-danger[disabled], +.ant-btn-danger-disabled:hover, +.ant-btn-danger.disabled:hover, +.ant-btn-danger[disabled]:hover, +.ant-btn-danger-disabled:focus, +.ant-btn-danger.disabled:focus, +.ant-btn-danger[disabled]:focus, +.ant-btn-danger-disabled:active, +.ant-btn-danger.disabled:active, +.ant-btn-danger[disabled]:active, +.ant-btn-danger-disabled.active, +.ant-btn-danger.disabled.active, +.ant-btn-danger[disabled].active { + opacity: .5; + color: @btn-danger-color; + border-color: @btn-danger-border; + background-color: @btn-danger-bg; + box-shadow: @btn-primary-shadow; + text-shadow: @btn-text-shadow; +} +.ant-radio-button-wrapper-disabled, +.ant-radio-button-wrapper-disabled:first-child, +.ant-radio-button-wrapper-disabled:hover { + opacity: .5; + color: @radio-button-color; + background-color: @radio-button-bg; +} +.ant-radio-button-wrapper-disabled.ant-radio-button-wrapper-checked { + opacity: .5; + color: @btn-primary-color; + border-color: @btn-primary-bg; + background-color: @btn-primary-bg; + box-shadow: @btn-primary-shadow; +} diff --git a/web-react/src/assets/style/default/lib/dropdown.less b/web-react/src/assets/style/default/lib/dropdown.less new file mode 100644 index 0000000..4accbdb --- /dev/null +++ b/web-react/src/assets/style/default/lib/dropdown.less @@ -0,0 +1,6 @@ +@import (reference) '../extend.less'; +.ant-dropdown-trigger { + .anticon-down { + transform: scaleY(.75); + } +} diff --git a/web-react/src/assets/style/default/lib/font-size.less b/web-react/src/assets/style/default/lib/font-size.less new file mode 100644 index 0000000..67f8742 --- /dev/null +++ b/web-react/src/assets/style/default/lib/font-size.less @@ -0,0 +1,25 @@ +@import (reference) '../extend.less'; +h1, +.h1 { + font-size: 36px; +} +h2, +.h2 { + font-size: 32px; +} +h3, +.h3 { + font-size: 24px; +} +h4, +.h4 { + font-size: 18px; +} +h5, +.h5 { + font-size: 16px; +} +h6, +.h6 { + font-size: 14px; +} diff --git a/web-react/src/assets/style/default/lib/font-weight.less b/web-react/src/assets/style/default/lib/font-weight.less new file mode 100644 index 0000000..b24c9c7 --- /dev/null +++ b/web-react/src/assets/style/default/lib/font-weight.less @@ -0,0 +1,24 @@ +@import (reference) '../extend.less'; +body { + font-weight: 100; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: 300; +} + +@btn-font-weight: 100; +.ant-card-meta-title { + font-weight: inherit; +} +.ant-table-thead { + >tr { + >th { + font-weight: 500; + } + } +} diff --git a/web-react/src/assets/style/default/lib/form-page.less b/web-react/src/assets/style/default/lib/form-page.less new file mode 100644 index 0000000..270d18a --- /dev/null +++ b/web-react/src/assets/style/default/lib/form-page.less @@ -0,0 +1,169 @@ +@import (reference) '../extend.less'; + +.yo-form-page { + position: relative; + + height: 100%; + + .yo-tab-external-mount { + display: flex; + flex-direction: column; + + height: 100%; + + >.ant-tabs { + >.ant-tabs-nav { + margin-bottom: 0; + padding: 0 @padding-md; + + background-color: @component-background; + + &.ant-tabs-card-bar { + .ant-tabs-nav-container { + height: @tabs-card-height + @padding-xs; + padding: (@tabs-card-height + @padding-xs - @btn-height-base) / 2 @padding-md; + } + + .ant-tabs-extra-content { + padding: (@tabs-card-height + @padding-xs - @btn-height-base) / 2 @padding-md; + } + + .ant-tabs-tab { + transition: none; + + .ant-btn(); + + &:hover { + border-color: @btn-default-border; + } + } + + .ant-tabs-tab { + line-height: @btn-height-base; + + margin-right: -1px; + } + + .ant-tabs-tab-active { + z-index: 2; + + color: @btn-primary-color; + border-color: @btn-primary-bg; + background-color: @btn-primary-bg; + + &:hover { + color: @btn-primary-color; + border-color: color(~`colorPalette('@{btn-primary-bg}', 5) `); + background-color: color(~`colorPalette('@{btn-primary-bg}', 5) `); + } + } + } + } + } + + >.yo-tab-external-mount-content { + position: relative; + + flex: 1; + + >.yo-tab-external-tabpane { + position: absolute; + top: 0; + left: 0; + + overflow: auto; + + width: 100%; + height: 100%; + + &.yo-tab-external-tabpane-inactive { + pointer-events: none; + + opacity: 0; + } + } + } + } + + &--bar { + position: sticky; + bottom: 0; + z-index: 200; + + &--with-tab { + position: absolute; + + display: flex; + align-items: flex-end; + + width: 100%; + height: 0; + padding-right: 7px; + + >.container-fluid { + width: 100%; + } + + ~.yo-tab-external-mount { + >.yo-tab-external-mount-content { + >.yo-tab-external-tabpane { + padding-bottom: @padding-xs * 2 + @btn-height-base + @border-width-base * 2; + } + } + } + } + } + + &--bar-inner { + display: flex; + justify-content: space-between; + + padding: @padding-xs @padding-md; + + border: @border-width-base @border-style-base @border-color-split; + background-color: fade(@component-background, 80%); + + backdrop-filter: blur(5px); + + >:first-child { + flex: 1; + } + + .ant-btn { + margin-left: @padding-sm; + } + } + + &--body { + >.ant-card-body { + padding: 0; + + >section { + padding: @padding-lg; + + >h5 { + padding-left: @padding-md; + + border-left: @padding-xs @border-style-base @primary-color; + } + } + } + } + + &-layout { + display: flex; + flex-direction: column; + + height: 100%; + + &--horizontal { + flex-direction: row; + } + } + + &--header { + padding: @padding-md 0; + + background-color: @component-background; + } +} \ No newline at end of file diff --git a/web-react/src/assets/style/lib/form.less b/web-react/src/assets/style/default/lib/form.less similarity index 96% rename from web-react/src/assets/style/lib/form.less rename to web-react/src/assets/style/default/lib/form.less index 4efbe7a..69ea80c 100644 --- a/web-react/src/assets/style/lib/form.less +++ b/web-react/src/assets/style/default/lib/form.less @@ -29,7 +29,7 @@ padding: @padding-xs @padding-md; border: @border-width-base @border-style-base @border-color-split; - background-color: @white; + background-color: @component-background; @box-shadow-focused: 0 0 0 2px fade(@primary-color, 50%); @control-background: lighten(@black, 95%) !important; @@ -58,7 +58,7 @@ } .ant-mentions { textarea { - background-color: lighten(@black, 95%); + background-color: @control-background; } } .focus { @@ -299,7 +299,7 @@ text-align: right; border-top: @border-width-base @border-style-base @border-color-split; - background: @white; + background: @component-background; button+button { margin-left: @padding-xs; } @@ -346,7 +346,7 @@ border-top: 4px solid transparent; border-bottom: 4px solid transparent; - border-left: 5px solid #f5222d; + border-left: 5px solid @highlight-color; background: none; } } @@ -356,7 +356,7 @@ margin-right: @padding-xs; margin-bottom: @padding-xs; - border-left: @border-width-base @border-style-base @normal-color; + border-left: @border-width-base @border-style-base @border-color-base; &.ant-radio-button-wrapper-checked { border-left-color: @primary-color; } diff --git a/web-react/src/assets/style/default/lib/icon-selector.less b/web-react/src/assets/style/default/lib/icon-selector.less new file mode 100644 index 0000000..3438d23 --- /dev/null +++ b/web-react/src/assets/style/default/lib/icon-selector.less @@ -0,0 +1,59 @@ +@import (reference) '../extend.less'; +.yo-icon-selector { + .ant-drawer-wrapper-body { + display: flex; + flex-direction: column; + } + .ant-drawer-body { + position: relative; + + flex: 1 1 100%; + + padding: 0; + } + .ant-tabs { + height: 100%; + .ant-tabs-content-left { + position: relative; + + height: 100%; + .ant-tabs-tabpane { + position: absolute; + top: 0; + left: 0; + + overflow-y: auto; + + width: 100%; + height: 100%; + padding: @padding-lg; + } + } + } + .ant-card { + margin: 0; + } + .ant-card-grid { + width: 25%; + + text-align: center; + >span { + font-size: @font-size-sm; + + display: block; + + margin: @padding-xxs -@padding-lg 0; + + white-space: nowrap; + + color: fade(@black, 50%); + } + &.yo-icon--selected { + color: @white; + background-color: @primary-color; + >span { + color: fade(@white, 50%); + } + } + } +} diff --git a/web-react/src/assets/style/default/lib/input.less b/web-react/src/assets/style/default/lib/input.less new file mode 100644 index 0000000..d464a3c --- /dev/null +++ b/web-react/src/assets/style/default/lib/input.less @@ -0,0 +1,4 @@ +@import (reference) '../extend.less'; +.yo-addon { + padding: 0 @padding-xs; +} diff --git a/web-react/src/assets/style/default/lib/list.less b/web-react/src/assets/style/default/lib/list.less new file mode 100644 index 0000000..2dbb2de --- /dev/null +++ b/web-react/src/assets/style/default/lib/list.less @@ -0,0 +1,95 @@ +@import (reference) '../extend.less'; +.ant-list-bordered { + border-color: @border-color-split; + background-color: @white; +} +.yo-list { + @title-color: lighten(@black, 70%); + @value-color: lighten(@black, 30%); + &-content--h { + display: flex; + align-items: center; + &--item { + margin-left: @padding-xl; + >span { + line-height: 20px; + + color: @title-color; + } + >p { + line-height: 22px; + + margin-top: @padding-xxs; + margin-bottom: 0; + + color: @value-color; + } + } + } + .ant-pagination { + margin: @padding-md 0; + } + .ant-descriptions { + .ant-descriptions-item-label { + color: @title-color; + } + .ant-descriptions-item-content { + color: @value-color; + } + .ant-descriptions-row { + &:last-child { + >td { + padding-bottom: 0; + } + } + } + } + &--scroll { + position: relative; + + overflow-x: auto; + } + .ant-list-items { + min-width: 1000px; + } + .ant-list-item { + transition: @animation-duration-slow; + transition-property: background, border-bottom-color; + &:hover { + border-bottom-color: lighten(@primary-color, 30%); + background: linear-gradient(90deg, transparent 10%, @background-color-light 70%, transparent); + } + } + &-container { + position: relative; + &::before, + &::after { + position: absolute; + top: 0; + bottom: 0; + z-index: 3; + + width: 30px; + + content: ''; + transition: box-shadow @animation-duration-slow; + pointer-events: none; + } + &::before { + left: 0; + } + &::after { + right: 0; + } + &.yo-list--ping-left { + &::before { + box-shadow: inset 10px 0 8px -8px fade(@black, 15%); + } + } + &.yo-list--ping-right { + &::after { + box-shadow: inset -10px 0 8px -8px fade(@black, 15%); + } + } + } +} diff --git a/web-react/src/assets/style/default/lib/margin.less b/web-react/src/assets/style/default/lib/margin.less new file mode 100644 index 0000000..bdc8235 --- /dev/null +++ b/web-react/src/assets/style/default/lib/margin.less @@ -0,0 +1,68 @@ +@import (reference) '../extend.less'; +@margin-padding-position: ~'', ~'-top', ~'-left', ~'-right', ~'-bottom'; +@margin-padding-position-name: ~'', ~'t', ~'l', ~'r', ~'b'; + +.margin-padding (@i) when (@i <=length(@margin-padding-position)) { + @position: extract(@margin-padding-position, @i); + @name: extract(@margin-padding-position-name, @i); + + .m@{name}-xl { + margin@{position}: @padding-xl !important; + } + + .m@{name}-lg { + margin@{position}: @padding-lg !important; + } + + .m@{name}-md { + margin@{position}: @padding-md !important; + } + + .m@{name}-sm { + margin@{position}: @padding-sm !important; + } + + .m@{name}-xs { + margin@{position}: @padding-xs !important; + } + + .m@{name}-xxs { + margin@{position}: @padding-xxs !important; + } + + .p@{name}-xl { + padding@{position}: @padding-xl !important; + } + + .p@{name}-lg { + padding@{position}: @padding-lg !important; + } + + .p@{name}-md { + padding@{position}: @padding-md !important; + } + + .p@{name}-sm { + padding@{position}: @padding-sm !important; + } + + .p@{name}-xs { + padding@{position}: @padding-xs !important; + } + + .p@{name}-xxs { + padding@{position}: @padding-xxs !important; + } + + .m@{name}-none { + margin@{position}: 0 !important; + } + + .p@{name}-none { + padding@{position}: 0 !important; + } + + .margin-padding(@i + 1); +} + +.margin-padding(1); \ No newline at end of file diff --git a/web-react/src/assets/style/default/lib/modal.less b/web-react/src/assets/style/default/lib/modal.less new file mode 100644 index 0000000..8c9c850 --- /dev/null +++ b/web-react/src/assets/style/default/lib/modal.less @@ -0,0 +1,38 @@ +@import (reference) '../extend.less'; +.ant-modal-content { + background-color: fade(@primary-color, 50%); + + backdrop-filter: blur(5px); +} +.ant-modal-header { + padding: @padding-sm @padding-md; + + border-bottom: 0; + background-color: transparent; +} +.ant-modal-title { + color: fade(@white, 85%); +} +.ant-modal-body { + background-color: @component-background; +} +.ant-modal-footer { + background-color: @component-background; +} +.ant-modal-close { + top: 10px; + right: 10px; + + color: fade(@white, 75%); + background-color: @error-color; + &:hover, + &:focus { + color: @white; + } +} +.ant-modal-close-x { + line-height: 26px; + + width: 26px; + height: 26px; +} diff --git a/web-react/src/assets/style/default/lib/page.less b/web-react/src/assets/style/default/lib/page.less new file mode 100644 index 0000000..bda6aa4 --- /dev/null +++ b/web-react/src/assets/style/default/lib/page.less @@ -0,0 +1,8 @@ +@import (reference) '../extend.less'; +.yo-page { + &--header { + padding: @padding-md 0; + + background-color: @white; + } +} diff --git a/web-react/src/assets/style/default/lib/radio.less b/web-react/src/assets/style/default/lib/radio.less new file mode 100644 index 0000000..ab0b99f --- /dev/null +++ b/web-react/src/assets/style/default/lib/radio.less @@ -0,0 +1,7 @@ +@import (reference) '../extend.less'; +.ant-radio-button-wrapper-checked { + &:not(.ant-radio-button-wrapper-disabled), + &:not(.ant-radio-button-wrapper-disabled):hover { + box-shadow: none; + } +} diff --git a/web-react/src/assets/style/lib/scrollbar.less b/web-react/src/assets/style/default/lib/scrollbar.less similarity index 100% rename from web-react/src/assets/style/lib/scrollbar.less rename to web-react/src/assets/style/default/lib/scrollbar.less diff --git a/web-react/src/assets/style/default/lib/select.less b/web-react/src/assets/style/default/lib/select.less new file mode 100644 index 0000000..5f80810 --- /dev/null +++ b/web-react/src/assets/style/default/lib/select.less @@ -0,0 +1,6 @@ +@import (reference) '../extend.less'; +.ant-select-arrow { + .anticon-down { + transform: scaleY(.75); + } +} diff --git a/web-react/src/assets/style/lib/table.less b/web-react/src/assets/style/default/lib/table.less similarity index 98% rename from web-react/src/assets/style/lib/table.less rename to web-react/src/assets/style/default/lib/table.less index 6ed273f..48fbda4 100644 --- a/web-react/src/assets/style/lib/table.less +++ b/web-react/src/assets/style/default/lib/table.less @@ -228,7 +228,7 @@ width: 300px; padding: @padding-xs @padding-sm; - background-color: @white; + background-color: @card-background; } } } diff --git a/web-react/src/assets/style/default/lib/text-color.less b/web-react/src/assets/style/default/lib/text-color.less new file mode 100644 index 0000000..7ba0e79 --- /dev/null +++ b/web-react/src/assets/style/default/lib/text-color.less @@ -0,0 +1,35 @@ +@import (reference) '../extend.less'; +.text-primary { + color: @primary-color; +} +.text-info { + color: @info-color; +} +.text-success { + color: @success-color; +} +.text-processing { + color: @processing-color; +} +.text-error, +.text-danger { + color: @error-color; +} +.text-highlight { + color: @highlight-color; +} +.text-warning { + color: @warning-color; +} +.text-gray { + color: fade(@black, 50%); +} +.text-normal { + color: fade(@black, 30%); +} +.text-white { + color: @white; +} +.text-black { + color: @black; +} diff --git a/web-react/src/assets/style/lib/tree-layout.less b/web-react/src/assets/style/default/lib/tree-layout.less similarity index 87% rename from web-react/src/assets/style/lib/tree-layout.less rename to web-react/src/assets/style/default/lib/tree-layout.less index a54090a..5140cea 100644 --- a/web-react/src/assets/style/lib/tree-layout.less +++ b/web-react/src/assets/style/default/lib/tree-layout.less @@ -1,4 +1,5 @@ @import (reference) '../extend.less'; +@import (reference) './text-color.less'; .yo-tree-layout { position: absolute; top: 0; @@ -7,11 +8,11 @@ width: 100%; height: 100%; .ant-layout-sider { - background-color: @white; + background-color: @component-background; .ant-layout-header { height: @layout-header-height - 20px; - background-color: @white; + background-color: @component-background; .header-actions { .ant-input-search { margin: (@layout-header-height - 20px - 32px) / 2 @padding-md; @@ -64,7 +65,7 @@ width: 5px; height: 5px; - background-color: @white; + background-color: @component-background; } &::-webkit-scrollbar-thumb { background-color: transparent; @@ -77,6 +78,6 @@ } } .ant-tree { - color: fade(@black, 60%); + .text-gray(); } } diff --git a/web-react/src/assets/style/default/lib/upload.less b/web-react/src/assets/style/default/lib/upload.less new file mode 100644 index 0000000..a2aa434 --- /dev/null +++ b/web-react/src/assets/style/default/lib/upload.less @@ -0,0 +1,29 @@ +@import (reference) '../extend.less'; +.ant-upload-list-text { + display: flex; + flex-wrap: wrap; + .ant-upload-list-item { + height: auto; + margin-right: @padding-xs; + } + .ant-upload-list-item-info { + position: relative; + + padding: @padding-xxs @padding-xs; + + border: @border-width-base @border-style-base @border-color-split; + .anticon-paper-clip { + top: 7.5px; + } + >span { + display: flex; + } + } + .ant-upload-list-item-card-actions { + position: relative; + + margin-left: @padding-xs; + + white-space: nowrap; + } +} diff --git a/web-react/src/assets/style/default/lib/visibility.less b/web-react/src/assets/style/default/lib/visibility.less new file mode 100644 index 0000000..3e16f62 --- /dev/null +++ b/web-react/src/assets/style/default/lib/visibility.less @@ -0,0 +1,46 @@ +@import (reference) '../extend.less'; +.hide { + visibility: hidden !important; +} +.hidden { + display: none !important; +} +.block { + display: block; +} +.inline-block { + display: inline-block; +} +.inline { + display: inline; +} +.inline-flex { + display: inline-flex; +} +.flex { + display: flex; +} +.ellipsis { + overflow: hidden; + + white-space: nowrap; + text-overflow: ellipsis; +} +.ellipsis-2 { + display: -webkit-box; + overflow: hidden; + -webkit-box-orient: vertical; + + text-overflow: ellipsis; + + -webkit-line-clamp: 2; +} +.ellipsis-3 { + display: -webkit-box; + overflow: hidden; + -webkit-box-orient: vertical; + + text-overflow: ellipsis; + + -webkit-line-clamp: 3; +} diff --git a/web-react/src/assets/style/default/lib/width-height.less b/web-react/src/assets/style/default/lib/width-height.less new file mode 100644 index 0000000..ae39ddc --- /dev/null +++ b/web-react/src/assets/style/default/lib/width-height.less @@ -0,0 +1,47 @@ +@import (reference) '../extend.less'; + +.width-height (@i) when (@i <=20) { + + @n : @i * 50; + @px : @n * 1px; + + .w-@{n} { + width: @px !important; + } + + .w-@{n}-min { + min-width: @px !important; + } + + .w-@{n}-max { + max-width: @px !important; + } + + .h-@{n} { + height: @px !important; + } + + .h-@{n}-min { + min-height: @px !important; + } + + .h-@{n}-max { + max-height: @px !important; + } + + .w-@{n}-p { + width: @n * 1% !important; + } + + .h-@{n}-p { + height: @n * 1% !important; + } + + .width-height(@i + 1); +} + +.width-height(0); + +.flex-1 { + flex: 1; +} \ No newline at end of file diff --git a/web-react/src/assets/style/default/main.less b/web-react/src/assets/style/default/main.less new file mode 100644 index 0000000..fa81795 --- /dev/null +++ b/web-react/src/assets/style/default/main.less @@ -0,0 +1,618 @@ +@import (reference) './extend.less'; +@import (reference) './lib/container.less'; +@import (reference) './lib/text-color.less'; +.yo-layout--spin { + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + + background-color: @layout-header-background; + >.ant-spin-nested-loading { + height: 100%; + >div>.ant-spin { + max-height: none; + @-webkit-keyframes borderScale { + 0% { + border: 5px solid white; + } + 50% { + border: 25px solid transparent; + } + 100% { + border: 5px solid white; + } + } + @keyframes borderScale { + 0% { + border: 5px solid white; + } + 50% { + border: 25px solid transparent; + } + 100% { + border: 5px solid white; + } + } + .loader-container { + position: absolute; + top: 50%; + left: 50%; + + box-sizing: content-box; + width: 200px; + height: 200px; + margin: 0 auto; + margin-right: -50%; + + transform: translate(-50%, -50%); + -webkit-animation: borderScale 1s infinite ease-in-out; + animation: borderScale 1s infinite ease-in-out; + + color: white; + border: 5px solid transparent; + border-radius: 50%; + >p { + font-family: 'Raleway', sans-serif; + font-size: 2em; + font-weight: bold; + + position: absolute; + top: 50%; + left: 50%; + + margin-right: -50%; + + transform: translate(-50%, -50%); + } + } + } + >.ant-spin-container { + width: 100%; + height: 100%; + &.ant-spin-blur { + opacity: 0; + } + } + } +} +.ant-layout-header { + .header-actions { + display: flex; + .header-action { + display: inline-block; + + padding: 0 @padding-md; + + cursor: pointer; + transition: @animation-duration-slow; + transition-property: background-color; + .anticon { + font-size: @font-size-base + 6px; + + transition: @animation-duration-slow; + transition-property: color; + } + &:active { + box-shadow: inset 1px 1px 10px rgba(0, 0, 0, .05); + } + } + .ant-select-auto-complete { + margin: (@layout-header-height - 10px - 30px) / 2 @padding-md; + .ant-input-affix-wrapper { + border: 0; + background-color: fade(@white, 15%); + &:focus, + &-focused { + background-color: fade(@white, 30%); + } + .ant-input { + color: fade(@white, 85%); + background-color: transparent; + } + .ant-input-suffix { + .anticon { + color: fade(@white, 60%); + } + } + } + } + } + .user-container { + z-index: 10; + + width: 32px + @padding-sm * 2; + height: @layout-header-height - 24px; + margin: 2px 0; + + transition: @animation-duration-slow; + .user-container-inner { + position: relative; + + transition: @animation-duration-slow; + + border-radius: @border-radius-base; + } + .user { + &--base { + line-height: @layout-header-height - 24px; + + position: relative; + + display: flex; + overflow: hidden; + align-items: center; + + width: 100%; + height: @layout-header-height - 24px; + padding: 0 @padding-sm; + + transition: @animation-duration-slow; + } + &--avatar { + box-shadow: 0 0 0 2px @white; + } + } + } +} +.ant-layout-content { + position: relative; + + overflow-y: auto; + >.yo-tab-external-mount { + position: absolute; + top: 0; + left: 0; + bottom: 0; + + display: flex; + flex-direction: column; + + width: 100%; + >.ant-tabs { + z-index: 5; + + overflow: visible; + >.ant-tabs-nav { + margin-bottom: 0; + + border-bottom: 0; + background-color: @card-background; + box-shadow: 0 2px 12px fade(@black, 8%); + &::before { + content: none; + } + .ant-tabs-nav-container { + height: 30px; + margin-bottom: 0; + } + .ant-tabs-tab { + line-height: 30px; + + height: 30px; + margin-right: 0; + padding: 0; + + transition: none; + + border: 0; + background-color: transparent; + &:hover { + color: @black; + } + .ant-tabs-tab-btn { + transition: none; + } + &.ant-tabs-tab-active { + border-color: darken(@primary-color, 10%); + background-color: @primary-color; + .ant-tabs-tab-btn { + color: @white; + } + .ant-tabs-tab-remove { + color: fade(@white, 70%); + &:hover { + color: @white; + } + } + } + .yo-layout-tab-subtitle { + line-height: 1; + + display: inline-block; + overflow: hidden; + + max-width: 150px; + + transform: translateY(1px); + white-space: nowrap; + text-overflow: ellipsis; + + opacity: .75; + } + +.ant-tabs-tab { + margin-left: 0; + &::before { + position: absolute; + left: -.5px; + + width: 1px; + height: 24px; + + content: ''; + transform: scaleX(.5); + + background: linear-gradient(transparent, fade(@black, 30%), transparent); + } + } + .ant-dropdown-trigger { + padding: 0 @padding-md * 2 0 @padding-md; + } + .ant-tabs-tab-unclosable { + .ant-dropdown-trigger { + padding: 0 @padding-lg 0 @padding-md; + } + } + .ant-tabs-tab-remove { + line-height: 28px; + + position: absolute; + top: 0; + right: 0; + + margin: 0; + + transition: none; + } + } + .ant-tabs-nav-more { + padding: 5px @padding-md; + } + } + } + >.yo-tab-external-mount-content { + position: relative; + + height: 100%; + >.yo-tab-external-tabpane { + position: absolute; + top: 0; + left: 0; + + overflow-x: hidden; + overflow-y: auto; + + width: 100%; + height: 100%; + &.yo-tab-external-tabpane-inactive { + pointer-events: none; + + opacity: 0; + } + >iframe { + display: block; + + width: 100%; + height: 100%; + + border: 0; + } + } + } + } +} +.ant-layout-sider { + .ant-menu-inline { + border-right: 0; + } +} +.yo-nav { + padding-top: @padding-lg; + padding-bottom: @padding-lg; + &--row { + padding: 1px 0; + + column-gap: @padding-md; + column-count: 3; + } + &--col { + break-inside: avoid; + } + &--sub-item { + } + &--item-group { + font-size: @font-size-base; + line-height: 1.5; + + margin-bottom: @padding-xs; + padding-top: @padding-xs * 2; + + color: fade(@black, 35%); + border: @border-width-base @border-style-base transparent; + } + &--item { + font-size: @font-size-base; + line-height: 1.5; + + position: relative; + + margin-bottom: @padding-xs; + padding: @padding-xs @padding-sm; + + cursor: pointer; + transition: @animation-duration-fast; + + border: @border-width-base @border-style-base @border-color-split; + border-radius: @border-radius-base; + background-color: @white; + &:hover { + color: @white; + border-color: @primary-color; + background-color: @primary-color; + } + } +} +.yo-layout-sider { + height: 100%; + + background-color: @white; + .ant-layout-sider-children { + display: flex; + flex-direction: column; + } + .logo { + font-size: @font-size-lg * 1.5; + font-weight: 500; + line-height: @layout-header-height + 10px; + + z-index: 11; + + display: flex; + overflow: hidden; + align-items: center; + flex: 0 0 @layout-header-height + 10px; + + height: @layout-header-height + 10px; + padding: 0 @padding-md 0 @padding-lg; + + color: @white; + box-shadow: none; + img { + max-height: 100%; + } + span { + margin-left: @padding-sm; + + transition: @animation-duration-slow; + transition-property: opacity; + } + } + &.ant-layout-sider-collapsed { + .logo { + span { + opacity: 0; + } + } + } + .yo-sider-nav { + position: relative; + z-index: 10; + + flex: 1 1 100%; + + box-shadow: 2px 0 8px fade(@black, 25%); + &--app { + font-size: @font-size-sm; + + margin-top: @padding-sm; + padding: 0 @padding-md; + +.text-gray(); + } + } + .swiper-container { + position: absolute; + top: 0; + left: 0; + bottom: 0; + + width: 100%; + .swiper-scrollbar { + transition: @animation-duration-slow; + transition-property: opacity; + + opacity: 0; + } + .swiper-scrollbar-drag { + background-color: fade(@white, 30%); + } + &:hover { + .swiper-scrollbar { + opacity: 1; + } + } + } + .swiper-slide { + height: auto; + min-height: 100%; + >.ant-spin-nested-loading { + height: 100%; + .ant-spin-blur { + &::after { + opacity: 0; + } + } + } + } +} +.yo-layout--left-menu, +.yo-layout--right-menu { + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + .ant-layout-header { + line-height: @layout-header-height - 20px; + + z-index: 6; + + height: @layout-header-height - 20px; + padding: 0; + + background-color: @white; + >section { + display: flex; + justify-content: space-between; + } + .header-actions { + .header-action { + line-height: @layout-header-height - 16px; + + height: @layout-header-height - 20px; + .anticon { + color: fade(@black, 35%); + } + &:hover { + background-color: fade(@black, 5%); + .anticon { + color: @icon-color-hover; + } + } + } + } + } + >section { + >.ant-layout-sider { + .yo-layout-sider(); + } + } +} +.yo-layout--top-nav { + position: absolute; + top: 0; + left: 0; + + display: flex; + flex-direction: column; + + width: 100%; + height: 100%; + + @layout-header-height: 54px; + .ant-layout-header { + line-height: @layout-header-height; + + z-index: 11; + + flex: 0 0 @layout-header-height; + + height: @layout-header-height; + padding: 0; + + background-color: @layout-header-background; + section { + display: flex; + justify-content: space-between; + + height: 100%; + } + .header-actions { + .header-action { + .anticon { + color: fade(@white, 60%); + } + &:hover { + background-color: fade(@white, 20%); + .anticon { + color: @white; + } + } + } + } + .user-container { + margin: (@layout-header-height - 40px) / 2 0; + } + .logo { + font-size: @font-size-lg * 1.5; + font-weight: 500; + line-height: @layout-header-height - 10px; + + display: flex; + overflow: hidden; + align-items: center; + + height: @layout-header-height 10px; + margin: 5px @padding-lg 5px 0; + + color: @white; + img { + max-height: 100%; + } + span { + margin-left: @padding-sm; + } + } + .ant-menu-horizontal { + line-height: @layout-header-height; + + border-bottom: 0; + >.ant-menu-submenu { + top: 0; + + border-bottom: 0; + } + } + .header-actions { + .header-action { + line-height: @layout-header-height - 16px; + + margin: 10px 0; + } + } + } + &--container { + .ant-layout-header { + .ant-menu-horizontal { + width: 400px; + } + } + .ant-layout-content { + .yo-tab-external-mount { + >.ant-tabs { + >.ant-tabs-bar { + .ant-tabs-nav-container { + width: @container-width - @padding-md * 2; + margin: 0 auto; + } + } + } + } + } + } + &--container-fluid { + .ant-layout-header { + .ant-menu-horizontal { + width: 800px; + } + @media (max-width: 1400px) { + .ant-menu-horizontal { + width: 600px; + } + } + } + } +} +.yo-user-popover { + width: 280px; + padding-top: 0; + .ant-popover-arrow { + display: none; + } + .ant-popover-inner-content { + padding: 0; + } +} diff --git a/web-react/src/assets/style/default/pages/account-base.less b/web-react/src/assets/style/default/pages/account-base.less new file mode 100644 index 0000000..6ec0db8 --- /dev/null +++ b/web-react/src/assets/style/default/pages/account-base.less @@ -0,0 +1,51 @@ +@import (reference) '../extend.less'; +.yo-avatar-info { + position: relative; + + overflow: hidden; + + width: 128px; + margin: 0 auto; + + border-radius: 50%; + &--cover { + font-size: @font-size-lg * 2; + + position: absolute; + top: 0; + left: 0; + + display: flex; + align-items: center; + justify-content: center; + + width: 100%; + height: 100%; + + cursor: pointer; + transition: @animation-duration-slow; + + opacity: 0; + color: @white; + background-color: fade(@black, 50%); + &:hover { + opacity: 1; + } + } +} +.yo-avatar-cropper { + overflow: hidden; + + border-radius: @border-radius-base; + background-color: #ccc; +} +.yo-avatar-preview { + overflow: hidden; + + width: 200px; + height: 200px; + margin: 0 auto; + + border-radius: 50%; + background: #ccc; +} diff --git a/web-react/src/assets/style/default/pages/home.less b/web-react/src/assets/style/default/pages/home.less new file mode 100644 index 0000000..e6b1a5f --- /dev/null +++ b/web-react/src/assets/style/default/pages/home.less @@ -0,0 +1,42 @@ +@import (reference) '../extend.less'; +.home-header { + margin-bottom: @padding-md; + padding: @padding-lg 0; + + background-color: @component-background; +} +.home-header-row { + display: flex; +} +.home-header-content { + margin-left: @padding-lg; + h4 { + span { + color: @primary-color; + } + } + p { + margin: 0; + } +} +.home-container { + .ant-card-meta-title { + font-size: @font-size-base + 1px; + + display: -webkit-box; + -webkit-box-orient: vertical; + + height: 42px; + + white-space: normal; + + -webkit-line-clamp: 2; + } + .ant-card-meta-description { + .ant-row { + line-height: 24px; + + height: 24px; + } + } +} diff --git a/web-react/src/assets/style/default/pages/index.less b/web-react/src/assets/style/default/pages/index.less new file mode 100644 index 0000000..7927e7a --- /dev/null +++ b/web-react/src/assets/style/default/pages/index.less @@ -0,0 +1,3 @@ +@import './login.less'; +@import './home.less'; +@import './account-base.less'; diff --git a/web-react/src/assets/style/default/pages/login.less b/web-react/src/assets/style/default/pages/login.less new file mode 100644 index 0000000..b2e8e8e --- /dev/null +++ b/web-react/src/assets/style/default/pages/login.less @@ -0,0 +1,86 @@ +@import (reference) '../extend.less'; +.yo-login { + position: fixed; + top: 0; + left: 0; + + width: 100%; + height: 100%; + >img { + display: block; + + width: 100%; + height: 100%; + + object-fit: cover; + } + &::before { + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + + content: ''; + + background: fade(@black, 30%) url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABZJREFUeNpiMLJ0+w8EDIwgAgQAAgwAUdAHrAFSJ6cAAAAASUVORK5CYII=); + } + &--placeholder { + position: absolute; + top: 50%; + left: 0; + + width: 100%; + height: 0; + .container-sm { + display: flex; + align-items: center; + justify-content: flex-end; + + height: 0; + } + } + .ant-form { + width: 300px; + padding: @padding-lg; + + border-radius: @border-radius-base + 2px; + background: linear-gradient(45deg, @white, fade(@white, 80%)); + } + .ant-form-item { + margin-bottom: 0; + } + .ant-form-item-label { + padding: @padding-xs 0 0 !important; + + transition: @animation-duration-base; + transform: translate(0); + >label { + font-weight: normal !important; + + color: fade(@black, 40%); + } + } + &--label { + .ant-form-item-label { + transform: translate(11px, 28px); + } + } + .ant-input, + .ant-input-affix-wrapper { + color: fade(@black, 85%); + border-width: 0 0 @border-width-base 0 !important; + border-color: fade(@black, 10%); + background-color: transparent; + } + .ant-input:hover, + .ant-input:focus, + .ant-input-affix-wrapper:not(.ant-input-affix-wrapper-disabled):hover, + .ant-input-affix-wrapper:focus, + .ant-input-affix-wrapper-focused { + border-width: 0 0 @border-width-base 0 !important; + border-color: @primary-color; + box-shadow: none !important; + } +} diff --git a/web-react/src/assets/style/default/public.less b/web-react/src/assets/style/default/public.less new file mode 100644 index 0000000..16a4aed --- /dev/null +++ b/web-react/src/assets/style/default/public.less @@ -0,0 +1,45 @@ +@import (reference) './extend.less'; +.yo-map { + &-container { + position: relative; + + padding: @padding-sm; + + border: @border-width-base @border-style-base @border-color-split; + border-radius: @border-radius-base; + background-color: @component-background; + .amap-icon { + img { + width: 25px; + } + } + } + &--search { + position: absolute; + top: @padding-md; + left: @padding-md; + z-index: 20; + + width: 25%; + min-width: 300px; + + background-color: @component-background; + box-shadow: @box-shadow-base; + } +} +.yo-adorn { + &--house-top { + height: 65px; + + background: url('~assets/image/adorn/house-top-01.png') no-repeat bottom right; + } +} +a.link-gray { + color: fade(@black, 50%); + &:hover { + color: @link-hover-color; + } + &:active { + color: @link-active-color; + } +} diff --git a/web-react/src/assets/style/default/theme/README.md b/web-react/src/assets/style/default/theme/README.md new file mode 100644 index 0000000..d6f8b27 --- /dev/null +++ b/web-react/src/assets/style/default/theme/README.md @@ -0,0 +1 @@ +/** 在此文件夹中添加控制主题颜色的less文件 **/ \ No newline at end of file diff --git a/web-react/src/assets/style/theme/primary.less b/web-react/src/assets/style/default/theme/primary.less similarity index 81% rename from web-react/src/assets/style/theme/primary.less rename to web-react/src/assets/style/default/theme/primary.less index 3d4f9b8..5b6f5a8 100644 --- a/web-react/src/assets/style/theme/primary.less +++ b/web-react/src/assets/style/default/theme/primary.less @@ -1,4 +1,4 @@ -@import '../app.less'; +@import '../index.less'; @primary-color: #007bff; @font-size-base: 13px; @border-radius-base: 0; diff --git a/web-react/src/assets/style/frame/dark.less b/web-react/src/assets/style/frame/dark.less deleted file mode 100644 index 19da8cd..0000000 --- a/web-react/src/assets/style/frame/dark.less +++ /dev/null @@ -1,13 +0,0 @@ -@import (reference) '../main.less'; -@layout-header-background: #1c2127; -.dark { - .main(@nav-background: @layout-header-background; - @nav-box-shadow-color: fade(@black, 25%); - @nav-scrollbar-background: fade(@white, 50%); - @nav-app-color: fade(@white, 35%); - @logo-color: @white; - @logo-box-shadow: none; - @header-action-color: fade(@white, 60%); - @header-action-hover-color: @white; - @header-action-hover-background: fade(@white, 20%)); -} diff --git a/web-react/src/assets/style/frame/light.less b/web-react/src/assets/style/frame/light.less deleted file mode 100644 index ea9fb10..0000000 --- a/web-react/src/assets/style/frame/light.less +++ /dev/null @@ -1,12 +0,0 @@ -@import (reference) '../main.less'; -.light { - .main(@nav-background: @white; - @nav-box-shadow-color: fade(@black, 5%); - @nav-scrollbar-background: fade(@black, 30%); - @nav-app-color: fade(@black, 35%); - @logo-color: @black; - @logo-box-shadow: inset -1px -1px 1px @border-color-split; - @header-action-color: fade(@black, 35%); - @header-action-hover-color: @icon-color-hover; - @header-action-hover-background: fade(@black, 5%)); -} diff --git a/web-react/src/assets/style/main.less b/web-react/src/assets/style/main.less deleted file mode 100644 index 3abb0d5..0000000 --- a/web-react/src/assets/style/main.less +++ /dev/null @@ -1,628 +0,0 @@ -@import (reference) './extend.less'; -@import (reference) './lib/container.less'; - -.main(@nav-background: @layout-header-background, - @nav-box-shadow-color: fade(@black, 25%), - @nav-scrollbar-background: fade(@white, 30%), - @nav-app-color: fade(@white, 35%), - @logo-color: @white, - @logo-box-shadow: none, - @header-action-color: fade(@white, 60%), - @header-action-hover-color: @white, - @header-action-hover-background: fade(@white, 20%)) { - .yo-layout--spin { - position: absolute; - top: 0; - left: 0; - - width: 100%; - height: 100%; - - background-color: @layout-header-background; - >.ant-spin-nested-loading { - height: 100%; - >div>.ant-spin { - max-height: none; - @-webkit-keyframes borderScale { - 0% { - border: 5px solid white; - } - 50% { - border: 25px solid transparent; - } - 100% { - border: 5px solid white; - } - } - @keyframes borderScale { - 0% { - border: 5px solid white; - } - 50% { - border: 25px solid transparent; - } - 100% { - border: 5px solid white; - } - } - .loader-container { - position: absolute; - top: 50%; - left: 50%; - - box-sizing: content-box; - width: 200px; - height: 200px; - margin: 0 auto; - margin-right: -50%; - - transform: translate(-50%, -50%); - -webkit-animation: borderScale 1s infinite ease-in-out; - animation: borderScale 1s infinite ease-in-out; - - color: white; - border: 5px solid transparent; - border-radius: 50%; - >p { - font-family: 'Raleway', sans-serif; - font-size: 2em; - font-weight: bold; - - position: absolute; - top: 50%; - left: 50%; - - margin-right: -50%; - - transform: translate(-50%, -50%); - } - } - } - >.ant-spin-container { - width: 100%; - height: 100%; - &.ant-spin-blur { - opacity: 0; - } - } - } - } - .ant-layout-header { - .header-actions { - display: flex; - .header-action { - display: inline-block; - - padding: 0 @padding-md; - - cursor: pointer; - transition: @animation-duration-slow; - transition-property: background-color; - .anticon { - font-size: @font-size-base + 6px; - - transition: @animation-duration-slow; - transition-property: color; - } - &:active { - box-shadow: inset 1px 1px 10px rgba(0, 0, 0, .05); - } - } - .ant-select-auto-complete { - margin: (@layout-header-height - 10px - 30px) / 2 @padding-md; - .ant-input-affix-wrapper { - border: 0; - background-color: fade(@white, 15%); - &:focus, - &-focused { - background-color: fade(@white, 30%); - } - .ant-input { - color: fade(@white, 85%); - background-color: transparent; - } - .ant-input-suffix { - .anticon { - color: fade(@white, 60%); - } - } - } - } - } - .user-container { - z-index: 10; - - width: 32px + @padding-sm * 2; - height: @layout-header-height - 24px; - margin: 2px 0; - - transition: @animation-duration-slow; - .user-container-inner { - position: relative; - - transition: @animation-duration-slow; - - border-radius: @border-radius-base; - } - .user { - &--base { - line-height: @layout-header-height - 24px; - - position: relative; - - display: flex; - overflow: hidden; - align-items: center; - - width: 100%; - height: @layout-header-height - 24px; - padding: 0 @padding-sm; - - transition: @animation-duration-slow; - } - &--avatar { - box-shadow: 0 0 0 2px @white; - } - } - } - } - .ant-layout-content { - position: relative; - - overflow-y: auto; - >.yo-tab-external-mount { - position: absolute; - top: 0; - left: 0; - bottom: 0; - - display: flex; - flex-direction: column; - - width: 100%; - >.ant-tabs { - z-index: 5; - - overflow: visible; - >.ant-tabs-nav { - margin-bottom: 0; - - border-bottom: 0; - background-color: @white; - box-shadow: 0 2px 12px fade(@black, 8%); - &::before { - content: none; - } - .ant-tabs-nav-container { - height: 30px; - margin-bottom: 0; - } - .ant-tabs-tab { - line-height: 30px; - - height: 30px; - margin-right: 0; - padding: 0; - - transition: none; - - border: 0; - background-color: transparent; - &:hover { - color: @black; - } - .ant-tabs-tab-btn { - transition: none; - } - &.ant-tabs-tab-active { - border-color: darken(@primary-color, 10%); - background-color: @primary-color; - .ant-tabs-tab-btn { - color: @white; - } - .ant-tabs-tab-remove { - color: fade(@white, 70%); - &:hover { - color: @white; - } - } - } - .yo-layout-tab-subtitle { - line-height: 1; - - display: inline-block; - overflow: hidden; - - max-width: 150px; - - transform: translateY(1px); - white-space: nowrap; - text-overflow: ellipsis; - - opacity: .75; - } - +.ant-tabs-tab { - margin-left: 0; - &::before { - position: absolute; - left: -.5px; - - width: 1px; - height: 24px; - - content: ''; - transform: scaleX(.5); - - background: linear-gradient(transparent, fade(@black, 30%), transparent); - } - } - .ant-dropdown-trigger { - padding: 0 @padding-md * 2 0 @padding-md; - } - .ant-tabs-tab-unclosable { - .ant-dropdown-trigger { - padding: 0 @padding-lg 0 @padding-md; - } - } - .ant-tabs-tab-remove { - line-height: 28px; - - position: absolute; - top: 0; - right: 0; - - margin: 0; - - transition: none; - } - } - .ant-tabs-nav-more { - padding: 5px @padding-md; - } - } - } - >.yo-tab-external-mount-content { - position: relative; - - height: 100%; - >.yo-tab-external-tabpane { - position: absolute; - top: 0; - left: 0; - - overflow-x: hidden; - overflow-y: auto; - - width: 100%; - height: 100%; - &.yo-tab-external-tabpane-inactive { - pointer-events: none; - - opacity: 0; - } - >iframe { - display: block; - - width: 100%; - height: 100%; - - border: 0; - } - } - } - } - } - .ant-layout-sider { - .ant-menu-inline { - border-right: 0; - } - } - .yo-nav { - padding-top: @padding-lg; - padding-bottom: @padding-lg; - &--row { - padding: 1px 0; - - column-gap: @padding-md; - column-count: 3; - } - &--col { - break-inside: avoid; - } - &--sub-item { - } - &--item-group { - font-size: @font-size-base; - line-height: 1.5; - - margin-bottom: @padding-xs; - padding-top: @padding-xs * 2; - - color: fade(@black, 35%); - border: @border-width-base @border-style-base transparent; - } - &--item { - font-size: @font-size-base; - line-height: 1.5; - - position: relative; - - margin-bottom: @padding-xs; - padding: @padding-xs @padding-sm; - - cursor: pointer; - transition: @animation-duration-fast; - - border: @border-width-base @border-style-base @border-color-split; - border-radius: @border-radius-base; - background-color: @white; - &:hover { - color: @white; - border-color: @primary-color; - background-color: @primary-color; - } - } - } - .yo-layout-sider { - height: 100%; - - background-color: @nav-background; - .ant-layout-sider-children { - display: flex; - flex-direction: column; - } - .logo { - font-size: @font-size-lg * 1.5; - font-weight: 500; - line-height: @layout-header-height + 10px; - - z-index: 11; - - display: flex; - overflow: hidden; - align-items: center; - flex: 0 0 @layout-header-height + 10px; - - height: @layout-header-height + 10px; - padding: 0 @padding-md 0 @padding-lg; - - color: @logo-color; - box-shadow: @logo-box-shadow; - img { - max-height: 100%; - } - span { - margin-left: @padding-sm; - - transition: @animation-duration-slow; - transition-property: opacity; - } - } - &.ant-layout-sider-collapsed { - .logo { - span { - opacity: 0; - } - } - } - .yo-sider-nav { - position: relative; - z-index: 10; - - flex: 1 1 100%; - - box-shadow: 2px 0 8px @nav-box-shadow-color; - &--app { - font-size: @font-size-sm; - - margin-top: @padding-sm; - padding: 0 @padding-md; - - color: @nav-app-color; - } - } - .swiper-container { - position: absolute; - top: 0; - left: 0; - bottom: 0; - - width: 100%; - .swiper-scrollbar { - transition: @animation-duration-slow; - transition-property: opacity; - - opacity: 0; - } - .swiper-scrollbar-drag { - background-color: @nav-scrollbar-background; - } - &:hover { - .swiper-scrollbar { - opacity: 1; - } - } - } - .swiper-slide { - height: auto; - min-height: 100%; - >.ant-spin-nested-loading { - height: 100%; - .ant-spin-blur { - &::after { - opacity: 0; - } - } - } - } - } - .yo-layout--left-menu, - .yo-layout--right-menu { - position: absolute; - top: 0; - left: 0; - - width: 100%; - height: 100%; - .ant-layout-header { - line-height: @layout-header-height - 20px; - - z-index: 6; - - height: @layout-header-height - 20px; - padding: 0; - - background-color: @white; - >section { - display: flex; - justify-content: space-between; - } - .header-actions { - .header-action { - line-height: @layout-header-height - 16px; - - height: @layout-header-height - 20px; - .anticon { - color: fade(@black, 35%); - } - &:hover { - background-color: fade(@black, 5%); - .anticon { - color: @icon-color-hover; - } - } - } - } - } - >section { - >.ant-layout-sider { - .yo-layout-sider(); - } - } - } - .yo-layout--top-nav { - position: absolute; - top: 0; - left: 0; - - display: flex; - flex-direction: column; - - width: 100%; - height: 100%; - - @layout-header-height: 54px; - .ant-layout-header { - line-height: @layout-header-height; - - z-index: 11; - - flex: 0 0 @layout-header-height; - - height: @layout-header-height; - padding: 0; - - background-color: @nav-background; - section { - display: flex; - justify-content: space-between; - - height: 100%; - } - .header-actions { - .header-action { - .anticon { - color: @header-action-color; - } - &:hover { - background-color: @header-action-hover-background; - .anticon { - color: @header-action-hover-color; - } - } - } - } - .user-container { - margin: (@layout-header-height - 40px) / 2 0; - } - .logo { - font-size: @font-size-lg * 1.5; - font-weight: 500; - line-height: @layout-header-height - 10px; - - display: flex; - overflow: hidden; - align-items: center; - - height: @layout-header-height 10px; - margin: 5px @padding-lg 5px 0; - - color: @logo-color; - img { - max-height: 100%; - } - span { - margin-left: @padding-sm; - } - } - .ant-menu-horizontal { - line-height: @layout-header-height; - - border-bottom: 0; - >.ant-menu-submenu { - top: 0; - - border-bottom: 0; - } - } - .header-actions { - .header-action { - line-height: @layout-header-height - 16px; - - margin: 10px 0; - } - } - } - &--container { - .ant-layout-header { - .ant-menu-horizontal { - width: 400px; - } - } - .ant-layout-content { - .yo-tab-external-mount { - >.ant-tabs { - >.ant-tabs-bar { - .ant-tabs-nav-container { - width: @container-width - @padding-md * 2; - margin: 0 auto; - } - } - } - } - } - } - &--container-fluid { - .ant-layout-header { - .ant-menu-horizontal { - width: 800px; - } - @media (max-width: 1400px) { - .ant-menu-horizontal { - width: 600px; - } - } - } - } - } -} -.yo-user-popover { - width: 280px; - padding-top: 0; - .ant-popover-arrow { - display: none; - } - .ant-popover-inner-content { - padding: 0; - } -} diff --git a/web-react/src/index.js b/web-react/src/index.js index 8c136cd..f63c526 100644 --- a/web-react/src/index.js +++ b/web-react/src/index.js @@ -5,10 +5,20 @@ import reportWebVitals from './reportWebVitals'; import { ConfigProvider } from 'antd' import { AntIcon } from 'components' +import { SETTING_KEY } from 'common/storage'; import zhCN from 'antd/lib/locale/zh_CN' import moment from 'moment' import 'moment/locale/zh-cn' -import './assets/style/app.less' + +const SETTING = JSON.parse(window.localStorage.getItem(SETTING_KEY)) || { + theme: 'default' +}; + +if (SETTING.theme === 'dark') { + require('./assets/style/dark/index.less') +} else { + require('./assets/style/default/index.less') +} moment.locale('zh-cn') @@ -34,7 +44,4 @@ ReactDOM.render( // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals -reportWebVitals(); - - -document.body.classList.add('yo-nav-theme--dark') \ No newline at end of file +reportWebVitals(); \ No newline at end of file diff --git a/web-react/src/pages/home/index.jsx b/web-react/src/pages/home/index.jsx index dc6292d..0d02873 100644 --- a/web-react/src/pages/home/index.jsx +++ b/web-react/src/pages/home/index.jsx @@ -4,7 +4,6 @@ import { isEqual } from 'lodash' import store from 'store' import { Container, Image, AntIcon } from 'components' import moment from 'moment' -import './index.less' import Statistics from './statistics' import Task from './task' @@ -17,9 +16,8 @@ const { getState, subscribe } = store const storePath = 'user' export default class index extends Component { - state = { - [storePath]: getState(storePath) + [storePath]: getState(storePath), } constructor(props) { @@ -47,22 +45,37 @@ export default class index extends Component {
- } type="avatar" /> + } + type="avatar" + />

- {moment().format('A')}好,{this.state.user.nickName || this.state.user.name},欢迎您登录系统! -

+ {moment().format('A')}好, + + {this.state.user.nickName || this.state.user.name} + + ,欢迎您登录系统! +
上次IP:{this.state.user.lastLoginIp} - 上次登录时间:{this.state.user.lastLoginTime} + + 上次登录时间:{this.state.user.lastLoginTime} +
- + 您有0封未读邮件,请尽快查收! diff --git a/web-react/src/pages/home/statistics.jsx b/web-react/src/pages/home/statistics.jsx index b8c6d5a..a28f01b 100644 --- a/web-react/src/pages/home/statistics.jsx +++ b/web-react/src/pages/home/statistics.jsx @@ -43,14 +43,14 @@ export default class statistics extends Component { > 当月活跃用户 - + } prefix={ - }> - + } + > diff --git a/web-react/src/pages/system/account/base.jsx b/web-react/src/pages/system/account/base.jsx index 7d7348b..298f2b4 100644 --- a/web-react/src/pages/system/account/base.jsx +++ b/web-react/src/pages/system/account/base.jsx @@ -5,7 +5,6 @@ import { Cropper } from 'react-cropper' import 'cropperjs/dist/cropper.css' import { BlobToFile } from 'util/file' -import './base.less' import { api } from 'common/api' export default class base extends Component { diff --git a/web-react/src/pages/system/dict/dictdata/form.jsx b/web-react/src/pages/system/dict/dictdata/form.jsx index 67ed191..50ce9d7 100644 --- a/web-react/src/pages/system/dict/dictdata/form.jsx +++ b/web-react/src/pages/system/dict/dictdata/form.jsx @@ -7,7 +7,6 @@ import MonacoEditor from 'react-monaco-editor' const initialValues = {} export default class form extends Component { - state = { // 加载状态 loading: true, @@ -32,7 +31,7 @@ export default class form extends Component { * 填充数据 * 可以在设置this.record之后对其作出数据结构调整 * [异步,必要] - * @param {*} params + * @param {*} params */ async fillData(params) { this.record = cloneDeep(params.record) @@ -45,7 +44,7 @@ export default class form extends Component { this.form.current.setFieldsValue(this.record) this.setState({ - loading: false + loading: false, }) } @@ -53,7 +52,7 @@ export default class form extends Component { * 获取数据 * 可以对postData进行数据结构调整 * [异步,必要] - * @returns + * @returns */ async getData() { const form = this.form.current @@ -66,11 +65,11 @@ export default class form extends Component { } //#region 从前段转换后端所需格式 try { - const code = JSON.parse(this.code.current.editor.getValue()); + const code = JSON.parse(this.code.current.editor.getValue()) if (code.constructor === Object) { - postData.extCode = JSON.stringify(code); + postData.extCode = JSON.stringify(code) } else { - throw new Error(0); + throw new Error(0) } } catch { Message.error('错误的JSON格式') @@ -85,18 +84,15 @@ export default class form extends Component { render() { return ( -
+ }>
diff --git a/web-react/src/store/reducer/layout.js b/web-react/src/store/reducer/layout.js index 1441e84..776fdc9 100644 --- a/web-react/src/store/reducer/layout.js +++ b/web-react/src/store/reducer/layout.js @@ -3,7 +3,8 @@ import { SIDER_BREAK_POINT } from "util/global" const defaultState = { siderCollapsed: false, - allowSiderCollapsed: true + allowSiderCollapsed: true, + theme: 'default' } const localStorageState = () => { @@ -36,6 +37,7 @@ const layout = (state = mergeState, action) => { window.localStorage.setItem(SETTING_KEY, JSON.stringify(_state)) return _state } + // 自动收起侧边 case 'AUTO_TOGGLE_COLLAPSED': { const _state = { @@ -45,6 +47,13 @@ const layout = (state = mergeState, action) => { } return _state } + // 切换主题 + case 'SET_THEME': + { + const _state = { ...state, theme: action.theme } + window.localStorage.setItem(SETTING_KEY, JSON.stringify(_state)) + return _state + } default: return state } diff --git a/web-react/src/views/login/index.jsx b/web-react/src/views/login/index.jsx index a431711..d7290aa 100644 --- a/web-react/src/views/login/index.jsx +++ b/web-react/src/views/login/index.jsx @@ -5,7 +5,6 @@ import { encryptByRSA } from 'util/rsa' import { RSA_PUBLIC_KEY } from 'util/global' import { api } from 'common/api' import { token } from 'common/token' -import './index.less' export default class index extends Component { state = { diff --git a/web-react/src/views/main/_layout/header/index.jsx b/web-react/src/views/main/_layout/header/index.jsx index ccf9f9d..796d6f1 100644 --- a/web-react/src/views/main/_layout/header/index.jsx +++ b/web-react/src/views/main/_layout/header/index.jsx @@ -33,7 +33,7 @@ export default class index extends Component { } render() { - const { allowSiderCollapsed } = this.state + const { allowSiderCollapsed, theme } = this.state return ( @@ -62,6 +62,21 @@ export default class index extends Component { + { + dispatch({ + type: 'SET_THEME', + theme: { dark: 'default', default: 'dark' }[theme], + }) + window.location.reload() + }} + > +
+
+
+
+
From 850d490a1b7bed19534ae79cebf9660ce8b7fdc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=87=AA=E5=B8=A6=E5=A4=A7=E4=BD=AC=E6=B0=94=E5=9C=BA?= <188633308@qq.com> Date: Thu, 1 Jul 2021 22:26:11 +0800 Subject: [PATCH 03/15] =?UTF-8?q?update=20=E9=80=9A=E7=9F=A5=E5=85=AC?= =?UTF-8?q?=E5=91=8A=E6=98=BE=E7=A4=BA=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Api/Ewide.Core/Ewide.Core.xml | 6 + .../Service/Notice/SysNoticeService.cs | 75 ++++++--- .../Service/Notice/SysNoticeUserService.cs | 11 -- Api/Ewide.Core/applicationconfig.json | 5 +- web-react/craco.config.js | 2 +- web-react/package.json | 1 + web-react/src/assets/style/dark/lib/form.less | 2 + .../src/assets/style/dark/lib/visibility.less | 17 +- web-react/src/assets/style/dark/main.less | 100 ++++++++---- .../src/assets/style/default/lib/form.less | 2 + .../assets/style/default/lib/visibility.less | 17 +- web-react/src/assets/style/default/main.less | 66 ++++++++ .../src/common/api/requests/sys/index.js | 2 + .../common/api/requests/sys/noticeManage.js | 14 -- .../api/requests/sys/noticeReceiveManage.js | 6 +- .../components/form/braft-editor/index.jsx | 4 +- web-react/src/components/index.js | 2 +- web-react/src/pages/system/notice/form.jsx | 16 +- web-react/src/pages/system/notice/index.jsx | 4 +- .../src/views/main/_layout/header/index.jsx | 122 +++++---------- .../src/views/main/_layout/header/notice.jsx | 145 ++++++++++++++++++ web-react/yarn.lock | 9 +- 22 files changed, 435 insertions(+), 193 deletions(-) create mode 100644 web-react/src/views/main/_layout/header/notice.jsx diff --git a/Api/Ewide.Core/Ewide.Core.xml b/Api/Ewide.Core/Ewide.Core.xml index 8e83b57..113caf5 100644 --- a/Api/Ewide.Core/Ewide.Core.xml +++ b/Api/Ewide.Core/Ewide.Core.xml @@ -5536,6 +5536,12 @@ + + + 获取接收到的通知公告总数 + + + 更新发布信息 diff --git a/Api/Ewide.Core/Service/Notice/SysNoticeService.cs b/Api/Ewide.Core/Service/Notice/SysNoticeService.cs index 26e20ad..9825efd 100644 --- a/Api/Ewide.Core/Service/Notice/SysNoticeService.cs +++ b/Api/Ewide.Core/Service/Notice/SysNoticeService.cs @@ -1,4 +1,6 @@ -using Furion.DatabaseAccessor; +using Dapper; +using Ewide.Core.Extension; +using Furion.DatabaseAccessor; using Furion.DatabaseAccessor.Extensions; using Furion.DependencyInjection; using Furion.DynamicApiController; @@ -9,6 +11,7 @@ using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; +using System.Text.RegularExpressions; using System.Threading.Tasks; namespace Ewide.Core.Service.Notice @@ -26,15 +29,20 @@ namespace Ewide.Core.Service.Notice private readonly ISysNoticeUserService _sysNoticeUserService; + private readonly IDapperRepository _dapperRepository; + + public SysNoticeService(IRepository sysNoticeRep, IRepository sysNoticeUserRep, IUserManager userManager, - ISysNoticeUserService sysNoticeUserService) + ISysNoticeUserService sysNoticeUserService, IDapperRepository dapperRepository) { _sysNoticeRep = sysNoticeRep; _sysNoticeUserRep = sysNoticeUserRep; _userManager = userManager; _sysNoticeUserService = sysNoticeUserService; + + _dapperRepository = dapperRepository; } /// @@ -150,7 +158,6 @@ namespace Ewide.Core.Service.Notice var noticeUserRead = new NoticeUserRead { UserId = u.UserId, - UserName = _userManager.Name, ReadStatus = u.ReadStatus, ReadTime = u.ReadTime }; @@ -158,18 +165,17 @@ namespace Ewide.Core.Service.Notice }); } var noticeResult = notice.Adapt(); - noticeResult.NoticeUserIdList = noticeUserIdList; - noticeResult.NoticeUserReadInfoList = noticeUserReadInfoList; + if (_userManager.SuperAdmin) + { + noticeResult.NoticeUserIdList = noticeUserIdList; + noticeResult.NoticeUserReadInfoList = noticeUserReadInfoList; + } // 如果该条通知公告为已发布,则将当前用户的该条通知公告设置为已读 if (notice.Status == (int)NoticeStatus.PUBLIC) await _sysNoticeUserService.Read(notice.Id, _userManager.UserId, (int)NoticeUserStatus.READ); return noticeResult; } - [HttpGet("/sysNotice/detailById")] - public async Task GetNotice(string id) - { - return await _sysNoticeRep.FirstOrDefaultAsync(u => u.Id == id); - } + /// /// 修改通知公告状态 /// @@ -201,18 +207,45 @@ namespace Ewide.Core.Service.Notice /// /// /// - [HttpGet("/sysNotice/received")] - public async Task ReceivedNoticePageList([FromQuery] NoticeInput input) + [HttpPost("/sysNotice/received")] + public async Task ReceivedNoticePageList([FromBody] NoticeInput input) { - var searchValue = !string.IsNullOrEmpty(input.SearchValue?.Trim()); - var notices = await _sysNoticeRep.DetachedEntities.Join(_sysNoticeUserRep.DetachedEntities, u => u.Id, e => e.NoticeId, (u, e) => new { u, e }) - .Where(u => u.e.UserId == _userManager.UserId) - .Where(searchValue, u => EF.Functions.Like(u.u.Title, $"%{input.SearchValue.Trim()}%") || EF.Functions.Like(u.u.Content, $"%{input.SearchValue.Trim()}%")) - .Where(input.Type > 0, u => u.u.Type == input.Type) - .Where(u => u.u.Status != (int)NoticeStatus.DELETED) - .Select(u => u.u.Adapt()) - .ToPagedListAsync(input.PageIndex, input.PageSize); - return PageDataResult.PageResult(notices); + var sql = @"SELECT +SN.*, +SU.Avatar +FROM sys_notice SN +LEFT JOIN sys_notice_user SNU ON SN.Id = SNU.NoticeId +LEFT JOIN sys_user SU ON SN.PublicUserId = SU.Id +WHERE SNU.UserId = @UserId AND SN.Status <> @Status"; + + var data = await _dapperRepository.QueryPageDataDynamic( + sql, + input, + new + { + _userManager.UserId, + Status = (int)NoticeStatus.DELETED + } + ); + + data.Items = data.Items.Select(p => { + var r = p.Adapt(); + r.Content = Regex.Replace(r.Content, @"<\/?.+?\/?>", "").Replace("\r\n", ""); + return r; + }); + + return data; + + } + + /// + /// 获取接收到的通知公告总数 + /// + /// + [HttpGet("/sysNotice/unread")] + public async Task GetUnreadCount() + { + return await _sysNoticeUserRep.Where(u => u.UserId == _userManager.UserId && u.ReadStatus == (int)NoticeUserStatus.UNREAD).CountAsync(); } /// diff --git a/Api/Ewide.Core/Service/Notice/SysNoticeUserService.cs b/Api/Ewide.Core/Service/Notice/SysNoticeUserService.cs index 845a8e3..fea4020 100644 --- a/Api/Ewide.Core/Service/Notice/SysNoticeUserService.cs +++ b/Api/Ewide.Core/Service/Notice/SysNoticeUserService.cs @@ -48,18 +48,7 @@ namespace Ewide.Core.Service.Notice }.InsertAsync(); } } - [HttpGet("/NoticeUser/getCount")] - public async Task GetCount() - { - return await _sysNoticeUserRep.Where(u => u.UserId == _userManager.UserId && u.ReadStatus == (int)NoticeUserStatus.UNREAD).CountAsync(); - } - [HttpGet("/NoticeUser/GetNoticeInfo")] - public async Task> GetNoticeInfo() - { - var noticeIdList = await _sysNoticeUserRep.Where(u => u.UserId == _userManager.UserId && u.ReadStatus == (int)NoticeUserStatus.UNREAD).Select(p => p.NoticeId).ToListAsync(); - return await _sysNoticeRep.Where(s => noticeIdList.Contains(s.Id)).ToListAsync(); - } /// /// 更新 /// diff --git a/Api/Ewide.Core/applicationconfig.json b/Api/Ewide.Core/applicationconfig.json index 0266d1e..9008b08 100644 --- a/Api/Ewide.Core/applicationconfig.json +++ b/Api/Ewide.Core/applicationconfig.json @@ -97,7 +97,10 @@ "sysFileInfo:preview", "sysUser:updateInfo", "sysUser:updatePwd", - "sysUser:updateAvatar" + "sysUser:updateAvatar", + "sysNotice:received", + "sysNotice:unread", + "sysNotice:detail" ] } } \ No newline at end of file diff --git a/web-react/craco.config.js b/web-react/craco.config.js index 2cde7a0..0b2c146 100644 --- a/web-react/craco.config.js +++ b/web-react/craco.config.js @@ -29,7 +29,7 @@ module.exports = { ], webpack: { plugins: [ - new MonacoWebpackPlugin() + //new MonacoWebpackPlugin() ] } } \ No newline at end of file diff --git a/web-react/package.json b/web-react/package.json index 04d6bff..e486365 100644 --- a/web-react/package.json +++ b/web-react/package.json @@ -23,6 +23,7 @@ "react-color": "^2.19.3", "react-cropper": "^2.1.8", "react-dom": "^17.0.2", + "react-infinite-scroller": "^1.2.4", "react-json-view": "^1.21.3", "react-monaco-editor": "^0.43.0", "react-router": "^5.2.0", diff --git a/web-react/src/assets/style/dark/lib/form.less b/web-react/src/assets/style/dark/lib/form.less index e770583..9a5fc4e 100644 --- a/web-react/src/assets/style/dark/lib/form.less +++ b/web-react/src/assets/style/dark/lib/form.less @@ -151,6 +151,8 @@ flex: 0 0 100%; width: 100%; + + text-align: inherit; } } .yo-form--short { diff --git a/web-react/src/assets/style/dark/lib/visibility.less b/web-react/src/assets/style/dark/lib/visibility.less index 3e16f62..a3d6235 100644 --- a/web-react/src/assets/style/dark/lib/visibility.less +++ b/web-react/src/assets/style/dark/lib/visibility.less @@ -21,26 +21,25 @@ display: flex; } .ellipsis { + display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } -.ellipsis-2 { +.ellipsis-line(@line) { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; text-overflow: ellipsis; + word-break: break-all; - -webkit-line-clamp: 2; + -webkit-line-clamp: @line; +} +.ellipsis-2 { + .ellipsis-line(2); } .ellipsis-3 { - display: -webkit-box; - overflow: hidden; - -webkit-box-orient: vertical; - - text-overflow: ellipsis; - - -webkit-line-clamp: 3; + .ellipsis-line(3); } diff --git a/web-react/src/assets/style/dark/main.less b/web-react/src/assets/style/dark/main.less index 3ea8756..1060b2f 100644 --- a/web-react/src/assets/style/dark/main.less +++ b/web-react/src/assets/style/dark/main.less @@ -94,44 +94,76 @@ transition: @animation-duration-slow; transition-property: color; - // 特殊工具按钮 - .theme-toggle { - position: relative; - - overflow: hidden; - - width: 20px; - height: 20px; - margin: 7px 0; - - border-radius: 50%; - &--real { - width: 100%; - height: 100%; - - border-radius: 50%; - background-color: #fff; - } - &--imaginary { - position: absolute; - top: 6px; - left: -6px; - - width: 18px; - height: 18px; - - transform: @animation-duration-slow transform; - transform: rotate(45deg) scaleY(1); - transform-origin: top right; - - border-radius: 50%; - background-color: fade(@layout-header-background, 70%); - } - } } &:active { box-shadow: inset 1px 1px 10px rgba(0, 0, 0, .05); } + // 特殊工具按钮 + .theme-toggle { + position: relative; + + overflow: hidden; + + width: 20px; + height: 20px; + margin: 7px 0; + + border-radius: 50%; + &--real { + position: relative; + + width: 20px; + height: 20px; + + transition: @animation-duration-slow background-color; + + border-radius: 50%; + background-color: fade(@white, 60%); + &::before { + position: absolute; + top: 5px; + left: 5px; + + width: 10px; + height: 10px; + + content: ''; + transition: @animation-duration-slow transform; + transform: scale(0); + + border: 2px solid @layout-header-background; + border-radius: 50%; + } + } + &--imaginary { + position: absolute; + top: 6px; + right: -6px; + + width: 18px; + height: 18px; + + transition: @animation-duration-slow transform; + transform: rotate(45deg) scaleY(1); + transform-origin: top right; + + border-radius: 50%; + background-color: @layout-header-background; + } + } + &:hover { + .theme-toggle { + &--real { + background-color: @white; + &::before { + transform: scale(1); + } + } + &--imaginary { + transform: rotate(45deg) scaleY(0); + } + } + } } .ant-select-auto-complete { margin: (@layout-header-height - 10px - 30px) / 2 @padding-md; diff --git a/web-react/src/assets/style/default/lib/form.less b/web-react/src/assets/style/default/lib/form.less index 69ea80c..a53f1c6 100644 --- a/web-react/src/assets/style/default/lib/form.less +++ b/web-react/src/assets/style/default/lib/form.less @@ -151,6 +151,8 @@ flex: 0 0 100%; width: 100%; + + text-align: inherit; } } .yo-form--short { diff --git a/web-react/src/assets/style/default/lib/visibility.less b/web-react/src/assets/style/default/lib/visibility.less index 3e16f62..a3d6235 100644 --- a/web-react/src/assets/style/default/lib/visibility.less +++ b/web-react/src/assets/style/default/lib/visibility.less @@ -21,26 +21,25 @@ display: flex; } .ellipsis { + display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } -.ellipsis-2 { +.ellipsis-line(@line) { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; text-overflow: ellipsis; + word-break: break-all; - -webkit-line-clamp: 2; + -webkit-line-clamp: @line; +} +.ellipsis-2 { + .ellipsis-line(2); } .ellipsis-3 { - display: -webkit-box; - overflow: hidden; - -webkit-box-orient: vertical; - - text-overflow: ellipsis; - - -webkit-line-clamp: 3; + .ellipsis-line(3); } diff --git a/web-react/src/assets/style/default/main.less b/web-react/src/assets/style/default/main.less index fa81795..8f1100f 100644 --- a/web-react/src/assets/style/default/main.less +++ b/web-react/src/assets/style/default/main.less @@ -98,6 +98,72 @@ &:active { box-shadow: inset 1px 1px 10px rgba(0, 0, 0, .05); } + // 特殊工具按钮 + .theme-toggle { + position: relative; + + overflow: hidden; + + width: 20px; + height: 20px; + margin: 7px 0; + + border-radius: 50%; + &--real { + position: relative; + + width: 100%; + height: 100%; + + transition: @animation-duration-slow background-color; + + border-radius: 50%; + background-color: fade(@white, 60%); + &::before { + position: absolute; + top: 5px; + left: 5px; + + width: 10px; + height: 10px; + + content: ''; + transition: @animation-duration-slow transform; + transform: scale(1); + + border: 2px solid @layout-header-background; + border-radius: 50%; + } + } + &--imaginary { + position: absolute; + top: 6px; + right: -6px; + + width: 18px; + height: 18px; + + transition: @animation-duration-slow transform; + transform: rotate(45deg) scaleY(0); + transform-origin: top right; + + border-radius: 50%; + background-color: #334454; + } + } + &:hover { + .theme-toggle { + &--real { + background-color: @white; + &::before { + transform: scale(0); + } + } + &--imaginary { + transform: rotate(45deg) scaleY(1); + } + } + } } .ant-select-auto-complete { margin: (@layout-header-height - 10px - 30px) / 2 @padding-md; diff --git a/web-react/src/common/api/requests/sys/index.js b/web-react/src/common/api/requests/sys/index.js index ab2797e..4f94a58 100644 --- a/web-react/src/common/api/requests/sys/index.js +++ b/web-react/src/common/api/requests/sys/index.js @@ -9,6 +9,7 @@ import logManage from './logManage' import machineManage from './machineManage' import menuManage from './menuManage' import noticeManage from './noticeManage' +import noticeReceiveManage from './noticeReceiveManage' import onlineUserManage from './onlineUserManage' import orgManage from './orgManage' import posManage from './posManage' @@ -31,6 +32,7 @@ const urls = { ...machineManage, ...menuManage, ...noticeManage, + ...noticeReceiveManage, ...onlineUserManage, ...orgManage, ...posManage, diff --git a/web-react/src/common/api/requests/sys/noticeManage.js b/web-react/src/common/api/requests/sys/noticeManage.js index 5b9e1fb..c1c692f 100644 --- a/web-react/src/common/api/requests/sys/noticeManage.js +++ b/web-react/src/common/api/requests/sys/noticeManage.js @@ -28,20 +28,6 @@ const urls = { * 修改状态 */ sysNoticeChangeStatus: ['/sysNotice/changeStatus', 'post'], - - /** - * 获取Notice总数 - */ - sysNoticeGetCount: ['/NoticeUser/getCount', 'get'], - - /** - * 获取Notice详细 - */ - sysNoticeInfo: ['/NoticeUser/GetNoticeInfo', 'get'], - /** - * 获取Notice详细ByID - */ - sysNoticeShow: ['/sysNotice/detailById', 'get'], } export default urls diff --git a/web-react/src/common/api/requests/sys/noticeReceiveManage.js b/web-react/src/common/api/requests/sys/noticeReceiveManage.js index ddff640..85d50ef 100644 --- a/web-react/src/common/api/requests/sys/noticeReceiveManage.js +++ b/web-react/src/common/api/requests/sys/noticeReceiveManage.js @@ -1,8 +1,12 @@ const urls = { /** + * 获取接收到的通知公告总数 + */ + sysNoticeUnread: ['/sysNotice/unread', 'get'], + /** * 查询我收到的系统通知公告 */ - sysNoticeReceived: ['/sysNotice/received', 'get'], + sysNoticeReceived: ['/sysNotice/received', 'post'], } export default urls \ No newline at end of file diff --git a/web-react/src/components/form/braft-editor/index.jsx b/web-react/src/components/form/braft-editor/index.jsx index d6d09b0..510c247 100644 --- a/web-react/src/components/form/braft-editor/index.jsx +++ b/web-react/src/components/form/braft-editor/index.jsx @@ -7,7 +7,7 @@ import 'braft-editor/dist/index.css' export default class index extends Component { state = { editorState: BraftEditor.createEditorState(this.props.value), // 设置编辑器初始内容 - outputHTML: '

', + outputHTML: '', } /** * mount后回调 @@ -43,7 +43,7 @@ export default class index extends Component { const { editorState, outputHTML } = this.state //localStorage.setItem('props', JSON.stringify(this.props)) - const controls = ['bold', 'italic', 'underline', 'text-color', 'separator', 'media'] + const controls = ['bold', 'italic', 'underline', 'text-color', 'separator'] return ( }> -
+
- + { + const v = value.replace(/<\/?.+?\/?>/g, '') + if (!v) { + throw Error('请输入内容') + } + }, + }, + ]} > diff --git a/web-react/src/pages/system/notice/index.jsx b/web-react/src/pages/system/notice/index.jsx index 5a94045..0b37040 100644 --- a/web-react/src/pages/system/notice/index.jsx +++ b/web-react/src/pages/system/notice/index.jsx @@ -28,7 +28,7 @@ const apiAction = { * 用于弹窗标题 * [必要] */ -const name = '啥玩意' +const name = '通知公告' /** * 统一配置权限标识 @@ -253,6 +253,7 @@ export default class index extends Component { this.table.current.onReloadData()} @@ -264,6 +265,7 @@ export default class index extends Component { this.table.current.onReloadData()} diff --git a/web-react/src/views/main/_layout/header/index.jsx b/web-react/src/views/main/_layout/header/index.jsx index e289d28..0cdf6c8 100644 --- a/web-react/src/views/main/_layout/header/index.jsx +++ b/web-react/src/views/main/_layout/header/index.jsx @@ -1,23 +1,19 @@ import React, { Component, useState } from 'react' -import { Layout, Badge, Popover, Menu, Modal } from 'antd' +import { Layout, Badge, Popover, Menu, Modal, Tooltip, Popconfirm } from 'antd' import { AntIcon, Container } from 'components' -import Logo from '../logo' -import User from './user' -import Search from './search' import store from 'store' import { api } from 'common/api' +import Logo from '../logo' +import Search from './search' +import Notice from './notice' +import User from './user' + const { getState, subscribe, dispatch } = store export default class index extends Component { state = { ...getState('layout'), - notice: { - count: 0, - data: [], - }, - modalVisible: false, - currentNotice: {}, } constructor(props) { @@ -28,10 +24,6 @@ export default class index extends Component { }) } - componentDidMount() { - this.loadNotice() - } - componentWillUnmount() { this.unsubscribe() } @@ -43,27 +35,8 @@ export default class index extends Component { }) } - async loadNotice() { - const { data } = await api.sysNoticeGetCount() - const items = await api.sysNoticeInfo() - this.setState({ - notice: { - count: data, - data: items.data, - }, - }) - } - async showDetail(params, visible) { - this.setState({ currentNotice: params }) - - if (visible) { - this.setState({ modalVisible: visible }) - } else { - this.setState({ modalVisible: visible }) - } - } render() { - const { allowSiderCollapsed, notice, currentNotice } = this.state + const { allowSiderCollapsed, theme } = this.state return ( @@ -80,57 +53,38 @@ export default class index extends Component {
- window.realodContentWindow()} - > - - - - - {notice.data.map(item => ( - this.showDetail(item, true)} - key={item.id} - > - {item.title} - - ))} - - } - > - - - - - - - this.showDetail(false)} - onCancel={() => this.showDetail(false)} - style={{ zIndex: 1000 }} + + window.realodContentWindow()} > -
-
-
-
- 发布人:{currentNotice.createdUserName} - {' '} - 发布时间:{currentNotice.createdTime} -
-
-
+ + + + + + { + dispatch({ + type: 'SET_THEME', + theme: { default: 'dark', dark: 'default' }[theme], + }) + window.location.reload() + }} + > + +
+
+
+
+ + +
diff --git a/web-react/src/views/main/_layout/header/notice.jsx b/web-react/src/views/main/_layout/header/notice.jsx new file mode 100644 index 0000000..dd89eab --- /dev/null +++ b/web-react/src/views/main/_layout/header/notice.jsx @@ -0,0 +1,145 @@ +import React, { Component } from 'react' +import { Badge, Divider, List, Menu, Modal, Popover, Row, Spin } from 'antd' +import { AntIcon, Image } from 'components' +import { api } from 'common/api' +import InfiniteScroll from 'react-infinite-scroller' +import moment from 'moment' + +export default class notice extends Component { + state = { + count: 0, + list: [], + + loading: false, + hasMore: true, + + detailVisible: false, + detailLoading: false, + detailData: {}, + } + + async componentDidMount() { + const { data: count } = await api.sysNoticeUnread() + this.setState({ count }) + } + + finish() { + this.setState({ loading: false, hasMore: false }) + } + + async onInfiniteOnLoad(pageIndex) { + this.setState({ loading: true }) + const { list } = this.state + if (list.length >= 30) { + return this.finish() + } + + const { + data: { items }, + } = await api.sysNoticeReceived({ + pageIndex, + pageSize: 5, + sortField: 'createdTime', + sortOrder: 'descend', + }) + + if (!items.length) { + return this.finish() + } + + this.setState({ + list: [...list, ...items], + loading: false, + }) + } + + async onOpenDetail(id) { + this.setState({ detailLoading: true, detailVisible: true }) + const { data } = await api.sysNoticeDetail({ id }) + this.setState({ + detailLoading: false, + detailData: data, + }) + } + + renderList() { + const { list, loading, hasMore } = this.state + return ( + this.onInfiniteOnLoad(pageIndex)} + hasMore={!loading && hasMore} + useWindow={false} + threshold={100} + > + ( + + } + title={ + this.onOpenDetail(item.id)} + > + {item.title} + + } + description={moment(item.createdTime || item.publicTime).fromNow()} + /> +
{item.content}
+
+ )} + > + {loading && hasMore && ( +
+ } /> +
+ )} +
+
+ ) + } + + render() { + const { count, detailLoading, detailVisible, detailData } = this.state + + return ( + + + + + + + + this.setState({ detailVisible: false, detailData: {} })} + > + }> +
{detailData.title}
+ +
+ + + 发布人:{detailData.publicUserName} + 发布时间:{detailData.publicTime} + +
+
+
+ ) + } +} diff --git a/web-react/yarn.lock b/web-react/yarn.lock index 963891e..a636c28 100644 --- a/web-react/yarn.lock +++ b/web-react/yarn.lock @@ -9285,7 +9285,7 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.5.10, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.npm.taobao.org/prop-types/download/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha1-UsQedbjIfnK52TYOAga5ncv/psU= @@ -9877,6 +9877,13 @@ react-error-overlay@^6.0.9: resolved "https://registry.nlark.com/react-error-overlay/download/react-error-overlay-6.0.9.tgz?cache=0&sync_timestamp=1618847933355&other_urls=https%3A%2F%2Fregistry.nlark.com%2Freact-error-overlay%2Fdownload%2Freact-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a" integrity sha1-PHQwEMk1lgjDdezWvHbzXZOZWwo= +react-infinite-scroller@^1.2.4: + version "1.2.4" + resolved "https://registry.npm.taobao.org/react-infinite-scroller/download/react-infinite-scroller-1.2.4.tgz#f67eaec4940a4ce6417bebdd6e3433bfc38826e9" + integrity sha1-9n6uxJQKTOZBe+vdbjQzv8OIJuk= + dependencies: + prop-types "^15.5.8" + react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: version "16.13.1" resolved "https://registry.nlark.com/react-is/download/react-is-16.13.1.tgz?cache=0&sync_timestamp=1623273254569&other_urls=https%3A%2F%2Fregistry.nlark.com%2Freact-is%2Fdownload%2Freact-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" From 3725f586d2a16187ce2e0b0bc3edfb6e769375c3 Mon Sep 17 00:00:00 2001 From: ky_yusj <2655568377@qq.com> Date: Fri, 2 Jul 2021 09:50:24 +0800 Subject: [PATCH 04/15] =?UTF-8?q?update=20=20=20=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E6=96=B0=E5=A2=9E=E6=94=B9=E4=B8=BA=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E9=BB=98=E8=AE=A4=E5=AF=86=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Api/Ewide.Core/Ewide.Core.xml | 10 ---------- Api/Ewide.Core/Service/User/Dto/UserInput.cs | 16 ++++++---------- Api/Ewide.Core/Service/User/SysUserService.cs | 2 +- .../src/pages/business/house/member/form.jsx | 4 ++-- web-react/src/pages/system/user/form.jsx | 4 ++-- 5 files changed, 11 insertions(+), 25 deletions(-) diff --git a/Api/Ewide.Core/Ewide.Core.xml b/Api/Ewide.Core/Ewide.Core.xml index 113caf5..5d038ce 100644 --- a/Api/Ewide.Core/Ewide.Core.xml +++ b/Api/Ewide.Core/Ewide.Core.xml @@ -6804,16 +6804,6 @@ 账号
- - - 密码 - - - - - 确认密码 - - 用户Id diff --git a/Api/Ewide.Core/Service/User/Dto/UserInput.cs b/Api/Ewide.Core/Service/User/Dto/UserInput.cs index 28068f9..a096e4c 100644 --- a/Api/Ewide.Core/Service/User/Dto/UserInput.cs +++ b/Api/Ewide.Core/Service/User/Dto/UserInput.cs @@ -84,17 +84,13 @@ namespace Ewide.Core.Service [Required(ErrorMessage = "账号名称不能为空")] public override string Account { get; set; } - /// - /// 密码 - /// - [Required(ErrorMessage = "密码不能为空")] - public override string Password { get; set; } + + //[Required(ErrorMessage = "密码不能为空")] + //public override string Password { get; set; } - /// - /// 确认密码 - /// - [Required(ErrorMessage = "确认密码不能为空"), Compare(nameof(Password), ErrorMessage = "两次密码不一致")] - public string Confirm { get; set; } + + //[Required(ErrorMessage = "确认密码不能为空"), Compare(nameof(Password), ErrorMessage = "两次密码不一致")] + //public string Confirm { get; set; } } public class DeleteUserInput : UserInput diff --git a/Api/Ewide.Core/Service/User/SysUserService.cs b/Api/Ewide.Core/Service/User/SysUserService.cs index e32a508..2a36cb5 100644 --- a/Api/Ewide.Core/Service/User/SysUserService.cs +++ b/Api/Ewide.Core/Service/User/SysUserService.cs @@ -113,7 +113,7 @@ namespace Ewide.Core.Service var isExist = await _sysUserRep.AnyAsync(u => u.Account == input.Account, false); if (isExist) throw Oops.Oh(ErrorCode.D1003); - + input.Password = CommonConst.DEFAULT_PASSWORD; var user = input.Adapt(); user.Password = MD5Encryption.Encrypt(input.Password); if (string.IsNullOrEmpty(user.Name)) diff --git a/web-react/src/pages/business/house/member/form.jsx b/web-react/src/pages/business/house/member/form.jsx index 3a8145b..db24377 100644 --- a/web-react/src/pages/business/house/member/form.jsx +++ b/web-react/src/pages/business/house/member/form.jsx @@ -204,7 +204,7 @@ export default class form extends Component { > - {this.props.mode == 'add' && ( + {/* {this.props.mode == 'add' && ( <> - )} + )} */} diff --git a/web-react/src/pages/system/user/form.jsx b/web-react/src/pages/system/user/form.jsx index 204c88a..8504d3a 100644 --- a/web-react/src/pages/system/user/form.jsx +++ b/web-react/src/pages/system/user/form.jsx @@ -298,7 +298,7 @@ export default class form extends Component { > - {this.props.mode == 'add' && ( + {/* {this.props.mode == 'add' && ( <> - )} + )} */} From 0d9e77afc751905e6b9d4cd2ef7b4763fe55be72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=87=AA=E5=B8=A6=E5=A4=A7=E4=BD=AC=E6=B0=94=E5=9C=BA?= <188633308@qq.com> Date: Fri, 2 Jul 2021 12:15:23 +0800 Subject: [PATCH 05/15] =?UTF-8?q?fix=20=E6=89=93=E5=8C=85=E5=90=8E?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E5=88=87=E6=8D=A2=E6=A0=B7=E5=BC=8F=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web-react/.env | 1 + web-react/src/assets/style/dark/extend.less | 5 +++++ web-react/src/assets/style/default/extend.less | 5 +++++ web-react/src/index.js | 9 ++++++--- 4 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 web-react/.env diff --git a/web-react/.env b/web-react/.env new file mode 100644 index 0000000..4f79a0f --- /dev/null +++ b/web-react/.env @@ -0,0 +1 @@ +GENERATE_SOURCEMAP=false \ No newline at end of file diff --git a/web-react/src/assets/style/dark/extend.less b/web-react/src/assets/style/dark/extend.less index 9bdd94f..7f3c2c9 100644 --- a/web-react/src/assets/style/dark/extend.less +++ b/web-react/src/assets/style/dark/extend.less @@ -4,3 +4,8 @@ body { line-height: 1.42857143; } +#root { + transition: @animation-duration-slow opacity; + + opacity: 1 !important; +} diff --git a/web-react/src/assets/style/default/extend.less b/web-react/src/assets/style/default/extend.less index 07ee081..4b038cc 100644 --- a/web-react/src/assets/style/default/extend.less +++ b/web-react/src/assets/style/default/extend.less @@ -4,3 +4,8 @@ body { line-height: 1.42857143; } +#root { + transition: @animation-duration-slow opacity; + + opacity: 1 !important; +} diff --git a/web-react/src/index.js b/web-react/src/index.js index f63c526..3d85d46 100644 --- a/web-react/src/index.js +++ b/web-react/src/index.js @@ -15,15 +15,18 @@ const SETTING = JSON.parse(window.localStorage.getItem(SETTING_KEY)) || { }; if (SETTING.theme === 'dark') { - require('./assets/style/dark/index.less') + import('./assets/style/dark/index.less') } else { - require('./assets/style/default/index.less') + import('./assets/style/default/index.less') } moment.locale('zh-cn') // +const root = document.getElementById('root') +root.style.opacity = 0 + ReactDOM.render( , - document.getElementById('root') + root ); // If you want to start measuring performance in your app, pass a function From 4053d6ff0a1eb3601d16c2355550d9ae4118ebd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=87=AA=E5=B8=A6=E5=A4=A7=E4=BD=AC=E6=B0=94=E5=9C=BA?= <188633308@qq.com> Date: Fri, 2 Jul 2021 12:15:48 +0800 Subject: [PATCH 06/15] =?UTF-8?q?fix=20=E6=97=A0=E9=99=90=E6=BB=9A?= =?UTF-8?q?=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Api/Ewide.Core/Manager/UserManager.cs | 2 +- web-react/src/assets/style/dark/main.less | 7 +++++ web-react/src/assets/style/default/main.less | 7 +++++ .../src/views/main/_layout/header/notice.jsx | 27 ++++++++++++------- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/Api/Ewide.Core/Manager/UserManager.cs b/Api/Ewide.Core/Manager/UserManager.cs index a2ec008..c596181 100644 --- a/Api/Ewide.Core/Manager/UserManager.cs +++ b/Api/Ewide.Core/Manager/UserManager.cs @@ -202,7 +202,7 @@ namespace Ewide.Core .Select(u => u.Permission).ToListAsync(); #if DEBUG #else - await _sysCacheService.SetPermission(userId, permissions); // 缓存结果 + await _sysCacheService.SetPermission(UserId, permissions); // 缓存结果 #endif } return permissions; diff --git a/web-react/src/assets/style/dark/main.less b/web-react/src/assets/style/dark/main.less index 1060b2f..c6ea34e 100644 --- a/web-react/src/assets/style/dark/main.less +++ b/web-react/src/assets/style/dark/main.less @@ -688,3 +688,10 @@ padding: 0; } } +.yo-popover-infinite-scroll { + .ant-popover-inner-content { + overflow-y: auto; + + max-height: 300px; + } +} diff --git a/web-react/src/assets/style/default/main.less b/web-react/src/assets/style/default/main.less index 8f1100f..68cd631 100644 --- a/web-react/src/assets/style/default/main.less +++ b/web-react/src/assets/style/default/main.less @@ -682,3 +682,10 @@ padding: 0; } } +.yo-popover-infinite-scroll { + .ant-popover-inner-content { + overflow-y: auto; + + max-height: 300px; + } +} diff --git a/web-react/src/views/main/_layout/header/notice.jsx b/web-react/src/views/main/_layout/header/notice.jsx index dd89eab..b6f7d9d 100644 --- a/web-react/src/views/main/_layout/header/notice.jsx +++ b/web-react/src/views/main/_layout/header/notice.jsx @@ -1,5 +1,5 @@ import React, { Component } from 'react' -import { Badge, Divider, List, Menu, Modal, Popover, Row, Spin } from 'antd' +import { Badge, Button, Divider, List, Menu, Modal, Popover, Row, Spin } from 'antd' import { AntIcon, Image } from 'components' import { api } from 'common/api' import InfiniteScroll from 'react-infinite-scroller' @@ -69,7 +69,7 @@ export default class notice extends Component { loadMore={pageIndex => this.onInfiniteOnLoad(pageIndex)} hasMore={!loading && hasMore} useWindow={false} - threshold={100} + threshold={50} > } title={ - this.onOpenDetail(item.id)} - > - {item.title} - + <> + this.onOpenDetail(item.id)}> + {item.title} + + + {moment(item.createdTime || item.publicTime).fromNow()} + + } - description={moment(item.createdTime || item.publicTime).fromNow()} />
{item.content}
@@ -98,6 +99,11 @@ export default class notice extends Component {
)} + {!hasMore && ( + + )} ) } @@ -110,8 +116,9 @@ export default class notice extends Component { arrowPointAtCenter={true} placement="bottomRight" content={this.renderList()} - overlayInnerStyle={{ width: 300, maxHeight: 300, overflowY: 'auto' }} + overlayInnerStyle={{ width: 300 }} overlayStyle={{ zIndex: 999 }} + overlayClassName="yo-popover-infinite-scroll" > From 717c264518352f66f29a542e339b1aa28a6bc26f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=87=AA=E5=B8=A6=E5=A4=A7=E4=BD=AC=E6=B0=94=E5=9C=BA?= <188633308@qq.com> Date: Fri, 2 Jul 2021 14:11:48 +0800 Subject: [PATCH 07/15] =?UTF-8?q?update=20=E5=A4=84=E7=90=86=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E6=A0=B7=E5=BC=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web-react/craco.config.js | 4 +- web-react/src/assets/style/dark/lib/card.less | 10 ++++ .../src/assets/style/dark/lib/table.less | 45 +++++++++++------ web-react/src/assets/style/dark/public.less | 2 +- .../src/assets/style/default/lib/table.less | 45 +++++++++++------ web-react/src/index.js | 48 ++++++++++--------- .../src/pages/system/dict/dictdata/form.jsx | 8 +++- 7 files changed, 106 insertions(+), 56 deletions(-) diff --git a/web-react/craco.config.js b/web-react/craco.config.js index 0b2c146..e240718 100644 --- a/web-react/craco.config.js +++ b/web-react/craco.config.js @@ -29,7 +29,7 @@ module.exports = { ], webpack: { plugins: [ - //new MonacoWebpackPlugin() + new MonacoWebpackPlugin() ] - } + }, } \ No newline at end of file diff --git a/web-react/src/assets/style/dark/lib/card.less b/web-react/src/assets/style/dark/lib/card.less index 7ae210e..6fdc1e2 100644 --- a/web-react/src/assets/style/dark/lib/card.less +++ b/web-react/src/assets/style/dark/lib/card.less @@ -2,3 +2,13 @@ .ant-card { margin-bottom: @padding-md; } +.ant-card-grid-hoverable { + &:hover { + box-shadow: 1px 0 0 0 #303030, + 0 1px 0 0 #303030, + 1px 1px 0 0 #303030, + 1px 0 0 0 #303030 inset, + 0 1px 0 0 #303030 inset, + @card-shadow; + } +} diff --git a/web-react/src/assets/style/dark/lib/table.less b/web-react/src/assets/style/dark/lib/table.less index 684a4ea..72993b8 100644 --- a/web-react/src/assets/style/dark/lib/table.less +++ b/web-react/src/assets/style/dark/lib/table.less @@ -75,6 +75,9 @@ .ant-table-sticky-scroll { display: none; } +.ant-table-expanded-row>td { + border-right: @border-width-base @border-style-base @table-border-color !important; +} .yo-table { .ant-table { margin: 0 !important; @@ -196,11 +199,13 @@ } } .ant-table-tbody { - >.ant-table-expanded-row-level-1>td { + >.ant-table-expanded-row>td { padding: 0; border-right: none !important; .ant-table-wrapper { + margin-bottom: -1px; + border: none; .ant-table { margin: 0 !important; @@ -215,20 +220,17 @@ padding-left: @padding-md; } } - .ant-table-expanded-row-level-1>td { - padding: @padding-sm @padding-xs @padding-sm @padding-xl; - - border-right: @border-width-base @border-style-base @table-border-color !important; - .ant-card { - max-width: fit-content; - margin-bottom: 0; - - background: none; - .ant-card-grid { - width: 300px; - padding: @padding-xs @padding-sm; - - background-color: @card-background; + .ant-table-tbody { + >tr { + &:last-child { + >td { + border-bottom: @border-width-base @border-style-base @table-border-color; + } + &:hover { + >td { + border-bottom-color: lighten(@primary-color, 30%); + } + } } } } @@ -237,4 +239,17 @@ } } } + .ant-card { + max-width: fit-content; + margin: @padding-sm @padding-xs @padding-sm @padding-xl; + + background: none; + .ant-card-grid { + width: 300px; + height: 90px; + padding: @padding-xs @padding-sm; + + background-color: @card-background; + } + } } diff --git a/web-react/src/assets/style/dark/public.less b/web-react/src/assets/style/dark/public.less index 16a4aed..ee4716d 100644 --- a/web-react/src/assets/style/dark/public.less +++ b/web-react/src/assets/style/dark/public.less @@ -35,7 +35,7 @@ } } a.link-gray { - color: fade(@black, 50%); + color: fade(@white, 50%); &:hover { color: @link-hover-color; } diff --git a/web-react/src/assets/style/default/lib/table.less b/web-react/src/assets/style/default/lib/table.less index 48fbda4..72993b8 100644 --- a/web-react/src/assets/style/default/lib/table.less +++ b/web-react/src/assets/style/default/lib/table.less @@ -75,6 +75,9 @@ .ant-table-sticky-scroll { display: none; } +.ant-table-expanded-row>td { + border-right: @border-width-base @border-style-base @table-border-color !important; +} .yo-table { .ant-table { margin: 0 !important; @@ -196,11 +199,13 @@ } } .ant-table-tbody { - >.ant-table-expanded-row-level-1>td { + >.ant-table-expanded-row>td { padding: 0; border-right: none !important; .ant-table-wrapper { + margin-bottom: -1px; + border: none; .ant-table { margin: 0 !important; @@ -215,20 +220,17 @@ padding-left: @padding-md; } } - .ant-table-expanded-row-level-1>td { - padding: @padding-sm @padding-xs @padding-sm @padding-xl; - - border-right: @border-width-base @border-style-base @table-border-color !important; - .ant-card { - max-width: fit-content; - margin-bottom: 0; - - background: none; - .ant-card-grid { - width: 300px; - padding: @padding-xs @padding-sm; - - background-color: @card-background; + .ant-table-tbody { + >tr { + &:last-child { + >td { + border-bottom: @border-width-base @border-style-base @table-border-color; + } + &:hover { + >td { + border-bottom-color: lighten(@primary-color, 30%); + } + } } } } @@ -237,4 +239,17 @@ } } } + .ant-card { + max-width: fit-content; + margin: @padding-sm @padding-xs @padding-sm @padding-xl; + + background: none; + .ant-card-grid { + width: 300px; + height: 90px; + padding: @padding-xs @padding-sm; + + background-color: @card-background; + } + } } diff --git a/web-react/src/index.js b/web-react/src/index.js index 3d85d46..2d346e4 100644 --- a/web-react/src/index.js +++ b/web-react/src/index.js @@ -14,10 +14,12 @@ const SETTING = JSON.parse(window.localStorage.getItem(SETTING_KEY)) || { theme: 'default' }; +let imp + if (SETTING.theme === 'dark') { - import('./assets/style/dark/index.less') + imp = import('./assets/style/dark/index.less') } else { - import('./assets/style/default/index.less') + imp = import('./assets/style/default/index.less') } moment.locale('zh-cn') @@ -27,24 +29,26 @@ moment.locale('zh-cn') const root = document.getElementById('root') root.style.opacity = 0 -ReactDOM.render( - ( -
- -

暂无数据

-
- ) - } - > - -
, - root -); +imp.then(() => { + ReactDOM.render( + ( +
+ +

暂无数据

+
+ ) + } + > + +
, + root + ); -// If you want to start measuring performance in your app, pass a function -// to log results (for example: reportWebVitals(console.log)) -// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals -reportWebVitals(); \ No newline at end of file + // If you want to start measuring performance in your app, pass a function + // to log results (for example: reportWebVitals(console.log)) + // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals + reportWebVitals(); +}) \ No newline at end of file diff --git a/web-react/src/pages/system/dict/dictdata/form.jsx b/web-react/src/pages/system/dict/dictdata/form.jsx index 50ce9d7..764cd99 100644 --- a/web-react/src/pages/system/dict/dictdata/form.jsx +++ b/web-react/src/pages/system/dict/dictdata/form.jsx @@ -3,6 +3,9 @@ import { Form, message as Message, Spin } from 'antd' import { AntIcon } from 'components' import { cloneDeep } from 'lodash' import MonacoEditor from 'react-monaco-editor' +import store from 'store' + +const { getState } = store const initialValues = {} @@ -10,6 +13,7 @@ export default class form extends Component { state = { // 加载状态 loading: true, + ...getState('layout'), } // 表单实例 @@ -83,6 +87,8 @@ export default class form extends Component { //#endregion render() { + const { theme } = this.state + return ( }> @@ -90,7 +96,7 @@ export default class form extends Component { Date: Fri, 2 Jul 2021 14:48:19 +0800 Subject: [PATCH 08/15] =?UTF-8?q?fix=20=E9=BB=98=E8=AE=A4=E5=80=BC?= =?UTF-8?q?=E8=A2=AB=E7=A9=BA=E8=8A=82=E7=82=B9=E8=A6=86=E7=9B=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web-react/src/pages/business/house/info/form/index.jsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/web-react/src/pages/business/house/info/form/index.jsx b/web-react/src/pages/business/house/info/form/index.jsx index 5a2363d..1bf327c 100644 --- a/web-react/src/pages/business/house/info/form/index.jsx +++ b/web-react/src/pages/business/house/info/form/index.jsx @@ -1,6 +1,6 @@ import React, { Component } from 'react' import { Form, Button, Input, Descriptions, message as Message, Modal, Spin, Tabs } from 'antd' -import { merge, isEqual } from 'lodash' +import { merge, isEqual, pickBy } from 'lodash' import { AntIcon, ComponentDynamic, Container } from 'components' import { api } from 'common/api' @@ -90,6 +90,10 @@ export default class index extends Component { const { taskId } = this.props.param if (taskId) { api.houseInfoGetByTaskId({ taskId }).then(({ data }) => { + // 删除空节点 + for (const key in data) { + data[key] = pickBy(data[key], p => p !== null && p !== undefined) + } this.setState({ taskStatus: data.patrolInfo.status, record: data, @@ -168,7 +172,6 @@ export default class index extends Component { this.formData.patrolInfo.id = this.props.param.taskId } - console.log(this.formData) this.setState({ saving: true }) if (action) { From 072aabdd22b156abbae492d2bec631b59c323b29 Mon Sep 17 00:00:00 2001 From: ky_yusj <2655568377@qq.com> Date: Fri, 2 Jul 2021 15:42:56 +0800 Subject: [PATCH 09/15] =?UTF-8?q?update=20=E6=A0=91=E6=9F=A5=E8=AF=A2table?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=B8=AA=E9=80=89=E9=A1=B9,?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E5=9C=A8"=E5=8F=AA=E7=9C=8B=E6=9C=AC?= =?UTF-8?q?=E7=BA=A7"=E5=92=8C"=E6=9F=A5=E7=9C=8B=E6=9C=AC=E7=BA=A7?= =?UTF-8?q?=E5=8F=8A=E4=BB=A5=E4=B8=8B"=E4=B9=8B=E9=97=B4=E5=88=87?= =?UTF-8?q?=E6=8D=A2=20=E6=96=B0=E5=A2=9E=E7=94=A8=E6=88=B7=E6=97=B6?= =?UTF-8?q?=E7=9A=84=E4=B8=80=E4=BA=9B=E6=A0=BC=E5=BC=8F=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HouseMember/HouseMemberService.cs | 4 ++- Api/Ewide.Core/Ewide.Core.xml | 5 ++++ Api/Ewide.Core/Extension/InputBase.cs | 5 ++++ .../src/pages/business/house/member/form.jsx | 27 ++++++++++++++++--- .../src/pages/business/house/member/index.jsx | 16 ++++++++++- web-react/src/pages/system/user/form.jsx | 25 +++++++++++++++-- 6 files changed, 75 insertions(+), 7 deletions(-) diff --git a/Api/Ewide.Application/Service/HouseSafety/HouseMember/HouseMemberService.cs b/Api/Ewide.Application/Service/HouseSafety/HouseMember/HouseMemberService.cs index 309d93b..5f68f22 100644 --- a/Api/Ewide.Application/Service/HouseSafety/HouseMember/HouseMemberService.cs +++ b/Api/Ewide.Application/Service/HouseSafety/HouseMember/HouseMemberService.cs @@ -82,7 +82,9 @@ WHERE 1=1"; if (!string.IsNullOrEmpty(input.SysEmpParam.OrgId)) { - sql += " AND (SO.Id = @OrgId OR SO.Pids Like CONCAT('%[', @OrgId, ']%'))"; + var filter = " AND (SO.Id = @OrgId {0}) "; + filter = String.Format(filter, input.TreeNodeDataScope.GetValueOrDefault(1) == 2 ? " OR SO.Pids Like CONCAT('%[', @OrgId, ']%') " : ""); + sql += filter; param.Add("OrgId", input.SysEmpParam.OrgId); } diff --git a/Api/Ewide.Core/Ewide.Core.xml b/Api/Ewide.Core/Ewide.Core.xml index 5d038ce..712fedc 100644 --- a/Api/Ewide.Core/Ewide.Core.xml +++ b/Api/Ewide.Core/Ewide.Core.xml @@ -2674,6 +2674,11 @@ 查询条件
+ + + 树节点数据范围 (1"只看本级" 2"查看本级及以下") + + 小诺分页列表结果 diff --git a/Api/Ewide.Core/Extension/InputBase.cs b/Api/Ewide.Core/Extension/InputBase.cs index 0b86364..1911128 100644 --- a/Api/Ewide.Core/Extension/InputBase.cs +++ b/Api/Ewide.Core/Extension/InputBase.cs @@ -76,6 +76,11 @@ namespace Ewide.Core /// 查询条件 /// public virtual SearchInfo[] SearchInfo { get; set; } + + /// + /// 树节点数据范围 (1"只看本级" 2"查看本级及以下") + /// + public virtual int? TreeNodeDataScope { get; set; } } } diff --git a/web-react/src/pages/business/house/member/form.jsx b/web-react/src/pages/business/house/member/form.jsx index db24377..262d9fd 100644 --- a/web-react/src/pages/business/house/member/form.jsx +++ b/web-react/src/pages/business/house/member/form.jsx @@ -256,11 +256,32 @@ export default class form extends Component { - + - - + + diff --git a/web-react/src/pages/business/house/member/index.jsx b/web-react/src/pages/business/house/member/index.jsx index e5b64d0..02dd057 100644 --- a/web-react/src/pages/business/house/member/index.jsx +++ b/web-react/src/pages/business/house/member/index.jsx @@ -339,13 +339,27 @@ export default class index extends Component { > {this.state.codes.commonStatus.map(item => { return ( - + {item.value} ) })} + + + } operator={ diff --git a/web-react/src/pages/system/user/form.jsx b/web-react/src/pages/system/user/form.jsx index 8504d3a..a33b5ed 100644 --- a/web-react/src/pages/system/user/form.jsx +++ b/web-react/src/pages/system/user/form.jsx @@ -350,10 +350,31 @@ export default class form extends Component { - + - + From f8e2952727ac9ba8657c3c0c62383997cb984e06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=87=AA=E5=B8=A6=E5=A4=A7=E4=BD=AC=E6=B0=94=E5=9C=BA?= <188633308@qq.com> Date: Fri, 2 Jul 2021 16:01:22 +0800 Subject: [PATCH 10/15] =?UTF-8?q?update=20=E5=85=81=E8=AE=B8=E5=90=91modal?= =?UTF-8?q?=E4=B8=AD=E6=B7=BB=E5=8A=A0=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web-react/src/components/modal-form/index.jsx | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/web-react/src/components/modal-form/index.jsx b/web-react/src/components/modal-form/index.jsx index 5b86f51..ff78981 100644 --- a/web-react/src/components/modal-form/index.jsx +++ b/web-react/src/components/modal-form/index.jsx @@ -15,8 +15,23 @@ function renderModal(props, on, childWithProps) { onCancel: () => this.onClose(), } + const { buttons } = this.props + + const _buttons = [ + , + , + ] + + if (Array.isArray(buttons)) { + for (const { index, button } of buttons) { + _buttons.splice(index, 0, button(this.getData, this.close)) + } + } + return ( - + {childWithProps} ) @@ -112,6 +127,13 @@ export default class ModalForm extends Component { this.setState({ visible: false }) } + getData = async () => { + const body = this.childNode.current + if (!body || !body.getData) throw Error('为获取到子表单') + + return await body.getData() + } + /** * 子元素创建后回调 * 对子元素数据进行填充,(如需关闭时对比)之后再获取结构调整后的数据快照 From 837680422afacb21a82d23f888bc4d308e59b497 Mon Sep 17 00:00:00 2001 From: ky_yusj <2655568377@qq.com> Date: Fri, 2 Jul 2021 17:56:22 +0800 Subject: [PATCH 11/15] =?UTF-8?q?UPDATE=20=E6=9C=BA=E6=9E=84=E7=AE=A1?= =?UTF-8?q?=E7=90=86/=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E9=A1=B5=E6=96=B0=E5=A2=9E"=E5=8F=AA=E7=9C=8B?= =?UTF-8?q?=E6=9C=AC=E7=BA=A7"=E5=92=8C"=E6=9F=A5=E7=9C=8B=E6=9C=AC?= =?UTF-8?q?=E7=BA=A7=E5=8F=8A=E4=BB=A5=E4=B8=8B"=E7=9A=84=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Api/Ewide.Core/Service/Org/SysOrgService.cs | 4 ++-- Api/Ewide.Core/Service/User/SysUserService.cs | 4 ++-- web-react/src/pages/system/org/index.jsx | 18 ++++++++++++++++-- web-react/src/pages/system/user/index.jsx | 11 +++++++++++ 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/Api/Ewide.Core/Service/Org/SysOrgService.cs b/Api/Ewide.Core/Service/Org/SysOrgService.cs index 7c15c46..a0e5896 100644 --- a/Api/Ewide.Core/Service/Org/SysOrgService.cs +++ b/Api/Ewide.Core/Service/Org/SysOrgService.cs @@ -59,8 +59,8 @@ namespace Ewide.Core.Service var orgs = await _sysOrgRep.DetachedEntities .Where((name, u => EF.Functions.Like(u.Name, $"%{input.Name.Trim()}%")), // 根据机构名称模糊查询 (id, u => u.Id == input.Id.Trim()), // 根据机构id查询 - (pId, u => EF.Functions.Like(u.Pids, $"%[{input.Pid.Trim()}]%") - || u.Id == input.Pid.Trim())) // 根据父机构id查询 + (pId, u => input.TreeNodeDataScope.GetValueOrDefault(1) == 2 ? (EF.Functions.Like(u.Pids, $"%[{input.Pid.Trim()}]%") + || u.Id == input.Pid.Trim()) : u.Id == input.Pid.Trim() )) // 根据父机构id查询 .Where(dataScopeList.Count > 0, u => dataScopeList.Contains(u.Id)) // 非管理员范围限制 .Where(u => u.Status != CommonStatus.DELETED).OrderBy(u => u.Sort) .ToPageData(input); diff --git a/Api/Ewide.Core/Service/User/SysUserService.cs b/Api/Ewide.Core/Service/User/SysUserService.cs index 2a36cb5..ad041cd 100644 --- a/Api/Ewide.Core/Service/User/SysUserService.cs +++ b/Api/Ewide.Core/Service/User/SysUserService.cs @@ -79,8 +79,8 @@ namespace Ewide.Core.Service .Where(!string.IsNullOrEmpty(searchValue), x => (x.n.u.Account.Contains(input.SearchValue) || x.n.u.Name.Contains(input.SearchValue) || x.n.u.Phone.Contains(input.SearchValue))) - .Where(!string.IsNullOrEmpty(pid), x => (x.n.e.OrgId == pid || - x.o.Pids.Contains($"[{pid.Trim()}]"))) + .Where(!string.IsNullOrEmpty(pid), x => input.TreeNodeDataScope.GetValueOrDefault(1) == 2 ? (x.n.e.OrgId == pid || + x.o.Pids.Contains($"[{pid.Trim()}]")) : x.n.e.OrgId == pid ) .Where(input.SearchStatus >= 0, x => x.n.u.Status == input.SearchStatus) .Where(!superAdmin, x => x.n.u.AdminType != AdminType.SuperAdmin) .Where(!superAdmin && dataScopes.Count > 0, x => dataScopes.Contains(x.n.e.OrgId)) diff --git a/web-react/src/pages/system/org/index.jsx b/web-react/src/pages/system/org/index.jsx index d671ce5..76ac8f1 100644 --- a/web-react/src/pages/system/org/index.jsx +++ b/web-react/src/pages/system/org/index.jsx @@ -1,5 +1,5 @@ import React, { Component } from 'react' -import { Button, Card, Form, Input, message as Message, Popconfirm } from 'antd' +import { Button, Card, Form, Input, message as Message, Popconfirm, Select } from 'antd' import { AntIcon, Auth, @@ -159,7 +159,10 @@ export default class index extends Component { ...query, pid: this.selectId, } - + if (params) { + params.sortField = 'areaCode' + params.sortOrder = 'ascend' + } const { data } = await apiAction.page({ ...params, ...query, @@ -270,6 +273,17 @@ export default class index extends Component { + + + } operator={ diff --git a/web-react/src/pages/system/user/index.jsx b/web-react/src/pages/system/user/index.jsx index 080b4e0..fc0a0a0 100644 --- a/web-react/src/pages/system/user/index.jsx +++ b/web-react/src/pages/system/user/index.jsx @@ -322,6 +322,17 @@ export default class index extends Component { })} + + + } operator={ From 36a99648991e8f513445523383f0929f2f9b7598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=87=AA=E5=B8=A6=E5=A4=A7=E4=BD=AC=E6=B0=94=E5=9C=BA?= <188633308@qq.com> Date: Fri, 2 Jul 2021 19:00:01 +0800 Subject: [PATCH 12/15] =?UTF-8?q?update=20=E9=AA=8C=E8=AF=81=E5=AF=86?= =?UTF-8?q?=E7=A0=81=E5=BC=BA=E5=BA=A6,=E5=B9=B6=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=AF=86=E7=A0=81,=E5=9C=A8debug=E6=A8=A1=E5=BC=8F=E4=B8=8B?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E4=B8=8D=E9=9C=80=E8=A6=81=E6=AD=A3=E7=A1=AE?= =?UTF-8?q?=E5=AF=86=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Api/Ewide.Core/Ewide.Core.xml | 58 +++++---- Api/Ewide.Core/Service/Auth/AuthService.cs | 103 +++++++++++++--- Api/Ewide.Core/Service/Auth/Dto/LoginInput.cs | 23 +++- .../Service/Auth/Dto/LoginOutput.cs | 11 +- Api/Ewide.Core/Service/Auth/IAuthService.cs | 4 +- Api/Ewide.Core/applicationconfig.json | 5 + .../common/api/requests/sys/loginManage.js | 4 + web-react/src/views/login/index.jsx | 116 +++++++++++++++++- 8 files changed, 274 insertions(+), 50 deletions(-) diff --git a/Api/Ewide.Core/Ewide.Core.xml b/Api/Ewide.Core/Ewide.Core.xml index 712fedc..c72f463 100644 --- a/Api/Ewide.Core/Ewide.Core.xml +++ b/Api/Ewide.Core/Ewide.Core.xml @@ -3228,122 +3228,132 @@
123456 - + + + 新密码 + + + + + 确认密码 + + + 用户登录输出参数 - + 主键 - + 账号 - + 密码安全级别 - + 昵称 - + 姓名 - + 头像 - + 生日 - + 性别(字典 1男 2女) - + 邮箱 - + 手机 - + 电话 - + 管理员类型(0超级管理员 1非管理员) - + 最后登陆IP - + 最后登陆时间 - + 最后登陆地址 - + 最后登陆所用浏览器 - + 最后登陆所用系统 - + 员工信息 - + 具备应用信息 - + 角色信息 - + 权限信息 - + 登录菜单信息---AntDesign版本菜单 - + 数据范围(机构)信息 diff --git a/Api/Ewide.Core/Service/Auth/AuthService.cs b/Api/Ewide.Core/Service/Auth/AuthService.cs index 0571c5f..b1e7d0f 100644 --- a/Api/Ewide.Core/Service/Auth/AuthService.cs +++ b/Api/Ewide.Core/Service/Auth/AuthService.cs @@ -14,6 +14,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Text.RegularExpressions; using System.Threading.Tasks; using UAParser; @@ -68,20 +69,90 @@ namespace Ewide.Core.Service /// [HttpPost("/login")] [AllowAnonymous] - public async Task LoginAsync([Required] LoginInput input) + public async Task LoginAsync([Required] LoginInput input) { - string pwd = RSAHandler.RSADecrypt(input.Password); - // 获取加密后的密码 - var encryptPasswod = MD5Encryption.Encrypt(pwd); + var password = RSAHandler.RSADecrypt(input.Password); + var user = await GetUser(input); + +#if !DEBUG + // 验证密码强度 + var pattern = App.Configuration.GetSection("SimplePassword:Pattern").Value; + if (!Regex.Match(password, pattern).Success) + { + return new LoginOutput + { + Passed = false, + Pattern = pattern, + Descriptions = App.Configuration.GetSection("SimplePassword:Descriptions").Value + }; + } +#endif + + return new LoginOutput + { + Passed = true, + Token = await HandlerLoginAsync(user) + }; + } + + [HttpPost("/loginPass")] + [AllowAnonymous] + public async Task LoginPassAsync([Required] LoginPassInput input) + { + var user = await GetUser(input); + + var newPassword = RSAHandler.RSADecrypt(input.NewPassword); + // 验证新密码强度 + var pattern = App.Configuration.GetSection("SimplePassword:Pattern").Value; + if (!Regex.Match(newPassword, pattern).Success) + { + return new LoginOutput + { + Passed = false, + Pattern = pattern, + Descriptions = App.Configuration.GetSection("SimplePassword:Descriptions").Value + }; + } + + newPassword = MD5Encryption.Encrypt(newPassword); + if (newPassword.Equals(user.Password)) + throw Oops.Oh(ErrorCode.D10041); + + user.Password = newPassword; + + return new LoginOutput + { + Passed = true, + Token = await HandlerLoginAsync(user) + }; + + } + + private async Task GetUser(LoginInput input) + { + var password = RSAHandler.RSADecrypt(input.Password); + // 获取加密后的密码 + var encryptPasswod = MD5Encryption.Encrypt(password); + +#if DEBUG + var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Account.Equals(input.Account)); +#else // 判断用户名和密码是否正确 var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Account.Equals(input.Account) && u.Password.Equals(encryptPasswod)); _ = user ?? throw Oops.Oh(ErrorCode.D1000); +#endif // 验证账号是否被冻结 if (user.Status == CommonStatus.DISABLE) throw Oops.Oh(ErrorCode.D1017); + return user; + } + + + private async Task HandlerLoginAsync(SysUser user) + { // 生成Token令牌 //var accessToken = await _jwtBearerManager.CreateTokenAdmin(user); var accessToken = JWTEncryption.Encrypt(new Dictionary @@ -102,38 +173,40 @@ namespace Ewide.Core.Service _httpContextAccessor.HttpContext.Response.Headers["x-access-token"] = refreshToken; // 增加登录日志 - var loginOutput = user.Adapt(); + var loginUserOutput = user.Adapt(); var clent = Parser.GetDefault().Parse(App.GetService().HttpContext.Request.Headers["User-Agent"]); - loginOutput.LastLoginBrowser = clent.UA.Family + clent.UA.Major; - loginOutput.LastLoginOs = clent.OS.Family + clent.OS.Major; + loginUserOutput.LastLoginBrowser = clent.UA.Family + clent.UA.Major; + loginUserOutput.LastLoginOs = clent.OS.Family + clent.OS.Major; await new SysLogVis { Name = "登录", Success = true, Message = "登录成功", - Ip = loginOutput.LastLoginIp, - Browser = loginOutput.LastLoginBrowser, - Os = loginOutput.LastLoginOs, + Ip = loginUserOutput.LastLoginIp, + Browser = loginUserOutput.LastLoginBrowser, + Os = loginUserOutput.LastLoginOs, VisType = 1, - VisTime = loginOutput.LastLoginTime, - Account = loginOutput.Account + VisTime = loginUserOutput.LastLoginTime, + Account = loginUserOutput.Account }.InsertAsync(); return accessToken; + } + /// /// 获取当前登录用户信息 /// /// [HttpGet("/getLoginUser")] - public async Task GetLoginUserAsync() + public async Task GetLoginUserAsync() { var user = _userManager.User; var userId = user.Id; var httpContext = App.GetService().HttpContext; - var loginOutput = user.Adapt(); + var loginOutput = user.Adapt(); // 隐藏手机号/邮箱中间几位 loginOutput.Phone = String.IsNullOrEmpty(loginOutput.Phone) ? loginOutput.Phone @@ -197,7 +270,7 @@ namespace Ewide.Core.Service var userId = user.Id; var httpContext = App.GetService().HttpContext; - var loginOutput = user.Adapt(); + var loginOutput = user.Adapt(); var ip = httpContext.Request.Headers["X-Real-IP"]; diff --git a/Api/Ewide.Core/Service/Auth/Dto/LoginInput.cs b/Api/Ewide.Core/Service/Auth/Dto/LoginInput.cs index e57dbb7..2bd2803 100644 --- a/Api/Ewide.Core/Service/Auth/Dto/LoginInput.cs +++ b/Api/Ewide.Core/Service/Auth/Dto/LoginInput.cs @@ -1,4 +1,5 @@ -using Furion.DependencyInjection; +using Furion; +using Furion.DependencyInjection; using System.ComponentModel.DataAnnotations; namespace Ewide.Core.Service @@ -14,13 +15,29 @@ namespace Ewide.Core.Service ///
/// superAdmin [Required(ErrorMessage = "用户名不能为空"), MinLength(3, ErrorMessage = "用户名不能少于3位字符")] - public string Account { get; set; } + public virtual string Account { get; set; } /// /// 密码 /// /// 123456 [Required(ErrorMessage = "密码不能为空"), MinLength(5, ErrorMessage = "密码不能少于5位字符")] - public string Password { get; set; } + public virtual string Password { get; set; } + } + + [SkipScan] + public class LoginPassInput : LoginInput + { + /// + /// 新密码 + /// + [Required(ErrorMessage = "新密码不能为空")] + public string NewPassword { get; set; } + + /// + /// 确认密码 + /// + [Required(ErrorMessage = "确认密码不能为空"), Compare(nameof(NewPassword), ErrorMessage = "两次密码不一致")] + public string Confirm { get; set; } } } diff --git a/Api/Ewide.Core/Service/Auth/Dto/LoginOutput.cs b/Api/Ewide.Core/Service/Auth/Dto/LoginOutput.cs index e066ed6..3fb0bb8 100644 --- a/Api/Ewide.Core/Service/Auth/Dto/LoginOutput.cs +++ b/Api/Ewide.Core/Service/Auth/Dto/LoginOutput.cs @@ -4,11 +4,20 @@ using System.Collections.Generic; namespace Ewide.Core.Service { + [SkipScan] + public class LoginOutput + { + public bool Passed { get; set; } + public string Pattern { get; set; } + public string Descriptions { get; set; } + public string Token { get; set; } + } + /// /// 用户登录输出参数 /// [SkipScan] - public class LoginOutput + public class LoginUserOutput { /// /// 主键 diff --git a/Api/Ewide.Core/Service/Auth/IAuthService.cs b/Api/Ewide.Core/Service/Auth/IAuthService.cs index 5c63d70..395a3d6 100644 --- a/Api/Ewide.Core/Service/Auth/IAuthService.cs +++ b/Api/Ewide.Core/Service/Auth/IAuthService.cs @@ -7,8 +7,8 @@ namespace Ewide.Core.Service { Task GetCaptcha(); Task GetCaptchaOpen(); - Task GetLoginUserAsync(); - Task LoginAsync([Required] LoginInput input); + Task GetLoginUserAsync(); + Task LoginAsync([Required] LoginInput input); Task LogoutAsync(); Task VerificationCode(ClickWordCaptchaInput input); } diff --git a/Api/Ewide.Core/applicationconfig.json b/Api/Ewide.Core/applicationconfig.json index 9008b08..3ae16a9 100644 --- a/Api/Ewide.Core/applicationconfig.json +++ b/Api/Ewide.Core/applicationconfig.json @@ -102,5 +102,10 @@ "sysNotice:unread", "sysNotice:detail" ] + }, + + "SimplePassword": { + "Pattern": "(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[^a-zA-Z0-9]){8,}", + "Descriptions": "密码中必须包含大小字母、数字、特称字符,至少8个字符" } } \ No newline at end of file diff --git a/web-react/src/common/api/requests/sys/loginManage.js b/web-react/src/common/api/requests/sys/loginManage.js index 8d969e3..216a8e4 100644 --- a/web-react/src/common/api/requests/sys/loginManage.js +++ b/web-react/src/common/api/requests/sys/loginManage.js @@ -3,6 +3,10 @@ const urls = { * 登录 */ login: ['/login', 'post'], + /** + * 登录时修改密码 + */ + loginPass: ['/loginPass', 'post'], /** * 登出 */ diff --git a/web-react/src/views/login/index.jsx b/web-react/src/views/login/index.jsx index d7290aa..ef7dfa2 100644 --- a/web-react/src/views/login/index.jsx +++ b/web-react/src/views/login/index.jsx @@ -1,5 +1,5 @@ import React, { Component } from 'react' -import { Button, Form, Input, message as Message } from 'antd' +import { Alert, Button, Form, Input, message as Message, Modal } from 'antd' import Container from 'components/container' import { encryptByRSA } from 'util/rsa' import { RSA_PUBLIC_KEY } from 'util/global' @@ -14,6 +14,10 @@ export default class index extends Component { focusPassword: false, btnDisabled: true, + + pattern: '', + descriptions: '', + visible: false, } backgroundImage = require(`assets/image/login-bg-0${Math.floor(Math.random() * 4)}.jpg`) @@ -33,9 +37,19 @@ export default class index extends Component { api.login({ account, password }) .then(({ success, data, message }) => { if (success) { - token.value = data - Message.success('登录成功') - this.props.history.replace('/') + const { passed, pattern, descriptions, token } = data + // 简单密码需要更改 + if (!passed) { + this.setState({ + visible: true, + loading: false, + btnDisabled: true, + pattern, + descriptions, + }) + } else { + this.onLoginSuccess(token) + } } else { this.setState({ loading: false }) Message.error(message) @@ -49,8 +63,52 @@ export default class index extends Component { }) } + onLoginPass = values => { + this.setState({ loading: true }) + const account = this.form.current.getFieldValue('account') + let { password, newPassword } = values + password = encryptByRSA(password, RSA_PUBLIC_KEY) + newPassword = encryptByRSA(newPassword, RSA_PUBLIC_KEY) + const confirm = newPassword // 前端验证两次密码即可.不需要加密 + + api.loginPass({ account, password, newPassword, confirm }) + .then(({ success, data, message }) => { + if (success) { + const { passed, pattern, descriptions, token } = data + // 简单密码需要更改 + if (!passed) { + this.setState({ + visible: true, + loading: false, + btnDisabled: true, + pattern, + descriptions, + }) + } else { + this.onLoginSuccess(token) + } + } else { + this.setState({ loading: false }) + Message.error(message) + } + }) + .catch(({ message }) => { + if (typeof message === 'object' && message[0]) { + Message.error(message[0].messages[0]) + } + this.setState({ loading: false }) + }) + } + + onLoginSuccess(jwtToken) { + token.value = jwtToken + Message.success('登录成功') + this.props.history.replace('/') + } + render() { - const { loading, focusUser, focusPassword, btnDisabled } = this.state + const { loading, focusUser, focusPassword, btnDisabled, visible, pattern, descriptions } = + this.state return (
@@ -121,6 +179,54 @@ export default class index extends Component {
+ + +
+
+
+ + + + + + + ({ + validator(_, value) { + if (!value || getFieldValue('newPassword') === value) { + return Promise.resolve() + } + return Promise.reject(new Error('确认新密码不匹配')) + }, + }), + ]} + name="confirm" + > + + +
+ + + +
+
) } From 63374ac2c8af12274381f9e4abffae9e1aa4e9e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=87=AA=E5=B8=A6=E5=A4=A7=E4=BD=AC=E6=B0=94=E5=9C=BA?= <188633308@qq.com> Date: Fri, 2 Jul 2021 20:17:41 +0800 Subject: [PATCH 13/15] =?UTF-8?q?update=20=E5=85=81=E8=AE=B8=E6=89=8B?= =?UTF-8?q?=E6=9C=BA=E5=8F=B7/=E9=82=AE=E7=AE=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Api/Ewide.Core/Service/Auth/AuthService.cs | 4 +-- Api/Ewide.Core/Service/User/SysUserService.cs | 32 +++++++++++++++++-- .../src/assets/style/dark/lib/modal.less | 3 ++ .../src/assets/style/dark/pages/login.less | 11 ++++--- .../src/assets/style/default/lib/modal.less | 3 ++ .../src/assets/style/default/pages/login.less | 5 ++- web-react/src/pages/system/user/index.jsx | 6 ++-- web-react/src/views/login/index.jsx | 2 ++ .../src/views/main/_layout/header/notice.jsx | 2 +- 9 files changed, 55 insertions(+), 13 deletions(-) diff --git a/Api/Ewide.Core/Service/Auth/AuthService.cs b/Api/Ewide.Core/Service/Auth/AuthService.cs index b1e7d0f..08c6da5 100644 --- a/Api/Ewide.Core/Service/Auth/AuthService.cs +++ b/Api/Ewide.Core/Service/Auth/AuthService.cs @@ -136,10 +136,10 @@ namespace Ewide.Core.Service var encryptPasswod = MD5Encryption.Encrypt(password); #if DEBUG - var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Account.Equals(input.Account)); + var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Account.Equals(input.Account) || u.Phone.Equals(input.Account) || u.Email.Equals(input.Account)); #else // 判断用户名和密码是否正确 - var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Account.Equals(input.Account) && u.Password.Equals(encryptPasswod)); + var user = await _sysUserRep.FirstOrDefaultAsync(u => (u.Account.Equals(input.Account) || u.Phone.Equals(input.Account) || u.Email.Equals(input.Account)) && u.Password.Equals(encryptPasswod)); _ = user ?? throw Oops.Oh(ErrorCode.D1000); #endif diff --git a/Api/Ewide.Core/Service/User/SysUserService.cs b/Api/Ewide.Core/Service/User/SysUserService.cs index 2a36cb5..74e8478 100644 --- a/Api/Ewide.Core/Service/User/SysUserService.cs +++ b/Api/Ewide.Core/Service/User/SysUserService.cs @@ -111,7 +111,21 @@ namespace Ewide.Core.Service // 数据范围检查 await CheckDataScope(input); - var isExist = await _sysUserRep.AnyAsync(u => u.Account == input.Account, false); + var email = input.Email?.ToLower(); + + var isExist = await _sysUserRep.AnyAsync(u => + input.Account.Equals(u.Account) || + input.Account.Equals(u.Phone) || + input.Account.Equals(u.Email) || + (!string.IsNullOrWhiteSpace(input.Phone) && ( + input.Phone.Equals(u.Account) || + input.Phone.Equals(u.Phone) + )) || + (!string.IsNullOrWhiteSpace(email) && ( + email.Equals(u.Account) || + email.Equals(u.Email) + )) + , false); if (isExist) throw Oops.Oh(ErrorCode.D1003); input.Password = CommonConst.DEFAULT_PASSWORD; var user = input.Adapt(); @@ -171,8 +185,22 @@ namespace Ewide.Core.Service // 数据范围检查 await CheckDataScope(input); + var email = input.Email?.ToLower(); + // 排除自己并且判断与其他是否相同 - var isExist = await _sysUserRep.AnyAsync(u => u.Account == input.Account && u.Id != input.Id, false); + var isExist = await _sysUserRep.AnyAsync(u => + (input.Account.Equals(u.Account) && !input.Id.Equals(u.Id)) || + input.Account.Equals(u.Phone) || + input.Account.Equals(u.Email) || + (!string.IsNullOrWhiteSpace(input.Phone) && ( + input.Phone.Equals(u.Account) || + (input.Phone.Equals(u.Phone) && !input.Id.Equals(u.Id)) + )) || + (!string.IsNullOrWhiteSpace(email) && ( + email.Equals(u.Account) || + (email.Equals(u.Email) && !input.Id.Equals(u.Id)) + )) + , false); if (isExist) throw Oops.Oh(ErrorCode.D1003); var user = input.Adapt(); diff --git a/web-react/src/assets/style/dark/lib/modal.less b/web-react/src/assets/style/dark/lib/modal.less index 8c9c850..f87defd 100644 --- a/web-react/src/assets/style/dark/lib/modal.less +++ b/web-react/src/assets/style/dark/lib/modal.less @@ -36,3 +36,6 @@ width: 26px; height: 26px; } +.ant-modal-mask { + backdrop-filter: blur(3px); +} diff --git a/web-react/src/assets/style/dark/pages/login.less b/web-react/src/assets/style/dark/pages/login.less index b2e8e8e..d4a7bcd 100644 --- a/web-react/src/assets/style/dark/pages/login.less +++ b/web-react/src/assets/style/dark/pages/login.less @@ -46,7 +46,7 @@ padding: @padding-lg; border-radius: @border-radius-base + 2px; - background: linear-gradient(45deg, @white, fade(@white, 80%)); + background: linear-gradient(45deg, @component-background, fade(@component-background, 80%)); } .ant-form-item { margin-bottom: 0; @@ -59,7 +59,7 @@ >label { font-weight: normal !important; - color: fade(@black, 40%); + color: fade(@white, 40%); } } &--label { @@ -69,9 +69,9 @@ } .ant-input, .ant-input-affix-wrapper { - color: fade(@black, 85%); + color: fade(@white, 85%); border-width: 0 0 @border-width-base 0 !important; - border-color: fade(@black, 10%); + border-color: fade(@white, 10%); background-color: transparent; } .ant-input:hover, @@ -83,4 +83,7 @@ border-color: @primary-color; box-shadow: none !important; } + .ant-input::placeholder { + font-size: @font-size-base; + } } diff --git a/web-react/src/assets/style/default/lib/modal.less b/web-react/src/assets/style/default/lib/modal.less index 8c9c850..f87defd 100644 --- a/web-react/src/assets/style/default/lib/modal.less +++ b/web-react/src/assets/style/default/lib/modal.less @@ -36,3 +36,6 @@ width: 26px; height: 26px; } +.ant-modal-mask { + backdrop-filter: blur(3px); +} diff --git a/web-react/src/assets/style/default/pages/login.less b/web-react/src/assets/style/default/pages/login.less index b2e8e8e..636988c 100644 --- a/web-react/src/assets/style/default/pages/login.less +++ b/web-react/src/assets/style/default/pages/login.less @@ -46,7 +46,7 @@ padding: @padding-lg; border-radius: @border-radius-base + 2px; - background: linear-gradient(45deg, @white, fade(@white, 80%)); + background: linear-gradient(45deg, @component-background, fade(@component-background, 80%)); } .ant-form-item { margin-bottom: 0; @@ -83,4 +83,7 @@ border-color: @primary-color; box-shadow: none !important; } + .ant-input::placeholder { + font-size: @font-size-base; + } } diff --git a/web-react/src/pages/system/user/index.jsx b/web-react/src/pages/system/user/index.jsx index 080b4e0..3a29671 100644 --- a/web-react/src/pages/system/user/index.jsx +++ b/web-react/src/pages/system/user/index.jsx @@ -183,10 +183,10 @@ export default class index extends Component { /** * 删除 - * @param {*} record + * @param {*} id */ - onDelete(record) { - this.onAction(apiAction.delete(record), '删除成功') + onDelete(id) { + this.onAction(apiAction.delete({ id }), '删除成功') } //#region 自定义方法 diff --git a/web-react/src/views/login/index.jsx b/web-react/src/views/login/index.jsx index ef7dfa2..ce8ca80 100644 --- a/web-react/src/views/login/index.jsx +++ b/web-react/src/views/login/index.jsx @@ -142,6 +142,7 @@ export default class index extends Component { }} size="large" autoComplete="off" + placeholder={focusUser && '请输入用户名/手机号/邮箱'} /> diff --git a/web-react/src/views/main/_layout/header/notice.jsx b/web-react/src/views/main/_layout/header/notice.jsx index b6f7d9d..d0d2ec6 100644 --- a/web-react/src/views/main/_layout/header/notice.jsx +++ b/web-react/src/views/main/_layout/header/notice.jsx @@ -122,7 +122,7 @@ export default class notice extends Component { > - + From 1ebee158bda3d1ee8a5d52449a365099c9f31361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=87=AA=E5=B8=A6=E5=A4=A7=E4=BD=AC=E6=B0=94=E5=9C=BA?= <188633308@qq.com> Date: Fri, 2 Jul 2021 20:35:57 +0800 Subject: [PATCH 14/15] =?UTF-8?q?fix=20=E6=9C=8D=E5=8A=A1=E7=9B=91?= =?UTF-8?q?=E6=8E=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web-react/src/pages/system/machine/base.jsx | 2 +- web-react/src/pages/system/machine/index.jsx | 6 ++++-- web-react/src/pages/system/machine/use-charts.jsx | 15 +++++++++++---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/web-react/src/pages/system/machine/base.jsx b/web-react/src/pages/system/machine/base.jsx index 9437b73..47403fe 100644 --- a/web-react/src/pages/system/machine/base.jsx +++ b/web-react/src/pages/system/machine/base.jsx @@ -13,7 +13,7 @@ export default class base extends Component { {hostName} diff --git a/web-react/src/pages/system/machine/index.jsx b/web-react/src/pages/system/machine/index.jsx index fa6a8a9..55155a3 100644 --- a/web-react/src/pages/system/machine/index.jsx +++ b/web-react/src/pages/system/machine/index.jsx @@ -21,8 +21,10 @@ export default class index extends Component { } async componentDidMount() { - const { data: base } = await api.sysMachineBase() - this.setState({ loading: false, base }) + try { + const { data: base } = await api.sysMachineBase() + this.setState({ loading: false, base }) + } catch {} } render() { diff --git a/web-react/src/pages/system/machine/use-charts.jsx b/web-react/src/pages/system/machine/use-charts.jsx index 2693159..22f903b 100644 --- a/web-react/src/pages/system/machine/use-charts.jsx +++ b/web-react/src/pages/system/machine/use-charts.jsx @@ -14,6 +14,8 @@ export default class useCharts extends Component { timer = null timerMoment = null + actived = true + systemStart = moment() now = Date.now() @@ -27,6 +29,7 @@ export default class useCharts extends Component { shouldComponentUpdate(props) { // 当前页签未选中时停止获取状态 if (this.props.actived !== props.actived) { + this.actived = props.actived if (props.actived) { this.start() } else { @@ -53,9 +56,7 @@ export default class useCharts extends Component { } start() { - this.timer = setInterval(() => { - this.refreshData() - }, 3000) + this.actived = true this.refreshData() this.timerMoment = setInterval(() => { this.setState({ nowMoment: moment() }) @@ -63,7 +64,8 @@ export default class useCharts extends Component { } stop() { - clearInterval(this.timer) + this.actived = false + clearTimeout(this.timer) clearInterval(this.timerMoment) } @@ -91,6 +93,11 @@ export default class useCharts extends Component { }) this.setState({ use }) + + if (this.actived) + this.timer = setTimeout(() => { + this.refreshData() + }, 3000) } initCpuChart() { From 6d9fbd15da9c0460d7601033a1ab73dd37c10ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=87=AA=E5=B8=A6=E5=A4=A7=E4=BD=AC=E6=B0=94=E5=9C=BA?= <188633308@qq.com> Date: Fri, 2 Jul 2021 21:25:28 +0800 Subject: [PATCH 15/15] fix --- Api/Ewide.Core/Service/Auth/AuthService.cs | 7 +------ web-react/src/views/login/index.jsx | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Api/Ewide.Core/Service/Auth/AuthService.cs b/Api/Ewide.Core/Service/Auth/AuthService.cs index 08c6da5..5728f2d 100644 --- a/Api/Ewide.Core/Service/Auth/AuthService.cs +++ b/Api/Ewide.Core/Service/Auth/AuthService.cs @@ -107,12 +107,7 @@ namespace Ewide.Core.Service var pattern = App.Configuration.GetSection("SimplePassword:Pattern").Value; if (!Regex.Match(newPassword, pattern).Success) { - return new LoginOutput - { - Passed = false, - Pattern = pattern, - Descriptions = App.Configuration.GetSection("SimplePassword:Descriptions").Value - }; + throw Oops.Oh("新密码强度不符合规则"); } newPassword = MD5Encryption.Encrypt(newPassword); diff --git a/web-react/src/views/login/index.jsx b/web-react/src/views/login/index.jsx index ce8ca80..0e9b331 100644 --- a/web-react/src/views/login/index.jsx +++ b/web-react/src/views/login/index.jsx @@ -197,7 +197,7 @@ export default class index extends Component { label="新密码" rules={[ { required: true, message: '请输入新密码' }, - // { pattern, message: '密码格式错误' }, + { pattern, message: '密码格式错误' }, ]} name="newPassword" tooltip={descriptions}