diff --git a/src/components/ImageUploader.jsx b/src/components/ImageUploader.jsx
new file mode 100644
index 0000000..b08c89b
--- /dev/null
+++ b/src/components/ImageUploader.jsx
@@ -0,0 +1,179 @@
+import { useEffect, useState } from "react";
+import { Upload, List } from "antd";
+import { UploadOutlined } from "@ant-design/icons";
+import { Image } from "antd";
+import { fetchJSON } from "@/utils/request";
+import { HT3_HOST } from "@/config";
+
+// 加密函数
+const simple_encrypt = text => {
+ const key = "TPDa*UU8h5%!zS";
+ let encrypted = [];
+ let keyIndex = 0;
+ for (let i = 0; i < text.length; i++) {
+ const charCode = text.charCodeAt(i);
+ const keyCharCode = key.charCodeAt(keyIndex);
+ const encryptedChar = charCode ^ keyCharCode;
+ encrypted.push(encryptedChar);
+ keyIndex = (keyIndex + 1) % key.length;
+ }
+ return encrypted.map(byte => byte.toString(16).padStart(2, "0")).join("");
+};
+
+// 获取图片列表
+const getImageList = async key => {
+ try {
+ const { errcode, result } = await fetchJSON(`${HT3_HOST}/oss/list_unique_key?key=${key}`);
+ if (errcode === 0) {
+ return result
+ .map(file => ({
+ key: file.key,
+ encrypt_key: file.encrypt_key,
+ size: file.size,
+ status: "done",
+ url: file.url,
+ last_modified: file.last_modified,
+ }))
+ .sort((a, b) => {
+ const dateA = new Date(a.last_modified);
+ const dateB = new Date(b.last_modified);
+ return dateA - dateB;
+ });
+ }
+ } catch (error) {
+ console.error("获取图片列表失败", error);
+ }
+ return [];
+};
+
+// 删除图片
+const deleteImage = async key => {
+ try {
+ const { errcode } = await fetchJSON(`${HT3_HOST}/oss/delete_unique_key?key=${key}`, {
+ method: "GET",
+ });
+ return errcode === 0;
+ } catch (error) {
+ console.error("删除图片失败", error);
+ return false;
+ }
+};
+
+// 获取上传签名
+const getSignature = async (file, key, onSuccess, onError) => {
+ try {
+ const { errcode, result } = await fetchJSON(`${HT3_HOST}/oss/signature_unique_key?key=${key}&filename=${file.name}`);
+ if (errcode === 0) {
+ const { method, host, signed_headers } = result;
+ const response = await fetch(host, {
+ method,
+ headers: signed_headers,
+ body: file,
+ });
+ if (response.ok) {
+ onSuccess(response, file);
+ } else {
+ onError(new Error("图片上传失败"));
+ }
+ }
+ } catch (error) {
+ console.error("获取签名失败:", error);
+ onError(error);
+ }
+};
+
+const ImageUploader = props => {
+ const [fileList, setFileList] = useState([]);
+ const [isLoading, setIsLoading] = useState(false);
+ const [previewOpen, setPreviewOpen] = useState(false);
+ const [previewImage, setPreviewImage] = useState("");
+ const key = simple_encrypt(props.osskey);
+
+ // 组件挂载时获取图片列表
+ useEffect(() => {
+ const loadImages = async () => {
+ setIsLoading(true);
+ const images = await getImageList(key);
+ setFileList(images);
+ setIsLoading(false);
+ };
+
+ if (key) {
+ loadImages();
+ }
+ }, [key]);
+
+ // 处理删除操作
+ const handleDelete = async file => {
+ const success = await deleteImage(file.encrypt_key);
+ if (success) {
+ setFileList(prevList => prevList.filter(item => item.key !== file.key));
+ console.log("删除成功");
+ } else {
+ console.error("删除失败");
+ }
+ };
+
+ // 处理上传操作
+ const handleChange = ({ fileList: newFileList }) => {
+ setFileList(newFileList);
+ };
+
+ const handleUploadFile = ({ file, onProgress, onSuccess, onError }) => {
+ getSignature(
+ file,
+ key,
+ (response, file) => {
+ getImageList(key).then(newImages => {
+ setFileList(prevList => {
+ // 找到当前正在上传的文件并移除
+ const index = prevList.findIndex(item => item.status === "uploading");
+ if (index !== -1) {
+ const newPrevList = [...prevList];
+ newPrevList.splice(index, 1);
+ // 找出新增元素
+ const newItems = newImages.filter(newItem => !newPrevList.some(prevItem => prevItem.key === newItem.key));
+ // 将新增元素添加到过滤后的列表末尾
+ return [...newPrevList, ...newItems];
+ }
+ return prevList;
+ });
+ });
+ },
+ onError
+ );
+ };
+
+ const handlePreview = file => {
+ if (!file.url) {
+ return;
+ }
+ setPreviewImage(file.url);
+ setPreviewOpen(true);
+ };
+
+ return (
+ <>
+
+
+
+
+ {previewImage && (
+ setPreviewOpen(visible),
+ afterOpenChange: visible => !visible && setPreviewImage(""),
+ }}
+ src={previewImage}
+ />
+ )}
+ >
+ );
+};
+
+export default ImageUploader;
diff --git a/src/config.js b/src/config.js
index dc8ad02..25c1040 100644
--- a/src/config.js
+++ b/src/config.js
@@ -2,6 +2,7 @@ export const PROJECT_NAME = "GHHub";
// mode: test,内部测试使用
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 HT3_HOST = 'https://hub.globalhighlights.com/ht3.0'
export const OVERSEA_HOST = 'https://ht20-p9axztuwd7x8a7.mycht.cn'
diff --git a/src/stores/Trainticket.js b/src/stores/Trainticket.js
index 8f0a1bf..d83371e 100644
--- a/src/stores/Trainticket.js
+++ b/src/stores/Trainticket.js
@@ -133,6 +133,7 @@ const trainTicketStore = create((set, get) => ({
const searchParams = {
VEI_SN: VEI_SN,
GRI_SN: GRI_SN,
+ ServiceType: 2,
};
const { errcode, result } = await fetchJSON(`${HT_HOST}/Service_BaseInfoWeb/GetVeiFlightPlanChange`, searchParams);
const _result = errcode !== 0 ? [] : result;
diff --git a/src/views/trainticket/plan.jsx b/src/views/trainticket/plan.jsx
index dbd899e..7933724 100644
--- a/src/views/trainticket/plan.jsx
+++ b/src/views/trainticket/plan.jsx
@@ -9,6 +9,8 @@ import trainTicketStore from "@/stores/Trainticket";
import { usingStorage } from "@/hooks/usingStorage";
import BackBtn from "@/components/BackBtn";
import { station_names } from "@/views/trainticket/station_name";
+import { Upload } from "antd";
+import ImageUploader from "@/components/ImageUploader";
const TrainticketPlan = props => {
const { coli_sn, gri_sn } = useParams();
@@ -243,7 +245,7 @@ const TrainticketPlan = props => {
-
+
@@ -270,6 +272,15 @@ const TrainticketPlan = props => {
+
+ 车票图片
+
+
+
+
+
+
+