Merge remote-tracking branch 'origin/main' into main
commit
6578760a87
|
@ -89,7 +89,7 @@ export interface InvoiceDetail {
|
||||||
invoiceUploader: Staff;
|
invoiceUploader: Staff;
|
||||||
invoiceUploadTime: string|Dayjs;
|
invoiceUploadTime: string|Dayjs;
|
||||||
modified: boolean;
|
modified: boolean;
|
||||||
reimbursement: Reimbursement;
|
reimbursement?: Reimbursement;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InvoiceIdentifyResponse {
|
export interface InvoiceIdentifyResponse {
|
||||||
|
|
|
@ -69,12 +69,13 @@ export interface Reimbursement {
|
||||||
reimbursementInvoiceAmount: number;
|
reimbursementInvoiceAmount: number;
|
||||||
reimbursementNote?: string;
|
reimbursementNote?: string;
|
||||||
/**
|
/**
|
||||||
* 0: success
|
* 0: 已报销
|
||||||
* 1: 待主管审批
|
* 1: 待主管审批
|
||||||
* 2: 待财务审批
|
* 2: 待财务审批
|
||||||
* 3: 待财务主管审批
|
* 3: 待财务主管审批
|
||||||
* 4: 待总经理审批
|
* 4: 待总经理审批
|
||||||
* 5: 未通过
|
* 5: 未通过
|
||||||
|
* 6: 已终止
|
||||||
*/
|
*/
|
||||||
reimbursementStatus: number;
|
reimbursementStatus: number;
|
||||||
reimbursementSubmitDepartment: Department;
|
reimbursementSubmitDepartment: Department;
|
||||||
|
|
|
@ -0,0 +1,450 @@
|
||||||
|
// To parse this data:
|
||||||
|
//
|
||||||
|
// import { Convert, ReimbursementDetailModal } from "./file";
|
||||||
|
//
|
||||||
|
// const reimbursementDetailModal = Convert.toReimbursementDetailModal(json);
|
||||||
|
//
|
||||||
|
// These functions will throw an error if the JSON doesn't
|
||||||
|
// match the expected interface, even if the JSON is valid.
|
||||||
|
|
||||||
|
export interface Invoice {
|
||||||
|
/**
|
||||||
|
* 发票金额
|
||||||
|
*/
|
||||||
|
invoiceAmount?: number;
|
||||||
|
/**
|
||||||
|
* 发票代码
|
||||||
|
*/
|
||||||
|
invoiceCode?: string;
|
||||||
|
/**
|
||||||
|
* 开票日期
|
||||||
|
*/
|
||||||
|
invoiceDate: string;
|
||||||
|
/**
|
||||||
|
* 出发地名称
|
||||||
|
*/
|
||||||
|
invoiceDeparture?: null | string;
|
||||||
|
/**
|
||||||
|
* 目的地名称
|
||||||
|
*/
|
||||||
|
invoiceDestination?: null | string;
|
||||||
|
/**
|
||||||
|
* 发票原图URI
|
||||||
|
*/
|
||||||
|
invoiceFileUri?: string;
|
||||||
|
/**
|
||||||
|
* 发票ID
|
||||||
|
*/
|
||||||
|
invoiceId: number;
|
||||||
|
/**
|
||||||
|
* 发票种类
|
||||||
|
*/
|
||||||
|
invoiceKind?: number;
|
||||||
|
/**
|
||||||
|
* 发票名称
|
||||||
|
*/
|
||||||
|
invoiceName?: null | string;
|
||||||
|
/**
|
||||||
|
* 发票编号
|
||||||
|
*/
|
||||||
|
invoiceNo?: string;
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
invoiceNote?: null | string;
|
||||||
|
/**
|
||||||
|
* 发票状态,-1: 不合格 0: 已上传 1: 报销中 2: 已报销
|
||||||
|
*/
|
||||||
|
invoiceState?: number;
|
||||||
|
/**
|
||||||
|
* 发票缩略图URI
|
||||||
|
*/
|
||||||
|
invoiceThumbnailUri?: string;
|
||||||
|
/**
|
||||||
|
* 上传员工
|
||||||
|
*/
|
||||||
|
invoiceUploader?: Staff;
|
||||||
|
/**
|
||||||
|
* 上传时间
|
||||||
|
*/
|
||||||
|
invoiceUploadTime?: string;
|
||||||
|
/**
|
||||||
|
* 是否被修改
|
||||||
|
*/
|
||||||
|
modified?: boolean;
|
||||||
|
/**
|
||||||
|
* 所属报销单
|
||||||
|
*/
|
||||||
|
reimbursement?: ReimbursementDetailModal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ApprovalProcess
|
||||||
|
*/
|
||||||
|
export interface ApprovalProcess {
|
||||||
|
/**
|
||||||
|
* 审批意见
|
||||||
|
*/
|
||||||
|
approvalOpinion: string;
|
||||||
|
/**
|
||||||
|
* 审批结果
|
||||||
|
*/
|
||||||
|
approvalResult: number;
|
||||||
|
/**
|
||||||
|
* 审批员工
|
||||||
|
*/
|
||||||
|
approvalStaff: Staff;
|
||||||
|
approvalTime: string;
|
||||||
|
/**
|
||||||
|
* 进程顺序
|
||||||
|
*/
|
||||||
|
processOrder: number;
|
||||||
|
/**
|
||||||
|
* 报销单
|
||||||
|
*/
|
||||||
|
reimbursement?: ReimbursementDetailModal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reimbursement
|
||||||
|
*
|
||||||
|
* 报销单
|
||||||
|
*
|
||||||
|
* 所属报销单
|
||||||
|
*/
|
||||||
|
export interface ReimbursementDetailModal {
|
||||||
|
/**
|
||||||
|
* 审批进程
|
||||||
|
*/
|
||||||
|
approvalProcesses?: ApprovalProcess[];
|
||||||
|
/**
|
||||||
|
* 其他发票
|
||||||
|
*/
|
||||||
|
invoices: Array<Invoice>;
|
||||||
|
/**
|
||||||
|
* 补助总金额
|
||||||
|
*/
|
||||||
|
reimbursementAdditionalAmount: number;
|
||||||
|
/**
|
||||||
|
* 往程交通发票
|
||||||
|
*/
|
||||||
|
reimbursementDepartureInvoice:Invoice;
|
||||||
|
/**
|
||||||
|
* 出发地名
|
||||||
|
*/
|
||||||
|
reimbursementDepartureName: string;
|
||||||
|
/**
|
||||||
|
* 返程交通发票
|
||||||
|
*/
|
||||||
|
reimbursementDestinationInvoice: null | Invoice;
|
||||||
|
/**
|
||||||
|
* 目的地名
|
||||||
|
*/
|
||||||
|
reimbursementDestinationName: string;
|
||||||
|
/**
|
||||||
|
* 报销单ID
|
||||||
|
*/
|
||||||
|
reimbursementId: number;
|
||||||
|
/**
|
||||||
|
* 发票总金额
|
||||||
|
*/
|
||||||
|
reimbursementInvoiceAmount: number;
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
reimbursementNote?: null | string;
|
||||||
|
/**
|
||||||
|
* 报销单状态,0: success
|
||||||
|
* 1: 待主管审批
|
||||||
|
* 2: 待财务审批
|
||||||
|
* 3: 待财务主管审批
|
||||||
|
* 4: 待总经理审批
|
||||||
|
* 5: 未通过
|
||||||
|
* 6: 被终止
|
||||||
|
*/
|
||||||
|
reimbursementStatus: number;
|
||||||
|
/**
|
||||||
|
* 提交部门
|
||||||
|
*/
|
||||||
|
reimbursementSubmitDepartment: Department;
|
||||||
|
/**
|
||||||
|
* 提交员工
|
||||||
|
*/
|
||||||
|
reimbursementSubmitStaff: Staff;
|
||||||
|
/**
|
||||||
|
* 提交时间
|
||||||
|
*/
|
||||||
|
reimbursementSubmitTime: string;
|
||||||
|
/**
|
||||||
|
* 出差天数,单位为天
|
||||||
|
*/
|
||||||
|
reimbursementTripDuration: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主管部门
|
||||||
|
*
|
||||||
|
* Department
|
||||||
|
*
|
||||||
|
* 提交部门
|
||||||
|
*/
|
||||||
|
export interface Department {
|
||||||
|
/**
|
||||||
|
* 部门ID
|
||||||
|
*/
|
||||||
|
departmentId: number;
|
||||||
|
/**
|
||||||
|
* 部门主管
|
||||||
|
*/
|
||||||
|
departmentManager?: Staff;
|
||||||
|
/**
|
||||||
|
* 部门名
|
||||||
|
*/
|
||||||
|
departmentName?: string;
|
||||||
|
/**
|
||||||
|
* 部门员工
|
||||||
|
*/
|
||||||
|
staff?: Staff[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审批员工
|
||||||
|
*
|
||||||
|
* Staff
|
||||||
|
*
|
||||||
|
* 部门主管
|
||||||
|
*
|
||||||
|
* 上传员工
|
||||||
|
*
|
||||||
|
* 提交员工
|
||||||
|
*/
|
||||||
|
export interface Staff {
|
||||||
|
/**
|
||||||
|
* 主管部门
|
||||||
|
*/
|
||||||
|
managingDepartment?: Department;
|
||||||
|
/**
|
||||||
|
* 员工工作地点
|
||||||
|
*/
|
||||||
|
staffBase?: string;
|
||||||
|
/**
|
||||||
|
* 工作部门
|
||||||
|
*/
|
||||||
|
staffDepartments?: Department[];
|
||||||
|
/**
|
||||||
|
* 员工工号
|
||||||
|
*/
|
||||||
|
staffId: string;
|
||||||
|
/**
|
||||||
|
* 员工姓名
|
||||||
|
*/
|
||||||
|
staffName: string;
|
||||||
|
/**
|
||||||
|
* 密码
|
||||||
|
*/
|
||||||
|
staffPassword?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts JSON strings to/from your types
|
||||||
|
// and asserts the results of JSON.parse at runtime
|
||||||
|
export class Convert {
|
||||||
|
public static toReimbursementDetailModal(json: string): ReimbursementDetailModal {
|
||||||
|
return cast(JSON.parse(json), r("ReimbursementDetailModal"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static reimbursementDetailModalToJson(value: ReimbursementDetailModal): string {
|
||||||
|
return JSON.stringify(uncast(value, r("ReimbursementDetailModal")), null, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function invalidValue(typ: any, val: any, key: any = ''): never {
|
||||||
|
if (key) {
|
||||||
|
throw Error(`Invalid value for key "${key}". Expected type ${JSON.stringify(typ)} but got ${JSON.stringify(val)}`);
|
||||||
|
}
|
||||||
|
throw Error(`Invalid value ${JSON.stringify(val)} for type ${JSON.stringify(typ)}`, );
|
||||||
|
}
|
||||||
|
|
||||||
|
function jsonToJSProps(typ: any): any {
|
||||||
|
if (typ.jsonToJS === undefined) {
|
||||||
|
const map: any = {};
|
||||||
|
typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ });
|
||||||
|
typ.jsonToJS = map;
|
||||||
|
}
|
||||||
|
return typ.jsonToJS;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jsToJSONProps(typ: any): any {
|
||||||
|
if (typ.jsToJSON === undefined) {
|
||||||
|
const map: any = {};
|
||||||
|
typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ });
|
||||||
|
typ.jsToJSON = map;
|
||||||
|
}
|
||||||
|
return typ.jsToJSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
function transform(val: any, typ: any, getProps: any, key: any = ''): any {
|
||||||
|
function transformPrimitive(typ: string, val: any): any {
|
||||||
|
if (typeof typ === typeof val) return val;
|
||||||
|
return invalidValue(typ, val, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformUnion(typs: any[], val: any): any {
|
||||||
|
// val must validate against one typ in typs
|
||||||
|
const l = typs.length;
|
||||||
|
for (let i = 0; i < l; i++) {
|
||||||
|
const typ = typs[i];
|
||||||
|
try {
|
||||||
|
return transform(val, typ, getProps);
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
return invalidValue(typs, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformEnum(cases: string[], val: any): any {
|
||||||
|
if (cases.indexOf(val) !== -1) return val;
|
||||||
|
return invalidValue(cases, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformArray(typ: any, val: any): any {
|
||||||
|
// val must be an array with no invalid elements
|
||||||
|
if (!Array.isArray(val)) return invalidValue("array", val);
|
||||||
|
return val.map(el => transform(el, typ, getProps));
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformDate(val: any): any {
|
||||||
|
if (val === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const d = new Date(val);
|
||||||
|
if (isNaN(d.valueOf())) {
|
||||||
|
return invalidValue("Date", val);
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformObject(props: { [k: string]: any }, additional: any, val: any): any {
|
||||||
|
if (val === null || typeof val !== "object" || Array.isArray(val)) {
|
||||||
|
return invalidValue("object", val);
|
||||||
|
}
|
||||||
|
const result: any = {};
|
||||||
|
Object.getOwnPropertyNames(props).forEach(key => {
|
||||||
|
const prop = props[key];
|
||||||
|
const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined;
|
||||||
|
result[prop.key] = transform(v, prop.typ, getProps, prop.key);
|
||||||
|
});
|
||||||
|
Object.getOwnPropertyNames(val).forEach(key => {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(props, key)) {
|
||||||
|
result[key] = transform(val[key], additional, getProps, key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typ === "any") return val;
|
||||||
|
if (typ === null) {
|
||||||
|
if (val === null) return val;
|
||||||
|
return invalidValue(typ, val);
|
||||||
|
}
|
||||||
|
if (typ === false) return invalidValue(typ, val);
|
||||||
|
while (typeof typ === "object" && typ.ref !== undefined) {
|
||||||
|
typ = typeMap[typ.ref];
|
||||||
|
}
|
||||||
|
if (Array.isArray(typ)) return transformEnum(typ, val);
|
||||||
|
if (typeof typ === "object") {
|
||||||
|
return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val)
|
||||||
|
: typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val)
|
||||||
|
: typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val)
|
||||||
|
: invalidValue(typ, val);
|
||||||
|
}
|
||||||
|
// Numbers can be parsed by Date but shouldn't be.
|
||||||
|
if (typ === Date && typeof val !== "number") return transformDate(val);
|
||||||
|
return transformPrimitive(typ, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
function cast<T>(val: any, typ: any): T {
|
||||||
|
return transform(val, typ, jsonToJSProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
function uncast<T>(val: T, typ: any): any {
|
||||||
|
return transform(val, typ, jsToJSONProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
function a(typ: any) {
|
||||||
|
return { arrayItems: typ };
|
||||||
|
}
|
||||||
|
|
||||||
|
function u(...typs: any[]) {
|
||||||
|
return { unionMembers: typs };
|
||||||
|
}
|
||||||
|
|
||||||
|
function o(props: any[], additional: any) {
|
||||||
|
return { props, additional };
|
||||||
|
}
|
||||||
|
|
||||||
|
function m(additional: any) {
|
||||||
|
return { props: [], additional };
|
||||||
|
}
|
||||||
|
|
||||||
|
function r(name: string) {
|
||||||
|
return { ref: name };
|
||||||
|
}
|
||||||
|
|
||||||
|
const typeMap: any = {
|
||||||
|
"Invoice": o([
|
||||||
|
{ json: "invoiceAmount", js: "invoiceAmount", typ: u(undefined, 0) },
|
||||||
|
{ json: "invoiceCode", js: "invoiceCode", typ: u(undefined, "") },
|
||||||
|
{ json: "invoiceDate", js: "invoiceDate", typ: u(undefined, "") },
|
||||||
|
{ json: "invoiceDeparture", js: "invoiceDeparture", typ: u(undefined, u(null, "")) },
|
||||||
|
{ json: "invoiceDestination", js: "invoiceDestination", typ: u(undefined, u(null, "")) },
|
||||||
|
{ json: "invoiceFileUri", js: "invoiceFileUri", typ: u(undefined, "") },
|
||||||
|
{ json: "invoiceId", js: "invoiceId", typ: 0 },
|
||||||
|
{ json: "invoiceKind", js: "invoiceKind", typ: u(undefined, 0) },
|
||||||
|
{ json: "invoiceName", js: "invoiceName", typ: u(undefined, u(null, "")) },
|
||||||
|
{ json: "invoiceNo", js: "invoiceNo", typ: u(undefined, "") },
|
||||||
|
{ json: "invoiceNote", js: "invoiceNote", typ: u(undefined, u(null, "")) },
|
||||||
|
{ json: "invoiceState", js: "invoiceState", typ: u(undefined, 0) },
|
||||||
|
{ json: "invoiceThumbnailUri", js: "invoiceThumbnailUri", typ: u(undefined, "") },
|
||||||
|
{ json: "invoiceUploader", js: "invoiceUploader", typ: u(undefined, r("Staff")) },
|
||||||
|
{ json: "invoiceUploadTime", js: "invoiceUploadTime", typ: u(undefined, "") },
|
||||||
|
{ json: "modified", js: "modified", typ: u(undefined, true) },
|
||||||
|
{ json: "reimbursement", js: "reimbursement", typ: u(undefined, r("ReimbursementDetailModal")) },
|
||||||
|
], "any"),
|
||||||
|
"ApprovalProcess": o([
|
||||||
|
{ json: "approvalOpinion", js: "approvalOpinion", typ: "" },
|
||||||
|
{ json: "approvalResult", js: "approvalResult", typ: 0 },
|
||||||
|
{ json: "approvalStaff", js: "approvalStaff", typ: r("Staff") },
|
||||||
|
{ json: "processOrder", js: "processOrder", typ: 0 },
|
||||||
|
{ json: "reimbursement", js: "reimbursement", typ: u(undefined, r("ReimbursementDetailModal")) },
|
||||||
|
], "any"),
|
||||||
|
"ReimbursementDetailModal": o([
|
||||||
|
{ json: "approvalProcesses", js: "approvalProcesses", typ: u(undefined, a(r("ApprovalProcess"))) },
|
||||||
|
{ json: "invoices", js: "invoices", typ: u(undefined, a(u(null, r("Invoice")))) },
|
||||||
|
{ json: "reimbursementAdditionalAmount", js: "reimbursementAdditionalAmount", typ: 0 },
|
||||||
|
{ json: "reimbursementDepartureInvoice", js: "reimbursementDepartureInvoice", typ: u(null, r("Invoice")) },
|
||||||
|
{ json: "reimbursementDepartureName", js: "reimbursementDepartureName", typ: "" },
|
||||||
|
{ json: "reimbursementDestinationInvoice", js: "reimbursementDestinationInvoice", typ: u(null, r("Invoice")) },
|
||||||
|
{ json: "reimbursementDestinationName", js: "reimbursementDestinationName", typ: "" },
|
||||||
|
{ json: "reimbursementId", js: "reimbursementId", typ: 0 },
|
||||||
|
{ json: "reimbursementInvoiceAmount", js: "reimbursementInvoiceAmount", typ: 0 },
|
||||||
|
{ json: "reimbursementNote", js: "reimbursementNote", typ: u(undefined, u(null, "")) },
|
||||||
|
{ json: "reimbursementStatus", js: "reimbursementStatus", typ: 0 },
|
||||||
|
{ json: "reimbursementSubmitDepartment", js: "reimbursementSubmitDepartment", typ: r("Department") },
|
||||||
|
{ json: "reimbursementSubmitStaff", js: "reimbursementSubmitStaff", typ: r("Staff") },
|
||||||
|
{ json: "reimbursementSubmitTime", js: "reimbursementSubmitTime", typ: "" },
|
||||||
|
{ json: "reimbursementTripDuration", js: "reimbursementTripDuration", typ: 0 },
|
||||||
|
], "any"),
|
||||||
|
"Department": o([
|
||||||
|
{ json: "departmentId", js: "departmentId", typ: 0 },
|
||||||
|
{ json: "departmentManager", js: "departmentManager", typ: u(undefined, r("Staff")) },
|
||||||
|
{ json: "departmentName", js: "departmentName", typ: u(undefined, "") },
|
||||||
|
{ json: "staff", js: "staff", typ: u(undefined, a(r("Staff"))) },
|
||||||
|
], "any"),
|
||||||
|
"Staff": o([
|
||||||
|
{ json: "managingDepartment", js: "managingDepartment", typ: u(undefined, r("Department")) },
|
||||||
|
{ json: "staffBase", js: "staffBase", typ: u(undefined, "") },
|
||||||
|
{ json: "staffDepartments", js: "staffDepartments", typ: u(undefined, a(r("Department"))) },
|
||||||
|
{ json: "staffId", js: "staffId", typ: "" },
|
||||||
|
{ json: "staffName", js: "staffName", typ: "" },
|
||||||
|
{ json: "staffPassword", js: "staffPassword", typ: u(undefined, "") },
|
||||||
|
], "any"),
|
||||||
|
};
|
|
@ -70,6 +70,7 @@ const statusEnum = {
|
||||||
3: {text: '待财务主管审批', status: 'Processing'},
|
3: {text: '待财务主管审批', status: 'Processing'},
|
||||||
4: {text: '待总经理审批', status: 'Warning'},
|
4: {text: '待总经理审批', status: 'Warning'},
|
||||||
5: {text: '审批未通过', status: 'Error'},
|
5: {text: '审批未通过', status: 'Error'},
|
||||||
|
6: {text: '已终止', status: 'Error'},
|
||||||
}
|
}
|
||||||
|
|
||||||
class Subpage extends React.Component<any, any> {
|
class Subpage extends React.Component<any, any> {
|
||||||
|
@ -196,10 +197,12 @@ class Subpage extends React.Component<any, any> {
|
||||||
|
|
||||||
closeDetail = () => {
|
closeDetail = () => {
|
||||||
this.setState({detailedReimbursement: undefined})
|
this.setState({detailedReimbursement: undefined})
|
||||||
|
this.tableAction.current?.reload()
|
||||||
}
|
}
|
||||||
|
|
||||||
showDetail(reimbursementId: number) {
|
showDetail(reimbursementId: number) {
|
||||||
axiosInstance.get("common/reimbursement/" + reimbursementId).then((response) => {
|
axiosInstance.get("common/reimbursement/" + reimbursementId).then((response) => {
|
||||||
|
console.log(response.data)
|
||||||
this.setState({detailedReimbursement: response.data})
|
this.setState({detailedReimbursement: response.data})
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
openNotification("拉取报销单详情失败")
|
openNotification("拉取报销单详情失败")
|
||||||
|
@ -207,12 +210,12 @@ class Subpage extends React.Component<any, any> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async converter(value: Reimbursement[] | undefined | Reimbursement, pageSize: number | undefined) {
|
async converter(value: Reimbursement[] | undefined | Reimbursement | null, pageSize: number | undefined) {
|
||||||
if (value === undefined) {
|
if (value == undefined) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
let result: TableListItem[] = []
|
let result: TableListItem[] = []
|
||||||
if ("reimbursementAdditionalAmount" in value) {
|
if ("reimbursementId" in value) {
|
||||||
result.push({
|
result.push({
|
||||||
key: 1,
|
key: 1,
|
||||||
id: value.reimbursementId,
|
id: value.reimbursementId,
|
||||||
|
@ -223,11 +226,11 @@ class Subpage extends React.Component<any, any> {
|
||||||
amount: value.reimbursementInvoiceAmount + value.reimbursementAdditionalAmount,
|
amount: value.reimbursementInvoiceAmount + value.reimbursementAdditionalAmount,
|
||||||
invoiceAmount: value.reimbursementInvoiceAmount,
|
invoiceAmount: value.reimbursementInvoiceAmount,
|
||||||
additionalAmount: value.reimbursementAdditionalAmount,
|
additionalAmount: value.reimbursementAdditionalAmount,
|
||||||
status: value.reimbursementStatus % 6,
|
status: value.reimbursementStatus % 7,
|
||||||
departmentId: value.reimbursementSubmitDepartment.departmentId,
|
departmentId: value.reimbursementSubmitDepartment.departmentId,
|
||||||
submitDateTime: Date.parse(value.reimbursementSubmitTime),
|
submitDateTime: Date.parse(value.reimbursementSubmitTime),
|
||||||
detail: "查看详情",
|
detail: "查看详情",
|
||||||
back: value.reimbursementDestinationInvoice !== undefined,
|
back: value.reimbursementDestinationInvoice != undefined,
|
||||||
})
|
})
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -242,11 +245,11 @@ class Subpage extends React.Component<any, any> {
|
||||||
amount: value[i].reimbursementInvoiceAmount + value[i].reimbursementAdditionalAmount,
|
amount: value[i].reimbursementInvoiceAmount + value[i].reimbursementAdditionalAmount,
|
||||||
invoiceAmount: value[i].reimbursementInvoiceAmount,
|
invoiceAmount: value[i].reimbursementInvoiceAmount,
|
||||||
additionalAmount: value[i].reimbursementAdditionalAmount,
|
additionalAmount: value[i].reimbursementAdditionalAmount,
|
||||||
status: value[i].reimbursementStatus % 6,
|
status: value[i].reimbursementStatus % 7,
|
||||||
departmentId: value[i].reimbursementSubmitDepartment.departmentId,
|
departmentId: value[i].reimbursementSubmitDepartment.departmentId,
|
||||||
submitDateTime: Date.parse(value[i].reimbursementSubmitTime),
|
submitDateTime: Date.parse(value[i].reimbursementSubmitTime),
|
||||||
detail: "查看详情",
|
detail: "查看详情",
|
||||||
back: value[i].reimbursementDestinationInvoice !== undefined,
|
back: value[i].reimbursementDestinationInvoice != undefined,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
@ -344,7 +347,6 @@ class Subpage extends React.Component<any, any> {
|
||||||
actionRef={this.tableAction}
|
actionRef={this.tableAction}
|
||||||
columns={this.columns}
|
columns={this.columns}
|
||||||
request={async (params, sorter, filter) => {
|
request={async (params, sorter, filter) => {
|
||||||
// 表单搜索项会从 params 传入,传递给后端接口。
|
|
||||||
console.log(params, sorter, filter);
|
console.log(params, sorter, filter);
|
||||||
return this.updateRequest(params.current, params.pageSize, sorter, filter)
|
return this.updateRequest(params.current, params.pageSize, sorter, filter)
|
||||||
|
|
||||||
|
@ -352,7 +354,7 @@ class Subpage extends React.Component<any, any> {
|
||||||
rowKey="key"
|
rowKey="key"
|
||||||
pagination={{
|
pagination={{
|
||||||
defaultPageSize: 5,
|
defaultPageSize: 5,
|
||||||
pageSizeOptions: [5, 10, 20, 50, 100],
|
pageSizeOptions: ['5', '20', '50', '100'],
|
||||||
showQuickJumper: true,
|
showQuickJumper: true,
|
||||||
}}
|
}}
|
||||||
// toolbar={{
|
// toolbar={{
|
||||||
|
|
|
@ -22,7 +22,8 @@ import {invoiceTypeNameMap} from "../../../models/Invoice";
|
||||||
import SingleInvoiceSelector from "./component/SingleInvoiceSelector";
|
import SingleInvoiceSelector from "./component/SingleInvoiceSelector";
|
||||||
import MultiInvoiceSelector from "./component/MultiInvoiceSelector";
|
import MultiInvoiceSelector from "./component/MultiInvoiceSelector";
|
||||||
import {ActionType, StatisticCard} from "@ant-design/pro-components";
|
import {ActionType, StatisticCard} from "@ant-design/pro-components";
|
||||||
import {openNotification} from "./utils";
|
import {openNotification, openErrorNotification} from "./utils";
|
||||||
|
import {NotificationPlacement} from "antd/es/notification/interface";
|
||||||
|
|
||||||
const {Operation} = StatisticCard;
|
const {Operation} = StatisticCard;
|
||||||
|
|
||||||
|
@ -132,12 +133,24 @@ class ReimbursementCreate extends React.Component<any, any> {
|
||||||
|
|
||||||
submitCheck = () => {
|
submitCheck = () => {
|
||||||
//TODO: check
|
//TODO: check
|
||||||
return {ok: true, msg: ""}
|
let msgContent:string = ""
|
||||||
|
if(this.state.departureName == "" ) {
|
||||||
|
msgContent = "未填写出发地"
|
||||||
|
} else if(this.state.destinationName == "") {
|
||||||
|
msgContent = "未填写目的地"
|
||||||
|
} else if(this.state.departureInvoice == null) {
|
||||||
|
msgContent = "未上传出发票据"
|
||||||
|
} else if(this.state.selectedDepartment == null || this.state.selectedDepartment.isEmpty()) {
|
||||||
|
msgContent = "未选择报销部门"
|
||||||
|
} else {
|
||||||
|
return {ok: true, msg: ""}
|
||||||
|
}
|
||||||
|
return {ok: false, msg: msgContent}
|
||||||
}
|
}
|
||||||
submit = () => {
|
submit = () => {
|
||||||
let checkResult = this.submitCheck()
|
let checkResult = this.submitCheck()
|
||||||
if (!checkResult.ok) {
|
if (!checkResult.ok) {
|
||||||
openNotification(checkResult.msg)
|
openErrorNotification(checkResult.msg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let params = {
|
let params = {
|
||||||
|
|
|
@ -1,11 +1,207 @@
|
||||||
import React from "react";
|
import React, {ReactNode} from "react";
|
||||||
import {Reimbursement} from "../../../models/Reimbursement";
|
import {
|
||||||
import {Button, Modal} from "antd";
|
Button, Radio,
|
||||||
|
Col,
|
||||||
|
Descriptions,
|
||||||
|
Modal,
|
||||||
|
Popconfirm,
|
||||||
|
Popover,
|
||||||
|
Row,
|
||||||
|
Select,
|
||||||
|
StepProps,
|
||||||
|
Steps,
|
||||||
|
Tag
|
||||||
|
} from "antd";
|
||||||
|
import TextArea from "antd/es/input/TextArea";
|
||||||
|
import {ApprovalProcess, Invoice, ReimbursementDetailModal} from "../../../models/ReimbursementDetailModal";
|
||||||
|
import dayjs, {Dayjs} from "dayjs";
|
||||||
|
import {ExclamationCircleOutlined} from "@ant-design/icons";
|
||||||
|
import DisplayInvoicesList from "./component/ReimbursementDetailFiles";
|
||||||
|
import {
|
||||||
|
CheckCircleOutlined,
|
||||||
|
ClockCircleOutlined,
|
||||||
|
CloseCircleOutlined,
|
||||||
|
MinusCircleOutlined,
|
||||||
|
SyncOutlined,
|
||||||
|
} from '@ant-design/icons';
|
||||||
|
import axiosInstance from "../../../utils/axiosInstance";
|
||||||
|
import {openNotification} from "./utils";
|
||||||
|
|
||||||
|
const statusEnum = {
|
||||||
|
0: {text: '已报销', status: 'Success'},
|
||||||
|
1: {text: '待主管审批', status: 'Processing'},
|
||||||
|
2: {text: '待财务审批', status: 'Processing'},
|
||||||
|
3: {text: '待财务主管审批', status: 'Processing'},
|
||||||
|
4: {text: '待总经理审批', status: 'Warning'},
|
||||||
|
5: {text: '审批未通过', status: 'Error'},
|
||||||
|
6: {text: '已终止', status: 'Error'},
|
||||||
|
}
|
||||||
|
const statusEnum2 = {
|
||||||
|
0: "主管",
|
||||||
|
1: "财务",
|
||||||
|
2: "财务主管",
|
||||||
|
3: "总经理",
|
||||||
|
}
|
||||||
|
|
||||||
|
// function displayInvoicesList(departureInvoice: Invoice, destinationInvoice: Invoice | null, otherInvoices: Invoice[]) {
|
||||||
|
//
|
||||||
|
// return (<></>)
|
||||||
|
// }
|
||||||
|
|
||||||
|
function displayRawInfo(reimbursement: ReimbursementDetailModal | undefined | null) {
|
||||||
|
if (reimbursement == undefined)
|
||||||
|
return null;
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Descriptions
|
||||||
|
title="基本信息"
|
||||||
|
bordered
|
||||||
|
column={{xxl: 2, xl: 2, lg: 2, md: 2, sm: 1, xs: 1}}
|
||||||
|
>
|
||||||
|
<Descriptions.Item span={1} style={{whiteSpace: "nowrap"}}
|
||||||
|
label="行程">{reimbursement.reimbursementDepartureName}
|
||||||
|
{reimbursement.reimbursementDestinationInvoice != undefined ? " ⇌ " : " → "}
|
||||||
|
{reimbursement.reimbursementDestinationName}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item span={1} style={{whiteSpace: "pre-wrap", textAlign: "center"}}
|
||||||
|
label="日期">
|
||||||
|
{reimbursement.reimbursementDepartureInvoice.invoiceDate}<br/>
|
||||||
|
至<br/>
|
||||||
|
{reimbursement.reimbursementDestinationInvoice !== null ? reimbursement.reimbursementDestinationInvoice.invoiceDate :
|
||||||
|
dayjs(Date.parse(reimbursement.reimbursementDepartureInvoice.invoiceDate) + 24 * 60 * 60 * 1000 * reimbursement.reimbursementTripDuration).format("YYYY-MM-DD")}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item span={1} style={{whiteSpace: "nowrap"}}
|
||||||
|
label="申请人">{reimbursement.reimbursementSubmitStaff.staffName}</Descriptions.Item>
|
||||||
|
<Descriptions.Item span={1} style={{whiteSpace: "normal"}}
|
||||||
|
label="申请部门">{reimbursement.reimbursementSubmitDepartment.departmentName}</Descriptions.Item>
|
||||||
|
<Descriptions.Item span={1} label="总金额">¥{((reimbursement.reimbursementAdditionalAmount +
|
||||||
|
reimbursement.reimbursementInvoiceAmount) / 100.0).toFixed(2)}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item span={1} style={{whiteSpace: "nowrap"}}
|
||||||
|
label="出差时长">{reimbursement.reimbursementTripDuration}天
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item span={1} label="差旅账单" style={{whiteSpace: "nowrap"}}>
|
||||||
|
¥{reimbursement.reimbursementInvoiceAmount / 100.0}{reimbursement.reimbursementDestinationInvoice == undefined ? "(单程)" : "(往返)"}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item span={1} label="公司补贴" style={{whiteSpace: "nowrap"}}>
|
||||||
|
¥{reimbursement.reimbursementAdditionalAmount / 100.0}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item span={2} style={{whiteSpace: "pre-wrap"}} label="申请人备注"
|
||||||
|
labelStyle={{whiteSpace: "nowrap"}}>
|
||||||
|
{reimbursement.reimbursementNote}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item span={2} label="附件列表">
|
||||||
|
<DisplayInvoicesList departureInvoice={reimbursement.reimbursementDepartureInvoice}
|
||||||
|
destinationInvoice={reimbursement.reimbursementDestinationInvoice}
|
||||||
|
otherInvoices={reimbursement.invoices}/>
|
||||||
|
</Descriptions.Item>
|
||||||
|
</Descriptions>
|
||||||
|
</>)
|
||||||
|
}
|
||||||
|
|
||||||
|
function displaySteps(reimbursement: ReimbursementDetailModal | undefined | null, onApprove: boolean) {
|
||||||
|
if (reimbursement == undefined)
|
||||||
|
return null;
|
||||||
|
let currentStep = 0;
|
||||||
|
let items: StepProps[] = [{
|
||||||
|
title: '提交申请',
|
||||||
|
status: 'finish',
|
||||||
|
subTitle: reimbursement.reimbursementSubmitTime.replace("T", " "),
|
||||||
|
description: "【" + reimbursement.reimbursementSubmitStaff.staffName + "】" + "提交申请",
|
||||||
|
}];
|
||||||
|
let approvalSteps = reimbursement.approvalProcesses;
|
||||||
|
if (approvalSteps == null)
|
||||||
|
approvalSteps = []
|
||||||
|
for (let i = 0; i < approvalSteps.length; i++) {
|
||||||
|
if (approvalSteps[i].approvalResult === i + 1) {
|
||||||
|
let description: string | ReactNode = "【" + approvalSteps[i].approvalStaff.staffName + "】" + "审批通过";
|
||||||
|
if (approvalSteps[i].approvalOpinion != null && approvalSteps[i].approvalOpinion !== "") {
|
||||||
|
description = (<>{"【" + approvalSteps[i].approvalStaff.staffName + "】" + "审批通过"}<Popover
|
||||||
|
content={approvalSteps[i].approvalOpinion}><ExclamationCircleOutlined
|
||||||
|
style={{marginLeft: 5}}/></Popover></>)
|
||||||
|
}
|
||||||
|
items.push({
|
||||||
|
// @ts-ignore
|
||||||
|
title: statusEnum2[i] + "审批",
|
||||||
|
status: 'finish',
|
||||||
|
subTitle: approvalSteps[i].approvalTime.replace("T", " "),
|
||||||
|
description: description
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reimbursement.reimbursementStatus >= 1 && reimbursement.reimbursementStatus <= 4) {
|
||||||
|
items.push({
|
||||||
|
// @ts-ignore
|
||||||
|
title: statusEnum2[approvalSteps.length] + "审批",
|
||||||
|
status: 'process',
|
||||||
|
subTitle: onApprove ? "请您审核" : "审核中",
|
||||||
|
description: "",
|
||||||
|
})
|
||||||
|
currentStep = items.length - 2;
|
||||||
|
} else if (reimbursement.reimbursementStatus === 0) {
|
||||||
|
items.push({
|
||||||
|
title: '通知出纳',
|
||||||
|
status: 'finish',
|
||||||
|
description: "报销申请成功",
|
||||||
|
})
|
||||||
|
currentStep = items.length - 1;
|
||||||
|
} else if (reimbursement.reimbursementStatus === 5) {
|
||||||
|
for (let i = 0; i < approvalSteps.length; i++) {
|
||||||
|
if (approvalSteps[i].approvalResult === 5) {
|
||||||
|
let description: string | ReactNode = "【" + approvalSteps[i].approvalStaff.staffName + "】" + "驳回申请";
|
||||||
|
if (approvalSteps[i].approvalOpinion != null && approvalSteps[i].approvalOpinion !== "") {
|
||||||
|
description = (<>{"【" + approvalSteps[i].approvalStaff.staffName + "】" + "驳回申请"}<Popover
|
||||||
|
content={approvalSteps[i].approvalOpinion}><ExclamationCircleOutlined style={{marginLeft: 5}}/></Popover></>)
|
||||||
|
}
|
||||||
|
items.push({
|
||||||
|
// @ts-ignore
|
||||||
|
title: statusEnum2[i - 1] + "审批",
|
||||||
|
status: 'error',
|
||||||
|
subTitle: approvalSteps[i].approvalTime.replace("T", " "),
|
||||||
|
description: description
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentStep = items.length - 1;
|
||||||
|
} else if (reimbursement.reimbursementStatus === 6) {
|
||||||
|
for (let i = 0; i < approvalSteps.length; i++) {
|
||||||
|
if (approvalSteps[i].approvalResult === 6) {
|
||||||
|
items.push({
|
||||||
|
title: '申请终止',
|
||||||
|
status: 'error',
|
||||||
|
subTitle: approvalSteps[i].approvalTime.replace("T", " "),
|
||||||
|
description: "【" + reimbursement.reimbursementSubmitStaff.staffName + "】" + "终止申请",
|
||||||
|
})
|
||||||
|
currentStep = items.length - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
items.push({
|
||||||
|
// @ts-ignore
|
||||||
|
title: statusEnum2[approvalSteps.length - 1] + '审批',
|
||||||
|
status: 'wait',
|
||||||
|
subTitle: "",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
console.log(items, currentStep)
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Descriptions
|
||||||
|
title="流程进度"
|
||||||
|
>
|
||||||
|
</Descriptions>
|
||||||
|
<Steps
|
||||||
|
percent={99}
|
||||||
|
current={currentStep}
|
||||||
|
direction={"vertical"}
|
||||||
|
items={items}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</>)
|
||||||
|
}
|
||||||
|
|
||||||
class ReimbursementDetail extends React.Component<any, any> {
|
class ReimbursementDetail extends React.Component<any, any> {
|
||||||
constructor(props: {
|
constructor(props: {
|
||||||
reimbursement: Reimbursement | undefined;
|
reimbursement: ReimbursementDetailModal | undefined;
|
||||||
closeDetail: any;
|
closeDetail: any;
|
||||||
accessLevel: number;
|
accessLevel: number;
|
||||||
}) {
|
}) {
|
||||||
|
@ -14,14 +210,19 @@ class ReimbursementDetail extends React.Component<any, any> {
|
||||||
this.state = {
|
this.state = {
|
||||||
open: props.reimbursement !== undefined,
|
open: props.reimbursement !== undefined,
|
||||||
reimbursement: props.reimbursement,
|
reimbursement: props.reimbursement,
|
||||||
|
approvalOpinion: "",
|
||||||
|
approvalChecked: props.accessLevel === 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static getDerivedStateFromProps(nextProps: any, prevState: any) {
|
static getDerivedStateFromProps(nextProps: any, prevState: any) {
|
||||||
|
console.log(nextProps);
|
||||||
if (nextProps.reimbursement !== prevState.reimbursement) {
|
if (nextProps.reimbursement !== prevState.reimbursement) {
|
||||||
return {
|
return {
|
||||||
open: nextProps.reimbursement !== undefined,
|
open: nextProps.reimbursement !== undefined,
|
||||||
reimbursement: nextProps.reimbursement,
|
reimbursement: nextProps.reimbursement,
|
||||||
|
approvalOpinion: "",
|
||||||
|
approvalChecked: nextProps.accessLevel === 1,
|
||||||
};
|
};
|
||||||
} else return null;
|
} else return null;
|
||||||
}
|
}
|
||||||
|
@ -31,16 +232,145 @@ class ReimbursementDetail extends React.Component<any, any> {
|
||||||
this.props.closeDetail();
|
this.props.closeDetail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
approve = () => {
|
||||||
|
let params = {approvalOpinion: this.state.approvalOpinion}
|
||||||
|
axiosInstance.put("approval/" + this.state.reimbursement.reimbursementId.toString() + "/"+(this.state.approvalChecked?"1":"0"), params).then((res) => {
|
||||||
|
openNotification("审核成功");
|
||||||
|
this.props.closeDetail();
|
||||||
|
}).catch((err) => {
|
||||||
|
openNotification(err.response.data.msg==null?"操作失败,请稍后重试":err.response.data.msg);
|
||||||
|
console.log(err);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
terminate = () => {
|
||||||
|
let params = {approvalOpinion: ""}
|
||||||
|
axiosInstance.put("approval/" + this.state.reimbursement.reimbursementId.toString() + "/-1", params).then((res) => {
|
||||||
|
openNotification("已终止申请");
|
||||||
|
this.props.closeDetail();
|
||||||
|
}).catch((err) => {
|
||||||
|
openNotification(err.response.data.msg==null?"操作失败,请稍后重试":err.response.data.msg);
|
||||||
|
console.log(err);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
getSubmitButton = () => {
|
||||||
|
if (this.state.reimbursement === undefined || this.state.reimbursement.reimbursementStatus === 0
|
||||||
|
|| this.state.reimbursement.reimbursementStatus === 5
|
||||||
|
|| this.state.reimbursement.reimbursementStatus === 6)
|
||||||
|
return null;
|
||||||
|
if (this.props.accessLevel === 1) {
|
||||||
|
if (this.state.approvalChecked)
|
||||||
|
return (
|
||||||
|
<Popconfirm
|
||||||
|
title="确定批准申请吗?"
|
||||||
|
onConfirm={this.approve}
|
||||||
|
okText="确定"
|
||||||
|
cancelText="取消"
|
||||||
|
>
|
||||||
|
<Button type="primary">批准报销</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
)
|
||||||
|
else
|
||||||
|
return (
|
||||||
|
<Popconfirm
|
||||||
|
title="确定驳回流程吗?"
|
||||||
|
onConfirm={this.approve}
|
||||||
|
okText="确定"
|
||||||
|
cancelText="取消"
|
||||||
|
>
|
||||||
|
<Button type="primary" danger>驳回申请</Button>
|
||||||
|
</Popconfirm>)
|
||||||
|
} else if (this.props.accessLevel === 0) {
|
||||||
|
return (
|
||||||
|
<Popconfirm
|
||||||
|
title="确定终止流程吗?"
|
||||||
|
onConfirm={this.terminate}
|
||||||
|
okText="确定"
|
||||||
|
cancelText="取消"
|
||||||
|
>
|
||||||
|
<Button danger type="primary">终止流程</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return <></>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkerMenu = () => {
|
||||||
|
if (this.props.accessLevel === 1 && this.state.reimbursement != undefined &&
|
||||||
|
this.state.reimbursement.reimbursementStatus >= 1 && this.state.reimbursement.reimbursementStatus <= 4) {
|
||||||
|
return (<>
|
||||||
|
<Row>
|
||||||
|
<TextArea autoSize={{minRows: 2}} placeholder="审批意见" value={this.state.approvalOpinion}
|
||||||
|
onChange={(e) => {
|
||||||
|
this.setState({
|
||||||
|
approvalOpinion: e.target.value,
|
||||||
|
})
|
||||||
|
}}/>
|
||||||
|
</Row>
|
||||||
|
<Row style={{marginTop:15}}>
|
||||||
|
<Radio.Group buttonStyle="solid" style={{width:'100%'}} defaultValue={true} onChange={(value) => {
|
||||||
|
this.setState({approvalChecked: value.target.value})
|
||||||
|
}}>
|
||||||
|
<Radio.Button value={true} checked={true} style={{width:'50%',textAlign:"center"}}>通过</Radio.Button>
|
||||||
|
<Radio.Button value={false} style={{width:'50%',textAlign:"center"}}>不通过</Radio.Button>
|
||||||
|
</Radio.Group>
|
||||||
|
</Row>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return <></>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getTag = () => {
|
||||||
|
if (this.state.reimbursement == undefined)
|
||||||
|
return <></>
|
||||||
|
if (this.state.reimbursement.reimbursementStatus === 0)
|
||||||
|
return (<Tag icon={<CheckCircleOutlined/>} color="success" style={{marginLeft: 20, scale: "1.1"}}>
|
||||||
|
单号:{this.state.reimbursement.reimbursementId}
|
||||||
|
</Tag>)
|
||||||
|
else if (this.state.reimbursement.reimbursementStatus >= 5) {
|
||||||
|
return (
|
||||||
|
<Tag icon={<CloseCircleOutlined/>} color="error" style={{marginLeft: 20, scale: "1.1"}}>
|
||||||
|
单号:{this.state.reimbursement.reimbursementId}
|
||||||
|
</Tag>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<Tag icon={<ClockCircleOutlined/>} color="processing" style={{marginLeft: 20, scale: "1.1"}}>
|
||||||
|
单号:{this.state.reimbursement.reimbursementId}
|
||||||
|
</Tag>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Modal title={"报销单详情"} onCancel={this.cancel} open={this.state.open} width={1000}
|
<Modal
|
||||||
destroyOnClose={true}
|
title={<>报销单详情{this.getTag()}</>}
|
||||||
footer={[
|
onCancel={this.cancel} open={this.state.open}
|
||||||
<Button key="next" type="primary" onClick={this.cancel}>
|
width={1000}
|
||||||
关闭
|
destroyOnClose={true}
|
||||||
</Button>]}>
|
footer={[
|
||||||
{this.props.reimbursement === undefined ? "123" : this.props.reimbursement.reimbursementId}
|
this.getSubmitButton(),
|
||||||
</Modal>)
|
<Button key="next" type="default" onClick={this.cancel}>
|
||||||
|
关闭
|
||||||
|
</Button>]}>
|
||||||
|
<Row gutter={40}>
|
||||||
|
<Col span={15}>
|
||||||
|
{displayRawInfo(this.state.reimbursement)}
|
||||||
|
</Col>
|
||||||
|
<Col span={9}>
|
||||||
|
{displaySteps(this.state.reimbursement, this.props.accessLevel === 1)}
|
||||||
|
<Row style={{marginTop: 50}}>
|
||||||
|
<Col span={20}>
|
||||||
|
{this.checkerMenu()}
|
||||||
|
</Col>
|
||||||
|
<Col span={4}/>
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -335,7 +335,6 @@ class MultiInvoiceSelector extends React.Component<any, any> {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
<Button name={"select"} onClick={() => this.pickerOpen(true)}>
|
<Button name={"select"} onClick={() => this.pickerOpen(true)}>
|
||||||
|
|
||||||
{this.state.selectedInvoice === null || this.state.selectedInvoice === undefined ||
|
{this.state.selectedInvoice === null || this.state.selectedInvoice === undefined ||
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
import {Invoice} from "../../../../models/ReimbursementDetailModal";
|
||||||
|
import {InvoiceDetail} from "../../../../models/Invoice";
|
||||||
|
import {Staff} from "../../../../models/Staff";
|
||||||
|
import React, {useState} from "react";
|
||||||
|
import {Tree} from 'antd';
|
||||||
|
import type {DataNode, DirectoryTreeProps} from 'antd/es/tree';
|
||||||
|
import {SwapRightOutlined, SwapLeftOutlined} from '@ant-design/icons'
|
||||||
|
import InvoiceDetailModal from "../../../Invoice/InvoiceDetailModal";
|
||||||
|
import axiosInstance from "../../../../utils/axiosInstance";
|
||||||
|
|
||||||
|
const {DirectoryTree} = Tree;
|
||||||
|
|
||||||
|
function toInvoiceDetail(invoice: Invoice) {
|
||||||
|
let uploader = invoice.invoiceUploader;
|
||||||
|
let initStaff: Staff = {
|
||||||
|
managingDepartment: null,
|
||||||
|
staffBase: "",
|
||||||
|
staffDepartments: [],
|
||||||
|
staffId: "0000",
|
||||||
|
staffName: ""
|
||||||
|
}
|
||||||
|
let resInvoiceDetail: InvoiceDetail = {
|
||||||
|
invoiceAmount: invoice.invoiceAmount ? invoice.invoiceAmount : 0,
|
||||||
|
invoiceNote: invoice.invoiceNote ? invoice.invoiceNote : "",
|
||||||
|
invoiceState: invoice.invoiceState ? invoice.invoiceState : 0,
|
||||||
|
invoiceUploadTime: invoice.invoiceUploadTime ? invoice.invoiceUploadTime : "",
|
||||||
|
invoiceUploader: initStaff,
|
||||||
|
modified: invoice.modified ? invoice.modified : false,
|
||||||
|
invoiceNo: invoice.invoiceNo ? invoice.invoiceNo : "Undefined",
|
||||||
|
invoiceCode: invoice.invoiceCode ? invoice.invoiceCode : "Undefined",
|
||||||
|
invoiceDate: invoice.invoiceDate,
|
||||||
|
invoiceDeparture: invoice.invoiceDeparture ? invoice.invoiceDeparture : "",
|
||||||
|
invoiceDestination: invoice.invoiceDestination ? invoice.invoiceDestination : "",
|
||||||
|
invoiceFileUri: invoice.invoiceFileUri ? invoice.invoiceFileUri : "",
|
||||||
|
invoiceThumbnailUri: invoice.invoiceThumbnailUri ? invoice.invoiceThumbnailUri : "",
|
||||||
|
invoiceId: invoice.invoiceId,
|
||||||
|
invoiceKind: invoice.invoiceKind ? invoice.invoiceKind : 0
|
||||||
|
};
|
||||||
|
return resInvoiceDetail;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function DisplayInvoicesList(props:{departureInvoice: Invoice, destinationInvoice: Invoice | null, otherInvoices: Invoice[]}) {
|
||||||
|
let departureInvoice = props.departureInvoice;
|
||||||
|
let destinationInvoice = props.destinationInvoice;
|
||||||
|
let otherInvoices = props.otherInvoices;
|
||||||
|
|
||||||
|
const [invoiceDetail, setInvoiceDetail] = useState(departureInvoice)
|
||||||
|
const [detailModalOpen, setDetailModalOpen] = useState(false)
|
||||||
|
function getTreeData() {
|
||||||
|
let treeData: DataNode[] = [];
|
||||||
|
let mainData = {
|
||||||
|
title: '往返票据',
|
||||||
|
key: '0-0',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
title: '出发票据',
|
||||||
|
key: departureInvoice.invoiceId.toString(),
|
||||||
|
isLeaf: true,
|
||||||
|
icon: <SwapRightOutlined/>,
|
||||||
|
style: {color: '\t#6495ED'},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
};
|
||||||
|
if (destinationInvoice != null) {
|
||||||
|
mainData.children.push({
|
||||||
|
title: '返程票据',
|
||||||
|
key: destinationInvoice.invoiceId.toString(),
|
||||||
|
isLeaf: true,
|
||||||
|
icon: <SwapLeftOutlined/>,
|
||||||
|
style: {color: '\t#6495ED'},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
mainData.title+=`(${mainData.children.length})`;
|
||||||
|
let othersData: DataNode = {
|
||||||
|
title: '其他票据',
|
||||||
|
key: '0-1',
|
||||||
|
children: []
|
||||||
|
};
|
||||||
|
let cnt = 0
|
||||||
|
for (let i = 0; i < otherInvoices.length; i++) {
|
||||||
|
if (otherInvoices[i].invoiceId != departureInvoice.invoiceId && otherInvoices[i].invoiceId != destinationInvoice?.invoiceId) {
|
||||||
|
othersData.children?.push({
|
||||||
|
title: `附加票据-${cnt + 1}`,
|
||||||
|
key: otherInvoices[i].invoiceId.toString(),
|
||||||
|
isLeaf: true,
|
||||||
|
style: {color: '\t#6495ED'},
|
||||||
|
});
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
othersData.title+=`(${cnt})`;
|
||||||
|
treeData.push(mainData)
|
||||||
|
treeData.push(othersData)
|
||||||
|
return treeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSelect: DirectoryTreeProps['onSelect'] = (keys, info) => {
|
||||||
|
if (keys[0] == '0-0' || keys[0] == '0-1') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let invoiceId = Number(keys[0]);
|
||||||
|
axiosInstance.get("common/invoice/" + invoiceId).then((res) => {
|
||||||
|
setInvoiceDetail(res.data);
|
||||||
|
setDetailModalOpen(true);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
return (<>
|
||||||
|
<DirectoryTree
|
||||||
|
selectedKeys={[]}
|
||||||
|
onSelect={onSelect}
|
||||||
|
treeData={getTreeData()}
|
||||||
|
/>
|
||||||
|
<InvoiceDetailModal invoiceDetail={invoiceDetail} open={detailModalOpen} onClose={() => {
|
||||||
|
setDetailModalOpen(false)
|
||||||
|
}}/>
|
||||||
|
</>)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DisplayInvoicesList
|
|
@ -9,3 +9,9 @@ export const openNotification = (hint: string) => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const openErrorNotification = (placement: string) => {
|
||||||
|
notification.error({
|
||||||
|
message: `${placement}`
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue