反馈表统计数据显示

release
YCC 2 years ago
parent b689d68218
commit 0492623a32

@ -16,6 +16,8 @@ antd https://ant-design.antgroup.com/components/upload-cn#uploadfile
国内供应商平台 http://p.mycht.cn/index.aspx 国内供应商平台 http://p.mycht.cn/index.aspx
文档预览 https://github.com/cyntler/react-doc-viewer 文档预览 https://github.com/cyntler/react-doc-viewer
wps的文档预览 https://wwo.wps.cn/docs/front-end/introduction/quick-start wps的文档预览 https://wwo.wps.cn/docs/front-end/introduction/quick-start
pdf生成 https://github.com/ivmarcos/react-to-pdf
react-pdf https://react-pdf.org
## 阿里云OSS ## 阿里云OSS
Bucket 名称global-highlights-hub Bucket 名称global-highlights-hub

@ -9,12 +9,14 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@react-pdf/renderer": "^3.4.0",
"antd": "^5.4.2", "antd": "^5.4.2",
"mobx": "^6.9.0", "mobx": "^6.9.0",
"mobx-react": "^7.6.0", "mobx-react": "^7.6.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-router-dom": "^6.10.0" "react-router-dom": "^6.10.0",
"react-to-pdf": "^1.0.1"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^18.0.28", "@types/react": "^18.0.28",

