custom/钱智

This commit is contained in:
lys 2025-09-25 09:41:11 +08:00
parent 81c05e7e5f
commit 8a6e9bbadd
13 changed files with 418 additions and 60 deletions

View File

@ -8,7 +8,8 @@ export const getSalaryAcctList = params => {
// 薪资记录--保存薪资核算的基本信息
export const saveBasic = params => {
return postFetch("/api/bs/hrmsalary/salaryacct/basic/save", params);
// return postFetch("/api/bs/hrmsalary/salaryacct/basic/save", params);
return postFetch("/api/bs/hrmsalary/salaryacct/basic/batSave", params);
};
// 薪资记录--薪资核算详情

View File

@ -13,7 +13,8 @@ export const getDeclareForm = params => {
//个税申报表-个税申报表生成
export const saveDeclare = params => {
return postFetch("/api/bs/hrmsalary/taxdeclaration/save", params);
// return postFetch("/api/bs/hrmsalary/taxdeclaration/save", params);
return postFetch("/api/bs/hrmsalary/taxdeclaration/batSave", params);
};
//个税申报表-获取分类

View File

@ -242,8 +242,7 @@ class Calculate extends Component {
onCancel={(bool, id) => this.setState({
calcDaialog: { ...calcDaialog, visible: false },
isRefresh: bool === "refresh" ? !isRefresh : isRefresh
}, () => bool === "refresh" && window.open(`/spa/hrmSalary/static/index.html#/main/hrmSalary/calculate/${id}`))}
/>
})}/>
{/*操作日志*/}
<LogDialog visible={logDialogVisible} logFunction="acctrecord" filterConditions={filterConditions}
onCancel={() => this.setState({ logDialogVisible: false })}/>

View File

