diff --git a/package.json b/package.json
index 459544b..e6681c7 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "global-highlights-hub",
"private": true,
- "version": "2.0.0-beta.4",
+ "version": "2.0.0-beta.5",
"type": "module",
"scripts": {
"dev": "vite",
diff --git a/public/locales/en/common.json b/public/locales/en/common.json
index a8a131c..ebc8ee7 100644
--- a/public/locales/en/common.json
+++ b/public/locales/en/common.json
@@ -25,46 +25,40 @@
"Import": "Import",
"Export": "Export",
"Copy": "Copy",
-
"sureCancel": "Are you sure to cancel?",
- "sureDelete":"Are you sure to delete?",
- "sureSubmit":"Are you sure to submit?",
+ "sureDelete": "Are you sure to delete?",
+ "sureSubmit": "Are you sure to submit?",
"Yes": "Yes",
"No": "No",
-
"Success": "Success",
"Failed": "Failed",
-
"All": "All",
-
"Table": {
"Total": "Total {{total}} items"
},
-
"Login": "Login",
"Username": "Username",
"Realname": "Realname",
"Password": "Password",
-
"ChangePassword": "Change password",
"Profile": "Profile",
"Logout": "Logout",
"LoginTimeout": "Login timeout",
"LoginTimeoutTip": "Please input your password",
-
"userProfile": "User Profile",
"Telephone": "Telephone",
"Email": "Email address",
"Address": "Address",
"Company": "Company",
"Department": "Department",
-
"datetime": {
"thisWeek": "This Week",
"lastWeek": "Last Week",
"thisMonth": "This Month",
"lastMonth": "Last Month",
+ "nextMonth": "Next Month",
"lastThreeMonth": "Last Three Month",
+ "nextThreeMonth": "Next Three Month",
"firstHalfYear": "First Half Year",
"latterHalfYear": "Latter Half Year",
"thisYear": "This Year"
@@ -101,5 +95,13 @@
"LoginFailed": "Incorrect password, Login failed.",
"UsernameIsEmpty": "Please input your username",
"PasswordIsEmpty": "Please input your password"
+ },
+ "invoiceStatus": {
+ "Status": "Status",
+ "Not_submitted": "Not submitted",
+ "Submitted": "Submitted",
+ "Travel_advisor_approved": "Travel advisor approved",
+ "Finance_Dept_arrproved": "Finance Dept arrproved",
+ "Paid": "Paid"
}
-}
+}
\ No newline at end of file
diff --git a/public/locales/zh/common.json b/public/locales/zh/common.json
index 977f98f..e28688f 100644
--- a/public/locales/zh/common.json
+++ b/public/locales/zh/common.json
@@ -25,46 +25,40 @@
"Import": "导入",
"Export": "导出",
"Copy": "复制",
-
"sureCancel": "确定取消?",
- "sureDelete":"确定删除?",
- "sureSubmit":"确定提交?",
+ "sureDelete": "确定删除?",
+ "sureSubmit": "确定提交?",
"Yes": "是",
"No": "否",
-
"Success": "成功",
"Failed": "失败",
-
"All": "所有",
-
"Table": {
"Total": "共 {{total}} 条"
},
-
"Login": "登录",
"Username": "账号",
"Realname": "姓名",
"Password": "密码",
-
"ChangePassword": "修改密码",
"Profile": "账户中心",
"Logout": "退出",
"LoginTimeout": "登录超时",
"LoginTimeoutTip": "请输入密码",
-
"userProfile": "账号信息",
"Telephone": "联系电话",
"Email": "电子邮箱",
"Address": "公司地址",
"Company": "公司名称",
"Department": "部门",
-
"datetime": {
"thisWeek": "本周",
"lastWeek": "上周",
"thisMonth": "本月",
"lastMonth": "上月",
+ "nextMonth": "下月",
"lastThreeMonth": "前三个月",
+ "nextThreeMonth": "后三个月",
"firstHalfYear": "上半年",
"latterHalfYear": "下半年",
"thisYear": "今年"
@@ -101,5 +95,13 @@
"LoginFailed": "密码错误,登陆失败。",
"UsernameIsEmpty": "请输入账号",
"PasswordIsEmpty": "请输入密码"
+ },
+ "invoiceStatus": {
+ "Status": "审核状态",
+ "Not_submitted": "待提交",
+ "Submitted": "待审核",
+ "Travel_advisor_approved": "顾问已审核",
+ "Finance_Dept_arrproved": "财务已审核",
+ "Paid": "已打款"
}
-}
+}
\ No newline at end of file
diff --git a/src/components/SearchForm.jsx b/src/components/SearchForm.jsx
index 54174ff..5fc1fa1 100644
--- a/src/components/SearchForm.jsx
+++ b/src/components/SearchForm.jsx
@@ -1,350 +1,347 @@
-import { useEffect } from 'react';
-import { Form, Input, Row, Col, Select, DatePicker, Space, Button, Checkbox } from 'antd';
-import { objectMapper, at } from '@/utils/commons';
-import { DATE_FORMAT, SMALL_DATETIME_FORMAT } from '@/config';
-import useFormStore from '@/stores/Form';
-import { useDatePresets } from '@/hooks/useDatePresets';
-import { useTranslation } from 'react-i18next';
+import { useEffect } from "react";
+import { Form, Input, Row, Col, Select, DatePicker, Space, Button, Checkbox } from "antd";
+import { objectMapper, at } from "@/utils/commons";
+import { DATE_FORMAT, SMALL_DATETIME_FORMAT } from "@/config";
+import useFormStore from "@/stores/Form";
+import { useDatePresets } from "@/hooks/useDatePresets";
+import { useTranslation } from "react-i18next";
-import SearchInput from './SearchInput';
-import AuditStateSelector from './AuditStateSelector';
-import DeptSelector from './DeptSelector';
-import ProductsTypesSelector from './ProductsTypesSelector';
-import CitySelector from '@/components/CitySelector';
-import VendorSelector from '@/components/VendorSelector';
+import SearchInput from "./SearchInput";
+import AuditStateSelector from "./AuditStateSelector";
+import DeptSelector from "./DeptSelector";
+import ProductsTypesSelector from "./ProductsTypesSelector";
+import CitySelector from "@/components/CitySelector";
+import VendorSelector from "@/components/VendorSelector";
const { RangePicker } = DatePicker;
const SearchForm = ({ initialValue, onSubmit, onReset, onMounted, confirmText, formName, formLayout, loading, ...props }) => {
- const { t } = useTranslation();
- const presets = useDatePresets();
- const [formValues, setFormValues] = useFormStore((state) => [state.formValues, state.setFormValues]);
- const [formValuesToSub, setFormValuesToSub] = useFormStore((state) => [state.formValuesToSub, state.setFormValuesToSub]);
- const [form] = Form.useForm();
- const { sort, hides, shows, fieldProps, fieldComProps } = {
- sort: '',
- // initialValue: '',
- fieldProps: '',
- fieldComProps: '',
- hides: [],
- shows: [],
- ...props.fieldsConfig,
- };
- const readValues = { ...initialValue, ...formValues };
+ const { t } = useTranslation();
+ const presets = useDatePresets();
+ const [formValues, setFormValues] = useFormStore(state => [state.formValues, state.setFormValues]);
+ const [formValuesToSub, setFormValuesToSub] = useFormStore(state => [state.formValuesToSub, state.setFormValuesToSub]);
+ const [form] = Form.useForm();
+ const { sort, hides, shows, fieldProps, fieldComProps } = {
+ sort: "",
+ // initialValue: '',
+ fieldProps: "",
+ fieldComProps: "",
+ hides: [],
+ shows: [],
+ ...props.fieldsConfig,
+ };
+ const readValues = { ...initialValue, ...formValues };
- const formValuesMapper = (values) => {
- const destinationObject = {
- 'keyword': { key: 'keyword', transform: (value) => value || '' },
- 'username': { key: 'username', transform: (value) => value || '' },
- 'referenceNo': { key: 'referenceNo', transform: (value) => value || '' },
- 'dates': [
- { key: 'startdate', transform: (arrVal) => (arrVal ? arrVal[0].format(DATE_FORMAT) : '') },
- { key: 'enddate', transform: (arrVal) => (arrVal ? arrVal[1].format(DATE_FORMAT) : '') },
- { key: 'starttime', transform: (arrVal) => (arrVal ? arrVal[0].format(DATE_FORMAT) : '') },
- { key: 'endtime', transform: (arrVal) => (arrVal ? arrVal[1].format(SMALL_DATETIME_FORMAT) : '') },
- ],
- 'invoiceStatus': { key: 'invoiceStatus', transform: (value) => value?.value || value?.key || '', default: '' },
- 'audit_state': { key: 'audit_state', transform: (value) => value?.value || value?.key || '', default: '' },
- 'agency': {
- key: 'agency',
- transform: (value) => {
- return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.value : '';
- },
- },
- 'year': [
- { key: 'year', transform: (arrVal) => (arrVal ? arrVal.format('YYYY') : '') },
- ],
- 'products_types': {
- key: 'products_types',
- transform: (value) => {
- return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.value : '';
- },
- },
- 'dept': {
- key: 'dept',
- transform: (value) => {
- console.log(value);
- return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.value : '';
- },
- },
- 'city': {
- key: 'city',
- transform: (value) => {
- return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.value : '';
- },
- },
- 'unconfirmed': { key: 'unconfirmed', transform: (value) => value ? 1 : 0 },
- };
- let dest = {};
- const { dates, ...omittedValue } = values;
- dest = { ...omittedValue, ...objectMapper(values, destinationObject) };
- for (const key in dest) {
- if (Object.prototype.hasOwnProperty.call(dest, key)) {
- dest[key] = typeof dest[key] === 'string' ? (dest[key] || '').trim() : dest[key];
- }
- }
- // omit empty
- // Object.keys(dest).forEach((key) => (dest[key] == null || dest[key] === '' || dest[key].length === 0) && delete dest[key]);
- return dest;
- };
+ const formValuesMapper = values => {
+ const destinationObject = {
+ keyword: { key: "keyword", transform: value => value || "" },
+ username: { key: "username", transform: value => value || "" },
+ referenceNo: { key: "referenceNo", transform: value => value || "" },
+ dates: [
+ { key: "startdate", transform: arrVal => (arrVal ? arrVal[0].format(DATE_FORMAT) : "") },
+ { key: "enddate", transform: arrVal => (arrVal ? arrVal[1].format(DATE_FORMAT) : "") },
+ { key: "starttime", transform: arrVal => (arrVal ? arrVal[0].format(DATE_FORMAT) : "") },
+ { key: "endtime", transform: arrVal => (arrVal ? arrVal[1].format(SMALL_DATETIME_FORMAT) : "") },
+ ],
+ invoiceStatus: { key: "invoiceStatus", transform: value => value?.value || value?.key || "", default: "" },
+ audit_state: { key: "audit_state", transform: value => value?.value || value?.key || "", default: "" },
+ agency: {
+ key: "agency",
+ transform: value => {
+ return Array.isArray(value) ? value.map(ele => ele.key).join(",") : value ? value.value : "";
+ },
+ },
+ year: [{ key: "year", transform: arrVal => (arrVal ? arrVal.format("YYYY") : "") }],
+ products_types: {
+ key: "products_types",
+ transform: value => {
+ return Array.isArray(value) ? value.map(ele => ele.key).join(",") : value ? value.value : "";
+ },
+ },
+ dept: {
+ key: "dept",
+ transform: value => {
+ console.log(value);
+ return Array.isArray(value) ? value.map(ele => ele.key).join(",") : value ? value.value : "";
+ },
+ },
+ city: {
+ key: "city",
+ transform: value => {
+ return Array.isArray(value) ? value.map(ele => ele.key).join(",") : value ? value.value : "";
+ },
+ },
+ unconfirmed: { key: "unconfirmed", transform: value => (value ? 1 : 0) },
+ };
+ let dest = {};
+ const { dates, ...omittedValue } = values;
+ dest = { ...omittedValue, ...objectMapper(values, destinationObject) };
+ for (const key in dest) {
+ if (Object.prototype.hasOwnProperty.call(dest, key)) {
+ dest[key] = typeof dest[key] === "string" ? (dest[key] || "").trim() : dest[key];
+ }
+ }
+ // omit empty
+ // Object.keys(dest).forEach((key) => (dest[key] == null || dest[key] === '' || dest[key].length === 0) && delete dest[key]);
+ return dest;
+ };
- useEffect(() => {
- setFormValues(readValues);
- const dest = formValuesMapper(readValues);
- setFormValuesToSub(dest);
+ useEffect(() => {
+ setFormValues(readValues);
+ const dest = formValuesMapper(readValues);
+ setFormValuesToSub(dest);
- if (typeof onMounted === 'function') {
- onMounted(dest)
- }
+ if (typeof onMounted === "function") {
+ onMounted(dest);
+ }
- return () => {};
- }, []);
+ return () => {};
+ }, []);
- const onFinish = (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);
- const str = new URLSearchParams(dest).toString();
- setFormValues(values);
- setFormValuesToSub(dest);
- if (typeof onSubmit === 'function') {
- onSubmit(null, dest, values, str);
- }
- };
+ const onFinish = 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);
+ const str = new URLSearchParams(dest).toString();
+ setFormValues(values);
+ setFormValuesToSub(dest);
+ if (typeof onSubmit === "function") {
+ onSubmit(null, dest, values, str);
+ }
+ };
- const handleReset = () => {
- form.setFieldsValue({
- // 'DateType': undefined,
- });
- if (typeof onReset === 'function') {
- onReset();
- }
- };
- const onValuesChange = (changedValues, allValues) => {
+ const handleReset = () => {
+ form.setFieldsValue({
+ // 'DateType': undefined,
+ });
+ if (typeof onReset === "function") {
+ onReset();
+ }
+ };
+ const onValuesChange = (changedValues, allValues) => {
+ const dest = formValuesMapper(allValues);
+ setFormValues(allValues);
+ setFormValuesToSub(dest);
+ // console.log('form onValuesChange', Object.keys(changedValues), args);
+ };
- const dest = formValuesMapper(allValues);
- setFormValues(allValues);
- setFormValuesToSub(dest);
- // console.log('form onValuesChange', Object.keys(changedValues), args);
- };
+ const onFinishFailed = ({ values, errorFields }) => {
+ console.log("form validate failed", "\nform values:", values, "\nerrorFields", errorFields);
+ };
- const onFinishFailed = ({ values, errorFields }) => {
- console.log('form validate failed', '\nform values:', values, '\nerrorFields', errorFields);
- };
-
- return (
- <>
-
+ >
+ );
};
function getFields(props) {
- const { fieldProps, fieldComProps, form, presets, t } = props;
- const bigCol = 4 * 2;
- const midCol = 6;
- const layoutProps = {
- // gutter: { xs: 8, sm: 8, lg: 16 },
- lg: { span: 4 },
- md: { span: 8 },
- sm: { span: 12 },
- xs: { span: 24 },
- };
- const item = (name, sort = 0, render, col) => {
- const customCol = col || 4;
- const mdCol = customCol * 2;
- return {
- 'key': '',
- sort,
- name,
- render,
- 'hide': false,
- 'col': { lg: { span: customCol }, md: { span: mdCol < 8 ? 10 : mdCol }, flex: mdCol < 8 ? '1 0' : '' },
- };
- };
- let baseChildren = [];
- baseChildren = [
- item(
- 'keyword',
- 99,
-
-
- ,
- fieldProps?.keyword?.col || 6
- ),
- item(
- 'referenceNo',
- 99,
-
-
- ,
- fieldProps?.referenceNo?.col || 6
- ),
- item(
- 'PNR',
- 99,
-
-
- ,
- fieldProps?.PNR?.col || 4
- ),
- item(
- 'invoiceStatus',
- 99,
-
-
- ,
- fieldProps?.invoiceStatus?.col || 3
- ),
- item(
- 'dates',
- 99,
-
- {/* */}
-
- ,
- fieldProps?.dates?.col || midCol
- ),
- item(
- 'username',
- 99,
-
-
- ,
- fieldProps?.username?.col || 4
- ),
- /**
- *
- */
- item(
- 'year',
- 99,
-
-
- ,
- fieldProps?.year?.col || 3
- ),
- item(
- 'agency',
- 99,
-
-
- ,
- fieldProps?.agency?.col || 6
- ),
- item(
- 'audit_state',
- 99,
-
-
- ,
- fieldProps?.audit_state?.col || 3
- ),
- item(
- 'products_types',
- 99,
-
-
- ,
- fieldProps?.products_types?.col || 6
- ),
- item(
- 'dept',
- 99,
-
-
- ,
- fieldProps?.dept?.col || 6
- ),
- item(
- 'city',
- 99,
-
-
- ,
- fieldProps?.city?.col || 4
- ),
- item(
- 'unconfirmed',
- 99,
-
- {t('group:unconfirmed')}
- ,
- fieldProps?.unconfirmed?.col || 2
- ),
- ];
- baseChildren = baseChildren
- .map((x) => {
- x.hide = false;
- if (props.sort === undefined) {
- return x;
- }
- const tmpSort = props.sort;
- for (const key in tmpSort) {
- if (Object.prototype.hasOwnProperty.call(tmpSort, key)) {
- if (x.name === key) {
- x.sort = tmpSort[key];
- }
- }
- }
- return x;
- })
- .map((x) => {
- if (props.hides.length === 0 && props.shows.length === 0) {
- return x;
- }
- if (props.hides.length === 0) {
- x.hide = !props.shows.includes(x.name);
- } else if (props.shows.length === 0) {
- x.hide = props.hides.includes(x.name);
- }
- return x;
- })
- .filter((x) => !x.hide)
- .sort((a, b) => {
- return a.sort < b.sort ? -1 : 1;
- });
- const children = [];
- const leftStyle = {}; // { borderRight: '1px solid #dedede' };
- for (let i = 0; i < baseChildren.length; i++) {
- let style = {}; // { padding: '0px 2px' };
- style = i % 2 === 0 && baseChildren[i].col === 12 ? { ...style, ...leftStyle } : style;
- style = !baseChildren[i].hide ? { ...style, display: 'block' } : { ...style, display: 'none' };
- const Item = (
-
- {baseChildren[i].render}
-
- );
- children.push(Item);
- }
- return children;
+ const { fieldProps, fieldComProps, form, presets, t } = props;
+ const bigCol = 4 * 2;
+ const midCol = 6;
+ const layoutProps = {
+ // gutter: { xs: 8, sm: 8, lg: 16 },
+ lg: { span: 4 },
+ md: { span: 8 },
+ sm: { span: 12 },
+ xs: { span: 24 },
+ };
+ const item = (name, sort = 0, render, col) => {
+ const customCol = col || 4;
+ const mdCol = customCol * 2;
+ return {
+ key: "",
+ sort,
+ name,
+ render,
+ hide: false,
+ col: { lg: { span: customCol }, md: { span: mdCol < 8 ? 10 : mdCol }, flex: mdCol < 8 ? "1 0" : "" },
+ };
+ };
+ let baseChildren = [];
+ baseChildren = [
+ item(
+ "keyword",
+ 99,
+
+
+ ,
+ fieldProps?.keyword?.col || 6
+ ),
+ item(
+ "referenceNo",
+ 99,
+
+
+ ,
+ fieldProps?.referenceNo?.col || 6
+ ),
+ item(
+ "PNR",
+ 99,
+
+
+ ,
+ fieldProps?.PNR?.col || 4
+ ),
+ item(
+ "invoiceStatus",
+ 99,
+
+
+ ,
+ fieldProps?.invoiceStatus?.col || 3
+ ),
+ item(
+ "dates",
+ 99,
+
+ {/* */}
+
+ ,
+ fieldProps?.dates?.col || midCol
+ ),
+ item(
+ "username",
+ 99,
+
+
+ ,
+ fieldProps?.username?.col || 4
+ ),
+ /**
+ *
+ */
+ item(
+ "year",
+ 99,
+
+
+ ,
+ fieldProps?.year?.col || 3
+ ),
+ item(
+ "agency",
+ 99,
+
+
+ ,
+ fieldProps?.agency?.col || 6
+ ),
+ item(
+ "audit_state",
+ 99,
+
+
+ ,
+ fieldProps?.audit_state?.col || 3
+ ),
+ item(
+ "products_types",
+ 99,
+
+
+ ,
+ fieldProps?.products_types?.col || 6
+ ),
+ item(
+ "dept",
+ 99,
+
+
+ ,
+ fieldProps?.dept?.col || 6
+ ),
+ item(
+ "city",
+ 99,
+
+
+ ,
+ fieldProps?.city?.col || 4
+ ),
+ item(
+ "unconfirmed",
+ 99,
+
+ {t("group:unconfirmed")}
+ ,
+ fieldProps?.unconfirmed?.col || 2
+ ),
+ ];
+ baseChildren = baseChildren
+ .map(x => {
+ x.hide = false;
+ if (props.sort === undefined) {
+ return x;
+ }
+ const tmpSort = props.sort;
+ for (const key in tmpSort) {
+ if (Object.prototype.hasOwnProperty.call(tmpSort, key)) {
+ if (x.name === key) {
+ x.sort = tmpSort[key];
+ }
+ }
+ }
+ return x;
+ })
+ .map(x => {
+ if (props.hides.length === 0 && props.shows.length === 0) {
+ return x;
+ }
+ if (props.hides.length === 0) {
+ x.hide = !props.shows.includes(x.name);
+ } else if (props.shows.length === 0) {
+ x.hide = props.hides.includes(x.name);
+ }
+ return x;
+ })
+ .filter(x => !x.hide)
+ .sort((a, b) => {
+ return a.sort < b.sort ? -1 : 1;
+ });
+ const children = [];
+ const leftStyle = {}; // { borderRight: '1px solid #dedede' };
+ for (let i = 0; i < baseChildren.length; i++) {
+ let style = {}; // { padding: '0px 2px' };
+ style = i % 2 === 0 && baseChildren[i].col === 12 ? { ...style, ...leftStyle } : style;
+ style = !baseChildren[i].hide ? { ...style, display: "block" } : { ...style, display: "none" };
+ const Item = (
+
+ {baseChildren[i].render}
+
+ );
+ children.push(Item);
+ }
+ return children;
}
export default SearchForm;
diff --git a/src/config.js b/src/config.js
index 256e171..786bbfe 100644
--- a/src/config.js
+++ b/src/config.js
@@ -1,7 +1,7 @@
export const PROJECT_NAME = "GHHub";
// mode: test,内部测试使用
-export const HT_HOST = import.meta.env.MODE === 'test' ? 'http://202.103.68.144:890' : import.meta.env.PROD ? "https://p9axztuwd7x8a7.mycht.cn" : 'http://202.103.68.144:890'
+export const HT_HOST = import.meta.env.MODE === 'test' ? 'http://120.79.9.217:10024' : import.meta.env.PROD ? 'https://p9axztuwd7x8a7.mycht.cn' : 'http://202.103.68.144:890'
export const DATE_FORMAT = "YYYY-MM-DD";
diff --git a/src/hooks/useDatePresets.js b/src/hooks/useDatePresets.js
index 05e251c..aa1d553 100644
--- a/src/hooks/useDatePresets.js
+++ b/src/hooks/useDatePresets.js
@@ -25,10 +25,18 @@ export const useDatePresets = () => {
label: t("datetime.lastMonth"),
value: [dayjs().subtract(1, "M").startOf("M"), dayjs().subtract(1, "M").endOf("M")],
},
+ {
+ label: t("datetime.nextMonth"),
+ value: [dayjs().add(1, "M").startOf("M"), dayjs().add(1, "M").endOf("M")],
+ },
{
label: t("datetime.lastThreeMonth"),
value: [dayjs().subtract(2, "M").startOf("M"), dayjs().endOf("M")],
},
+ {
+ label: t("datetime.nextThreeMonth"),
+ value: [dayjs().startOf("M"), dayjs().add(3,"M").endOf("M")],
+ },
{
label: t("datetime.firstHalfYear"),
value: [dayjs().startOf("y"), dayjs().endOf("y").subtract(6, "M")],
diff --git a/src/main.jsx b/src/main.jsx
index b675476..25a7270 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -29,6 +29,7 @@ import InvoicePaid from '@/views/invoice/Paid'
import InvoicePaidDetail from '@/views/invoice/PaidDetail'
import Airticket from '@/views/airticket/Index'
import AirticketPlan from '@/views/airticket/Plan'
+import AirticketInvoice from '@/views/airticket/Invoice'
import { ThemeContext } from '@/stores/ThemeContext'
import { usingStorage } from '@/hooks/usingStorage'
import useAuthStore from './stores/Auth'
@@ -69,6 +70,7 @@ const initRouter = async () => {
{ path: 'invoice/paid/detail/:flid', element: },
{ path: 'airticket',element: },
{ path: 'airticket/plan/:coli_sn/:gri_sn',element:},
+ { path: 'airticket/invoice',element:},
{ path: "products",element: },
{ path: "products/:travel_agency_id/:use_year/:audit_state/audit",element:},
diff --git a/src/stores/Airticket.js b/src/stores/Airticket.js
index cd8ada5..23c8a5f 100644
--- a/src/stores/Airticket.js
+++ b/src/stores/Airticket.js
@@ -10,6 +10,7 @@ const airTicketStore = create((set, get) => ({
setPlanList: planList => set({ planList }),
setPlanDetail: planDetail => set({ planDetail }),
setGuestList: guestList => set({ guestList }),
+ setVEIFlightBill: vEIFlightBill => set({ vEIFlightBill }),
async getPlanList(vei_sn, GRI_Name, TimeStart, TimeEnd) {
const { setLoading, setPlanList } = get();
@@ -68,15 +69,21 @@ const airTicketStore = create((set, get) => ({
const _result = errcode !== 0 ? [] : result;
setGuestList(_result);
},
- // async getFlightCostList(CLF_SN) {
- // const searchParams = {
- // CLF_SN: CLF_SN,
- // };
- // const { errcode, result } = await fetchJSON(`${HT_HOST}/Service_BaseInfoWeb/Get_flight_cost`, searchParams);
- // const _result = errcode !== 0 ? [] : result;
- // console.log(_result);
- // return _result;
- // },
+ //获取账单列表
+ async getVEIFlightBill(VEI_SN, GRI_Name, CheckStatus, FlightDate1, FlightDate2) {
+ const { setVEIFlightBill } = get();
+ const searchParams = {
+ VEI_SN: VEI_SN,
+ GRI_Name: GRI_Name,
+ CheckStatus: CheckStatus,
+ FlightDate1: FlightDate1,
+ FlightDate2: FlightDate2,
+ };
+ 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)) {
@@ -91,6 +98,15 @@ const airTicketStore = create((set, get) => ({
}
});
},
+
+ async deleteFlightCost(CLC_SN) {
+ const searchParams = {
+ CLC_SN: CLC_SN,
+ };
+ const { errcode, result } = await fetchJSON(`${HT_HOST}/Service_BaseInfoWeb/Delete_flight_cost`, searchParams);
+ const _result = errcode !== 0 ? [] : result;
+ return _result;
+ },
}));
export default airTicketStore;
diff --git a/src/views/airticket/Index.jsx b/src/views/airticket/Index.jsx
index 09b0d87..52c4f05 100644
--- a/src/views/airticket/Index.jsx
+++ b/src/views/airticket/Index.jsx
@@ -1,6 +1,6 @@
import { useState, useEffect } from "react";
-import { Grid, Divider, Layout, Spin, Input, Col, Row, Space, List, Table } from "antd";
-import { PhoneOutlined, CustomerServiceOutlined, AudioOutlined } from "@ant-design/icons";
+import { Grid, Divider, Layout, Spin, Input, Col, Row, Space, List, Table, Button } from "antd";
+import { PhoneOutlined, CustomerServiceOutlined, AudioOutlined,AuditOutlined } from "@ant-design/icons";
import { useParams, useHref, useNavigate, NavLink } from "react-router-dom";
import { isEmpty, formatColonTime } from "@/utils/commons";
import dayjs from "dayjs";
@@ -14,6 +14,7 @@ const planListColumns = [
title: "团名",
key: "GRI_No",
dataIndex: "GRI_No",
+ // sorter: (a, b) => b.GRI_No - a.GRI_No,
},
{
title: "组团人",
@@ -77,35 +78,40 @@ const planListColumns = [
];
const Airticket = props => {
- const href = useHref();
const navigate = useNavigate();
- const { phonenumber } = useParams();
const { travelAgencyId } = usingStorage();
const [getPlanList, planList, loading] = airTicketStore(state => [state.getPlanList, state.planList, state.loading]);
- const [phone_number, setPhone_number] = useState(phonenumber);
const showTotal = total => `合计 ${total} `;
useEffect(() => {}, []);
- const oncall = () => {};
-
return (
- {
- getPlanList(travelAgencyId, formVal.referenceNo, formVal.startdate, formVal.endtime);
- }}
- />
+
+
+ {
+ getPlanList(travelAgencyId, formVal.referenceNo, formVal.startdate, formVal.endtime);
+ }}
+ />
+
+
+ } onClick={() => navigate(`/airticket/invoice`)}>
+ 报账
+
+
+
+
diff --git a/src/views/airticket/Invoice.jsx b/src/views/airticket/Invoice.jsx
new file mode 100644
index 0000000..2d0bb2b
--- /dev/null
+++ b/src/views/airticket/Invoice.jsx
@@ -0,0 +1,151 @@
+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 { useParams, useHref, useNavigate, NavLink } from "react-router-dom";
+import { isEmpty, formatColonTime } from "@/utils/commons";
+import dayjs from "dayjs";
+import SearchForm from "@/components/SearchForm";
+import BackBtn from "@/components/BackBtn";
+
+import airTicketStore from "@/stores/Airticket";
+import { usingStorage } from "@/hooks/usingStorage";
+
+const Invoice = props => {
+ const navigate = useNavigate();
+ const { travelAgencyId } = usingStorage();
+ const [getVEIFlightBill, vEIFlightBill, loading] = airTicketStore(state => [state.getVEIFlightBill, state.vEIFlightBill, state.loading]);
+ const showTotal = total => `合计 ${total} `;
+
+ //统计总的费用
+ const totalFee = vEIFlightBill.reduce((acc, curr) => acc + curr.ServiceFee, 0);
+ const vEIFlightBillColumns = [
+ {
+ title: "团名",
+ key: "GRI_No",
+ dataIndex: "GRI_No",
+ render: (text, record) => `${record.GRI_No} ${record.WL}`,
+ },
+ {
+ title: "费用类型",
+ key: "CostType",
+ dataIndex: "CostType",
+ },
+ {
+ title: "手续费/费用",
+ children: [
+ {
+ title: totalFee,
+ dataIndex: "ServiceFee",
+ },
+ ],
+ },
+ {
+ title: "出发日期",
+ key: "StartDate",
+ dataIndex: "StartDate",
+ sorter: (a, b) => {
+ const dateA = new Date(a.StartDate);
+ const dateB = new Date(b.StartDate);
+ return dateB.getTime() - dateA.getTime();
+ },
+ },
+ {
+ title: "城市",
+ key: "FromCity",
+ dataIndex: "FromCity",
+ render: (text, record) => (record.CostType == "出票" ? `${record.FromCity} - ${record.ToCity}` : "-"),
+ },
+ {
+ title: "航班",
+ key: "FlightNo",
+ dataIndex: "FlightNo",
+ render: (text, record) => (record.CostType == "出票" ? text : "-"),
+ },
+
+ {
+ title: "PNR",
+ key: "PNR",
+ dataIndex: "PNR",
+ render: (text, record) => (record.CostType == "出票" ? text : "-"),
+ },
+ {
+ title: "票号",
+ key: "TicketNo",
+ dataIndex: "TicketNo",
+ render: (text, record) => (record.CostType == "出票" ? text : "-"),
+ },
+ {
+ title: "机票类型",
+ key: "FlightType",
+ dataIndex: "FlightType",
+ render: (text, record) => (record.CostType == "出票" ? text : "-"),
+ },
+ {
+ title: "机票价格",
+ key: "Cost",
+ dataIndex: "Cost",
+ render: (text, record) => (record.CostType == "出票" ? text : "-"),
+ },
+ {
+ title: "折扣",
+ key: "Discount",
+ dataIndex: "Discount",
+ render: (text, record) => (record.CostType == "出票" ? text : "-"),
+ },
+ {
+ title: "备注",
+ key: "Memo",
+ dataIndex: "Memo",
+ },
+ {
+ title: "审核状态",
+ children: [
+ {
+ title: ,
+ dataIndex: "CheckStatus", //状态小于2,表示还未提交审核
+ render: (text, record) => (record.CheckStatus < 2 ? 待提交 : record.CheckStatusName),
+ },
+ ],
+ sorter: (a, b) => {
+ return b.CheckStatus - a.CheckStatus;
+ },
+ },
+ ];
+
+ useEffect(() => {}, []);
+
+ return (
+
+
+
+ {
+ getVEIFlightBill(travelAgencyId, formVal.referenceNo, formVal.invoiceStatus, formVal.startdate, formVal.endtime);
+ }}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+export default Invoice;
diff --git a/src/views/airticket/Plan.jsx b/src/views/airticket/Plan.jsx
index 71a07c6..3641d4a 100644
--- a/src/views/airticket/Plan.jsx
+++ b/src/views/airticket/Plan.jsx
@@ -1,5 +1,5 @@
import { useState, useEffect } from "react";
-import { Grid, Divider, Layout, Modal, Form, Input, Col, Row, Space, Collapse, Table, Button, Select, App, Typography } from "antd";
+import { Grid, Divider, Layout, Modal, Form, Input, Col, Row, Space, Collapse, Table, Button, Select, App, Popconfirm } from "antd";
import { PhoneOutlined, FrownTwoTone, LikeTwoTone, ArrowUpOutlined, ArrowDownOutlined } from "@ant-design/icons";
import { useParams, useHref, useNavigate, NavLink } from "react-router-dom";
import { isEmpty, formatColonTime } from "@/utils/commons";
@@ -7,106 +7,41 @@ import { OFFICEWEBVIEWERURL } from "@/config";
import airTicketStore from "@/stores/Airticket";
import { usingStorage } from "@/hooks/usingStorage";
+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, getFlightCostList, postFlightCost] = airTicketStore(state => [
+ const [getPlanDetail, planDetail, getGuestList, guestList, loading, postFlightDetail, postFlightCost, deleteFlightCost] = airTicketStore(state => [
state.getPlanDetail,
state.planDetail,
state.getGuestList,
state.guestList,
state.loading,
state.postFlightDetail,
- state.getFlightCostList,
state.postFlightCost,
+ state.deleteFlightCost,
]);
- const reservationUrl = `https://p9axztuwd7x8a7.mycht.cn/Service_BaseInfoWeb/FlightPlanDocx?GRI_SN=${gri_sn}&VEI_SN=${travelAgencyId}`;
+ const reservationUrl = `https://p9axztuwd7x8a7.mycht.cn/Service_BaseInfoWeb/FlightPlanDocx?GRI_SN=${gri_sn}&VEI_SN=${travelAgencyId}&token=${loginToken}`;
const reservationPreviewUrl = OFFICEWEBVIEWERURL + encodeURIComponent(reservationUrl);
const [form] = Form.useForm();
const { notification } = App.useApp();
//console.log(reservationPreviewUrl);
//乘客列表
- const guestListColumns = [
- {
- title: "姓名",
- key: "MEI_Name",
- dataIndex: "MEI_Name",
- },
- {
- title: "证件类型",
- key: "MEI_PassportType",
- dataIndex: "MEI_PassportType",
- },
- {
- title: "证件号",
- key: "MEI_PassportNo",
- dataIndex: "MEI_PassportNo",
- },
- {
- title: "证件有效期",
- key: "MEI_PassportValidDate",
- dataIndex: "MEI_PassportValidDate",
- },
- {
- title: "性别",
- key: "MEI_Gender",
- dataIndex: "MEI_Gender",
- },
- {
- title: "年龄",
- key: "MEI_age",
- dataIndex: "MEI_age",
- },
- {
- title: "国籍",
- key: "MEI_Country",
- dataIndex: "MEI_Country",
- },
- {
- title: "票号",
- key: "MEI_SN",
- dataIndex: "MEI_SN",
- },
- {
- title: "PNR",
- key: "MEI_SN",
- dataIndex: "MEI_SN",
- },
- {
- title: "机票费用(RMB)含基建和税",
- key: "MEI_SN",
- dataIndex: "MEI_SN",
- },
- {
- title: "折扣",
- key: "MEI_SN",
- dataIndex: "MEI_SN",
- },
- {
- title: "手续费",
- key: "MEI_SN",
- dataIndex: "MEI_SN",
- },
- {
- title: "机票类型(成人/儿童/婴儿)",
- key: "MEI_SN",
- dataIndex: "MEI_SN",
- },
- {
- title: "操作",
- key: "MEI_SN",
- dataIndex: "MEI_SN",
- render: (_, record) => {
- return (
-
- showModal(record)}>编辑 | console.log("del")}>删除
-
- );
- },
- },
- ];
+ const guestList_select = () => {
+ return (
+ guestList &&
+ guestList.map(item => {
+ return { label: `${item.MEI_Name} , ${item.MEI_PassportNo}`, value: `${item.MEI_Name} , ${item.MEI_PassportNo} , ${item.MEI_Country} , ${item.MEI_Gender} , ${item.MEI_age} , ${item.MEI_Birthday}` };
+ })
+ );
+ };
+
+ const guestList_OnChange = value => {
+ console.log(value);
+ ticket_form.setFieldsValue({ Memo: `${value}` });
+ };
//费用列表
const costListColumns = [
@@ -117,8 +52,8 @@ const AirticketPlan = props => {
},
{
title: "手续费/费用",
- key: "Cost",
- dataIndex: "Cost",
+ key: "ServiceFee",
+ dataIndex: "ServiceFee",
},
{
title: "PNR",
@@ -128,8 +63,8 @@ const AirticketPlan = props => {
},
{
title: "票号",
- key: "FlightCost",
- dataIndex: "FlightCost",
+ key: "TicketNo",
+ dataIndex: "TicketNo",
render: (text, record) => (record.CostType == "出票" ? text : "-"),
},
{
@@ -140,8 +75,8 @@ const AirticketPlan = props => {
},
{
title: "机票价格",
- key: "FlightCost",
- dataIndex: "FlightCost",
+ key: "Cost",
+ dataIndex: "Cost",
render: (text, record) => (record.CostType == "出票" ? text : "-"),
},
{
@@ -157,9 +92,20 @@ const AirticketPlan = props => {
},
{
title: "编辑",
- key: "CLF_SN",
- dataIndex: "CLF_SN",
- render: (text, record) => showModal(record)}>编辑,
+ key: "CLC_SN",
+ dataIndex: "CLC_SN",
+ render: (text, record) => (
+ <>
+
+ showModal(record)}>编辑
+ handleDelete(record.CLC_SN)} okText="是" cancelText="否">
+
+
+
+ >
+ ),
},
];
@@ -228,7 +174,7 @@ const AirticketPlan = props => {
-
+
@@ -241,7 +187,7 @@ const AirticketPlan = props => {
-
+
@@ -300,7 +246,7 @@ const AirticketPlan = props => {
? planDetail.map(item => {
return {
key: item.id,
- label: `${item.StartDate}`,
+ label: `${item.StartDate} ${item.FlightNo}(${item.FromAirport}${item.FlightStart}-${item.ToAirport}${item.FlightEnd})(${item.FlightCabin})`,
children: ,
};
})
@@ -314,7 +260,8 @@ const AirticketPlan = props => {
const showModal = ticket => {
setIsModalOpen(true);
- ticket.CostType == "出票" ? setisTicketType(true) : setisTicketType(false);//如果是出票类型,显示票号、折扣等选项
+ if (isEmpty(ticket.CostType)) ticket.CostType = "出票";
+ ticket.CostType == "出票" ? setisTicketType(true) : setisTicketType(false); //如果是出票类型,显示票号、折扣等选项
ticket_form.setFieldsValue(ticket);
};
@@ -357,6 +304,29 @@ const AirticketPlan = props => {
setIsModalOpen(false);
};
+ const handleDelete = CLC_SN => {
+ deleteFlightCost(CLC_SN)
+ .then(() => {
+ notification.success({
+ message: `成功`,
+ description: "删除成功!",
+ placement: "top",
+ duration: 4,
+ icon: ,
+ });
+ getPlanDetail(travelAgencyId, gri_sn);
+ })
+ .catch(() => {
+ notification.error({
+ message: `错误`,
+ description: "删除失败",
+ placement: "top",
+ duration: 4,
+ icon: ,
+ });
+ });
+ };
+
const onChangeType = value => {
if (value == "出票") {
setisTicketType(true);
@@ -413,7 +383,7 @@ const AirticketPlan = props => {
-
+
@@ -437,8 +407,7 @@ const AirticketPlan = props => {
]}
/>
-
-
+
{
}}
/>
-
-
>
)}
@@ -508,14 +453,20 @@ const AirticketPlan = props => {
useEffect(() => {
getPlanDetail(travelAgencyId, gri_sn);
- getGuestList(travelAgencyId, coli_sn);
+ getGuestList(coli_sn);
}, []);
return (
+
+
+
+
+
+
-
+ {/* */}