Merge branch 'feature/2.15.2.2411.01业务线' into feature/2.15.2.2411.01业务线-数据推送

This commit is contained in:
lys 2024-12-27 09:16:26 +08:00
commit 6a4f9cd2af
22 changed files with 214 additions and 93 deletions

View File

@ -218,8 +218,9 @@ export const exportComparisonResult = (salaryAcctRecordId) => {
};
// 核算进度条
export const getCalculateProgress = (id) => {
return WeaTools.callApi("/api/bs/hrmsalary/progress/getRate?cacheKey=ACCT_PROGRESS_" + id, "get", {});
export const getCalculateProgress = (id = "", paymentOrganization = "") => {
const extra= paymentOrganization ? `_${paymentOrganization}` : paymentOrganization
return WeaTools.callApi(`/api/bs/hrmsalary/progress/getRate?cacheKey=ACCT_PROGRESS_${id}${extra}`, "get", {});
};
// 核算进度条

View File

@ -0,0 +1,96 @@
import React, { Component } from "react";
import { WeaCheckbox, WeaFormItem, WeaSearchGroup } from "ecCom";
import { observer } from "mobx-react";
import { WeaSwitch } from "comsMobx";
@observer
export default class FormInfo extends Component {
renderForm = () => {
const {
formFields, form, colCount, itemRender, onSelectedChangeHandle,
showLabel, multiColumn, custLabelCol, childrenComponents
} = 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 },
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, j) => {
const customerRender = itemRender != null ? itemRender[field.domkey[0]] : null;
const showCheckbox = field.checkbox || false;
let label = field.label;
if (showCheckbox)
label = <WeaCheckbox content={label} value={field.checkboxValue} onChange={(v) => {
field.checkboxValue = v === "1";
onSelectedChangeHandle && onSelectedChangeHandle(field, v);
}}/>;
let coms;
if (customerRender == null) {
coms = <WeaSwitch fieldConfig={{ ...field, ...textAreaProps, hasBorder: field.viewAttr === 1 }} form={form}
formParams={formParams}/>;
} 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: (<WeaFormItem {...itemProps}>{coms}</WeaFormItem>),
col
});
if (childrenComponents && childrenComponents[field.domkey[0]]) {
childrenComponents[field.domkey[0]]().map(child => formItems.push(child));
}
});
groupArr.push(<WeaSearchGroup
center={this.props.center != null ? this.props.center : true}
needTigger={true}
title={formFields.length < 2 ? null : fields.title}
showGroup={true}
items={formItems}
col={col}
fontSize={14}/>);
});
return groupArr;
};
render() {
const { formFields, className } = this.props;
if (formFields == null) return (<div></div>);
return (
<div className={className}>
{this.renderForm()}
</div>
);
}
}

View File

