Merge branch 'dev' of gitee.com:MustangDeng/salary-management-front-end into dev

This commit is contained in:
liyongshun 2022-05-09 15:10:52 +08:00
commit 8b966e6cfb
20 changed files with 281 additions and 60 deletions

View File

@ -228,3 +228,9 @@ export const viewAttendQuote = (ids) => {
body: JSON.stringify(ids)
}).then(res => res.json())
}
// 根据所属月和账套获取周期
export const getSalaryCycleAndAttendCycle = (params) => {
return WeaTools.callApi('/api/bs/hrmsalary/attendQuote/getSalaryCycleAndAttendCycle', 'get', params);
}

View File

@ -51,5 +51,46 @@ export const getImportDocumentParams = params => {
// 导入档案- 导出现有数据
export const exportCurData = params => {
return WeaTools.callApi('/api/bs/hrmsalary/exportTemplate', 'get', params);
};
fetch('/api/bs/hrmsalary/scheme/template/export',{
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
}).then(res => res.blob().then(blob => {
var filename=`福利档案模板.xlsx`
var a = document.createElement('a');
var url = window.URL.createObjectURL(blob);
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);
}))
};
// 导入档案-预览
export const previewCurData = (params) => {
return fetch('/api/bs/hrmsalary/scheme/preview', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
}).then(res => res.json())
}
// 档案导入
export const importBatch = (params) => {
return fetch('/api/bs/hrmsalary/scheme/importBatch', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
}).then(res => res.json())
}

View File

@ -11,14 +11,13 @@ export default class ModalStep2 extends React.Component {
const {dataSource, columns} = this.props;
return (
<div style={{height: "550px", display: "flex", flexFlow: "column"}}>
<div style={{flex: "1"}}>
<WeaTable dataSource={dataSource} columns={columns} />
<div style={{flex: "1", maxHeight: '500px', overflowY: "scroll"}}>
<WeaTable dataSource={dataSource} columns={columns} scroll={{x: columns.length * 150 }}/>
</div>
<div className="footerBtnWrapper" style={{marginTop: "10px", overflow: "hidden", height: "30px"}}>
<Button type="primary" style={{float: "right", marginLeft: "10px"}} onClick={this.props.onStep2Next}>下一步</Button>
<Button type="default" style={{float: "right"}} onClick={this.props.onStep2Pre}>上一步</Button>
</div>
</div>
)
}

View File

