From 5b30aec3e548fab5eafa1ff94cd6f0175f59de54 Mon Sep 17 00:00:00 2001 From: Lei OT Date: Wed, 5 Jun 2024 11:32:53 +0800 Subject: [PATCH 01/12] refactor: Report --- src/stores/Feedback.js | 1 - src/stores/Report.js | 174 +++----- src/stores/Root.js | 2 - src/views/report/Index.jsx | 871 ++++++++++++++++--------------------- 4 files changed, 449 insertions(+), 599 deletions(-) diff --git a/src/stores/Feedback.js b/src/stores/Feedback.js index a9f40fe..dd3feb1 100644 --- a/src/stores/Feedback.js +++ b/src/stores/Feedback.js @@ -85,7 +85,6 @@ const useFeedbackStore = create( ...initialState, reset: () => set(initialState), - setState: (state) => set(state), setLoading: (loading) => set({ loading }), setFeedbackList: (feedbackList) => set({ feedbackList }), diff --git a/src/stores/Report.js b/src/stores/Report.js index 45e075c..0767790 100644 --- a/src/stores/Report.js +++ b/src/stores/Report.js @@ -1,113 +1,69 @@ -import { makeAutoObservable, runInAction } from "mobx"; -import { fetchJSON, postForm } from "@/utils/request"; -import { prepareUrl, isNotEmpty } from "@/utils/commons"; +import { fetchJSON } from "@/utils/request"; import { HT_HOST } from "@/config"; -import { json } from "react-router-dom"; -import * as config from "@/config"; -import dayjs from "dayjs"; +import { create } from 'zustand'; +import { devtools } from 'zustand/middleware'; -class Report { - constructor(root) { - makeAutoObservable(this, { rootStore: false }); - this.root = root; - } +const initialState = { + loading: false, + vendorScoresData: [], //地接统计数据集,合计数据,每月数据,地接考核分数 + productScoresData: [], //产品体验分析 常用酒店分析, 导游接待情况 + commendScoresData: [], //表扬情况, 投诉情况, 评建议 +}; +export const useReportStore = create( + devtools((set, get) => ({ + ...initialState, + reset: () => set(initialState), - vendorScoresData = []; //地接统计数据集,合计数据,每月数据,地接考核分数 - productScoresData = []; //产品体验分析 常用酒店分析, 导游接待情况 - commendScoresData = []; //表扬情况, 投诉情况, 评建议 + setLoading: (loading) => set({ loading }), + setVendorScoresData: (vendorScoresData) => set({ vendorScoresData }), + setProductScoresData: (productScoresData) => set({ productScoresData }), + setCommendScoresData: (commendScoresData) => set({ commendScoresData }), - loading = false; - search_date_start = dayjs().month(0).startOf("month"); - search_date_end = dayjs().month(11).endOf("month"); - - onDateRangeChange = dates => { - this.search_date_start = dates == null ? null : dates[0].startOf("month"); - this.search_date_end = dates == null ? null : dates[1].endOf("month"); - }; - - getHWVendorScores(VEI_SN, StartDate, EndDate) { - this.loading = true; - const fetchUrl = prepareUrl(HT_HOST +"/service-cusservice/PTGetHWVendorScores") - .append("VEI_SN", VEI_SN) - .append("StartDate", StartDate) - .append("EndDate", EndDate) - .append("StrDEI_SN", "(,-1,)") - .append("OrderType", "-1") - .append("GroupType", "-1") - .append("token", this.root.authStore.login.token) - .build(); - - return fetchJSON(fetchUrl).then(json => { - runInAction(() => { - this.loading = false; - if (json.errcode == 0) { - if (isNotEmpty(json)) { - this.vendorScoresData = json; - } else { - this.vendorScoresData = []; - } - } else { - throw new Error(json.errmsg + ": " + json.errcode); - } - }); - }); - } - - getHWProductScores(VEI_SN, StartDate, EndDate) { - this.loading = true; - const fetchUrl = prepareUrl(HT_HOST +"/service-cusservice/PTGetHWProductScores") - .append("VEI_SN", VEI_SN) - .append("StartDate", StartDate) - .append("EndDate", EndDate) - .append("StrDEI_SN", "(,-1,)") - .append("OrderType", "-1") - .append("GroupType", "-1") - .append("token", this.root.authStore.login.token) - .build(); - - return fetchJSON(fetchUrl).then(json => { - runInAction(() => { - this.loading = false; - if (json.errcode == 0) { - if (isNotEmpty(json)) { - this.productScoresData = json; - } else { - this.productScoresData = []; - } - } else { - throw new Error(json.errmsg + ": " + json.errcode); - } - }); - }); - } - - getHWCommendScores(VEI_SN, StartDate, EndDate) { - this.loading = true; - const fetchUrl = prepareUrl(HT_HOST +"/service-cusservice/PTGetHWCommendScores") - .append("VEI_SN", VEI_SN) - .append("StartDate", StartDate) - .append("EndDate", EndDate) - .append("StrDEI_SN", "(,-1,)") - .append("OrderType", "-1") - .append("GroupType", "-1") - .append("token", this.root.authStore.login.token) - .build(); - - return fetchJSON(fetchUrl).then(json => { - runInAction(() => { - this.loading = false; - if (json.errcode == 0) { - if (isNotEmpty(json)) { - this.commendScoresData = json; - } else { - this.commendScoresData = []; - } - } else { - throw new Error(json.errmsg + ": " + json.errcode); - } - }); - }); - } -} - -export default Report; + async getHWVendorScores(VEI_SN, StartDate, EndDate) { + const { setLoading, setVendorScoresData } = get(); + setLoading(true); + const searchParams = { + VEI_SN, + StartDate, + EndDate, + StrDEI_SN: '(,-1,)', + OrderType: '-1', + GroupType: '-1', + }; + const { errcode, ...Result } = await fetchJSON(`${HT_HOST}/service-cusservice/PTGetHWVendorScores`, searchParams); + setVendorScoresData(errcode === 0 ? Result : {}); + setLoading(false); + }, + async getHWProductScores(VEI_SN, StartDate, EndDate) { + const { setLoading, setProductScoresData } = get(); + setLoading(true); + const searchParams = { + VEI_SN, + StartDate, + EndDate, + StrDEI_SN: '(,-1,)', + OrderType: '-1', + GroupType: '-1', + }; + const { errcode, ...Result } = await fetchJSON(`${HT_HOST}/service-cusservice/PTGetHWProductScores`, searchParams); + setProductScoresData(errcode === 0 ? Result : {}); + setLoading(false); + }, + async getHWCommendScores(VEI_SN, StartDate, EndDate) { + const { setLoading, setCommendScoresData } = get(); + setLoading(true); + const searchParams = { + VEI_SN, + StartDate, + EndDate, + StrDEI_SN: '(,-1,)', + OrderType: '-1', + GroupType: '-1', + }; + const { errcode, ...Result } = await fetchJSON(`${HT_HOST}/service-cusservice/PTGetHWCommendScores`, searchParams); + setCommendScoresData(errcode === 0 ? Result : {}); + setLoading(false); + }, + })) +); +export default useReportStore; diff --git a/src/stores/Root.js b/src/stores/Root.js index 2f75dd9..57645f4 100644 --- a/src/stores/Root.js +++ b/src/stores/Root.js @@ -2,14 +2,12 @@ import { makeAutoObservable } from "mobx"; import { Reservation } from "./Reservation"; import { Auth } from "./Auth"; import {Invoice} from "./Invoice"; -import Report from "./Report"; class Root { constructor() { this.reservationStore = new Reservation(this); this.authStore = new Auth(this); this.invoiceStore = new Invoice(this); - this.reportStore = new Report(this); makeAutoObservable(this); } diff --git a/src/views/report/Index.jsx b/src/views/report/Index.jsx index 6e9038f..9e8724e 100644 --- a/src/views/report/Index.jsx +++ b/src/views/report/Index.jsx @@ -1,505 +1,402 @@ -import { useEffect } from "react"; -import { observer } from "mobx-react"; -import { Row, Col, Space, Button, Table, Divider, Typography, DatePicker } from "antd"; -import { useStore } from "@/stores/StoreContext.js"; -import * as config from "@/config"; -import * as comm from "@/utils/commons"; -import { usePDF } from "react-to-pdf"; +import { Row, Col, Space, Button, Table, Divider, Typography } from 'antd'; +import * as comm from '@/utils/commons'; +import { usePDF } from 'react-to-pdf'; +import dayjs from 'dayjs'; +import SearchForm from '@/components/SearchForm'; +import useAuthStore from '@/stores/Auth'; +import useReportStore from '@/stores/Report'; function Index() { - const { reportStore, authStore } = useStore(); - const { search_date_start, search_date_end, vendorScoresData, productScoresData, commendScoresData } = reportStore; - const evaluationScores = vendorScoresData.EvaluationScores ? vendorScoresData.EvaluationScores[0] : []; - useEffect(() => {}, []); - const columns_month = [ - { - title: "Date", - dataIndex: "VMonth", - key: "VMonth", - }, - { - title: "Groups", - dataIndex: "Groups", - key: "Groups", - }, - { - title: "Number of People", - dataIndex: "PersonNum", - key: "PersonNum", - }, - { - title: "Transaction Amount(USD)", - dataIndex: "AmountUSD", - key: "AmountUSD", - render: value => comm.formatPrice(value), - }, - { - title: "Evaluation Score", - dataIndex: "EvaluationScore", - key: "EvaluationScore", - }, - { - title: "TP Reviews", - dataIndex: "TPReviews", - key: "TPReviews", - }, - { - title: "TP Reviews Rate", - dataIndex: "TPReviewRate", - key: "TPReviewRate", - render: value => comm.formatPercent(value), - }, - { - title: "Complaints", - dataIndex: "Complaints", - key: "Complaints", - }, - { - title: "Complaint Rate", - dataIndex: "ComplaintRate", - key: "ComplaintRate", - render: value => comm.formatPercent(value), - }, - ]; + const [travelAgencyId, ] = useAuthStore((state) => [state.loginUser.travelAgencyId]); + const [vendorScoresData, getHWVendorScores] = useReportStore((state) => [state.vendorScoresData, state.getHWVendorScores]); + const [productScoresData, getHWProductScores] = useReportStore((state) => [state.productScoresData, state.getHWProductScores]); + const [commendScoresData, getHWCommendScores] = useReportStore((state) => [state.commendScoresData, state.getHWCommendScores]); - const columns_guide = [ - { - title: "Name", - dataIndex: "TGI2_Name", - key: "TGI2_Name", - }, - { - title: "Average Scores", - dataIndex: "VAverage", - key: "VAverage", - }, - { - title: "Group Numbers", - dataIndex: "ReceptionGroups", - key: "ReceptionGroups", - }, - { - title: "TP Reviews", - dataIndex: "CommendNum", - key: "CommendNum", - }, - { - title: "TP Review Rate", - dataIndex: "CommendRate", - key: "CommendRate", - render: value => comm.formatPercent(value), - }, - { - title: "Complaints", - dataIndex: "Complaints", - key: "Complaints", - }, - { - title: "Complaint Rate", - dataIndex: "ComplaintRate", - key: "ComplaintRate", - render: value => comm.formatPercent(value), - }, - ]; + const evaluationScores = vendorScoresData.EvaluationScores ? vendorScoresData.EvaluationScores[0] : []; + const primaryData = vendorScoresData.EvaluationScores + ? [comm.pick(vendorScoresData.EvaluationScores[0], ['Groups', 'PersonNum', 'AmountUSD', 'EvaluationScore', 'TPReviews', 'TPReviewRate', 'Complaints', 'ComplaintRate'])] + : []; - const columns_commend = [ - { - title: "Reference Number", - dataIndex: "GRI_No", - key: "GRI_No", - }, - { - title: "Tour Guides", - dataIndex: "ObjectName", - key: "ObjectName", - }, - { - title: "Essential Comments", - dataIndex: "ECI_Content", - key: "ECI_Content", - }, - ]; + const evaluationScoresData = [ + { category: 'DMC Services', item: 'Guide', value: evaluationScores.FRTGuide, note: evaluationScores.FRTText }, + { category: 'DMC Services', item: 'Driver & Vehicle', value: evaluationScores.FRTGriver }, + { category: 'DMC Services', item: 'Food Arrangement', value: evaluationScores.FRTMeal }, + { category: 'DMC Services', item: 'Activity', value: evaluationScores.FRTProduct }, + { category: 'Itinerary Arrangements', item: 'Hotel', value: evaluationScores.FRTHotel, }, + { category: 'Itinerary Arrangements', item: 'Travel Advisor’s Planning', value: evaluationScores.FRTAdvisor }, + ]; + const columns_evaluation = [ + { title: 'Category', dataIndex: 'category', key: 'category',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 4 : index === 4 ? 2 : 0 }) }, + { title: 'Item', dataIndex: 'item', key: 'item', align: 'center' }, + { title: 'Your Scores', dataIndex: 'value', key: 'value',align: 'center', }, + { title: 'Note', dataIndex: 'note', key: 'note',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 7 : 0 })}, + ]; - const { toPDF, targetRef } = usePDF({ - method: "save", - filename: "GHH-Report.pdf", - page: { margin: "3", format: "letter" }, //margin: Margin.SMALL, - canvas: { mimeType: "image/jpeg", qualityRatio: 1 }, - overrides: { pdf: { compress: true }, canvas: { useCORS: true } }, - }); + const columns_DMC_customer_satisfaction = [ + { title: 'Customer Satisfaction', dataIndex: 'item', key: 'item',align: 'center', }, + { title: '3 scores', dataIndex: 'stand_3', key: 'stand_3', align: 'center', onCell: (_, index) => ({ colSpan: (index === 2 || index===4) ? 3 : 1 }) }, + { title: '4 scores', dataIndex: 'stand_4', key: 'stand_4',align: 'center',onCell: (_, index) => ({ colSpan: (index === 2 || index===4) ? 0 : 1 }) }, + { title: '5 scores', dataIndex: 'stand_5', key: 'stand_5',align: 'center',onCell: (_, index) => ({ colSpan: (index === 2 || index===4) ? 0 : 1 }) }, + { title: 'Your Scores', dataIndex: 'value', key: 'value',align: 'center', }, + { title: 'Final Scores', dataIndex: 'final_score', key: 'final_score',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 5 : 0 })}, + { title: 'Note', dataIndex: 'note', key: 'note',align: 'center', }, + ]; + const DMCData_customer_satisfaction = [ + { + item: 'TP review rating', + stand_3: '\\', + stand_4: '30%', + stand_5: '60%', + value: evaluationScores.TPReviewRating, + final_score: evaluationScores.AvgCusSatisfaction, + note: evaluationScores.AvgCusSatisfaction, + }, + { + item: 'Post tour complaints', + stand_3: '1', + stand_4: '0', + stand_5: '0', + value: evaluationScores.PostTourComplaints, + // final_score: evaluationScores.AvgCusSatisfaction, + note: evaluationScores.PostTourComplaintsText, + }, + { + item: 'Complaints resolved during the tour', + stand_3: '3', + // stand_4: '0', + // stand_5: '0', + value: evaluationScores.ComplaintsDuringTour, + note: evaluationScores.ComplaintsDuringTourText, + }, + { item: 'Customer photos', stand_3: '\\', stand_4: '30%', stand_5: '50%', value: evaluationScores.CustomerPhotoRate, note: evaluationScores.CustomerPhotoRateText }, + { item: 'Evaluation scores', stand_3: '4.5', value: evaluationScores.EvaluationFormScore, note: evaluationScores.EvaluationFormScoreText }, + ]; - return ( - - - - - - Select Date - - - - - - - - - - - + const columns_DMC_sopport_local = [ + { title: 'Operator Support & Local resources', dataIndex: 'item', key: 'item',align: 'center', }, + { title: '3 scores', dataIndex: 'stand_3', key: 'stand_3', align: 'center', }, + { title: '4 scores', dataIndex: 'stand_4', key: 'stand_4',align: 'center', }, + { title: '5 scores', dataIndex: 'stand_5', key: 'stand_5',align: 'center', }, + { title: 'Your Scores', dataIndex: 'value', key: 'value',align: 'center', }, + { title: 'Final Scores', dataIndex: 'final_score', key: 'final_score',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 6 : 0 })}, + { title: 'Note', dataIndex: 'note', key: 'note',align: 'center', }, + ]; + const DMCData_sopport_local = [ + { + item: 'Response efficiency', + stand_3: '1d', + stand_4: '6hrs', + stand_5: '3hrs', + value: evaluationScores.ResponseEfficiency, + final_score: evaluationScores.AvgLocalResources, + note: evaluationScores.ResponseEfficiencyText, + }, + { + item: 'Provide suggestions and alternatives', + stand_3: '\\', + stand_4: '√', + stand_5: '√', + value: evaluationScores.ProvideSuggestions, + // final_score: evaluationScores.AvgCusSatisfaction, + note: evaluationScores.ProvideSuggestionsText, + }, + { + item: 'Provide local tourism information', + stand_3: '\\', + stand_4: '√', + stand_5: '√', + value: evaluationScores.ProvideLocalInfo, + note: evaluationScores.ProvideLocalInfoText, + }, + { item: 'Assist in developing exclusive products', + stand_3: '\\', + stand_4: '\\', + stand_5: '√', value: evaluationScores.ExclusiveProducts, note: evaluationScores.ExclusiveProductsText }, + { item: 'Dedicated tour guide team for AH', + stand_3: '\\', + stand_4: '√', + stand_5: '√', value: evaluationScores.DedicatedTourGuide, note: evaluationScores.DedicatedTourGuideText }, + { item: 'Partner hotels with contracted rate', + stand_3: '\\', + stand_4: '√', + stand_5: '√', value: evaluationScores.PartnerHotels, note: evaluationScores.PartnerHotelsText }, + ]; + const columns_DMC_pricing = [ + { title: 'Pricing & Settlement (20%)', dataIndex: 'item', key: 'item',align: 'center', }, + { title: '3 scores', dataIndex: 'stand_3', key: 'stand_3', align: 'center', }, + { title: '4 scores', dataIndex: 'stand_4', key: 'stand_4',align: 'center', }, + { title: '5 scores', dataIndex: 'stand_5', key: 'stand_5',align: 'center', }, + { title: 'Your Scores', dataIndex: 'value', key: 'value',align: 'center', }, + { title: 'Final Scores', dataIndex: 'final_score', key: 'final_score',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 3 : 0 })}, + { title: 'Note', dataIndex: 'note', key: 'note',align: 'center', }, + ]; + const DMCData_pricing = [ + { + item: 'Quotation', + stand_3: 'Package', + stand_4: 'Day tours', + stand_5: 'Individual services', + value: evaluationScores.Quotation, + final_score: evaluationScores.AvgPricingAndSettlement, + note: evaluationScores.QuotationText, + }, + { + item: 'Settlement', + stand_3: 'Prepayment', + stand_4: 'Monthly Prepayment', + stand_5: 'Monthly settlement after the tours', + value: evaluationScores.Settlement, + note: evaluationScores.SettlementText, + }, + { + item: 'Cancellation policy', + stand_3: '30 days', + stand_4: '21 days', + stand_5: '1 day', + value: evaluationScores.CancellationPolicy, + note: evaluationScores.CancellationPolicyText, + },]; - - - - Primary Data - -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - -
GroupsNumber of PeopleTransaction Amount (USD)Evaluation ScoreTP ReviewsTP Reviews RateComplaintsComplaint Rate
{evaluationScores.Groups}{evaluationScores.PersonNum}{comm.formatPrice(evaluationScores.AmountUSD)}{evaluationScores.EvaluationScore}{evaluationScores.TPReviews}{comm.formatPercent(evaluationScores.TPReviewRate)}{evaluationScores.Complaints}{comm.formatPercent(evaluationScores.ComplaintRate)}
-
-
-
-
- + const columns_primary = [ + { + title: 'Groups', + dataIndex: 'Groups', + key: 'Groups', + }, + { + title: 'Number of People', + dataIndex: 'PersonNum', + key: 'PersonNum', + }, + { + title: 'Transaction Amount(USD)', + dataIndex: 'AmountUSD', + key: 'AmountUSD', + render: (value) => comm.formatPrice(value), + }, + { + title: 'Evaluation Score', + dataIndex: 'EvaluationScore', + key: 'EvaluationScore', + }, + { + title: 'TP Reviews', + dataIndex: 'TPReviews', + key: 'TPReviews', + }, + { + title: 'TP Reviews Rate', + dataIndex: 'TPReviewRate', + key: 'TPReviewRate', + render: (value) => comm.formatPercent(value), + }, + { + title: 'Complaints', + dataIndex: 'Complaints', + key: 'Complaints', + }, + { + title: 'Complaint Rate', + dataIndex: 'ComplaintRate', + key: 'ComplaintRate', + render: (value) => comm.formatPercent(value), + }, + ]; - - - Monthly Data - - - + const columns_month = [{ title: 'Date', dataIndex: 'VMonth', key: 'VMonth' }, ...columns_primary]; - - - DMC Assessment Criteria - -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Customer Satisfaction3 scores4 scores5 scoresYour ScoresFinal ScoresNote
TP review rating\30%60%{evaluationScores.TPReviewRating}{evaluationScores.AvgCusSatisfaction}{evaluationScores.TPReviewRatingText}
Post tour complaints100{evaluationScores.PostTourComplaints}{evaluationScores.PostTourComplaintsText}
Complaints resolved during the tour3{evaluationScores.ComplaintsDuringTour}{evaluationScores.ComplaintsDuringTourText}
Customer photos\30%50%{evaluationScores.CustomerPhotoRate}{evaluationScores.CustomerPhotoRateText}
Evaluation scores4.5{evaluationScores.EvaluationFormScore}{evaluationScores.EvaluationFormScoreText}
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Operator Support & Local resources3 scores4 scores5 scoresYour ScoresFinal ScoresNote
Response efficiency1d6hrs3hrs{evaluationScores.ResponseEfficiency}{evaluationScores.AvgLocalResources}{evaluationScores.ResponseEfficiencyText}
Provide suggestions and alternatives\{evaluationScores.ProvideSuggestions}{evaluationScores.ProvideSuggestionsText}
Provide local tourism information\{evaluationScores.ProvideLocalInfo}{evaluationScores.ProvideLocalInfoText}
Assist in developing exclusive products\\{evaluationScores.ExclusiveProducts}{evaluationScores.ExclusiveProductsText}
Dedicated tour guide team for AH\{evaluationScores.DedicatedTourGuide}{evaluationScores.DedicatedTourGuideText}
Partner hotels with contracted rate\{evaluationScores.PartnerHotels}{evaluationScores.PartnerHotelsText}
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Pricing & Settlement (20%)3 scores4 scores5 scoresYour ScoresFinal ScoresNote
QuotationPackageDay toursIndividual services{evaluationScores.Quotation}{evaluationScores.AvgPricingAndSettlement}{evaluationScores.QuotationText}
SettlementPrepaymentMonthly PrepaymentMonthly settlement after the tours{evaluationScores.Settlement}{evaluationScores.SettlementText}
Cancellation policy30 days21 days1 day{evaluationScores.CancellationPolicy}{evaluationScores.CancellationPolicyText}
- - - - - - - Final Scores: {evaluationScores.FinalScores} - - -
- - - Scoring Rules - - -
    -
  1. The maximum score is 5
  2. -
  3. - The three categories are: -
      -
    • Customer satisfaction (40%)
    • -
    • Operator support & local resources (40%)
    • -
    • Pricing & settlement (20%)
    • -
    -
  4. -
  5. For each category, you can only get the corresponding score if you meet the standards of all items under the score.
  6. -
  7. The final score is the sum of the scores of each category multiplied by the proportion of the category.
  8. -
-
-
+ const columns_guide = [ + { + title: 'Name', + dataIndex: 'TGI2_Name', + key: 'TGI2_Name', + }, + { + title: 'Average Scores', + dataIndex: 'VAverage', + key: 'VAverage', + }, + { + title: 'Group Numbers', + dataIndex: 'ReceptionGroups', + key: 'ReceptionGroups', + }, + { + title: 'TP Reviews', + dataIndex: 'CommendNum', + key: 'CommendNum', + }, + { + title: 'TP Review Rate', + dataIndex: 'CommendRate', + key: 'CommendRate', + render: (value) => comm.formatPercent(value), + }, + { + title: 'Complaints', + dataIndex: 'Complaints', + key: 'Complaints', + }, + { + title: 'Complaint Rate', + dataIndex: 'ComplaintRate', + key: 'ComplaintRate', + render: (value) => comm.formatPercent(value), + }, + ]; -
- - Evaluation Scores - -
-
-
-
- - - - - - - - - - - - - - - - + const columns_commend = [ + { + title: 'Reference Number', + dataIndex: 'GRI_No', + key: 'GRI_No', + }, + { + title: 'Tour Guides', + dataIndex: 'ObjectName', + key: 'ObjectName', + }, + { + title: 'Essential Comments', + dataIndex: 'ECI_Content', + key: 'ECI_Content', + }, + ]; - - - - - - - - - - - - + const { toPDF, targetRef } = usePDF({ + method: 'save', + filename: 'GHH-Report.pdf', + page: { margin: '3', format: 'letter' }, //margin: Margin.SMALL, + canvas: { mimeType: 'image/jpeg', qualityRatio: 1 }, + overrides: { pdf: { compress: true }, canvas: { useCORS: true } }, + }); - - - - - - - - - - -
CategoryItemYour ScoresNote
DMC ServicesGuide{evaluationScores.FRTGuide}{evaluationScores.FRTText}
Driver & Vehicle{evaluationScores.FRTGriver}
Food Arrangement{evaluationScores.FRTMeal}
Activity{evaluationScores.FRTProduct}
Itinerary ArrangementsHotel{evaluationScores.FRTHotel}
Travel Advisor’s Planning{evaluationScores.FRTAdvisor}
-
-
-
-
- - - - Tour Guides Performence - - + return ( + + {/* */} + + + { + getHWVendorScores(travelAgencyId, formVal.startdate, formVal.enddate); + getHWProductScores(travelAgencyId, formVal.startdate, formVal.enddate); + getHWCommendScores(travelAgencyId, formVal.startdate, formVal.enddate); + }} + /> + + + + + - - TP Reviews - -
+ + + + + Primary Data + + +
+ - - Complaints - -
+ + + + Monthly Data + + +
+ - - Suggestions from Customers - -
- - - - ); + + + + DMC Assessment Criteria + + +
+
+
+
+
+ + + Final Scores: {evaluationScores.FinalScores} + + +
+ + + Scoring Rules + + +
    +
  1. The maximum score is 5
  2. +
  3. + The three categories are: +
      +
    • Customer satisfaction (40%)
    • +
    • Operator support & local resources (40%)
    • +
    • Pricing & settlement (20%)
    • +
    +
  4. +
  5. For each category, you can only get the corresponding score if you meet the standards of all items under the score.
  6. +
  7. The final score is the sum of the scores of each category multiplied by the proportion of the category.
  8. +
+
+
+ +
+ + + Evaluation Scores + + +
+ + + + + Tour Guides Performence + + +
+ + + + TP Reviews + + +
+ + + + Complaints + + +
+ + + + Suggestions from Customers + + +
+ + + + ); } -export default observer(Index); +export default (Index); From bf8c45033bad390a8e165ec199720fd39bece95d Mon Sep 17 00:00:00 2001 From: Lei OT Date: Wed, 5 Jun 2024 11:39:57 +0800 Subject: [PATCH 02/12] =?UTF-8?q?refactor:=20Notice=20=E8=AF=BB=E5=8F=96us?= =?UTF-8?q?erId?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/notice/Detail.jsx | 6 +++--- src/views/notice/Index.jsx | 8 ++++---- src/views/report/Index.jsx | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/views/notice/Detail.jsx b/src/views/notice/Detail.jsx index 033903b..575081b 100644 --- a/src/views/notice/Detail.jsx +++ b/src/views/notice/Detail.jsx @@ -1,22 +1,22 @@ import { NavLink, useParams } from 'react-router-dom'; import { useEffect, useState } from 'react'; import { Row, Col, Space, Typography, Divider } from 'antd'; -import { useStore } from '@/stores/StoreContext.js'; import * as comm from '@/utils/commons'; import { useTranslation } from 'react-i18next'; import { fetchNoticeDetail } from '@/stores/Notice'; +import useAuthStore from '@/stores/Auth'; const { Title, Paragraph } = Typography; function Detail() { const { t } = useTranslation(); - const { authStore } = useStore(); const { CCP_BLID } = useParams(); + const [userId, ] = useAuthStore((state) => [state.loginUser.userId]); const [noticeInfo, setNoticeInfo] = useState({}); useEffect(() => { // console.info("notice detail .useEffect " + CCP_BLID); - fetchNoticeDetail(authStore.login.userId, CCP_BLID).then((res) => { + fetchNoticeDetail(userId, CCP_BLID).then((res) => { setNoticeInfo(res); }); }, []); diff --git a/src/views/notice/Index.jsx b/src/views/notice/Index.jsx index f50f333..68a2c19 100644 --- a/src/views/notice/Index.jsx +++ b/src/views/notice/Index.jsx @@ -1,20 +1,20 @@ import { NavLink } from "react-router-dom"; import { useEffect, useState } from "react"; import { Row, Col, Space, Typography, Badge, List } from "antd"; -import { useStore } from "@/stores/StoreContext.js"; import useNoticeStore, { fetchBulletinList } from '@/stores/Notice'; +import useAuthStore from '@/stores/Auth'; function Index() { - const { authStore } = useStore(); + const [userId, ] = useAuthStore((state) => [state.loginUser.userId]); const getBulletinUnReadCount = useNoticeStore((state) => state.getBulletinUnReadCount); const [noticeList, setNoticeList] = useState([]); useEffect(() => { // console.info("notice.useEffect", authStore.login.userId); - fetchBulletinList(authStore.login.userId).then(data => { + fetchBulletinList(userId).then(data => { setNoticeList(data); }); - getBulletinUnReadCount(authStore.login.userId); //进入列表页的时候更新一下未读公告 + getBulletinUnReadCount(userId); //进入列表页的时候更新一下未读公告 }, []); return ( diff --git a/src/views/report/Index.jsx b/src/views/report/Index.jsx index 9e8724e..dcda29c 100644 --- a/src/views/report/Index.jsx +++ b/src/views/report/Index.jsx @@ -325,11 +325,11 @@ function Index() { DMC Assessment Criteria -
+

-
+

-
+
Final Scores: {evaluationScores.FinalScores} From b5c13f238d4a9239dae31a14cdecc3019d2fe107 Mon Sep 17 00:00:00 2001 From: Lei OT Date: Wed, 5 Jun 2024 11:44:16 +0800 Subject: [PATCH 03/12] =?UTF-8?q?perf:=20=E6=90=9C=E7=B4=A2=E6=A1=86,=20?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/SearchForm.jsx | 12 +++++------- src/views/report/Index.jsx | 1 + 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/components/SearchForm.jsx b/src/components/SearchForm.jsx index c116dd8..64e0794 100644 --- a/src/components/SearchForm.jsx +++ b/src/components/SearchForm.jsx @@ -14,10 +14,11 @@ const SearchForm = ({ initialValue, onSubmit, onReset, ...props }) => { 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 } = { + const { sort, hides, shows, fieldProps, fieldComProps } = { sort: '', // initialValue: '', fieldProps: '', + fieldComProps: '', hides: [], shows: [], ...props.defaultValue, @@ -87,7 +88,7 @@ const SearchForm = ({ initialValue, onSubmit, onReset, ...props }) => {
{/* */} - {getFields({ sort, initialValue: readValues, hides, shows, fieldProps, form, presets, t })} + {getFields({ sort, initialValue: readValues, hides, shows, fieldProps, fieldComProps, form, presets, t })} {/* 'textAlign': 'right' */}
@@ -107,7 +108,7 @@ const SearchForm = ({ initialValue, onSubmit, onReset, ...props }) => { }; function getFields(props) { - const { fieldProps, form, presets, t } = props; + const { fieldProps, fieldComProps, form, presets, t } = props; const bigCol = 4 * 2; const midCol = 6; const layoutProps = { @@ -167,11 +168,8 @@ function getFields(props) { allowClear={true} inputReadOnly={true} presets={presets} - // defaultValue={toJS(arrivalDateRange)} placeholder={['From', 'Thru']} - // onChange={(dateRange) => { - // reservationStore.updatePropertyValue('arrivalDateRange', dateRange == null ? [] : dateRange) - // }} + {...fieldComProps.dates} /> , fieldProps?.dates?.col || midCol diff --git a/src/views/report/Index.jsx b/src/views/report/Index.jsx index dcda29c..88769ce 100644 --- a/src/views/report/Index.jsx +++ b/src/views/report/Index.jsx @@ -286,6 +286,7 @@ function Index() { fieldProps: { dates: { label: 'Select Date', col: 12 }, }, + fieldComProps: { dates: { picker: 'month', presets: false } }, }} confirmText={'Get Report'} onSubmit={(err, formVal, filedsVal) => { From d8bc4d2ff422abaa566af0ca88504fff01b41ca7 Mon Sep 17 00:00:00 2001 From: Lei OT Date: Wed, 5 Jun 2024 13:49:19 +0800 Subject: [PATCH 04/12] =?UTF-8?q?perf(i18n):=20=E6=A3=80=E6=B5=8B=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E8=AE=BE=E5=A4=87=E8=AF=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/i18n/index.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/i18n/index.js b/src/i18n/index.js index 7611f57..10e586c 100644 --- a/src/i18n/index.js +++ b/src/i18n/index.js @@ -19,10 +19,14 @@ i18n }, ns: ['common', 'group'], defaultNS: 'common', - // detection: { - // convertDetectedLanguage: 'Iso15897', - // convertDetectedLanguage: (lng) => lng.replace('-', '_') - // }, + detection: { + // convertDetectedLanguage: 'Iso15897', + convertDetectedLanguage: (lng) => { + const langPart = lng.split('-')[0]; + return langPart; + // return lng.replace('-', '_'); + }, + }, supportedLngs: ['en', 'zh'], // resources: { // en: { translation: en }, From 5ef8c9a72f721194a3952169754067ea289e479c Mon Sep 17 00:00:00 2001 From: Lei OT Date: Wed, 5 Jun 2024 17:06:36 +0800 Subject: [PATCH 05/12] =?UTF-8?q?=E6=90=9C=E7=B4=A2:=20invoice=20status?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/SearchForm.jsx | 42 +++++++++++++++-------------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/src/components/SearchForm.jsx b/src/components/SearchForm.jsx index 64e0794..b9dafc8 100644 --- a/src/components/SearchForm.jsx +++ b/src/components/SearchForm.jsx @@ -137,40 +137,34 @@ function getFields(props) { 99, - ,4 + , + fieldProps?.referenceNo?.col || 4 ), item( 'invoiceStatus', 99, - - + +
+
@@ -317,7 +316,7 @@ function Index() { Monthly Data -
+
From 6b2d3d2b041081a7b9cccc694edf8db47412c95c Mon Sep 17 00:00:00 2001 From: Lei OT Date: Wed, 5 Jun 2024 17:29:35 +0800 Subject: [PATCH 07/12] i18n: + vendor.json --- public/locales/en/vendor.json | 5 +++++ public/locales/zh/vendor.json | 5 +++++ src/i18n/index.js | 2 +- src/views/report/Index.jsx | 4 +++- 4 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 public/locales/en/vendor.json create mode 100644 public/locales/zh/vendor.json diff --git a/public/locales/en/vendor.json b/public/locales/en/vendor.json new file mode 100644 index 0000000..52f97fe --- /dev/null +++ b/public/locales/en/vendor.json @@ -0,0 +1,5 @@ +{ + "report": { + "GetReport": "Get Report" + } +} diff --git a/public/locales/zh/vendor.json b/public/locales/zh/vendor.json new file mode 100644 index 0000000..678650f --- /dev/null +++ b/public/locales/zh/vendor.json @@ -0,0 +1,5 @@ +{ + "report": { + "GetReport": "获取报告" + } +} diff --git a/src/i18n/index.js b/src/i18n/index.js index 10e586c..b787ea2 100644 --- a/src/i18n/index.js +++ b/src/i18n/index.js @@ -17,7 +17,7 @@ i18n backend: { loadPath: '/locales/{{lng}}/{{ns}}.json', }, - ns: ['common', 'group'], + ns: ['common', 'group', 'vendor'], defaultNS: 'common', detection: { // convertDetectedLanguage: 'Iso15897', diff --git a/src/views/report/Index.jsx b/src/views/report/Index.jsx index 33076ab..a96a3c0 100644 --- a/src/views/report/Index.jsx +++ b/src/views/report/Index.jsx @@ -5,8 +5,10 @@ import dayjs from 'dayjs'; import SearchForm from '@/components/SearchForm'; import useAuthStore from '@/stores/Auth'; import useReportStore from '@/stores/Report'; +import { useTranslation } from 'react-i18next' function Index() { + const { t } = useTranslation(); const [travelAgencyId, ] = useAuthStore((state) => [state.loginUser.travelAgencyId]); const [loading, vendorScoresData, getHWVendorScores] = useReportStore((state) => [state.loading, state.vendorScoresData, state.getHWVendorScores]); @@ -288,7 +290,7 @@ function Index() { }, fieldComProps: { dates: { picker: 'month', presets: false } }, }} - confirmText={'Get Report'} + confirmText={t('vendor:report.GetReport')} onSubmit={(err, formVal, filedsVal) => { getHWVendorScores(travelAgencyId, formVal.startdate, formVal.enddate); getHWProductScores(travelAgencyId, formVal.startdate, formVal.enddate); From 30a83013291c0bb87ec4fb86ef55a0279a6612bb Mon Sep 17 00:00:00 2001 From: Lei OT Date: Thu, 6 Jun 2024 11:03:31 +0800 Subject: [PATCH 08/12] =?UTF-8?q?refactor:=20Invoice/index,=20Detail,=20?= =?UTF-8?q?=E8=AF=BB=E5=8F=96authstore;=20=E4=BD=BF=E7=94=A8=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/stores/Invoice.js | 10 ++-- src/views/invoice/Detail.jsx | 20 ++++--- src/views/invoice/Index.jsx | 104 ++++++++++++----------------------- 3 files changed, 52 insertions(+), 82 deletions(-) diff --git a/src/stores/Invoice.js b/src/stores/Invoice.js index 52e4984..95cab3e 100644 --- a/src/stores/Invoice.js +++ b/src/stores/Invoice.js @@ -8,7 +8,7 @@ import dayjs from "dayjs"; import { create } from 'zustand'; import { devtools } from 'zustand/middleware'; - +import useAuthStore from '@/stores/Auth'; const initialState = { invoiceList: [], //账单列表 @@ -124,7 +124,7 @@ export class Invoice { fetchInvoiceDetail(GMDSN, GSN) { const fetchUrl = prepareUrl(HT_HOST + "/service-cusservice/PTGetZDDetail") - .append("VEI_SN", this.root.authStore.login.travelAgencyId) + .append("VEI_SN", useAuthStore.getState().loginUser.travelAgencyId) .append("GRI_SN", GSN) .append("GMD_SN", GMDSN) .append("LGC", 1) @@ -231,7 +231,7 @@ export class Invoice { postEditInvoiceDetail(GMD_SN, Currency, Cost, PayDate, Pic, Memo) { let postUrl = HT_HOST + "/service-cusservice/EditSupplierFK"; let formData = new FormData(); - formData.append("LMI_SN", this.root.authStore.login.userId); + formData.append("LMI_SN", useAuthStore.getState().loginUser.userId); formData.append("GMD_SN", GMD_SN); formData.append("Currency", Currency); formData.append("Cost", Cost); @@ -249,8 +249,8 @@ export class Invoice { postAddInvoice(GRI_SN, Currency, Cost, PayDate, Pic, Memo) { let postUrl = HT_HOST + "/service-cusservice/AddSupplierFK"; let formData = new FormData(); - formData.append("LMI_SN", this.root.authStore.login.userId); - formData.append("VEI_SN", this.root.authStore.login.travelAgencyId); + formData.append("LMI_SN", useAuthStore.getState().loginUser.userId); + formData.append("VEI_SN", useAuthStore.getState().loginUser.travelAgencyId); formData.append("GRI_SN", GRI_SN); formData.append("Currency", Currency); formData.append("Cost", Cost); diff --git a/src/views/invoice/Detail.jsx b/src/views/invoice/Detail.jsx index cd1e539..01a91a2 100644 --- a/src/views/invoice/Detail.jsx +++ b/src/views/invoice/Detail.jsx @@ -8,6 +8,7 @@ import { PlusOutlined, AuditOutlined, SmileOutlined, SolutionOutlined, EditOutli import { isNotEmpty } from "@/utils/commons"; import * as config from "@/config"; import dayjs from "dayjs"; +import useAuthStore from '@/stores/Auth'; const { Title,Text } = Typography; const { TextArea } = Input; @@ -15,7 +16,10 @@ const { TextArea } = Input; function Detail() { const navigate = useNavigate(); const { GMDSN, GSN } = useParams(); - const { invoiceStore, authStore } = useStore(); + const { invoiceStore, } = useStore(); + + const [travelAgencyId, token] = useAuthStore((state) => [state.loginUser.travelAgencyId, state.loginUser.token]); + const { invoicekImages, invoiceGroupInfo, invoiceProductList, invoiceCurrencyList, invoiceZDDetail } = invoiceStore; const [form] = Form.useForm(); const [dataLoading, setDataLoading] = useState(false); @@ -35,7 +39,7 @@ function Detail() { invoiceStore .fetchInvoiceDetail(GMDSN, GSN) .then(json => { - let ZDDetail = json.ZDDetail; + let ZDDetail = json.ZDDetail; if (isNotEmpty(ZDDetail)) { let arrLen = ZDDetail.length; const formData = ZDDetail.map((data, index) => { @@ -122,7 +126,7 @@ function Detail() { description: "Success Submit!", placement: "top", duration: 4, - }); + }); } }); } @@ -272,13 +276,13 @@ function Detail() { }, ]} > - - - Payment is arranged during the last week of each month. If the invoice is issued after the 20th, please select the following month for payment. For urgent payments, please contact the travel advisor. + + + Payment is arranged during the last week of each month. If the invoice is issued after the 20th, please select the following month for payment. For urgent payments, please contact the travel advisor. -
+
- { - onGroupNoChange(e.target.value); - }} - /> - - + + + { + // fetchInvoiceList(travelAgencyId, formVal.referenceNo, formVal.startdate, formVal.enddate, formVal.invoiceStatus); + invoiceStore.fetchInvoiceList(travelAgencyId, formVal.referenceNo, formVal.startdate, formVal.enddate, formVal.invoiceStatus) + }} + /> + + + + + + -
From 2c8da99712ea4d4650d78764d9feb3a130f7aca0 Mon Sep 17 00:00:00 2001 From: Lei OT Date: Thu, 6 Jun 2024 11:11:36 +0800 Subject: [PATCH 09/12] =?UTF-8?q?refactor:=20Invoice/Paid,=20PaidDetail,?= =?UTF-8?q?=20=E8=AF=BB=E5=8F=96authstore;=20=E4=BD=BF=E7=94=A8=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/invoice/Paid.jsx | 205 ++++++++++++++----------------- src/views/invoice/PaidDetail.jsx | 9 +- 2 files changed, 100 insertions(+), 114 deletions(-) diff --git a/src/views/invoice/Paid.jsx b/src/views/invoice/Paid.jsx index 89461c1..f456ca2 100644 --- a/src/views/invoice/Paid.jsx +++ b/src/views/invoice/Paid.jsx @@ -1,121 +1,104 @@ -import { NavLink, useNavigate } from "react-router-dom"; -import { useEffect, useState } from "react"; -import { observer } from "mobx-react"; -import { toJS } from "mobx"; -import { Row, Col, Space, Button, Table, Input, DatePicker, Typography, App, Image } from "antd"; -import { useStore } from "@/stores/StoreContext.js"; -import * as config from "@/config"; -import { formatDate, isNotEmpty } from "@/utils/commons"; +import { NavLink, useNavigate } from 'react-router-dom'; +import { useEffect, useState } from 'react'; +import { observer } from 'mobx-react'; +import { toJS } from 'mobx'; +import { Row, Col, Space, Button, Table, Input, DatePicker, Typography, App, Image } from 'antd'; +import { useStore } from '@/stores/StoreContext.js'; +import * as config from '@/config'; +import { formatDate, isNotEmpty } from '@/utils/commons'; import usePresets from '@/hooks/usePresets'; +import SearchForm from '@/components/SearchForm'; +import useAuthStore from '@/stores/Auth'; +import dayjs from 'dayjs'; const { Title } = Typography; -function Paid(){ - const { authStore, invoiceStore } = useStore(); - const { invoicePaid, search_date_start, search_date_end } = invoiceStore; - const [groupNo, onGroupNoChange] = useState(""); - const navigate = useNavigate(); - const showTotal = total => `Total ${invoicePaid.length} items`; +function Paid() { + const { invoiceStore } = useStore(); + const { invoicePaid, search_date_start, search_date_end } = invoiceStore; + const [travelAgencyId] = useAuthStore((state) => [state.loginUser.travelAgencyId]); + const navigate = useNavigate(); + const showTotal = (total) => `Total ${total} items`; + useEffect(() => { + invoiceStore.fetchInvoicePaid(travelAgencyId, '', '', ''); + }, []); + const invoicePaidColumns = [ + { + title: 'Payment ref.NO', + dataIndex: 'fl_finaceNo', + key: 'fl_finaceNo', + render: (text, record) => {text}, + }, + { + title: 'Payment date', + key: 'fl_adddate', + dataIndex: 'fl_adddate', + render: (text, record) => (isNotEmpty(text) ? formatDate(new Date(text)) : ''), + }, + { + title: 'Number of bills', + key: 'fcount', + dataIndex: 'fcount', + }, + { + title: 'Total amount', + key: 'pSum', + dataIndex: 'pSum', + //render: (text, record) => (isNotEmpty(record.GMD_Currency) ? record.GMD_Currency + " " + text : text), + }, + { + title: 'Bank statement', + key: 'fl_pic', + dataIndex: 'fl_pic', + render: showPIc, + }, + ]; - useEffect (() => { - invoiceStore.fetchInvoicePaid(authStore.login.travelAgencyId,"","",""); - - },[]); - const invoicePaidColumns = [ - { - title: "Payment ref.NO", - dataIndex: "fl_finaceNo", - key: "fl_finaceNo", - render: (text, record) => {text}, - }, - { - title: "Payment date", - key: "fl_adddate", - dataIndex: "fl_adddate", - render: (text, record) => (isNotEmpty(text) ? formatDate(new Date(text)) : ""), - }, - { - title: "Number of bills", - key: "fcount", - dataIndex: "fcount", - }, - { - title: "Total amount", - key: "pSum", - dataIndex: "pSum", - //render: (text, record) => (isNotEmpty(record.GMD_Currency) ? record.GMD_Currency + " " + text : text), - }, - { - title: "Bank statement", - key: "fl_pic", - dataIndex: "fl_pic", - render: showPIc, - }, - ]; - - function showPIc(text,record) { - let strPic = record.fl_pic; - //console.log(JSON.parse(strPic)); - if (isNotEmpty(strPic)){ - return ( - - JSON.parse(strPic).map((item,index) => { - return ; - }) - - ); - }else{ - return ""; - } - + function showPIc(text, record) { + let strPic = record.fl_pic; + //console.log(JSON.parse(strPic)); + if (isNotEmpty(strPic)) { + return JSON.parse(strPic).map((item, index) => { + return ; + }); + } else { + return ''; } + } - - - return ( - - - - - - - - - - - - { - onGroupNoChange(e.target.value); - }} - /> - - - - Date - - - - - - - - - - -
- - - - ); + return ( + + + + { + invoiceStore.fetchInvoicePaid(travelAgencyId, formVal.referenceNo, formVal.startdate, formVal.enddate); + }} + /> + + + + + + + +
+ + + + ); } export default observer(Paid); diff --git a/src/views/invoice/PaidDetail.jsx b/src/views/invoice/PaidDetail.jsx index eb932da..87ffc26 100644 --- a/src/views/invoice/PaidDetail.jsx +++ b/src/views/invoice/PaidDetail.jsx @@ -6,16 +6,19 @@ import { Row, Col, Space, Button, Table, Typography } from "antd"; import { useStore } from "@/stores/StoreContext.js"; import * as config from "@/config"; import { formatDate, isNotEmpty } from "@/utils/commons"; +import useAuthStore from '@/stores/Auth'; + const { Title } = Typography; function PaidDetail(){ const navigate = useNavigate(); - const { authStore, invoiceStore } = useStore(); + const { invoiceStore } = useStore(); const { invoicePaidDetail } = invoiceStore; + const [travelAgencyId] = useAuthStore((state) => [state.loginUser.travelAgencyId]); const { flid } = useParams(); useEffect(() => { - invoiceStore.fetchInvoicePaidDetail(authStore.login.travelAgencyId,flid); + invoiceStore.fetchInvoicePaidDetail(travelAgencyId,flid); },[flid]); @@ -64,4 +67,4 @@ function PaidDetail(){ ); } -export default observer(PaidDetail); \ No newline at end of file +export default observer(PaidDetail); From 733c1c0fece4594988678a21643b71a5cb0c5b77 Mon Sep 17 00:00:00 2001 From: Lei OT Date: Thu, 6 Jun 2024 11:43:05 +0800 Subject: [PATCH 10/12] =?UTF-8?q?refactor:=20Invoice/index,=20Detail,=20?= =?UTF-8?q?=E8=AF=BB=E5=8F=96authstore;=20=E4=BD=BF=E7=94=A8=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/stores/Invoice.js | 15 +++++++-------- src/views/invoice/Detail.jsx | 8 ++++---- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/stores/Invoice.js b/src/stores/Invoice.js index 95cab3e..220549d 100644 --- a/src/stores/Invoice.js +++ b/src/stores/Invoice.js @@ -8,7 +8,6 @@ import dayjs from "dayjs"; import { create } from 'zustand'; import { devtools } from 'zustand/middleware'; -import useAuthStore from '@/stores/Auth'; const initialState = { invoiceList: [], //账单列表 @@ -122,9 +121,9 @@ export class Invoice { }); } - fetchInvoiceDetail(GMDSN, GSN) { + fetchInvoiceDetail(VEI_SN, GMDSN, GSN) { const fetchUrl = prepareUrl(HT_HOST + "/service-cusservice/PTGetZDDetail") - .append("VEI_SN", useAuthStore.getState().loginUser.travelAgencyId) + .append("VEI_SN", VEI_SN) .append("GRI_SN", GSN) .append("GMD_SN", GMDSN) .append("LGC", 1) @@ -228,10 +227,10 @@ export class Invoice { }); } - postEditInvoiceDetail(GMD_SN, Currency, Cost, PayDate, Pic, Memo) { + postEditInvoiceDetail(LMI_SN, GMD_SN, Currency, Cost, PayDate, Pic, Memo) { let postUrl = HT_HOST + "/service-cusservice/EditSupplierFK"; let formData = new FormData(); - formData.append("LMI_SN", useAuthStore.getState().loginUser.userId); + formData.append("LMI_SN", LMI_SN); formData.append("GMD_SN", GMD_SN); formData.append("Currency", Currency); formData.append("Cost", Cost); @@ -246,11 +245,11 @@ export class Invoice { }); } - postAddInvoice(GRI_SN, Currency, Cost, PayDate, Pic, Memo) { + postAddInvoice(LMI_SN, VEI_SN, GRI_SN, Currency, Cost, PayDate, Pic, Memo) { let postUrl = HT_HOST + "/service-cusservice/AddSupplierFK"; let formData = new FormData(); - formData.append("LMI_SN", useAuthStore.getState().loginUser.userId); - formData.append("VEI_SN", useAuthStore.getState().loginUser.travelAgencyId); + formData.append("LMI_SN", LMI_SN); + formData.append("VEI_SN", VEI_SN); formData.append("GRI_SN", GRI_SN); formData.append("Currency", Currency); formData.append("Cost", Cost); diff --git a/src/views/invoice/Detail.jsx b/src/views/invoice/Detail.jsx index 01a91a2..626d623 100644 --- a/src/views/invoice/Detail.jsx +++ b/src/views/invoice/Detail.jsx @@ -18,7 +18,7 @@ function Detail() { const { GMDSN, GSN } = useParams(); const { invoiceStore, } = useStore(); - const [travelAgencyId, token] = useAuthStore((state) => [state.loginUser.travelAgencyId, state.loginUser.token]); + const [userId, travelAgencyId, token] = useAuthStore((state) => [state.loginUser.userId,state.loginUser.travelAgencyId, state.loginUser.token]); const { invoicekImages, invoiceGroupInfo, invoiceProductList, invoiceCurrencyList, invoiceZDDetail } = invoiceStore; const [form] = Form.useForm(); @@ -37,7 +37,7 @@ function Detail() { function defaultShow() { setDataLoading(true); invoiceStore - .fetchInvoiceDetail(GMDSN, GSN) + .fetchInvoiceDetail(travelAgencyId, GMDSN, GSN) .then(json => { let ZDDetail = json.ZDDetail; if (isNotEmpty(ZDDetail)) { @@ -113,7 +113,7 @@ function Detail() { console.log("Success:", fieldVaule); //入库 if (fieldVaule) { - invoiceStore.postEditInvoiceDetail(fieldVaule.info_gmdsn, fieldVaule.info_Currency, fieldVaule.info_money, fieldVaule.info_date, fieldVaule.info_images, "").then(data => { + invoiceStore.postEditInvoiceDetail(userId, fieldVaule.info_gmdsn, fieldVaule.info_Currency, fieldVaule.info_money, fieldVaule.info_date, fieldVaule.info_images, "").then(data => { console.log(data); runInAction(() => { let param = { info_money: fieldVaule.info_money, info_Currency: fieldVaule.info_Currency, info_date: fieldVaule.info_date }; @@ -167,7 +167,7 @@ function Detail() { function addInvoice() { invoiceStore - .postAddInvoice(GSN, "", 0, "", "[]", "") + .postAddInvoice(userId, travelAgencyId, GSN, "", 0, "", "[]", "") .then(data => {}) .finally(() => { defaultShow(); From 96c8017271ac06259edae787562855b39e607854 Mon Sep 17 00:00:00 2001 From: Lei OT Date: Thu, 6 Jun 2024 15:06:23 +0800 Subject: [PATCH 11/12] refactor: Component/BackBtn --- src/components/BackBtn.jsx | 16 ++++++++++++++++ src/views/feedback/CustomerDetail.jsx | 5 ++--- src/views/feedback/Detail.jsx | 5 ++--- src/views/invoice/Detail.jsx | 5 ++--- src/views/invoice/Paid.jsx | 6 +++--- src/views/invoice/PaidDetail.jsx | 5 ++--- src/views/notice/Detail.jsx | 3 ++- src/views/reservation/Detail.jsx | 3 ++- 8 files changed, 31 insertions(+), 17 deletions(-) create mode 100644 src/components/BackBtn.jsx diff --git a/src/components/BackBtn.jsx b/src/components/BackBtn.jsx new file mode 100644 index 0000000..c12978e --- /dev/null +++ b/src/components/BackBtn.jsx @@ -0,0 +1,16 @@ +import { createContext, useContext, useEffect, useState } from 'react'; +import { Link, useNavigate } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; +import { Button } from 'antd'; +import { isNotEmpty } from '@/utils/commons'; + +const BackBtn = ({to, ...props}) => { + const { t } = useTranslation(); + const navigate = useNavigate(); + return ( + <> + {isNotEmpty(to) ? {t('Back')}l : } + + ); +}; +export default BackBtn; diff --git a/src/views/feedback/CustomerDetail.jsx b/src/views/feedback/CustomerDetail.jsx index 25afcf3..d9f77ce 100644 --- a/src/views/feedback/CustomerDetail.jsx +++ b/src/views/feedback/CustomerDetail.jsx @@ -5,6 +5,7 @@ import { PlusOutlined } from '@ant-design/icons'; import * as config from '@/config'; import useAuthStore from '@/stores/Auth'; import { getFeedbackDetail, getCustomerFeedbackDetail, getFeedbackImages, getFeedbackInfo, removeFeedbackImages, postFeedbackInfo } from '@/stores/Feedback'; +import BackBtn from '@/components/BackBtn'; const { Title, Text, Paragraph } = Typography; @@ -79,9 +80,7 @@ function Detail() { - + diff --git a/src/views/feedback/Detail.jsx b/src/views/feedback/Detail.jsx index a8f0388..9683fbe 100644 --- a/src/views/feedback/Detail.jsx +++ b/src/views/feedback/Detail.jsx @@ -5,6 +5,7 @@ import { PlusOutlined } from "@ant-design/icons"; import * as config from "@/config"; import useAuthStore from '@/stores/Auth'; import { getFeedbackDetail, getFeedbackImages, getFeedbackInfo, removeFeedbackImages, postFeedbackInfo } from '@/stores/Feedback'; +import BackBtn from "@/components/BackBtn"; const { Title, Text, Paragraph } = Typography; function Detail() { @@ -81,9 +82,7 @@ function Detail() { - + diff --git a/src/views/invoice/Detail.jsx b/src/views/invoice/Detail.jsx index 626d623..79d2cd4 100644 --- a/src/views/invoice/Detail.jsx +++ b/src/views/invoice/Detail.jsx @@ -9,6 +9,7 @@ import { isNotEmpty } from "@/utils/commons"; import * as config from "@/config"; import dayjs from "dayjs"; import useAuthStore from '@/stores/Auth'; +import BackBtn from '@/components/BackBtn'; const { Title,Text } = Typography; const { TextArea } = Input; @@ -337,9 +338,7 @@ function Detail() { Reference Number: {invoiceGroupInfo.VGroupInfo} - + diff --git a/src/views/invoice/Paid.jsx b/src/views/invoice/Paid.jsx index f456ca2..c036e3a 100644 --- a/src/views/invoice/Paid.jsx +++ b/src/views/invoice/Paid.jsx @@ -10,6 +10,8 @@ import usePresets from '@/hooks/usePresets'; import SearchForm from '@/components/SearchForm'; import useAuthStore from '@/stores/Auth'; import dayjs from 'dayjs'; +import BackBtn from '@/components/BackBtn'; + const { Title } = Typography; function Paid() { @@ -87,9 +89,7 @@ function Paid() { /> - + diff --git a/src/views/invoice/PaidDetail.jsx b/src/views/invoice/PaidDetail.jsx index 87ffc26..6b6de86 100644 --- a/src/views/invoice/PaidDetail.jsx +++ b/src/views/invoice/PaidDetail.jsx @@ -7,6 +7,7 @@ import { useStore } from "@/stores/StoreContext.js"; import * as config from "@/config"; import { formatDate, isNotEmpty } from "@/utils/commons"; import useAuthStore from '@/stores/Auth'; +import BackBtn from '@/components/BackBtn'; const { Title } = Typography; @@ -52,9 +53,7 @@ function PaidDetail(){ - + diff --git a/src/views/notice/Detail.jsx b/src/views/notice/Detail.jsx index 575081b..e4af7f4 100644 --- a/src/views/notice/Detail.jsx +++ b/src/views/notice/Detail.jsx @@ -5,6 +5,7 @@ import * as comm from '@/utils/commons'; import { useTranslation } from 'react-i18next'; import { fetchNoticeDetail } from '@/stores/Notice'; import useAuthStore from '@/stores/Auth'; +import BackBtn from '@/components/BackBtn'; const { Title, Paragraph } = Typography; @@ -33,7 +34,7 @@ function Detail() { - {t('Back')} + diff --git a/src/views/reservation/Detail.jsx b/src/views/reservation/Detail.jsx index 8ce7b1b..cc2fb90 100644 --- a/src/views/reservation/Detail.jsx +++ b/src/views/reservation/Detail.jsx @@ -8,6 +8,7 @@ import { } from '@ant-design/icons'; import { useStore } from '@/stores/StoreContext.js'; import { useTranslation } from 'react-i18next'; +import BackBtn from '@/components/BackBtn'; const { Title, Paragraph } = Typography; const { TextArea } = Input; @@ -158,7 +159,7 @@ function Detail() { {t('group:RefNo')}: {reservationDetail.referenceNumber}; {t('group:ArrivalDate')}: {reservationDetail.arrivalDate}; - + From b682fcb9cb713963e38365524927fc558e052156 Mon Sep 17 00:00:00 2001 From: Lei OT Date: Thu, 6 Jun 2024 15:10:07 +0800 Subject: [PATCH 12/12] # --- src/components/BackBtn.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/BackBtn.jsx b/src/components/BackBtn.jsx index c12978e..26068e0 100644 --- a/src/components/BackBtn.jsx +++ b/src/components/BackBtn.jsx @@ -9,7 +9,7 @@ const BackBtn = ({to, ...props}) => { const navigate = useNavigate(); return ( <> - {isNotEmpty(to) ? {t('Back')}l : } + {isNotEmpty(to) ? {t('Back')} : } ); };