Merge branch 'feature/0612-工资单水印设置' into release/2.8.3.2306.02

This commit is contained in:
黎永顺 2023-06-26 11:30:35 +08:00
commit 229884d9ed
24 changed files with 1621 additions and 399 deletions

View File

@ -367,3 +367,24 @@ export const getAvailableSalaryItemSet = (params) => {
export const salaryBillSendSum = (params) => {
return postFetch("/api/bs/hrmsalary/salaryBill/send/sum", params);
};
//工资单发放-发送短信验证码
export const sendMobileCode = (params) => {
return postFetch("/api/bs/hrmsalary/salaryBill/sendMobileCode", params);
};
//工资单-验证方式
export const payrollCheckType = params => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryBill/payrollCheckType", "GET", params);
};
// 工资单基础设置-获取设置列表
export const getSalaryBillBaseSetForm = (id) => {
return WeaTools.callApi("/api/bs/hrmsalary/salaryBill/baseSet/getForm", "get", {});
};
//工资单基础设置-保存工资单基础设置(设置水印)
export const salaryBillBaseSetSave = (params) => {
return postFetch("/api/bs/hrmsalary/salaryBill/baseSet/save", params);
};
//工资单基础设置-保存工资单基础设置(水印预览)
export const salaryBillBaseSetPreviewWaterMark = (params) => {
return postFetch("/api/bs/hrmsalary/salaryBill/baseSet/previewWaterMark", params);
};

View File

@ -1,53 +1,57 @@
import { WeaTools } from 'ecCom';
import { postFetch } from '../util/request';
import { WeaTools } from "ecCom";
import { postFetch } from "../util/request";
//通用字典表 {enumClass:""}
export const commonEnumList = (params) => {
return WeaTools.callApi('/api/bs/hrmsalary/common/enum/list', 'GET', params);
}
return WeaTools.callApi("/api/bs/hrmsalary/common/enum/list", "GET", params);
};
export const sysOrderRule = params => {
return WeaTools.callApi('/api/bs/hrmsalary/sys/orderRule', 'GET', params);
}
return WeaTools.callApi("/api/bs/hrmsalary/sys/orderRule", "GET", params);
};
//保存排序规则
export const updateOrderRule = (params) => {
return postFetch('/api/bs/hrmsalary/sys/updateOrderRule', params);
}
return postFetch("/api/bs/hrmsalary/sys/updateOrderRule", params);
};
//导入规则详情信息
export const sysConfCodeRule = params => {
return WeaTools.callApi('/api/bs/hrmsalary/sys/conf/code', 'GET', params);
}
return WeaTools.callApi("/api/bs/hrmsalary/sys/conf/code", "GET", params);
};
//保存导入规则
export const saveMatchEmployeeModeRule = (params) => {
return postFetch('/api/bs/hrmsalary/sys/saveMatchEmployeeModeRule', params);
}
return postFetch("/api/bs/hrmsalary/sys/saveMatchEmployeeModeRule", params);
};
//应用配置查询
export const queryAppsetting = (params) => {
return WeaTools.callApi('/api/bs/hrmsalary/sys/app/setting', 'GET', params);
}
return WeaTools.callApi("/api/bs/hrmsalary/sys/app/setting", "GET", params);
};
//加密配置保存
export const saveEncryptSetting = (params) => {
return postFetch('/api/bs/hrmsalary/sys/app/setting/saveEncryptSetting', params);
}
return postFetch("/api/bs/hrmsalary/sys/app/setting/saveEncryptSetting", params);
};
//加密配置保存
export const appSettingSave = (params) => {
return postFetch('/api/bs/hrmsalary/sys/app/setting/save', params);
}
return postFetch("/api/bs/hrmsalary/sys/app/setting/save", params);
};
//获取加密进度条
export const getEncryptProgress = params => {
return WeaTools.callApi('/api/bs/hrmsalary/sys/app/getEncryptProgress', 'GET', params);
}
return WeaTools.callApi("/api/bs/hrmsalary/sys/app/getEncryptProgress", "GET", params);
};
//保存报税规则
export const operateTaxDeclarationFunction = (params) => {
return postFetch('/api/bs/hrmsalary/sys/operateTaxDeclarationFunction', params);
}
return postFetch("/api/bs/hrmsalary/sys/operateTaxDeclarationFunction", params);
};
//保存匹配规则
export const saveSalaryAcctEmployeeRule = (params) => {
return postFetch("/api/bs/hrmsalary/sys/saveSalaryAcctEmployeeRule", params);
};
//保存薪酬统计报表
export const reportStatisticsReportSave = (params) => {
return postFetch('/api/bs/hrmsalary/report/statistics/report/save', params);
}
return postFetch("/api/bs/hrmsalary/report/statistics/report/save", params);
};
//薪酬统计维度下拉列表
export const reportGetForm = params => {
return WeaTools.callApi('/api/bs/hrmsalary/report/statistics/report/getForm', 'GET', params);
}
return WeaTools.callApi("/api/bs/hrmsalary/report/statistics/report/getForm", "GET", params);
};

View File

@ -0,0 +1,94 @@
/*
* Author: 黎永顺
* name: 验证码弹框
* Description:
* Date: 2023/6/16
*/
import React, { Component } from "react";
import { WeaDialog, WeaError, WeaFormItem, WeaInput, WeaLocaleProvider, WeaSearchGroup } from "ecCom";
import { sendMobileCode } from "../../apis/payroll";
import { Button } from "antd";
import "./index.less";
const { getLabel } = WeaLocaleProvider;
class Index extends Component {
constructor(props) {
super(props);
this.state = {
captcha: "",
time: 60
};
this.timeRef = null;
}
componentWillUnmount() {
clearInterval(this.timeRef);
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible && !nextProps.visible) {
clearInterval(this.timeRef);
this.setState({ captcha: "", time: 60 });
}
}
handleSendCaptcha = () => {
sendMobileCode({ id: this.props.id }).then(({ status, data }) => {
if (status) {
console.log(data);
this.timeRef = setInterval(() => {
const { time } = this.state;
this.setState({ time: time - 1 }, () => {
if (this.state.time === -1) {
clearInterval(this.timeRef);
this.setState({ time: 60 });
}
});
}, 1000);
}
});
};
handleConfirm = () => {
if (!this.state.captcha) {
this.refs.weaError.showError();
// return
}
this.props.onCancel();
this.props.onConfirm();
};
render() {
const { captcha, time } = this.state;
return (
<WeaDialog
initLoadCss {...this.props} style={{ width: 550 }}
className="captchaWrapper" title={getLabel(111, "验证码验证")}
buttons={[
<Button type="primary" onClick={this.handleConfirm}>{getLabel(826, "确定")}</Button>
]}
>
<WeaSearchGroup needTigger={false} title="" showGroup>
<WeaFormItem
label={getLabel(111, "验证码")}
labelCol={{ span: 8 }}
wrapperCol={{ span: 16 }}
>
<WeaError tipPosition="bottom" ref="weaError" error={getLabel(826, "验证码未填写")}>
<div className="captchaInputBox">
<WeaInput value={captcha} onChange={captcha => this.setState({ captcha })}/>
<Button type="primary" onClick={this.handleSendCaptcha} disabled={time !== 60}>
{
time === 60 ? getLabel(111, "发送验证码") : `${time}S`
}
</Button>
</div>
</WeaError>
</WeaFormItem>
</WeaSearchGroup>
</WeaDialog>
);
}
}
export default Index;

View File

@ -0,0 +1,29 @@
.captchaWrapper {
.wea-dialog-body {
padding: 30px 20px;
.wea-form-item-wrapper {
.wea-error {
width: 100%;
.captchaInputBox {
display: flex;
align-items: center;
.wea-input-normal {
flex: 1;
}
button {
padding: 8px 10px;
border-radius: 0;
min-width: 80px;
text-align: center;
height: 30px;
line-height: 15px;
}
}
}
}
}
}

View File

@ -0,0 +1,84 @@
import React, { Component } from "react";
import { WeaLocaleProvider, WeaTools, WeaUpload } from "ecCom";
import { Icon, Modal } from "antd";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
const { viewer } = WeaTools;
class ImageUploadList extends Component {
constructor(props) {
super(props);
this.state = {
imageUrl: ""
};
}
componentDidMount() {
const { wmImg } = this.props;
if (!_.isEmpty(wmImg)) {
this.setState({
imageUrl: wmImg[0].imgSrc
});
}
}
handleChange = (ids, list) => {
this.setState({
imageUrl: list[0].imgSrc
}, () => this.props.onChange([{ imgSrc: this.state.imageUrl }]));
};
handleDelete = () => {
Modal.confirm({
title: getLabel(111, "信息确认"),
content: getLabel(111, "确认要删除吗?"),
onOk: () => {
this.setState({
imageUrl: ""
}, () => this.props.onChange(null));
}
});
};
render() {
const { imageUrl } = this.state;
const uploadProps = {
uploadUrl: "/api/doc/upload/uploadFile",
listType: "img",
limitType: "jpg,jpeg,png,gif",
category: "string",
maxFilesNumber: 1,
onChange: this.handleChange
};
const imgPreviewProps = {
src: imageUrl,
width: 100,
height: 100
};
return (
<div className="uploadWrapper">
{
imageUrl &&
<div className="previewWrapper">
<img data-imgsrc={imgPreviewProps.src} {...imgPreviewProps} onClick={viewer} alt=""/>
<div className="operateWrapper">
<i className="icon-coms-Delete operateIcon" onClick={this.handleDelete}/>
</div>
</div>
}
{
!imageUrl &&
<WeaUpload {...uploadProps}>
<div className="upload-select-picture-card">
<Icon type="plus"/>
<div className="uploadText">{getLabel(111, "上传图片")}</div>
</div>
</WeaUpload>
}
</div>
);
}
}
export default ImageUploadList;