@ -41,7 +41,7 @@ class PersonalScopeTable extends Component {
}
getPersonalScopeList = (tabActive = this.props.tabActive) => {
const { searchValue, searchKeyVal, APIFox } = this.props;
const { searchValue, searchKeyVal, APIFox, showOperateBtn } = this.props;
const { pageInfo, loading } = this.state;
const payload = {
[searchKeyVal["key"]]: searchKeyVal["value"],
@ -60,7 +60,7 @@ class PersonalScopeTable extends Component {
return {
...item,
render: (text, record) => {
if (item.dataIndex === "targetName") {
if (item.dataIndex === "targetName" && showOperateBtn) {
return <a href="javascript:void(0);" onClick={() => this.props.onEditScope(record)}>{text}</a>;
}
return <span className="tdEllipsis" title={text}>{text}</span>;

View File

@ -46,8 +46,8 @@ class Index extends Component {
const payload = {
...pageInfo, ...extra,
departmentIds: departmentIds ? departmentIds.split(",") : [],
positionIds: departmentIds ? departmentIds.split(",") : [],
operatorIds: departmentIds ? departmentIds.split(",") : [],
positionIds: positionIds ? positionIds.split(",") : [],
operatorIds: operatorIds ? operatorIds.split(",") : [],
effectiveTime: effectiveTime1 ? [effectiveTime1, effectiveTime2] : [],
operateTime: operateTime1 ? [operateTime1, operateTime2] : []
};

View File

@ -77,7 +77,8 @@ class Index extends Component {
if (this.timer) clearInterval(this.timer);
this.timer = setInterval(() => {
getCalculateProgress(salaryAcctRecordId).then(({ data }) => {
if ((_.isNil(data) || data.progress === 1) && this.timer) {
let progress = data.progress;
if (progress === 1 && this.timer) {
clearInterval(this.timer);
this.timer = null;
this.setState({
@ -95,7 +96,7 @@ class Index extends Component {
});
message.error(data.message);
}
this.setState({ progress: Number(data.progress) * 100 });
this.setState({ progress: Number(progress) * 100 });
});
}, 1000);
});

View File

@ -287,6 +287,7 @@ class LedgerAssociatedPersonnel extends Component {
APIFox={APIFox}
tabActive={selectedKey}
searchValue={searchValue}
showOperateBtn={showOperateBtn}
onChangeSelectKey={rowKeys => this.setState({ rowKeys })}
onEditScope={this.handleAddPersonal}
/>

View File

@ -254,20 +254,19 @@ class LedgerSalaryItem extends Component {
* Params:
* Date: 2022/12/14
*/
handleAddSalaryItems = (id, items) => {
handleAddSalaryItems = (id, items, insertId) => {
const { itemGroups } = this.state;
this.setState({
itemGroups: _.map(itemGroups, it => {
if (id === it.uuid) {
items = _.map(items, child => {
const { id: itemsId, ...extraItems } = child;
return { ...extraItems, salaryItemGroupId: it.uuid };
});
if (insertId) it.items.splice(_.findIndex(it.items, k => (k.id === insertId) || (k.key === insertId)) + 1, 0, ...items);
return {
...it, items: _.map([..._.map(items, child => {
const { id: itemsId, ...extraItems } = child;
return { ...extraItems, salaryItemGroupId: it.uuid };
}), ...it.items], (childItem, childItemIndex) => {
return {
...childItem,
sortedIndex: childItemIndex
};
...it, items: _.map(insertId ? it.items : [...items, ...it.items], (childItem, childItemIndex) => {
return { ...childItem, sortedIndex: childItemIndex };
})
};
}

View File

@ -1,25 +1,15 @@
import React from "react";
import { Button, Switch } from "antd";
import { WeaDialog, WeaInputSearch, WeaTable } from "ecCom";
import { Button, Spin } from "antd";
import { WeaCheckbox, WeaDialog, WeaInputSearch, WeaLocaleProvider, WeaTable } from "ecCom";
import { listSalaryItem } from "../../../apis/ledger";
const getLabel = WeaLocaleProvider.getLabel;
export default class LedgerSalaryItemAddModal extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: {
query: false
},
name: "",
selectedRowKeys: [],
dataSource: [],
dataSourceCopy: [],
columns: [],
pageInfo: {
current: 1,
pageSize: 10,
total: 0
}
loading: { query: false }, name: "", selectedRowKeys: [], dataSource: [],
dataSourceCopy: [], columns: [], pageInfo: { current: 1, pageSize: 10, total: 0 }
};
}
@ -42,12 +32,7 @@ export default class LedgerSalaryItemAddModal extends React.Component {
excludeIds.push(i.salaryItemId);
});
});
const payload = {
excludeIds,
name,
...pageInfo,
...extra
};
const payload = { excludeIds, name, ...pageInfo, ...extra };
this.setState({ loading: { ...loading, query: true } });
listSalaryItem(payload).then(({ status, data }) => {
this.setState({ loading: { ...loading, query: false } });
@ -56,9 +41,7 @@ export default class LedgerSalaryItemAddModal extends React.Component {
const tmpV = !_.isEmpty(dataSource) ? dataSource : [];
this.setState({
dataSourceCopy: [...dataSourceCopy, ...tmpV],
pageInfo: { ...pageInfo, current, pageSize, total },
dataSource: tmpV,
columns
pageInfo: { ...pageInfo, current, pageSize, total }, dataSource: tmpV, columns
});
}
}).catch(() => {
@ -76,7 +59,7 @@ export default class LedgerSalaryItemAddModal extends React.Component {
case "useDefault":
case "hideDefault":
case "useInEmployeeSalary":
return <Switch checked={text === 1}/>;
return <WeaCheckbox value={String(text)} disabled display="switch"/>;
default:
return <div dangerouslySetInnerHTML={{ __html: valueSpan }}/>;
}
@ -85,10 +68,9 @@ export default class LedgerSalaryItemAddModal extends React.Component {
});
return newColumns;
};
handleAdd = () => {
const { dataSourceCopy, selectedRowKeys } = this.state;
const { onAddSalaryItems, id, onCancel, itemGroups } = this.props;
const { onAddSalaryItems, id, onCancel, itemGroups, record } = this.props;
const arrItems = _.find(itemGroups, it => it.uuid === id).items || [];
let selectItems = [];
_.uniqWith(dataSourceCopy, _.isEqual).map((item) => {
@ -104,55 +86,53 @@ export default class LedgerSalaryItemAddModal extends React.Component {
});
});
onCancel();
onAddSalaryItems(id, selectItems);
onAddSalaryItems(id, selectItems, record.id || record.key);
};
renderTitle = () => {
const { name, pageInfo } = this.state;
return <div className="sys-item-title">
<span>{getLabel(111, "添加薪资项目")}</span>
<WeaInputSearch value={name} onChange={val => this.setState({ name: val })} style={{ width: 200 }}
placeholder={getLabel(111, "请输入薪资项目名称")} onSearch={() => this.setState({
pageInfo: { ...pageInfo, current: 1 }
}, () => this.listSalaryItem())}/>
</div>;
};
render() {
const { onCancel, visible } = this.props;
const { name, selectedRowKeys, pageInfo, dataSource, loading } = this.state;
const { selectedRowKeys, pageInfo, dataSource, loading } = this.state;
const pagination = {
...pageInfo,
showTotal: total => `${total}`,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ["10", "20", "50", "100"],
onShowSizeChange: (current, pageSize) => {
this.setState({ pageInfo: { ...pageInfo, current: 1, pageSize } }, () => this.listSalaryItem());
},
onChange: current => {
this.setState({
pageInfo: { ...pageInfo, current }
}, () => {
this.listSalaryItem();
});
this.setState({ pageInfo: { ...pageInfo, current } }, () => this.listSalaryItem());
}
};
const rowSelection = {
selectedRowKeys,
onChange: (selectedRowKeys) => {
this.setState({ selectedRowKeys }, () => {
});
}
selectedRowKeys, onChange: (selectedRowKeys) => this.setState({ selectedRowKeys })
};
return (
<WeaDialog
visible={visible} onCancel={onCancel} hasScroll
title="添加薪资项目" style={{ width: "80vw", height: 400 }}
buttons={[<Button type="primary" onClick={this.handleAdd} disabled={_.isEmpty(selectedRowKeys)}>添加</Button>]}
>
<div style={{ display: "flex", justifyContent: "flex-end", alignItems: "center", padding: 20 }}>
<WeaInputSearch
placeholder="请输入薪资项目名称"
value={name}
onChange={(name) => this.setState({ name })}
onSearch={() => this.listSalaryItem({ current: 1 })}
/>
<WeaDialog {...this.props} initLoadCss className="sys-salary-wrapper" ref={dom => this.sysItemRef = dom}
title={this.renderTitle()}
buttons={[<Button type="primary" onClick={this.handleAdd}
disabled={_.isEmpty(selectedRowKeys)}>{getLabel(111, "添加")}</Button>]}
style={{
width: "60vw", height: 600, minHeight: 200, minWidth: 380,
maxHeight: "90%", maxWidth: "90%", overflow: "hidden", transform: "translate(0px, 0px)"
}}>
<div className="sys-item-table-box">
<Spin spinning={loading.query && pageInfo.total === 0}>
<WeaTable columns={this.getSalaryItemAddColumns()} dataSource={dataSource} pagination={pagination}
loading={loading.query} scroll={{ y: this.sysItemRef ? this.sysItemRef.state.height - 112 : 600 }}
rowKey={record => record.id || record.key} rowSelection={rowSelection}/>
</Spin>
</div>
<WeaTable
rowKey={record => record.id || record.key}
rowSelection={rowSelection}
dataSource={dataSource}
pagination={pagination}
loading={loading.query}
columns={this.getSalaryItemAddColumns()}
/>
</WeaDialog>
);
}

View File

@ -22,7 +22,7 @@ class LedgerSalaryItemNormal extends Component {
constructor(props) {
super(props);
this.state = {
addCategoryItemsVisible: false,
addCategoryItemsVisible: { visible: false, id: "", record: {} },
categoryModal: {
visible: false,
title: "新增分类",
@ -170,7 +170,11 @@ class LedgerSalaryItemNormal extends Component {
onEditCategory={this.handleAddCategory}
onDeleteCategory={this.handleDeleteCategory}
onDeleteCategoryItems={this.handleDeleteCategoryItems}
onAddCategoryItems={(id) => this.setState({ addCategoryItemsVisible: { visible: true, id } })}
onAddCategoryItems={(id) => this.setState({
addCategoryItemsVisible: {
...addCategoryItemsVisible, visible: true, id
}
})}
onUpgo={this.handleUpgo}
onDowngo={this.handleDowngo}
/>
@ -178,13 +182,16 @@ class LedgerSalaryItemNormal extends Component {
>
<LedgerSalaryItemTable
tableData={items}
dataSource={_.find(dataSource, childItem => childItem.id === id || childItem.uuid === uuid).items}
dataSource={_.find(newDateSource, childItem => childItem.uuid === uuid).items}
salarySobId={editId || saveSalarySobId}
selectedRowKeys={field.selectedRowKeys || []}
onDropCategoryItem={(data) => onDropCategoryItem(field, data)}
onHandleItemhide={(data) => onHandleItemhide(field, data)}
onChangeSelectedRowKeys={(data) => onChangeSelectedRowKeys(field, data)}
onMoveTo={this.handleMoveTo}
onAddCategoryItems={(record) => this.setState({
addCategoryItemsVisible: { visible: true, record, id: uuid }
})}
/>
</WeaSearchGroup>;
})
@ -198,7 +205,7 @@ class LedgerSalaryItemNormal extends Component {
<LedgerSalaryItemAddModal
{...addCategoryItemsVisible}
itemGroups={dataSource}
onCancel={() => this.setState({ addCategoryItemsVisible: { visible: false, id: "" } })}
onCancel={() => this.setState({ addCategoryItemsVisible: { visible: false, id: "", record: {} } })}
onAddSalaryItems={onAddSalaryItems}
/>
<CategoryAddModal

View File

@ -295,11 +295,13 @@ class LedgerSalaryItemTable extends Component {
title: "操作",
dataIndex: "operate",
key: "operate",
width: 120,
width: 180,
render: (_, record) => (
<React.Fragment>
<a href="javascript:void(0);" onClick={() => this.handleEditSalaryItem(record)}
style={{ marginRight: 10 }}>编辑</a>
<a href="javascript:void(0);" onClick={() => this.props.onAddCategoryItems(record)}
style={{ marginRight: 10 }}>{getLabel(111, "插入")}</a>
<a href="javascript:void(0);" onClick={() => onMoveTo(record)}>移动到</a>
</React.Fragment>
)

View File

@ -87,7 +87,7 @@ class LedgerSlide extends Component {
* Date: 2022/12/12
*/
saveLedgerAdjustRule = () => {
const { adjustRules, saveSalarySobId } = this.state;
const { adjustRules, saveSalarySobId, salaryApprovalStatus } = this.state;
const payload = {
salarySobId: this.props.editId || saveSalarySobId,
ruleParams: adjustRules
@ -97,6 +97,7 @@ class LedgerSlide extends Component {
this.setState({ loading: false });
if (status) {
message.success("保存成功");
!salaryApprovalStatus && this.handleClose();
} else {
message.success(errormsg || "保存失败");
}
@ -260,7 +261,7 @@ class LedgerSlide extends Component {
<Button type="ghost"
onClick={() => this.setState({ current: current - 1 })}>{getLabel(111, "上一步")}</Button>,
<Button type="primary"
onClick={() => this.setState({ current: current + 1 }, () => this.saveLedgerAdjustRule())}>{getLabel(111, "保存并进入下一步")}</Button>
onClick={() => this.setState({ current: !salaryApprovalStatus ? current : current + 1 }, () => this.saveLedgerAdjustRule())}>{!salaryApprovalStatus ? getLabel(111, "完成") : getLabel(111, "保存并进入下一步")}</Button>
],
editBtns: [
<Button type="primary" loading={loading}

View File

@ -28,7 +28,7 @@ class Index extends Component {
<span>{moment(it.sendTime).format("YYYY-MM")}</span>
</div>
<a
href={`/spa/hrmSalary/static/index.html#/main/hrmSalary/mobilepayroll?id=${it.id}&recipient=${it.employeeId}&type=phone`}
href={`/spa/hrmSalary/static/index.html#/main/hrmSalary/mobilepayroll?id=${it.id}&salaryCode=${it.salaryCode}&type=phone`}
target="_blank">
{`${getLabel(33564, "查看")}>`}
</a>

View File

@ -152,6 +152,22 @@ export const conditions = [
lanId: 538004,
defaultshow: true
},
{
items: [
{
conditionType: "SWITCH",
domkey: ["ATTENDANCE_SERIAL_COLLECTION_BTN"],
fieldcol: 10,
label: "考勤引用是否采集班次数据",
lanId: 111,
labelcol: 8,
viewAttr: 2
}
],
title: "数据采集",
lanId: 111,
defaultshow: true
},
{
items: [
{

View File

@ -153,6 +153,7 @@ class RuleConfig extends Component {
case "APPROVAL_CAN_MANUAL_FILE_STATUS":
case "APPROVAL_CAN_RE_CALC_STATUS":
case "APPROVAL_CAN_EDIT_RESULT_STATUS":
case "ATTENDANCE_SERIAL_COLLECTION_BTN":
if (!this.handleDebounce) {
this.handleDebounce = _.debounce(() => {
const confTitle = {
@ -169,7 +170,8 @@ class RuleConfig extends Component {
SALARY_APPROVAL_STATUS: getLabel(111, "是否开启薪资审批"),
APPROVAL_CAN_MANUAL_FILE_STATUS: getLabel(111, "开启审批的核算记录允许手动归档"),
APPROVAL_CAN_RE_CALC_STATUS: getLabel(111, "开启审批的核算记录允许重新核算"),
APPROVAL_CAN_EDIT_RESULT_STATUS: getLabel(111, "审批流程发起后允许修改核算数据")
APPROVAL_CAN_EDIT_RESULT_STATUS: getLabel(111, "审批流程发起后允许修改核算数据"),
ATTENDANCE_SERIAL_COLLECTION_BTN: getLabel(111, "考勤引用是否采集班次数据")
};
this.unifiedSettings(key, confTitle[key]);
this.handleDebounce = null;

View File

@ -50,7 +50,7 @@ export default class SystemSalaryItemModal extends React.Component {
return <div className="sys-item-title">
<span>{getLabel(111, "添加系统薪资项目")}</span>
<WeaInputSearch value={name} onChange={val => this.setState({ name: val })} style={{ width: 200 }}
placeholder={getLabel(111, "请输入薪资项目名称")} a onSearch={() => this.setState({
placeholder={getLabel(111, "请输入薪资项目名称")} onSearch={() => this.setState({
pageInfo: { ...pageInfo, current: 1 }
}, () => this.getSysItemList())}/>
</div>;
@ -92,7 +92,7 @@ export default class SystemSalaryItemModal extends React.Component {
<div className="sys-item-table-box">
<Spin spinning={loading && pageInfo.total === 0}>
<WeaTable columns={columns} dataSource={dataSource} pagination={pagination} rowSelection={rowSelection}
loading={loading} scroll={{ y: this.importRef ? this.sysItemRef.state.height - 16 : 600 }}
loading={loading} scroll={{ y: this.sysItemRef ? this.sysItemRef.state.height - 16 : 600 }}
rowKey="id"/>
</Spin>
</div>

View File

@ -60,7 +60,7 @@ class StandingBook extends Component {
progressVisible: true
}, () => {
this.timer = setInterval(() => {
getCalculateProgress(moment(billMonth).format("YYYY-MM")).then(({ status, data }) => {
getCalculateProgress(moment(billMonth).format("YYYY-MM"), payload.paymentOrganization).then(({ status, data }) => {
if (status) {
if (!data.status) {
clearInterval(this.timer);

View File

@ -359,7 +359,7 @@ export default class NormalIndex extends Component {
progressVisible: true
}, () => {
this.timer = setInterval(() => {
getCalculateProgress(billMonth).then(({ status, data }) => {
getCalculateProgress(billMonth, paymentOrganization).then(({ status, data }) => {
if (status) {
if (!data.status) {
clearInterval(this.timer);

View File

@ -118,7 +118,7 @@ class Index extends Component {
} else if (getKey(g).indexOf("StartTime") !== -1) {
return {
...g, label: getLabel(g.lanId, g.label),
viewAttr: (formData[o["typename"]][`${o.title}Name`] && showOperateBtn) ? 3 : g.viewAttr
viewAttr: (runStatuses === "4,5" || !showOperateBtn) ? 1 : (formData[o["typename"]][`${o.title}Name`] && showOperateBtn) ? 3 : g.viewAttr
};
}
return {

View File

@ -84,7 +84,7 @@ class PlanSetTable extends Component {
com: [{
type: "custom",
key: "custom",
render: text => (<span>{text}</span>)
render: text => (<span className="text-td-elli" title={text}>{text}</span>)
}]
},
{

View File

@ -232,6 +232,14 @@
text-overflow: ellipsis;
overflow: hidden;
}
.text-td-elli {
display: inline-block;
width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}

View File

@ -68,7 +68,7 @@ class Index extends Component {
label: o.name,
labelcol: 6,
value: detail[`${String(o.id)}_variableItem`] || "",
viewAttr: 2
viewAttr: 2, dataType: o.dataType
})),
title: "", col: 2,
defaultshow: true

View File

@ -128,3 +128,10 @@
}
}
//公共表格操作按钮间距
.space_div {
a:not(:last-child) {
margin-right: 8px;
}
}