@ -4,7 +4,7 @@ export const calculateConditions = [
{
colSpan: 1,
conditionType: "MONTHPICKER",
domkey: ["salaryMonthStr"],
domkey: ["salaryMonth"],
fieldcol: 14,
label: "薪资所属月",
lanId: 542604,
@ -16,12 +16,13 @@ export const calculateConditions = [
{
colSpan: 1,
conditionType: "SELECT",
domkey: ["salarySobId"],
domkey: ["salarySobIds"],
fieldcol: 14,
label: "核算账套",
lanId: 519146,
labelcol: 6,
options: [],
multiple: true,
otherParams: {
showSearch: true, optionFilterProp: "children"
},

View File

@ -39,7 +39,7 @@ class Index extends Component {
conditions: _.map(calculateConditions, item => ({
...item,
items: _.map(item.items, o => {
if (getKey(o) === "salarySobId") {
if (getKey(o) === "salarySobIds") {
return {
...o,
options: _.map(salarySobs, g => ({ key: g.id.toString(), showname: g.name }))
@ -56,13 +56,16 @@ class Index extends Component {
const { calculateStore: { calculateForm } } = this.props;
calculateForm.validateForm().then(f => {
if (f.isValid) {
const payload = calculateForm.getFormParams();
const { salarySobIds, salaryMonth, ...payload } = calculateForm.getFormParams();
this.setState({ loading: true });
saveBasic({ ...payload }).then(({ status, data, errormsg }) => {
saveBasic({
...payload, salaryMonth: salaryMonth + "-01",
salarySobIds: !!salarySobIds ? salarySobIds.split(",") : []
}).then(({ status, data, errormsg }) => {
this.setState({ loading: false });
if (status) {
message.success(getLabel(30700, "操作成功"));
this.props.onCancel("refresh", data);
this.props.onCancel("refresh");
} else {
message.error(errormsg);
}
@ -80,7 +83,7 @@ class Index extends Component {
<WeaDialog
{...this.props} style={{ width: 480, height: 174 }} initLoadCss
buttons={[
<Button type="primary" onClick={this.save} loading={loading}>{getLabel(543233, "保存并进入核算")}</Button>
<Button type="primary" onClick={this.save} loading={loading}>{getLabel(111, "确定")}</Button>
]}
>
<div className="calculate-dialog-layout">{getSearchs(calculateForm, conditions, 1, false)}</div>

View File

@ -149,6 +149,10 @@
.calculate-dialog-layout {
background: #f6f6f6;
.wea-form-item-wrapper {
display: inline-block !important;
}
.wea-search-group {
padding: 16px;
}
@ -160,6 +164,38 @@
.wea-select {
display: inline-block;
position: relative;
.wea-select-input .arrow {
position: absolute;
right: 4px;
top: 8px;
color: #666;
}
.wdb {
word-break: break-all !important;
word-wrap: break-word !important;
}
.wea-select-input {
height: 30px;
white-space: nowrap;
min-width: 100px;
max-width: 345px;
width: 100%;
display: inline-block;
padding: 4px 17px 4px 4px;
position: relative;
min-height: 30px;
border: 1px solid #d9d9d9;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
overflow: hidden;
}
}
.ant-select-selection {

View File

@ -16,12 +16,13 @@ export const declareConditions = [
{
colSpan: 1,
conditionType: "SELECT",
domkey: ["taxAgentId"],
domkey: ["taxAgentIds"],
fieldcol: 14,
label: "个税扣缴义务人",
lanId: 537996,
labelcol: 6,
options: [],
multiple: true,
rules: "required|string",
viewAttr: 3,
},

View File

@ -42,7 +42,7 @@ class Index extends Component {
conditions: _.map(declareConditions, item => ({
...item,
items: _.map(item.items, o => {
if (getKey(o) === "taxAgentId") {
if (getKey(o) === "taxAgentIds") {
return {
...o, label: getLabel(o.lanId, o.label),
options: _.map(data, g => ({ key: String(g.id), showname: g.name }))
@ -65,39 +65,40 @@ class Index extends Component {
const { declareStore: { declareForm } } = this.props;
declareForm.validateForm().then(f => {
if (f.isValid) {
const { salaryMonth, ...payload } = declareForm.getFormParams();
const { salaryMonth, taxAgentIds, ...payload } = declareForm.getFormParams();
this.setState({ loading: true });
saveDeclare({
...payload, salaryMonth: salaryMonth + "-01",
taxAgentIds: !!taxAgentIds ? taxAgentIds.split(",") : [],
taxCycle: `${salaryMonth}-01`,
salaryDate: `${salaryMonth}-01`
}).then(async ({ status, data, errormsg }) => {
this.setState({ loading: false });
if (status) {
message.destroy();
message.loading(getLabel(111, "生成中..."), 0);
this.timer = setInterval(async () => {
const { status: resStatus, data: result } = await taxdeclarationGetRate({ index: data });
const { status: rateStatus, finish, msg } = result;
if (resStatus && rateStatus) {
if (finish) {
clearInterval(this.timer);
message.destroy();
message.success(getLabel(30700, "操作成功"));
this.props.onCancel("refresh");
}
} else {
this.setState({ loading: false });
if (status) {
message.destroy();
message.loading(getLabel(111, "生成中..."), 0);
this.timer = setInterval(async () => {
const { status: resStatus, data: result } = await taxdeclarationGetRate({ index: data });
const { status: rateStatus, finish, msg } = result;
if (resStatus && rateStatus) {
if (finish) {
clearInterval(this.timer);
message.destroy();
message.warning(msg);
message.success(getLabel(30700, "操作成功"));
this.props.onCancel("refresh");
}
}, 1000);
} else {
clearInterval(this.timer);
message.destroy();
message.warning(errormsg);
}
}).catch(() => {
} else {
clearInterval(this.timer);
message.destroy();
message.warning(msg);
}
}, 1000);
} else {
clearInterval(this.timer);
message.destroy();
message.warning(errormsg);
}
}).catch(() => {
message.destroy();
clearInterval(this.timer);
this.setState({ loading: false });

View File

@ -59,6 +59,10 @@
.wea-search-group {
padding: 16px;
.wea-form-item-wrapper {
display: inline-block !important;
}
}
.wea-select, .ant-select-selection, .ant-select {
@ -68,6 +72,38 @@
.wea-select {
display: inline-block;
position: relative;
.wea-select-input .arrow {
position: absolute;
right: 4px;
top: 8px;
color: #666;
}
.wdb {
word-break: break-all !important;
word-wrap: break-word !important;
}
.wea-select-input {
height: 30px;
white-space: nowrap;
min-width: 100px;
max-width: 345px;
width: 100%;
display: inline-block;
padding: 4px 17px 4px 4px;
position: relative;
min-height: 30px;
border: 1px solid #d9d9d9;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
overflow: hidden;
}
}
.ant-select-selection {

View File

@ -0,0 +1,98 @@
/*
* 人员信息报送
* 批量操作: 批量属性(batRefresh)/批量报送(batDeclare)/批量获取结果(batGetDeclareFeedback)
* @Author: 黎永顺
* @Date: 2025/9/24
* @Wechat:
* @Email: 971387674@qq.com
* @description:
*/
import React, { Component } from "react";
import { WeaDialog, WeaLocaleProvider } from "ecCom";
import { Button, message } from "antd";
import { WeaForm, WeaSwitch } from "comsMobx";
import { postFetch } from "../../util/request";
import FormInfo from "../../components/FormInfo";
import { batchEmployeeDeclareConditions } from "./conditions";
const getLabel = WeaLocaleProvider.getLabel;
let form = new WeaForm();
class BatchEmployeeDeclare extends Component {
constructor(props) {
super(props);
this.state = {
loading: false, taxAgentOpts: []
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible && nextProps.visible) this.getTaxAgentSelectListAsAdmin();
if (nextProps.visible !== this.props.visible && !nextProps.visible) form = new WeaForm();
}
getTaxAgentSelectListAsAdmin = () => {
postFetch("/api/bs/hrmsalary/taxAgent/listAuth", { filterType: "ADMIN_DATA" })
.then(({ status, data }) => {
if (status) {
this.setState({
taxAgentOpts: _.map(data, g => ({ key: String(g.id), showname: g.name }))
}, () => form.initFormFields(batchEmployeeDeclareConditions));
}
});
};
save = () => {
form.validateForm().then(f => {
if (f.isValid) {
const { type } = this.props;
const { taxAgentIds, taxCycle } = form.getFormParams();
this.setState({ loading: true });
postFetch(`/api/bs/hrmsalary/employeedeclare/${type}`, {
taxCycle: taxCycle + "-01", taxAgentIds: !!taxAgentIds ? taxAgentIds.split(",") : []
}).then(({ status, data, errormsg }) => {
this.setState({ loading: false });
if (status) {
message.success(data || getLabel(111, "操作成功"));
this.props.onCancel(this.props.onSuccess);
} else {
message.error(errormsg);
}
});
} else {
f.showErrors();
}
});
};
render() {
const { taxAgentOpts, loading } = this.state;
const itemRender = {
taxCycle: (field, textAreaProps, form, formParams) => {
return (
<WeaSwitch fieldConfig={{ ...field, ...textAreaProps, label: getLabel(field.lanId, field.label) }} form={form}
formParams={formParams}/>);
},
taxAgentIds: (field, textAreaProps, form, formParams) => {
return (
<WeaSwitch className="multiple_select" fieldConfig={{
...field, ...textAreaProps, options: taxAgentOpts, abel: getLabel(field.lanId, field.label)
}} form={form} formParams={formParams}/>);
}
};
return (
<WeaDialog
{...this.props} style={{ width: 500, height: 127 }} initLoadCss
buttons={[
<Button type="primary" onClick={this.save} loading={loading}>{getLabel(111, "确定")}</Button>,
<Button type="ghost" onClick={() => this.props.onCancel()}>{getLabel(111, "取消")}</Button>
]}
>
<FormInfo className="form-dialog-layout" center={false} itemRender={itemRender} form={form}
formFields={batchEmployeeDeclareConditions}/>
</WeaDialog>
);
}
}
export default BatchEmployeeDeclare;

View File

@ -0,0 +1,65 @@
export const batchEmployeeDeclareConditions = [
{
items: [
{
colSpan: 1,
conditionType: "MONTHPICKER",
domkey: ["taxCycle"],
fieldcol: 14,
label: "税款所属期",
lanId: 111,
labelcol: 6,
value: "",
rules: "required|string",
viewAttr: 3
},
{
colSpan: 1,
conditionType: "SELECT",
domkey: ["taxAgentIds"],
fieldcol: 14,
label: "个税扣缴义务人",
lanId: 537996,
labelcol: 6,
options: [],
multiple: true,
rules: "required|string",
viewAttr: 3
}
],
defaultshow: true,
title: ""
}
];
export const employeeDeclareAdvanceConditions = [
{
items: [
{
colSpan: 1,
conditionType: "SELECT",
domkey: ["lastOperates"],
fieldcol: 18,
label: "最后操作功能",
lanId: 111,
labelcol: 6,
options: [],
multiple: true,
viewAttr: 2
},
{
colSpan: 1,
conditionType: "SELECT",
domkey: ["statuses"],
fieldcol: 18,
label: "报送状态",
lanId: 111,
labelcol: 6,
options: [],
multiple: true,
viewAttr: 2
}
],
defaultshow: true,
title: ""
}
];

View File

@ -6,40 +6,62 @@
*/
import React, { Component } from "react";
import { WeaInputSearch, WeaLocaleProvider, WeaTable, WeaTop } from "ecCom";
import { Col, Dropdown, Menu, message, Row } from "antd";
import { WeaForm, WeaSwitch } from "comsMobx";
import { Button, Col, Dropdown, Menu, message, Row } from "antd";
import LogDialog from "../../components/logViewModal";
import { taxAgentDeclareList } from "../../apis/declare";
import TipLabel from "../../components/TipLabel";
import BatchEmployeeDeclare from "./batchEmployeeDeclare";
import FormInfo from "../../components/FormInfo";
import { employeeDeclareAdvanceConditions } from "./conditions";
import { commonEnumList } from "../../apis/ruleconfig";
import cs from "classnames";
import "./index.less";
const { getLabel } = WeaLocaleProvider;
const form = new WeaForm();
class Index extends Component {
constructor(props) {
super(props);
this.state = {
dataSource: [], loading: false, taxAgentName: "",
dataSource: [], columns: [], loading: false, taxAgentName: "",
pageInfo: { current: 1, pageSize: 10, total: 0 },
logDialogVisible: false, filterConditions: "[]"
logDialogVisible: false, filterConditions: "[]", showAdvance: false,
batchEPDialog: { visible: false, title: "", type: "" },
lastOperatesOptions: [], statusesOptions: []
};
}
componentDidMount() {
async componentDidMount() {
const [{ data: optEnum }, { data: statusEnum }] = await Promise.all([
commonEnumList({ enumClass: "com.engine.salary.enums.employeedeclare.DeclareOptEnum" }),
commonEnumList({ enumClass: "com.engine.salary.enums.employeedeclare.DeclareStatusEnum" })
]);
this.setState({
lastOperatesOptions: optEnum.map(({ value, defaultLabel }) => ({ key: value, showname: defaultLabel })),
statusesOptions: statusEnum.map(({ value, defaultLabel }) => ({ key: String(value), showname: defaultLabel }))
});
form.initFormFields(employeeDeclareAdvanceConditions);
this.taxAgentDeclareList();
}
taxAgentDeclareList = () => {
const { pageInfo, taxAgentName } = this.state;
const payload = { ...pageInfo, taxAgentName };
const { pageInfo, taxAgentName } = this.state, { lastOperates, statuses } = form.getFormParams();
const payload = {
...pageInfo, taxAgentName,
lastOperates: !!lastOperates ? lastOperates.split(",") : [],
statuses: !!statuses ? statuses.split(",") : []
};
this.setState({ loading: true });
taxAgentDeclareList(payload).then(({ status, data, errormsg }) => {
this.setState({ loading: false });
if (status) {
const { pageNum: current, pageSize, total, list: dataSource } = data;
const { pageNum: current, pageSize, total, list: dataSource, columns } = data;
this.setState({
pageInfo: { ...pageInfo, current, pageSize, total },
dataSource
dataSource, columns
});
} else {
message.error(errormsg);
@ -48,6 +70,16 @@ class Index extends Component {
};
onDropMenuClick = (key, targetid = "") => {
switch (key) {
case "batRefresh":
case "batDeclare":
case "batGetDeclareFeedback":
this.setState({
batchEPDialog: {
visible: true, type: key,
title: key === "batRefresh" ? getLabel(111, "批量刷新") : key === "batDeclare" ? getLabel(111, "批量报送") : getLabel(111, "批量获取结果")
}
});
break;
case "log":
this.setState({
logDialogVisible: true,
@ -60,38 +92,68 @@ class Index extends Component {
};
render() {
const { pageInfo, taxAgentName, dataSource, logDialogVisible, filterConditions } = this.state;
const {
pageInfo, taxAgentName, dataSource, columns, logDialogVisible, filterConditions,
batchEPDialog, showAdvance, statusesOptions, lastOperatesOptions
} = this.state;
const tipList = [
getLabel(544290, "1、点击查看详情管理各个个税扣缴义务人的人员报送信息如购买了在线报送服务可在线报送如未购买在线报送服务也可导出数据线下报送。")
];
const itemRender = {
lastOperates: (field, textAreaProps, form, formParams) => {
return (
<WeaSwitch fieldConfig={{
...field, ...textAreaProps, options: lastOperatesOptions, label: getLabel(field.lanId, field.label)
}} form={form} formParams={formParams}/>);
},
statuses: (field, textAreaProps, form, formParams) => {
return (
<WeaSwitch className="multiple_select" fieldConfig={{
...field, ...textAreaProps, options: statusesOptions, label: getLabel(field.lanId, field.label)
}} form={form} formParams={formParams}/>);
}
};
return (
<WeaTop
title={getLabel(544289, "人员信息报送")} iconBgcolor="#F14A2D"
title={getLabel(544289, "人员信息报送")} iconBgcolor="#F14A2D" className="employeeDeclare-container"
icon={<i className="icon-coms-fa"/>} showDropIcon onDropMenuClick={this.onDropMenuClick}
dropMenuDatas={[{
key: "log", icon: <i className="iconfont icon-caozuorizhi32"/>,
content: getLabel(545781, "操作日志")
}]} buttons={[
<WeaInputSearch placeholder={getLabel(543634, "请输入个税扣缴义务人名称")}
value={taxAgentName} onChange={val => this.setState({ taxAgentName: val })}
onSearch={this.taxAgentDeclareList}
/>
]}
>
<Button type="primary" onClick={() => this.onDropMenuClick("batRefresh")}>{getLabel(111, "批量刷新")}</Button>,
<Button type="primary" onClick={() => this.onDropMenuClick("batDeclare")}>{getLabel(111, "批量报送")}</Button>,
<Button type="primary"
onClick={() => this.onDropMenuClick("batGetDeclareFeedback")}>{getLabel(111, "批量获取结果")}</Button>,
<div className="advance-custom">
<WeaInputSearch placeholder={getLabel(543634, "请输入个税扣缴义务人名称")}
value={taxAgentName} onChange={val => this.setState({ taxAgentName: val })}
onSearch={this.taxAgentDeclareList}/>
<a href="javascript:void(0);"
onClick={() => this.setState({ showAdvance: !showAdvance })}>{getLabel(111, "高级搜索")}</a>
</div>
]}>
<div style={{ height: "100%", background: "#f6f6f6", padding: 16 }}>
<div className={cs("advance-employeeDeclare", { "show-advance-employeeDeclare": showAdvance })}>
<FormInfo center={false} itemRender={itemRender} form={form} formFields={employeeDeclareAdvanceConditions}
colCount={2}/>
<div className="advance-employeeDeclare-btns">
<Button type="primary" onClick={this.taxAgentDeclareList}>{getLabel(111, "搜索")}</Button>
<Button type="ghost" onClick={() => form.resetForm()}>{getLabel(111, "重置")}</Button>
<Button type="ghost"
onClick={() => this.setState({ showAdvance: !showAdvance })}>{getLabel(111, "取消")}</Button>
</div>
</div>
<Row gutter={16}>
<Col span={16}>
<WeaTable
className="declareTable"
columns={[
{
title: getLabel(537996, "个税扣缴义务人"),
dataIndex: "taxAgentName"
},
...columns,
{
title: getLabel(30585, "操作"),
dataIndex: "operate",
width: 260,
width: 120,
render: (_, record) => (<React.Fragment>
<a
href={`${window.ecologyContentPath || ""}/spa/hrmSalary/static/index.html#/main/hrmSalary/employeedeclareDetail?id=${record.id}&taxName=${encodeURIComponent(record.taxAgentName)}`}
@ -135,6 +197,12 @@ class Index extends Component {
{/*操作日志*/}
<LogDialog visible={logDialogVisible} logFunction="empdeclare" filterConditions={filterConditions}
onCancel={() => this.setState({ logDialogVisible: false })}/>
{/*批量操作*/}
<BatchEmployeeDeclare {...batchEPDialog}
onSuccess={() => this.taxAgentDeclareList()}
onCancel={(callback) => this.setState({
batchEPDialog: { visible: false, title: "", type: "" }
}, () => callback && callback())}/>
</WeaTop>
);
}

View File

@ -1,3 +1,51 @@
.declareTable {
background: #FFF;
.employeeDeclare-container {
.declareTable {
background: #FFF;
}
.advance-custom {
display: flex;
align-items: center;
& > a {
border-radius: 0;
height: 28px;
position: relative;
color: #474747;
padding: 4px 15px;
background-color: transparent;
display: flex;
align-items: center;
border: 1px solid #d9d9d9;
border-left: none;
top: 1px;
}
}
.advance-employeeDeclare {
display: none;
background: #FFF;
margin-bottom: 8px;
.advance-employeeDeclare-btns {
display: flex;
justify-content: center;
align-items: center;
padding: 15px 0;
border-top: 1px solid #dadada;
button {
margin-right: 15px;
}
}
.wea-search-group, .wea-content {
padding: 0;
}
}
.show-advance-employeeDeclare {
display: block;
}
}