View File

@ -0,0 +1,68 @@
.textSetting {
.uploadWrapper {
display: flex;
align-items: center;
position: relative;
.previewWrapper {
border: 1px solid #d9d9d9 !important;
img {
width: 100%;
height: 100%;
margin-left: 0 !important;
cursor: pointer;
}
.operateWrapper {
display: none;
}
}
.previewWrapper:hover {
.operateWrapper {
display: flex;
position: absolute;
align-items: center;
justify-content: flex-end;
width: 30px;
height: 20px;
background-color: rgba(0, 0, 0, 0.3);
bottom: 4px;
right: 13px;
border-radius: 3px;
padding-right: 4px;
}
}
}
.upload-select-picture-card, .previewWrapper {
border: 1px dashed #d9d9d9;
width: 96px;
height: 96px;
padding: 0;
border-radius: 6px;
background-color: #fbfbfb;
text-align: center;
cursor: pointer;
-webkit-transition: border-color .3s ease;
-o-transition: border-color .3s ease;
transition: border-color .3s ease;
display: flex;
flex-direction: column;
justify-content: center;
margin-right: 8px;
margin-bottom: 8px;
span.rc-upload {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
}
.upload-select-picture-card:hover {
border-color: #2db7f5;
}
}

View File

@ -35,6 +35,8 @@ import FieldManagement from "./pages/fieldManagement";
import AnalysisOfSalaryStatistics from "./pages/analysisOfSalaryStatistics";
import EmployeeList from "./pages/employeeView";
import ReportView from "./pages/reportView";
import MySalaryView from "./pages/mySalary/mySalaryView";
import WatermarkPreview from "./pages/payroll/watermarkPreview";
import stores from "./stores";
import "./style/index";
@ -53,6 +55,7 @@ const SocialSecurityBenefits = (props) => props.children;
const DataAcquisition = (props) => props.children;
// mySalary 我的薪资福利
// mySalaryView 我的薪资福利-查看工资单
// socialSecurityBenefits 社保福利
// programme 社保福利方案
// archives 社保福利档案
@ -91,6 +94,7 @@ const Routes = (
onEnter={getLocaleLabel}
component={Home}>
<Route key="mySalary" path="mySalary" component={MySalary}/>
<Route key="mySalaryView" path="mySalary/:salaryInfoId" component={MySalaryView}/>
<Route
key="socialSecurityBenefits"
path="socialSecurityBenefits"
@ -135,6 +139,7 @@ const Routes = (
/>
<Route key="compareDetail" path="compareDetail" component={CompareDetail}/>
<Route key="payroll" path="payroll" component={Payroll}/>
<Route key="watermarkPreview" path="payroll/watermark/preview" component={WatermarkPreview}/>
<Route key="payrollGrant" path="payrollGrant" component={PayrollGrant}/>
<Route key="payrollDetail" path="payrollDetail" component={PayrollDetail}/>
<Route

View File

@ -8,7 +8,9 @@ import ComputerTemplate from "../payroll/templatePreview/computerTemplate";
import PhoneTemplate from "../payroll/templatePreview/phoneTemplate";
import "../payroll/templatePreview/index.less";
import * as API from "../../apis/mySalaryBenefits";
import { payrollCheckType } from "../../apis/payroll";
import "./index.less";
import CaptchaModal from "../../components/captchaModal";
@inject("mySalaryStore")
@observer
@ -17,6 +19,7 @@ export default class MobilePayroll extends React.Component {
super(props);
this.state = {
visible: false,
captchaVisible: false,
authCode: "",
mySalaryBillData: {
employeeInformation: {},
@ -26,13 +29,20 @@ export default class MobilePayroll extends React.Component {
this.id = "";
}
componentWillMount() {
async componentWillMount() {
const type = getQueryString("type");
this.id = getQueryString("id");
const { mySalaryStore: { init } } = this.props;
type !== "phone" && init(false);
type === "phone" && this.initMobile();
this.getMySalaryBill(this.id);
const { data, status } = await payrollCheckType();
if (type !== "phone") {
if (status && data === "PWD") {
init(false);
} else {
this.setState({ captchaVisible: true });
}
}
type === "phone" && this.initMobile();
}
initMobile = () => {
@ -96,7 +106,7 @@ export default class MobilePayroll extends React.Component {
render() {
const { mySalaryStore: { clearLoading } } = this.props;
const { mySalaryBillData, visible } = this.state;
const { mySalaryBillData, visible, captchaVisible } = this.state;
const type = getQueryString("type");
const employeeInformation = mySalaryBillData.employeeInformation ? mySalaryBillData.employeeInformation : {};
const salaryGroups = mySalaryBillData.salaryGroups ? mySalaryBillData.salaryGroups : [];
@ -148,6 +158,11 @@ export default class MobilePayroll extends React.Component {
</div>
</Authority>
}
<CaptchaModal
visible={captchaVisible} id={getQueryString("id")}
onCancel={() => this.setState({ captchaVisible: false })}
onConfirm={() => this.props.mySalaryStore.setInitEmVerify()}
/>
</div>
);
}

View File

@ -1,15 +1,15 @@
import React from "react";
import { inject, observer } from "mobx-react";
import { DatePicker } from "antd";
import { WeaNewScroll, WeaTop } from "ecCom";
import { WeaLocaleProvider, WeaNewScroll, WeaTop } from "ecCom";
import { renderNoright } from "../../util"; // 渲染form数据的方法因为多个页面都会使用所以抽的公共方法在util中
import CustomTab from "../../components/customTab";
import moment from "moment";
import PayrollModal from "./payrollModal";
import Authority from "./authority";
import CustomPaginationTable from "../../components/customPaginationTable";
import "./index.less";
const { getLabel } = WeaLocaleProvider;
const { RangePicker } = DatePicker;
@inject("mySalaryStore")
@ -28,9 +28,9 @@ export default class MySalary extends React.Component {
this.historyPageInfo = { current: 1, pageSize: 10 };
}
componentWillMount() {
const { mySalaryStore: { init } } = this.props;
init();
componentDidMount() {
const { mySalaryStore: { mySalaryBillList } } = this.props;
mySalaryBillList([moment().startOf("year").format("YYYY-MM"), moment().format("YYYY-MM")]);
}
// 查看工资单
@ -61,9 +61,8 @@ export default class MySalary extends React.Component {
dataIndex: "operate",
render: (text, record) => {
return (
<a onClick={() => {
this.handleView(record);
}}>查看</a>
<a target="_blank"
href={`${window.location.origin}/spa/hrmSalary/static/index.html#/main/hrmSalary/mySalary/${record.id}`}>{getLabel(33564, "查看")}</a>
);
}
});
@ -114,7 +113,6 @@ export default class MySalary extends React.Component {
myBillPageInfo
} = mySalaryStore;
const { salaryBillVisible, salaryInfoId, salaryRange } = this.state;
if (!hasRight && !loading) return renderNoright();
const topTab = [
{
@ -141,64 +139,62 @@ export default class MySalary extends React.Component {
};
return (
<div className="mySalaryBenefitsWrapper">
<Authority ecId={`${this && this.props && this.props.ecId || ""}_Authority@lulowc`} store={mySalaryStore}>
<WeaTop
title="我的薪资福利" // 文字
icon={<i className="icon-coms-fa"/>} // 左侧图标
iconBgcolor="#F14A2D" // 左侧图标背景色
showDropIcon={false} // 是否显示下拉按钮
>
<CustomTab
topTab={topTab}
searchOperationItem={renderSearchOperationItem()}
onChange={(v) => {
this.handleTabChange(v);
this.setState({ selectedKey: v });
}}
/>
<div className="tableWrapper">
<WeaNewScroll height="100%">
{
this.state.selectedKey === "0" &&
<CustomPaginationTable
loading={loading}
columns={this.getColumns()}
dataSource={myBillDataSource ? myBillDataSource : []}
total={myBillPageInfo.total}
current={myBillPageInfo.pageNum}
pageSize={this.pageInfo.pageSize}
onPageChange={(value) => {
this.pageInfo.current = value;
this.handlePageChange();
}}
onShowSizeChange={(current, pageSize) => {
this.pageInfo = { current, pageSize };
this.handlePageChange();
}}
/>
}
{
this.state.selectedKey === "2" &&
<CustomPaginationTable
columns={recordListColumns}
dataSource={recordListDataSource}
total={recordListPageInfo.total}
current={recordListPageInfo.pageNum}
pageSize={this.historyPageInfo.pageSize}
onPageChange={(value) => {
this.historyPageInfo.current = value;
this.handleHistoryPageChange();
}}
onShowSizeChange={(current, pageSize) => {
this.historyPageInfo = { current, pageSize };
this.handleHistoryPageChange();
}}
/>
}
</WeaNewScroll>
</div>
</WeaTop>
</Authority>
<WeaTop
title="我的薪资福利" // 文字
icon={<i className="icon-coms-fa"/>} // 左侧图标
iconBgcolor="#F14A2D" // 左侧图标背景色
showDropIcon={false} // 是否显示下拉按钮
>
<CustomTab
topTab={topTab}
searchOperationItem={renderSearchOperationItem()}
onChange={(v) => {
this.handleTabChange(v);
this.setState({ selectedKey: v });
}}
/>
<div className="tableWrapper">
<WeaNewScroll height="100%">
{
this.state.selectedKey === "0" &&
<CustomPaginationTable
loading={loading}
columns={this.getColumns()}
dataSource={myBillDataSource ? myBillDataSource : []}
total={myBillPageInfo.total}
current={myBillPageInfo.pageNum}
pageSize={this.pageInfo.pageSize}
onPageChange={(value) => {
this.pageInfo.current = value;
this.handlePageChange();
}}
onShowSizeChange={(current, pageSize) => {
this.pageInfo = { current, pageSize };
this.handlePageChange();
}}
/>
}
{
this.state.selectedKey === "2" &&
<CustomPaginationTable
columns={recordListColumns}
dataSource={recordListDataSource}
total={recordListPageInfo.total}
current={recordListPageInfo.pageNum}
pageSize={this.historyPageInfo.pageSize}
onPageChange={(value) => {
this.historyPageInfo.current = value;
this.handleHistoryPageChange();
}}
onShowSizeChange={(current, pageSize) => {
this.historyPageInfo = { current, pageSize };
this.handleHistoryPageChange();
}}
/>
}
</WeaNewScroll>
</div>
</WeaTop>
{
salaryBillVisible && <PayrollModal
visible={salaryBillVisible}

View File

@ -0,0 +1,66 @@
/*
* Author: 黎永顺
* name: 查看我的薪资-工资单
* Description:
* Date: 2023/6/14
*/
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { toJS } from "mobx";
import Authority from "./authority";
import ComputerTemplate from "../payroll/templatePreview/computerTemplate";
import { payrollCheckType } from "../../apis/payroll";
import CaptchaModal from "../../components/captchaModal";
import "../payroll/templatePreview/index.less";
@inject("mySalaryStore")
@observer
class MySalaryView extends Component {
constructor(props) {
super(props);
this.state = {
captchaVisible: false
};
}
async componentDidMount() {
const { mySalaryStore: { getMySalaryBill, init }, params: { salaryInfoId } } = this.props;
const { data, status } = await payrollCheckType();
if (status && data === "PWD") {
init(false);
} else {
this.setState({ captchaVisible: true });
}
getMySalaryBill(Number(salaryInfoId));
}
render() {
const { captchaVisible } = this.state;
const { mySalaryStore, params: { salaryInfoId } } = this.props;
const { mySalaryBill } = mySalaryStore;
const employeeInformation = mySalaryBill.employeeInformation && toJS(mySalaryBill.employeeInformation);
const salaryGroups = mySalaryBill.salaryGroups && toJS(mySalaryBill.salaryGroups);
return (
<React.Fragment>
<Authority ecId={`${this && this.props && this.props.ecId || ""}_Authority@lulowc`} store={mySalaryStore}>
<div style={{ height: "100%", overflow: "auto" }}>
<div className="templatePreview">
<ComputerTemplate
isPreview isMsgPreview
salaryTemplateShowSet={JSON.stringify(mySalaryBill.salaryTemplate)}
salaryItemSet={!_.isEmpty(salaryGroups) ? JSON.stringify([employeeInformation, ...salaryGroups]) : []}
/>
</div>
</div>
</Authority>
<CaptchaModal
visible={captchaVisible} id={salaryInfoId}
onCancel={() => this.setState({ captchaVisible: false })}
onConfirm={() => mySalaryStore.setInitEmVerify()}
/>
</React.Fragment>
);
}
}
export default MySalaryView;

View File

@ -92,7 +92,7 @@ export default class SalarySendList extends React.Component {
title: "操作",
key: "operate",
render: (text, record) => {
const { sendNum, sendTotal, salaryAcctType, haveBackCalc } = record;
const { sendNum, sendTotal, salaryAcctType, haveBackCalc, canSeeDetail } = record;
//显示发放
const showGrant = haveBackCalc === 1 && salaryAcctType === 0;
return (
@ -100,7 +100,7 @@ export default class SalarySendList extends React.Component {
<a href="javascript:void(0);" onClick={() => this.handleGrant(record)}
style={{ marginRight: 10 }}>发放</a>
{
!showGrant &&
canSeeDetail &&
<a href="javascript:void(0);" onClick={() => this.handleShowDetail(record)}
style={{ marginRight: 10 }}>查看详情</a>
}

View File

@ -0,0 +1,14 @@
import { WeaLocaleProvider } from "ecCom";
const getLabel = WeaLocaleProvider.getLabel;
export const commonVariables = [
{ id: "HRM_Name", name: getLabel(111, "当前操作者姓名")},
{ id: "HRM_Num", name: getLabel(111, "当前操作者编号")},
{ id: "HRM_Mobile", name: getLabel(111, "当前操作者移动电话")},
{ id: "HRM_Email", name: getLabel(111, "当前操作者电子邮件")},
{ id: "HRM_CurrentOperatorId", name: getLabel(111, "当前操作者人员id")},
{ id: "HRM_Department", name: getLabel(111, "当前操作者部门")},
{ id: "HRM_SecondDepartment", name: getLabel(111, "分部")},
{ id: "HRM_CurrentDate", name: getLabel(111, "当前日期")},
{ id: "HRM_CurrentTime", name: getLabel(111, "当前时间")},
];

View File

@ -46,3 +46,124 @@
}
}
}
.waterMarkSetWrapper, .wmContentWrapper {
.rodal {
.rodal-dialog {
& > div:nth-child(2) {
height: calc(100% - 52px) !important;
padding-bottom: 0 !important;
}
}
}
.waterMark-select-header {
padding: 0 5px;
}
.wea-transfer-list-wrapper {
.transfer-tree {
li {
cursor: pointer;
margin: 10px 0;
}
}
}
.wea-slide-modal-content {
padding-bottom: 65px;
}
.wmTitle {
float: left;
margin-left: 16px;
}
.slideBottom {
display: flex;
justify-content: flex-end;
padding: 16px 25px;
border-top: 1px solid #e5e5e5;
position: absolute;
width: 100%;
bottom: 0;
background: #f4f4f4;
button:first-child {
margin-right: 16px;
}
}
.waterMarkWrapper {
padding-top: 16px;
}
.wmContGroup {
.wea-title {
border: 1px solid #e5e5e5;
border-bottom: none;
}
.wea-content {
padding-top: 0;
}
.content-box {
padding: 16px;
.ant-col-18 {
height: 319px;
}
}
.wea-form-cell-wrapper {
border-bottom: none;
}
}
.mt16 {
.wea-form-cell-wrapper {
border: 1px solid #e5e5e5;
}
}
.wea-form-cell-wrapper {
border: 1px solid #e5e5e5;
border-bottom: none;
}
.wea-form-item {
padding: 5px 16px;
border-bottom: 1px solid #e5e5e5;
}
.textSetting {
display: flex;
align-items: center;
margin-top: 7px;
min-width: 200px;
.icon-coms-Flow-setting {
font-size: 16px;
color: #666;
cursor: pointer;
}
img {
margin-left: 5px;
}
}
.previewBtn {
cursor: pointer;
color: #2db7f5;
position: relative;
margin-left: 10px;
}
.txtPrew {
margin-left: 20px !important;
}
}

View File

@ -0,0 +1,201 @@
/*
* Author: 黎永顺
* name: 水印设置-弹框
* Description:
* Date: 2023/6/13
*/
import React, { Component } from "react";
import {
WeaError,
WeaFormItem,
WeaHelpfulTip,
WeaInputNumber,
WeaLocaleProvider,
WeaSearchGroup,
WeaSelect,
WeaSlideModal
} from "ecCom";
import { Button } from "antd";
import ImageUploadList from "../../../components/upload";
import WmContentSetModal from "./wmContentSetModal";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
class WaterMarkSetModal extends Component {
constructor(props) {
super(props);
this.state = {
wmClassify: "text", wmNoTransparent: 0,
wmRotate: 0, wmImg: null, wmcontSet: {
visible: false, textSet: {}
}
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible && nextProps.visible) {
const { watermarkSetting } = nextProps;
const {
wmClassify = "text",
wmNoTransparent = 0,
wmRotate = 0,
wmImg,
wmOriginText,
wmHeight,
wmWidth,
pureWmText,
wmSelectedFieldIds,
wmText
} = watermarkSetting;
if (wmClassify === "text") {
this.setState({
wmClassify, wmNoTransparent, wmRotate,
wmcontSet: {
...this.state.wmcontSet, textSet: wmOriginText ? {
wmOriginText, wmHeight, wmWidth, pureWmText, wmSelectedFieldIds, wmText
} : {}
}
});
} else {
this.setState({
wmClassify, wmNoTransparent, wmRotate, wmImg
});
}
}
}
handleCustomSave = () => {
const { wmClassify, wmImg, wmRotate, wmNoTransparent, wmcontSet } = this.state;
if ((wmClassify === "text" && _.isEmpty(wmcontSet.textSet)) || (wmClassify !== "text" && !wmImg)) {
this.refs.watermarkContError.showError();
return;
}
if (wmClassify === "text") {
this.props.onChange({
wmSetting: {
wmClassify, ...wmcontSet.textSet,
wmNoTransparent, wmRotate
}
});
} else {
this.props.onChange({
wmSetting: {
wmClassify, wmImg,
wmNoTransparent, wmRotate
}
});
}
this.props.onClose();
};
render() {
const { wmClassify, wmNoTransparent, wmRotate, wmImg, wmcontSet } = this.state;
return (
<WeaSlideModal
{...this.props} className="waterMarkSetWrapper"
title={<span className="wmTitle">{getLabel(111, "水印设置")}</span>}
direction="right" top={0} width={800} height={100}
measureT="%" measureX="px" measureY="%"
content={
<React.Fragment>
<WeaSearchGroup showGroup needTigger={false} className="waterMarkWrapper">
<WeaFormItem label={getLabel(111, "水印类型")} labelCol={{ span: 5 }} wrapperCol={{ span: 10 }}>
<div style={{ display: "flex", alignItems: "center" }}>
<WeaSelect
value={wmClassify} detailtype={3}
options={[
{ key: "text", showname: getLabel(111, "文本") },
{ key: "image", showname: getLabel(111, "图片") }
]}
onChange={wmClassify => this.setState({ wmClassify })}
/>
<WeaHelpfulTip title={getLabel(111, "邮件发送不支持图片水印")} placement="topLeft"
style={{ marginLeft: 10 }}/>
</div>
</WeaFormItem>
<WeaFormItem label={getLabel(111, "水印类型")} labelCol={{ span: 5 }} wrapperCol={{ span: 10 }}>
{
wmClassify === "text" ?
<WeaError tipPosition="bottom" ref="watermarkContError" error={getLabel(385869, "此项必填")}>
<div className="textSetting">
<i className="icon-coms-Flow-setting"
onClick={() => this.setState({ wmcontSet: { ...wmcontSet, visible: true } })}/>
{
_.isEmpty(wmcontSet.textSet) ? <img src="/images/BacoError_wev9.png" alt=""/> :
<span className="previewBtn txtPrew"
onClick={() => {
window.open(`${window.location.origin}/spa/hrmSalary/static/index.html#/main/hrmSalary/payroll/watermark/preview`, "_blank");
}}
>
<i className="icon-coms-Selected" style={{
"color": "#093",
"marginRight": "5px"
}}/>
预览
</span>
}
</div>
</WeaError> :
<WeaError tipPosition="bottom" ref="watermarkContError" error={getLabel(385869, "此项必填")}>
<div className="textSetting">
<ImageUploadList onChange={wmImg => this.setState({ wmImg }, () => {
window.localStorage.setItem("wmSetting", JSON.stringify({
wmSetting: {
wmClassify, wmRotate, wmNoTransparent,
...this.state.wmImg
}
}));
})} wmImg={wmImg}/>
{
!wmImg ? <img src="/images/BacoError_wev9.png" alt=""/> :
<span className="previewBtn" onClick={() => {
window.open(`${window.location.origin}/spa/hrmSalary/static/index.html#/main/hrmSalary/payroll/watermark/preview`, "_blank");
}}>预览</span>
}
</div>
</WeaError>
}
</WeaFormItem>
<WeaFormItem label={getLabel(111, "不透明(百分比)")} labelCol={{ span: 5 }} wrapperCol={{ span: 10 }}>
<WeaInputNumber
min={0} max={80} precision={2} value={wmNoTransparent}
onChange={wmNoTransparent => this.setState({ wmNoTransparent })}
/>
</WeaFormItem>
<WeaFormItem label={getLabel(111, "旋转角度(逆时针)")} labelCol={{ span: 5 }} wrapperCol={{ span: 10 }}>
<WeaInputNumber
min={0} max={360} precision={2} value={wmRotate}
onChange={wmRotate => this.setState({ wmRotate })}
/>
</WeaFormItem>
</WeaSearchGroup>
<div className="slideBottom">
<Button type="primary" onClick={this.handleCustomSave}>{getLabel(111, "确定")}</Button>
<Button type="ghost" onClick={this.props.onClose}>{getLabel(111, "取消")}</Button>
</div>
{/* 水印内容设置弹框*/}
<WmContentSetModal {...wmcontSet}
onClose={textSet => this.setState({
wmcontSet: {
...wmcontSet,
visible: false,
textSet
}
}, () => {
window.localStorage.setItem("wmSetting", JSON.stringify({
wmSetting: {
wmClassify, wmRotate, wmNoTransparent,
...this.state.wmcontSet.textSet
}
}));
})}
/>
</React.Fragment>
}
/>
);
}
}
export default WaterMarkSetModal;

View File

@ -0,0 +1,188 @@
/*
* Author: 黎永顺
* name: 水印内容设置
* Description:
* Date: 2023/6/14
*/
import React, { Component } from "react";
import {
WeaFormItem,
WeaHelpfulTip,
WeaInputNumber,
WeaInputSearch,
WeaLocaleProvider,
WeaRichText,
WeaSearchGroup,
WeaSlideModal,
WeaTransfer
} from "ecCom";
import { Button, Col, message, Row } from "antd";
import { commonVariables } from "./config";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
const WeaTransferList = WeaTransfer.list;
class WmContentSetModal extends Component {
constructor(props) {
super(props);
this.state = {
wmWidth: 100,
wmHeight: 100,
wmOriginText: "",
searchV: ""
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.visible !== this.props.visible) {
this.setState({
wmWidth: nextProps.textSet.wmWidth || 100,
wmHeight: nextProps.textSet.wmHeight || 100,
wmOriginText: nextProps.textSet.wmOriginText || ""
});
} else {
this.setState({
wmWidth: 100,
wmHeight: 100,
wmOriginText: "",
searchV: ""
});
}
}
handleSaveWMContent = () => {
const html = this.refs.TextContentRichText.getData().replace(/\n/ig, "");
if (!html) {
message.warning(getLabel(111, "请输入水印内容!"));
return;
}
const { wmWidth, wmHeight } = this.state;
this.props.onClose({
wmWidth, wmHeight,
wmSelectedFieldIds: this.getHtmlAttrVal(html),
pureWmText: this.convertToPlain(html),
wmOriginText: html, wmText: this.convertToWMText(html)
});
};
convertToWMText = (html) => {
_.map(commonVariables, item => {
const { id, name } = item;
const reg = eval("/" + name + "/g");
html = html.replace(reg, `$${id}`).replace(/ data-id=\"(.*?)\"/g, "");
});
return html.replace(/ contenteditable="false"/g, "");
};
getHtmlAttrVal = (html) => {
let attrAndValueArr = html.match(/ data-id=\"(.*?)\"/g);
let valueArr = []; // 放所有该属性的值
if (!_.isEmpty(attrAndValueArr)) {
for (let i = 0; i < attrAndValueArr.length; i++) {
valueArr.push(attrAndValueArr[i].replace(/ data-id=/g, "").replace(/\"/g, ""));
}
}
return valueArr;
};
convertToPlain = (html) => {
let tempDivElement = document.createElement("div");
tempDivElement.innerHTML = html;
return tempDivElement.textContent || tempDivElement.innerText || "";
};
renderItem = (item = {}) => {
return <span>{item.name}</span>;
};
selectHeader() {
return (
<div className={"waterMark-select-header"}>
<WeaInputSearch onSearchChange={(v) => {
this.setState({ searchV: v });
}}/>
</div>
);
}
render() {
const { wmWidth, wmHeight, wmOriginText, searchV } = this.state;
const ckConfig = {
toolbar: [
{ name: "paragraph", items: ["JustifyLeft", "JustifyCenter", "JustifyRight"] },
{ name: "styles", items: ["Font", "FontSize"] },
{ name: "colors", items: ["TextColor"] }
],
removePlugins: "resize",
height: 280
};
const tempOptions = _.filter(commonVariables, (item) => {
const { name } = item;
let flag = true;
if (searchV && name) {
flag = name.indexOf(searchV) > -1;
}
return flag;
});
return (
<WeaSlideModal
{...this.props} className="wmContentWrapper" onClose={() => this.props.onClose(this.props.textSet)}
title={<span className="wmTitle">{getLabel(111, "水印内容设置")}</span>}
direction="right" top={0} width={800} height={100}
measureT="%" measureX="px" measureY="%"
content={
<React.Fragment>
<WeaSearchGroup
title={<span><span style={{ marginRight: 10 }}>{getLabel(111, "水印格式设置")}</span><WeaHelpfulTip
title={getLabel(111, "水印最小100px*100px")} placement="topLeft"/></span>}
showGroup needTigger={false} className="waterMarkWrapper wmContGroup">
<WeaFormItem label={getLabel(111, "水印宽度") + "px"} labelCol={{ span: 5 }} wrapperCol={{ span: 10 }}>
<WeaInputNumber
min={100} precision={3} value={wmWidth}
onChange={wmWidth => this.setState({ wmWidth })}
/>
</WeaFormItem>
<WeaFormItem label={getLabel(111, "水印高度") + "px"} labelCol={{ span: 5 }} wrapperCol={{ span: 10 }}>
<WeaInputNumber
min={100} precision={3} value={wmHeight}
onChange={wmHeight => this.setState({ wmHeight })}
/>
</WeaFormItem>
</WeaSearchGroup>
<WeaSearchGroup
title={getLabel(111, "内容")}
showGroup needTigger={false} className="waterMarkWrapper wmContGroup mt16">
<Row className="content-box" gutter={10}>
<Col span={18}>
<WeaRichText ckConfig={ckConfig} value={wmOriginText} ref={"TextContentRichText"}/>
</Col>
<Col span={6}>
<WeaTransferList
header={this.selectHeader()}
data={tempOptions}
renderItem={this.renderItem}
checkedCb={(keys) => {
let result = _.filter(commonVariables, (item) => item.id === keys[0]);
if (result && result.length > 0) {
this.refs.TextContentRichText.insertHTML(`&nbsp;<span contenteditable="false" data-id="${result[0].id}">${result[0].name}</span>&nbsp;`);
}
}}
height={280}
checkedKeys={[]}
/>
</Col>
</Row>
</WeaSearchGroup>
<div className="slideBottom">
<Button type="primary"
onClick={this.handleSaveWMContent}>{getLabel(111, "保存")}</Button>
<Button type="ghost"
onClick={() => this.props.onClose(this.props.textSet)}>{getLabel(111, "取消")}</Button>
</div>
</React.Fragment>
}
/>
);
}
}
export default WmContentSetModal;

View File

@ -3,8 +3,16 @@ import { inject, observer } from "mobx-react";
import { toJS } from "mobx";
import { Button, DatePicker, message, Modal } from "antd";
import moment from "moment";
import { WeaHelpfulTip, WeaInputSearch, WeaNewScroll, WeaSelect, WeaSlideModal, WeaTop } from "ecCom";
import { renderLoading } from "../../util"; // 渲染form数据的方法因为多个页面都会使用所以抽的公共方法在util中
import {
WeaHelpfulTip,
WeaInputSearch,
WeaLocaleProvider,
WeaNewScroll,
WeaSelect,
WeaSlideModal,
WeaTop
} from "ecCom";
import { renderLoading } from "../../util";
import CustomTab from "../../components/customTab";
import StepSlide from "../../components/stepSlide";
import BaseInformForm from "./stepForm/baseInformForm";
@ -12,11 +20,13 @@ import ShowSettingForm from "./stepForm/showSettingForm";
import SlideModalTitle from "../../components/slideModalTitle";
import TemplateSettingList from "./templateSettingList";
import TemplateSettingForm from "./stepForm/tmplateSettingForm";
import TemplateBaseSettings from "./templateBaseSettings";
import CopyModal from "./copyModal";
import SalarySendList from "./SalarySendList";
import { getReplenishForm } from "../../apis/payroll";
import "../dataAcquisition/cumDeduct/index.less";
const getLabel = WeaLocaleProvider.getLabel;
const { MonthPicker } = DatePicker;
@inject("payrollStore", "taxAgentStore")
@ -38,7 +48,8 @@ export default class Payroll extends React.Component {
templateCurrentId: "",
copyModalVisible: false,
startDate: moment(new Date()).startOf("year").format("YYYY-MM"),
endDate: moment(new Date()).startOf("month").format("YYYY-MM")
endDate: moment(new Date()).startOf("month").format("YYYY-MM"),
loading: false
};
this.recordId = "";
this.salaryYearMonth = [moment(new Date()).startOf("year").format("YYYY-MM"), moment(new Date()).startOf("month").format("YYYY-MM")];
@ -243,7 +254,15 @@ export default class Payroll extends React.Component {
render() {
const { payrollStore, taxAgentStore: { showOperateBtn } } = this.props;
const { loading, hasRight, templateStore, deletePayroll, templateBaseData } = payrollStore;
const {
loading,
hasRight,
templateTableSelectedRowKeys,
setTemplateTableSelectedRowKeys,
deletePayroll,
templateBaseData,
setTemplateTablePageInfo
} = payrollStore;
const { currentStep, selectedTab, templateSearchValue, templateSelect, startDate, endDate } = this.state;
if (!hasRight && !loading) { // 无权限处理
return renderLoading();
@ -256,6 +275,10 @@ export default class Payroll extends React.Component {
{
title: "工资单模板设置",
viewcondition: "1"
},
{
title: getLabel(111, "工资单模板基础设置"),
viewcondition: "2"
}
];
const renderRightOperation = () => {
@ -302,7 +325,7 @@ export default class Payroll extends React.Component {
style={{ marginLeft: 10 }}
type="ghost"
onClick={() => {
const selectedRowKeys = toJS(templateStore.selectedRowKeys);
const selectedRowKeys = toJS(templateTableSelectedRowKeys);
if (!selectedRowKeys.length) {
message.info("未选中任何数据!");
return;
@ -328,11 +351,18 @@ export default class Payroll extends React.Component {
<WeaInputSearch style={{ marginleft: "10px" }} placeholder="请输入工资单名称" value={templateSearchValue}
onChange={(value) => {
this.setState({ templateSearchValue: value });
}} onSearch={(value) => {
this.handleTemplateSearch(value);
}}/>
}}
onSearch={(value) => {
this.handleTemplateSearch(value);
}}
/>
</div>
);
} else if (this.state.selectedKey === "2") {
return <Button type="primary"
onClick={() => this.baseSetRef.salaryBillBaseSetSave()}
loading={this.state.loading}
>{getLabel(111, "保存")}</Button>;
}
};
const steps = ["基础设置", "正常核算工资单模板", "补发工资单模版"];
@ -371,7 +401,14 @@ export default class Payroll extends React.Component {
topTab={topTab}
searchOperationItem={renderRightOperation()}
onChange={(v) => {
this.setState({ selectedKey: v, stepSlideVisible: false, editSlideVisible: false });
this.setState({
selectedKey: v,
stepSlideVisible: false,
editSlideVisible: false
}, () => {
setTemplateTablePageInfo({ current: 1 });
setTemplateTableSelectedRowKeys([]);
});
}}
/>
<div className="tableWrapper">
@ -405,6 +442,13 @@ export default class Payroll extends React.Component {
onDelete={(record) => this.handleTemplateListDelete(record)}
/>
}
{
this.state.selectedKey === "2" &&
<TemplateBaseSettings
ref={dom => this.baseSetRef = dom}
onChangeLoading={loading => this.setState({ loading })}
/>
}
</WeaNewScroll>
</div>
</WeaTop>

View File

@ -0,0 +1,22 @@
.waterMarkWrapper {
.wea-form-cell-wrapper {
border: 1px solid #e5e5e5;
border-bottom: none;
}
.wea-form-item {
padding: 5px 16px;
border-bottom: 1px solid #e5e5e5;
.waterMarkTitle {
margin-left: 10px;
cursor: pointer;
color: #2db7f5;
position: absolute;
display: inline-block;
width: 48px;
top: 50%;
margin-top: -10px;
}
}
}

View File

@ -310,7 +310,7 @@ export default class PayrollGrant extends React.Component {
dataIndex: "",
display: true,
render: (text, record) => {
if (record.sendStatus === "1" && !notShowGrantOrWithdraw) {
if (record.sendStatus === "1" && salarySendDetailBaseInfo.canSend) {
return (
<a
href="javascript:void(0);"
@ -318,7 +318,7 @@ export default class PayrollGrant extends React.Component {
撤回
</a>
);
} else if (!notShowGrantOrWithdraw) {
} else if (salarySendDetailBaseInfo.canSend) {
return (
<a
href="javascript:void(0);"
@ -370,7 +370,7 @@ export default class PayrollGrant extends React.Component {
更多
</Dropdown.Button>
];
if (selectedKey === "0" && !notShowGrantOrWithdraw) {
if (selectedKey === "0" && salarySendDetailBaseInfo.canSend) {
btnDom = [
<ButtonSelect
datas={[
@ -384,7 +384,7 @@ export default class PayrollGrant extends React.Component {
/>,
...btnDom
];
} else if (selectedKey === "1" && !notShowGrantOrWithdraw) {
} else if (selectedKey === "1" && salarySendDetailBaseInfo.canSend) {
btnDom = [
<ButtonSelect
datas={[

View File

@ -0,0 +1,104 @@
/*
* Author: 黎永顺
* name: 工资单模板基础设置
* Description:
* Date: 2023/6/12
*/
import React, { Component } from "react";
import { WeaCheckbox, WeaFormItem, WeaLocaleProvider, WeaSearchGroup, WeaSelect } from "ecCom";
import { message } from "antd";
import { getSalaryBillBaseSetForm, salaryBillBaseSetSave } from "../../apis/payroll";
import WaterMarkSetModal from "./components/waterMarkSetModal";
import "./index.less";
const getLabel = WeaLocaleProvider.getLabel;
class TemplateBaseSettings extends Component {
constructor(props) {
super(props);
this.state = {
watermarkStatus: "0",
watermark: "DEFAULT",
wmSetting: null,
watermarkSet: {
visible: false, watermarkSetting: null
}
};
}
componentDidMount() {
this.getSalaryBillBaseSetForm();
}
getSalaryBillBaseSetForm = () => {
const { watermarkSet } = this.state;
getSalaryBillBaseSetForm().then(({ status, data }) => {
if (status) {
const { watermarkStatus, watermark = "DEFAULT", watermarkSetting } = data;
this.setState({
watermark, watermarkStatus: watermarkStatus ? "1" : "0",
watermarkSet: {
...watermarkSet,
watermarkSetting
}
}, () => window.localStorage.setItem("wmSetting", JSON.stringify({ wmSetting: watermarkSetting })));
}
});
};
salaryBillBaseSetSave = () => {
const { watermark, watermarkStatus, wmSetting } = this.state;
let payload = { watermarkStatus: watermarkStatus === "1" };
if (watermarkStatus === "1") payload = { ...payload, watermark };
if (!_.isNil(wmSetting)) payload = { ...payload, watermark, ...wmSetting };
this.props.onChangeLoading(true);
salaryBillBaseSetSave(payload).then(({ status, errormsg }) => {
this.props.onChangeLoading(false);
if (status) {
message.success(getLabel(111, "保存成功"));
this.getSalaryBillBaseSetForm();
} else {
message.error(errormsg || getLabel(111, "保存失败"));
}
}).catch(() => this.props.onChangeLoading(false));
};
render() {
const { watermarkStatus, watermark, watermarkSet } = this.state;
return (
<WeaSearchGroup title={getLabel(111, "水印设置")} showGroup needTigger className="waterMarkWrapper">
<WeaFormItem label={getLabel(111, "启用水印")} labelCol={{ span: 2 }} wrapperCol={{ span: 4 }}>
<WeaCheckbox value={watermarkStatus} display="switch"
onChange={watermarkStatus => this.setState({ watermarkStatus, watermark: "DEFAULT" })}/>
</WeaFormItem>
{
watermarkStatus === "1" &&
<WeaFormItem label={getLabel(111, "水印类型")} labelCol={{ span: 2 }} wrapperCol={{ span: 4 }}>
<WeaSelect
value={watermark}
options={[
{ key: "DEFAULT", showname: getLabel(111, "系统默认水印") },
{ key: "CUSTOM", showname: getLabel(111, "自定义水印") }
]}
onChange={watermark => this.setState({ watermark })}
/>
{
watermark === "CUSTOM" &&
<span className="waterMarkTitle" onClick={() => this.setState({
watermarkSet: {
...watermarkSet,
visible: true
}
})}>{getLabel(111, "水印设置")}</span>
}
<WaterMarkSetModal {...watermarkSet}
onClose={() => this.setState({ watermarkSet: { ...watermarkSet, visible: false } })}
onChange={wmSetting => this.setState({ wmSetting })}
/>
</WeaFormItem>
}
</WeaSearchGroup>
);
}
}
export default TemplateBaseSettings;

View File

@ -1,10 +1,10 @@
import React from "react";
import { inject, observer } from "mobx-react";
import { WeaLocaleProvider, WeaTable } from "ecCom";
import { toJS } from "mobx";
import { Radio, Spin } from "antd";
import { WeaTableNew } from "comsMobx";
const WeaTable = WeaTableNew.WeaTable;
const getLabel = WeaLocaleProvider.getLabel;
@inject("payrollStore")
@observer
export default class TemplateSettingList extends React.Component {
@ -15,23 +15,23 @@ export default class TemplateSettingList extends React.Component {
}
// 编辑操作按钮
onEdit(record) {
onEdit = (record) => {
this.props.onEdit && this.props.onEdit(record);
}
};
// 复制操作按钮
onCopy(record) {
onCopy = (record) => {
this.props.onCopy && this.props.onCopy(record);
}
};
// 删除操作按钮
onDelete(record) {
onDelete = (record) => {
this.props.onDelete && this.props.onDelete(record);
}
};
// 操作按钮
onOperatesClick = (record, index, operate, flag) => {
switch (operate.index.toString()) {
onOperatesClick = (record, operate) => {
switch (operate) {
case "0": // 编辑
this.onEdit(record);
break;
@ -45,21 +45,22 @@ export default class TemplateSettingList extends React.Component {
};
// 默认使用配置
recordItemChange(record) {
recordItemChange = (record) => {
const { payrollStore } = this.props;
const { changePayrollDefaultUse, getPayrollTemplateList } = payrollStore;
changePayrollDefaultUse(record.id).then(() => {
getPayrollTemplateList();
});
}
};
// 增加编辑功能重写columns绑定事件
getColumns = columns => {
const { showOperateBtn } = this.props;
let newColumns = "";
newColumns = columns.map(column => {
getColumns = () => {
const { showOperateBtn, payrollStore } = this.props;
const { templateTableColumns: columns } = payrollStore;
let newColumns = [];
newColumns = _.filter(toJS(columns), item => item.dataIndex !== "id").map(column => {
let newColumn = column;
newColumn.render = (text, record, index) => {
newColumn.render = (text, record) => {
//前端元素转义
let valueSpan =
record[newColumn.dataIndex + "span"] !== undefined
@ -70,10 +71,8 @@ export default class TemplateSettingList extends React.Component {
return (
<Radio
disabled={!showOperateBtn}
checked={record.useType == "1"}
onChange={value => {
this.recordItemChange(record);
}}
checked={record.useType === "1"}
onChange={() => this.recordItemChange(record)}
/>
);
default:
@ -82,25 +81,73 @@ export default class TemplateSettingList extends React.Component {
};
return newColumn;
});
return newColumns;
return [
...newColumns,
{
dataIndex: "operate",
title: getLabel(30585, "操作"),
width: 150,
render: (_, record) => {
return <React.Fragment>
<a href="javascript:void(0);" style={{ marginRight: 10 }}
onClick={() => this.onOperatesClick(record, "0")}>{getLabel(501169, "编辑")}</a>
<a href="javascript:void(0);" style={{ marginRight: 10 }}
onClick={() => this.onOperatesClick(record, "1")}>{getLabel(77, "复制")}</a>
<a href="javascript:void(0);"
onClick={() => this.onOperatesClick(record, "2")}>{getLabel(535052, "删除")}</a>
</React.Fragment>;
}
}
];
};
render() {
const { payrollStore } = this.props;
const { templateStore, loading } = payrollStore;
const {
templateTableDataSource,
loading,
templateTablePageInfo,
setTemplateTablePageInfo,
getPayrollTemplateList,
templateTableSelectedRowKeys,
setTemplateTableSelectedRowKeys
} = payrollStore;
const pagination = {
...templateTablePageInfo,
showTotal: total => `${getLabel(18609, "共")} ${total} ${getLabel(18256, "条")}`,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ["10", "20", "50", "100"],
onShowSizeChange: (current, pageSize) => {
setTemplateTablePageInfo({ ...templateTablePageInfo, current, pageSize }, () => {
getPayrollTemplateList();
});
},
onChange: current => {
setTemplateTablePageInfo({ ...templateTablePageInfo, current }, () => {
getPayrollTemplateList();
});
}
};
const rowSelection = {
selectedRowKeys: toJS(templateTableSelectedRowKeys),
onChange: selectedRowKeys => setTemplateTableSelectedRowKeys(selectedRowKeys)
};
return (
<div>
{loading
? <div style={{ width: "100%", textAlign: "center" }}>
<Spin/>
</div>
: <WeaTable // table内部做了loading加载处理页面就不需要再加了
comsWeaTableStore={templateStore} // table store
hasOrder={true} // 是否启用排序
needScroll={true} // 是否启用table内部列表滚动将自适应到父级高度
getColumns={this.getColumns}
onOperatesClick={this.onOperatesClick.bind(this)}
/>}
{
loading
? <div style={{ width: "100%", textAlign: "center" }}>
<Spin/>
</div>
: <WeaTable
rowKey="id"
rowSelection={rowSelection}
columns={this.getColumns()}
dataSource={toJS(templateTableDataSource)}
pagination={pagination}
/>
}
</div>
);
}

View File

@ -0,0 +1,58 @@
/*
* Author: 黎永顺
* name: 水印预览
* Description:
* Date: 2023/6/15
*/
import React, { Component } from "react";
import { salaryBillBaseSetPreviewWaterMark } from "../../apis/payroll";
import { WeaTools } from "ecCom";
const { watermark } = WeaTools;
class WatermarkPreview extends Component {
componentDidMount() {
const wmSetting = window.localStorage.getItem("wmSetting");
wmSetting && this.salaryBillBaseSetPreviewWaterMark(JSON.parse(wmSetting));
}
salaryBillBaseSetPreviewWaterMark = (payload) => {
salaryBillBaseSetPreviewWaterMark(payload).then(({ status, data }) => {
if (status) {
const { wmHeight: height, wmWidth: width, wmNoTransparent, wmRotate } = payload;
watermark({
text: data,
src: "",
width, height,
rotate: `-${wmRotate || 15}`,
alpha: wmNoTransparent / 100 || 0.15,
interval: 2000,
intervalCheck: true,
clickCheck: true
});
}
});
};
render() {
return (
<div style={{ display: "flex", alignItems: "center", flexDirection: "column" }}>
<h1 style={{ textAlign: "center" }}>水印预览效果</h1>
<p
style={{ fontSize: 14 }}>水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果</p>
<p
style={{ fontSize: 14 }}>水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果</p>
<p
style={{ fontSize: 14 }}>水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果</p>
<p
style={{ fontSize: 14 }}>水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果</p>
<p
style={{ fontSize: 14 }}>水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果</p>
<p
style={{ fontSize: 14 }}>水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果水印预览效果</p>
</div>
);
}
}
export default WatermarkPreview;

View File

@ -5,107 +5,67 @@
* Date: 2022-09-19 18:15:32
*/
import React, { Component } from "react";
import { WeaFormItem, WeaNewScroll, WeaSearchGroup, WeaSelect, WeaTop } from "ecCom";
import { CheckBox } from "../appConfig";
import { Button, message, Modal } from "antd";
import { WeaCheckbox, WeaFormItem, WeaLocaleProvider, WeaNewScroll, WeaSearchGroup, WeaSelect, WeaTop } from "ecCom";
import { message, Modal } from "antd";
import * as API from "../../apis/ruleconfig";
import "./index.less";
import ProgressModal from "../../components/progressModal";
class Index extends Component {
const { getLabel } = WeaLocaleProvider;
export default class Index extends Component {
constructor(props) {
super(props);
this.state = {
items: [],
importItems: [],
enctryItems: [],
declareItems: [],
loading: {
order: false,
employee: false,
encry: false,
declare: false
},
matchRuleOptions: [], orderOptions: [], ascOptions: [], employeeOptions: [],
saveParams: {
orderRule: "",
ascOrDesc: "",
rule: "",
enctry: "",
operateTaxDeclaration: ""
operateTaxDeclaration: "",
matchRule: ""
},
showEncryptOperationButton: "",
progressVisible: false,
progress: 50
};
}
componentDidMount() {
let sysSetting = this.getSysSetting();
async componentDidMount() {
const { saveParams } = this.state;
const [
matchRuleEnum, orderRuleEnum, ascOrDescEnum, matchEmployeeModeEnum,
orderRules, codeRule, appSettings
] = await Promise.all([
this.matchRuleEnum(), this.orderRuleEnum(), this.ascOrDescEnum(), this.matchEmployeeModeEnum(),
this.sysOrderRule(), this.sysConfCodeRule(), this.queryAppsetting()
]);
const matchRuleOptions = _.map(matchRuleEnum.data, it => ({ key: it.value, showname: it.defaultLabel }));
const orderOptions = _.map(orderRuleEnum.data, it => ({ key: it.value, showname: it.defaultLabel }));
const ascOptions = _.map(ascOrDescEnum.data, it => ({ key: it.value, showname: it.defaultLabel }));
const employeeOptions = _.map(matchEmployeeModeEnum.data, it => ({ key: it.value, showname: it.defaultLabel }));
const { data: { ascOrDesc, orderRule } } = orderRules;
const { data: rule } = codeRule;
const {
data: {
showEncryptOperationButton,
isOpenEncrypt: enctry,
isOpenTaxDeclaration: operateTaxDeclaration,
salaryAcctEmployeeRule: matchRule
}
} = appSettings;
this.setState({
matchRuleOptions, orderOptions, ascOptions, employeeOptions,
showEncryptOperationButton,
saveParams: {
...saveParams,
ascOrDesc, orderRule, rule, enctry, operateTaxDeclaration, matchRule
}
});
}
getSysSetting = async () => {
const [orderRuleEnum, ascOrDescEnum, matchEmployeeModeEnum, sysOrderRule, sysConfCodeRule, queryAppsetting] = await Promise.all([this.orderRuleEnum(), this.ascOrDescEnum(), this.matchEmployeeModeEnum(), this.sysOrderRule(), this.sysConfCodeRule(), this.queryAppsetting()]);
if (orderRuleEnum.status && ascOrDescEnum.status && matchEmployeeModeEnum.status) {
const orderOptions = _.map(orderRuleEnum.data, it => ({ key: it.value, showname: it.defaultLabel }));
const ascOptions = _.map(ascOrDescEnum.data, it => ({ key: it.value, showname: it.defaultLabel }));
const employeeOptions = _.map(matchEmployeeModeEnum.data, it => ({ key: it.value, showname: it.defaultLabel }));
this.setState({
items: [
{
com: Select({
label: "排序字段",
onChange: this.handleChane,
value: sysOrderRule.data.orderRule,
options: orderOptions
})
},
{
com: Select({
label: "正序/倒序",
onChange: this.handleChane,
value: sysOrderRule.data.ascOrDesc,
options: ascOptions
})
}
],
importItems: [
{
com: Select({
label: "人员字段",
onChange: this.handleChane,
value: sysConfCodeRule.data,
options: employeeOptions
})
}
],
enctryItems: queryAppsetting.data.showEncryptOperationButton === "true" ? [
{
com: CheckBox({
label: "加密设置",
value: queryAppsetting.data.isOpenEncrypt,
onChange: (data) => this.handleChane({ type: "加密设置", selected: data })
})
}
] : [],
declareItems: [
{
com: CheckBox({
label: "个税申报",
value: queryAppsetting.data.isOpenTaxDeclaration,
onChange: (data) => this.handleChane({ type: "个税申报", selected: data })
})
}
],
saveParams: {
...this.state.saveParams,
orderRule: sysOrderRule.data.orderRule,
ascOrDesc: sysOrderRule.data.ascOrDesc,
rule: sysConfCodeRule.data,
enctry: queryAppsetting.data.isOpenEncrypt,
operateTaxDeclaration: queryAppsetting.data.isOpenTaxDeclaration
}
});
}
};
sysOrderRule = () => {
return API.sysOrderRule();
};
@ -115,6 +75,12 @@ class Index extends Component {
queryAppsetting = () => {
return API.queryAppsetting();
};
matchRuleEnum = () => {
const payload = {
enumClass: "com.engine.salary.sys.enums.SalaryAcctEmployeeRuleEnum"
};
return API.commonEnumList(payload);
};
orderRuleEnum = () => {
const payload = {
enumClass: "com.engine.salary.sys.enums.OrderRuleEnum"
@ -133,199 +99,214 @@ class Index extends Component {
};
return API.commonEnumList(payload);
};
handleSave = (type) => {
const { saveParams } = this.state;
if (type === "ORDER") {
if (_.isEmpty(saveParams.orderRule) || _.isEmpty(saveParams.ascOrDesc)) {
Modal.warning({
title: "信息确认",
content: "必要信息不完整,红色*为必填项!"
});
return;
}
this.setState({ loading: { ...this.state.loading, order: true } });
API.updateOrderRule(_.pick(saveParams, ["orderRule", "ascOrDesc"])).then(({ status, errormsg }) => {
this.setState({ loading: { ...this.state.loading, order: false } });
updateOrderRule = () => {
API.updateOrderRule(_.pick(this.state.saveParams, ["orderRule", "ascOrDesc"]))
.then(({ status, errormsg }) => {
if (status) {
message.success("保存成功!");
let sysSetting = this.getSysSetting();
message.success(getLabel(22619, "保存成功!"));
} else {
message.error(errormsg || "保存失败!");
message.error(errormsg || getLabel(22620, "保存失败!"));
}
});
} else if (type === "EMPLOYEE") {
if (_.isEmpty(saveParams.rule)) {
Modal.warning({
title: "信息确认",
content: "必要信息不完整,红色*为必填项!"
});
return;
};
saveMatchEmployeeModeRule = () => {
API.saveMatchEmployeeModeRule(_.pick(this.state.saveParams, ["rule"])).then(({ status, errormsg }) => {
if (status) {
message.success(getLabel(22619, "保存成功!"));
} else {
message.error(errormsg || getLabel(22620, "保存失败!"));
}
this.setState({ loading: { ...this.state.loading, employee: true } });
API.saveMatchEmployeeModeRule(_.pick(saveParams, ["rule"])).then(({ status, errormsg }) => {
this.setState({ loading: { ...this.state.loading, employee: false } });
});
};
saveSalaryAcctEmployeeRule = () => {
API.saveSalaryAcctEmployeeRule({ rule: this.state.saveParams.matchRule })
.then(({ status, errormsg }) => {
if (status) {
message.success("保存成功!");
let sysSetting = this.getSysSetting();
message.success(getLabel(22619, "保存成功!"));
} else {
message.error(errormsg || "保存失败!");
message.error(errormsg || getLabel(22620, "保存失败!"));
}
});
} else if (type === "ENCRYTION") {
Modal.confirm({
title: "信息确认",
content: "开启/关闭加密前请做好数据库备份!!!逆向解密会花费几分钟时间,请耐心等待!!!",
onOk: () => {
this.setState({ loading: { ...this.state.loading, encry: true } });
API.saveEncryptSetting({ isOpenEncrypt: saveParams.enctry }).then(({ data, status, errormsg }) => {
this.setState({ loading: { ...this.state.loading, encry: false } });
if (status) {
const { isSuccess, progressId, msg } = data;
if (!isSuccess) {
message.error(errormsg || msg || "保存失败!");
return;
}
this.setState({
progressVisible: true,
progress: 0
}, () => {
let number = 1;
this.timer && clearInterval(this.timer);
this.timer = setInterval(() => {
API.getEncryptProgress({ progressId }).then(({ status, data, errormsg }) => {
const { progress_statue } = data;
if (progress_statue === "success" && this.timer) {
clearInterval(this.timer);
this.timer = null;
number = 1;
this.setState({
progress: 100
}, () => {
this.setState({
progressVisible: false
});
});
message.success("保存成功");
} else if (progress_statue === "in_progress" && this.timer) {
if (this.state.progress >= 90) {
this.setState({
progress: this.state.progress + (0.001 * this.state.progress)
});
} else {
this.setState({
progress: 10 * number
}, () => number++);
}
} else if (!status || (progress_statue === "fail" && this.timer)) {
clearInterval(this.timer);
this.timer = null;
number = 1;
this.setState({
progress: 100
}, () => {
this.setState({
progressVisible: false
});
});
message.error(errormsg || "保存失败!");
}
};
operateTaxDeclarationFunction = () => {
API.operateTaxDeclarationFunction(_.pick(this.state.saveParams, ["operateTaxDeclaration"]))
.then(({ status, errormsg }) => {
if (status) {
message.success(getLabel(22619, "保存成功!"));
} else {
message.error(errormsg || getLabel(22620, "保存失败!"));
}
});
};
saveEncryptSetting = () => {
API.saveEncryptSetting({ isOpenEncrypt: this.state.saveParams.enctry })
.then(({ data, status, errormsg }) => {
if (status) {
const { isSuccess, progressId, msg } = data;
if (!isSuccess) {
message.error(errormsg || msg || getLabel(22620, "保存失败!"));
return;
}
this.setState({
progressVisible: true,
progress: 0
}, () => {
let number = 1;
this.timer && clearInterval(this.timer);
this.timer = setInterval(() => {
API.getEncryptProgress({ progressId }).then(({ status, data, errormsg }) => {
const { progress_statue } = data;
if (progress_statue === "success" && this.timer) {
clearInterval(this.timer);
this.timer = null;
number = 1;
this.setState({
progress: 100
}, () => {
this.setState({
progressVisible: false
});
});
}, 1000);
message.success(getLabel(22619, "保存成功!"));
} else if (progress_statue === "in_progress" && this.timer) {
if (this.state.progress >= 90) {
this.setState({
progress: this.state.progress + (0.001 * this.state.progress)
});
} else {
this.setState({
progress: 10 * number
}, () => number++);
}
} else if (!status || (progress_statue === "fail" && this.timer)) {
clearInterval(this.timer);
this.timer = null;
number = 1;
this.setState({
progress: 100
}, () => {
this.setState({
progressVisible: false
});
});
message.error(errormsg || getLabel(22620, "保存失败!"));
}
});
}
}, 1000);
});
},
onCancel: () => {
}
});
} else if (type === "DECLARATION") {
this.setState({ loading: { ...this.state.loading, declare: true } });
API.operateTaxDeclarationFunction(_.pick(saveParams, ["operateTaxDeclaration"])).then(({ status, errormsg }) => {
this.setState({ loading: { ...this.state.loading, declare: false } });
if (status) {
message.success("保存成功!");
let sysSetting = this.getSysSetting();
} else {
message.error(errormsg || "保存失败!");
}
});
}
};
handleChane = (data) => {
const { type, selected } = data;
if (type === "排序字段") {
this.setState({
saveParams: { ...this.state.saveParams, orderRule: selected }
});
} else if (type === "正序/倒序") {
this.setState({
saveParams: { ...this.state.saveParams, ascOrDesc: selected }
});
} else if (type === "人员字段") {
this.setState({
saveParams: { ...this.state.saveParams, rule: selected }
});
} else if (type === "加密设置") {
this.setState({
saveParams: { ...this.state.saveParams, enctry: selected }
});
} else if (type === "个税申报") {
this.setState({
saveParams: { ...this.state.saveParams, operateTaxDeclaration: selected }
});
}
handleChange = (key, val) => {
const { saveParams } = this.state;
Modal.confirm({
title: getLabel(131329, "信息确认"),
content: getLabel(111, "确认要保存吗?"),
onOk: () => {
this.setState({
saveParams: {
...saveParams,
[key]: val
}
}, () => {
switch (key) {
case "orderRule":
case "ascOrDesc":
this.updateOrderRule();
break;
case "rule":
this.saveMatchEmployeeModeRule();
break;
case "matchRule":
this.saveSalaryAcctEmployeeRule();
break;
case "operateTaxDeclaration":
this.operateTaxDeclarationFunction();
break;
case "enctry":
this.saveEncryptSetting();
break;
default:
break;
}
});
},
onCancel: () => {
this.setState({
saveParams: {
...saveParams,
[key]: saveParams[key]
}
});
}
});
};
render() {
const { items, importItems, enctryItems, declareItems, loading } = this.state;
const {
saveParams,
matchRuleOptions,
orderOptions,
ascOptions,
employeeOptions,
showEncryptOperationButton
} = this.state;
const { orderRule, ascOrDesc, rule, enctry, operateTaxDeclaration, matchRule } = saveParams;
return (
<div className="ruleWrapper">
<WeaTop
title={<span>规则配置</span>}
title={<span>{getLabel(543355, "规则配置")}</span>}
icon={<i className="icon-coms-Flow-setting"/>}
iconBgcolor="#F14A2D"
buttons={[]}
/>
<WeaNewScroll height={`calc(100% - 46px)`}>
<WeaSearchGroup
title={
<div className="titleWrapper">
<span>排序规则</span>
<Button type="primary" onClick={() => this.handleSave("ORDER")} loading={loading.order}>保存</Button>
</div>
} showGroup center items={items}/>
<WeaSearchGroup
title={
<div className="titleWrapper">
<span>人员校验规则</span>
<Button type="primary" onClick={() => this.handleSave("EMPLOYEE")}
loading={loading.employee}>保存</Button>
</div>
} showGroup center items={importItems}/>
<WeaSearchGroup title={getLabel(543356, "排序规则")} showGroup center>
<WeaFormItem label={getLabel(15512, "排序字段")} labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
<WeaSelect options={orderOptions} value={orderRule}
onChange={val => this.handleChange("orderRule", val)}
/>
</WeaFormItem>
<WeaFormItem label={getLabel(543351, "正序/倒序")} labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
<WeaSelect options={ascOptions} value={ascOrDesc}
onChange={val => this.handleChange("ascOrDesc", val)}
/>
</WeaFormItem>
</WeaSearchGroup>
<WeaSearchGroup title={getLabel(543357, "人员校验规则")} showGroup center>
<WeaFormItem label={getLabel(543352, "人员字段")} labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
<WeaSelect options={employeeOptions} value={rule}
onChange={val => this.handleChange("rule", val)}
/>
</WeaFormItem>
</WeaSearchGroup>
{
!_.isEmpty(enctryItems) &&
<WeaSearchGroup
title={
<div className="titleWrapper">
<span>加密规则</span>
<Button type="primary" onClick={() => this.handleSave("ENCRYTION")}
loading={loading.encry}>保存</Button>
</div>
} showGroup center items={enctryItems}/>
showEncryptOperationButton === "true" &&
<WeaSearchGroup title={getLabel(543358, "加密规则")} showGroup center>
<WeaFormItem label={getLabel(526997, "加密设置")} labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
<WeaCheckbox display="switch" value={enctry}
onChange={val => this.handleChange("enctry", val)}/>
</WeaFormItem>
</WeaSearchGroup>
}
<WeaSearchGroup
title={
<div className="titleWrapper">
<span>报税规则</span>
<Button type="primary" onClick={() => this.handleSave("DECLARATION")}
loading={loading.declare}>保存</Button>
</div>
} showGroup center items={declareItems}/>
<WeaSearchGroup title={getLabel(543359, "报税规则")} showGroup center>
<WeaFormItem label={getLabel(543353, "个税申报")} labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
<WeaCheckbox display="switch" value={operateTaxDeclaration}
onChange={val => this.handleChange("operateTaxDeclaration", val)}/>
</WeaFormItem>
</WeaSearchGroup>
<WeaSearchGroup title={getLabel(111, "薪资核算人员匹配规则")} showGroup center>
<WeaFormItem label={getLabel(111, "匹配规则")} labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
<WeaSelect options={matchRuleOptions} value={matchRule}
onChange={val => this.handleChange("matchRule", val)}
/>
</WeaFormItem>
</WeaSearchGroup>
{
this.state.progressVisible &&
<ProgressModal
title="加密/解密中..."
title={getLabel(543360, "加密/解密中...")}
visible={this.state.progressVisible}
onCancel={() => {
this.setState({ progressVisible: false, progress: 0 });
@ -339,8 +320,6 @@ class Index extends Component {
}
}
export default Index;
export const Select = payload => {
const {
label,
@ -354,7 +333,7 @@ export const Select = payload => {
} = payload;
return (
<WeaFormItem label={label} labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
<WeaSelect options={multiple ? options : [{ key: "", showname: "" }, ...options]} viewAttr={viewAttr}
<WeaSelect options={multiple ? options : [...options]} viewAttr={viewAttr}
detailtype={detailtype}
value={value}
multiple={multiple}

View File

@ -1,11 +1,12 @@
import { action, observable } from "mobx";
import { message } from "antd";
import { WeaForm, WeaLogView, WeaTableNew } from "comsMobx";
import { WeaLocaleProvider } from "ecCom";
import { WeaLocaleProvider, WeaTools } from "ecCom";
import moment from "moment";
import * as API from "../apis/mySalaryBenefits";
const { watermark } = WeaTools;
const { LogStore } = WeaLogView;
const getLabel = WeaLocaleProvider.getLabel;
const { TableStore } = WeaTableNew;
@ -167,6 +168,46 @@ export class MySalaryStore {
if (res.status) {
this.mySalaryBill = res.data;
resolve(res.data);
const { salaryTemplate } = res.data;
const { salaryWatermark } = salaryTemplate;
if (watermark && salaryWatermark) {
const { wmSetting, watermarkStatus } = JSON.parse(salaryWatermark);
if (!watermarkStatus) return;
const {
wmText,
wmHeight: height,
wmWidth: width,
wmNoTransparent,
wmRotate,
wmImg,
wmClassify
} = wmSetting;
if (wmClassify === "text") {
watermark({
text: wmText,
width,
height,
src: "",
rotate: `-${wmRotate || 15}`,
alpha: wmNoTransparent / 100 || 0.15,
interval: 2000,
intervalCheck: true,
clickCheck: true
});
} else {
watermark({
text: "",
width,
height,
src: wmImg[0].imgSrc,
rotate: `-${wmRotate || 15}`,
alpha: wmNoTransparent / 100 || 0.15,
interval: 2000,
intervalCheck: true,
clickCheck: true
});
}
}
} else {
message.error(res.errormsg || "获取失败");
reject("获取失败");

View File

@ -55,6 +55,14 @@ export class payrollStore {
@observable canWidthdrawColumns = []; // 可以撤回的列表列名
@observable canWithdrawPageInfo = {}; // 可以撤回列表分页对象
// **** 工资单模板 ****
@observable templateTableColumns = []; // 工资单模板columns
@observable templateTableDataSource = []; // 工资单模板dataSource
@observable templateTablePageInfo = {
current: 1, pageSize: 10, total: 0
}; // 工资单模板pageInfo
@observable templateTableSelectedRowKeys = []; // 工资单模板复选框
@action
setReplenishSalaryTemplateSalaryItemSet = replenishSalaryTemplateSalaryItemSet =>
(this.replenishSalaryTemplateSalaryItemSet = replenishSalaryTemplateSalaryItemSet);
@ -80,6 +88,14 @@ export class payrollStore {
@action
setSalaryItemSet = salaryItemSet => (this.salaryItemSet = salaryItemSet);
@action("工资单模板分页信息修改")
setTemplateTablePageInfo = (pageInfo, callback) => {
this.templateTablePageInfo = { ...this.templateTablePageInfo, ...pageInfo };
callback && callback();
};
@action("工资单模板复选框选择")
setTemplateTableSelectedRowKeys = (selectedRowKeys) => this.templateTableSelectedRowKeys = selectedRowKeys;
// 初始化操作
@action
doInit = () => {
@ -136,9 +152,15 @@ export class payrollStore {
@action
getPayrollTemplateList = (params = {}) => {
this.loading = true;
API.getPayrollTemplateList(params).then(res => {
API.getPayrollTemplateList({ ...this.templateTablePageInfo, ...params }).then(res => {
if (res.status) {
this.templateStore.getDatas(res.data.datas);
this.templateTableColumns = res.data.columns;
this.templateTableDataSource = res.data.list;
this.setTemplateTablePageInfo({
current: res.data.pageNum,
pageSize: res.data.pageSize,
total: res.data.total
});
} else {
message.error(res.errormsg || "获取失败");
}
@ -149,9 +171,7 @@ export class payrollStore {
// 工资单模板-获取工资单模板基础设置表单
@action
getPayrollBaseForm = (id = "") => {
let params = {
id
};
let params = { id };
return new Promise((resolve, reject) => {
API.getPayrollBaseForm(params).then(res => {
if (res.status) {
@ -354,6 +374,7 @@ export class payrollStore {
API.deletePayroll(ids).then(res => {
if (res.status) {
message.success("删除成功");
this.setTemplateTableSelectedRowKeys([]);
this.getPayrollTemplateList();
} else {
message.error(res.errormsg || "删除失败");
@ -525,7 +546,7 @@ export class payrollStore {
reject();
}
}).catch(() => {
this.btnLoading = false
this.btnLoading = false;
// WeaLoadingGlobal.end();
// WeaLoadingGlobal.destroy();
});
@ -553,7 +574,7 @@ export class payrollStore {
reject();
}
}).catch(() => {
this.btnLoading = false
this.btnLoading = false;
WeaLoadingGlobal.end();
WeaLoadingGlobal.destroy();
});