@ -2,7 +2,7 @@ import React from 'react';
import { inject, observer } from 'mobx-react';
import { toJS } from 'mobx';
import { Button, Table, DatePicker, Dropdown, Menu } from 'antd';
import { Button, Table, DatePicker, Dropdown, Menu, Modal } from 'antd';
import { WeaTop, WeaTab, WeaRightMenu, WeaRangePicker, WeaTable, WeaDatePicker, WeaInputSearch } from 'ecCom';
@ -26,6 +26,8 @@ export default class Calculate extends React.Component {
value: "",
selectedKey: "0",
searchValue: "",
startDate: moment(new Date()).format("YYYY-MM"),
endDate: moment(new Date()).format("YYYY-MM"),
columns: columns.map(item => {
if(item.dataIndex == 'cz') {
item.render = () => (
@ -66,6 +68,10 @@ export default class Calculate extends React.Component {
handleRangePickerChange(value) {
let range = value.map(item => moment(item).format("YYYY-MM"))
const { calculateStore: {getSalaryAcctList} } = this.props;
this.setState({
startDate: range[0],
endDate: range[1]
})
getSalaryAcctList({
name: this.state.searchValue,
startMonthStr: range[0],
@ -80,10 +86,18 @@ export default class Calculate extends React.Component {
// 列表项删除回调
handleDeleteItem(record) {
const { calculateStore: {deleteSalaryacct}} = this.props;
deleteSalaryacct([record.id]).then(() => {
this.handleSearch(this.state.searchValue)
})
Modal.confirm({
title: '信息确认',
content: '确认删除',
onOk:() => {
const { calculateStore: {deleteSalaryacct}} = this.props;
deleteSalaryacct([record.id]).then(() => {
this.handleSearch(this.state.searchValue)
})
},
onCancel: () => {
},
});
}
// 列表项归档回调
@ -229,7 +243,6 @@ export default class Calculate extends React.Component {
/>
<CustomTable loadding={loading} columns={this.getColumns()} dataSource={salaryListDataSource}/>
</WeaTop>
{
this.state.baseFormVisible && <BaseFormModal
visible={this.state.baseFormVisible}

View File

@ -24,6 +24,7 @@ export default class PlaceOnFileDetail extends React.Component {
slideVisiable: false,
}
}
componentWillMount() {
let id = getQueryString("id");
const { calculateStore: { getSalarySobCycle, acctResultList } } = this.props;
@ -34,9 +35,22 @@ export default class PlaceOnFileDetail extends React.Component {
// 获取列表的列
getColumns() {
const { calculateStore: {acctResultListTableStore }} = this.props;
let columns = acctResultListTableStore.columns ? [...acctResultListTableStore.columns] : [];
columns = columns.filter(item => item.hide == "false")
const { calculateStore: {acctResultListTableStore, acctResultListColumns }} = this.props;
let columns = acctResultListColumns ? acctResultListColumns : []
columns = columns.filter(item => item.hide == "FALSE").map(item => {
let result = {...item}
result.title = item.text;
result.dataIndex = item.column
result.oldWidth = result.width;
result.width = null;
if(result.children) {
result.children.map(child => {
child.title = child.text
child.dataIndex = child.column
})
}
return result;
})
columns.push({
title: '操作',
key: "cz",
@ -55,6 +69,7 @@ export default class PlaceOnFileDetail extends React.Component {
const { calculateStore } = this.props;
const { baseSalarySobCycle, acctResultListDateSource, acctResultListColumns } = calculateStore
const menu = (
<Menu>
<Menu.Item key="3">导出所选</Menu.Item>

View File

@ -177,13 +177,25 @@ export default class Attendance extends React.Component {
getAttendanceList(this.listSearch)
}
// 获取周期
handleLoadCycle(month, sob) {
if(!month || month == "") {
return
}
if(!sob || sob == "") {
return
}
const { attendanceStore: {getSalaryCycleAndAttendCycle}} = this.props;
getSalaryCycleAndAttendCycle(month, sob)
}
render() {
const { attendanceStore } = this.props;
const { modalParam } = this.state;
const { loading, hasRight, form, condition, tableStore, showSearchAd, getTableDatas, doSearch, setShowSearchAd } = attendanceStore;
const { step, setStep, setSlideVisiable, slideVisiable, doBatchDelete, attendTableStore, fieldSettingAttendList, fieldSettingCustomList, setFieldSettingAttendList, setFieldSettingCustomList, searchFieldSettingList } = attendanceStore;
const { getAttendanceFieldSettingList, saveAttendanceFieldSetting, fieldDataSource, fieldTableStore, fieldPageInfo, attendanceDataSource, attendanceColumns, attendancePageInfo, importLedgerList,
previewAttendQuoteColumns, previewAttendQuoteDataSource, importResult} = attendanceStore
previewAttendQuoteColumns, previewAttendQuoteDataSource, importResult, cycle} = attendanceStore
const selectedRowKeys = toJS(tableStore.selectedRowKeys) || []; // tableStore 右侧选中数组
if (!hasRight && !loading) { // 无权限处理
@ -273,6 +285,7 @@ export default class Attendance extends React.Component {
value={this.state.modalParam.salaryYearMonth}
onChange={(value) => {
this.setState({modalParam: {...modalParam, salaryYearMonth: value}})
this.handleLoadCycle(value, this.state.modalParam.salarySobId)
}}
/>
</Col>
@ -283,6 +296,7 @@ export default class Attendance extends React.Component {
<Select
defaultValue={this.state.modalParam.salarySobId} value={this.state.modalParam.salarySobId} style={{ width: "200px" }} onChange={(value) => {
this.setState({modalParam: {...modalParam, salarySobId: value}})
this.handleLoadCycle(this.state.modalParam.salaryYearMonth, value)
}}>
{importLedgerList.map(item => (
<Option value={item.id} key={item.id}>{item.content}</Option>
@ -293,21 +307,13 @@ export default class Attendance extends React.Component {
<Col span={12}>
<span className="formLabel" style={{ lineHeight: "30px", marginRight: "10px" }}>薪资周期</span>
{
moment(this.state.modalParam.salaryYearMonth + "-01").startOf("month").format("YYYY-MM-DD")
}
~
{
moment(this.state.modalParam.salaryYearMonth + "-01").endOf("month").format("YYYY-MM-DD")
cycle.salaryCycle
}
</Col>
<Col span={12}>
<span className="formLabel" style={{ lineHeight: "30px", marginRight: "10px" }}>考勤周期</span>
{
moment(this.state.modalParam.salaryYearMonth + "-01").startOf("month").format("YYYY-MM-DD")
}
~
{
moment(this.state.modalParam.salaryYearMonth + "-01").endOf("month").format("YYYY-MM-DD")
cycle.attendCycle
}
</Col>
</Row>

View File

@ -32,11 +32,10 @@ export default class CustomSalaryItemSlide extends React.Component {
}
render() {
const { editable, request } = this.props;
const { editable, request, isAdd } = this.props;
const { name, useDefault, useInEmployeeSalary, roundingMode, pattern, valueType, description, dataType, formulaContent, formulaId } = request;
const { formalModalVisible } = this.state;
console.log("request: ", request);
return (
<div className="customSalaryItemSlide">
<div>
@ -78,7 +77,7 @@ export default class CustomSalaryItemSlide extends React.Component {
<Row>
<Col span={8}>字段类型<RequiredLabelTip /></Col>
<Col span={16}>
<WeaSelect value={dataType} options={dataTypeOptions} onChange={(value) => {this.handleChange({dataType: value})}} style={{width: "200px"}}/>
<WeaSelect disabled={isAdd ? false: true} value={dataType} options={dataTypeOptions} onChange={(value) => {this.handleChange({dataType: value})}} style={{width: "200px"}}/>
</Col>
</Row>
</Col>
@ -106,7 +105,7 @@ export default class CustomSalaryItemSlide extends React.Component {
<Row className="formItem">
<Col span={4}>取值方式<RequiredLabelTip /></Col>
<Col span={20}>
<Radio.Group disabled={editable? false: true} value={valueType} onChange={(e) => {
<Radio.Group disabled={isAdd ? false : true} value={valueType} onChange={(e) => {
this.handleChange({valueType: e.target.value})
}}>
<Radio key={1} value={"1"}>输入</Radio>

View File

@ -67,7 +67,7 @@ export default class FormalFormModal extends React.Component {
this.setState({
value
})
console.log("value: ", value);
}
// 获取光标位置
@ -107,6 +107,20 @@ export default class FormalFormModal extends React.Component {
const { salaryItemStore } = this.props;
const { saveFormual } = salaryItemStore
this.parameters = this.parameters.filter(item => this.state.value.indexOf(item.name) > -1)
// 去重
let result = []
this.parameters.map(item => {
let flag = false;
result.map(i => {
if(item.fieldId == i.fieldId) {
flag = true
}
})
if(!flag) {
result.push(item)
}
})
this.parameters = result;
let params = {
name:'公式1',
description:'备注',
@ -146,6 +160,7 @@ export default class FormalFormModal extends React.Component {
cursorPos += str.length;
obj.selectionStart = obj.selectionEnd = cursorPos;
obj.focus();
this.setState({value: obj.value})
} else {
obj.value += str;
}

View File

@ -68,7 +68,7 @@ export default class SalaryItem extends React.Component {
}
// 删除列表项
handleDeleteItem() {
handleDeleteItem(record) {
const { salaryItemStore: {deleteItemRequest}} = this.props;
Modal.confirm({
title: '信息确认',
@ -121,8 +121,7 @@ export default class SalaryItem extends React.Component {
<Dropdown overlay={<Menu>
<Menu.Item>
<a onClick={() => {
this.handleDeleteItem()
this.handleDeleteItem(record)
}}>删除</a>
</Menu.Item>
</Menu>}>
@ -331,7 +330,7 @@ export default class SalaryItem extends React.Component {
title={
<SlideModalTitle
subtitle={(this.state.editable ? "修改" : "新建") + "自定义薪资项目"}
subtitle={(this.state.isAdd ? "新建" : "修改") + "自定义薪资项目"}
editable={false}
customOperate={renderCustomOperate()}
subItemChange={
@ -339,7 +338,7 @@ export default class SalaryItem extends React.Component {
}
/>
}
content={<CustomSalaryItemSlide editable={this.state.editable} request={request} onChange={(value) => {handleSaveSlideChange(value)}}/>}
content={<CustomSalaryItemSlide editable={this.state.editable} isAdd={this.state.isAdd} request={request} onChange={(value) => {handleSaveSlideChange(value)}}/>}
onClose={() => setEditSlideVisible(false)}
showMask={true}
closeMaskOnClick={() => setEditSlideVisible(false)} />

View File

@ -55,14 +55,14 @@ export const patternOptions = [
]
export const dataTypeOptions = [
{
key: "number",
showname: "数值",
selected: false
},
{
key: "string",
showname: "字符",
selected: false
},
{
key: "number",
showname: "数值",
selected: false
}
]

View File

@ -49,7 +49,7 @@ export default class SystemSalaryItemModal extends React.Component {
}}/>
</div>
</div>
<div style={{margin: "10px"}}>
<div style={{margin: "10px", height: "500px"}}>
<WeaTable // table内部做了loading加载处理页面就不需要再加了
comsWeaTableStore={sysListTableStore} // table store
hasOrder={true} // 是否启用排序

View File

@ -10,8 +10,9 @@ import "./index.less"
export default class AccumulationFundForm extends React.Component {
componentWillMount() {
const { archivesStore: { getBaseForm }} = this.props;
const { archivesStore: { getBaseForm, getPaymentForm }} = this.props;
getBaseForm(this.props.employeeId, "ACCUMULATION_FUND");
getPaymentForm(this.props.employeeId, "ACCUMULATION_FUND", this.props.record.fundSchemeId)
}
// 表单变化
@ -76,7 +77,7 @@ export default class AccumulationFundForm extends React.Component {
<Row>
<Col span={6} className="formItem">公积金方案名称</Col>
<Col span={6} className="formItem">
<Select defaultValue={data && data.fundName} value={data && data.fundName} style={{ width: 150 }} onChange={(value) => this.handleFormChange({fundName: value})}>
<Select defaultValue={data && data.fundSchemeId} value={data && data.fundSchemeId} style={{ width: 150 }} onChange={(value) => this.handleFormChange({fundName: value})}>
{
items && items[0].items &&items[0].items[0] && items[0].items[0].options.map(item => (
<Option value={item.key}>{item.showname}</Option>

View File

@ -18,6 +18,7 @@ import AccumulationFundForm from './accumulationFundForm';
import OtherForm from './otherForm';
import { tempateColumns } from '../../payroll/columns';
import CustomTable from '../../../components/customTable';
import ImportModal from '../../../components/importModal';
const { MonthPicker } = DatePicker;
@ -31,8 +32,13 @@ export default class Archives extends React.Component {
selectedKey: "0",
selectedTab: 0,
editSlideVisible: false,
employeeId: ""
employeeId: "",
importVisible: false,
modalParam: {},
step: 0,
}
this.record = {}
}
componentWillMount() {
@ -41,9 +47,14 @@ export default class Archives extends React.Component {
}
handleEdit(record) {
this.record = record
this.setState({employeeId: record.employeeId, editSlideVisible: true})
}
setStep(step) {
this.setState({step})
}
getColumns() {
const { archivesStore: {tableStore}} = this.props;
let columns = [...tableStore.columns]
@ -83,10 +94,40 @@ export default class Archives extends React.Component {
getTableDatas()
}
// 导入
handleBtnImport() {
this.setState({importVisible: true})
}
// 模板点击
handleTemplateLinkClick() {
const { archivesStore: {exportTempateDownload} } = this.props;
exportTempateDownload()
}
// 导入预览
handlePreviewImport(params) {
const { archivesStore: {previewCurData}} = this.props;
previewCurData(params)
}
// 导入
handleImport(params) {
const { archivesStore: {importBatch}} = this.props;
importBatch(params)
}
// 导入完成
handleFinish() {
this.setState({importVisible: false})
}
render() {
const { archivesStore } = this.props;
const { selectedTab } = this.state;
const { loading, hasRight, form, condition, tableStore, showSearchAd, getTableDatas, doSearch, setShowSearchAd } = archivesStore;
const { loading, hasRight, form, condition, tableStore, showSearchAd, getTableDatas, doSearch, setShowSearchAd,
previewCurDataColumns, previewCurDataDataSource, importResult
} = archivesStore;
const { dataSource, pageInfo } = archivesStore
if (!hasRight && !loading) { // 无权限处理
return renderNoright();
@ -120,7 +161,7 @@ export default class Archives extends React.Component {
const handleMenuClick = () => {}
const btns = [
<Button type="primary" onClick={() => { handleBtnImport() }}>导入</Button>,
<Button type="primary" onClick={() => { this.handleBtnImport() }}>导入</Button>,
<Dropdown.Button onClick={handleButtonClick} overlay={
<Menu onClick={handleMenuClick}>
<Menu.Item key="1">导出选中</Menu.Item>
@ -210,13 +251,13 @@ export default class Archives extends React.Component {
selectedTab == 0 && <BaseForm employeeId={this.state.employeeId}/>
}
{
selectedTab == 1 && <SocialSecurityForm employeeId={this.state.employeeId}/>
selectedTab == 1 && <SocialSecurityForm employeeId={this.state.employeeId} record={this.record}/>
}
{
selectedTab == 2 && <AccumulationFundForm employeeId={this.state.employeeId} />
selectedTab == 2 && <AccumulationFundForm employeeId={this.state.employeeId} record={this.record}/>
}
{
selectedTab == 3 && <OtherForm employeeId={this.state.employeeId} />
selectedTab == 3 && <OtherForm employeeId={this.state.employeeId} record={this.record}/>
}
</div>}
@ -224,6 +265,22 @@ export default class Archives extends React.Component {
showMask={true}
closeMaskOnClick={() => this.setState({editSlideVisible: false})} />
}
{
this.state.importVisible && <ImportModal
params={this.state.modalParam}
columns={previewCurDataColumns}
step={this.state.step}
setStep={this.setStep.bind(this)}
slideDataSource={previewCurDataDataSource}
importResult={importResult}
onFinish={() => {this.handleFinish()}}
previewImport={(params) => {this.handlePreviewImport(params)}}
importFile={(params) => {this.handleImport(params)}}
templateLink={() => {this.handleTemplateLinkClick()}}
visiable={this.state.importVisible}
onCancel={() => { this.setState({importVisible: false})}}
/>
}
</div>
)
}

View File

@ -5,5 +5,7 @@
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin-left: 10px;
margin-right: 10px;
}
}

View File

@ -1,7 +1,7 @@
import React from 'react'
import { inject, observer } from 'mobx-react';
import { Row, Col, Select } from 'antd'
import { WeaDatePicker } from "ecCom";
import { WeaDatePicker, WeaInput } from "ecCom";
import GroupCard from '../../../components/groupCard'
import "./index.less"
const { Option } = Select
@ -17,8 +17,9 @@ export default class OtherForm extends React.Component {
}
componentWillMount() {
const { archivesStore: { getBaseForm }} = this.props;
getBaseForm(this.props.employeeId, "OTHER")
const { archivesStore: { getBaseForm, getPaymentForm}} = this.props;
getBaseForm(this.props.employeeId, "OTHER");
getPaymentForm(this.props.employeeId, "OTHER", this.props.record.otherSchemeId)
}
// 表单变化

View File

@ -13,8 +13,9 @@ const { Option } = Select
export default class SocialSecurityForm extends React.Component {
componentWillMount() {
const { archivesStore } = this.props;
const { getBaseForm } = archivesStore
const { getBaseForm, getPaymentForm } = archivesStore
getBaseForm(this.props.employeeId, "SOCIAL_SECURITY")
getPaymentForm(this.props.employeeId, "SOCIAL_SECURITY", this.props.record.siSchemeId)
}
// 表单变化

View File

@ -32,6 +32,12 @@ export class ArchivesStore {
@observable otherPaymentForm = {}; // 其他福利表单
@observable pageInfo = {};
// 导入预览
@observable previewCurDataList = {}
@observable previewCurDataColumns = []
@observable previewCurDataDataSource = []
@observable importResult = {}
// 社保表单
@action
@ -118,9 +124,9 @@ export class ArchivesStore {
} else if(welfareTypeEnum == "OTHER") {
this.otherForm = res.data
}
if(res.data && res.data.data && res.data.data.id) {
this.getPaymentForm(employeeId, welfareTypeEnum, res.data.data.id)
}
// if(res.data && res.data.data && res.data.data.id) {
// this.getPaymentForm(employeeId, welfareTypeEnum, res.data.data.id)
// }
} else {
message.error(res.errormsg || "获取失败")
}
@ -165,4 +171,49 @@ export class ArchivesStore {
})
}
// 导入模板下载
@action
exportTempateDownload = (params = {}) => {
API.exportCurData(params)
}
// 导入预览
@action
previewCurData = (params) => {
API.previewCurData(params).then(res => {
if(res.status) {
this.previewCurDataList = res.data
this.previewCurDataColumns = res.data.headers.map((item, index) => {
let column = {}
column.title = item;
column.dataIndex = "" + index;
column.key = index + ""
return column
})
this.previewCurDataDataSource = res.data.list.map((item) => {
let data = {}
item.map((i, index) => {
data[index + ''] = i
})
return data
})
} else {
message.error(res.errormsg || "获取失败");
}
})
}
// 导入
@action
importBatch = (params) => {
API.importBatch(params).then(res => {
if(res.status) {
this.importResult = res.data
} else {
message.error(res.errormsg || "导入失败")
}
})
}
}

View File

@ -46,6 +46,8 @@ export class AttendanceStore {
@observable attendQuoteDetailPageInfo = {}; // 详情列表分页数据
@observable attendQuoteDetailTableStore = new TableStore(); // 详情列表表头数据
@observable cycle = {};
@action
searchFieldSettingList = (value) => {
if(value != "") {
@ -413,6 +415,18 @@ export class AttendanceStore {
}
})
})
}
// 根据所属月和账套获取周期
@action
getSalaryCycleAndAttendCycle = (salaryYearMonthStr, salarySobId) => {
API.getSalaryCycleAndAttendCycle({salaryYearMonthStr, salarySobId}).then(res => {
if(res.status) {
this.cycle = res.data
} else {
message.error(res.errormsg || "获取失败")
}
})
}
}

View File

@ -102,7 +102,8 @@ export class LedgerStore {
}
let item = {
fieldId,
sortedIndex
sortedIndex,
canDelete: true
}
let result = [...this.empFields]
result.push(item)

View File

@ -27,7 +27,7 @@ export class SalaryItemStore {
roundingMode: 0,
pattern: 0,
valueType: 1,
dataType: "string",
dataType: "number",
description: ""
}
@ -59,7 +59,7 @@ export class SalaryItemStore {
roundingMode: 0,
pattern: 0,
valueType: "1",
dataType: "string",
dataType: "number",
description: ""
}