diff --git a/pc4mobx/organization/apis/fieldDefined.js b/pc4mobx/organization/apis/fieldDefined.js new file mode 100644 index 0000000..5a5a66a --- /dev/null +++ b/pc4mobx/organization/apis/fieldDefined.js @@ -0,0 +1,43 @@ +import { + WeaTools +} from 'ecCom'; + +/** + * 获取tab数据 + * @param {Object} params [description] + * @return {[type]} [description] + */ +export const getTabInfo = (moduleName, params = {}) => WeaTools.callApi(`/api/hrm/${moduleName}/getTabInfo?is_multilang_set=true`, 'GET', params) + +export const getFieldDefinedInfo = (moduleName, params = {}) => WeaTools.callApi(`/api/hrm/${moduleName}/getFieldDefinedInfo?is_multilang_set=true`, 'GET', params) + +export const saveFieldDefinedInfo = (moduleName, params = {}) => WeaTools.callApi(`/api/hrm/${moduleName}/save`, 'POST', params) + +export const removeFieldDefinedInfo = (moduleName, params = {}) => WeaTools.callApi(`/api/hrm/${moduleName}/del`, 'POST', params) + +export const saveGroupInfo = (moduleName, params = {}) => WeaTools.callApi(`/api/hrm/${moduleName}/saveGroup`, 'POST', params) + +export const removeGroupInfo = (moduleName, params = {}) => WeaTools.callApi(`/api/hrm/${moduleName}/delGroup`, 'POST', params) + +export const getTree = (params = {}) => WeaTools.callApi(`/api/hrm/resourcefielddefined/getTree`, 'GET', params) + +export const saveTree = (params = {}) => WeaTools.callApi(`/api/hrm/resourcefielddefined/saveTree`, 'POST', params) + +export const changeGroup = (moduleName, params = {}) => WeaTools.callApi(`/api/hrm/${moduleName}/changeGroup`, 'POST', params) + +export const getEncryptFieldSettingForm = (params = {}) => WeaTools.callApi(`/api/encrypt/fieldsetting/getEncryptFieldSettingForm`, 'GET', params) + +export const saveEncryptFieldSettingForm = (params = {}) => WeaTools.callApi(`/api/encrypt/fieldsetting/saveEncryptFieldSettingForm`, 'POST', params) + +//获取字段可查看范围列表 +export const getEncryptFieldScopeList = (params = {}) => WeaTools.callApi('/api/encrypt/fieldsetting/getEncryptFieldScopeList', 'POST', params); + +//获取字段可查看范围表单 +export const getEncryptFieldScopeForm = (params = {}) => WeaTools.callApi('/api/encrypt/fieldsetting/getEncryptFieldScopeForm', 'GET', params); + +//保存字段可查看范围 +export const saveEncryptFieldScopeSetting = (params = {}) => WeaTools.callApi('/api/encrypt/fieldsetting/saveEncryptFieldScopeSetting', 'POST', params); + +//删除字段可查看范围 +export const delEncryptFieldScopeSetting = (params = {}) => WeaTools.callApi('/api/encrypt/fieldsetting/delEncryptFieldScopeSetting', 'POST', params); + diff --git a/pc4mobx/organization/components/fieldDefinedSet/FieldDefined.js b/pc4mobx/organization/components/fieldDefinedSet/FieldDefined.js new file mode 100644 index 0000000..8300743 --- /dev/null +++ b/pc4mobx/organization/components/fieldDefinedSet/FieldDefined.js @@ -0,0 +1,272 @@ +import '../../style/index.less'; +import React, { + Component +} from 'react'; +import * as mobx from 'mobx' +import { + inject, + observer +} from 'mobx-react'; +import { + WeaTop, + WeaTab, + WeaAlertPage, + WeaLeftTree, + WeaLeftRightLayout, + WeaDropdown, + WeaRightMenu, + WeaTableEdit, + WeaDialog + +} from 'ecCom'; +import { Spin, Button } from 'antd'; + +import { + i18n +} from '../../public/i18n'; +import FormInfo from './FormInfo'; +const { ButtonSelect } = WeaDropdown; +const toJS = mobx.toJS; + + +@inject('fieldDefined') +@observer +export default class FieldDefined extends Component { + constructor(props) { + super(props); + this.setState = { + + } + } + + componentDidMount() { + this.init(this.props); + } + + componentWillReceiveProps(nextProps) { + if (this.props.location.key !== nextProps.location.key) { + this.init(nextProps); + } + } + + init = (props) => { + const { + fieldDefined: store, + params + } = props, { + // checkAuthorized, + //initData, + initResourceData + } = store, { + type: moduleType + } = params + let moduleName, logSmallType; + if (moduleType === 'subCompany') { + moduleName = 'subcompanyfielddefined'; + } else if (moduleType === 'department') { + moduleName = 'departmentfielddefined'; + } else if (moduleType === 'job') { + moduleName = 'jobfielddefined'; + } else { + moduleName = 'resourcefielddefined'; + } + initResourceData(moduleName); + //checkAuthorized(moduleName, null, callbackFunc); + } + + getDropMenuDatas() { + const { + fieldDefined + } = this.props; + const { + rightMenu + } = fieldDefined; + + let menus = []; + toJS(rightMenu).map((item, index) => { + let obj = { + key: item.menuFun, + icon: , + content: item.menuName, + } + if (item.menuFun == 'collection' || item.menuFun == 'help' || item.menuFun == 'pageAddress') { + obj.disabled = true; + } + menus.push(obj); + }) + return menus; + } + + getTopMenuBtns() { + const { + fieldDefined + } = this.props; + const { + topMenu, + } = fieldDefined; + + let btns = []; + topMenu.map((item, i) => { + btns.push(); + }); + + return btns; + } + + handleClick(item) { + const { + fieldDefined + } = this.props; + this[item.menuFun] && this[item.menuFun](); + } + + new() { + const { + fieldDefined + } = this.props; + fieldDefined.editGroup(); + } + + onTabChange = tabKey => { + const { + fieldDefined + } = this.props; + fieldDefined.onTabChange(tabKey); + } + + onTabEdit = (tabKey, type) => { + debugger + console.log('onTabEdit: ', tabKey, type); + } + + render() { + + + const { + fieldDefined: store, + params + } = this.props, { + spinning, + refreshMainTabComponent, + treeConfig, + formTarget, + tabInfo, + tabKey, + setEditTable, + tableEditConfig, + dialogParams, + setDialogVisible, + getDialogOpButtons, + editorDialogRightMenu, + + } = store, { + type: moduleType + } = params, + title = moduleType === 'subCompany' ? i18n.module.subCompanyFieldDef() : moduleType === 'department' ? i18n.module.departmentFieldDef() : i18n.module.resourceFieldDef(), + topProps = { + title, + icon: , + iconBgcolor: '#217346', + showDropIcon: true, + buttons: this.getTopMenuBtns(), + dropMenuDatas: this.getDropMenuDatas(), + + }; + let children = []; + + //tabprops + let tabsData = cloneDeep(tabConfig.tabs) || []; + let tabProps = { + type: 'editable-inline', + datas: tabsData, + keyParam: tabConfig.keyParam, + selectedKey: tabConfig.activeTabKey, + onChange: tabChangeHandle, + leftStyle + } + + //end + + const { + groupInfoFrom, + groupInfoFromFields, + childInfoForm, + childInfoFormFields + } = formTarget; + + const { + editGroupInfo, + groupInfoSetting, + createChildInfo, + childInfoSetting + } = dialogParams; + + + const { + data, + onSelectedTreeNode, + selectedKeys, + onExpand, + treeExpandKeys + } = store.toJS(treeConfig); + const treeCom = ( + + ) + children = [ + ( + + + + + + { + + setEditTable(editTable, 'fieldDef')} + {...tableEditConfig['fieldDef']} + /> + + } + setDialogVisible('editGroupInfo', false)} + buttons={getDialogOpButtons()} + moreBtn={{ datas: editorDialogRightMenu }} + > + + + + + + ) + ] + + + return ( +
+ {children} +
+ ) + } +} \ No newline at end of file diff --git a/pc4mobx/organization/components/fieldDefinedSet/FormInfo.js b/pc4mobx/organization/components/fieldDefinedSet/FormInfo.js new file mode 100644 index 0000000..0c626ba --- /dev/null +++ b/pc4mobx/organization/components/fieldDefinedSet/FormInfo.js @@ -0,0 +1,151 @@ +import React, { + Component +} from 'react'; +import { + observer +} from 'mobx-react'; +import { + Button +} from 'antd'; +import { + WeaFormItem, + WeaSearchGroup, + WeaCheckbox +} from 'ecCom'; +import { + WeaSwitch +} from 'comsMobx'; +import findIndex from 'lodash/findIndex'; + +@observer +export default class FormInfo extends Component { + renderForm = () => { + const { + formFields, + form, + colCount, + itemRender, + onSelectedChangeHandle, + showLabel, + multiColumn, + custLabelCol, + childrenComponents, + onSwitchChange, + } = this.props; + + let groupArr = []; + const formParams = form.getFormParams(); + const labelVisible = showLabel == null || showLabel == true; + const col = colCount ? colCount : 1; + const labelCol = labelVisible ? (custLabelCol || `${window.HrmEngineLabelCol}`) : 0; + const itemProps = { + ratio1to2: labelVisible && custLabelCol == null, + style: { + marginLeft: 0 //labelVisible ? -30 : 0 + }, + tipPosition: 'bottom', + labelCol: { + span: labelCol + }, + wrapperCol: { + span: 24 - labelCol + } + } + + const textAreaProps = { + minRows: 4, + maxRows: 4 + } + + formFields.map((fields, i) => { + let formItems = []; + fields.items.map((field, index) => { + const customerRender = itemRender != null ? itemRender[field.domkey[0]] : null; + const showCheckbox = field.checkbox || false; + let label = field.label; + if (showCheckbox) + label = {field.checkboxValue = v === '1'; onSelectedChangeHandle && onSelectedChangeHandle(field, v)}}/> + + let coms; + if (customerRender == null) { + coms = onSwitchChange && onSwitchChange(datas)}/>; + } else { + coms = customerRender(field, textAreaProps, form, formParams); + } + Object.assign(itemProps, { + label, + error: form.getError(field) + }) + let col = 1; + if (multiColumn != null) { //检查有哪些字段需要一行显示多个 + const idx = findIndex(multiColumn, item => item.key === field.domkey[0]); + if (idx > -1) { + col = field.colSpan || 1; + if (multiColumn[idx].labelCol != null) //检查字段是否有配置标题宽度 + Object.assign(itemProps, { + labelCol: { + span: multiColumn[idx].labelCol + }, + wrapperCol: { + span: 24 - multiColumn[idx].labelCol + } + }) + } else { + Object.assign(itemProps, { + labelCol: { + span: labelCol + }, + wrapperCol: { + span: 24 - labelCol + } + }) + } + } + + coms != null && formItems.push({ + com: ( + + {coms} + + ), + col + }) + + if (childrenComponents && childrenComponents[field.domkey[0]]) { + childrenComponents[field.domkey[0]]().map(child => formItems.push(child)); + } + }) + + groupArr.push( + ( + + ) + ) + }); + + return groupArr; + } + + render() { + const { + formFields, + className, + showError + } = this.props; + if (formFields == null) + return (
) + + return ( +
+ {this.renderForm()} +
+ ) + } +} \ No newline at end of file diff --git a/pc4mobx/organization/index.js b/pc4mobx/organization/index.js index 917c942..38c1391 100644 --- a/pc4mobx/organization/index.js +++ b/pc4mobx/organization/index.js @@ -22,6 +22,7 @@ import Job from "./components/job/Job"; import JobExtend from "./components/job/JobExtend"; import Department from "./components/department/department"; import DepartmentExtendStore from "./components/department/departmentExtend"; +import FieldDefined from "./components/fieldDefinedSet/FieldDefined"; import stores from "./stores"; import "./style/index"; @@ -77,6 +78,8 @@ const Routes = ( + + ); diff --git a/pc4mobx/organization/stores/baseStore.js b/pc4mobx/organization/stores/baseStore.js new file mode 100644 index 0000000..ad4852c --- /dev/null +++ b/pc4mobx/organization/stores/baseStore.js @@ -0,0 +1,626 @@ +/** + * @Author: 程亮 + * @Date: 2022-06-09 10:14:20 + * @LastEditTime: 2022-06-09 10:41:31 + * @Description: + * @FilePath: /trunk/src4js/pc4mobx/organization/stores/baseStore.js + */ +import { + observable, + action, + computed, + extendObservable, + autorun +} from 'mobx'; +import { + Button, + message, + Modal +} from 'antd'; +import { + WeaForm, + WeaTableNew, + WeaLogView +} from 'comsMobx'; +import { + WeaTableEdit, + WeaBrowser, + WeaButtonIcon, + WeaCascader, + WeaLoadingGlobal +} from 'ecCom'; +import classnames from 'classnames'; +import * as mobx from 'mobx'; +import { + authorized, + detachable, + checkAuthAndDetach, + getPinYin +} from '../apis/common'; +import { + i18n +} from '../public/i18n'; +// import { +// logTypeDef +// } from '../public/logType'; +import has from 'lodash/has'; +import moment from 'moment'; + +const {OptionManage} = WeaCascader; + +const confirm = Modal.confirm; +const info = Modal.confirm; +const { + LogStore +} = WeaLogView; + +export default class HrmBaseStore { + /********************* unobservable list *********************/ + //logTypeDef = logTypeDef; + getPinYin = getPinYin; + toJS = mobx.toJS; + moment = moment; + tabConfig = { //模块主tab组件参数,通过继承来重写 + keyParam: 'viewCondition', + activeTabKey: '' + }; + basicDialogParams = { + icon: "icon-coms-hrm", + iconBgcolor: "#217346", + style: { + width: 520, + height: 300 + }, + visible: false, + title: '', + } + menuIconCollection = { + save: 'icon-coms-Preservation', + create: 'icon-coms-New-Flow', + modify: 'icon-coms-edit', + remove: 'icon-coms-Batch-delete', + copy: 'icon-coms-form-copy', + entry: 'icon-coms-edit', + setting: 'icon-coms-Flow-setting', + log: 'icon-coms-Print-log', + multiModify: 'icon-coms-BatchEditing', + import: ' icon-coms-leading-in', + export: 'icon-coms-export', + search: 'icon-coms-search', + sync: 'icon-coms-Update-synchronization', + done: 'icon-coms-Upload-successfully', + selectAll: 'icon-coms-batch' + } + getBasicMenus = (logTypeKey, targetId = null) => { + let arr = []; + if(logTypeKey){ + arr.push({ + key: '99', + content: i18n.button.log(), + icon: , + onClick: () => this.showLog({logSmallType: this.logTypeDef[logTypeKey], targetId}) + }); + } + return arr; + } + + generateLogMenu = (logType = '4', logTypeKey, targetId = null) => { + let arr = []; + if(logTypeKey){ + arr.push({ + key: '99', + content: i18n.button.log(), + icon: , + onClick: () => this.showLog({logType, logSmallType: this.logTypeDef[logTypeKey], targetId}) + }); + } + return arr; + } + + dialogPropsDef = { + moduleName: 'hrm', + visible: false, + title: '', + moreBtn: { + datas: [] + }, + // hasScroll: true + } + refsDialogPropsDef = { + moduleName: 'hrm', + visible: false, + title: '', + } + dateSwitchTypeList = ['year', 'month', 'week', 'day']; + formTarget = {}; //form collection + opId = null; //数据操作对象主键ID + authorizationInfo = {}; + + /** + * 权限验证 + * @param {String} moduleName [模块名] + * @param {Object} params [restful request url params] + * @param {Function} callback [验证通过后的callback function] + * @return {null} + */ + checkAuthorized = (moduleName, params, callback, apiMethod, needCheckDetachable = false) => { + if (needCheckDetachable) { + checkAuthAndDetach(moduleName, params, apiMethod).then(rs => { + rs.map((result, index) => { + if (result.status === '1') { + switch (index) { + case 0: + const init = !result.hasRight; + this.authorizationInfo = result; + this.containerInitFinished = { + ...this.containerInitFinished, + init, + authorized: result.hasRight, + userId: result.userId + } + this.containerInitFinished.authorized && callback && callback(); + break; + case 1: + this.containerInitFinished.detachable = result.detachable === '0' ? false : true + break; + } + } + }) + }) + } else { + authorized(moduleName, params, apiMethod).then((data) => { + if (data.status === '1') { + const init = !data.hasRight; + this.authorizationInfo = data; + this.containerInitFinished = { + init, + authorized: data.hasRight + } + this.containerInitFinished.authorized && callback && callback(); + } + }, error => { + this.containerInitFinished = { + init: true, + authorized: false + } + }); + } + } + + /** + * 获取激活的tab页下标 + * @param {Array} tabs [tabData数组] + * @param {String} key [tabKey] + * @return {Integer} [tab下标] + */ + getTabIndex(tabs, key) { + if (tabs != null && tabs.length > 0) { + return _.findIndex(tabs, { + viewCondition: key + }) + } + return -1; + } + + /** + * 获取WeaTop按钮、WeaTab按钮以及右键菜单列表 + * @param {Object} tabConfig [description] + * @return {Object} [description] + */ + btnsAndMenus = (tabConfig) => { + let topBtnDef = [], //WeaTop按钮 + menuDef = [], //右键菜单 + tabBtnDef = []; //WeaTab按钮 + + const activeTabIndex = this.getTabIndex(tabConfig.tabs, tabConfig.activeTabKey); + if (tabConfig.activeTabKey === '' || activeTabIndex < 0) { + return { + btns: topBtnDef, + menus: menuDef, + tabBtnDef: tabBtnDef + } + } + const tab = tabConfig.tabs[activeTabIndex]; + const { + topButtonDef, + tabButtonDef + } = tab; + topButtonDef && topButtonDef.map((def, idx) => { //组织WeaTop按钮 + const lbl = (typeof(def.label) == 'function' ? def.label() : def.label); + switch (def.comType) { + case 'button': + let disabled = false; + if (def.checkAction) + disabled = this[def.checkAction]; + topBtnDef.push(); + menuDef.push({ //组织右键菜单 + key: `$top-btn-${idx}`, + content: lbl, + icon: , + onClick: def.onClickHandle, + disabled: disabled || def.disabled || false + }) + break; + default: + break; + } + }); + tabButtonDef && tabButtonDef.map((def, idx) => { //组织WeaTab按钮 + const lab = (typeof(def.label) == 'function' ? def.label() : def.label); + let disabled = false; + if (def.checkAction) + disabled = this[def.checkAction]; + switch (def.comType) { + case 'button': + const classes = classnames({ + [def.icon]: true, + 'tabBtn': true, + 'tabBtn-active': !disabled, + 'tabBtn-disable': disabled + }); + if (def.brower == null) { + tabBtnDef.push( + + ); + } else { + switch (def.brower) { + case 'authorization': + tabBtnDef.push( + def.onClickHandle(ids, names, datas)} + isSingle={false} + > + + + ); + break; + } + } + break; + case 'WeaButtonIcon': + tabBtnDef.push( + + ); + break; + case 'customer': + tabBtnDef.push(def.coms) + break; + default: + tabBtnDef.push( + + ); + break; + } + }); + // menuDef.push(...this.getBasicMenus()); //组织右键菜单 + return { + btns: topBtnDef, + menus: menuDef, + tabBtnDef: tabBtnDef + } + } + + /** + * [description] + * @param {String} com [dialog's name] + * @param {Boolean} val [visible: true or false] + * @param {String} title [dialog's title] + * @param {Function} callback [callback function] + * @return {null} + */ + setDialogVisible = (com, val, title = '', callback) => { + this.dialogParams[com] = { + ...this.dialogParams[com], + visible: val, + title: title + }; + callback && callback(); + } + + confirmInfo = (props) => { + confirm({ ...props, + title: props.title || i18n.confirm.defaultTitle(), + okText: i18n.button.ok(), + cancelText: i18n.button.cancel() + }); + } + + hint = (props) => { + info({ ...props, + title: i18n.confirm.defaultTitle(), + okText: i18n.button.ok(), + }); + } + + /** + * 初始化formStore + * @param {String} formName [form's name] + * @param {Array} fields [form field definition] + * @return {null} + */ + setFormData = (formName, fields) => { + this.formTarget[`${formName}Fields`] = fields; + this.formTarget[formName] = new WeaForm(); + this.formTarget[formName].initFormFields(fields); + //this.formTarget[formName].setCondition(fields); + } + + /** + * 请求高级搜索表单的通用方法 + * @param {String} form [form's name] + * @param {Function} api [restful api function] + * @param {Object} params [restful request url params] + * @param {Function} callback [callback function] + * @return {null} + */ + requestFormData = (form, api, params = {}, callback) => { + api(params).then((data) => { + if (data.status === '1') { + this.setFormData(form, data.formField); + callback && callback(); + } + }, error => { + + }); + } + + /** + * 获取表格数据的通用方法 + * @param {String} tableStore [tableStore's name] + * @param {Function} api [restful api function] + * @param {Object} params [restful request url params] + * @return {null} + */ + requestTableData = (tableStore, api, params = {}, callback) => { + api(params).then(data => { + if (data.status === '1') { + tableStore.getDatas(data.sessionkey, 1); + callback && callback(); + } else + message.error(data.message); + }, error => { + message.error(i18n.message.actionError()); + }); + } + + showLog = (logTypeParams) => { + window.setLogViewProps({ + ...logTypeParams + }); + } + /********************* unobservable list *********************/ + + /********************* observable list *********************/ + @observable containerInitFinished = { //模块初始化状态 + init: false, + authorized: false, + detachable: false + } + @observable topTabCount = {}; //WeaTab统计值 + @observable rDate = new Date().getTime(); //状态刷新,组件引用该值监听变化重新render + @observable showError = new Date().getTime(); //状态刷新,组件引用该值监听变化重新render + @observable dialogParams = {}; //模态框参数 + @observable i18nLoaded = false; + + monitorI18n = () => { + this.i18nLoaded; + } + + monitor = autorun(this.monitorI18n) + /********************* observable list *********************/ + + /********************* action list *********************/ + @action definedColumn = (table, callback) => {//显示列定义 + table.setColSetVisible(true); + table.tableColSet(true, callback); + } + /********************* action list *********************/ + + /********************* tableEdit props & functions *********************/ + editTable = {}; //可编辑表格refs对象 + editTableConfig = { //WeaTableEdit参数定义,通过继承来重写 + showTitle: false, + draggable: true, + showAdd: false, + showDelete: false, + showCopy: false, + deleteConfirm: true + } + + /** + * 设置WeaTableEdit的refs对象 + * @param {Object} refs [WeaTableEdit] + */ + setEditTable = (refs, name) => { + this.editTable[name] = refs; + } + + /** + * 通过refs对WeaTableEdit进行添加行、删除行、复制行操作 + * @param {String} type [action] + */ + @action + recordOP = (target, type, callback = null) => { + switch (type) { + case 'add': + target.refs.edit.doAdd() + break; + case 'remove': + target.refs.edit.doDelete() + break; + case 'copy': + target.refs.edit.doCopy() + break; + case 'valid': + return target.refs.edit.doRequiredCheck() + default: + break; + } + } + + generateTableEditRightMenuInfo = (tableConfig) => { + let rightMenuInfo = []; + const keys = Object.keys(tableConfig); + keys.map((key, index) => { + rightMenuInfo.push({ + key: `8${index + 1}`, + disabled: tableConfig[key].disabled, + content: tableConfig[key].content, + icon: , + onClick: tableConfig[key].callback + }) + }) + return rightMenuInfo; + } + + generateTableSelectedData = (target) => { + let selectedData = {}; + this.tableEditConfig[target].columns.map(column => { + column.hasOwnProperty('checkType') && column.checkType === 'checkbox' && Object.assign(selectedData, { + [column.dataIndex]: [] + }) + }) + return selectedData; + } + + generateOtherParams = (componentType, used, domkey) => { + let otherParams = { + customProps: { + 'root': { + viewAttr: 1 + } + }, + optionManageProps: { + dialogProps: { + icon: "icon-coms-hrm", + iconBgcolor: "#217346", + }, + showAdd: !used, + showCopy: !used, + showDelete: !used, + tableEditDraggable: !used + } + } + switch (componentType) { + case 'input': + Object.assign(otherParams.customProps, { + 'input': { + viewAttr: 1 + }, + 'input.text': { + viewAttr: 1 + } + }); + break; + case 'select': + Object.assign(otherParams.customProps, { + 'select': { + viewAttr: 1, + }, + // 'select.*': { + // parent: { type: "span", className: `${domkey}-clz` } + // }, + }); + break; + } + return otherParams; + } + + convertData = (datas, target) => { + let tData = [], + selectedData = this.generateTableSelectedData(target); + datas.map((data, index) => { + let d = {}; + Object.assign(d, { + ...data.record, + ...data.props, + isSysField: data.isSysField + }); + delete d.key; + const selectedDataKey = Object.keys(selectedData); + selectedDataKey.map(key => { + data.record.hasOwnProperty(key) && data.record[key] === '1' && selectedData[key].push(index); + }) + + if (data.hasOwnProperty('com')) { + const keys = Object.keys(data.com); + keys.map(key => { + if (data.com[key].length > 0) { + let comDef = data.com[key][0]; + if (comDef.type === 'CUSTOMFIELD' && data.hasOwnProperty(comDef.key) && data[comDef.key].length > 0) { + Object.assign(d, { + [comDef.key]: data[comDef.key], + }); + Object.assign(comDef, { + viewAttr: 1, + otherParams: this.generateOtherParams(data[comDef.key][0], d.isSysField, d.fieldname), + }) + } else if (comDef.type === 'INPUT' && key != 'fieldname') { + comDef.otherParams = { + ...window.inputType + } + } + } + }) + Object.assign(d, { + com: data.com + }); + } + + tData.push(d); + }) + return { + datas: tData, + selectedData + } + } + + getLocale() { + return { + firstDayOfWeek: 0, + lang: { + format: { + eras: [getLabel(383357, "公元前"), getLabel(383358, "公元")], + months: [getLabel(1492, "一月"), getLabel(1493, "二月"), getLabel(383385, "三月"), getLabel(383387, "四月"), getLabel(1496, "五月"), getLabel(383392, "六月"), + getLabel(383393, "七月"), getLabel(383394, "八月"), getLabel(383395, "九月"), getLabel(383396, "十月"), getLabel(383397, "十一月"), getLabel(383398, "十二月") + ], + shortMonths: [getLabel(1492, "一月"), getLabel(1493, "二月"), getLabel(383385, "三月"), getLabel(383387, "四月"), getLabel(1496, "五月"), getLabel(383392, "六月"), + getLabel(383393, "七月"), getLabel(383394, "八月"), getLabel(383395, "九月"), getLabel(383396, "十月"), getLabel(383397, "十一月"), getLabel(383398, "十二月") + ], + weekdays: [getLabel(24626, "星期天"), getLabel(383399, "星期一"), getLabel(383400, "星期二"), getLabel(383402, "星期三"), getLabel(383403, "星期四"), + getLabel(383404, "星期五"), getLabel(383405, "星期六") + ], + shortWeekdays: [getLabel(16106, "周日"), getLabel(16100, "周一"), getLabel(16101, "周二"), getLabel(16102, "周三"), getLabel(16103, "周四"), getLabel(16104, "周五"), + getLabel(16105, "周六") + ], + veryShortWeekdays: [getLabel(16106, "周日"), getLabel(16100, "周一"), getLabel(16101, "周二"), getLabel(16102, "周三"), getLabel(16103, "周四"), getLabel(16104, "周五"), getLabel(16105, "周六")], + ampms: [getLabel(383408, "上午"), getLabel(383409, "下午")], + datePatterns: [`yyyy'${getLabel(383372,"年")}'M'${getLabel(383373,"月")}'d'${getLabel(383374,"日")}' EEEE`, `yyyy'${getLabel(383372,"年")}'M'${getLabel(383373,"月")}'d'${getLabel(383374,"日")}'`, "yyyy-M-d", "yy-M-d"], + timePatterns: [`ahh'${getLabel(383411,"时")}'mm'${getLabel(383412,"分")}'ss'${getLabel(383414,"秒")}' 'GMT'Z`, `ahh'${getLabel(383411,"时")}'mm'${getLabel(383412,"分")}'ss'${getLabel(383414,"秒")}'`, "H:mm:ss", "ah:mm"], + dateTimePattern: '{date} {time}' + } + }, + } + } + + @action showWeaLoadingGlobal = (tip = '') => WeaLoadingGlobal.start({tip}); + @action hideWeaLoadingGlobal = () => { + WeaLoadingGlobal.end(); // 停止遮罩loading + WeaLoadingGlobal.destroy(); // 销毁遮罩loading + } + /********************* tableEdit props & functions *********************/ +} \ No newline at end of file diff --git a/pc4mobx/organization/stores/fieldDefined.js b/pc4mobx/organization/stores/fieldDefined.js new file mode 100644 index 0000000..c576ff0 --- /dev/null +++ b/pc4mobx/organization/stores/fieldDefined.js @@ -0,0 +1,730 @@ +/** + * @Author: 程亮 + * @Date: 2022-06-09 10:16:00 + * @LastEditTime: 2022-06-10 16:32:02 + * @Description: + * @FilePath: /trunk/src4js/pc4mobx/organization/stores/fieldDefined.js + */ +import { + observable, + action, + computed +} from 'mobx'; +import { + WeaForm, + WeaTableNew, + WeaSwitch +} from 'comsMobx'; +import {WeaLocaleProvider, WeaInputLocale, WeaButtonIcon, WeaSelect} from 'ecCom'; +import { + Button, + message, + Menu +} from 'antd'; +import HrmBaseStore from './baseStore'; +import * as api from '../apis/fieldDefined'; +import { + cloneDeep, + indexOf, + findIndex, + uniq, + has, + remove, + filter +} from 'lodash'; +import find from 'lodash/find'; +import isEmpty from 'lodash/isEmpty'; +import { + i18n +} from '../public/i18n'; +const getLabel = WeaLocaleProvider.getLabel; +const getCurrentLabel = WeaInputLocale.getCurrentLabel; +const {TableStore} = WeaTableNew; + +export class FieldDefinedStore extends HrmBaseStore { + + tabDef = { + topButtonDef: [{ + isBatch: 0, + isTop:1, + menuFun: "save", + menuIcon: "icon-coms-Preservation", + menuName: "保存", + type: "BTN_Save" + }, { + isBatch: 0, + isTop:1, + menuFun: "new", + menuIcon: "icon-coms-New-Flow", + menuName: "新建分组", + type: "BTN_Addnew" + }, { + isBatch: 0, + isTop:1, + menuFun: "set", + menuIcon: "icon-coms-Flow-setting", + menuName: "分组维护", + type: "BTN_GroupSet" + }], + tabButtonDef: [{ + comType: 'button', + icon: 'icon-coms-Add-to-hot', + label: i18n.button.create, + rightMenuIcon: this.menuIconCollection.create, + onClickHandle: () => this.recordOP(this.editTable['fieldDef'], 'add') + }] + } + + /********************* tabProps *********************/ + tabConfig = { + tabs: [], + keyParam: 'viewCondition', + activeTabKey: '1', + onTabEdit: this.onTabEdit + }; + activeTabInfo = {} + tabRecord = []; + + fieldDefColumns = () => { + const columns = [{ + title: i18n.label.fieldLabel(), //列名 + dataIndex: 'fieldlabel', //列的id 对应数据 + key: 'fieldlabel', //前端渲染key值 + useRecord: true, + colSpan: 1, + width: '15%', + com: [{ + label: '', + type: 'INPUT', + key: 'fieldlabel', + viewAttr: '3', + otherParams: { + ...window.inputType + } + }], + }, { + title: i18n.label.fieldName(), + dataIndex: 'fieldname', + key: 'fieldname', + useRecord: true, + colSpan: 1, + width: '15%', + com: [{ + label: '', + type: 'INPUT', + key: 'fieldname', + viewAttr: '3', + otherParams: { + length: 25, + regExp: /^[a-zA-Z][a-zA-Z0-9]*$/, + filter: (val) => { + const { + isValid, + value + } = validDBKeys(val); + this.isDBKeyValid = isValid; + return value; + } + } + }], + }, { + title: i18n.label.fieldType(), + dataIndex: 'fieldType', + key: 'fieldType', + useRecord: true, + colSpan: 1, + width: (this.moduleName === 'resourcefielddefined' && !this.isJobTreeNode) ? "30%" : "40%", + com: [{ + label: '', + type: 'CUSTOMFIELD', + key: 'fieldType', + viewAttr: '3', + options: ['peculiar'], + otherParams: { + customProps: { + 'input.text': { + viewAttr: 3 + }, + 'textarea': { + parent: { + type: "div", + style: { + display: "none" + } + }, + style: { + display: "none" + } + }, + 'textarea.*': { + parent: { + type: "div", + style: { + display: "none" + } + }, + style: { + display: "none" + } + }, + 'textarea.*.*': { + style: { + display: "none" + } + }, + "select": { + options: [{ + key: 'select', + selected: true, + showname: i18n.label.selectComponent() + }] + }, + "upload": { + options: [{ + key: 'file', + selected: true, + showname: i18n.label.uploadFile() + }] + } + } + } + }], + }, { + title: i18n.label.enable(), + dataIndex: 'enable', + key: 'enable', + checkType: 'checkbox', + colSpan: 1, + width: '7%' + }, { + title: i18n.label.required(), + dataIndex: 'required', + key: 'required', + checkType: 'checkbox', + colSpan: 1, + width: '8%' + }]; + + //人员卡片字段定义-添加【允许个人修改】列 + if (this.moduleName === 'resourcefielddefined') { + if (this.isJobTreeNode) {//【工作信息】列表不添加【允许个人修改】列 + } else { + columns.push({ + title: getLabel(510359,'允许个人修改'), + dataIndex: 'isModify', + key: 'isModify', + checkType: 'checkbox', + colSpan: 1, + width: '11%' + }); + } + } + this.encryptEnable && columns.push({ + title: getLabel('526997','加密设置'), + dataIndex: 'canEncrypt', + key: 'canEncrypt', + com: [ + { + type: 'custom', + key: 'custom', + render: (text, record, index, onEdit) => { + const {canEncrypt} = record; + if(canEncrypt == '1') + return ( + this.onEncryptHandle(record)}>{getLabel('526997','加密设置')} + ) + return null; + } + } + ], + colSpan: 1, + width: '8%' + }); + return columns; + } + + groupDefColumns = () => [{ + title: i18n.label.groupName(), //列名 + dataIndex: 'groupName', //列的id 对应数据 + key: 'groupName', //前端渲染key值 + colSpan: 1, + width: '70%', + useRecord: true, + com: [{ + label: '', + type: 'INPUT', + key: 'groupName', + viewAttr: '3', + otherParams: { + ...window.inputType + } + }], + }, { + title: i18n.label.show(), + dataIndex: 'isShow', + key: 'isShow', + checkType: 'checkbox', + colSpan: 1, + useRecord: true, + width: '30%' + }]; + + childInfoDefColumns = () => [{ + title: i18n.label.childInfoName(), //列名 + dataIndex: 'name', //列的id 对应数据 + key: 'name', //前端渲染key值 + colSpan: 1, + width: '70%', + useRecord: true, + com: [{ + label: '', + type: 'INPUT', + key: 'name', + viewAttr: '3', + otherParams: { + ...window.inputType + } + }], + }, { + title: i18n.label.show(), + dataIndex: 'isShow', + key: 'isShow', + checkType: 'checkbox', + colSpan: 1, + useRecord: true, + width: '30%' + }]; + + getColumns = () => { + let columns = cloneDeep(this.fieldDefColumns()) + return columns; + } + + tableEditConfig = { + fieldDef: { + ...this.editTableConfig, + showAdd: false, + showDelete: false, + showCopy: false, + columns: this.getColumns(), + copyFilterProps: ['id', 'fieldlabel', 'fieldname', 'com.fieldname', 'com.fieldlabel'], + datas: [], + selectedData: {}, + onChange: this.onFieldDefChange, + onRowSelect: this.onFieldDefRowSelect, + getRowSelection: this.onFieldDefRowSelection, + onDelete: this.onFieldDefDeleteOpr, + onEdit: this.onEdit, + onAdd: this.onAdd + }, + groupSetting: { + ...this.editTableConfig, + showTitle: true, + showAdd: true, + showDelete: true, + showCopy: false, + columns: this.groupDefColumns(), + copyFilterProps: ['id', 'groupName', 'isShow'], + datas: [], + selectedData: {}, + onChange: (datas) => this.onGroupSettingChange(datas, 'group'), + onRowSelect: (sRowKeys, rows, dataIndex, selectedDatas) => this.onGroupSettingRowSelect(sRowKeys, rows, dataIndex, selectedDatas, 'group'), + getRowSelection: this.onGroupSettingRowSelection, + onDelete: (ks, ds) => this.onGroupSettingDeleteOpr(ks, ds, 'group') + }, + childInfoSetting: { + ...this.editTableConfig, + showTitle: true, + showAdd: true, + showDelete: true, + showCopy: false, + columns: this.childInfoDefColumns(), + copyFilterProps: ['id', 'name', 'isShow'], + datas: [], + selectedData: {}, + onChange: (datas) => this.onGroupSettingChange(datas, 'childInfo'), + onRowSelect: (sRowKeys, rows, dataIndex, selectedDatas) => this.onGroupSettingRowSelect(sRowKeys, rows, dataIndex, selectedDatas, 'childInfo'), + getRowSelection: this.onGroupSettingRowSelection, + onDelete: (ks, ds) => this.onGroupSettingDeleteOpr(ks, ds, 'childInfo') + } + } + + + + /********************* dialog info setting *********************/ + editorDialogRightMenu = []; + getDialogOpButtons = () => { //获取权限组编辑对话框按钮列表 + this.editorDialogRightMenu.length = 0; + let buttons = []; + this.editorDialogRightMenu.push({ + key: '1', + content: i18n.button.save(), + icon: , + onClick: () => this.dialogSaveOp(false) + }); + + if(this.dialogParams.groupInfoSetting.visible){ + let logType = ''; + // switch(this.moduleName){ + // case 'subcompanyfielddefined': + // logType = 'HRM_ENGINE_SUBCOMPANYFIELDDEFINED_GROUP'; + // break; + // case 'departmentfielddefined': + // logType = 'HRM_ENGINE_DEPARTMENTFIELDDEFINED_GROUP'; + // break; + // case 'resourcefielddefined': + // logType = 'HRM_ENGINE_RESOURCEFIELDDEFINED_GROUP'; + // break; + // } + this.editorDialogRightMenu.push(...this.getBasicMenus(logType)); + } + + return buttons; + } + + /***** form ****/ + editGroupInfoFormFields = [{ + "title": i18n.label.basicSetting(), + "items": [{ + "colSpan": 2, + "conditionType": "INPUT", + "domkey": ["groupName"], + "fieldcol": 12, + "isQuickSearch": false, + "label": i18n.label.groupName, + "labelcol": 6, + "precision": 0, + "rules": "required|string", + "value": "", + "viewAttr": 3, + }], + "defaultshow": true + }] + + editChildInfoFormFields = [{ + "title": i18n.label.basicSetting, + "items": [{ + "colSpan": 2, + "conditionType": "INPUT", + "domkey": ["name"], + "fieldcol": 12, + "isQuickSearch": false, + "label": i18n.label.childInfoName, + "labelcol": 6, + "precision": 0, + "rules": "required|string", + "value": "", + "viewAttr": 3 + }, { + "colSpan": 2, + "conditionType": "INPUTNUMBER", + "domkey": ["infoOrder"], + "fieldcol": 12, + "isQuickSearch": false, + "label": i18n.label.displayOrder, + "labelcol": 6, + "precision": 0, + "value": "0", + "viewAttr": 2 + }], + "defaultshow": true + }] + + /********************* observable list *********************/ + dialogParams = { //override baseStore.dialogParams + editGroupInfo: { + visible: false, + title: '', + moreBtn: { + datas: [] + } + }, + groupInfoSetting: { + visible: false, + title: '', + moreBtn: { + datas: [] + } + }, + createChildInfo: { + visible: false, + title: '', + moreBtn: { + datas: [] + } + }, + childInfoSetting: { + visible: false, + title: '', + moreBtn: { + datas: [] + } + } + } + + @observable spinning = false; + @observable moduleName = ''; //模块名称 + @observable topMenu = []; + @observable rightMenu = []; + + @observable tabKey = '1' + @observable tabInfo = [] //需要自定义返回 + + //选中树节点信息 + @observable selectedTreeNodeInfo; + @observable treeConfig = { + data: [], + selectedKeys: [], + treeExpandKeys: [], + onExpand: (keys) => { + this.treeConfig.treeExpandKeys = keys; + }, + onSelectedTreeNode: (key, count, countType) => { + this.treeConfig.selectedKeys = [key]; + this.selectedTreeNodeInfo = countType.node.props.data; + this.getTabInfoByTreeNode(null, true); + } + } + + @observable refreshMainTabComponent = new Date().getTime(); + + + @observable moveToGroup = false; //移动到组 + /** + * 初始化模块数据 + */ + @action initResourceData = (module) => { + this.selectedTreeNodeInfo = null; + this.treeConfig.treeExpandKeys.length = 0; + this.moduleName = module; + api.getTree().then(data => { + if (data.status === '1') { + // this.setTableEditColTitle(); + if (data.treejson.length > 0) { + this.treeConfig.data = data.treejson; + this.treeConfig.selectedKeys = [data.treejson[0].key]; + this.selectedTreeNodeInfo = data.treejson[0]; + this.getTabInfoByTreeNode(null, true); + + } + } else { + message.error(data.message); + } + }, error => {}) + } + + @action getTabInfoByTreeNode = (create = false, init = false, isLeaf) => { + api.getTabInfo(this.moduleName, { + groupType: this.treeConfig.selectedKeys[0] + }).then(data => { + if (data.status === '1') { + let t = cloneDeep(this.tabDef); + this.setTopMenu(t.topButtonDef); + this.setRightMenu(t.topButtonDef); + data.tabs && this.setTabInfo(data.tabs); + this.getFieldDefinedInfo(this.tabKey); + } else { + message.error(data.message); + } + }) + } + + + + @action("tab切换") onTabChange(tabKey) { + this.setTabKey(tabKey); + this.getFieldDefinedInfo(tabKey); + } + + @action onTabEdit = (targetKey, action) => { + const tabIndex = this.getTabIndex(this.tabConfig.tabs, targetKey); + if (tabIndex < 0) return; + const tabInfo = this.tabConfig.tabs[tabIndex]; + switch (action) { + case 'remove': + this.confirmInfo({ + content: i18n.confirm.delete(), + onOk: () => { + let params = { + id: tabInfo.groupid + } + if (this.selectedTreeNodeInfo != null) + params.groupType = this.selectedTreeNodeInfo.key + api.removeGroupInfo(this.moduleName, params).then(data => { + if (data.status === '1') { + message.success(i18n.message.deleteSuccess()); + this.tabConfig.activeTabKey = '1'; + if (this.moduleName.indexOf('resource') >= 0) + this.getTabInfoByTreeNode(); + else + this.initData(); + } else { + message.error(data.message); + } + }) + } + }); + break; + default: + break; + } + } + + @action getFieldDefinedInfo(tabKey) { + let params = { + groupId:tabKey, + groupType: -1 + } + api.getFieldDefinedInfo(this.moduleName, params).then(data => { + if (data.status === '1') { + const { + datas, + selectedData + } = this.convertData(data.data, 'fieldDef'); + this.encryptEnable = data.encryptEnable; + this.tableEditConfig.fieldDef.datas = datas; + this.tableEditConfig.fieldDef.columns = this.getColumns(); + + //人员卡片字段定义columns是动态的,因此需要重新计算得出selectedData + if (this.moduleName === 'resourcefielddefined') { + const { + selectedData + } = this.convertData(data.data, 'fieldDef'); + this.tableEditConfig.fieldDef.selectedData = selectedData; + } else { + this.tableEditConfig.fieldDef.selectedData = selectedData; + } + + // if (this.tabRecord.length > 0) { + // this.tabRecord[this.activeTabInfo.activeTabIndex].editable = (data.data.length === 0); + // this.activeTabInfo.tabInfo.editable = (data.data.length === 0); + // } + } else + message.error(data.message); + this.spinning = false; + this.refreshMainTabComponent = new Date().getTime(); + }, error => {this.spinning = false;}) + } + + + @action editGroup = (group, moveToGroup = false) => { + this.moveToGroup = moveToGroup; + this.editGroupInfoFormFields.map(f => { + if (typeof(f.title) == 'function') + f.title = f.title(); + f.items.map(item => { + if (typeof(item.label) == 'function') + item.label = item.label(); + item.otherParams = {...window.inputType}; + }) + }) + let fields = [...this.editGroupInfoFormFields], + dialogTitle = ''; + this.setFormData('groupInfoFrom', fields); + if (group) { + this.formTarget.groupInfoFrom.updateFields({ + groupName: {value: group.multiTitle || group.title || ''} + }); + this.opId = group.groupid; + dialogTitle = i18n.button.editGroup(); + } else { + this.formTarget.groupInfoFrom.updateFields({ + groupName: {value: ''} + }); + this.opId = null; + dialogTitle = i18n.button.createGroup(); + } + this.setDialogVisible('editGroupInfo', true, dialogTitle); + } + + @action dialogSaveOp = () => { + this.dialogParams.editGroupInfo.visible && this.doSaveGroupInfo(); + // this.dialogParams.groupInfoSetting.visible && this.doSaveGroupSetting(); + // this.dialogParams.createChildInfo.visible && this.doSaveChildInfo(); + // this.dialogParams.childInfoSetting.visible && this.doSaveChildInfoSetting(); + } + + + doSaveGroupInfo = () => { + this.formTarget.groupInfoFrom.validateForm().then(f => { + if (f.isValid) { + let record = { + ...this.formTarget.groupInfoFrom.getFormParams(), + isShow: 1 + } + const recordIndex = findIndex(this.tabInfo.tabs, { + title: getCurrentLabel(record.groupName) + }); + if (recordIndex >= 0) { + f.showError('groupName', i18n.confirm.groupNameExist()); + this.showError = new Date().getTime(); + return; + } + let found = false, + records = []; + this.opId != null && Object.assign(record, { + id: this.opId, + isShow: this.tabInfo.isShow + }); + this.tabInfo.map(tabInfo => { + if (tabInfo.groupid === this.opId) { + found = true; + records.push(record) + } else { + records.push({ + id: tabInfo.groupid, + isShow: tabInfo.isShow, + groupName: tabInfo.title + }) + } + }); + !found && records.push(record); + let params = { + data: JSON.stringify({ + records: records + }) + } + if (this.selectedTreeNodeInfo != null) + params.groupType = this.selectedTreeNodeInfo.key + + api.saveGroupInfo(this.moduleName, params).then(data => { + if (data.status === '1') { + this.setDialogVisible('editGroupInfo', false, ''); + if(this.moveToGroup){ + const ids = data.groupid.split(','); + //this.changeGroup(null, ids[ids.length - 1]); 移动到组 + }else{ + this.getTabInfoByTreeNode(); + message.success(i18n.message.saveSuccess()); + } + } else + message.error(data.message); + }, error => { + message.error(i18n.message.actionError()); + }); + } else { + f.showErrors(); + this.showError = new Date().getTime(); + } + }); + } + + setTabInfo(tabInfo) { + this.tabInfo = tabInfo; + } + + setTabKey(tabKey) { + this.tabKey = tabKey; + } + + setTopMenu(topMenu) { + this.topMenu = topMenu; + } + + + setRightMenu(rightMenu) { + this.rightMenu = rightMenu; + } + + +} \ No newline at end of file diff --git a/pc4mobx/organization/stores/index.js b/pc4mobx/organization/stores/index.js index d42be77..ca229ff 100644 --- a/pc4mobx/organization/stores/index.js +++ b/pc4mobx/organization/stores/index.js @@ -15,6 +15,7 @@ import { StaffStore } from "./staff"; import { JobStore } from "./job"; import { JobExtendStore } from "./jobextend"; import { NumberSetStore } from "./numberSet"; +import {FieldDefinedStore} from "./fieldDefined"; module.exports = { simpleOrgStore: new SimpleOrgStore(), @@ -34,4 +35,5 @@ module.exports = { job: new JobStore(), jobExtend: new JobExtendStore(), numberSet: new NumberSetStore(), + fieldDefined: new FieldDefinedStore() }; diff --git a/pc4mobx/organization/style/index.less b/pc4mobx/organization/style/index.less index f661c00..683be40 100644 --- a/pc4mobx/organization/style/index.less +++ b/pc4mobx/organization/style/index.less @@ -35,6 +35,23 @@ html { background-color: transparent; } +//自定义设置 +.fieldDef{ + width: 100%; + height: 100%; + .wea-tab .wea-search-tab{ + &>span{ + margin-left: 0px !important; + } + } + + .status-clz, .sex-clz, .accounttype-clz{ + a { + display: none; + } + } +} + //组织架构图 #node {