Compare commits

..

81 Commits

Author SHA1 Message Date
lys c5d5609a1f release/2.19.1.2503.01-业务线个税 3 months ago
lys 5812022207 Merge branch 'feature/业务线管理' into release/2.19.1.2503.01-业务线个税 3 months ago
lys 1dd9bc997b Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 4 months ago
lys 78643df60d Merge branch 'master' into feature/业务线管理 4 months ago
lys 8908b23300 feature/业务线管理 4 months ago
lys 4f9bc70fc7 Merge branch 'master' into feature/业务线管理 5 months ago
lys f0f5e8ab36 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图
# Conflicts:
#	src/pages/calcTable/index.tsx
5 months ago
lys 3a6dd41f32 master 5 months ago
lys f4f209c998 Merge remote-tracking branch 'origin/feature/2.9.42310.01-薪资项目拓扑图' into feature/2.9.42310.01-薪资项目拓扑图
# Conflicts:
#	src/pages/atdTable/components/index.less
#	src/pages/calcTable/calcExplainFooter.tsx
5 months ago
lys 79cfecc766 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图
# Conflicts:
#	src/pages/atdTable/components/index.less
#	src/pages/calcTable/calcExplainFooter.tsx
5 months ago
lys e7f1958694 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图
# Conflicts:
#	src/pages/atdTable/components/index.less
#	src/pages/calcTable/calcExplainFooter.tsx
5 months ago
lys 069131b999 Merge branch 'master' into feature/业务线管理 5 months ago
lys 2de5be08d8 feature/2.9.42310.01-薪资项目拓扑图 6 months ago
lys 2c13ef67e7 feature/2.9.42310.01-薪资项目拓扑图 6 months ago
lys 6431c32e78 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 6 months ago
lys ef37ad4806 feature/2.9.42310.01-薪资项目拓扑图 7 months ago
lys 4ff9bda282 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 7 months ago
lys 9702881965 Merge branch 'master' into feature/业务线管理 7 months ago
lys 5f37df75cc feature/业务线管理 8 months ago
lys 7b95a64415 Merge branch 'master' into feature/业务线管理 8 months ago
lys 979a35dc54 Merge branch 'master' into feature/业务线管理 8 months ago
lys c1760af39d Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 8 months ago
lys fae2b93749 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 8 months ago
lys 597c00af41 Merge branch 'master' into feature/业务线管理
# Conflicts:
#	src/pages/unitTable/renderColsOpts.tsx
8 months ago
lys 4580128814 Merge branch 'master' into feature/业务线管理 8 months ago
lys 5bab142e05 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 8 months ago
lys 5b17d10230 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图
# Conflicts:
#	src/pages/calcTable/index.tsx
9 months ago
lys c86656f970 Merge branch 'master' into feature/业务线管理 9 months ago
lys d375704faf Merge branch 'master' into feature/业务线管理 9 months ago
lys caa31ad1ba feature/2.9.42310.01-薪资项目拓扑图 9 months ago
lys 1dbe38a87e Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图
# Conflicts:
#	src/pages/calcTable/customTableTitle.tsx
#	src/pages/calcTable/index.tsx
9 months ago
lys ad5c781bcb feature/2.9.42310.01-薪资项目拓扑图 9 months ago
lys 78faf02e22 样式修改 9 months ago
lys ee0eaf67ad Merge branch 'master' into feature/业务线管理 9 months ago
lys 7d8441749a Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 9 months ago
黎永顺 d82ca76290 Merge branch 'master' into feature/业务线管理
# Conflicts:
#	src/pages/salaryFileTable/index.tsx
#	src/pages/welfareArchiveTable/index.tsx
9 months ago
黎永顺 004bba38a8 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 9 months ago
黎永顺 3a5e06a6e7 Merge branch 'master' into feature/业务线管理
# Conflicts:
#	src/pages/salaryFileTable/index.tsx
#	src/pages/welfareArchiveTable/index.tsx
9 months ago
黎永顺 b72ccf78d7 Merge branch 'master' into feature/业务线管理 9 months ago
黎永顺 bba707b041 业务线管理 9 months ago
黎永顺 793d7acefb 业务线管理 10 months ago
黎永顺 9f21c7dc2e Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 10 months ago
黎永顺 3c4634dffd Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 11 months ago
黎永顺 e075344bca feature/2.9.42310.01-薪资项目拓扑图 11 months ago
黎永顺 52a45f38b3 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图
# Conflicts:
#	src/api/calculate.service.ts
#	src/pages/calcTable/index.tsx
11 months ago
黎永顺 22398469e5 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 1a9fbbe533 feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 5a37144950 feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 20c9897d06 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 ed0ff1d819 feature/2.9.42310.01-薪资项目拓扑图
图标显示优化
1 year ago
黎永顺 783ab813cb Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图
# Conflicts:
#	src/pages/calcTable/customTableTitle.tsx
1 year ago
黎永顺 cebb23b02e feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 70f452c19f Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 ca881157d6 feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 055e10296e feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 da70788569 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 1e028bb2ad feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 2708ff3dc5 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 db6bbd8bfa Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 7508a3a4b1 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 df75a3cdfa Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 14e25e6d2b Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 de2c10c400 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 30d225b4ed feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 992c85acf5 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 1 year ago
黎永顺 81a30417a9 feature/2.9.42310.01-薪资项目拓扑图
去掉固定根节点
2 years ago
黎永顺 f7cd8f8cbc feature/2.9.42310.01-薪资项目拓扑图 2 years ago
黎永顺 0229e27df5 feature/2.9.42310.01-薪资项目拓扑图 2 years ago
黎永顺 03d0e23191 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图
# Conflicts:
#	public/css/iconfont/demo_index.html
#	public/css/iconfont/iconfont.css
#	public/css/iconfont/iconfont.js
#	public/css/iconfont/iconfont.json
#	public/css/iconfont/iconfont.ttf
#	public/css/iconfont/iconfont.woff
#	public/css/iconfont/iconfont.woff2
#	src/pages/atdTable/components/index.less
#	src/pages/calcTable/calcExplainFooter.tsx
#	src/pages/calcTable/customTableTitle.tsx
2 years ago
黎永顺 7fc3c7538c feature/2.9.42310.01-薪资项目拓扑图
中江薪资核算列表表头修改
2 years ago
黎永顺 722e0b39db feature/2.9.42310.01-薪资项目拓扑图 2 years ago
黎永顺 042a962a2f feature/2.9.42310.01-薪资项目拓扑图 2 years ago
黎永顺 607f62b89e feature/2.9.42310.01-薪资项目拓扑图 2 years ago
黎永顺 33c7f9d270 添加线下对比表格 2 years ago
黎永顺 dba9cf3206 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 2 years ago
黎永顺 df5cee8255 feature/2.9.42310.01-薪资项目拓扑图以及中江的薪资账套下的图形展示 2 years ago
黎永顺 0ae7c8365c feature/2.9.42310.01-薪资项目拓扑图以及中江的薪资账套下的图形展示 2 years ago
黎永顺 4c3c2999be Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图
# Conflicts:
#	public/css/iconfont/demo_index.html
#	public/css/iconfont/iconfont.css
#	public/css/iconfont/iconfont.js
#	public/css/iconfont/iconfont.json
#	public/css/iconfont/iconfont.ttf
#	public/css/iconfont/iconfont.woff
#	public/css/iconfont/iconfont.woff2
2 years ago
黎永顺 ff6f036a38 feature/2.9.42310.01-薪资项目拓扑图以及中江的薪资账套下的图形展示 2 years ago
黎永顺 726e6c6715 Merge branch 'master' into feature/2.9.42310.01-薪资项目拓扑图 2 years ago
黎永顺 7b59ba7cf0 泛微薪资核算iframe表格-薪资项目拓扑图 2 years ago

