From dd201d8b4e6554f7642fe543914f8b0612f53144 Mon Sep 17 00:00:00 2001 From: Lei OT Date: Thu, 4 Jan 2024 17:28:18 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B5=B7=E5=A4=96=E5=8F=8D=E9=A6=88?= =?UTF-8?q?=E8=A1=A8.=20=E6=9C=89service=20Item=E7=9A=84=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jsconfig.json | 9 ++ src/main.jsx | 8 +- src/stores/Feedback.js | 41 +++++- src/utils/commons.js | 15 +- src/views/feedback/CustomerDetail.jsx | 197 ++++++++++++++++++++++++++ src/views/feedback/Index.jsx | 2 +- 6 files changed, 266 insertions(+), 6 deletions(-) create mode 100644 jsconfig.json create mode 100644 src/views/feedback/CustomerDetail.jsx diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..130459b --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "experimentalDecorators": true, + "baseUrl": "./", + "paths": { + "@/*": ["src/*"] + } + } +} diff --git a/src/main.jsx b/src/main.jsx index 06ef9e0..89f22af 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -19,6 +19,7 @@ import ChangePassword from "@/views/account/ChangePassword"; import AccountProfile from "@/views/account/Profile"; import FeedbackIndex from "@/views/feedback/Index"; import FeedbackDetail from "@/views/feedback/Detail"; +import FeedbackCustomerDetail from "@/views/feedback/CustomerDetail"; import NoticeIndex from "@/views/notice/Index"; import NoticeDetail from "@/views/notice/Detail"; import InvoiceIndex from "@/views/invoice/Index"; @@ -28,7 +29,7 @@ import InvoicePaidDetail from "@/views/invoice/PaidDetail"; import ChangeVendor from "@/views/account/ChangeVendor"; -configure({ +configure({ useProxies: "ifavailable", enforceActions: "observed", computedRequiresReaction: true, @@ -50,6 +51,7 @@ const router = createBrowserRouter([ { path: "account/profile", element: }, { path: "feedback", element: }, { path: "feedback/:GRI_SN/:RefNo", element: }, + { path: "feedback/:GRI_SN/:CII_SN/:RefNo", element: }, { path: "notice", element: }, { path: "notice/:CCP_BLID", element: }, { path: "invoice",element:}, @@ -72,10 +74,10 @@ const rootStore = new RootStore(); ReactDOM.createRoot(document.getElementById("root")).render( // -
Loading...
} />
//
-); \ No newline at end of file +); diff --git a/src/stores/Feedback.js b/src/stores/Feedback.js index 739c5d0..ba0f7c1 100644 --- a/src/stores/Feedback.js +++ b/src/stores/Feedback.js @@ -1,6 +1,6 @@ import { makeAutoObservable, runInAction } from "mobx"; import { fetchJSON, postForm } from "@/utils/request"; -import { prepareUrl } from "@/utils/commons"; +import { prepareUrl, groupBy } from "@/utils/commons"; import * as config from "@/config"; import dayjs from "dayjs"; @@ -68,6 +68,45 @@ class Feedback { }); } + /** + * 客人填写的反馈 + * @param {number} VEI_SN 供应商 + * @param {number} GRI_SN 团 + * @author LYT + * 2024-01-04 + */ + getCustomerFeedbackDetail(VEI_SN, GRI_SN, CII_SN) { + let url = `/service-CooperateSOA/get_feedback_service_item`; + url += `?GRI_SN=${GRI_SN}&VEI_SN=${VEI_SN}&city_sn=${CII_SN}&lgc=1`; + url += `&token=${this.root.authStore.login.token}`; + fetch(config.HT_HOST + url) + .then(response => response.json()) + .then(json => { + const itemGroup = groupBy(json.feedbackItemList, ele => ele.type); + const serviceItem = { + HWO_Guide: itemGroup?.W || [], + HWO_Driver: itemGroup?.Y || [], + HWO_Activity: [ + ...(itemGroup['7'] || []), + ...(itemGroup.G || []), + ...(itemGroup.C || []), + ...(itemGroup.A || []).map(ele => ({ ...ele, Describe: 'Hotel ' + ele.name })),], + }; + const OtherThoughts = json.feedbackEvaluation[0]?.otherComments || ''; + const PhotoPermission = json.feedbackEvaluation[0]?.usePhotos || ''; + const signatureData = json.feedbackEvaluation[0]?.signatureDataUrl || ''; + const cityName = json.group[0]?.cityName || ''; + + runInAction(() => { + this.feedbackRate = {...serviceItem, OtherThoughts, PhotoPermission, signatureData, cityName }; + // this.feedbackReview = json.Result1; + }); + }) + .catch(error => { + console.log("fetch data failed", error); + }); + } + //获取供应商提交的图片 getFeedbackImages(VEI_SN, GRI_SN) { let url = `/service-fileServer/ListFile`; diff --git a/src/utils/commons.js b/src/utils/commons.js index 2dd6b0d..ce0d136 100644 --- a/src/utils/commons.js +++ b/src/utils/commons.js @@ -129,4 +129,17 @@ export function escape2Html(str) { var output = temp.innerText || temp.textContent; temp = null; return output; - } \ No newline at end of file + } + +export function groupBy(array, callback) { + return array.reduce((groups, item) => { + const key = typeof callback === 'function' ? callback(item) : item[callback]; + + if (!groups[key]) { + groups[key] = []; + } + + groups[key].push(item); + return groups; + }, {}); +} diff --git a/src/views/feedback/CustomerDetail.jsx b/src/views/feedback/CustomerDetail.jsx new file mode 100644 index 0000000..3a1ff64 --- /dev/null +++ b/src/views/feedback/CustomerDetail.jsx @@ -0,0 +1,197 @@ +import { useParams, useNavigate } from "react-router-dom"; +import { useEffect } from "react"; +import { observer } from "mobx-react"; +import { toJS, runInAction } from "mobx"; +import { Row, Col, Space, Button, Divider, Form, Typography, Rate, Radio, Upload, Input, App, Card } from "antd"; +import { useStore } from "../../stores/StoreContext.js"; +import { PlusOutlined } from "@ant-design/icons"; +const { Title, Text, Paragraph } = Typography; +import * as config from "@/config"; + +function Detail() { + const navigate = useNavigate(); + const { GRI_SN, RefNo, CII_SN } = useParams(); + const { feedbackStore, authStore } = useStore(); + const { feedbackRate, feedbackReview, feedbackImages, feedbackInfo } = feedbackStore; + const desc = ["none", "Unacceptable", "Poor", "Fair", "Very Good", "Excellent"]; + const { notification } = App.useApp(); + const [form] = Form.useForm(); + + useEffect(() => { + console.info("Detail.useEffect: " + GRI_SN); + feedbackStore.getCustomerFeedbackDetail(authStore.login.travelAgencyId, GRI_SN, CII_SN); + feedbackStore.getFeedbackImages(authStore.login.travelAgencyId, GRI_SN); + feedbackStore.getFeedbackInfo(authStore.login.travelAgencyId, GRI_SN).then(v => { + form.setFieldsValue({ info_content: v.EEF_Content }); + }); + }, [GRI_SN]); + + const HWO_Guide = feedbackRate && feedbackRate.HWO_Guide ? feedbackRate.HWO_Guide : []; + const HWO_Driver = feedbackRate && feedbackRate.HWO_Driver ? feedbackRate.HWO_Driver : []; + const HWO_Activity = feedbackRate && feedbackRate.HWO_Activity ? feedbackRate.HWO_Activity : []; + const OtherThoughts = feedbackRate && feedbackRate.OtherThoughts ? feedbackRate.OtherThoughts : ""; + const signatureData = feedbackRate && feedbackRate.signatureData ? feedbackRate.signatureData : ""; + const PhotoPermission = feedbackRate?.PhotoPermission === 1; + const cityName = feedbackRate.cityName; + const ECI_Content = feedbackReview && feedbackReview.ECI_Content ? feedbackReview.ECI_Content : "None"; + const fileList = toJS(feedbackImages); + + const handleChange = info => { + let newFileList = [...info.fileList]; + newFileList = newFileList.map(file => { + if (file.response && file.response.result) { + file.url = file.response.result.file_url; + } + return file; + }); + runInAction(() => { + feedbackStore.feedbackImages = newFileList; + }); + }; + + const handRemove = info => { + return feedbackStore.removeFeedbackImages(info.url); + }; + + const onFinish = values => { + console.log("Success:", values); + if (values) { + feedbackStore.postFeedbackInfo(feedbackInfo.EEF_VEI_SN, feedbackInfo.EEF_GRI_SN, feedbackInfo.EEF_EOI_SN, values.info_content).then(() => { + notification.success({ + message: `Notification`, + description: "Submit Successful", + placement: "top", + duration: 4, + }); + }); + } + }; + + return ( + + + + + + + + + + + + + Post Survey {RefNo} for {cityName}}> +
+ How satisfied were you with your tour guide? + {HWO_Guide.map(ele => ( + + + + {desc[ele.rate]} + + + ))} + + How about the Driver and Car/Van? + {HWO_Driver.map(ele => ( + + + + {desc[ele.rate]} + + + ))} + + General Experience with: + {HWO_Activity.map(ele => ( + + + + {desc[ele.rate]} + + + ))} + + Would you like to give us permission to use the photos taken by the tour guide(s) during your trip which contain your portrait? + + {PhotoPermission ? ( + <> + Yes + No + + ) : ( + <> + Yes + No + + )} + + Other thoughts you want to share with us: + {OtherThoughts} + Signature: + customer signature + +
+ + +
+ + + + + + External Reviews}> + {ECI_Content} + + + + + + + + + Feedback from local agent}> +
+ + +
+ +
Upload photos
+
+
+
+ + + + + + +
+
+ + +
+
+ ); +} + +export default observer(Detail); diff --git a/src/views/feedback/Index.jsx b/src/views/feedback/Index.jsx index 817e738..d536fdf 100644 --- a/src/views/feedback/Index.jsx +++ b/src/views/feedback/Index.jsx @@ -11,7 +11,7 @@ const feedbackListColumns = [ { title: "Ref.No", dataIndex: "EOI_Group_Name", - render: (text, record) => {text}, + render: (text, record) => {text}, }, { title: "Arrival Date",