123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- import { StudentCheckItem } from "./types";
- import { useAppStore } from "@/store";
- import { randomCode } from "@/utils/tool";
- import axios from "axios";
- import Papa from "papaparse";
- const appStore = useAppStore();
- export const allCheckList = async (
- params: AllCheckFilter
- ): Promise<StudentCheckItem[]> => {
- // if (!params.isCheck && !params.imageName) {
- // return Promise.resolve([]);
- // }
- const fname = params.isCheck ? "check" : "success";
- const url = `${appStore.serverUrl}/${fname}.csv?${randomCode()}`;
- let students: StudentCheckItem[] = await fetchAndParseData(url);
- if (params.imageName) {
- students = students.filter((item) => item.imageName === params.imageName);
- }
- const cacheList = await fetchCacheList();
- const data = (students || []).map((item) => {
- return {
- ...item,
- checked: cacheList.includes(item.imageName),
- };
- });
- return Promise.resolve(data);
- };
- export const getExamNumberInfo = async (
- imageName: string
- ): Promise<DataCheckListResult> => {
- const url = `${appStore.serverUrl}/cache/${imageName}.csv?${randomCode()}`;
- const students = await fetchAndParseData(url).catch(() => []);
- if (!students || students.length === 0) {
- return Promise.resolve(null);
- }
- const item = students[0];
- const questions = (item.smda ? item.smda.split("|") : []).map((item) =>
- item.trim().replace(/[\.\?]/g, "")
- );
- return Promise.resolve({ ...students[0], questions });
- };
- export const fetchCacheList = async () => {
- try {
- const res = await axios.get(`${appStore.serverUrl}/cache/`);
- const parser = new DOMParser();
- const doc = parser.parseFromString(res.data, "text/html");
- const links = Array.from(doc.querySelectorAll("a"))
- .map((a) => a.getAttribute("href"))
- .filter((href) => href && /\/cache\/.*\.csv$/.test(href))
- .map((href) => {
- // Extract filename without extension
- const parts = href.split("/");
- const filenameWithExtension = parts[parts.length - 1];
- return filenameWithExtension.replace(".csv", "");
- });
- // console.log("缓存文件列表:", links);
- return links; // Return the extracted list
- } catch (err) {
- console.error("获取失败:", err);
- }
- };
- export const saveCheck = async (data: string[][], filename): Promise<any> => {
- const url = `${appStore.serverUrl}/upload?path=/cache`;
- return uploadCsvData(url, data, filename);
- };
- /**
- * 请求给定远程地址,获取文件流数据(CSV 或 JSON),并解析其内容。
- * @param remoteUrl 远程文件地址
- * @returns 解析后的数据
- */
- export const fetchAndParseData = async (remoteUrl: string): Promise<any> => {
- try {
- const response = await axios.get(remoteUrl, {
- responseType: "text", // Fetch as text to handle both JSON and CSV
- });
- const contentType = response.headers["content-type"];
- let data;
- if (contentType && contentType.includes("application/json")) {
- // Try parsing as JSON
- try {
- data = JSON.parse(response.data);
- } catch (error) {
- console.error("Error parsing JSON:", error);
- throw new Error("Failed to parse JSON data");
- }
- } else if (contentType && contentType.includes("text/csv")) {
- // Try parsing as CSV
- return new Promise((resolve, reject) => {
- Papa.parse(response.data, {
- header: true, // Assume header row
- skipEmptyLines: true,
- complete: (results) => {
- resolve(results.data);
- },
- error: (error: any) => {
- console.error("Error parsing CSV:", error);
- reject(new Error("Failed to parse CSV data"));
- },
- });
- });
- } else {
- // Attempt to guess format or throw error
- try {
- // Try JSON first
- data = JSON.parse(response.data);
- } catch (jsonError) {
- // If JSON fails, try CSV
- return new Promise((resolve, reject) => {
- Papa.parse(response.data, {
- header: true,
- skipEmptyLines: true,
- complete: (results) => {
- if (results.errors.length > 0) {
- console.error("CSV parsing errors:", results.errors);
- // If CSV parsing also has issues, reject
- reject(
- new Error(
- "Failed to parse data: Unknown format or invalid content"
- )
- );
- } else {
- resolve(results.data);
- }
- },
- error: (csvError: any) => {
- console.error("Error parsing CSV:", csvError);
- reject(
- new Error(
- "Failed to parse data: Could not determine format or invalid content"
- )
- );
- },
- });
- });
- }
- }
- return data;
- } catch (error) {
- console.error("Error fetching or parsing data:", error);
- throw new Error("Failed to fetch or parse data from the remote URL");
- }
- };
- /**
- * 构建 CSV 文件内容并上传到指定 URL。
- * @param uploadUrl 上传的目标 URL
- * @param data 要转换为 CSV 并上传的数据数组
- * @param filename 上传的文件名
- * @returns 上传结果
- */
- export const uploadCsvData = async (
- uploadUrl: string,
- data: string[][],
- filename: string = "upload.csv"
- ): Promise<any> => {
- try {
- // Convert data array to CSV string
- const csvString = Papa.unparse(data);
- // Create a Blob from the CSV string
- const blob = new Blob([csvString], { type: "text/csv;charset=utf-8;" });
- // Create FormData and append the Blob as a file
- const formData = new FormData();
- formData.append("file", blob, filename); // 'file' is a common field name for uploads, adjust if needed
- // Upload the FormData using axios
- const response = await axios.post(uploadUrl, formData, {
- headers: {
- "Content-Type": "multipart/form-data",
- },
- });
- return response.data; // Return the response from the server
- } catch (error) {
- console.error("Error building or uploading CSV data:", error);
- throw new Error("Failed to build or upload CSV data");
- }
- };
|