@ -20,7 +20,9 @@
] ]
}, },
"dependencies": { "dependencies": {
"@ant-design/charts": "^1.4.2",
"@ant-design/pro-layout": "6.32.1", "@ant-design/pro-layout": "6.32.1",
"@antv/g6": "^4.8.17",
"@types/lodash": "^4.14.172", "@types/lodash": "^4.14.172",
"@wtto00/html2canvas": "^1.4.3", "@wtto00/html2canvas": "^1.4.3",
"@ztree/ztree_v3": "^3.5.42", "@ztree/ztree_v3": "^3.5.42",
@ -45,6 +47,7 @@
"react-fast-compare": "^3.2.0", "react-fast-compare": "^3.2.0",
"react-media": "^1.10.0", "react-media": "^1.10.0",
"react-sortable-hoc": "^2.0.0", "react-sortable-hoc": "^2.0.0",
"relation-graph": "^2.1.19",
"simple-query-string": "^1.3.2", "simple-query-string": "^1.3.2",
"solarlunar": "^2.0.7", "solarlunar": "^2.0.7",
"store": "^2.0.12", "store": "^2.0.12",

@ -78,6 +78,10 @@ class CalculateService extends BasicService {
getSyMixSum = async (params: any) => { getSyMixSum = async (params: any) => {
return this.post(`/api/bs/hrmsalary/siaccount/detail/list/syMixSum`, params); return this.post(`/api/bs/hrmsalary/siaccount/detail/list/syMixSum`, params);
}; };
//薪资项目拓扑图
getSalarysobItemTopology = async (params: any) => {
return this.post(`/api/bs/hrmsalary/salarysob/item/topology`, params);
};
//工资发放数据 //工资发放数据
getAcctresult = async (params: any) => { getAcctresult = async (params: any) => {
return this.post(`/api/bs/hrmsalary/salaryacct/acctresult/sjjtReport`, params); return this.post(`/api/bs/hrmsalary/salaryacct/acctresult/sjjtReport`, params);

@ -13,6 +13,9 @@ module.exports = {
"/reportTable.*": "blank", "/reportTable.*": "blank",
"/commonTable.*": "blank", "/commonTable.*": "blank",
"/calcTable.*": "blank", "/calcTable.*": "blank",
"/salaryItemDiagram.*": "blank",
"/ledgerSalaryItemDiagram.*": "blank",
"/salaryItemFlowGraph.*": "blank",
"/welfareLedgerTable.*": "blank", "/welfareLedgerTable.*": "blank",
"/payrollFilesTable.*": "blank", "/payrollFilesTable.*": "blank",
"/employeeDeclareTable.*": "blank", "/employeeDeclareTable.*": "blank",

@ -65,10 +65,10 @@ const OCTable: FC = (props) => {
<span>{excelResultValue}</span> <span>{excelResultValue}</span>
</div> </div>
{ {
showDifference && !!parseInt(calculateDifference(acctResultValue, excelResultValue || 0)) && showDifference &&
<div className={cs(styles["danger"], styles["comparison-single-row"])}> <div className={cs(styles["danger"], styles["comparison-single-row"])}>
<span>{lanObj["差值"]}</span> <span>{lanObj["差值"]}</span>
<span>{calculateDifference(acctResultValue, excelResultValue || 0)}</span> <span>{calculateDifference(acctResultValue, excelResultValue)}</span>
</div> </div>
} }
</div>; </div>;
@ -104,7 +104,7 @@ const OCTable: FC = (props) => {
return <Table return <Table
rowKey="id" className={styles.tableWrapper} rowKey="id" className={styles.tableWrapper}
columns={columns} dataSource={dataSource} bordered size="small" columns={columns} dataSource={dataSource} bordered size="small"
scroll={{ x: 1200, y: `calc(100vh - 165px)` }} scroll={{ x: 1200, y: `calc(100vh - 137px)` }}
pagination={{ pagination={{
...paginationFun(pageInfo, sizeChange, onChange, i18n), ...paginationFun(pageInfo, sizeChange, onChange, i18n),
size: "default" size: "default"

@ -0,0 +1,446 @@
import React, { FC, useEffect, useState } from "react";
import { exceptStr, paginationFun } from "@/utils/common";
import { defaultPage, ILoading, IPage } from "@/common/types/page";
import { Button, message, Spin, Table, Typography } from "antd";
import { LockOutlined, UnlockOutlined } from "@ant-design/icons";
import API from "@/api";
import styles from "./index.less";
const { Text } = Typography;
interface ITableProps {
}
const AntdTableColumns2: FC<ITableProps> = (props) => {
const [selected, setSelected] = useState<Array<string>>([]); //列表选中的数据
const [tab, setTab] = useState<string>(""); //顶部TAB变量
const [usertab, setUsertab] = useState<string>(""); //底部TAB变量
const [pageParams, setPageParams] = useState<IPage>(defaultPage); //分页变量
const [loading, setLoading] = useState<ILoading>({});
const [columns, setColumns] = useState<any[]>([]);
const [dataSource, setDataSource] = useState<any[]>([]);
const [sumRow, setSumRow] = useState<Partial<{}>>({});//薪资核算总计行数据
const [showSumrow, setShowSumrow] = useState<boolean>(false);//薪资核算总计行是否隐藏
useEffect(() => {
window.parent.postMessage(
{
type: "PC",
data: { id: "SA" }
},
"*"
);
window.addEventListener("message", receiveMessageFromIndex, false);
return () => {
setSumRow({});
window.removeEventListener("message", receiveMessageFromIndex, false);
};
}, []);
const getPCDataList = (params: any = {}) => {
let { type, listType, hasOperate = true, ...extraParams } = params;
setLoading({ query: true });
setTab(type);
setUsertab(listType);
API.CalculateService.getPCDataList(extraParams).then(async ({ success, data, errorMsg }) => {
setLoading({ query: false });
if (success) {
const { data: dataCopy } = data;
if (type === "PC") {
if (listType === "SA") {
const { columns = [], list = [], total, pageSize: size, pageNum } = dataCopy;
setColumns(getUserListColumns(columns));
setDataSource(list);
setPageParams({ ...pageParams, total, size, pageNum });
} else if (listType === "MA") {
const { columns = [], list = [], total, pageSize: size, pageNum } = dataCopy;
setColumns(columns);
setDataSource(list);
setPageParams({ ...pageParams, total, size, pageNum });
}
} else {
const { columns = [], columns2 = [], pageInfo = {} } = dataCopy;
const { list = [], total, pageSize: size, pageNum } = pageInfo;
setColumns(getColumns(columns2, hasOperate));
setDataSource(list);
setPageParams({ ...pageParams, total, size, pageNum });
const confCode: any = await API.CalculateService.getSysconfcode({ code: "OPEN_ACCT_RESULT_SUM" });
setShowSumrow(confCode.data.status && confCode.data.data === "1");
if (confCode.data.status && confCode.data.data === "1") {
const sumRowlist: any = await API.CalculateService.getAcctresultsum({ ...extraParams["queryParams"] });
if (sumRowlist.data.status && !_.isEmpty(sumRowlist.data.data.sumRow)) {
setSumRow(sumRowlist.data.data.sumRow);
}
if (sumRowlist.data.status && _.isNil(sumRowlist.data.data.sumRow)) {
setSumRow({ [new Date().getTime()]: new Date().getTime() });
}
}
}
} else {
message.error(errorMsg || "");
}
});
};
const getUserListColumns = (acctemployeeListColumns: any) => {
let tmpColumns = [...acctemployeeListColumns, {
key: "cz",
title: "操作",
render: (text: string, record: any) => {
return (
<Button type="link" style={{ padding: "0" }}
onClick={() => {
window.parent.postMessage(
{
type: "PC",
data: { id: "DELETE", data: record }
},
"*"
);
}}
>
</Button>
);
}
}];
tmpColumns = _.map(tmpColumns, (item) => {
if (item.dataIndex === "costCenter") {
return {
...item,
ellipsis: true,
width: 110,
render: (text: string, r: any) => {
const { costCenter } = r;
return (
<a href="javascript: void(0);" onClick={() => {
window.parent.postMessage(
{
type: "PC",
data: { id: "COSTCENTER", data: costCenter }
},
"*"
);
}}>{costCenter.name || ""}</a>
);
}
};
}
return { ...item, ellipsis: true };
});
return tmpColumns;
};
//薪资核算页面列表
const getColumns = (column: any, hasOperate: boolean = true) => {
let tmpColumns = [...column];
tmpColumns = tmpColumns.filter(item => item.hide == "FALSE").map((item, index) => {
let result = { ...item };
result.title = <span className={styles.titleWrapper}>
<span onClick={() => {
window.parent.postMessage(
{
type: "PR",
data: { id: "COLUMNINDEX", data: item.column }
},
"*"
);
}}>{item.text}</span>
{
item.lockStatus && <span className={styles.titleIcon}>
{
item.lockStatus === "UNLOCK" && <LockOutlined
title="点击锁定所有解锁的项目值"
onClick={() => {
window.parent.postMessage(
{
type: "PR",
data: { id: "COLUMNINDEX", data: item.column, extraId: "LOCK" }
},
"*"
);
}}
/>
}
{
item.lockStatus !== "UNLOCK" && <UnlockOutlined
title="点击解锁所有锁定的项目值"
onClick={() => {
window.parent.postMessage(
{
type: "PR",
data: { id: "COLUMNINDEX", data: item.column, extraId: "UNLOCK" }
},
"*"
);
}}
/>
}
</span>
}
</span>;
result.dataIndex = item.column;
result.oldWidth = result.width;
result.width = "150px";
result.ellipsis = true;
result.render = (text: string, r: any) => {
if (item.column === "costCenter") {
const { costCenter } = r;
return <a href="javascript: void(0);" onClick={() => {
window.parent.postMessage(
{
type: "PR",
data: { id: "COSTCENTER", data: costCenter }
},
"*"
);
}}>{!_.isEmpty(costCenter) ? costCenter.name : ""}</a>;
}
return <span className={styles.contentSpan}>
<span title={text} className={styles.contentTitle}>{text}</span>
{
result.lockStatus === "LOCK" ? <LockOutlined title="锁定的项目值"/> : null
}
</span>;
};
if (result.children) {
result.width = (result.children.length * 150) + "px";
result.children.map((child: any) => {
child.title = <span className={styles.titleWrapper}>
<span title={child.text} onClick={() => {
window.parent.postMessage(
{
type: "PR",
data: { id: "COLUMNINDEX", data: child.column }
},
"*"
);
}}>{child.text}</span>
{
child.lockStatus &&
<span className={styles.titleIcon}>
{
child.lockStatus === "UNLOCK" &&
<LockOutlined
title="点击锁定所有解锁的项目值"
onClick={() => {
window.parent.postMessage(
{
type: "PR",
data: { id: "COLUMNINDEX", data: child.column, extraId: "LOCK" }
},
"*"
);
}}
/>
}
{
child.lockStatus !== "UNLOCK" &&
<UnlockOutlined
title="点击解锁所有锁定的项目值"
onClick={() => {
window.parent.postMessage(
{
type: "PR",
data: { id: "COLUMNINDEX", data: child.column, extraId: "UNLOCK" }
},
"*"
);
}}
/>
}
</span>
}
</span>;
child.dataIndex = child.column;
child.width = "150px";
child.ellipsis = true;
child.render = (text: string) => {
return <span className={styles.contentSpan}>
<span title={text} className={styles.contentTitle}>{text}</span>
{
child.lockStatus === "LOCK" ? <LockOutlined title="锁定的项目值"/> : null
}
</span>;
};
if (child.children) {
child.children.map((grandSon: any) => {
grandSon.title = <span className={styles.titleWrapper}>
<span title={grandSon.text} onClick={() => {
window.parent.postMessage(
{
type: "PR",
data: { id: "COLUMNINDEX", data: grandSon.column }
},
"*"
);
}}>{grandSon.text}</span>
{
grandSon.lockStatus &&
<span className={styles.titleIcon}>
{
grandSon.lockStatus === "UNLOCK" &&
<LockOutlined
title="点击锁定所有解锁的项目值"
onClick={() => {
window.parent.postMessage(
{
type: "PR",
data: { id: "COLUMNINDEX", data: grandSon.column, extraId: "LOCK" }
},
"*"
);
}}
/>
}
{
grandSon.lockStatus !== "UNLOCK" &&
<UnlockOutlined
title="点击解锁所有锁定的项目值"
onClick={() => {
window.parent.postMessage(
{
type: "PR",
data: { id: "COLUMNINDEX", data: grandSon.column, extraId: "UNLOCK" }
},
"*"
);
}}
/>
}
</span>
}
</span>;
grandSon.dataIndex = grandSon.column;
grandSon.width = "150px";
grandSon.ellipsis = true;
grandSon.render = (text: string) => {
return <span className={styles.contentSpan}>
<span title={text} className={styles.contentTitle}>{text}</span>
{
grandSon.lockStatus === "LOCK" ? <LockOutlined title="锁定的项目值"/> : null
}
</span>;
};
});
}
});
}
if (index < 3) {
result.fixed = "left";
result.render = (text: string) => {
return <span title={text}>{text}</span>;
};
}
return result;
});
hasOperate && tmpColumns.push({
title: "操作",
key: "cz",
width: "100px",
fixed: "right",
render: (text: string, record: any) => {
return <Button type="link" style={{ padding: "0" }} onClick={() => {
window.parent.postMessage(
{
type: "PR",
data: { id: "EDIT", data: record }
},
"*"
);
}}></Button>;
}
});
return tmpColumns;
};
const receiveMessageFromIndex = (event: any) => {
setDataSource([]);
const data: any = exceptStr(event.data);
if (!_.isEmpty(data)) {
const { selectedRowKeys, ...extraData } = data;
getPCDataList({ ...extraData, ...pageParams });
if (selectedRowKeys) setSelected(selectedRowKeys);
}
};
const sizeChange = (pageobj: IPage) => {
};
const onChange = (pageobj: IPage) => {
setPageParams({ ...pageParams, ...pageobj });
window.parent.postMessage(
{
type: tab,
data: { id: "PAGEINFO", extraId: usertab, data: { ...pageParams, ...pageobj } }
},
"*"
);
};
const rowSelection = {
selectedRowKeys: selected,
onChange: (selectedRowKeys: Array<any>) => {
setSelected(selectedRowKeys);
window.parent.postMessage(
{
type: tab,
data: { id: "BATCHDELETE", extraId: usertab, data: selectedRowKeys }
},
"*"
);
}
};
return <Table
rowKey="id"
loading={loading.query}
className={styles.tableWrapper}
columns={columns}
dataSource={dataSource}
size="small"
bordered
// rowSelection={tab === "PC" && usertab === "SA" ? rowSelection : undefined}
rowSelection={rowSelection}
pagination={{
...paginationFun(pageParams, sizeChange, onChange),
size: "default"
}}
scroll={{
x: "calc(700px + 50%)",
y: tab !== "PR" ? "calc(100vh - 96px)" : !_.isEmpty(sumRow) ? "calc(100vh - 192px)" : "calc(100vh - 156px)"
}}
summary={() => {
if (tab !== "PR" || !showSumrow) return;
let totalColumns: any[] = [];
_.forEach(columns, it => {
if (_.isEmpty(it.children)) {
totalColumns.push(it);
} else {
_.forEach(it.children, gt => {
if (_.isEmpty(gt.children)) {
totalColumns.push(gt);
} else {
totalColumns = [...totalColumns, ...gt.children];
}
});
}
});
return (
<Table.Summary fixed>
<Table.Summary.Row>
{
_.isEmpty(sumRow) ? <Spin tip="加载中"/> :
_.map([{}, ...totalColumns], (item, index) => {
if (index === 0) {
return <Table.Summary.Cell index={0} align="center"><Text
type="danger"></Text></Table.Summary.Cell>;
}
return <Table.Summary.Cell index={index} key={index}>
<Text type="danger">{sumRow[item.dataIndex] || "-"}</Text>
</Table.Summary.Cell>;
})
}
</Table.Summary.Row>
</Table.Summary>
);
}}
/>;
};
export default AntdTableColumns2;

@ -26,6 +26,12 @@
} }
} }
.contentSpan:hover {
.diagramIcon {
display: block;
}
}
.contentSpan { .contentSpan {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@ -40,8 +46,20 @@
word-break: keep-all; word-break: keep-all;
} }
.diagramIcon {
color: #5d9cec;
cursor: pointer;
display: none;
}
:global { :global {
span.anticon {
color: #5d9cec;
cursor: pointer;
}
span.anticon-lock, span.anticon-question-circle { span.anticon-lock, span.anticon-question-circle {
margin-left: 4px;
color: #5d9cec; color: #5d9cec;
} }
} }

@ -1,9 +1,9 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import AntdTable from './components/antdTable'; import AntdTableColumns2 from './components/antdTable';
const AtdTable: FC = (props) => { const AtdTable: FC = (props) => {
return <AntdTable /> return <AntdTableColumns2 />
}; };
export default AtdTable; export default AtdTable;

@ -35,6 +35,10 @@ const CalcExplainFooter: FunctionComponent<Props> = (props) => {
<span>{i18n["反馈信息,右击删除反馈信息"] || i18n["反馈信息,右击设置反馈信息"]}</span> <span>{i18n["反馈信息,右击删除反馈信息"] || i18n["反馈信息,右击设置反馈信息"]}</span>
</div> </div>
)} )}
<div className={styles["icon-item"]}>
<Icon type="icon-piliangfenpei"/>
<span>{i18n["查看拓扑图"]}</span>
</div>
<div className={styles["icon-item"]}> <div className={styles["icon-item"]}>
<Icon type="icon-pilianggengxin"/> <Icon type="icon-pilianggengxin"/>
<span>{i18n["批量更新"]}</span> <span>{i18n["批量更新"]}</span>

@ -37,6 +37,7 @@ const customTableTitle: FunctionComponent<Props> = (props) => {
<div className={styles["toogle-lock-tool"]}> <div className={styles["toogle-lock-tool"]}>
<Icon type="icon-piliangsuoding" title={i18n["点击锁定所有解锁的项目值"]} onClick={() => handleToggleSalaryItemVal(dataIndex as string, "LOCK")} /> <Icon type="icon-piliangsuoding" title={i18n["点击锁定所有解锁的项目值"]} onClick={() => handleToggleSalaryItemVal(dataIndex as string, "LOCK")} />
<Icon type="icon-piliangjiesuo" title={i18n["点击解锁所有锁定的项目值"]} onClick={() => handleToggleSalaryItemVal(dataIndex as string, "UNLOCK")} /> <Icon type="icon-piliangjiesuo" title={i18n["点击解锁所有锁定的项目值"]} onClick={() => handleToggleSalaryItemVal(dataIndex as string, "UNLOCK")} />
<Icon type="icon-piliangfenpei" title={i18n["查看拓扑图"]} onClick={() => handleToggleSalaryItemVal(dataIndex as string, "DIAGRAM")} />
<Icon type="icon-pilianggengxin" title={i18n["批量更新"]} onClick={() => handleToggleSalaryItemVal(dataIndex as string, "BATCHUPDATE", { pattern, salaryItemName: title, dataType })} /> <Icon type="icon-pilianggengxin" title={i18n["批量更新"]} onClick={() => handleToggleSalaryItemVal(dataIndex as string, "BATCHUPDATE", { pattern, salaryItemName: title, dataType })} />
</div> </div>
)} )}

@ -15,6 +15,7 @@ import type { ColumnType } from "antd/lib/table";
import type { PaginationData } from "rc-pagination"; import type { PaginationData } from "rc-pagination";
import { exceptStr, paginationFun } from "@/utils/common"; import { exceptStr, paginationFun } from "@/utils/common";
import { IPage } from "@/common/types"; import { IPage } from "@/common/types";
import Icon from "../../lib/CustomIcon";
import styles from "@/pages/atdTable/components/index.less"; import styles from "@/pages/atdTable/components/index.less";
interface OwnProps {} interface OwnProps {}
@ -201,6 +202,7 @@ const index: FunctionComponent<Props> = (props) => {
<span title={text} className={styles.contentTitle} style={{ color: `${record?.[item.dataIndex + "_color"]}` }}> <span title={text} className={styles.contentTitle} style={{ color: `${record?.[item.dataIndex + "_color"]}` }}>
{text} {text}
</span> </span>
<Icon type="icon-piliangfenpei" title={i18n["查看拓扑图"]} className={styles.diagramIcon} onClick={() => handleDiagramTd(item?.dataIndex, record?.id)} />
{record.lockItems && record.lockItems.includes(item.dataIndex) ? <LockOutlined title={item.i18n["锁定的项目值"]} /> : null} {record.lockItems && record.lockItems.includes(item.dataIndex) ? <LockOutlined title={item.i18n["锁定的项目值"]} /> : null}
{!_.isEmpty(record[`${item.dataIndex}_feedback`]) ? ( {!_.isEmpty(record[`${item.dataIndex}_feedback`]) ? (
<Tooltip title={record[`${item.dataIndex}_feedback`]}> <Tooltip title={record[`${item.dataIndex}_feedback`]}>
@ -218,6 +220,9 @@ const index: FunctionComponent<Props> = (props) => {
const handleFormulaTd = (dataIndex: string) => { const handleFormulaTd = (dataIndex: string) => {
window.parent.postMessage({ type: "turn", payload: { id: "FORMULA", params: { dataIndex } } }, "*"); window.parent.postMessage({ type: "turn", payload: { id: "FORMULA", params: { dataIndex } } }, "*");
}; };
const handleDiagramTd = (salaryItemId: string, acctEmpId: string) => {
window.parent.postMessage({ type: "turn", payload: { id: "DIAGRAM", params: { salaryItemId, acctEmpId } } }, "*");
};
const handleEdit = (id: string, showSee: boolean) => { const handleEdit = (id: string, showSee: boolean) => {
window.parent.postMessage({ type: "turn", payload: { id: "EDIT", params: { id, showSee } } }, "*"); window.parent.postMessage({ type: "turn", payload: { id: "EDIT", params: { id, showSee } } }, "*");
}; };

@ -24,29 +24,30 @@ const CommonTable: FC = (props) => {
const receiveMessageFromIndex = (event: any) => { const receiveMessageFromIndex = (event: any) => {
const data: any = exceptStr(event.data); const data: any = exceptStr(event.data);
if (!_.isEmpty(data)) { if (!_.isEmpty(data)) {
const { columns, dataSource, pageInfo, i18n, selectedRowKeys, selectedKey } = data; const { columns, dataSource, pageInfo, i18n, selectedRowKeys, selectedKey, azOperate = true } = data;
const { current: pageNum, pageSize: size, total } = pageInfo; const { current: pageNum, pageSize: size, total } = pageInfo;
setDataSource(dataSource); setDataSource(dataSource);
setI18n(i18n); setI18n(i18n);
setPageInfo({ pageNum, size, total }); setPageInfo({ pageNum, size, total });
setSelected(selectedRowKeys); setSelected(selectedRowKeys);
setColumns([ setColumns(azOperate ? [
...columns, ...columns,
{ {
title: i18n["操作"], title: i18n["操作"],
dataIndex: "operate", dataIndex: "operate",
fixed: "right", fixed: "right",
width: 120, width: 140,
render: (_: any, record: any) => { render: (_: any, record: any) => {
return selectedKey === "list" ? ( return selectedKey === "list" ? (
<Space> <Space>
<Button type="link" onClick={() => handleEdit(record)}>{i18n["编辑"]}</Button> <Button type="link" onClick={() => handleEdit(record)}>{i18n["编辑"]}</Button>
<Button type="link" onClick={() => handleDelete(record)}>{i18n["删除"]}</Button> <Button type="link" onClick={() => handleDelete(record)}>{i18n["删除"]}</Button>
<Button type="link" onClick={() => handleVoid(record)}>{i18n["作废"]}</Button>
</Space> </Space>
) : null; ) : null;
} }
} }
]); ] : columns);
} }
}; };
const handleEdit = (record: any) => { const handleEdit = (record: any) => {
@ -55,6 +56,9 @@ const CommonTable: FC = (props) => {
const handleDelete = (record: any) => { const handleDelete = (record: any) => {
window.parent.postMessage({ type: "turn", payload: { id: "DELETE", params: { ...record } } }, "*"); window.parent.postMessage({ type: "turn", payload: { id: "DELETE", params: { ...record } } }, "*");
}; };
const handleVoid = (record: any) => {
window.parent.postMessage({ type: "turn", payload: { id: "VOID", params: { ...record } } }, "*");
};
const sizeChange = (pageobj: IPage) => { const sizeChange = (pageobj: IPage) => {
}; };
const onChange = (pageobj: IPage) => { const onChange = (pageobj: IPage) => {

@ -0,0 +1,123 @@
/*
* Author:
* name: -
* Description:
* Date: 2023/11/30
*/
import type { MutableRefObject } from "react";
import React, { useEffect, useMemo, useRef, useState } from "react";
import { notification } from "antd";
// @ts-ignore
import type { RelationGraphExpose, RGNode, RGNodeSlotProps, RGOptions } from "relation-graph/react";
// @ts-ignore
import RelationGraph from "relation-graph/react";
import { exceptStr } from "@/utils/common";
import { extractTree } from "@/pages/salaryItemDiagram";
import cs from "classnames";
import styles from "../salaryItemFlowGraph/index.less";
const NodeSlot: React.FC<RGNodeSlotProps> = ({ node }) => {
if (node.id === "0") {
return <div className={styles.rootNode}> {node.text} </div>;
}
// @ts-ignore
if (node.id !== "0" && !node.data.parentId) {
return <div className={cs(styles.levelNode, styles.commonNode)}> {node.text} </div>;
}
return <div className={styles.commonNode}>
<span title={node.text}>{node.text}</span>
</div>;
};
const Index: React.FC = () => {
const [itemsTree, setItemsTree] = useState<any[]>([]);
const [i18n, setI18n] = useState<any>({});
const graphRef = useRef() as MutableRefObject<RelationGraphExpose>;
useEffect(() => {
window.parent.postMessage({ type: "initDiagram" }, "*");
window.addEventListener("message", receiveMessageFromIndex, false);
return () => {
window.removeEventListener("message", receiveMessageFromIndex, false);
};
}, []);
const receiveMessageFromIndex = (event: any) => {
const data: any = exceptStr(event.data);
if (!_.isEmpty(data)) {
const { itemsTree, i18n } = data;
setI18n(i18n);
setItemsTree(itemsTree);
}
};
const dataSource: any = useMemo(() => {
return {
rootId: "0",
// { id: "0", text: i18n["薪资项目"] },
nodes: [..._.map(extractTree(itemsTree), o => ({
id: o.salaryItemId,
text: o.salaryItemName, data: { ...o }
}))],
lines: _.map(extractTree(itemsTree), o => ({
from: o.parentId ? o.parentId : "0",
to: o.salaryItemId
})).filter(g => g.from !== "0")
};
}, [itemsTree, i18n]);
useEffect(() => {
if (!_.isEmpty(dataSource.nodes)) {
const init = showGraph();
}
}, [dataSource]);
const showGraph = async () => {
await graphRef.current.setJsonData(dataSource, () => {
});
};
const options: RGOptions = useMemo(() => {
return {
debug: false,
layout: {
label: "树",
layoutName: "tree",
layoutClassName: "seeks-layout-center",
from: "left",
// 通过这4个属性来调整 tree-层级距离&节点距离
min_per_width: 500,
max_per_width: 500,
min_per_height: 60,
max_per_height: undefined
// levelDistance: "" // 如果此选项有值则优先级高于上面那4个选项
},
defaultExpandHolderPosition: "right",
defaultNodeWidth: 180,
defaultNodeHeight: 50,
defaultLineShape: 4,
defaultNodeBorderWidth: 1,
defaultLineColor: "#333",
defaultExpandHolderColor: "rgba(0, 206, 209, 1)",
defaultNodeColor: "transparent",
defaultNodeBorderColor: "#333",
allowShowMiniToolBar: false //工具栏展示与否
};
}, []);
const onNodeClick = (node: RGNode) => {
if (node.type === "node") {
// @ts-ignore
const { formula } = node?.data;
notification.destroy();
if (_.isEmpty(formula)) return;
const { formula: description } = formula;
notification.open({
message: i18n["公式"],
duration: 5,
description,
style: { maxWidth: 600 }
});
}
return true;
};
return <div style={{ height: "100%", width: "100%" }}>
<RelationGraph ref={graphRef} options={options} nodeSlot={NodeSlot}
// @ts-ignore
onNodeClick={onNodeClick}
/>
</div>;
};
export default Index;

@ -24,9 +24,7 @@ const Index: FunctionComponent<Props> = (props) => {
const [pageInfo, setPageInfo] = useState<Partial<PaginationData>>({}); const [pageInfo, setPageInfo] = useState<Partial<PaginationData>>({});
const [i18n, setI18n] = useState<any>({}); const [i18n, setI18n] = useState<any>({});
const [runStatuses, setRunStatuses] = useState<string>(""); const [runStatuses, setRunStatuses] = useState<string>("");
const [showOperateBtn, setShowOperateBtn] = useState<boolean>(false);
const [showDelSalaryFileBtn, setShowDelSalaryFileBtn] = useState<boolean>(false);//待定薪、停薪员工 是否允许删除薪资档案 const [showDelSalaryFileBtn, setShowDelSalaryFileBtn] = useState<boolean>(false);//待定薪、停薪员工 是否允许删除薪资档案
const [DCChiefPermission, setDCChiefPermission] = useState<undefined>(undefined);//二开权限(大成)
useEffect(() => { useEffect(() => {
window.parent.postMessage({ type: "init" }, "*"); window.parent.postMessage({ type: "init" }, "*");
@ -40,10 +38,8 @@ const Index: FunctionComponent<Props> = (props) => {
const data: any = exceptStr(event.data); const data: any = exceptStr(event.data);
if (!_.isEmpty(data)) { if (!_.isEmpty(data)) {
const { const {
columns, dataSource, pageInfo, selectedRowKeys: rowKeys = [], i18n: i18nRes = {}, columns, dataSource, pageInfo, selectedRowKeys: rowKeys = [], i18n: i18nRes = {}, selectedKey, showDelSalaryFileBtn
selectedKey, showOperateBtn, showDelSalaryFileBtn, DCChiefPermission
} = data; } = data;
setShowOperateBtn(showOperateBtn);
setRunStatuses(selectedKey); setRunStatuses(selectedKey);
setI18n(i18nRes); setI18n(i18nRes);
setPageInfo(pageInfo); setPageInfo(pageInfo);
@ -51,7 +47,6 @@ const Index: FunctionComponent<Props> = (props) => {
setSelectedRowKeys([...rowKeys, ...selectedRowKeys]); setSelectedRowKeys([...rowKeys, ...selectedRowKeys]);
setColumns(columns); setColumns(columns);
setShowDelSalaryFileBtn(showDelSalaryFileBtn); setShowDelSalaryFileBtn(showDelSalaryFileBtn);
setDCChiefPermission(DCChiefPermission);
} }
}; };
const onChange = (current: number, pageSize: number) => { const onChange = (current: number, pageSize: number) => {
@ -113,19 +108,30 @@ const Index: FunctionComponent<Props> = (props) => {
} }
]; ];
!showDelSalaryFileBtn && (items = _.dropRight(items)); !showDelSalaryFileBtn && (items = _.dropRight(items));
return (<Space> return (
{ record?.opts.includes("admin") ?
(_.isNil(DCChiefPermission) || DCChiefPermission) ? <Space>
<Button type="link" <Button type="link"
onClick={() => handleSalaryFileOperate("EDIT", record)}>{i18n["编辑"]}</Button> : onClick={() => handleSalaryFileOperate("EDIT", record)}>{i18n["编辑"]}</Button>
<Button type="link" onClick={() => handleSalaryFileOperate("VIEW", record)}>{i18n["查看"]}</Button>
}
<Button type="link" <Button type="link"
onClick={() => handleSalaryFileOperate("ADD-TO-SALARYPAYMENT", record, [record?.id])}>{i18n["设为发薪人员"]}</Button> onClick={() => handleSalaryFileOperate("ADD-TO-SALARYPAYMENT", record, [record?.id])}>{i18n["设为发薪人员"]}</Button>
<Dropdown menu={{ items }} placement="bottomRight"> <Dropdown menu={{ items }} placement="bottomRight">
<Button type="link" icon={<MoreOutlined/>}/> <Button type="link" icon={<MoreOutlined/>}/>
</Dropdown> </Dropdown>
</Space>); </Space> : <Space>
<Button type="link"
onClick={() => handleSalaryFileOperate("VIEW", record)}>{i18n["查看"]}</Button>
<Dropdown menu={{
items: [
{
key: "Log", label: i18n["操作日志"], onClick: () => handleSalaryFileOperate("log", record)
}
]
}} placement="bottomRight">
<Button type="link" icon={<MoreOutlined/>}/>
</Dropdown>
</Space>
);
} }
}; };
break; break;
@ -142,15 +148,24 @@ const Index: FunctionComponent<Props> = (props) => {
} }
]; ];
return ( return (
record?.opts.includes("admin") ?
<Space> <Space>
{
(((_.isNil(DCChiefPermission) || DCChiefPermission) && runStatuses === "fixed") || runStatuses === "ext") ?
<Button type="link" <Button type="link"
onClick={() => handleSalaryFileOperate("CHANGE-SALARY", record)}>{i18n["调薪"]}</Button> : onClick={() => handleSalaryFileOperate("CHANGE-SALARY", record)}>{i18n["调薪"]}</Button>
<Dropdown menu={{ items }} placement="bottomRight">
<Button type="link" icon={<MoreOutlined/>}/>
</Dropdown>
</Space> :
<Space>
<Button type="link" <Button type="link"
onClick={() => handleSalaryFileOperate("VIEW", record)}>{i18n["查看"]}</Button> onClick={() => handleSalaryFileOperate("VIEW", record)}>{i18n["查看"]}</Button>
<Dropdown menu={{
items: [
{
key: "Log", label: i18n["操作日志"], onClick: () => handleSalaryFileOperate("log", record)
} }
<Dropdown menu={{ items }} placement="bottomRight"> ]
}} placement="bottomRight">
<Button type="link" icon={<MoreOutlined/>}/> <Button type="link" icon={<MoreOutlined/>}/>
</Dropdown> </Dropdown>
</Space> </Space>
@ -174,14 +189,30 @@ const Index: FunctionComponent<Props> = (props) => {
onClick: () => handleSalaryFileOperate("log", record) onClick: () => handleSalaryFileOperate("log", record)
} }
]; ];
return (<Space> return (
record?.opts.includes("admin") ?
<Space>
<Button type="link" onClick={() => handleSalaryFileOperate("EDIT", record)}>{i18n["编辑"]}</Button> <Button type="link" onClick={() => handleSalaryFileOperate("EDIT", record)}>{i18n["编辑"]}</Button>
<Button type="link" <Button type="link"
onClick={() => handleSalaryFileOperate("SALARY-SUSPENSION", record, [record?.id])}>{i18n["停薪"]}</Button> onClick={() => handleSalaryFileOperate("SALARY-SUSPENSION", record, [record?.id])}>{i18n["停薪"]}</Button>
<Dropdown menu={{ items: downsizingItems }} placement="bottomRight"> <Dropdown menu={{ items: downsizingItems }} placement="bottomRight">
<Button type="link" icon={<MoreOutlined/>}/> <Button type="link" icon={<MoreOutlined/>}/>
</Dropdown> </Dropdown>
</Space>); </Space> :
<Space>
<Button type="link"
onClick={() => handleSalaryFileOperate("VIEW", record)}>{i18n["查看"]}</Button>
<Dropdown menu={{
items: [
{
key: "Log", label: i18n["操作日志"], onClick: () => handleSalaryFileOperate("log", record)
}
]
}} placement="bottomRight">
<Button type="link" icon={<MoreOutlined/>}/>
</Dropdown>
</Space>
);
} }
}; };
break; break;
@ -190,19 +221,21 @@ const Index: FunctionComponent<Props> = (props) => {
...opts, ...opts,
render: (__: any, record: any) => { render: (__: any, record: any) => {
let stopItems: MenuProps["items"] = [ let stopItems: MenuProps["items"] = [
{
key: "Log",
label: i18n["操作日志"],
onClick: () => handleSalaryFileOperate("log", record)
},
{ {
key: "CancelSuspension", key: "CancelSuspension",
label: i18n["删除档案"], label: i18n["删除档案"],
onClick: () => handleSalaryFileOperate("DEL-SALARY-FILES", record, [record?.id]) onClick: () => handleSalaryFileOperate("DEL-SALARY-FILES", record, [record?.id])
},
{
key: "Log",
label: i18n["操作日志"],
onClick: () => handleSalaryFileOperate("log", record)
} }
]; ];
!showDelSalaryFileBtn && (stopItems = _.dropRight(stopItems)); !showDelSalaryFileBtn && (stopItems = _.dropRight(stopItems));
return (<Space> return (
record?.opts.includes("admin") ?
<Space>
<Button type="link" onClick={() => handleSalaryFileOperate("VIEW", record)}>{i18n["查看"]}</Button> <Button type="link" onClick={() => handleSalaryFileOperate("VIEW", record)}>{i18n["查看"]}</Button>
<Button type="link" <Button type="link"
onClick={() => handleSalaryFileOperate("CANCEL-SALARY-SUSPENSION", record, [record?.id])}>{i18n["取消停薪"]}</Button> onClick={() => handleSalaryFileOperate("CANCEL-SALARY-SUSPENSION", record, [record?.id])}>{i18n["取消停薪"]}</Button>
@ -212,32 +245,32 @@ const Index: FunctionComponent<Props> = (props) => {
<Button type="link" icon={<MoreOutlined/>}/> <Button type="link" icon={<MoreOutlined/>}/>
</Dropdown> </Dropdown>
} }
</Space>); </Space> :
<Space>
<Button type="link"
onClick={() => handleSalaryFileOperate("VIEW", record)}>{i18n["查看"]}</Button>
<Dropdown menu={{
items: [
{
key: "Log", label: i18n["操作日志"], onClick: () => handleSalaryFileOperate("log", record)
}
]
}} placement="bottomRight">
<Button type="link" icon={<MoreOutlined/>}/>
</Dropdown>
</Space>
);
} }
}; };
break; break;
default: default:
break; break;
} }
return showOperateBtn ? [..._.filter(columns, o => o.dataIndex !== "operate"), opts] : return [..._.filter(columns, o => o.dataIndex !== "operate"), opts];
[..._.filter(columns, o => o.dataIndex !== "operate"), {
...opts,
render: (__: any, record: any) => (
<Space>
{
(DCChiefPermission && (runStatuses === "pending" || runStatuses === "fixed")) ?
<Button type="link"
onClick={() => handleSalaryFileOperate(runStatuses === "fixed" ? "CHANGE-SALARY" : "EDIT", record)}>{runStatuses === "fixed" ? i18n["调薪"] : i18n["编辑"]}</Button> :
<Button type="link" onClick={() => handleSalaryFileOperate("VIEW", record)}>{i18n["查看"]}</Button>
}
<Button type="link" onClick={() => handleSalaryFileOperate("log", record)}>{i18n["操作日志"]}</Button>
</Space>
)
}];
} else { } else {
return []; return [];
} }
}, [columns, runStatuses, i18n, showOperateBtn, showDelSalaryFileBtn, DCChiefPermission]); }, [columns, runStatuses, i18n, showDelSalaryFileBtn]);
return (<Table return (<Table
rowKey="id" size="small" className={styles.tableWrapper} rowKey="id" size="small" className={styles.tableWrapper}
columns={cols} dataSource={dataSource} rowSelection={rowSelection} columns={cols} dataSource={dataSource} rowSelection={rowSelection}

@ -0,0 +1,125 @@
export const data = {
id: "root",
label: "利息收入",
subLabel: "3,283.456",
ratio: 3,
children: [
{
id: "child-a",
label: "平均利息",
subLabel: "9%",
ratio: 1,
increase: true
},
{
id: "child-b",
label: "贷款余额",
subLabel: "1,789,567",
ratio: 23,
increase: true,
children: [
{
id: "child-b-a",
label: "投放金额",
subLabel: "2,385,124",
ratio: 17,
increase: true,
operator: ""
},
{
id: "child-b-b",
label: "还款金额",
subLabel: "595,557",
ratio: 12,
increase: true,
children:[
{
id: 'child-b-b-a',
label: '还款期限',
subLabel: '7',
ratio: 23,
increase: true,
children:[
{
id: "child-b-b-a-a",
label: "还款金额",
subLabel: "595,557",
ratio: 12,
increase: true,
children:[
{
id: "child-b-b-a-a-a",
label: "还款金额",
subLabel: "595,557",
ratio: 12,
increase: true,
children:[
{
id: "child-b-b-a-a-a-a",
label: "还款金额",
subLabel: "595,557",
ratio: 12,
increase: true,
children:[
{
id: "child-b-b-a-a-a-a-a",
label: "还款金额",
subLabel: "595,557",
ratio: 12,
increase: true,
children:[
{
id: "child-b-b-a-a-a-a-a-a",
label: "还款金额",
subLabel: "595,557",
ratio: 12,
increase: true,
children:[
{
id: "child-b-b-a-a-a-a-a-a-a",
label: "还款金额",
subLabel: "595,557",
ratio: 12,
increase: true,
children:[
{
id: "child-b-b-a-a-a-a-a-a-a-a",
label: "还款金额",
subLabel: "595,557",
ratio: 12,
increase: true,
}
]
}
]
}
]
}
]
}
]
}
]
}
]
},
{
id: 'child-b-b-6',
label: '还款期限',
subLabel: '7',
ratio: 23,
increase: true,
}
]
}
]
},
{
id: "child-c",
label: "还款期限",
subLabel: "7",
ratio: 23,
increase: false
}
]
};

@ -0,0 +1,156 @@
/*
* Author:
* name: -
* Description:
* Date: 2023/10/19
*/
import React, { FunctionComponent, useEffect, useRef } from "react";
// @ts-ignore
import G6 from "@antv/g6";
import API from "@/api";
// @ts-ignore
import uuidV4 from "uuid/v4";
import "./registerShape";
interface OwnProps {
}
type Props = OwnProps;
const index: FunctionComponent<Props> = (props) => {
const ref: any = useRef(null);
let graph: any = null;
useEffect(() => {
initG6().then(r => {
});
return () => {
};
}, []);
// 1688699208883
const initG6 = async () => {
const { data: { data: result } }: any = await API.CalculateService.getSalarysobItemTopology({
salarySobId: "31",
salaryItemId: "1688699208872"
});
const dataSource = {
id: result.salaryItemId.toString(), label: result.salaryItemName || "",
subLabel: result.result || "", formula: result.formula, level: 0,
children: !_.isEmpty(result.children) ? traverse(result.children) : []
};
const width = ref.current.scrollWidth;
const height = ref.current.scrollHeight;
// @ts-ignore
G6.Util.traverseTree(dataSource, (subtree: any) => {
// if (subtree.level === undefined) subtree.level = 0;
// subtree.children?.forEach((child: any) => child.level = subtree.level + 1);
switch (subtree.level) {
case 0:
subtree.type = "root";
break;
case 1:
subtree.type = "level1node";
// subtree.collapsed = true;
break;
default:
subtree.type = "othernode";
}
});
if (!graph) {
graph = new G6.TreeGraph({
// fitCenter: true, linkCenter: true,
container: ref.current, width, height, fitView: true,
layout: {
// LR
type: "compactBox", direction: "LR", getHGap: function getVGap() {
return 5;
}
},
defaultEdge:
// {
// type: "cubic-vertical",
// style: {
// stroke: "#A3B1BF"
// }
// },
{
type: "round-poly",
sourceAnchor: 0,
targetAnchor: 1,
style: {
radius: 8,
stroke: "rgb(19, 33, 92)"
}
},
defaultNode: {
style: {
cursor: "pointer"
},
// anchorPoints: [
// [0.5, 0],
// [0.5, 1]
// ]
anchorPoints: [
[0.9, 0.5],
[0, 0.5]
]
},
nodeStateStyles: {
hover: {
fill: "#fff",
shadowBlur: 30,
shadowColor: "#ddd"
},
operatorhover: {
"operator-box": {
opacity: 1
}
}
},
modes: {
default: ["zoom-canvas", "drag-canvas", "collapse-expand", "drag-node"]
}
});
}
graph.data(dataSource);
graph.render();
graph.on("node:mouseenter", (e: any) => {
if (e.target.get("name")?.includes("operator")) {
graph.setItemState(e.item, "operatorhover", true);
} else {
graph.setItemState(e.item, "hover", true);
}
});
graph.on("node:mouseleave", (e: any) => {
graph.setItemState(e.item, "operatorhover", false);
graph.setItemState(e.item, "hover", false);
});
graph.on("node:click", (e: any) => {
// graph.zoom(3, { x: e.canvasX, y: e.canvasY });
});
};
return (<div ref={ref} style={{ width: "100%", height: "100%" }}/>);
};
export default index;
const traverse: any = (arr: any[]) => {
return _.map(arr, item => {
if (!_.isEmpty(item.children)) {
const uuid = uuidV4();
return {
id: uuid, label: item.salaryItemName,
subLabel: item.result, formula: item.formula,
ratio: 1, increase: true, level: 1, collapsed: true,
children: traverse(item.children)
};
} else {
const uuid = uuidV4();
return {
id: uuid, label: item.salaryItemName,
subLabel: item.result, formula: item.formula,
ratio: 1, increase: true, level: 2
};
}
});
};

@ -0,0 +1,192 @@
/*
* Author:
* name: -
* Description:
* Date: 2023/10/19
*/
import React, { FunctionComponent, useEffect, useMemo, useState } from "react";
import { DecompositionTreeGraph, NodeConfig } from "@ant-design/graphs";
import { notification } from "antd";
import { exceptStr } from "@/utils/common";
import API from "@/api";
// @ts-ignore
import uuidV4 from "uuid/v4";
interface OwnProps {
}
type Props = OwnProps;
const index: FunctionComponent<Props> = (props) => {
const [dataSource, setDataSource] = useState<any>({});
const [i18n, setI18n] = useState<any>({});
useEffect(() => {
window.parent.postMessage({ type: "initDiagram" }, "*");
window.addEventListener("message", receiveMessageFromIndex, false);
return () => {
window.removeEventListener("message", receiveMessageFromIndex, false);
};
}, []);
const receiveMessageFromIndex = (event: any) => {
const data: any = exceptStr(event.data);
if (!_.isEmpty(data)) {
const { i18n, acctEmpId, salaryItemId, salarySobId } = data;
setI18n(i18n);
init({ acctEmpId, salaryItemId, salarySobId });
}
};
const init = (paylaod: any) => {
API.CalculateService.getSalarysobItemTopology(paylaod).then(({ data }) => {
const { status, data: result } = data;
if (status) {
const dataSource = {
id: result.salaryItemId.toString(),
value: { title: result.salaryItemName, formula: result.formula, items: [{ text: result.result }] },
children: !_.isEmpty(result.children) ? traverse(result.children) : []
};
setDataSource(dataSource);
}
});
};
const getChildren = async (nodeCfg: NodeConfig) => {
return findChildren(extractTree(dataSource.children), nodeCfg.id);
};
const openNotification = (data: any) => {
const { value: { formula } } = data;
notification.destroy();
if (_.isEmpty(formula)) return;
const { formula: description } = formula;
notification.open({
message: i18n["公式"],
duration: 5,
description,
style: { maxWidth: 600 }
});
};
const component: any = useMemo(() => {
const config = {
data: {
...dataSource,
children: dataSource.children ? _.map(dataSource.children, o => ({ ...o, children: null })) : null
},
autoFit: false, animate: true,
nodeCfg: {
getChildren,
autoWidth: true,
title: {
style: { fill: "#333" },
containerStyle: () => {
return {
fill: "#f7fbfe",
stroke: "#e5e5e5"
};
}
},
nodeStateStyles: {
hover: {
stroke: '#e5e5e5',
lineWidth: 1,
},
},
items: {
style: (cfg: any, group: any, type: string) => {
const styles = {
value: { fill: "#333" }
};
return styles[type];
}
},
style: {
stroke: "#e5e5e5"
}
},
markerCfg: (cfg: any) => {
const { g_level, id } = cfg;
return {
show: (g_level === 0 && !_.isEmpty(dataSource.children)) || getStorageIds(dataSource.children).includes(id)
};
},
onReady: (graph: any) => {
graph.on("node:click", (evt: any) => {
if (_.isEmpty(evt.target.attrs) || JSON.stringify(evt.target.attrs).indexOf("cursor") !== -1) return;
openNotification(evt.item._cfg.model);
});
setTimeout(() => {
graph.zoom(1);
});
},
behaviors: ["drag-canvas", "zoom-canvas"]
};
// @ts-ignore
return !_.isEmpty(dataSource) ? <DecompositionTreeGraph {...config} /> : null;
}, [dataSource]);
return component;
};
export default index;
const traverse: any = (arr: any[]) => {
return _.map(arr, item => {
if (!_.isEmpty(item.children)) {
const uuid = uuidV4();
return {
id: uuid,
value: { title: item.salaryItemName, formula: item.formula, items: [{ text: item.result }] },
children: traverse(item.children)
};
} else {
const uuid = uuidV4();
return {
id: uuid, value: { title: item.salaryItemName, formula: item.formula, items: [{ text: item.result }] }
};
}
});
};
const findChildren: any = (arr: any[], id: string) => {
const dataSource = _.find(arr, o => o.id === id).children;
return _.map(dataSource, o => ({ ...o, children: [] }));
};
/*
* Author:
* Description:
* Params:
* Date: 2023/10/26
*/
export const extractTree = (data: any[]) => {
if (!data.length) return [];
const list: any[] = [];
const getObj = (arr: any[]) => {
arr.forEach((row: any) => {
let obj = {};
obj = JSON.parse(JSON.stringify(row));
list.push(obj);
if (row.children) {
getObj(row.children);
}
});
return list;
};
return getObj(data);
};
/*
* Author:
* Description: childrenid
* Params:
* Date: 2023/10/26
*/
const getStorageIds = (array: any[]) => {
let ids: any = [];
const getIds = (array: any, ids: any) => {
array.forEach((item: any) => {
if (item.children) ids.push(item.id);
if (item.children) ids = getIds(item.children, ids);
});
return ids;
};
if (Array.isArray(array)) {
if (array.length === 0) return [];
} else {
return [];
}
ids = getIds(array, ids);
return ids;
};

@ -0,0 +1,292 @@
// @ts-ignore
import G6 from "@antv/g6";
G6.registerNode("root", {
draw: (cfg: any, group: any) => {
const size = [80, 30];
const keyShape = group.addShape("rect", {
attrs: {
width: size[0],
height: size[1],
x: -size[0] / 2,
y: -size[1] / 2,
fill: "rgb(19, 33, 92)",
radius: 5
},
draggable: true,
name: "root-keyshape"
});
group.addShape("text", {
attrs: {
text: `${cfg.ratio}%`,
fill: "rgba(255, 255, 255, 0.85)",
fontSize: 6,
x: 10 - size[0] / 2,
y: 3
},
draggable: true,
name: "ratio-shape"
});
group.addShape("text", {
attrs: {
text: `${cfg.label}`,
fill: "rgba(255, 255, 255, 0.85)",
fontSize: 9,
x: -6,
y: 0
},
draggable: true,
name: "label-shape"
});
group.addShape("line", {
attrs: {
x1: -6,
x2: 35,
y1: 2,
y2: 2,
stroke: "rgba(255, 255, 255, 0.85)",
lineWidth: 0.5
},
draggable: true,
name: "divider-shape"
});
group.addShape("text", {
attrs: {
text: `${cfg.subLabel}`,
fill: "rgba(255, 255, 255, 0.65)",
fontSize: 6,
x: -6,
y: 10
},
draggable: true,
name: "sublabel-shape"
});
return keyShape;
}
});
G6.registerNode("level1node", {
draw: (cfg: any, group: any) => {
const size = [60, 40];
const keyShape = group.addShape("rect", {
attrs: {
width: size[0],
height: size[1],
x: -size[0] / 2,
y: -size[1] / 2,
fill: "rgb(213, 225, 247)",
radius: 5
},
draggable: true,
name: "level1node-keyshape"
});
group.addShape("text", {
attrs: {
text: `${cfg.label}`,
fill: "rgba(19, 33, 92, 0.65)",
fontSize: 6,
x: 0,
y: -6,
textAlign: "center"
},
draggable: true,
name: "label-shape"
});
group.addShape("text", {
attrs: {
text: `${cfg.subLabel}`,
fill: "rgba(19, 33, 92, 0.65)",
fontSize: 8,
x: 0,
y: 6,
fontWeight: 800,
textAlign: "center"
},
draggable: true,
name: "sublabel-shape"
});
group.addShape("rect", {
attrs: {
x: -12,
y: 8,
width: 25,
height: 8,
radius: 4,
fill: cfg.increase ? "rgb(127, 193, 193)" : "rgb(220, 124, 125)"
},
draggable: true,
name: "ratio-box"
});
group.addShape("text", {
attrs: {
text: `${cfg.ratio}%`,
fill: "rgba(255, 255, 255, 0.85)",
fontSize: 6,
x: 0,
y: 9,
textAlign: "center",
textBaseline: "top"
},
draggable: true,
name: "ratio-shape"
});
// edge end
group.addShape("line", {
attrs: {
x1: -size[0] / 2,
x2: -size[0] / 2 + 6,
y1: 0,
y2: 0,
lineWidth: 1,
stroke: "rgb(19, 33, 92)"
}
});
group.addShape("circle", {
attrs: {
r: 2,
x: -size[0] / 2 + 6,
y: 0,
fill: "rgb(19, 33, 92)"
}
});
return keyShape;
},
update: undefined
}, "rect");
G6.registerNode("othernode", {
draw: (cfg: any, group: any) => {
const size = [100, 30];
const keyShape = group.addShape("rect", {
attrs: {
width: size[0],
height: size[1],
x: -size[0] / 2,
y: -size[1] / 2,
fill: "rgb(213, 225, 247)",
radius: 5
},
draggable: true,
name: "level1node-keyshape"
});
group.addShape("text", {
attrs: {
text: `${cfg.label}`,
fill: "rgba(19, 33, 92, 0.65)",
fontSize: 6,
x: 10 - size[0] / 2,
y: -2,
textAlign: "left"
},
draggable: true,
name: "label-shape"
});
group.addShape("text", {
attrs: {
text: `${cfg.subLabel}`,
fill: "rgba(19, 33, 92, 0.65)",
fontSize: 8,
fontWeight: 800,
x: 10 - size[0] / 2,
y: 8,
textAlign: "left"
},
draggable: true,
name: "sublabel-shape"
});
group.addShape("rect", {
attrs: {
x: 12,
y: -4,
width: 25,
height: 8,
radius: 4,
fill: cfg.increase ? "rgb(127, 193, 193)" : "rgb(220, 124, 125)"
},
draggable: true,
name: "ratio-box"
});
group.addShape("text", {
attrs: {
text: `${cfg.ratio}%`,
fill: "rgba(255, 255, 255, 0.85)",
fontSize: 6,
x: 18,
y: -3,
textAlign: "left",
textBaseline: "top"
},
draggable: true,
name: "ratio-shape"
});
if (cfg.operator) {
group.addShape("rect", {
attrs: {
x: -8,
y: 27,
width: 16,
height: 16,
lineWidth: 1,
stroke: "#aaa",
lineDash: [2, 1],
opacity: 0
},
name: "operator-box"
});
group.addShape("circle", {
attrs: {
r: 6,
x: 0,
y: 35,
fill: "rgba(240, 90, 109, 0.15)"
},
name: "operator-circle"
});
group.addShape("text", {
attrs: {
text: cfg.operator,
x: 0,
y: 34,
fontSize: 12,
fill: "rgba(240, 90, 109, 0.85)",
textAlign: "center",
textBaseline: "middle"
},
name: "operator-symbol"
});
}
// edge end
group.addShape("line", {
attrs: {
x1: -size[0] / 2,
x2: -size[0] / 2 + 6,
y1: 0,
y2: 0,
lineWidth: 1,
stroke: "rgb(19, 33, 92)"
}
});
group.addShape("circle", {
attrs: {
r: 2,
x: -size[0] / 2 + 6,
y: 0,
fill: "rgb(19, 33, 92)"
}
});
return keyShape;
},
update: undefined
}, "rect");
G6.registerEdge("round-poly", {
getControlPoints: (cfg: any) => {
const { startPoint, endPoint } = cfg;
return [
startPoint,
{
x: startPoint.x,
y: endPoint.y
},
endPoint
];
}
}, "polyline");

@ -0,0 +1,83 @@
.salaryItemOptWrapper {
:global {
.ant-menu-item-selected {
background: #FFF !important;
color: #333;
}
.ant-menu-item {
height: 26px !important;
line-height: 26px !important;
}
.ant-menu-title-content {
font-size: 12px;
}
}
}
:global {
.relation-graph .rel-toolbar-h {
width: auto !important;
}
}
.rootNode {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: rgb(0, 154, 73);
color: #FFF;
font-size: 14px;
font-weight: bold;
border-radius: 25px;
padding: 10px;
}
.levelNode {
background: rgb(170, 212, 179) !important;
}
.commonNode {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 10px;
font-size: 14px;
font-weight: bold;
color: #333;
& > span {
display: inline-block;
width: 100%;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
text-align: center;
}
}
.c-right-menu-panel {
z-index: 999;
background-color: rgb(255, 255, 255);
border: 1px solid rgb(238, 238, 238);
box-shadow: rgb(204, 204, 204) 0px 0px 8px;
position: absolute;
border-radius: 10px;
.c-node-menu-item {
line-height: 30px;
padding: 5px 8px;
cursor: pointer;
color: rgb(68, 68, 68);
font-size: 12px;
}
.c-node-menu-item:first-child {
border-bottom: 1px solid rgb(239, 239, 239);
}
}

@ -0,0 +1,152 @@
import type { MutableRefObject } from "react";
import React, { useEffect, useMemo, useRef, useState } from "react";
import type { RelationGraphExpose, RGLink, RGNode, RGNodeSlotProps, RGOptions } from "relation-graph/react";
import RelationGraph from "relation-graph/react";
import { exceptStr } from "@/utils/common";
import { extractTree } from "@/pages/salaryItemDiagram";
import { RGEventTargetType, RGUserEvent } from "relation-graph/types/types/types";
import cs from "classnames";
import styles from "./index.less";
const NodeSlot: React.FC<RGNodeSlotProps> = ({ node }) => {
if (node.id === "0") {
return <div className={styles.rootNode}> {node.text} </div>;
}
// @ts-ignore
if (node.id !== "0" && !node.data.parentId) {
return <div className={cs(styles.levelNode, styles.commonNode)}> {node.text} </div>;
}
return <div className={styles.commonNode}>
<span title={node.text}>{node.text}</span>
</div>;
};
const Index: React.FC = () => {
const [itemsTree, setItemsTree] = useState<any[]>([]);
const [i18n, setI18n] = useState<any>({});
const [menuXY, setMenuXY] = useState<any>({ left: "", top: "", data: {} });
const graphRef = useRef() as MutableRefObject<RelationGraphExpose>;
useEffect(() => {
window.parent.postMessage({ type: "init" }, "*");
window.addEventListener("message", receiveMessageFromIndex, false);
return () => {
window.removeEventListener("message", receiveMessageFromIndex, false);
};
}, []);
const receiveMessageFromIndex = (event: any) => {
const data: any = exceptStr(event.data);
if (!_.isEmpty(data)) {
const { itemsTree, i18n } = data;
setI18n(i18n);
setItemsTree(itemsTree);
}
};
const dataSource: any = useMemo(() => {
setMenuXY({ left: "", top: "", data: {} });
return {
rootId: "0",
nodes: [{ id: "0", text: i18n["薪资项目"] }, ..._.map(extractTree(itemsTree), o => ({
id: o.salaryItemId.toString(),
text: o.salaryItemName, data: { ...o }
}))],
lines: _.map(extractTree(itemsTree), o => ({
from: o.parentId ? o.parentId.toString() : "0",
to: o.salaryItemId.toString()
}))
};
}, [itemsTree, i18n]);
useEffect(() => {
if (!_.isEmpty(dataSource.nodes) && !_.isEmpty(dataSource.lines)) {
const init = showGraph();
}
}, [dataSource]);
const showGraph = async () => {
await graphRef.current.setJsonData(dataSource, (graphInstance) => {
});
};
const options: RGOptions = useMemo(() => {
return {
debug: false,
layout: {
label: "树",
layoutName: "tree",
layoutClassName: "seeks-layout-center",
from: "left",
// 通过这4个属性来调整 tree-层级距离&节点距离
min_per_width: undefined,
max_per_width: 300,
min_per_height: 60,
max_per_height: undefined,
levelDistance: "" // 如果此选项有值则优先级高于上面那4个选项
},
defaultExpandHolderPosition: "right",
defaultNodeWidth: 180,
defaultNodeHeight: 50,
defaultLineShape: 4,
defaultNodeBorderWidth: 1,
defaultLineColor: "#333",
defaultExpandHolderColor: "rgba(0, 206, 209, 1)",
defaultNodeColor: "transparent",
defaultNodeBorderColor: "#333",
allowShowMiniToolBar: true, //工具栏展示与否
toolBarDirection: 'h',
toolBarPositionH: 'right',
toolBarPositionV: 'top',
allowShowFullscreenMenu: false,
allowShowDownloadButton: false,
disableZoom: true,
disableDragNode: true,
};
}, []);
const onNodeRightClick = (e: RGUserEvent & { pageX: number, pageY: number }, objectType: RGEventTargetType, object: RGNode | RGLink | undefined) => {
if (objectType === "node") {
// @ts-ignore
setMenuXY({ left: e.pageX, top: e.pageY, data: object?.data });
} else {
setMenuXY({ left: "", top: "", data: {} });
}
return true;
};
const onNodeClick = (node: RGNode) => {
setMenuXY({ left: "", top: "", data: {} });
if (node.type === "node") {
// @ts-ignore
const { formulaId } = node?.data;
formulaId &&
window.parent.postMessage({ type: "turn", payload: { id: "VIEW", params: { formulaId } } }, "*");
}
return true;
};
const handleNodeOpt = (id: string) => {
const { data } = menuXY;
window.parent.postMessage({
type: "turn",
payload: {
id, params: {
visible: true, id: data?.groupId, dataType: data?.dateType,
formulaId: data?.formulaId, valueType: data?.valueType,
salaryItemId: data?.salaryItemId
}
}
}, "*");
};
return <div style={{ height: "100%", width: "100%" }}>
<RelationGraph ref={graphRef} options={options} nodeSlot={NodeSlot}
// @ts-ignore
onContextmenu={onNodeRightClick} onNodeClick={onNodeClick} onCanvasClick={onNodeClick}
/>
{
!_.isEmpty(menuXY.data) &&
<div className={styles["c-right-menu-panel"]} style={{ ...menuXY }}>
{
menuXY.data.canAddItem &&
<div className={styles["c-node-menu-item"]} onClick={() => handleNodeOpt("ADD")}>{i18n["添加薪资项目"]}</div>
}
{
!_.isNil(menuXY.data.formulaId) && menuXY.data.formulaId !== 0 && menuXY.data.canEditItem &&
<div className={styles["c-node-menu-item"]} onClick={() => handleNodeOpt("EDIT")}>{i18n["编辑公式"]}</div>
}
</div>
}
</div>;
};
export default Index;

@ -0,0 +1,168 @@
/*
* Author:
* name: -
* Description:
* Date: 2023/11/14
*/
import React, { FunctionComponent, useEffect, useMemo, useState } from "react";
import { Menu } from "antd";
// import { FundFlowGraph } from "@ant-design/graphs";
import { exceptStr } from "@/utils/common";
import { extractTree } from "@/pages/salaryItemDiagram";
import styles from "./index.less";
interface OwnProps {
}
type Props = OwnProps;
const index: FunctionComponent<Props> = (props) => {
const [nodes, setNodes] = useState<any[]>([]);
const [edges, setEdges] = useState<any[]>([]);
const [i18n, setI18n] = useState<any>({});
useEffect(() => {
window.parent.postMessage({ type: "init" }, "*");
window.addEventListener("message", receiveMessageFromIndex, false);
return () => {
window.removeEventListener("message", receiveMessageFromIndex, false);
};
}, []);
const openNotification = (data: any) => {
const { formulaId } = data;
window.parent.postMessage({ type: "turn", payload: { id: "VIEW", params: { formulaId } } }, "*");
};
const receiveMessageFromIndex = (event: any) => {
const data: any = exceptStr(event.data);
if (!_.isEmpty(data)) {
const { itemsTree, i18n } = data;
setI18n(i18n);
setNodes([{
id: "0",
salaryItemName: i18n["薪资项目"],
value: { text: i18n["薪资项目"] }
}, ..._.map(extractTree(itemsTree), o => ({
...o,
id: o.salaryItemId.toString(),
value: { text: o.salaryItemName.length >= 8 ? o.salaryItemName.slice(0, 8) + "..." : o.salaryItemName }
}))]);
const edges: any = _.map(extractTree(itemsTree), o => ({
source: o.parentId ? o.parentId.toString() : "0",
target: o.salaryItemId.toString()
}));
setEdges(edges);
}
};
const config: any = useMemo(() => {
const data = { nodes, edges };
return {
data,
menuCfg: {
className: styles.salaryItemOptWrapper,
shouldBegin: (evt: any) => {
const { item: { _cfg: { model } } } = evt;
return model.canAddItem || (!_.isNil(model.formulaId) && model.formulaId !== 0);
},
handleMenuClick: (__: any, evt: any) => {
const { _cfg: { model } } = evt;
const id = __.innerText.indexOf(i18n["添加薪资项目"]) !== -1 ? "ADD" : "EDIT";
window.parent.postMessage({
type: "turn",
payload: {
id, params: {
visible: true, id: model?.groupId, dataType: model?.dateType,
formulaId: model?.formulaId, valueType: model?.valueType,
salaryItemId: model?.salaryItemId
}
}
}, "*");
},
customContent: (evt: any) => {
const { item: { _cfg: { model } } } = evt;
let items: any = [
{ label: i18n["添加薪资项目"], key: "add" },
{ label: i18n["编辑公式"], key: "edit" }
];
(_.isNil(model.formulaId) || model.formulaId === 0) && (items = _.filter(items, o => o.key !== "edit"));
(!model.canAddItem) && (items = _.filter(items, o => o.key !== "add"));
return (
<Menu items={items}/>
);
}
},
edgeCfg: {
endArrow: { fill: "#333" },
style: { stroke: "#333" },
edgeStateStyles: {
hover: {
stroke: "#1890ff",
lineWidth: 2,
endArrow: {
fill: "#1890ff"
}
}
}
},
nodeCfg: {
style: (item: any, group: any) => {
const { id, parentId } = item;
let styleObj = {};
switch (id) {
case "0":
styleObj = { ...styleObj, fill: "rgb(0,154,73)", stroke: "rgb(0,154,73)" };
break;
default:
styleObj = { ...styleObj, fill: "#FFF", stroke: "#666", radius: [2, 2, 2, 2] };
if (_.isNil(parentId)) styleObj = {
...styleObj, fill: "rgb(170,212,179)",
stroke: "#000", radius: [2, 2, 2, 2]
};
break;
}
return styleObj;
},
label: {
style: (item: any) => {
const { id } = item;
return { fontWeight: "bold", fill: id === "0" ? "#FFF" : "#333", fontSize: id === "0" ? 18 : 12 };
}
}
},
markerCfg: (cfg: any) => {
const { edges } = data;
return {
position: "right",
show: edges.find((item) => item.source === cfg.id)
};
},
layout: {
rankdir: "LR",
// nodesep: 5,
// ranksep: 20
},
tooltipCfg: {
show: true,
shouldBegin: (evt: any) => {
const { item: { _cfg: { model } } } = evt;
return model.salaryItemName.length >= 8;
},
customContent: (item: any) => (<h3>{item.salaryItemName}</h3>)
},
onReady: (graph: any) => {
graph.on("node:click", (evt: any) => {
if (_.isEmpty(evt.target.attrs) || JSON.stringify(evt.target.attrs).indexOf("cursor") !== -1) return;
openNotification(evt.item._cfg.model);
});
graph.on("node:contextmenu", (evt: any) => {
});
},
behaviors: ["drag-canvas", "zoom-canvas", 'drag-node'],
// autoFit: false,
// fitCenter: true
};
}, [nodes, edges]);
// <FundFlowGraph {...config} />
return ((!_.isEmpty(nodes) && !_.isEmpty(edges)) ? <div></div> : null);
};
export default index;

@ -1,9 +1,8 @@
import React, { FC, useEffect, useState } from "react"; import React, { FC, useEffect, useState } from "react";
import { Button, Spin, Table, Typography } from "antd"; import { Button, Table, Typography } from "antd";
import { exceptStr, paginationFun } from "@/utils/common"; import { exceptStr, paginationFun } from "@/utils/common";
import { defaultPage, IPage } from "@/common/types"; import { defaultPage, IPage } from "@/common/types";
import styles from "@/pages/atdTable/components/index.less"; import styles from "@/pages/atdTable/components/index.less";
import API from "@/api";
const { Text } = Typography; const { Text } = Typography;
const StandingbookTable: FC = (props) => { const StandingbookTable: FC = (props) => {
@ -12,7 +11,6 @@ const StandingbookTable: FC = (props) => {
const [dataSource, setDataSource] = useState<Array<any>>([]); const [dataSource, setDataSource] = useState<Array<any>>([]);
const [pageInfo, setPageInfo] = useState<IPage>(defaultPage); const [pageInfo, setPageInfo] = useState<IPage>(defaultPage);
const [sumRow, setSumRow] = useState<Partial<{}>>({}); const [sumRow, setSumRow] = useState<Partial<{}>>({});
const [showSumrow, setShowSumrow] = useState<boolean>(false);
useEffect(() => { useEffect(() => {
window.parent.postMessage({ type: "init" }, "*"); window.parent.postMessage({ type: "init" }, "*");
@ -24,30 +22,33 @@ const StandingbookTable: FC = (props) => {
const receiveMessageFromIndex = async (event: any) => { const receiveMessageFromIndex = async (event: any) => {
const data: any = exceptStr(event.data); const data: any = exceptStr(event.data);
if (!_.isEmpty(data)) { if (!_.isEmpty(data)) {
const { const { columns, dataSource, pageInfo, showOperates, selectedRowKeys, sumRow } = data;
columns, dataSource, pageInfo, showOperates, selectedRowKeys,
sumpayload, selectedKey
} = data;
const { current: pageNum, pageSize: size, total } = pageInfo; const { current: pageNum, pageSize: size, total } = pageInfo;
const conventColumns = _.map(_.filter(columns, it => it.dataIndex !== "id"), item => { const conventColumns = _.map(
_.filter(columns, (it) => it.dataIndex !== "id"),
(item) => {
const { dataIndex } = item; const { dataIndex } = item;
if (dataIndex === "employeeId") { if (dataIndex === "employeeId") {
return { return {
title: "姓名", dataIndex, fixed: "left", width: 150, title: "姓名",
render: (_: any, record: Partial<any>) => ( dataIndex,
<span>{record?.userName}</span> fixed: "left",
) width: 150,
render: (_: any, record: Partial<any>) => <span>{record?.userName}</span>
}; };
} }
return { return {
dataIndex, width: 150, dataIndex,
width: 150,
title: <span dangerouslySetInnerHTML={{ __html: item.title }} /> title: <span dangerouslySetInnerHTML={{ __html: item.title }} />
}; };
}); }
);
setDataSource(dataSource); setDataSource(dataSource);
setColumns( setColumns(
!showOperates ? conventColumns : !showOperates
[ ? conventColumns
: [
...conventColumns, ...conventColumns,
{ {
title: "操作", title: "操作",
@ -56,7 +57,9 @@ const StandingbookTable: FC = (props) => {
width: 120, width: 120,
render: (_: any, record: any) => { render: (_: any, record: any) => {
return ( return (
<Button type="link" onClick={() => handleEdit(record)}></Button> <Button type="link" onClick={() => handleEdit(record)}>
</Button>
); );
} }
} }
@ -64,61 +67,27 @@ const StandingbookTable: FC = (props) => {
); );
setPageInfo({ pageNum, size, total }); setPageInfo({ pageNum, size, total });
setSelected(selectedRowKeys); setSelected(selectedRowKeys);
const confCode: any = await API.CalculateService.getSysconfcode({ code: "OPEN_ACCT_RESULT_SUM" }); setSumRow(sumRow);
setShowSumrow(confCode.data.status && confCode.data.data === "1");
if (confCode.data.status && confCode.data.data === "1") {
const sumRowlist: any = selectedKey === "1" ? await API.CalculateService.siaccountDetailCommonListSum(sumpayload) :
selectedKey === "3" ? await API.CalculateService.siaccountDetailSupplementaryListSum(sumpayload) :
selectedKey === "regression" ? await API.CalculateService.siaccountDetailRecessionListSum(sumpayload) :
selectedKey === "difference" ? await API.CalculateService.siaccountDetailBalanceListSum(sumpayload) : {
data: {
status: false,
data: { sumRow: {} }
}
};
if (sumRowlist.data.status) {
if (!_.isEmpty(sumRowlist.data.data.sumRow)) {
setSumRow(sumRowlist.data.data.sumRow);
} else {
setSumRow({ [new Date().getTime()]: new Date().getTime() });
}
}
if (sumRowlist.data.status && _.isNil(sumRowlist.data.data.sumRow)) {
setSumRow({ [new Date().getTime()]: new Date().getTime() });
}
}
} }
}; };
const handleEdit = (record: any) => { const handleEdit = (record: any) => {
window.parent.postMessage({ type: "turn", payload: { id: "EDIT", params: { ...record } } }, "*"); window.parent.postMessage({ type: "turn", payload: { id: "EDIT", params: { ...record } } }, "*");
}; };
const sizeChange = (pageobj: IPage) => { const sizeChange = (pageobj: IPage) => {};
};
const onChange = (pageobj: IPage) => { const onChange = (pageobj: IPage) => {
setPageInfo({ ...pageInfo, ...pageobj }); setPageInfo({ ...pageInfo, ...pageobj });
window.parent.postMessage( window.parent.postMessage({ type: "turn", payload: { id: "PAGEINFO", params: { ...pageInfo, ...pageobj } } }, "*");
{
type: "turn",
payload: { id: "PAGEINFO", params: { ...pageInfo, ...pageobj } }
},
"*"
);
}; };
const rowSelection = { const rowSelection = {
selectedRowKeys: selected, selectedRowKeys: selected,
columnWidth: 80, columnWidth: 60,
onChange: (selectedRowKeys: Array<any>) => { onChange: (selectedRowKeys: Array<any>) => {
setSelected(selectedRowKeys); setSelected(selectedRowKeys);
window.parent.postMessage( window.parent.postMessage({ type: "turn", payload: { id: "ROWSELECT", params: { selectedRowKeys } } }, "*");
{
type: "turn",
payload: { id: "ROWSELECT", params: { selectedRowKeys } }
},
"*"
);
} }
}; };
return <Table return (
<Table
rowKey="id" rowKey="id"
className={styles.tableWrapper} className={styles.tableWrapper}
columns={columns} columns={columns}
@ -131,27 +100,30 @@ const StandingbookTable: FC = (props) => {
}} }}
scroll={{ x: 1200, y: `calc(100vh - 172px)` }} scroll={{ x: 1200, y: `calc(100vh - 172px)` }}
summary={() => { summary={() => {
if (_.isEmpty(columns) || !showSumrow) return; if (_.isEmpty(sumRow)) return;
return ( return (
<Table.Summary fixed> <Table.Summary fixed>
<Table.Summary.Row> <Table.Summary.Row>
{ {_.map([{}, ...columns], (item, index) => {
_.isEmpty(sumRow) ? <Spin tip="加载中"/> :
_.map([{}, ...columns], (item, index) => {
if (index === 0) { if (index === 0) {
return <Table.Summary.Cell index={0} key={index} align="center"><Text return (
type="danger"></Text></Table.Summary.Cell>; <Table.Summary.Cell index={0} key={index} align="center">
<Text type="danger"></Text>
</Table.Summary.Cell>
);
} }
return <Table.Summary.Cell index={index} key={index}> return (
<Table.Summary.Cell index={index} key={index}>
<Text type="danger">{!_.isNil(sumRow[item.dataIndex]) ? sumRow[item.dataIndex] : "-"}</Text> <Text type="danger">{!_.isNil(sumRow[item.dataIndex]) ? sumRow[item.dataIndex] : "-"}</Text>
</Table.Summary.Cell>; </Table.Summary.Cell>
}) );
} })}
</Table.Summary.Row> </Table.Summary.Row>
</Table.Summary> </Table.Summary>
); );
}} }}
/>; />
);
}; };
export default StandingbookTable; export default StandingbookTable;

@ -5,6 +5,7 @@
* Date: 2023/12/27 * Date: 2023/12/27
*/ */
import React, { FC, useEffect, useState } from "react"; import React, { FC, useEffect, useState } from "react";
import { FileSearchOutlined } from "@ant-design/icons";
import { Button, Space, Table } from "antd"; import { Button, Space, Table } from "antd";
import { exceptStr, paginationAction } from "@/utils/common"; import { exceptStr, paginationAction } from "@/utils/common";
import styles from "@/pages/atdTable/components/index.less"; import styles from "@/pages/atdTable/components/index.less";
@ -26,12 +27,32 @@ const TaxDeclareTable: FC = (props) => {
const receiveMessageFromIndex = (event: any) => { const receiveMessageFromIndex = (event: any) => {
const data: any = exceptStr(event.data); const data: any = exceptStr(event.data);
if (!_.isEmpty(data)) { if (!_.isEmpty(data)) {
const { columns, dataSource, pageInfo, i18n, declareStatus } = data; const { columns, dataSource, pageInfo, i18n, declareStatus, azOperate = true } = data;
setDataSource(dataSource); setDataSource(dataSource);
setI18n(i18n); setI18n(i18n);
setPageInfo(pageInfo); setPageInfo(pageInfo);
setColumns(["NOT_DECLARE", "DECLARE_FAIL"].includes(declareStatus) ? [ setColumns(
...columns, ["NOT_DECLARE", "DECLARE_FAIL"].includes(declareStatus) && azOperate
? [
..._.map(columns, (o) => {
// 查看附表字段
if (o.isAppendix) {
return {
...o,
render: (text: string, record: any) => (
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
<span>{text}</span>
<FileSearchOutlined
title={i18n["查看附表"]}
style={{ color: "#2db7f5", fontSize: 16, cursor: "pointer" }}
onClick={() => handleViewAppendix({ ...record, dataIndex: o.dataIndex, title: o.title })}
/>
</div>
)
};
}
return { ...o };
}),
{ {
title: i18n["操作"], title: i18n["操作"],
dataIndex: "operate", dataIndex: "operate",
@ -39,12 +60,36 @@ const TaxDeclareTable: FC = (props) => {
width: 120, width: 120,
render: (_: any, record: any) => ( render: (_: any, record: any) => (
<Space> <Space>
<Button type="link" onClick={() => handleEdit(record)}>{i18n["编辑"]}</Button> <Button type="link" onClick={() => handleEdit(record)}>
<Button type="link" onClick={() => handleDelete(record)}>{i18n["删除"]}</Button> {i18n["编辑"]}
</Button>
<Button type="link" onClick={() => handleDelete(record)}>
{i18n["删除"]}
</Button>
</Space> </Space>
) )
} }
] : columns); ]
: _.map(columns, (o) => {
// 查看附表字段
if (o.isAppendix) {
return {
...o,
render: (text: string, record: any) => (
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
<span>{text}</span>
<FileSearchOutlined
title={i18n["查看附表"]}
style={{ color: "#2db7f5", fontSize: 16, cursor: "pointer" }}
onClick={() => handleViewAppendix({ ...record, dataIndex: o.dataIndex, title: o.title })}
/>
</div>
)
};
}
return { ...o };
})
);
} }
}; };
const handleEdit = (record: any) => { const handleEdit = (record: any) => {
@ -53,6 +98,9 @@ const TaxDeclareTable: FC = (props) => {
const handleDelete = (record: any) => { const handleDelete = (record: any) => {
window.parent.postMessage({ type: "turn", payload: { id: "DELETE", params: { ...record } } }, "*"); window.parent.postMessage({ type: "turn", payload: { id: "DELETE", params: { ...record } } }, "*");
}; };
const handleViewAppendix = (record: any) => {
window.parent.postMessage({ type: "turn", payload: { id: "APPENDIX", params: { ...record } } }, "*");
};
const onChange = (current: number, pageSize: number) => { const onChange = (current: number, pageSize: number) => {
setPageInfo((prevState) => { setPageInfo((prevState) => {
const { pageSize: size } = prevState; const { pageSize: size } = prevState;
@ -66,15 +114,21 @@ const TaxDeclareTable: FC = (props) => {
return { ...pageInfo, current: size === pageSize ? current : 1, pageSize }; return { ...pageInfo, current: size === pageSize ? current : 1, pageSize };
}); });
}; };
return <Table return (
rowKey="id" className={styles.tableWrapper} size="small" <Table
columns={columns} dataSource={dataSource} bordered rowKey="id"
className={styles.tableWrapper}
size="small"
columns={columns}
dataSource={dataSource}
bordered
scroll={{ x: 1200, y: `calc(100vh - 100px)` }} scroll={{ x: 1200, y: `calc(100vh - 100px)` }}
pagination={{ pagination={{
...paginationAction(pageInfo, i18n, onChange), ...paginationAction(pageInfo, i18n, onChange),
size: "default" size: "default"
}} }}
/>; />
);
}; };
export default TaxDeclareTable; export default TaxDeclareTable;

@ -27,7 +27,7 @@ export function renderCols(initialState: any[], type: string, i18n?: AnyObject,
render: (text: string, record: any) => { render: (text: string, record: any) => {
const { billStatus } = record; const { billStatus } = record;
return ( return (
<Button type="link" onClick={() => postMessageToParent(billStatus === "0" && extraParams?.permission ? "CALC" : "VIEW", record)}> <Button type="link" onClick={() => postMessageToParent(billStatus === "0" && record?.opts.includes("admin") ? "CALC" : "VIEW", record)}>
{text} {text}
</Button> </Button>
); );
@ -84,7 +84,7 @@ export function renderCols(initialState: any[], type: string, i18n?: AnyObject,
]; ];
return ( return (
<Space> <Space>
{!extraParams?.permission ? ( {!record?.opts.includes("admin") ? (
<Space> <Space>
<Button type="link" onClick={() => postMessageToParent("VIEW", record)}> <Button type="link" onClick={() => postMessageToParent("VIEW", record)}>
{i18n?.["查看"]} {i18n?.["查看"]}
@ -358,6 +358,8 @@ export function renderCols(initialState: any[], type: string, i18n?: AnyObject,
fixed: "right", fixed: "right",
render: (__: string, record: any) => { render: (__: string, record: any) => {
return ( return (
<Space>
{record?.opts.includes("admin") ? (
<Space> <Space>
<Button type="link" onClick={() => postMessageToParent("EDIT", record)}> <Button type="link" onClick={() => postMessageToParent("EDIT", record)}>
{i18n?.["编辑"]} {i18n?.["编辑"]}
@ -366,6 +368,12 @@ export function renderCols(initialState: any[], type: string, i18n?: AnyObject,
{i18n?.["删除"]} {i18n?.["删除"]}
</Button> </Button>
</Space> </Space>
) : (
<Button type="link" onClick={() => postMessageToParent("VIEW", record)}>
{i18n?.["查看"]}
</Button>
)}
</Space>
); );
} }
} }
@ -404,13 +412,15 @@ export function renderCols(initialState: any[], type: string, i18n?: AnyObject,
onClick: () => postMessageToParent("log", record) onClick: () => postMessageToParent("log", record)
} }
]; ];
isSpecial && items.shift(); (isSpecial || !record?.opts.includes("admin")) && items.shift();
return ( return (
<Space> <Space>
{record?.opts.includes("admin") && (
<Button type="link" onClick={() => postMessageToParent("EDIT", record)}> <Button type="link" onClick={() => postMessageToParent("EDIT", record)}>
{i18n?.["编辑"]} {i18n?.["编辑"]}
</Button> </Button>
{isSpecial ? ( )}
{isSpecial && record?.opts.includes("admin") ? (
<Button type="link" onClick={() => postMessageToParent("DEL", record)}> <Button type="link" onClick={() => postMessageToParent("DEL", record)}>
{i18n?.["删除"]} {i18n?.["删除"]}
</Button> </Button>

@ -25,7 +25,6 @@ const Index: FunctionComponent<Props> = (props) => {
const [pageInfo, setPageInfo] = useState<Partial<PaginationData>>({}); const [pageInfo, setPageInfo] = useState<Partial<PaginationData>>({});
const [i18n, setI18n] = useState<any>({}); const [i18n, setI18n] = useState<any>({});
const [runStatuses, setRunStatuses] = useState<string>(""); const [runStatuses, setRunStatuses] = useState<string>("");
const [showOperateBtn, setShowOperateBtn] = useState<boolean>(false);
useEffect(() => { useEffect(() => {
window.parent.postMessage({ type: "init" }, "*"); window.parent.postMessage({ type: "init" }, "*");
@ -38,11 +37,7 @@ const Index: FunctionComponent<Props> = (props) => {
const receiveMessageFromIndex = (event: any) => { const receiveMessageFromIndex = (event: any) => {
const data: any = exceptStr(event.data); const data: any = exceptStr(event.data);
if (!_.isEmpty(data)) { if (!_.isEmpty(data)) {
const { const { columns, dataSource, pageInfo, selectedRowKeys: rowKeys = [], i18n: i18nRes = {}, runStatuses } = data;
columns, dataSource, pageInfo, selectedRowKeys: rowKeys = [], i18n: i18nRes = {},
runStatuses, showOperateBtn
} = data;
setShowOperateBtn(showOperateBtn);
setRunStatuses(runStatuses); setRunStatuses(runStatuses);
setI18n(i18nRes); setI18n(i18nRes);
setPageInfo(pageInfo); setPageInfo(pageInfo);
@ -87,6 +82,14 @@ const Index: FunctionComponent<Props> = (props) => {
}; };
const cols: any = useMemo(() => { const cols: any = useMemo(() => {
let opts: any = { title: i18n["操作"], dataIndex: "operate", fixed: "right", width: 185 }; let opts: any = { title: i18n["操作"], dataIndex: "operate", fixed: "right", width: 185 };
const UnAuthOpts = (record: any) => (<Space>
<Button type="link" onClick={() => handleWelfareOperate("VIEW", record)}>{i18n["查看"]}</Button>
<Dropdown menu={{
items: [{ key: "Log", label: i18n["操作日志"], onClick: () => handleWelfareOperate("log", record) }]
}} placement="bottomRight">
<Button type="link" icon={<MoreOutlined/>}/>
</Dropdown>
</Space>);
switch (runStatuses) { switch (runStatuses) {
case "1": case "1":
opts = { opts = {
@ -109,13 +112,13 @@ const Index: FunctionComponent<Props> = (props) => {
onClick: () => handleWelfareOperate("log", record) onClick: () => handleWelfareOperate("log", record)
} }
]; ];
return (<Space> return (record?.opts.includes("admin") ? <Space>
<Button type="link" onClick={() => handleWelfareOperate("EDIT", record)}>{i18n["编辑"]}</Button> <Button type="link" onClick={() => handleWelfareOperate("EDIT", record)}>{i18n["编辑"]}</Button>
<Button type="link" onClick={() => handleWelfareOperate("ADD-TO-PAY", record)}>{i18n["增员"]}</Button> <Button type="link" onClick={() => handleWelfareOperate("ADD-TO-PAY", record)}>{i18n["增员"]}</Button>
<Dropdown menu={{ items }} placement="bottomRight"> <Dropdown menu={{ items }} placement="bottomRight">
<Button type="link" icon={<MoreOutlined/>}/> <Button type="link" icon={<MoreOutlined/>}/>
</Dropdown> </Dropdown>
</Space>); </Space> : UnAuthOpts(record));
} }
}; };
break; break;
@ -131,13 +134,12 @@ const Index: FunctionComponent<Props> = (props) => {
onClick: () => handleWelfareOperate("log", record) onClick: () => handleWelfareOperate("log", record)
} }
]; ];
return ( return (record?.opts.includes("admin") ? <Space>
<Space>
<Button type="link" onClick={() => handleWelfareOperate("EDIT", record)}>{i18n["编辑"]}</Button> <Button type="link" onClick={() => handleWelfareOperate("EDIT", record)}>{i18n["编辑"]}</Button>
<Dropdown menu={{ items }} placement="bottomRight"> <Dropdown menu={{ items }} placement="bottomRight">
<Button type="link" icon={<MoreOutlined/>}/> <Button type="link" icon={<MoreOutlined/>}/>
</Dropdown> </Dropdown>
</Space>); </Space> : UnAuthOpts(record));
} }
}; };
break; break;
@ -157,14 +159,14 @@ const Index: FunctionComponent<Props> = (props) => {
onClick: () => handleWelfareOperate("log", record) onClick: () => handleWelfareOperate("log", record)
} }
]; ];
return (<Space> return (record?.opts.includes("admin") ? <Space>
<Button type="link" onClick={() => handleWelfareOperate("EDIT", record)}>{i18n["编辑"]}</Button> <Button type="link" onClick={() => handleWelfareOperate("EDIT", record)}>{i18n["编辑"]}</Button>
<Button type="link" <Button type="link"
onClick={() => handleWelfareOperate("STAY-DEL-TO-STOP", record)}>{i18n["减员"]}</Button> onClick={() => handleWelfareOperate("STAY-DEL-TO-STOP", record)}>{i18n["减员"]}</Button>
<Dropdown menu={{ items: downsizingItems }} placement="bottomRight"> <Dropdown menu={{ items: downsizingItems }} placement="bottomRight">
<Button type="link" icon={<MoreOutlined/>}/> <Button type="link" icon={<MoreOutlined/>}/>
</Dropdown> </Dropdown>
</Space>); </Space> : UnAuthOpts(record));
} }
}; };
break; break;
@ -184,38 +186,27 @@ const Index: FunctionComponent<Props> = (props) => {
onClick: () => handleWelfareOperate("log", record) onClick: () => handleWelfareOperate("log", record)
} }
]; ];
return (<Space> return (record?.opts.includes("admin") ? <Space>
<Button type="link" onClick={() => handleWelfareOperate("VIEW", record)}>{i18n["查看"]}</Button> <Button type="link" onClick={() => handleWelfareOperate("VIEW", record)}>{i18n["查看"]}</Button>
<Button type="link" <Button type="link"
onClick={() => handleWelfareOperate("DEL-ARCHIVE", record)}>{i18n["删除档案"]}</Button> onClick={() => handleWelfareOperate("DEL-ARCHIVE", record)}>{i18n["删除档案"]}</Button>
<Dropdown menu={{ items: stopItems }} placement="bottomRight"> <Dropdown menu={{ items: stopItems }} placement="bottomRight">
<Button type="link" icon={<MoreOutlined/>}/> <Button type="link" icon={<MoreOutlined/>}/>
</Dropdown> </Dropdown>
</Space>); </Space> : UnAuthOpts(record));
} }
}; };
break; break;
default: default:
break; break;
} }
return showOperateBtn ? [...columns, opts] : [...columns, { return [...columns, opts];
...opts, }, [columns, runStatuses, i18n]);
render: (__: any, record: any) => (
<Space>
<Button type="link" onClick={() => handleWelfareOperate("VIEW", record)}>{i18n["查看"]}</Button>
<Button type="link" onClick={() => handleWelfareOperate("log", record)}>{i18n["操作日志"]}</Button>
</Space>
)
}];
}, [columns, runStatuses, i18n, showOperateBtn]);
return (<Table return (<Table
rowKey="baseInfo" size="small" className={styles.tableWrapper} rowKey="baseInfoId" size="small" className={styles.tableWrapper}
columns={cols} dataSource={dataSource} rowSelection={rowSelection} columns={cols} dataSource={dataSource} rowSelection={rowSelection}
scroll={{ x: 1200, y: `calc(100vh - 103px)` }} scroll={{ x: 1200, y: `calc(100vh - 103px)` }}
pagination={{ pagination={{ ...paginationAction(pageInfo, i18n, onChange), size: "default" }}
...paginationAction(pageInfo, i18n, onChange),
size: "default"
}}
/>); />);
}; };

@ -44,15 +44,15 @@ const Index: FunctionComponent<Props> = (props) => {
setPageInfo(pageInfo); setPageInfo(pageInfo);
setDataSource(dataSource); setDataSource(dataSource);
setColumns(_.map(columns, it => { setColumns(_.map(columns, it => {
if (it.dataIndex === "userName") { if (it.dataIndex === "userName" || it.dataIndex === "workcode") {
return { return {
...it, width: 200, title: ( ...it, width: 140, title: (
<span dangerouslySetInnerHTML={{ __html: it.title }}></span> <span dangerouslySetInnerHTML={{ __html: it.title }}></span>
), fixed: "left" ), fixed: "left", ellipsis: true
}; };
} }
return { return {
...it, width: 200, title: ( ...it, width: 140, ellipsis: true, title: (
<span dangerouslySetInnerHTML={{ __html: it.title }}></span> <span dangerouslySetInnerHTML={{ __html: it.title }}></span>
) )
}; };

Loading…
Cancel
Save