diff --git a/src/models/Invoice.ts b/src/models/Invoice.ts index 14631d9..ae000dd 100644 --- a/src/models/Invoice.ts +++ b/src/models/Invoice.ts @@ -89,7 +89,7 @@ export interface InvoiceDetail { invoiceUploader: Staff; invoiceUploadTime: string|Dayjs; modified: boolean; - reimbursement: Reimbursement; + reimbursement?: Reimbursement; } export interface InvoiceIdentifyResponse { diff --git a/src/models/Reimbursement.ts b/src/models/Reimbursement.ts index 58862cd..aada2a6 100644 --- a/src/models/Reimbursement.ts +++ b/src/models/Reimbursement.ts @@ -69,12 +69,13 @@ export interface Reimbursement { reimbursementInvoiceAmount: number; reimbursementNote?: string; /** - * 0: success + * 0: 已报销 * 1: 待主管审批 * 2: 待财务审批 * 3: 待财务主管审批 * 4: 待总经理审批 * 5: 未通过 + * 6: 已终止 */ reimbursementStatus: number; reimbursementSubmitDepartment: Department; diff --git a/src/models/ReimbursementDetailModal.ts b/src/models/ReimbursementDetailModal.ts new file mode 100644 index 0000000..6e1cbcc --- /dev/null +++ b/src/models/ReimbursementDetailModal.ts @@ -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; + /** + * 补助总金额 + */ + 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(val: any, typ: any): T { + return transform(val, typ, jsonToJSProps); +} + +function uncast(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"), +}; diff --git a/src/pages/reimbursement/mine/MyReimbursement.tsx b/src/pages/reimbursement/mine/MyReimbursement.tsx index 12c4cea..0f53073 100644 --- a/src/pages/reimbursement/mine/MyReimbursement.tsx +++ b/src/pages/reimbursement/mine/MyReimbursement.tsx @@ -70,6 +70,7 @@ const statusEnum = { 3: {text: '待财务主管审批', status: 'Processing'}, 4: {text: '待总经理审批', status: 'Warning'}, 5: {text: '审批未通过', status: 'Error'}, + 6: {text: '已终止', status: 'Error'}, } class Subpage extends React.Component { @@ -196,10 +197,12 @@ class Subpage extends React.Component { closeDetail = () => { this.setState({detailedReimbursement: undefined}) + this.tableAction.current?.reload() } showDetail(reimbursementId: number) { axiosInstance.get("common/reimbursement/" + reimbursementId).then((response) => { + console.log(response.data) this.setState({detailedReimbursement: response.data}) }).catch((error) => { openNotification("拉取报销单详情失败") @@ -207,12 +210,12 @@ class Subpage extends React.Component { } - async converter(value: Reimbursement[] | undefined | Reimbursement, pageSize: number | undefined) { - if (value === undefined) { + async converter(value: Reimbursement[] | undefined | Reimbursement | null, pageSize: number | undefined) { + if (value == undefined) { return [] } let result: TableListItem[] = [] - if ("reimbursementAdditionalAmount" in value) { + if ("reimbursementId" in value) { result.push({ key: 1, id: value.reimbursementId, @@ -223,11 +226,11 @@ class Subpage extends React.Component { amount: value.reimbursementInvoiceAmount + value.reimbursementAdditionalAmount, invoiceAmount: value.reimbursementInvoiceAmount, additionalAmount: value.reimbursementAdditionalAmount, - status: value.reimbursementStatus % 6, + status: value.reimbursementStatus % 7, departmentId: value.reimbursementSubmitDepartment.departmentId, submitDateTime: Date.parse(value.reimbursementSubmitTime), detail: "查看详情", - back: value.reimbursementDestinationInvoice !== undefined, + back: value.reimbursementDestinationInvoice != undefined, }) return result } @@ -242,11 +245,11 @@ class Subpage extends React.Component { amount: value[i].reimbursementInvoiceAmount + value[i].reimbursementAdditionalAmount, invoiceAmount: value[i].reimbursementInvoiceAmount, additionalAmount: value[i].reimbursementAdditionalAmount, - status: value[i].reimbursementStatus % 6, + status: value[i].reimbursementStatus % 7, departmentId: value[i].reimbursementSubmitDepartment.departmentId, submitDateTime: Date.parse(value[i].reimbursementSubmitTime), detail: "查看详情", - back: value[i].reimbursementDestinationInvoice !== undefined, + back: value[i].reimbursementDestinationInvoice != undefined, }) } return result @@ -344,7 +347,6 @@ class Subpage extends React.Component { actionRef={this.tableAction} columns={this.columns} request={async (params, sorter, filter) => { - // 表单搜索项会从 params 传入,传递给后端接口。 console.log(params, sorter, filter); return this.updateRequest(params.current, params.pageSize, sorter, filter) @@ -352,7 +354,7 @@ class Subpage extends React.Component { rowKey="key" pagination={{ defaultPageSize: 5, - pageSizeOptions: [5, 10, 20, 50, 100], + pageSizeOptions: ['5', '20', '50', '100'], showQuickJumper: true, }} // toolbar={{ diff --git a/src/pages/reimbursement/mine/ReimbursementCreate.tsx b/src/pages/reimbursement/mine/ReimbursementCreate.tsx index 3596448..b0baadf 100644 --- a/src/pages/reimbursement/mine/ReimbursementCreate.tsx +++ b/src/pages/reimbursement/mine/ReimbursementCreate.tsx @@ -22,7 +22,8 @@ import {invoiceTypeNameMap} from "../../../models/Invoice"; import SingleInvoiceSelector from "./component/SingleInvoiceSelector"; import MultiInvoiceSelector from "./component/MultiInvoiceSelector"; 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; @@ -132,12 +133,24 @@ class ReimbursementCreate extends React.Component { submitCheck = () => { //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 = () => { let checkResult = this.submitCheck() if (!checkResult.ok) { - openNotification(checkResult.msg) + openErrorNotification(checkResult.msg) return } let params = { diff --git a/src/pages/reimbursement/mine/ReimbursementDetail.tsx b/src/pages/reimbursement/mine/ReimbursementDetail.tsx index d08fd0b..d2133e9 100644 --- a/src/pages/reimbursement/mine/ReimbursementDetail.tsx +++ b/src/pages/reimbursement/mine/ReimbursementDetail.tsx @@ -1,11 +1,207 @@ -import React from "react"; -import {Reimbursement} from "../../../models/Reimbursement"; -import {Button, Modal} from "antd"; +import React, {ReactNode} from "react"; +import { + 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 ( + <> + + {reimbursement.reimbursementDepartureName} + {reimbursement.reimbursementDestinationInvoice != undefined ? " ⇌ " : " → "} + {reimbursement.reimbursementDestinationName} + + + {reimbursement.reimbursementDepartureInvoice.invoiceDate}
+ 至
+ {reimbursement.reimbursementDestinationInvoice !== null ? reimbursement.reimbursementDestinationInvoice.invoiceDate : + dayjs(Date.parse(reimbursement.reimbursementDepartureInvoice.invoiceDate) + 24 * 60 * 60 * 1000 * reimbursement.reimbursementTripDuration).format("YYYY-MM-DD")} +
+ {reimbursement.reimbursementSubmitStaff.staffName} + {reimbursement.reimbursementSubmitDepartment.departmentName} + ¥{((reimbursement.reimbursementAdditionalAmount + + reimbursement.reimbursementInvoiceAmount) / 100.0).toFixed(2)} + + {reimbursement.reimbursementTripDuration}天 + + + ¥{reimbursement.reimbursementInvoiceAmount / 100.0}{reimbursement.reimbursementDestinationInvoice == undefined ? "(单程)" : "(往返)"} + + + ¥{reimbursement.reimbursementAdditionalAmount / 100.0} + + + {reimbursement.reimbursementNote} + + + + +
+ ) +} + +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 + "】" + "审批通过"}) + } + 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 + "】" + "驳回申请"}) + } + 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 ( + <> + + + + + ) +} class ReimbursementDetail extends React.Component { constructor(props: { - reimbursement: Reimbursement | undefined; + reimbursement: ReimbursementDetailModal | undefined; closeDetail: any; accessLevel: number; }) { @@ -14,14 +210,19 @@ class ReimbursementDetail extends React.Component { this.state = { open: props.reimbursement !== undefined, reimbursement: props.reimbursement, + approvalOpinion: "", + approvalChecked: props.accessLevel === 1, } } static getDerivedStateFromProps(nextProps: any, prevState: any) { + console.log(nextProps); if (nextProps.reimbursement !== prevState.reimbursement) { return { open: nextProps.reimbursement !== undefined, reimbursement: nextProps.reimbursement, + approvalOpinion: "", + approvalChecked: nextProps.accessLevel === 1, }; } else return null; } @@ -31,16 +232,145 @@ class ReimbursementDetail extends React.Component { 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 ( + + + + ) + else + return ( + + + ) + } else if (this.props.accessLevel === 0) { + return ( + + + + ) + + } else { + return <> + } + } + checkerMenu = () => { + if (this.props.accessLevel === 1 && this.state.reimbursement != undefined && + this.state.reimbursement.reimbursementStatus >= 1 && this.state.reimbursement.reimbursementStatus <= 4) { + return (<> + +