diff --git a/Api/Ewide.Application/Ewide.Application.xml b/Api/Ewide.Application/Ewide.Application.xml index 8225ae3..22433b6 100644 --- a/Api/Ewide.Application/Ewide.Application.xml +++ b/Api/Ewide.Application/Ewide.Application.xml @@ -1456,5 +1456,20 @@ 上报备注 + + + 所属街道 + + + + + 名称 + + + + + 机构Id + + diff --git a/Api/Ewide.Application/Service/HouseSafety/HouseZone/Dto/HouseZoneInput.cs b/Api/Ewide.Application/Service/HouseSafety/HouseZone/Dto/HouseZoneInput.cs index 4c63c2d..1d69b94 100644 --- a/Api/Ewide.Application/Service/HouseSafety/HouseZone/Dto/HouseZoneInput.cs +++ b/Api/Ewide.Application/Service/HouseSafety/HouseZone/Dto/HouseZoneInput.cs @@ -1,4 +1,5 @@ -using System; +using Ewide.Core.Service; +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; @@ -13,4 +14,28 @@ namespace Ewide.Application [MinLength(9, ErrorMessage = "区域编码长度必须为9位及以上")] public string AreaCode { get; set; } } + + public class AddHouseZoneInput : OrgInput + { + /// + /// 所属街道 + /// + [Required(ErrorMessage = "所属街道不能为空")] + public override string Pid { get; set; } + /// + /// 名称 + /// + [Required(ErrorMessage = "片区名称不能为空")] + public override string Name { get; set; } + + } + + public class UpdateHouseZoneInput : AddHouseZoneInput + { + /// + /// 机构Id + /// + [Required(ErrorMessage = "片区Id不能为空")] + public string Id { get; set; } + } } diff --git a/Api/Ewide.Application/Service/HouseSafety/HouseZone/HouseZoneService.cs b/Api/Ewide.Application/Service/HouseSafety/HouseZone/HouseZoneService.cs index 323136c..4b9d3f8 100644 --- a/Api/Ewide.Application/Service/HouseSafety/HouseZone/HouseZoneService.cs +++ b/Api/Ewide.Application/Service/HouseSafety/HouseZone/HouseZoneService.cs @@ -2,9 +2,11 @@ using Ewide.Core.Extension; using Ewide.Core.Service; using Furion.DatabaseAccessor; +using Furion.DatabaseAccessor.Extensions; using Furion.DependencyInjection; using Furion.DynamicApiController; using Furion.FriendlyException; +using Mapster; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System; @@ -104,9 +106,9 @@ namespace Ewide.Application.Service } [HttpGet("/houseZone/autoIncrement")] - public async Task AutoIncrement([FromQuery] string code) + public async Task AutoIncrement([FromQuery] string roadId) { - var road = await _sysOrgRep.DetachedEntities.FirstOrDefaultAsync(p => p.AreaCode == code); + var road = await _sysOrgRep.DetachedEntities.FirstOrDefaultAsync(p => p.Id == roadId && p.Type == 3); if (road == null) throw Oops.Oh("组织机构错误"); return await AutoIncrement(road); } @@ -119,7 +121,7 @@ namespace Ewide.Application.Service } [HttpPost("/houseZone/add")] - public async Task AddZone(AddOrgInput input) + public async Task AddZone(AddHouseZoneInput input) { /* * 区县市限定所属区域/上级机构是否为当前区 @@ -136,15 +138,14 @@ namespace Ewide.Application.Service var roles = await _userManager.GetUserRoleList(); if (roles.Any(p => p.Code == areaManager)) { - var road = await _sysOrgRep.DetachedEntities.FirstOrDefaultAsync(p => p.AreaCode == input.AreaCode); - if (!road.Pids.Contains(org.Id)) throw Oops.Oh("组织机构错误"); + var road = await _sysOrgRep.DetachedEntities.FirstOrDefaultAsync(p => p.Id == input.Pid); + if (!road.Pids.Contains(org.Id)) throw Oops.Oh("当前用户组织机构错误"); - input.Pid = road.Id; + input.AreaCode = road.AreaCode; input.Code = road.Code + (await AutoIncrement(road)).ToString().PadLeft(3, '0'); } else if (roles.Any(p => p.Code == roadManager)) { - input.Pid = org.Id; input.AreaCode = org.AreaCode; input.Code = org.Code + (await AutoIncrement(org)).ToString().PadLeft(3, '0'); @@ -152,7 +153,17 @@ namespace Ewide.Application.Service input.Type = (int)OrgType.片区; - await _sysOrgService.AddOrg(input); + AddOrgInput addOrgInput = input.Adapt(); + await _sysOrgService.AddOrg(addOrgInput); + } + + [HttpPost("/houseZone/edit")] + public async Task EditZone(UpdateHouseZoneInput input) + { + var zone = await _sysOrgRep.DetachedEntities.FirstOrDefaultAsync(z => z.Id == input.Id); + if(zone == null) throw Oops.Oh("修改失败:数据有误,刷新列表后再尝试修改"); + zone.Remark = input.Remark; + await zone.UpdateIncludeAsync(new[] { nameof(SysOrg.Remark) }, true); } } } diff --git a/Api/Ewide.Core/Service/Org/Dto/OrgInput.cs b/Api/Ewide.Core/Service/Org/Dto/OrgInput.cs index accb321..bdabbbf 100644 --- a/Api/Ewide.Core/Service/Org/Dto/OrgInput.cs +++ b/Api/Ewide.Core/Service/Org/Dto/OrgInput.cs @@ -10,7 +10,7 @@ namespace Ewide.Core.Service /// /// 父Id /// - public string Pid { get; set; } + public virtual string Pid { get; set; } /// /// 父Ids diff --git a/web-react/src/common/api/requests/business/houseSafety/houseZone.js b/web-react/src/common/api/requests/business/houseSafety/houseZone.js index 0aa569f..d042f01 100644 --- a/web-react/src/common/api/requests/business/houseSafety/houseZone.js +++ b/web-react/src/common/api/requests/business/houseSafety/houseZone.js @@ -7,7 +7,8 @@ const urls = { houseZoneList: '/houseZone/list', houseZoneAutoIncrement: '/houseZone/autoIncrement', - houseZoneAdd: ['/houseZone/add', 'post'] + houseZoneAdd: ['/houseZone/add', 'post'], + houseZoneEdit: ['/houseZone/edit', 'post'] } export default urls \ No newline at end of file diff --git a/web-react/src/pages/business/house/project/form.jsx b/web-react/src/pages/business/house/project/form.jsx index 7ba461d..750743b 100644 --- a/web-react/src/pages/business/house/project/form.jsx +++ b/web-react/src/pages/business/house/project/form.jsx @@ -121,6 +121,7 @@ export default class form extends Component { async loadAreaData() { const { data } = await api.getAreaTree() + console.log(data) const clearChiildren = data => { data.forEach(item => { if (item.children && item.children.length) { diff --git a/web-react/src/pages/business/house/project/index.jsx b/web-react/src/pages/business/house/project/index.jsx index 7af0f2c..7ecec2f 100644 --- a/web-react/src/pages/business/house/project/index.jsx +++ b/web-react/src/pages/business/house/project/index.jsx @@ -47,22 +47,26 @@ export default class index extends Component { { title: '项目名称', dataIndex: 'name', + width: 150, sorter: true, }, { title: '社区', dataIndex: 'areaName', + width: 100, sorter: true, }, { title: '备注', dataIndex: 'note', + width: 150, sorter: true, }, { title: '类型', dataIndex: 'type', sorter: true, + width: 80, render: text => <>{this.bindCodeValue(text, 'house_type')}, }, ] @@ -73,7 +77,7 @@ export default class index extends Component { constructor(props) { super(props) - const flag = auth({ sysArea: [['edit'], ['delete']] }) + const flag = auth({ houseProjectInfo: [['edit'], ['delete']] }) if (flag) { this.columns.push({ diff --git a/web-react/src/pages/business/house/zone/form.jsx b/web-react/src/pages/business/house/zone/form.jsx index bb68a43..c93e21c 100644 --- a/web-react/src/pages/business/house/zone/form.jsx +++ b/web-react/src/pages/business/house/zone/form.jsx @@ -1,24 +1,36 @@ import React, { Component } from 'react' -import { Cascader, Form, Input, InputNumber, Select, Spin, TreeSelect } from 'antd' +import { Form, Input, InputNumber, Spin, TreeSelect } from 'antd' import { AntIcon } from 'components' import { cloneDeep } from 'lodash' -import getDictData from 'util/dic' import { api } from 'common/api' -import { numberToChinese } from 'util/format'; +import { numberToChinese } from 'util/format' +import store from 'store' +const { getState, subscribe } = store +const storePath = 'user' const initialValues = { - sort: 100 + sort: 100, } export default class form extends Component { state = { // 加载状态 loading: true, - + exist: false, options: { - areaData: [] - } + orgData: [], + }, + user: getState(storePath), } + constructor(props) { + super(props) + + this.unsubscribe = subscribe(storePath, () => { + this.setState({ + user: getState(storePath), + }) + }) + } // 表单实例 form = React.createRef() @@ -31,67 +43,55 @@ export default class form extends Component { componentDidMount() { this.props.created && this.props.created(this) } - + componentWillUnmount() { + this.unsubscribe() + } /** - * 填充数据 - * 可以在设置this.record之后对其作出数据结构调整 - * [异步,必要] - * @param {*} params - */ + * 填充数据 + * 可以在设置this.record之后对其作出数据结构调整 + * [异步,必要] + * @param {*} params + */ async fillData(params) { - + const { user } = this.state this.record = cloneDeep(params.record) //#region 从后端转换成前段所需格式 - const areaData = await this.loadAreaData() + const orgData = await this.loadOrgData() this.setState({ - options: { areaData } + exist: !!params.record, + options: { orgData }, }) - const areaCode = []; - const findCode = (data, level) => { - level = level || 0; - for (let i = 0; i < data.length; i++) { - const item = data[i]; - areaCode[level] = item.code; - - if (item.code === params.record.areaCode) { - areaCode.length = level + 1; - return true; + //街道角色新增,不管左侧树选中与否,默认值均为本街道 + if (user.adminType === 2) { + user.roles.map(role => { + if (role.code == 'road_manager') { + params.orgId = user.loginEmpInfo.orgId } - - if (item.children && item.children.length) { - const found = findCode(item.children, level + 1); - if (found) { - return true; - } - } - } - }; - - if (params.record && params.record.areaCode) { - findCode(areaData); + }) } this.record = { pid: params.orgId, ...this.record, - areaCode } - this.record.areaCode = areaCode - //#endregion + //#endregion + if (!params.record && !!params.orgId) { + this.onOrgIdChanged(params.orgId) + } this.form.current.setFieldsValue(this.record) this.setState({ - loading: false + loading: false, }) } /** * 获取数据 * 可以对postData进行数据结构调整 * [异步,必要] - * @returns + * @returns */ async getData() { const form = this.form.current @@ -102,74 +102,64 @@ export default class form extends Component { if (this.record) { postData.id = this.record.id } - //#region 从前段转换后端所需格式 - postData.areaCode = postData.areaCode[postData.areaCode.length - 1] + //#region 从前段转换后端所需格 //#endregion return postData } } - async loadAreaData() { - const { data } = await api.getAreaTree({ level: 3 }) - const clearChiildren = (data) => { - data.forEach((item) => { - if (item.children && item.children.length) { - clearChiildren(item.children); - } else { - delete item.children; - } - }); - }; - clearChiildren(data); + async loadOrgData() { + const { data } = await api.getOrgTree({ type: 4 }) return data } - onAreaCodeChange(value) { - this.loading = true; - // const { data } = api.houseZoneAutoIncrement({ code: selectedOptions[selectedOptions.length - 1] }); + onOrgIdChanged(value) { + this.loading = true - api.houseZoneAutoIncrement({ code: value[value.length - 1] }) + api.houseZoneAutoIncrement({ roadId: value }) .then(({ data }) => { this.form.current.setFieldsValue({ - name: `片区${numberToChinese(data)}` + name: `片区${numberToChinese(data)}`, + sort: data, }) }) .catch(() => { this.form.current.setFieldsValue({ name: '', - areaCode: [] + sort: 0, }) }) .finally(() => { - this.loading = false; - }); + this.loading = false + }) } render() { return ( -
+ }>
- - this.onAreaCodeChange(val)} + + this.onOrgIdChanged(value)} + disabled={this.state.exist} /> - - + + + @@ -187,4 +178,4 @@ export default class form extends Component { ) } -} \ No newline at end of file +} diff --git a/web-react/src/pages/business/house/zone/index.jsx b/web-react/src/pages/business/house/zone/index.jsx index 74dcbc8..fb8857f 100644 --- a/web-react/src/pages/business/house/zone/index.jsx +++ b/web-react/src/pages/business/house/zone/index.jsx @@ -1,6 +1,14 @@ import React, { Component } from 'react' import { Button, Card, Form, Input, message as Message, Popconfirm } from 'antd' -import { AntIcon, Auth, Container, ModalForm, QueryTable, QueryTableActions, QueryTreeLayout } from 'components' +import { + AntIcon, + Auth, + Container, + ModalForm, + QueryTable, + QueryTableActions, + QueryTreeLayout, +} from 'components' import { api } from 'common/api' import auth from 'components/authorized/handler' import { toCamelCase } from 'util/format' @@ -12,14 +20,13 @@ const apiAction = { tree: api.getOrgTree, page: api.houseZonePage, add: api.houseZoneAdd, - edit: api.sysOrgEdit, - delete: api.sysOrgDelete + edit: api.houseZoneEdit, + delete: api.sysOrgDelete, } const name = '片区' export default class index extends Component { - // 树框架实例 treeLayout = React.createRef() @@ -58,32 +65,34 @@ export default class index extends Component { /** * 构造函数,在渲染前动态添加操作字段等 - * @param {*} props + * @param {*} props */ constructor(props) { super(props) - const flag = auth({ sysOrg: [['edit'], ['delete']] }) + const flag = auth({ houseZone: [['edit'], ['delete']] }) if (flag) { this.columns.push({ title: '操作', width: 150, dataIndex: 'actions', - render: (text, record) => ( - - this.onOpen(this.editForm, record)}>编辑 - - - this.onDelete(record)} - > - 删除 - - - ) + render: (text, record) => ( + + + this.onOpen(this.editForm, record)}>编辑 + + + this.onDelete(record)} + > + 删除 + + + + ), }) } } @@ -92,9 +101,9 @@ export default class index extends Component { * 阻止外部组件引发的渲染,提升性能 * 可自行添加渲染条件 * [必要] - * @param {*} props - * @param {*} state - * @returns + * @param {*} props + * @param {*} state + * @returns */ shouldComponentUpdate(props, state) { return !isEqual(this.state, state) @@ -111,14 +120,14 @@ export default class index extends Component { /** * 调用加载数据接口,可在调用前对query进行处理 * [异步,必要] - * @param {*} params - * @param {*} query - * @returns + * @param {*} params + * @param {*} query + * @returns */ loadData = async (params, query) => { query = { ...query, - pid: this.selectId + pid: this.selectId, } const { data } = await apiAction.page({ @@ -141,7 +150,7 @@ export default class index extends Component { /** * 树节点选中事件 * [必要] - * @param {*} id + * @param {*} id */ onSelectTree(id) { this.selectId = id @@ -150,15 +159,15 @@ export default class index extends Component { /** * 绑定字典数据 - * @param {*} code - * @param {*} name - * @returns + * @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) + const c = codes.find(p => p.code === code) if (c) { return c.value } @@ -168,21 +177,21 @@ export default class index extends Component { /** * 打开新增/编辑弹窗 - * @param {*} modal - * @param {*} record + * @param {*} modal + * @param {*} record */ onOpen(modal, record) { modal.current.open({ orgId: this.selectId, - record + record, }) } /** * 对表格上的操作进行统一处理 * [异步] - * @param {*} action - * @param {*} successMessage + * @param {*} action + * @param {*} successMessage */ async onAction(action, successMessage) { this.table.current.onLoading() @@ -202,13 +211,10 @@ export default class index extends Component { /** * 删除 - * @param {*} record + * @param {*} record */ onDelete(record) { - this.onAction( - apiAction.delete(record), - '删除成功' - ) + this.onAction(apiAction.delete(record), '删除成功') } //#region 自定义方法 @@ -220,7 +226,7 @@ export default class index extends Component { ref={this.treeLayout} loadData={this.loadTreeData} defaultExpanded={true} - onSelect={(key) => this.onSelectTree(key)} + onSelect={key => this.onSelectTree(key)} > @@ -239,7 +245,9 @@ export default class index extends Component { + > + 新增{name} + } /> diff --git a/web-react/src/pages/system/area/index.jsx b/web-react/src/pages/system/area/index.jsx index ee8a43e..95e5f16 100644 --- a/web-react/src/pages/system/area/index.jsx +++ b/web-react/src/pages/system/area/index.jsx @@ -1,6 +1,14 @@ import React, { Component } from 'react' import { Button, Card, Form, Input, message as Message, Popconfirm } from 'antd' -import { AntIcon, Auth, Container, ModalForm, QueryTable, QueryTableActions, QueryTreeLayout } from 'components' +import { + AntIcon, + Auth, + Container, + ModalForm, + QueryTable, + QueryTableActions, + QueryTreeLayout, +} from 'components' import { api } from 'common/api' import auth from 'components/authorized/handler' import { toCamelCase } from 'util/format' @@ -13,17 +21,16 @@ const apiAction = { page: api.sysAreaPage, add: api.sysAreaAdd, edit: api.sysAreaEdit, - delete: api.sysAreaDelete + delete: api.sysAreaDelete, } const name = '区域' export default class index extends Component { - state = { codes: { - dicAreacodeType: [] - } + areacodeType: [], + }, } // 表格实例 @@ -41,37 +48,43 @@ export default class index extends Component { title: '区域类型', dataIndex: 'levelType', sorter: true, - render: text => (<>{this.bindCodeValue(text, 'dic_areacode_type')}) + width: 50, + render: text => <>{this.bindCodeValue(text, 'areacode_type')}, }, { title: '区域名称', dataIndex: 'name', + width: 100, sorter: true, }, { title: '区域编号', dataIndex: 'code', + width: 80, sorter: true, }, { title: '行政编号', dataIndex: 'adCode', + width: 80, sorter: true, }, { title: '描述', dataIndex: 'note', + width: 200, sorter: false, }, { title: '排序', dataIndex: 'sort', + width: 80, sorter: true, }, ] /** * 构造函数,在渲染前动态添加操作字段等 - * @param {*} props + * @param {*} props */ constructor(props) { super(props) @@ -83,20 +96,22 @@ export default class index extends Component { title: '操作', width: 150, dataIndex: 'actions', - render: (text, record) => ( - - this.onOpen(this.editForm, record)}>编辑 - - - this.onDelete(record)} - > - 删除 - - - ) + render: (text, record) => ( + + + this.onOpen(this.editForm, record)}>编辑 + + + this.onDelete(record)} + > + 删除 + + + + ), }) } } @@ -104,9 +119,9 @@ export default class index extends Component { * 阻止外部组件引发的渲染,提升性能 * 可自行添加渲染条件 * [必要] - * @param {*} props - * @param {*} state - * @returns + * @param {*} props + * @param {*} state + * @returns */ shouldComponentUpdate(props, state) { return !isEqual(this.state, state) @@ -118,31 +133,33 @@ export default class index extends Component { */ componentDidMount() { this.table.current.onLoading() - getDictData('dic_areacode_type').then(res => { - this.setState({ - codes: res - }, () => { - this.table.current.onLoadData() - }) + getDictData('areacode_type').then(res => { + this.setState( + { + codes: res, + }, + () => { + this.table.current.onLoadData() + } + ) }) } /** - * 调用加载数据接口,可在调用前对query进行处理 - * [异步,必要] - * @param {*} params - * @param {*} query - * @returns - */ + * 调用加载数据接口,可在调用前对query进行处理 + * [异步,必要] + * @param {*} params + * @param {*} query + * @returns + */ loadData = async (params, query) => { - query = { ...query, - pcode: this.selectCode + pcode: this.selectCode, } //首次加载根据code列升序排序 if (!params.sortField) { - params.sortField = 'code'; - params.sortOrder = 'ascend'; + params.sortField = 'code' + params.sortOrder = 'ascend' } const { data } = await apiAction.page({ ...params, @@ -164,7 +181,7 @@ export default class index extends Component { /** * 树节点选中事件 * [必要] - * @param {*} id + * @param {*} id */ onSelectTree(code) { this.selectCode = code @@ -173,15 +190,15 @@ export default class index extends Component { /** * 绑定字典数据 - * @param {*} code - * @param {*} name - * @returns + * @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) + const c = codes.find(p => +p.code === code) if (c) { return c.value } @@ -191,21 +208,21 @@ export default class index extends Component { /** * 打开新增/编辑弹窗 - * @param {*} modal - * @param {*} record + * @param {*} modal + * @param {*} record */ onOpen(modal, record) { modal.current.open({ pcode: this.pcode, - record + record, }) } /** * 对表格上的操作进行统一处理 * [异步] - * @param {*} action - * @param {*} successMessage + * @param {*} action + * @param {*} successMessage */ async onAction(action, successMessage) { this.table.current.onLoading() @@ -220,13 +237,10 @@ export default class index extends Component { /** * 删除 - * @param {*} record + * @param {*} record */ onDelete(record) { - this.onAction( - apiAction.delete(record), - '删除成功' - ) + this.onAction(apiAction.delete(record), '删除成功') } render() { @@ -234,7 +248,7 @@ export default class index extends Component { this.onSelectTree(key)} + onSelect={key => this.onSelectTree(key)} replaceFields={{ value: 'code', title: 'name', children: 'children' }} > @@ -259,12 +273,12 @@ export default class index extends Component { + > + 新增{name} + } - > - - + > ) } -} \ No newline at end of file +}