diff --git a/src/components/SearchForm.jsx b/src/components/SearchForm.jsx index 5fc1fa1..bbb73d4 100644 --- a/src/components/SearchForm.jsx +++ b/src/components/SearchForm.jsx @@ -99,9 +99,9 @@ const SearchForm = ({ initialValue, onSubmit, onReset, onMounted, confirmText, f }, []); const onFinish = values => { - console.log("Received values of form, origin form value: \n", values); + //console.log("Received values of form, origin form value: \n", values); const dest = formValuesMapper(values); - console.log("form value send to onSubmit:\n", dest); + //console.log("form value send to onSubmit:\n", dest); const str = new URLSearchParams(dest).toString(); setFormValues(values); setFormValuesToSub(dest); diff --git a/src/stores/Airticket.js b/src/stores/Airticket.js index 23c8a5f..d9ae6ba 100644 --- a/src/stores/Airticket.js +++ b/src/stores/Airticket.js @@ -11,6 +11,7 @@ const airTicketStore = create((set, get) => ({ setPlanDetail: planDetail => set({ planDetail }), setGuestList: guestList => set({ guestList }), setVEIFlightBill: vEIFlightBill => set({ vEIFlightBill }), + setVeiPlanChangeTxt: veiPlanChangeTxt => set({ veiPlanChangeTxt }), async getPlanList(vei_sn, GRI_Name, TimeStart, TimeEnd) { const { setLoading, setPlanList } = get(); @@ -81,9 +82,9 @@ const airTicketStore = create((set, get) => ({ }; const { errcode, result } = await fetchJSON(`${HT_HOST}/Service_BaseInfoWeb/GetVEIFlightBill`, searchParams); const _result = errcode !== 0 ? [] : result; - console.log(_result); setVEIFlightBill(_result); }, + //保存费用 async postFlightCost(values) { const formData = new FormData(); for (const [key, value] of Object.entries(values)) { @@ -98,7 +99,7 @@ const airTicketStore = create((set, get) => ({ } }); }, - + //删除费用 async deleteFlightCost(CLC_SN) { const searchParams = { CLC_SN: CLC_SN, @@ -107,6 +108,46 @@ const airTicketStore = create((set, get) => ({ const _result = errcode !== 0 ? [] : result; return _result; }, + //获取变更信息 + async getVeiPlanChange(VEI_SN, GRI_SN) { + const { setVeiPlanChangeTxt } = get(); + const searchParams = { + VEI_SN: VEI_SN, + GRI_SN: GRI_SN, + }; + const { errcode, result } = await fetchJSON(`${HT_HOST}/Service_BaseInfoWeb/GetVeiFlightPlanChange`, searchParams); + const _result = errcode !== 0 ? [] : result; + setVeiPlanChangeTxt(_result); + }, + //提交变更确认 + async postVeiFlightPlanConfirm(VEI_SN, GRI_SN, LMI_SN, ConfirmInfo) { + const formData = new FormData(); + formData.append("VEI_SN", VEI_SN); + formData.append("GRI_SN", GRI_SN); + formData.append("LMI_SN", LMI_SN); + formData.append("ConfirmInfo", ConfirmInfo); + const postUrl = HT_HOST + "/Service_BaseInfoWeb/VeiFlightPlanConfirm"; + return postForm(postUrl, formData).then(json => { + if (json.errcode == 0) { + return json; + } else { + throw new Error(json.errmsg + ": " + json.errcode); + } + }); + }, + //提交账单 + async postVEIFlightBillSubmit(values) { + const formData = new FormData(); + formData.append("billdata", JSON.stringify(values)); + const postUrl = HT_HOST + "/Service_BaseInfoWeb/VEIFlightBillSubmit"; + return postForm(postUrl, formData).then(json => { + if (json.errcode == 0) { + return json; + } else { + throw new Error(json.errmsg + ": " + json.errcode); + } + }); + }, })); export default airTicketStore; diff --git a/src/views/airticket/Index.jsx b/src/views/airticket/Index.jsx index 52c4f05..7c18370 100644 --- a/src/views/airticket/Index.jsx +++ b/src/views/airticket/Index.jsx @@ -112,7 +112,7 @@ const Airticket = props => { - + diff --git a/src/views/airticket/Invoice.jsx b/src/views/airticket/Invoice.jsx index 2d0bb2b..e1140b2 100644 --- a/src/views/airticket/Invoice.jsx +++ b/src/views/airticket/Invoice.jsx @@ -1,6 +1,6 @@ import { useState, useEffect } from "react"; -import { Grid, Divider, Layout, Spin, Input, Col, Row, Space, Checkbox, Table, Button } from "antd"; -import { PhoneOutlined, CustomerServiceOutlined, AudioOutlined, AuditOutlined } from "@ant-design/icons"; +import { Grid, Divider, Layout, Spin, Input, Col, Row, Space, Checkbox, Table, Button, App } from "antd"; +import { PhoneOutlined, CustomerServiceOutlined, FrownTwoTone, LikeTwoTone } from "@ant-design/icons"; import { useParams, useHref, useNavigate, NavLink } from "react-router-dom"; import { isEmpty, formatColonTime } from "@/utils/commons"; import dayjs from "dayjs"; @@ -12,12 +12,14 @@ import { usingStorage } from "@/hooks/usingStorage"; const Invoice = props => { const navigate = useNavigate(); + const { notification } = App.useApp(); const { travelAgencyId } = usingStorage(); - const [getVEIFlightBill, vEIFlightBill, loading] = airTicketStore(state => [state.getVEIFlightBill, state.vEIFlightBill, state.loading]); + const [getVEIFlightBill, vEIFlightBill, loading, postVEIFlightBillSubmit] = airTicketStore(state => [state.getVEIFlightBill, state.vEIFlightBill, state.loading, state.postVEIFlightBillSubmit]); const showTotal = total => `合计 ${total} `; + const [selectedValues, setSelectedValues] = useState([]); //统计总的费用 - const totalFee = vEIFlightBill.reduce((acc, curr) => acc + curr.ServiceFee, 0); + const totalFee = vEIFlightBill && vEIFlightBill.reduce((acc, curr) => acc + curr.ServiceFee, 0); const vEIFlightBillColumns = [ { title: "团名", @@ -61,7 +63,6 @@ const Invoice = props => { dataIndex: "FlightNo", render: (text, record) => (record.CostType == "出票" ? text : "-"), }, - { title: "PNR", key: "PNR", @@ -101,9 +102,20 @@ const Invoice = props => { title: "审核状态", children: [ { - title: , + title: ( + + ), dataIndex: "CheckStatus", //状态小于2,表示还未提交审核 - render: (text, record) => (record.CheckStatus < 2 ? 待提交 : record.CheckStatusName), + render: (text, record) => + record.CheckStatus < 2 ? ( + handleCheckboxChange(event, record.CLC_SN, record.OPI_SN)} checked={checkboxStates(record.CLC_SN)}> + 待提交 + + ) : ( + record.CheckStatusName + ), }, ], sorter: (a, b) => { @@ -111,6 +123,48 @@ const Invoice = props => { }, }, ]; + //获取当前状态 + const checkboxStates = CLC_SN => { + return selectedValues.some(v => v.CLC_SN === CLC_SN); + }; + // 处理checkbox改变事件 + const handleCheckboxChange = (event, CLC_SN, OPI_SN) => { + const value = { CLC_SN: CLC_SN, OPI_SN: OPI_SN }; + if (event.target.checked) { + setSelectedValues([...selectedValues, value]); // 如果被选中,则添加到数组 + } else { + setSelectedValues(selectedValues.filter(v => v.CLC_SN !== value.CLC_SN)); // 如果取消选中,则从数组中移除 + } + }; + //提交账单 + const postInvoice = () => { + postVEIFlightBillSubmit(selectedValues) + .then(() => { + notification.success({ + message: `成功`, + description: "保存成功!", + placement: "top", + duration: 4, + icon: , + }); + setSelectedValues([]); //清空选中的项目 + }) + .catch(() => { + notification.error({ + message: `错误`, + description: "保存失败", + placement: "top", + duration: 4, + icon: , + }); + }); + }; + //全选或不全选 + const checkALL = () => { + if (isEmpty(vEIFlightBill)) return; + const allChecked = selectedValues.length === vEIFlightBill.filter(item => item.CheckStatus < 2).length; + setSelectedValues(allChecked ? [] : vEIFlightBill.filter(item => item.CheckStatus < 2).map(item => ({ CLC_SN: item.CLC_SN, OPI_SN: item.OPI_SN }))); // 如果全选,则清空数组,否则添加所有项 + }; useEffect(() => {}, []); @@ -141,10 +195,19 @@ const Invoice = props => { -
+
+ + + + + + + ); }; diff --git a/src/views/airticket/Plan.jsx b/src/views/airticket/Plan.jsx index 3641d4a..d67fc92 100644 --- a/src/views/airticket/Plan.jsx +++ b/src/views/airticket/Plan.jsx @@ -11,8 +11,8 @@ import BackBtn from "@/components/BackBtn"; const AirticketPlan = props => { const { coli_sn, gri_sn } = useParams(); - const { travelAgencyId, loginToken } = usingStorage(); - const [getPlanDetail, planDetail, getGuestList, guestList, loading, postFlightDetail, postFlightCost, deleteFlightCost] = airTicketStore(state => [ + const { travelAgencyId, loginToken, userId } = usingStorage(); + const [getPlanDetail, planDetail, getGuestList, guestList, loading, postFlightDetail, postFlightCost, deleteFlightCost, getVeiPlanChange, veiPlanChangeTxt, postVeiFlightPlanConfirm] = airTicketStore(state => [ state.getPlanDetail, state.planDetail, state.getGuestList, @@ -21,6 +21,9 @@ const AirticketPlan = props => { state.postFlightDetail, state.postFlightCost, state.deleteFlightCost, + state.getVeiPlanChange, + state.veiPlanChangeTxt, + state.postVeiFlightPlanConfirm, ]); const reservationUrl = `https://p9axztuwd7x8a7.mycht.cn/Service_BaseInfoWeb/FlightPlanDocx?GRI_SN=${gri_sn}&VEI_SN=${travelAgencyId}&token=${loginToken}`; const reservationPreviewUrl = OFFICEWEBVIEWERURL + encodeURIComponent(reservationUrl); @@ -255,8 +258,10 @@ const AirticketPlan = props => { // 机票信息编辑表单 begin const [isModalOpen, setIsModalOpen] = useState(false); + const [isModalOpen_confirmInfo, setisModalOpen_confirmInfo] = useState(false); const [isTicketType, setisTicketType] = useState(true); const [ticket_form] = Form.useForm(); + const [confirmInfo_form] = Form.useForm(); const showModal = ticket => { setIsModalOpen(true); @@ -449,11 +454,73 @@ const AirticketPlan = props => { ); }; + //变更确认表单 + const showModal_confirmInfo = ConfirmInfo => { + setisModalOpen_confirmInfo(true); + confirmInfo_form.setFieldsValue({ ConfirmInfo: ConfirmInfo }); + }; + const handleCancel_confirmInfo = () => { + setisModalOpen_confirmInfo(false); + confirmInfo_form.resetFields(); + }; + + const handleOk_confirmInfo = () => { + confirmInfo_form + .validateFields() + .then(values => { + console.log("Received values of form: ", values.ConfirmInfo); + postVeiFlightPlanConfirm(travelAgencyId, gri_sn, userId, values.ConfirmInfo) + .then(() => { + notification.success({ + message: `成功`, + description: "保存成功!", + placement: "top", + duration: 4, + icon: , + }); + getVeiPlanChange(travelAgencyId, gri_sn); + }) + .catch(() => { + notification.error({ + message: `错误`, + description: "保存失败", + placement: "top", + duration: 4, + icon: , + }); + }); + confirmInfo_form.resetFields(); + setisModalOpen_confirmInfo(false); + }) + .catch(info => { + console.log("Validate Failed:", info); + }); + }; + //确认变更的界面 + const ConfirmInfoModal = () => { + return ( + <> + +
+ + + + +
+ + ); + }; + // 机票信息编辑表单 end useEffect(() => { - getPlanDetail(travelAgencyId, gri_sn); - getGuestList(coli_sn); + getPlanDetail(travelAgencyId, gri_sn); //计划详情,含费用列表 + getGuestList(coli_sn); //客人列表 + getVeiPlanChange(travelAgencyId, gri_sn); //计划变更信息 }, []); return ( @@ -464,6 +531,7 @@ const AirticketPlan = props => { +
{/* */} @@ -471,12 +539,36 @@ const AirticketPlan = props => { 下载 + + + 出票信息 + + 计划变更 + + + + + + + + + + + + ); };