diff --git a/src/models/Reimbursement.ts b/src/models/Reimbursement.ts new file mode 100644 index 0000000..5d4fcf3 --- /dev/null +++ b/src/models/Reimbursement.ts @@ -0,0 +1,294 @@ +// To parse this data: +// +// import { Convert, ApifoxModal } from "./file"; +// +// const apifoxModal = Convert.toApifoxModal(json); +// +// These functions will throw an error if the JSON doesn't +// match the expected interface, even if the JSON is valid. + +export interface ApifoxModal { + records: Reimbursement[]; + total: number; +} + +/** + * invoice + */ +export interface Invoice { + invoiceAmount: number; + invoiceCode: string; + invoiceDate: string; + invoiceDeparture?: string; + invoiceDestination?: string; + invoiceFileUri: string; + invoiceId: number; + invoiceKind: number; + invoiceName?: string; + invoiceNo: string; + invoiceNote: string; + /** + * -1: 不合格 0: 已上传 1: 报销中 2: 已报销 + */ + invoiceState: number; + invoiceThumbnailUri: string; + invoiceUploader: Staff; + invoiceUploadTime: string; + modified: boolean; + reimbursement: Reimbursement; +} + +/** + * reimbursement + */ +export interface Reimbursement { + /** + * 差旅补助金额 + */ + reimbursementAdditionalAmount: number; + reimbursementDepartureInvoice: Invoice; + reimbursementDepartureName: string; + reimbursementDestinationInvoice?: Invoice; + reimbursementDestinationName: string; + reimbursementId: number; + /** + * 发票金额 + */ + reimbursementInvoiceAmount: number; + reimbursementNote?: string; + /** + * 0: success + * 1: 待主管审批 + * 2: 待财务审批 + * 3: 待财务主管审批 + * 4: 待总经理审批 + * 5: 未通过 + */ + reimbursementStatus: number; + reimbursementSubmitDepartment: Department; + reimbursementSubmitStaff: Staff; + reimbursementSubmitTime: string; + /** + * 单位为天 + */ + reimbursementTripDuration: number; +} + +/** + * department + */ +export interface Department { + departmentId: number; + departmentManager: Staff; + departmentName: string; + staff: Staff[]; +} + +/** + * staff + */ +export interface Staff { + managingDepartment: Department; + staffBase: string; + staffDepartments: Department[]; + staffId: string; + staffName: string; +} + +// Converts JSON strings to/from your types +// and asserts the results of JSON.parse at runtime +export class Convert { + public static toApifoxModal(json: string): ApifoxModal { + return cast(JSON.parse(json), r("ApifoxModal")); + } + + public static apifoxModalToJson(value: ApifoxModal): string { + return JSON.stringify(uncast(value, r("ApifoxModal")), 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 = { + "ApifoxModal": o([ + { json: "records", js: "records", typ: a(r("Reimbursement")) }, + { json: "total", js: "total", typ: 0 }, + ], "any"), + "Invoice": o([ + { json: "invoiceAmount", js: "invoiceAmount", typ: 0 }, + { json: "invoiceCode", js: "invoiceCode", typ: "" }, + { json: "invoiceDate", js: "invoiceDate", typ: "" }, + { json: "invoiceDeparture", js: "invoiceDeparture", typ: u(undefined, "") }, + { json: "invoiceDestination", js: "invoiceDestination", typ: u(undefined, "") }, + { json: "invoiceFileUri", js: "invoiceFileUri", typ: "" }, + { json: "invoiceId", js: "invoiceId", typ: 0 }, + { json: "invoiceKind", js: "invoiceKind", typ: 0 }, + { json: "invoiceName", js: "invoiceName", typ: u(undefined, "") }, + { json: "invoiceNo", js: "invoiceNo", typ: "" }, + { json: "invoiceNote", js: "invoiceNote", typ: "" }, + { json: "invoiceState", js: "invoiceState", typ: 0 }, + { json: "invoiceThumbnailUri", js: "invoiceThumbnailUri", typ: "" }, + { json: "invoiceUploader", js: "invoiceUploader", typ: r("Staff") }, + { json: "invoiceUploadTime", js: "invoiceUploadTime", typ: "" }, + { json: "modified", js: "modified", typ: true }, + { json: "reimbursement", js: "reimbursement", typ: r("Reimbursement") }, + ], "any"), + "Reimbursement": o([ + { json: "reimbursementAdditionalAmount", js: "reimbursementAdditionalAmount", typ: 0 }, + { json: "reimbursementDepartureInvoice", js: "reimbursementDepartureInvoice", typ: r("Invoice") }, + { json: "reimbursementDepartureName", js: "reimbursementDepartureName", typ: "" }, + { json: "reimbursementDestinationInvoice", js: "reimbursementDestinationInvoice", typ: u(undefined, 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, "") }, + { 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: r("Staff") }, + { json: "departmentName", js: "departmentName", typ: "" }, + { json: "staff", js: "staff", typ: a(r("Staff")) }, + ], "any"), + "Staff": o([ + { json: "managingDepartment", js: "managingDepartment", typ: r("Department") }, + { json: "staffBase", js: "staffBase", typ: "" }, + { json: "staffDepartments", js: "staffDepartments", typ: a(r("Department")) }, + { json: "staffId", js: "staffId", typ: "" }, + { json: "staffName", js: "staffName", typ: "" }, + ], "any"), +}; \ No newline at end of file diff --git a/src/pages/reimbursement/mine/MyReimbursement.tsx b/src/pages/reimbursement/mine/MyReimbursement.tsx index d94177e..08f9191 100644 --- a/src/pages/reimbursement/mine/MyReimbursement.tsx +++ b/src/pages/reimbursement/mine/MyReimbursement.tsx @@ -8,7 +8,8 @@ import axiosInstance from "../../../utils/axiosInstance"; import {FormProps} from "antd/es/form/Form"; import {FormInstance} from "antd/es/form"; import {SortOrder} from "antd/es/table/interface"; -import {Reimbursement} from "../../../models/Staff"; +import {Reimbursement} from "../../../models/Reimbursement"; +import qs from 'qs'; const valueEnum = { 0: 'success', @@ -65,6 +66,7 @@ const statusEnum = { 4: {text: '待总经理审批', status: 'Warning'}, 5: {text: '审批未通过', status: 'Error'}, } + class Subpage extends React.Component { tableAction = React.createRef(); @@ -100,6 +102,7 @@ class Subpage extends React.Component { dataIndex: 'beginDate', search: false, valueType: 'date', + sorter: true, //render: (_) => {_}, }, { @@ -198,23 +201,26 @@ class Subpage extends React.Component { return Date.now() } - async converter(value: Reimbursement[], pageSize: number | undefined) { + async converter(value: Reimbursement[] | undefined, pageSize: number | undefined) { + if (value === undefined) { + return [] + } let result: TableListItem[] = [] for (let i = 0; i < value.length; i++) { result.push({ - id: value[i].reimbursementId, - beginDate: await this.getInvoiceDate(value[i].reimbursementDepartureInvoiceId), - endDate: await this.getInvoiceDate(value[i].reimbursementDestinationInvoiceId), + id: value[i].reimbursementSubmitDepartment.departmentId, + beginDate: Date.parse(value[i].reimbursementDepartureInvoice.invoiceDate), + endDate: Date.parse(value[i].reimbursementDepartureInvoice.invoiceDate)+value[i].reimbursementTripDuration*24*60*60*1000, duration: value[i].reimbursementTripDuration, OD: [value[i].reimbursementDepartureName, value[i].reimbursementDestinationName], amount: value[i].reimbursementInvoiceAmount + value[i].reimbursementAdditionalAmount, invoiceAmount: value[i].reimbursementInvoiceAmount, additionalAmount: value[i].reimbursementAdditionalAmount, status: value[i].reimbursementStatus % 6, - departmentId: value[i].reimbursementSubmitDepartmentId, + departmentId: value[i].reimbursementSubmitDepartment.departmentId, submitDateTime: (new Date(value[i].reimbursementSubmitTime)).getTime(), detail: "查看详情", - back: value[i].reimbursementDestinationInvoiceId !== undefined, + back: value[i].reimbursementDestinationInvoice !== undefined, }) } return result @@ -240,37 +246,41 @@ class Subpage extends React.Component { if (this.state.searchWord.trim() === "") { current = (current === undefined ? 0 : current) pageSize = (pageSize === undefined ? 5 : pageSize) - let params:any= { + let params: any = { current: current, pageSize: pageSize, } - if(filter.status !== undefined && filter.status !== null && filter.status.length !== 0){ - params['reimbursementStatuses'] = filter.status + if (filter.status !== undefined && filter.status !== null && filter.status.length !== 0) { + params['reimbursementStatuses'] = qs.stringify({reimbursementStatuses: filter.status}, {arrayFormat: 'indices'}) } - if(filter.departmentId !== undefined && filter.departmentId !== null && filter.departmentId.length !== 0){ - params['reimbursementSubmitDepartments'] = filter.departmentId + if (filter.departmentId !== undefined && filter.departmentId !== null && filter.departmentId.length !== 0) { + params['reimbursementSubmitDepartments'] = qs.stringify({reimbursementSubmitDepartments: filter.departmentId}, {arrayFormat: 'indices'}) } - if(sort.id !== undefined && sort.id !== null){ - params['sortBy']="reimbursementId" + if (sort.id !== undefined && sort.id !== null) { + params['sortBy'] = "reimbursementId" params['asc'] = (sort.id === "ascend") } - if(sort.duration !== undefined && sort.duration !== null){ - params['sortBy']="reimbursementTripDuration" + if (sort.duration !== undefined && sort.duration !== null) { + params['sortBy'] = "reimbursementTripDuration" params['asc'] = (sort.duration === "ascend") } - if(sort.submitDateTime !== undefined && sort.submitDateTime !== null){ - params['sortBy']="reimbursementSubmitTime" + if (sort.submitDateTime !== undefined && sort.submitDateTime !== null) { + params['sortBy'] = "reimbursementSubmitTime" params['asc'] = (sort.submitDateTime === "ascend") } + if(sort.beginDate !== undefined && sort.beginDate !== null){ + params['sortBy'] = "reimbursementDepartureDate" + params['asc'] = (sort.beginDate === "ascend") + } console.log(params) let response = await axiosInstance.get('common/reimbursement', {params: params}) - tableListDataSource =await this.converter(response.data.records, pageSize) + tableListDataSource = await this.converter(response.data.records, pageSize) console.log(response.data.records) totalRecordLength = response.data.total } else { let response = await axiosInstance.get('common/reimbursement/' + this.state.searchWord.trim(), {}) - tableListDataSource =await this.converter(response.data.records, pageSize) + tableListDataSource = await this.converter(response.data.records, pageSize) totalRecordLength = tableListDataSource.length }