@ -28,7 +28,7 @@ class Report {
getHWVendorScores(VEI_SN, StartDate, EndDate) { getHWVendorScores(VEI_SN, StartDate, EndDate) {
this.loading = true; //HT_HOST + this.loading = true; //HT_HOST +
const fetchUrl = prepareUrl("http://202.103.68.231:889/service-cusservice/PTGetHWVendorScores") const fetchUrl = prepareUrl("http://202.103.68.231:889/service-cusservice/PTGetHWVendorScores")
.append("VEI_SN", 1) .append("VEI_SN", 32865)
.append("StartDate", StartDate) .append("StartDate", StartDate)
.append("EndDate", EndDate) .append("EndDate", EndDate)
.append("StrDEI_SN", "(,-1,)") .append("StrDEI_SN", "(,-1,)")

@ -2,63 +2,21 @@ import { NavLink } from "react-router-dom";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import { toJS } from "mobx"; import { toJS } from "mobx";
import { Row, Col, Space, Button, Table, Divider, Typography, Badge, List, DatePicker } from "antd"; import { Row, Col, Space, Button, Table, Divider, Typography, List, Descriptions, DatePicker, Card } from "antd";
import { useStore } from "@/stores/StoreContext.js"; import { useStore } from "@/stores/StoreContext.js";
import * as config from "@/config"; import * as config from "@/config";
import * as comm from "@/utils/commons"; import * as comm from "@/utils/commons";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { usePDF } from "react-to-pdf";
const { Title, Paragraph, Text } = Typography; const { Title } = Typography;
function Index() { function Index() {
const { reportStore, authStore } = useStore(); const { reportStore, authStore } = useStore();
const { search_date_start, search_date_end, vendorScoresData, productScoresData, commendScoresData } = reportStore; const { search_date_start, search_date_end, vendorScoresData, productScoresData, commendScoresData } = reportStore;
const evaluationScores = vendorScoresData.EvaluationScores ? vendorScoresData.EvaluationScores[0] : [];
useEffect(() => {}, []); useEffect(() => {}, []);
const columns_primary = [
{
title: "Groups",
dataIndex: "Groups",
key: "Groups",
},
{
title: "Number of People",
dataIndex: "PersonNum",
key: "PersonNum",
},
{
title: "Transaction AmountUSD)",
dataIndex: "AmountUSD",
key: "AmountUSD",
},
{
title: "Evaluation Score",
dataIndex: "EvaluationScore",
key: "EvaluationScore",
},
{
title: "TP Reviews",
dataIndex: "TPReviews",
key: "TPReviews",
},
{
title: "TP Reviews Rate",
dataIndex: "TPReviewRate",
key: "TPReviewRate",
},
{
title: "Complaints",
dataIndex: "Complaints",
key: "Complaints",
},
{
title: "Complaint Rate",
dataIndex: "ComplaintRate",
key: "ComplaintRate",
},
];
const columns_month = [ const columns_month = [
{ {
title: "Date", title: "Date",
@ -202,7 +160,7 @@ function Index() {
key: "GRI_NO", key: "GRI_NO",
}, },
{ {
title: "投诉对象", title: "对象",
dataIndex: "ObjectName", dataIndex: "ObjectName",
key: "ObjectName", key: "ObjectName",
}, },
@ -251,9 +209,19 @@ function Index() {
}, },
]; ];
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 } },
});
return ( return (
<Space direction="vertical" style={{ width: "100%" }}> <Space direction="vertical" style={{ width: "100%" }}>
<Title level={3}></Title> <Title level={3}>
<div></div>
</Title>
<Row gutter={16}> <Row gutter={16}>
<Col md={24} lg={8} xxl={6}> <Col md={24} lg={8} xxl={6}>
<Space direction="horizontal"> <Space direction="horizontal">
@ -293,35 +261,289 @@ function Index() {
Get Report Get Report
</Button> </Button>
</Col> </Col>
<Col md={24} lg={10} xxl={11}></Col> <Col md={24} lg={10} xxl={11}>
<Button onClick={() => toPDF()}>Download PDF</Button>
</Col>
</Row> </Row>
<Title level={3}></Title> <Title level={3}></Title>
<Row>
<Row ref={targetRef}>
<Col md={24} lg={24} xxl={24}> <Col md={24} lg={24} xxl={24}>
<Divider>Primary Data</Divider> <Descriptions title="Primary Data" layout="vertical" bordered column={8}>
<Table dataSource={vendorScoresData.PrimaryData} columns={columns_primary} pagination={false} bordered /> <Descriptions.Item label="Groups">{evaluationScores.Groups}</Descriptions.Item>
<Descriptions.Item label="Number of People">{evaluationScores.PersonNum}</Descriptions.Item>
<Descriptions.Item label="Transaction AmountUSD)">{evaluationScores.AmountUSD}</Descriptions.Item>
<Descriptions.Item label="Evaluation Score">{evaluationScores.EvaluationScore}</Descriptions.Item>
<Descriptions.Item label="TP Reviews">{evaluationScores.TPReviews}</Descriptions.Item>
<Descriptions.Item label="TP Reviews Rate">{evaluationScores.TPReviewRate}</Descriptions.Item>
<Descriptions.Item label="Complaints">{evaluationScores.Complaints}</Descriptions.Item>
<Descriptions.Item label="Complaint Rate">{evaluationScores.ComplaintRate}</Descriptions.Item>
</Descriptions>
</Col> </Col>
<Col md={24} lg={24} xxl={24}> <Col md={24} lg={24} xxl={24}>
<Divider>Monthly Data</Divider> <Divider orientation="left">Monthly Data</Divider>
<Table dataSource={vendorScoresData.MonthlyData} columns={columns_month} pagination={false} bordered /> <Table dataSource={vendorScoresData.MonthlyData} columns={columns_month} pagination={false} bordered />
</Col> </Col>
<Col md={24} lg={24} xxl={24}> <Col md={24} lg={24} xxl={24}>
<Divider>地接考核分数</Divider> <Divider orientation="center">
<Table dataSource={dataSource_dmc} columns={columns_dmc} pagination={false} bordered /> 地接考核分数 Final Scores:
<Typography.Title level={3} type="danger">
{evaluationScores.FinalScores}
</Typography.Title>
</Divider>
<div class="ant-table-wrapper css-dev-only-do-not-override-3op25v">
<div class="ant-spin-nested-loading css-dev-only-do-not-override-3op25v">
<div class="ant-spin-container">
<div class="ant-table ant-table-bordered">
<div class="ant-table-container">
<div class="ant-table-content">
<table style={{ textAlign: "center" }}>
<thead class="ant-table-thead">
<tr>
<th class="ant-table-cell" scope="col">
Customer Satisfaction
</th>
<th class="ant-table-cell" scope="col">
3 scores
</th>
<th class="ant-table-cell" scope="col">
4 scores
</th>
<th class="ant-table-cell" scope="col">
5 scores
</th>
<th class="ant-table-cell" scope="col">
Your Scores
</th>
<th class="ant-table-cell" scope="col">
Final Scores
</th>
<th class="ant-table-cell" scope="col">
备注
</th>
</tr>
</thead>
<tbody class="ant-table-tbody">
<tr class="ant-table-row ant-table-row-level-0">
<td class="ant-table-cell">TP review rating</td>
<td class="ant-table-cell">\</td>
<td class="ant-table-cell">30%</td>
<td class="ant-table-cell">60%</td>
<td class="ant-table-cell">{evaluationScores.TPReviewRating}</td>
<td class="ant-table-cell" rowspan="5">
{evaluationScores.AvgCusSatisfaction}
</td>
<td class="ant-table-cell">{evaluationScores.TPReviewRatingText}</td>
</tr>
<tr class="ant-table-row ant-table-row-level-0">
<td class="ant-table-cell">Post tour complaints</td>
<td class="ant-table-cell">1</td>
<td class="ant-table-cell">0</td>
<td class="ant-table-cell">0</td>
<td class="ant-table-cell">{evaluationScores.PostTourComplaints}</td>
<td class="ant-table-cell">{evaluationScores.PostTourComplaintsText}</td>
</tr>
<tr class="ant-table-row ant-table-row-level-0">
<td class="ant-table-cell">Complaints resolved during the tour</td>
<td class="ant-table-cell" colspan="3">
3
</td>
<td class="ant-table-cell">{evaluationScores.ComplaintsDuringTour}</td>
<td class="ant-table-cell">{evaluationScores.ComplaintsDuringTourText}</td>
</tr>
<tr class="ant-table-row ant-table-row-level-0">
<td class="ant-table-cell">Customer photos</td>
<td class="ant-table-cell">\</td>
<td class="ant-table-cell">30%</td>
<td class="ant-table-cell">50%</td>
<td class="ant-table-cell">{evaluationScores.CustomerPhotoRate}</td>
<td class="ant-table-cell">{evaluationScores.CustomerPhotoRateText}</td>
</tr>
<tr class="ant-table-row ant-table-row-level-0">
<td class="ant-table-cell">Evaluation scores</td>
<td class="ant-table-cell" colspan="3">
4.5
</td>
<td class="ant-table-cell">{evaluationScores.EvaluationFormScore}</td>
<td class="ant-table-cell">{evaluationScores.EvaluationFormScoreText}</td>
</tr>
</tbody>
</table>
<br />
<table style={{ textAlign: "center" }}>
<thead class="ant-table-thead">
<tr>
<th class="ant-table-cell" scope="col">
Operator Support & Local resources
</th>
<th class="ant-table-cell" scope="col">
3 scores
</th>
<th class="ant-table-cell" scope="col">
4 scores
</th>
<th class="ant-table-cell" scope="col">
5 scores
</th>
<th class="ant-table-cell" scope="col">
Your Scores
</th>
<th class="ant-table-cell" scope="col">
Final Scores
</th>
<th class="ant-table-cell" scope="col">
备注
</th>
</tr>
</thead>
<tbody class="ant-table-tbody">
<tr class="ant-table-row ant-table-row-level-0">
<td class="ant-table-cell">Response efficiency</td>
<td class="ant-table-cell">1d</td>
<td class="ant-table-cell">6hrs</td>
<td class="ant-table-cell">3hrs</td>
<td class="ant-table-cell">{evaluationScores.ResponseEfficiency}</td>
<td class="ant-table-cell" rowspan="6">
{evaluationScores.AvgLocalResources}
</td>
<td class="ant-table-cell">{evaluationScores.ResponseEfficiencyText}</td>
</tr>
<tr class="ant-table-row ant-table-row-level-0">
<td class="ant-table-cell">Provide suggestions and alternatives</td>
<td class="ant-table-cell">\</td>
<td class="ant-table-cell"></td>
<td class="ant-table-cell"></td>
<td class="ant-table-cell">{evaluationScores.ProvideSuggestions}</td>
<td class="ant-table-cell">{evaluationScores.ProvideSuggestionsText}</td>
</tr>
<tr class="ant-table-row ant-table-row-level-0">
<td class="ant-table-cell">Provide local tourism information</td>
<td class="ant-table-cell">\</td>
<td class="ant-table-cell"></td>
<td class="ant-table-cell"></td>
<td class="ant-table-cell">{evaluationScores.ProvideLocalInfo}</td>
<td class="ant-table-cell">{evaluationScores.ProvideLocalInfoText}</td>
</tr>
<tr class="ant-table-row ant-table-row-level-0">
<td class="ant-table-cell">Assist in developing exclusive products</td>
<td class="ant-table-cell">\</td>
<td class="ant-table-cell">\</td>
<td class="ant-table-cell"></td>
<td class="ant-table-cell">{evaluationScores.ExclusiveProducts}</td>
<td class="ant-table-cell">{evaluationScores.ExclusiveProductsText}</td>
</tr>
<tr class="ant-table-row ant-table-row-level-0">
<td class="ant-table-cell">Dedicated tour guide team for AH</td>
<td class="ant-table-cell">\</td>
<td class="ant-table-cell"></td>
<td class="ant-table-cell"></td>
<td class="ant-table-cell">{evaluationScores.DedicatedTourGuide}</td>
<td class="ant-table-cell">{evaluationScores.DedicatedTourGuideText}</td>
</tr>
<tr class="ant-table-row ant-table-row-level-0">
<td class="ant-table-cell">Partner hotels with contracted rate</td>
<td class="ant-table-cell">\</td>
<td class="ant-table-cell"></td>
<td class="ant-table-cell"></td>
<td class="ant-table-cell">{evaluationScores.PartnerHotels}</td>
<td class="ant-table-cell">{evaluationScores.PartnerHotelsText}</td>
</tr>
</tbody>
</table>
<br />
<table style={{ textAlign: "center" }}>
<thead class="ant-table-thead">
<tr>
<th class="ant-table-cell" scope="col">
Pricing & Settlement 20%
</th>
<th class="ant-table-cell" scope="col">
3 scores
</th>
<th class="ant-table-cell" scope="col">
4 scores
</th>
<th class="ant-table-cell" scope="col">
5 scores
</th>
<th class="ant-table-cell" scope="col">
Your Scores
</th>
<th class="ant-table-cell" scope="col">
Final Scores
</th>
<th class="ant-table-cell" scope="col">
备注
</th>
</tr>
</thead>
<tbody class="ant-table-tbody">
<tr class="ant-table-row ant-table-row-level-0">
<td class="ant-table-cell">Quotation</td>
<td class="ant-table-cell">Package</td>
<td class="ant-table-cell">Day tours</td>
<td class="ant-table-cell">Individual services</td>
<td class="ant-table-cell">{evaluationScores.Quotation}</td>
<td class="ant-table-cell" rowspan="3">
{evaluationScores.AvgPricingAndSettlement}
</td>
<td class="ant-table-cell">{evaluationScores.QuotationText}</td>
</tr>
<tr class="ant-table-row ant-table-row-level-0">
<td class="ant-table-cell">Settlement</td>
<td class="ant-table-cell">Prepayment</td>
<td class="ant-table-cell">Monthly Prepayment</td>
<td class="ant-table-cell">Monthly settlement after the tours</td>
<td class="ant-table-cell">{evaluationScores.Settlement}</td>
<td class="ant-table-cell">{evaluationScores.SettlementText}</td>
</tr>
<tr class="ant-table-row ant-table-row-level-0">
<td class="ant-table-cell">Cancellation policy</td>
<td class="ant-table-cell">30 days</td>
<td class="ant-table-cell">21 days</td>
<td class="ant-table-cell">1 day</td>
<td class="ant-table-cell">{evaluationScores.CancellationPolicy}</td>
<td class="ant-table-cell">{evaluationScores.CancellationPolicyText}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<br />
<List header={<div>Scoring Rules</div>} bordered>
<List.Item>1. The maximum score is 5</List.Item>
<List.Item>
2. The three categories are:
<List>
<List.Item>1). Customer satisfaction (40%)</List.Item>
<List.Item>2). Operator support & local resources (40%) </List.Item>
<List.Item>3). Pricing & settlement (20%)</List.Item>
</List>
</List.Item>
<List.Item>3. For each category, you can only get the corresponding score if you meet the standards of all items under the score.</List.Item>
<List.Item>4. The final score is the sum of the scores of each category multiplied by the proportion of the category.</List.Item>
</List>
</Col> </Col>
<Col md={24} lg={24} xxl={24}> <Col md={24} lg={24} xxl={24}>
<Divider>导游接待情况</Divider> <Divider orientation="left">导游接待情况</Divider>
<Table dataSource={productScoresData.GuideScores} columns={columns_guide} pagination={false} bordered /> <Table dataSource={productScoresData.GuideScores} columns={columns_guide} pagination={false} bordered />
</Col>
<Divider>表扬情况</Divider> <Col md={24} lg={24} xxl={24}>
<Divider orientation="left">表扬情况</Divider>
<Table dataSource={commendScoresData.CommendScores} columns={columns_commend} pagination={false} bordered /> <Table dataSource={commendScoresData.CommendScores} columns={columns_commend} pagination={false} bordered />
</Col>
<Divider>投诉情况</Divider> <Col md={24} lg={24} xxl={24}>
<Divider orientation="left">投诉情况</Divider>
<Table dataSource={commendScoresData.ComplaintScores} columns={columns_commend} pagination={false} bordered /> <Table dataSource={commendScoresData.ComplaintScores} columns={columns_commend} pagination={false} bordered />
</Col>
<Divider>批评建议</Divider> <Col md={24} lg={24} xxl={24}>
<Divider orientation="left">批评建议</Divider>
<Table dataSource={commendScoresData.CriticizeScores} columns={columns_commend} pagination={false} bordered /> <Table dataSource={commendScoresData.CriticizeScores} columns={columns_commend} pagination={false} bordered />
</Col> </Col>
</Row> </Row>

Loading…
Cancel
Save