Compare commits

...

8 Commits

Author SHA1 Message Date
lys 18956dfa58 release/2.19.1.2503.01-业务线个税 2025-12-04 15:19:54 +08:00
lys 1799d404bf master 2025-10-15 17:49:17 +08:00
lys 4ac19f78fd master 2025-08-22 15:00:57 +08:00
lys 49634c9285 master 2025-07-14 14:47:27 +08:00
lys d607c2abcf master 2025-07-03 13:44:01 +08:00
lys e35f1999fb master 2025-06-19 10:09:07 +08:00
lys 0f1f099144 master 2025-06-19 10:05:57 +08:00
lys eb126006a1 master 2025-06-19 09:19:30 +08:00
14 changed files with 418 additions and 18 deletions

View File

@ -54,6 +54,30 @@
<div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe78c;</span>
<div class="name">标记-copy</div>
<div class="code-name">&amp;#xe78c;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe604;</span>
<div class="name">标记</div>
<div class="code-name">&amp;#xe604;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe710;</span>
<div class="name">取消标记</div>
<div class="code-name">&amp;#xe710;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6f0;</span>
<div class="name">双击</div>
<div class="code-name">&amp;#xe6f0;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe61e;</span>
<div class="name">export</div>
@ -204,9 +228,9 @@
<pre><code class="language-css"
>@font-face {
font-family: 'iconfont';
src: url('iconfont.woff2?t=1741245710478') format('woff2'),
url('iconfont.woff?t=1741245710478') format('woff'),
url('iconfont.ttf?t=1741245710478') format('truetype');
src: url('iconfont.woff2?t=1750298885691') format('woff2'),
url('iconfont.woff?t=1750298885691') format('woff'),
url('iconfont.ttf?t=1750298885691') format('truetype');
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@ -232,6 +256,42 @@
<div class="content font-class">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont icon-biaoji-copy"></span>
<div class="name">
标记-copy
</div>
<div class="code-name">.icon-biaoji-copy
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-biaoji"></span>
<div class="name">
标记
</div>
<div class="code-name">.icon-biaoji
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-quxiaobiaoji"></span>
<div class="name">
取消标记
</div>
<div class="code-name">.icon-quxiaobiaoji
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shuangji"></span>
<div class="name">
双击
</div>
<div class="code-name">.icon-shuangji
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-export"></span>
<div class="name">
@ -457,6 +517,38 @@
<div class="content symbol">
<ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-biaoji-copy"></use>
</svg>
<div class="name">标记-copy</div>
<div class="code-name">#icon-biaoji-copy</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-biaoji"></use>
</svg>
<div class="name">标记</div>
<div class="code-name">#icon-biaoji</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-quxiaobiaoji"></use>
</svg>
<div class="name">取消标记</div>
<div class="code-name">#icon-quxiaobiaoji</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shuangji"></use>
</svg>
<div class="name">双击</div>
<div class="code-name">#icon-shuangji</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-export"></use>

View File

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 4257468 */
src: url('iconfont.woff2?t=1741245710478') format('woff2'),
url('iconfont.woff?t=1741245710478') format('woff'),
url('iconfont.ttf?t=1741245710478') format('truetype');
src: url('iconfont.woff2?t=1750298885691') format('woff2'),
url('iconfont.woff?t=1750298885691') format('woff'),
url('iconfont.ttf?t=1750298885691') format('truetype');
}
.iconfont {
@ -13,6 +13,22 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-biaoji-copy:before {
content: "\e78c";
}
.icon-biaoji:before {
content: "\e604";
}
.icon-quxiaobiaoji:before {
content: "\e710";
}
.icon-shuangji:before {
content: "\e6f0";
}
.icon-export:before {
content: "\e61e";
}

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,34 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "44653522",
"name": "标记-copy",
"font_class": "biaoji-copy",
"unicode": "e78c",
"unicode_decimal": 59276
},
{
"icon_id": "14559255",
"name": "标记",
"font_class": "biaoji",
"unicode": "e604",
"unicode_decimal": 58884
},
{
"icon_id": "33872224",
"name": "取消标记",
"font_class": "quxiaobiaoji",
"unicode": "e710",
"unicode_decimal": 59152
},
{
"icon_id": "39084114",
"name": "双击",
"font_class": "shuangji",
"unicode": "e6f0",
"unicode_decimal": 59120
},
{
"icon_id": "10124054",
"name": "export",

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -23,10 +23,7 @@ class CalculateService extends BasicService {
delete queryParams[key];
}
}
return this.post(
url,
queryParams
);
return this.post(url, queryParams);
};
//获取系统配置项
getSysconfcode = async ({ code }: any) => {
@ -73,7 +70,7 @@ class CalculateService extends BasicService {
return this.post(`/api/bs/hrmsalary/salaryacct/acctresult/sum`, queryParams);
};
//合计行
getAcctResultsum = async (url: string, params: any) => (this.post(url, params));
getAcctResultsum = async (url: string, params: any) => this.post(url, params);
//社保合计行
getSyMixSum = async (params: any) => {
return this.post(`/api/bs/hrmsalary/siaccount/detail/list/syMixSum`, params);
@ -86,8 +83,12 @@ class CalculateService extends BasicService {
getAcctresultSum = async (params: any) => {
return this.post(`/api/bs/hrmsalary/salaryacct/acctresult/sjjtReportSum`, params);
};
//工资单查询
getMySalaryBill = async (salaryInfoId: string) => {
return this.get(`/api/bs/hrmsalary/salaryBill/mySalaryBill?salaryInfoId=${salaryInfoId}`);
};
}
const calculateService = new CalculateService();
export default calculateService;
export default calculateService;

View File

@ -23,6 +23,7 @@ module.exports = {
"/unitTable.*": "blank",
"/aliTable.*": "blank",
"/custom-project.*": "blank",
"/MPayroll.*": "blank",
"/hiprintDesign.*": "hiPrint",
"/manage.*": "manage",
"/portal.*": "template",
@ -36,4 +37,4 @@ module.exports = {
"/500": "blank",
"/": "template"
}
};
};

View File

@ -0,0 +1,136 @@
.pbmc_body {
height: calc(100% - 50px);
background: #f6f6f6;
overflow: auto;
font-size: 12px;
.weapp-salary-payroll-mobile-preview {
width: 100%;
height: 100%;
overflow-y: auto;
.bill-container {
background: #f6f6f6;
.space {
width: 100%;
display: flex;
align-items: center;
justify-content: flex-end;
margin-bottom: 16px;
.ant-btn {
margin-right: 16px;
}
}
.bill-info-header {
padding-top: 16px;
.title {
padding: 0 16px;
font-size: 19px;
font-weight: 700;
margin-bottom: 12px;
text-align: center;
}
.time {
padding: 0 16px;
font-size: 12px;
color: #999;
}
.img {
margin-top: 20px;
width: 100%;
img {
width: 100%;
}
}
}
.top {
padding-bottom: 0;
}
.footer {
padding-top: 8px;
}
.corporate-culture-text {
text-align: left;
color: #111;
padding: 8px 16px;
white-space: pre-wrap;
word-break: break-all;
}
.salary-detail-table-container {
padding-top: 8px;
.salary-group {
border-top: 1px solid #f2f2f2;
margin-bottom: 16px;
.group-title {
background: #fff;
display: flex;
align-items: center;
min-height: 45px;
padding: 0 16px;
border-bottom: 1px solid #f2f2f2;
font-weight: bolder;
font-size: 14px;
}
.group-list {
.list-item {
display: flex;
min-height: 45px;
border-bottom: 1px solid #f2f2f2;
width: 100%;
background: #fff;
.item-name {
padding: 8px 16px;
width: 50%;
display: flex;
align-items: center;
background: #fbfbfb;
border-right: 1px solid #f2f2f2;
flex-shrink: 0;
}
.item-count {
display: flex;
align-items: center;
padding: 16px;
white-space: pre-wrap;
word-break: break-all;
}
}
}
}
}
}
}
}
.pbmc_footer {
position: relative;
height: 50px;
.pbmcf_indicator {
position: absolute;
bottom: 16px;
left: 50%;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
width: 110px;
height: 4px;
background-color: #ebebeb;
border-radius: 2px;
}
}

View File

@ -0,0 +1,119 @@
import React, { useCallback, useEffect, useMemo, useState } from "react";
import styles from "./index.less";
import { Util } from "@/utils";
import cs from "classnames";
import API from "@/api";
interface OwnProps {}
type Props = OwnProps;
const MPayroll: React.FC<Props> = (props) => {
const [mySalaryBillData, setMySalaryBillData] = useState<any>({});
useEffect(() => {
getMySalaryBill();
return () => {};
}, []);
const getMySalaryBill = useCallback(() => {
API.CalculateService.getMySalaryBill(Util.getUrlData("salaryInfoId")).then(({ data: res }) => {
const { data, status } = res || {};
if (status) setMySalaryBillData(data);
});
}, []);
const dealTemplate = (itemTypeList: any, type: string) => {
let cloneItemTypeList = _.cloneDeep(itemTypeList);
let showData: any = [],
onlyOneGrup = false;
cloneItemTypeList.forEach((group: any) => {
const { items, groupName, groupId } = group;
if (items.length !== 0) {
items.forEach((item: any) => {
item.salaryItemValue = !_.isNil(item.salaryItemValue) ? item.salaryItemValue : "";
});
if (items.length % 2 && type === "pc") items.push({});
showData.push({ groupId, groupName, items });
}
});
if (cloneItemTypeList.length === 1) {
onlyOneGrup = true;
cloneItemTypeList[0].name = "";
}
return { onlyOneGrup, showData };
};
const salaryTemplate = useMemo(() => {
return !_.isEmpty(mySalaryBillData) ? mySalaryBillData?.salaryTemplate : {};
}, [mySalaryBillData]);
const itemTypeList = useMemo(() => {
return !_.isEmpty(mySalaryBillData) ? [mySalaryBillData?.employeeInformation, ...mySalaryBillData?.salaryGroups] : [];
}, [mySalaryBillData]);
const payrollData: any = useMemo(() => {
return !_.isEmpty(itemTypeList)
? dealTemplate(
_.filter(itemTypeList, (o) => !!o),
"mobile"
)
: {};
}, [mySalaryBillData, itemTypeList]);
console.log(payrollData);
return (
<>
<div className={styles.pbmc_body}>
<div className={styles["weapp-salary-payroll-mobile-preview"]}>
<div className={styles["bill-container"]}>
<div className={styles["bill-info-header"]}>
<div className={styles["title"]}>{salaryTemplate?.theme || ""}</div>
</div>
{!payrollData?.onlyOneGrup && salaryTemplate?.textContentPosition == 1 && salaryTemplate.textContent && (
<div className={cs(styles["corporate-culture-text"], styles["top"])} title={salaryTemplate.textContent} dangerouslySetInnerHTML={{ __html: salaryTemplate.textContent }} />
)}
<div className={styles["salary-detail-table-container"]}>
{!_.isEmpty(payrollData?.showData) &&
payrollData?.showData.map((groupItem: any, index: number) => {
if (!groupItem) return null;
const { groupId, groupName, items = [] } = groupItem;
return (
<div className={styles["salary-group"]} key={groupId || index}>
{groupName ? <div className={styles["group-title"]}>{groupName}</div> : null}
<div className={styles["group-list"]}>
{payrollData?.onlyOneGrup && salaryTemplate?.textContentPosition == "1" && salaryTemplate.textContent && (
<div className={cs(styles["list-item"], styles["top"])}>
<div></div>
<div>{salaryTemplate.textContent}</div>
</div>
)}
{items.map((templatItem: any, index: number) => {
const { salaryItemValue, name, salaryItemShowName } = templatItem || {};
return (
<div className={styles["list-item"]} key={index}>
<div className={styles["item-name"]} title={salaryItemShowName || name}>
<span>{salaryItemShowName || name || ""}</span>
</div>
<div className={styles["item-count"]}>{salaryItemValue}</div>
</div>
);
})}
{payrollData?.onlyOneGrup && salaryTemplate?.textContentPosition == "2" && salaryTemplate.textContent && (
<div className={styles["list-item"]}>
<div></div>
<div>{salaryTemplate.textContent}</div>
</div>
)}
</div>
</div>
);
})}
</div>
{!payrollData?.onlyOneGrup && salaryTemplate?.textContentPosition == 2 && salaryTemplate.textContent && (
<div className={cs(styles["corporate-culture-text"], styles["footer"])} title={salaryTemplate.textContent} dangerouslySetInnerHTML={{ __html: salaryTemplate.textContent }} />
)}
</div>
</div>
</div>
<div className={styles.pbmc_footer}>
<div className={styles.pbmcf_indicator}></div>
</div>
</>
);
};
export default MPayroll;

View File

@ -198,7 +198,7 @@ const index: FunctionComponent<Props> = (props) => {
return (
<Dropdown menu={{ items: !item.calcDetail || item.rightClickType ? items : [] }} trigger={["contextMenu"]} overlayClassName={styles.contextMenu} destroyPopupOnHide>
<span className={styles.contentSpan}>
<span title={text} className={styles.contentTitle} style={{ color: `${record?.[item.dataIndex + "_color"]}` }}>
<span title={text} className={styles.contentTitle} style={record?.[item.dataIndex + "_color"] ? { color: `${record?.[item.dataIndex + "_color"]}` } : {}}>
{text}
</span>
{record.lockItems && record.lockItems.includes(item.dataIndex) ? <LockOutlined title={item.i18n["锁定的项目值"]} /> : null}

View File

@ -46,7 +46,7 @@ export function renderCols(initialState: any[], type: string, i18n?: AnyObject,
};
break;
case "paymentOrganization":
col = { ...col, width: 200 };
col = { ...col, width: g.width || 200 };
break;
case "socialNum":
case "otherNum":
@ -494,6 +494,12 @@ export function renderCols(initialState: any[], type: string, i18n?: AnyObject,
return col;
})
];
} else if (type === "cusTitle") {
return [
..._.map(initialState, (g) => {
return { ...g, title: <span dangerouslySetInnerHTML={{ __html: g.title }} /> };
})
];
}
return initialState;
}, [initialState, type, i18n, extraParams]);

View File

@ -71,6 +71,7 @@ export const exceptStr = (str) => {
};
export const paginationFun = (tableListPageObj, sizeChange, onChange, i18n = {}) => {
const pageSizeOptions= tableListPageObj?.pageSizeOptions || ["10", "20", "50", "100"];
return {
current: tableListPageObj.pageNum || tableListPageObj.current,
pageSize: tableListPageObj.size || tableListPageObj.pageSize,
@ -78,7 +79,7 @@ export const paginationFun = (tableListPageObj, sizeChange, onChange, i18n = {})
showTotal: total => `${i18n["共"] ? i18n["共"] : "共"} ${total} ${i18n["条"] ? i18n["条"] : "条"}`,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ["10", "20", "50", "100"],
pageSizeOptions,
onShowSizeChange: (page, size) => {
const { total } = tableListPageObj;
sizeChange({
@ -122,4 +123,4 @@ export const toDecimal_n = (num, decimalPlaces) => {
const multiplier = Math.pow(10, decimalPlaces);
const roundedNum = Math.round(num * multiplier) / multiplier;
return roundedNum.toFixed(decimalPlaces);
};
};