diff --git a/pc4mobx/hrmSalary/apis/ledger.js b/pc4mobx/hrmSalary/apis/ledger.js index 94585fed..bb27784b 100644 --- a/pc4mobx/hrmSalary/apis/ledger.js +++ b/pc4mobx/hrmSalary/apis/ledger.js @@ -126,7 +126,14 @@ export const getLedgerItemGroupForm = params => { //保存薪资帐套薪资项目 export const saveLedgerItem = params => { - return WeaTools.callApi('/api/bs/hrmsalary/salarysob/item/save', 'POST', params); + return fetch('/api/bs/hrmsalary/salarysob/item/save', { + method: 'POST', + mode: 'cors', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(params) + }).then(res => res.json()) } //薪资帐套薪资项目详情 @@ -158,3 +165,20 @@ export const updateLedgerRuleFormula = params => { export const deleteLedgerRule = params => { return WeaTools.callApi('/api/bs/hrmsalary/salarysob/checkrule/delete', 'POST', params); } + +// 薪资项目可选列表 +export const listSalaryItem = params => { + return fetch('/api/bs/hrmsalary/salarysob/item/listSalaryItem', { + method: 'POST', + mode: 'cors', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(params) + }).then(res => res.json()) +} + +// 员工信息字段列表 +export const empFieldList = () => { + return WeaTools.callApi('/api/bs/hrmsalary/salarysob/empField/list', 'GET', {}); +} diff --git a/pc4mobx/hrmSalary/components/canDeleteItem/close.png b/pc4mobx/hrmSalary/components/canDeleteItem/close.png new file mode 100644 index 00000000..4f6376a6 Binary files /dev/null and b/pc4mobx/hrmSalary/components/canDeleteItem/close.png differ diff --git a/pc4mobx/hrmSalary/components/canDeleteItem/index.js b/pc4mobx/hrmSalary/components/canDeleteItem/index.js new file mode 100644 index 00000000..ea598daf --- /dev/null +++ b/pc4mobx/hrmSalary/components/canDeleteItem/index.js @@ -0,0 +1,33 @@ +import React from 'react' +import { Icon } from 'antd' +import closeIcon from './close.png' +export default class CanDeleteItem extends React.Component { + constructor(props) { + super(props) + this.state = { + showDelete: false + } + } + + handleMouseOver() { + this.setState({showDelete: true}) + } + + handelMouseout() { + setTimeout(() => { + this.setState({showDelete: false}) + }, 400) + } + + render() { + const { title } = this.props; + return ( +
this.handleMouseOver()} onMouseLeave={() => this.handelMouseout()}> + {title} + { + this.state.showDelete && this.props.onDelete(this.props.item)}/> + } +
+ ) + } +} \ No newline at end of file diff --git a/pc4mobx/hrmSalary/pages/ledger/columns.js b/pc4mobx/hrmSalary/pages/ledger/columns.js index 620c9d19..621c2460 100644 --- a/pc4mobx/hrmSalary/pages/ledger/columns.js +++ b/pc4mobx/hrmSalary/pages/ledger/columns.js @@ -58,9 +58,9 @@ export const slideStep2Columns= [ export const slideStep3Columns = [ { - title: "薪资项目", - dataIndex: 'title', - key: 'title', + title: "名称", + dataIndex: 'name', + key: 'name', }, { title: "规则", @@ -68,14 +68,9 @@ export const slideStep3Columns = [ key: 'title', }, { - title: "来源", - dataIndex: 'title', - key: 'title', - }, - { - title: "类型", - dataIndex: 'title', - key: 'title', + title: "个税申请表对应字段", + dataIndex: 'taxDeclarationColumn', + key: 'taxDeclarationColumn', } ] diff --git a/pc4mobx/hrmSalary/pages/ledger/index.js b/pc4mobx/hrmSalary/pages/ledger/index.js index 41f6f440..d40ff84f 100644 --- a/pc4mobx/hrmSalary/pages/ledger/index.js +++ b/pc4mobx/hrmSalary/pages/ledger/index.js @@ -88,6 +88,15 @@ export default class Ledger extends React.Component { } + // 编辑Slide保存按钮 + handleEditSlideSave() { + const { selectedTab } = this.state; + const { ledgerStore: {saveLedgerItem}} = this.props; + if(selectedTab == 2) { + saveLedgerItem() + } + } + // 增加编辑功能,重写columns绑定事件 getColumns = (columns) => { let newColumns = ''; @@ -194,6 +203,8 @@ export default class Ledger extends React.Component { nextStep() } + + return (
this.handleEditSlideSave()} subItemChange={ (item) => {this.setState({selectedTab: item.key})} } diff --git a/pc4mobx/hrmSalary/pages/ledger/index.less b/pc4mobx/hrmSalary/pages/ledger/index.less index 75d9dfdd..19d0e653 100644 --- a/pc4mobx/hrmSalary/pages/ledger/index.less +++ b/pc4mobx/hrmSalary/pages/ledger/index.less @@ -87,10 +87,9 @@ .userInfoSelected { margin-top: 10px; margin-bottom: 10px; - .selectedItem { - margin-right: 10px; - } - + padding: 10px; + border: 1px solid #eee; + border-radius: 5px; } .tableItemWrapper { margin-top: 10px; @@ -101,6 +100,10 @@ color: #2db7f5; } } + .itemTitle { + font-size: 14px; + font-weight: 500; + } } } diff --git a/pc4mobx/hrmSalary/pages/ledger/salaryItemForm.js b/pc4mobx/hrmSalary/pages/ledger/salaryItemForm.js index e1522933..d3d8be94 100644 --- a/pc4mobx/hrmSalary/pages/ledger/salaryItemForm.js +++ b/pc4mobx/hrmSalary/pages/ledger/salaryItemForm.js @@ -1,22 +1,56 @@ import React from 'react' import { Button, Icon, Table } from 'antd' -import { WeaInputSearch, WeaHelpfulTip } from 'ecCom' +import { WeaInputSearch, WeaHelpfulTip, WeaSelect } from 'ecCom' import { slideStep3Columns, dataSource} from './columns' import "./index.less" +import AddCategoryModal from './step3/AddCategoryModal' +import { inject, observer } from 'mobx-react'; +import { toJS } from 'mobx'; +import CanMoveItem from './step3/canMoveItem' +import UserInfoSelected from './step3/UserInfoSelect' + +@inject('ledgerStore') +@observer export default class SalaryItemForm extends React.Component { + constructor(props) { + super(props) + this.state = { + addCategoryVisible: false + } + + const { ledgerStore: { empFieldList }} = this.props; + empFieldList(); + } + + handleAddCategorySave(name) { + const {ledgerStore: {addItemGroup}} = this.props; + addItemGroup(name); + } + + handleCanMoveItemChange(dataSource, item) { + const {ledgerStore: {itemGroups, setItemGroups}} = this.props; + let groups = [...itemGroups] + groups.map(i => { + if(i.tlitle == item.title) { + item.items = dataSource + } + }) + setItemGroups(groups) + } + render() { + const {ledgerStore: {itemGroups, salaryItems, empBrowserList, setAddCategoryVisible, addCategoryVisible}} = this.props; return (
- +
- +
-
@@ -35,25 +69,26 @@ export default class SalaryItemForm extends React.Component {
-
- 个税扣缴义务人 - 姓名 - 部门 - -
-
+ -
-
- 未分类 - - - - - -
- + + { + itemGroups && itemGroups.map(item => { + item.items.map(i => {i.key = i.id}) + return ( + {this.handleCanMoveItemChange(dataSource, item)}}/> + ) + } + ) + } + { + + addCategoryVisible && + {this.handleAddCategorySave(value)}} visible={addCategoryVisible} onCancel={() => { + setAddCategoryVisible(false) + }} /> + } ) } diff --git a/pc4mobx/hrmSalary/pages/ledger/step3/AddCategoryModal.js b/pc4mobx/hrmSalary/pages/ledger/step3/AddCategoryModal.js new file mode 100644 index 00000000..222fa583 --- /dev/null +++ b/pc4mobx/hrmSalary/pages/ledger/step3/AddCategoryModal.js @@ -0,0 +1,29 @@ +import React from 'react' +import { Row, Col, Modal, Button } from 'antd' +import { WeaInput } from 'ecCom' + + +export default class AddCategoryModal extends React.Component { + constructor(props) { + super(props) + this.state = { + name: "" + } + } + render() { + return ( + {this.props.onSave(this.state.name)}}>保存} width={600} + visible={this.props.visible} onCancel={() => {this.props.onCancel()}} + > +
+ +
分类名称 + + {this.setState({name: value})}}/> + + + + + ) + } +} \ No newline at end of file diff --git a/pc4mobx/hrmSalary/pages/ledger/step3/AddSalaryItemModal.js b/pc4mobx/hrmSalary/pages/ledger/step3/AddSalaryItemModal.js new file mode 100644 index 00000000..97c6c6d5 --- /dev/null +++ b/pc4mobx/hrmSalary/pages/ledger/step3/AddSalaryItemModal.js @@ -0,0 +1,99 @@ +import React from 'react' +import { inject, observer } from 'mobx-react'; +import { Modal, Button, message, Switch } from 'antd' +import { WeaInputSearch } from 'ecCom' +import { WeaTableNew } from "comsMobx" +import { toJS } from 'mobx' + +const WeaTable = WeaTableNew.WeaTable; + +@inject('ledgerStore') +@observer +export default class AddSalaryItemModal extends React.Component { + constructor(props) { + super(props) + this.state = { + searchValue: "" + } + } + + componentWillMount() { + const { ledgerStore: {listSalaryItem}} = this.props; + listSalaryItem() + } + + // 增加编辑功能,重写columns绑定事件 + getColumns = (columns) => { + let newColumns = ''; + newColumns = columns.map(column => { + let newColumn = column; + newColumn.render = (text, record, index) => { //前端元素转义 + let valueSpan = record[newColumn.dataIndex + "span"] !== undefined ? record[newColumn.dataIndex + "span"] : record[newColumn.dataIndex]; + switch(newColumn.dataIndex) { + case "useDefault": + case "useInEmployeeSalary": + return + default: + return
+ } + } + return newColumn; + }); + return newColumns; + } + + handleAdd() { + const { ledgerStore } = this.props; + const { salaryItemTableStore, addItemsToGroup, addExcludeIds } = ledgerStore + const selectedRowKeys = toJS(salaryItemTableStore.selectedRowKeys) || []; + if(selectedRowKeys.length == 0) { + message.warning("未选择条目") + } + let selectItems = [] + salaryItemTableStore.datas.map(item => { + selectedRowKeys.map(key => { + if(item.id == key) { + selectItems.push(item) + } + }) + }) + + addItemsToGroup(this.props.title, selectItems) + this.props.onCancel(); + } + + handleSearch = (value) => { + const { ledgerStore: {listSalaryItem}} = this.props + listSalaryItem(value) + } + + render() { + const { ledgerStore } = this.props; + const { salaryItemTableStore } = ledgerStore + const { searchValue } = this.state; + return ( + {this.props.onCancel()}} width={800} + footer={null} + > +
+ 添加薪资项目 +
+ + {this.setState({searchValue: value})}} onSearch={(value) => {this.handleSearch(value)}}/> +
+
+ +
+ +
+
+ ) + } +} \ No newline at end of file diff --git a/pc4mobx/hrmSalary/pages/ledger/step3/UserInfoSelect.js b/pc4mobx/hrmSalary/pages/ledger/step3/UserInfoSelect.js new file mode 100644 index 00000000..cce381e9 --- /dev/null +++ b/pc4mobx/hrmSalary/pages/ledger/step3/UserInfoSelect.js @@ -0,0 +1,70 @@ +import React from 'react' +import { Icon, message } from "antd" +import { WeaSelect } from 'ecCom' +import { inject, observer } from 'mobx-react'; +import CanDeleteItem from '../../../components/canDeleteItem' + +@inject('ledgerStore') +@observer +export default class UserInfoSelected extends React.Component { + constructor(props) { + super(props) + this.state = { + list: [], + showSelect: false + } + } + + handleSelectChange(value) { + let list = [...this.state.list] + const { ledgerStore: {empBrowserList}} = this.props; + let selectedItem = {} + empBrowserList.map(item => { + if(item.key == value) { + selectedItem = item + } + }) + let flag = false; + list.map(item => { + if(item.key == value) { + flag = true + } + }) + if(!flag) { + list.push(selectedItem) + } + if(flag) { + message.warning("该信息已存在") + } + + const { ledgerStore: {empFields, addEmpFields}} = this.props; + addEmpFields(value) + this.setState({list, showSelect: false}) + } + + handleItemDelete(item) { + let list = [...this.state.list] + this.setState({list: list.filter(i => item.key != i.key)}) + } + + render() { + const { ledgerStore: {empBrowserList} } = this.props; + return ( +
+ { + this.state.list.map(item => ( + { + this.handleItemDelete(item) + }}/> + )) + } + {this.setState({showSelect: true})}}/> + { + this.state.showSelect && empBrowserList.length > 0 && { + this.handleSelectChange(value) + }}/> + } +
+ ) + } +} \ No newline at end of file diff --git a/pc4mobx/hrmSalary/pages/ledger/step3/canMoveItem.js b/pc4mobx/hrmSalary/pages/ledger/step3/canMoveItem.js new file mode 100644 index 00000000..4d17b39f --- /dev/null +++ b/pc4mobx/hrmSalary/pages/ledger/step3/canMoveItem.js @@ -0,0 +1,83 @@ +import React from 'react' +import { Icon, Table, message, Modal } from 'antd' +import { slideStep3Columns } from '../columns' +import AddSalaryItemModal from './AddSalaryItemModal' +import { inject, observer } from 'mobx-react'; + +@inject('ledgerStore') +@observer +export default class CanMoveItem extends React.Component { + constructor(props) { + super(props) + this.state = { + addItemVisible: false, + showContent: true, + selectedRowKeys: [] + } + } + + handleTiggleContent() { + this.setState({showContent: !this.state.showContent}) + } + + onSelectChange = selectedRowKeys => { + this.setState({ selectedRowKeys }); + }; + + // 删除 + handleDelete = () => { + + const { selectedRowKeys } = this.state; + if(selectedRowKeys.length == 0) { + message.warning("为选择任何条目") + return + } + Modal.confirm({ + title: '信息确认', + content: '确认删除', + onOk:() => { + const {dataSource} = this.props; + let result = [...dataSource] + this.props.onChange(result.filter(item => selectedRowKeys.indexOf(item.key) < 0)) + }, + onCancel: () => { + + }, + }); + + + } + + render() { + const {ledgerStore: {setAddItemVisible, addItemVisible}} = this.props; + const { selectedRowKeys } = this.state; + const rowSelection = { + selectedRowKeys, + onChange: this.onSelectChange, + }; + + return ( +
+
+ {this.props.title} + + {this.handleDelete()}}/> + { this.setState({addItemVisible: true}) }}/> + {this.handleTiggleContent()}}/> + +
+ { + this.state.showContent &&
+ } + { + this.state.addItemVisible && { this.setState({addItemVisible: false})}} + /> + } + + + ) + } +} \ No newline at end of file diff --git a/pc4mobx/hrmSalary/pages/socialSecurityBenefits/programme/index.js b/pc4mobx/hrmSalary/pages/socialSecurityBenefits/programme/index.js index ebef4966..95d69883 100644 --- a/pc4mobx/hrmSalary/pages/socialSecurityBenefits/programme/index.js +++ b/pc4mobx/hrmSalary/pages/socialSecurityBenefits/programme/index.js @@ -131,7 +131,6 @@ export default class Programme extends React.Component { onCustomEdit(record) { const { programmeStore: {getCustomForm, setCustomNewVisible, setCustomRequest}} = this.props; setCustomNewVisible(true) - alert(JSON.stringify(record)) setCustomRequest(record) } diff --git a/pc4mobx/hrmSalary/stores/ledger.js b/pc4mobx/hrmSalary/stores/ledger.js index 0189fe17..dd52f595 100644 --- a/pc4mobx/hrmSalary/stores/ledger.js +++ b/pc4mobx/hrmSalary/stores/ledger.js @@ -17,6 +17,95 @@ export class LedgerStore { @observable includeType=1; // 0:排除、1:包含 @observable userTableStore = {}; @observable addUserModalVisible = false; + @observable itemGroups = [ + { + id:"default", + name: "未分类", + items: [] + } + ]; + @observable salaryItemTableStore = new TableStore(); + @observable empBrowserList = [] + @observable empFields = [] + @observable excludeIds = [] + + @observable addCategoryVisible = false; // 薪资项目-添加分类Modal + + @action + setAddCategoryVisible = addCategoryVisible => this.addCategoryVisible = addCategoryVisible + + @action + setExcludeIds = excludeIds => this.excludeIds = excludeIds + + @action + addExcludeIds = id => { + let excludeIds = [...this.excludeIds] + excludeIds.push(id) + this.excludeIds = excludeIds + } + + @action + addEmpFields = (fieldId) => { + let sortedIndex = 1; + if(this.empFields.length > 0) { + let lastSortedIndex = this.empFields[this.empFields.length - 1].sortedIndex + sortedIndex = parseInt(lastSortedIndex) + 1 + } + let item = { + fieldId, + sortedIndex + } + let result = [...this.empFields] + result.push(item) + this.empFields = result + } + + @action + setItemGroups = itemGroups => this.itemGroups = itemGroups + + @action + addItemGroup = name => { + let itemGroups = [...this.itemGroups] + let flag = false; + itemGroups.map(item => { + if(item.name == name) { + flag = true; + } + }) + if(flag) { + message.warning("分类已存在") + return + } + let item = {name, items: []} + itemGroups.unshift(item) + this.setItemGroups(itemGroups) + this.addCategoryVisible = false + } + + @action + addItemsToGroup = (title, list) => { + let itemGroups = [...this.itemGroups] + itemGroups.map(item => { + if(item.name == title) { + item.items = item.items ? item.items.concat(list) : list + } + }) + this.setItemGroups(itemGroups); + } + + @action + addCategoryList = item => { + let list = [...this.categoryList] + list.push(item) + this.categoryList = list + } + + @action + removeCategoryList = item => { + let list = [...this.categoryList] + list.filter(i => item.name != i.name) + this.categoryList = list; + } @action setAddUserModalVisible = addUserModalVisible => this.addUserModalVisible = addUserModalVisible; @@ -180,5 +269,64 @@ export class LedgerStore { }) } + // 薪资项目可选列表 + @action + listSalaryItem = (searchValue = "") => { + let excludeIds = [] + this.itemGroups.map(item => { + item.items.map(i => { + excludeIds.push(i.id) + }) + }) + API.listSalaryItem({name:searchValue, excludeIds}).then(res => { + if(res.status) { + this.salaryItemTableStore.getDatas(res.data.datas); + } else { + message.error(res.errormsg || "获取数据失败") + } + }) + } + + @action + empFieldList = () => { + API.empFieldList().then(res => { + if(res.status) { + this.empBrowserList = res.data.map(item => {return {showname: item.name, key: item.id, selected: false}}) + } else { + message.error(res.errormsg || "获取失败") + } + }) + } + + @action + saveLedgerItem = () => { + let itemGroups = [...this.itemGroups] + itemGroups = itemGroups.map(item => { + let result = {...item} + result.items = result.items.map((i,index) => ( + { + salaryItemId: i.id, + sortedIndex: index + 1 + } + )) + return result; + }) + + let params = { + salarySobId: this.salarySobId, + empFields: this.empFields, + itemGroups: itemGroups.filter(item => item.id != "default"), + items: itemGroups.filter(item => item.id == 'default')[0].items + } + API.saveLedgerItem(params).then(res => { + if(res.status) { + message.success("保存成功"); + } else { + message.error(res.errormsg || "保存失败") + } + }) + } + + } \ No newline at end of file