fix
parent
e55b4eaf80
commit
e3c66c1f71
|
|
@ -15,6 +15,7 @@
|
||||||
"build:development": "cross-env NODE_ENV=development npm run build",
|
"build:development": "cross-env NODE_ENV=development npm run build",
|
||||||
"build:production": "cross-env NODE_ENV=production npm run build",
|
"build:production": "cross-env NODE_ENV=production npm run build",
|
||||||
"code-optimization": "node node_modules/@cqsjjb/scripts/code-optimization.js",
|
"code-optimization": "node node_modules/@cqsjjb/scripts/code-optimization.js",
|
||||||
|
"gen:districts": "node scripts/gen-china-districts.js",
|
||||||
"lint": "eslint --ext .js,.jsx,.tsx --fix src",
|
"lint": "eslint --ext .js,.jsx,.tsx --fix src",
|
||||||
"test:enterprise-info": "node docs/test-reports/测试用例/test-enterprise-info-api.mjs",
|
"test:enterprise-info": "node docs/test-reports/测试用例/test-enterprise-info-api.mjs",
|
||||||
"test:enterprise-info:granular": "node docs/test-reports/测试用例/test-enterprise-info-granular.mjs"
|
"test:enterprise-info:granular": "node docs/test-reports/测试用例/test-enterprise-info-granular.mjs"
|
||||||
|
|
@ -32,8 +33,6 @@
|
||||||
"docxtemplater": "latest",
|
"docxtemplater": "latest",
|
||||||
"echarts": "^6.1.0",
|
"echarts": "^6.1.0",
|
||||||
"history": "^4.10.1",
|
"history": "^4.10.1",
|
||||||
|
|
||||||
|
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"pizzip": "latest",
|
"pizzip": "latest",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
|
@ -48,6 +47,7 @@
|
||||||
"@babel/preset-react": "^7.29.7",
|
"@babel/preset-react": "^7.29.7",
|
||||||
"@cqsjjb/scripts": "latest",
|
"@cqsjjb/scripts": "latest",
|
||||||
"@eslint-react/eslint-plugin": "^2.2.2",
|
"@eslint-react/eslint-plugin": "^2.2.2",
|
||||||
|
"@province-city-china/data": "^8.5.8",
|
||||||
"babel-loader": "^9.1.3",
|
"babel-loader": "^9.1.3",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"css-loader": "^6.8.1",
|
"css-loader": "^6.8.1",
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
* 生成全国县级行政区划快照:node scripts/gen-china-districts.js
|
||||||
|
* 数据源:devDependency @province-city-china/data(GB/T 2260,省市区四级全量)
|
||||||
|
* 输出:src/enumerate/chinaDistricts.json,仅保留县级约 3300 条([code, 名称, 省+市],160KB 左右)
|
||||||
|
* 行政区划调整后重新执行本脚本即可刷新快照
|
||||||
|
*/
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const all = require("@province-city-china/data");
|
||||||
|
|
||||||
|
/** 省级名称表:code 形如 XX0000 */
|
||||||
|
const provinceNameByCode = {};
|
||||||
|
/** 地级名称表:code 形如 XXYY00 */
|
||||||
|
const cityNameByCode = {};
|
||||||
|
all.forEach((item) => {
|
||||||
|
const isProvince = item.city === 0 && item.area === 0 && item.town === 0;
|
||||||
|
const isCity = item.city !== 0 && item.area === 0 && item.town === 0;
|
||||||
|
if (isProvince) provinceNameByCode[item.province] = item.name;
|
||||||
|
if (isCity) cityNameByCode[item.province + item.city] = item.name;
|
||||||
|
});
|
||||||
|
|
||||||
|
const districts = all
|
||||||
|
.filter((item) => item.city !== 0 && item.area !== 0 && item.town === 0)
|
||||||
|
.map((item) => {
|
||||||
|
const province = provinceNameByCode[item.province] || "";
|
||||||
|
const city = cityNameByCode[item.province + item.city] || "";
|
||||||
|
// 直辖市等省市同名时不重复拼接
|
||||||
|
const region = city && city !== province ? `${province}${city}` : province;
|
||||||
|
return [item.code, item.name, region];
|
||||||
|
});
|
||||||
|
|
||||||
|
const outFile = path.join(__dirname, "../src/enumerate/chinaDistricts.json");
|
||||||
|
fs.writeFileSync(outFile, `${JSON.stringify(districts)}\n`, "utf8");
|
||||||
|
console.log(`已生成 ${path.relative(process.cwd(), outFile)}:${districts.length} 条`);
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { declareRequest } from "@cqsjjb/jjb-dva-runtime";
|
import { declareRequest } from "@cqsjjb/jjb-dva-runtime";
|
||||||
|
|
||||||
/** 教育培训 — 培训课件管理 / 培训课程管理 / 班级管理 */
|
/** 教育培训 — 培训课件管理 / 培训课程管理 / 班级管理 / 试卷管理(试卷接口统一声明在 courseware 命名空间) */
|
||||||
|
|
||||||
/** 分页查询课件 */
|
/** 分页查询课件 */
|
||||||
export const coursewarePage = declareRequest(
|
export const coursewarePage = declareRequest(
|
||||||
|
|
@ -222,3 +222,102 @@ export const studentExamPaperInfo = declareRequest(
|
||||||
"studentExamPaperLoading",
|
"studentExamPaperLoading",
|
||||||
"Get > /safetyEval/paperExam/exam/info",
|
"Get > /safetyEval/paperExam/exam/info",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* ------------------------------ 试卷管理 ------------------------------ */
|
||||||
|
|
||||||
|
/** 分页查询试卷 */
|
||||||
|
export const paperPage = declareRequest(
|
||||||
|
"paperLoading",
|
||||||
|
"Get > /safetyEval/paper/page",
|
||||||
|
"paperList: [] | res.data || [] & paperTotal: 0 | res.total || 0",
|
||||||
|
);
|
||||||
|
|
||||||
|
/** 试卷基本信息查询(不含试题列表) */
|
||||||
|
export const paperBasicInfo = declareRequest(
|
||||||
|
"paperBasicLoading",
|
||||||
|
"Get > /safetyEval/paper/paper/basic/info",
|
||||||
|
);
|
||||||
|
|
||||||
|
/** 试卷考试信息查询(基本信息 + 试题列表) */
|
||||||
|
export const paperExamInfo = declareRequest(
|
||||||
|
"paperExamLoading",
|
||||||
|
"Get > /safetyEval/paper/paper/exam/info",
|
||||||
|
);
|
||||||
|
|
||||||
|
/** 自动生成试卷(按课件与题型规则抽题组卷) */
|
||||||
|
export const paperRuleGenerate = declareRequest(
|
||||||
|
"paperRuleLoading",
|
||||||
|
"Post > @/safetyEval/paper/courseware/question/rule",
|
||||||
|
);
|
||||||
|
|
||||||
|
/** 修改试卷基本信息 */
|
||||||
|
export const paperUpdateBasic = declareRequest(
|
||||||
|
"paperUpdateLoading",
|
||||||
|
"Put > @/safetyEval/paper/update/basic",
|
||||||
|
);
|
||||||
|
|
||||||
|
/** 删除试卷 */
|
||||||
|
export const paperDelete = declareRequest(
|
||||||
|
"paperLoading",
|
||||||
|
"Delete > @/safetyEval/paper/{id}",
|
||||||
|
);
|
||||||
|
|
||||||
|
/** 复制试卷 */
|
||||||
|
export const paperCopy = declareRequest(
|
||||||
|
"paperCopyLoading",
|
||||||
|
"Post > @/safetyEval/paper/copy",
|
||||||
|
);
|
||||||
|
|
||||||
|
/** 导入试题模板地址 */
|
||||||
|
export const paperImportTemplate = declareRequest(
|
||||||
|
"paperTemplateLoading",
|
||||||
|
"Get > /safetyEval/paper/import/template",
|
||||||
|
'paperTemplateUrl: "" | res.data || ""',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新建试卷-导入试题(multipart,declareRequest 仅支持 json,手动 fetch)
|
||||||
|
* @param {FormData} payload paperName/paperTotalScore/paperPassScore/examTime/file
|
||||||
|
*/
|
||||||
|
export async function paperImport(payload) {
|
||||||
|
const res = await fetch(
|
||||||
|
`${window.process.env.app.API_HOST}/safetyEval/paper/import`,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: { token: sessionStorage.getItem("token") },
|
||||||
|
body: payload,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return res.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 试卷试题分页查询 */
|
||||||
|
export const paperQuestionPage = declareRequest(
|
||||||
|
"paperQuestionLoading",
|
||||||
|
"Get > /safetyEval/paper/paper/question/page",
|
||||||
|
"paperQuestionList: [] | res.data || [] & paperQuestionTotal: 0 | res.total || 0",
|
||||||
|
);
|
||||||
|
|
||||||
|
/** 删除试卷习题 */
|
||||||
|
export const paperQuestionDelete = declareRequest(
|
||||||
|
"paperQuestionLoading",
|
||||||
|
"Post > @/safetyEval/paperQuestionRel/delete",
|
||||||
|
);
|
||||||
|
|
||||||
|
/** 新增试卷试题(习题) */
|
||||||
|
export const paperQuestionSave = declareRequest(
|
||||||
|
"paperQuestionSaveLoading",
|
||||||
|
"Post > @/safetyEval/paperQuestionRel/save",
|
||||||
|
);
|
||||||
|
|
||||||
|
/** 查询试卷习题详情(分值取自试卷试题关系) */
|
||||||
|
export const paperQuestionFind = declareRequest(
|
||||||
|
"questionFindLoading",
|
||||||
|
"Get > /safetyEval/paperQuestionRel/find",
|
||||||
|
);
|
||||||
|
|
||||||
|
/** 编辑试卷习题 */
|
||||||
|
export const paperQuestionModify = declareRequest(
|
||||||
|
"questionModifyLoading",
|
||||||
|
"Post > @/safetyEval/paperQuestionRel/modify",
|
||||||
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
import { declareRequest } from "@cqsjjb/jjb-dva-runtime";
|
|
||||||
|
|
||||||
/** 教育培训 — 试卷管理 */
|
|
||||||
|
|
||||||
/** 分页查询试卷 */
|
|
||||||
export const paperPage = declareRequest(
|
|
||||||
"paperLoading",
|
|
||||||
"Get > /safetyEval/paper/page",
|
|
||||||
"paperList: [] | res.data || [] & paperTotal: 0 | res.total || 0",
|
|
||||||
);
|
|
||||||
|
|
||||||
/** 试卷基本信息查询(不含试题列表) */
|
|
||||||
export const paperBasicInfo = declareRequest(
|
|
||||||
"paperBasicLoading",
|
|
||||||
"Get > /safetyEval/paper/paper/basic/info",
|
|
||||||
);
|
|
||||||
|
|
||||||
/** 试卷考试信息查询(基本信息 + 试题列表) */
|
|
||||||
export const paperExamInfo = declareRequest(
|
|
||||||
"paperExamLoading",
|
|
||||||
"Get > /safetyEval/paper/paper/exam/info",
|
|
||||||
);
|
|
||||||
|
|
||||||
/** 自动生成试卷(按课件与题型规则抽题组卷) */
|
|
||||||
export const paperRuleGenerate = declareRequest(
|
|
||||||
"paperRuleLoading",
|
|
||||||
"Post > @/safetyEval/paper/courseware/question/rule",
|
|
||||||
);
|
|
||||||
|
|
||||||
/** 修改试卷基本信息 */
|
|
||||||
export const paperUpdateBasic = declareRequest(
|
|
||||||
"paperUpdateLoading",
|
|
||||||
"Put > @/safetyEval/paper/update/basic",
|
|
||||||
);
|
|
||||||
|
|
||||||
/** 删除试卷 */
|
|
||||||
export const paperDelete = declareRequest(
|
|
||||||
"paperLoading",
|
|
||||||
"Delete > @/safetyEval/paper/{id}",
|
|
||||||
);
|
|
||||||
|
|
||||||
/** 复制试卷 */
|
|
||||||
export const paperCopy = declareRequest(
|
|
||||||
"paperCopyLoading",
|
|
||||||
"Post > @/safetyEval/paper/copy",
|
|
||||||
);
|
|
||||||
|
|
||||||
/** 导入试题模板地址 */
|
|
||||||
export const paperImportTemplate = declareRequest(
|
|
||||||
"paperTemplateLoading",
|
|
||||||
"Get > /safetyEval/paper/import/template",
|
|
||||||
'paperTemplateUrl: "" | res.data || ""',
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新建试卷-导入试题(multipart,declareRequest 仅支持 json,手动 fetch)
|
|
||||||
* @param {FormData} payload paperName/paperTotalScore/paperPassScore/examTime/file
|
|
||||||
*/
|
|
||||||
export async function paperImport(payload) {
|
|
||||||
const res = await fetch(
|
|
||||||
`${window.process.env.app.API_HOST}/safetyEval/paper/import`,
|
|
||||||
{
|
|
||||||
method: "POST",
|
|
||||||
headers: { token: sessionStorage.getItem("token") },
|
|
||||||
body: payload,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
return res.json();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 试卷试题分页查询 */
|
|
||||||
export const paperQuestionPage = declareRequest(
|
|
||||||
"paperQuestionLoading",
|
|
||||||
"Get > /safetyEval/paper/paper/question/page",
|
|
||||||
"paperQuestionList: [] | res.data || [] & paperQuestionTotal: 0 | res.total || 0",
|
|
||||||
);
|
|
||||||
|
|
||||||
/** 删除试卷习题 */
|
|
||||||
export const paperQuestionDelete = declareRequest(
|
|
||||||
"paperQuestionLoading",
|
|
||||||
"Post > @/safetyEval/paperQuestionRel/delete",
|
|
||||||
);
|
|
||||||
|
|
||||||
/** 新增试卷试题(习题) */
|
|
||||||
export const paperQuestionSave = declareRequest(
|
|
||||||
"paperQuestionSaveLoading",
|
|
||||||
"Post > @/safetyEval/paperQuestionRel/save",
|
|
||||||
);
|
|
||||||
|
|
||||||
/** 查询试卷习题详情(分值取自试卷试题关系) */
|
|
||||||
export const paperQuestionFind = declareRequest(
|
|
||||||
"questionFindLoading",
|
|
||||||
"Get > /safetyEval/paperQuestionRel/find",
|
|
||||||
);
|
|
||||||
|
|
||||||
/** 编辑试卷习题 */
|
|
||||||
export const paperQuestionModify = declareRequest(
|
|
||||||
"questionModifyLoading",
|
|
||||||
"Post > @/safetyEval/paperQuestionRel/modify",
|
|
||||||
);
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -8,7 +8,6 @@ export const NS_PERSNONEL_CERTFICATE = defineNamespace("personnelCertificate");
|
||||||
export const NS_CORP_CERTIFICATE = defineNamespace("corpCertificate");
|
export const NS_CORP_CERTIFICATE = defineNamespace("corpCertificate");
|
||||||
export const NS_USER_CERTIFICATE = defineNamespace("userCertificate");
|
export const NS_USER_CERTIFICATE = defineNamespace("userCertificate");
|
||||||
export const NS_COURSEWARE = defineNamespace("courseware");
|
export const NS_COURSEWARE = defineNamespace("courseware");
|
||||||
export const NS_PAPER = defineNamespace("paper");
|
|
||||||
export const NS_ORG_INFO = defineNamespace("orgInfo");
|
export const NS_ORG_INFO = defineNamespace("orgInfo");
|
||||||
export const NS_ORG_QUALIFICATION_CERT = defineNamespace("orgQualificationCert");
|
export const NS_ORG_QUALIFICATION_CERT = defineNamespace("orgQualificationCert");
|
||||||
export const NS_ORG_DEPARTMENT = defineNamespace("orgDepartment");
|
export const NS_ORG_DEPARTMENT = defineNamespace("orgDepartment");
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
/**
|
||||||
|
* 全国备案属地下拉选项
|
||||||
|
* 数据来源:./chinaDistricts.json(由 `pnpm gen:districts` 从 @province-city-china/data 生成的县级快照)
|
||||||
|
* value 采用「省市区县全路径」(如“重庆市万州区”),避免同名区县(如北京/长春的“朝阳区”)冲突,
|
||||||
|
* 与 filingTerritoryName 直接存名称字符串的口径保持一致。
|
||||||
|
*/
|
||||||
|
import CHINA_DISTRICTS from "./chinaDistricts.json";
|
||||||
|
|
||||||
|
/** [code, 区县名, 省+市] → { label, value } */
|
||||||
|
export const NATIONWIDE_DISTRICTS = CHINA_DISTRICTS.map(
|
||||||
|
([, name, region]) => ({
|
||||||
|
label: region ? `${name}(${region})` : name,
|
||||||
|
value: region ? `${region}${name}` : name,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
@ -17,7 +17,7 @@ import {
|
||||||
import { DownloadOutlined, PlusOutlined } from "@ant-design/icons";
|
import { DownloadOutlined, PlusOutlined } from "@ant-design/icons";
|
||||||
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
|
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
|
||||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||||
import { NS_COURSEWARE, NS_PAPER } from "~/enumerate/namespace";
|
import { NS_COURSEWARE } from "~/enumerate/namespace";
|
||||||
import {
|
import {
|
||||||
CLASS_PAPER_TYPE_MAP,
|
CLASS_PAPER_TYPE_MAP,
|
||||||
CLASS_PAPER_TYPE_OPTIONS,
|
CLASS_PAPER_TYPE_OPTIONS,
|
||||||
|
|
@ -156,7 +156,7 @@ function PaperConfigModal({
|
||||||
// 打开且有绑定试卷时才查询基本信息;paperId 变化(换绑)后重新查询
|
// 打开且有绑定试卷时才查询基本信息;paperId 变化(换绑)后重新查询
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) {
|
if (!open) {
|
||||||
resetModelState?.(NS_PAPER, { paperBasicLoading: false });
|
resetModelState?.(NS_COURSEWARE, { paperBasicLoading: false });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setBasicInfo(null);
|
setBasicInfo(null);
|
||||||
|
|
@ -285,7 +285,7 @@ function PaperAddModal({
|
||||||
// 切换类型/打开时加载数据:平台试卷查分页,自动生成查课件下拉
|
// 切换类型/打开时加载数据:平台试卷查分页,自动生成查课件下拉
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) {
|
if (!open) {
|
||||||
resetModelState?.(NS_PAPER, {
|
resetModelState?.(NS_COURSEWARE, {
|
||||||
paperLoading: false,
|
paperLoading: false,
|
||||||
paperRuleLoading: false,
|
paperRuleLoading: false,
|
||||||
});
|
});
|
||||||
|
|
@ -660,7 +660,7 @@ function PaperExamPreviewModal({
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) {
|
if (!open) {
|
||||||
resetModelState?.(NS_PAPER, { paperExamLoading: false });
|
resetModelState?.(NS_COURSEWARE, { paperExamLoading: false });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!paperId) return;
|
if (!paperId) return;
|
||||||
|
|
@ -772,4 +772,4 @@ function PaperExamPreviewModal({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Connect([NS_COURSEWARE, NS_PAPER], true)(ClassPaperConfig);
|
export default Connect([NS_COURSEWARE], true)(ClassPaperConfig);
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,12 @@ import {
|
||||||
Table,
|
Table,
|
||||||
message,
|
message,
|
||||||
} from "antd";
|
} from "antd";
|
||||||
import { DeleteOutlined, ImportOutlined, PlusOutlined } from "@ant-design/icons";
|
import {
|
||||||
|
DeleteOutlined,
|
||||||
|
DownloadOutlined,
|
||||||
|
ImportOutlined,
|
||||||
|
PlusOutlined,
|
||||||
|
} from "@ant-design/icons";
|
||||||
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
||||||
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
|
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
|
||||||
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
||||||
|
|
@ -102,6 +107,31 @@ function CoursewareQuestionPage(props) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 下载试题导入模板(复用试卷导入模板接口):跨域地址下 a.download 无效,fetch 转 blob 后触发下载 */
|
||||||
|
const onDownloadTemplate = async () => {
|
||||||
|
const res = await props.paperImportTemplate();
|
||||||
|
const url = res?.paperTemplateUrl || res?.data;
|
||||||
|
if (!url) {
|
||||||
|
message.warning("模板地址未配置");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const fileRes = await fetch(url);
|
||||||
|
if (!fileRes.ok) throw new Error(`HTTP ${fileRes.status}`);
|
||||||
|
const blobUrl = window.URL.createObjectURL(await fileRes.blob());
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.href = blobUrl;
|
||||||
|
link.download = "试题导入模板.xlsx";
|
||||||
|
link.style.display = "none";
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
link.remove();
|
||||||
|
window.URL.revokeObjectURL(blobUrl);
|
||||||
|
} catch {
|
||||||
|
message.error("模板下载失败");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: "序号",
|
title: "序号",
|
||||||
|
|
@ -161,6 +191,13 @@ function CoursewareQuestionPage(props) {
|
||||||
>
|
>
|
||||||
新增
|
新增
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
icon={<DownloadOutlined />}
|
||||||
|
loading={props.courseware?.paperTemplateLoading}
|
||||||
|
onClick={onDownloadTemplate}
|
||||||
|
>
|
||||||
|
下载导入模板
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
icon={<ImportOutlined />}
|
icon={<ImportOutlined />}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import SearchForm from "~/components/SearchForm";
|
||||||
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
||||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||||
import { tools } from "@cqsjjb/jjb-common-lib";
|
import { tools } from "@cqsjjb/jjb-common-lib";
|
||||||
import { NS_PAPER, NS_COURSEWARE } from "~/enumerate/namespace";
|
import { NS_COURSEWARE } from "~/enumerate/namespace";
|
||||||
import { QUESTION_TYPE_MAP, QUESTION_TYPE_OPTIONS } from "~/enumerate/constant";
|
import { QUESTION_TYPE_MAP, QUESTION_TYPE_OPTIONS } from "~/enumerate/constant";
|
||||||
|
|
||||||
const { router } = tools;
|
const { router } = tools;
|
||||||
|
|
@ -48,12 +48,12 @@ function PaperQuestionPage(props) {
|
||||||
const [editQuestion, setEditQuestion] = useState(null);
|
const [editQuestion, setEditQuestion] = useState(null);
|
||||||
const paperId = router.query?.paperId;
|
const paperId = router.query?.paperId;
|
||||||
const paperName = router.query?.paperName;
|
const paperName = router.query?.paperName;
|
||||||
const { paper, courseware } = props;
|
const { courseware } = props;
|
||||||
const {
|
const {
|
||||||
paperQuestionList: dataSource,
|
paperQuestionList: dataSource,
|
||||||
paperQuestionTotal: total,
|
paperQuestionTotal: total,
|
||||||
paperQuestionLoading: loading,
|
paperQuestionLoading: loading,
|
||||||
} = paper || {};
|
} = courseware || {};
|
||||||
const coursewareOptions = (courseware?.coursewareList || []).map((c) => ({
|
const coursewareOptions = (courseware?.coursewareList || []).map((c) => ({
|
||||||
label: c.coursewareName,
|
label: c.coursewareName,
|
||||||
value: c.id,
|
value: c.id,
|
||||||
|
|
@ -226,10 +226,10 @@ function PaperQuestionPage(props) {
|
||||||
open={addOpen}
|
open={addOpen}
|
||||||
mode="add"
|
mode="add"
|
||||||
coursewareOptions={coursewareOptions}
|
coursewareOptions={coursewareOptions}
|
||||||
confirmLoading={paper?.paperQuestionSaveLoading}
|
confirmLoading={courseware?.paperQuestionSaveLoading}
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
setAddOpen(false);
|
setAddOpen(false);
|
||||||
props.resetModelState(NS_PAPER, { paperQuestionSaveLoading: false });
|
props.resetModelState(NS_COURSEWARE, { paperQuestionSaveLoading: false });
|
||||||
}}
|
}}
|
||||||
onSubmit={async (values) => {
|
onSubmit={async (values) => {
|
||||||
const res = await props.paperQuestionSave({ paperId, ...values });
|
const res = await props.paperQuestionSave({ paperId, ...values });
|
||||||
|
|
@ -247,12 +247,12 @@ function PaperQuestionPage(props) {
|
||||||
paperId={paperId}
|
paperId={paperId}
|
||||||
questionId={editQuestion?.id}
|
questionId={editQuestion?.id}
|
||||||
coursewareOptions={coursewareOptions}
|
coursewareOptions={coursewareOptions}
|
||||||
findLoading={paper?.questionFindLoading}
|
findLoading={courseware?.questionFindLoading}
|
||||||
confirmLoading={paper?.questionModifyLoading}
|
confirmLoading={courseware?.questionModifyLoading}
|
||||||
questionFind={props.paperQuestionFind}
|
questionFind={props.paperQuestionFind}
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
setEditQuestion(null);
|
setEditQuestion(null);
|
||||||
props.resetModelState(NS_PAPER, {
|
props.resetModelState(NS_COURSEWARE, {
|
||||||
questionFindLoading: false,
|
questionFindLoading: false,
|
||||||
questionModifyLoading: false,
|
questionModifyLoading: false,
|
||||||
});
|
});
|
||||||
|
|
@ -533,6 +533,6 @@ function QuestionFormModal({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Connect([NS_PAPER, NS_COURSEWARE], true)(
|
export default Connect([NS_COURSEWARE], true)(
|
||||||
AntdTableFuncControl(PaperQuestionPage),
|
AntdTableFuncControl(PaperQuestionPage),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@ import SearchForm from "~/components/SearchForm";
|
||||||
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
||||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||||
import { tools } from "@cqsjjb/jjb-common-lib";
|
import { tools } from "@cqsjjb/jjb-common-lib";
|
||||||
import { NS_PAPER } from "~/enumerate/namespace";
|
import { NS_COURSEWARE } from "~/enumerate/namespace";
|
||||||
import { PAPER_TYPE_MAP, PAPER_TYPE_OPTIONS } from "~/enumerate/constant";
|
import { PAPER_TYPE_MAP, PAPER_TYPE_OPTIONS } from "~/enumerate/constant";
|
||||||
import { paperImport } from "~/api/paper";
|
import { paperImport } from "~/api/courseware";
|
||||||
|
|
||||||
const { router } = tools;
|
const { router } = tools;
|
||||||
const { RangePicker } = DatePicker;
|
const { RangePicker } = DatePicker;
|
||||||
|
|
@ -53,9 +53,12 @@ function PaperManagePage(props) {
|
||||||
const [editRecord, setEditRecord] = useState(null);
|
const [editRecord, setEditRecord] = useState(null);
|
||||||
const [copyRecord, setCopyRecord] = useState(null);
|
const [copyRecord, setCopyRecord] = useState(null);
|
||||||
const [importOpen, setImportOpen] = useState(false);
|
const [importOpen, setImportOpen] = useState(false);
|
||||||
const { paper } = props;
|
const { courseware } = props;
|
||||||
const { paperList: dataSource, paperTotal: total, paperLoading: loading } =
|
const {
|
||||||
paper || {};
|
paperList: dataSource,
|
||||||
|
paperTotal: total,
|
||||||
|
paperLoading: loading,
|
||||||
|
} = courseware || {};
|
||||||
|
|
||||||
const handleSearch = () => {
|
const handleSearch = () => {
|
||||||
props.paperPage(router.query);
|
props.paperPage(router.query);
|
||||||
|
|
@ -74,14 +77,28 @@ function PaperManagePage(props) {
|
||||||
handleSearch();
|
handleSearch();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
/** 下载导入模板 */
|
/** 下载导入模板:跨域地址下 a.download 无效,fetch 转 blob 后触发下载 */
|
||||||
const onDownloadTemplate = async () => {
|
const onDownloadTemplate = async () => {
|
||||||
const res = await props.paperImportTemplate();
|
const res = await props.paperImportTemplate();
|
||||||
const url = res?.paperTemplateUrl || res?.data;
|
const url = res?.paperTemplateUrl || res?.data;
|
||||||
if (url) {
|
if (!url) {
|
||||||
window.open(url);
|
|
||||||
} else {
|
|
||||||
message.warning("模板地址未配置");
|
message.warning("模板地址未配置");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const fileRes = await fetch(url);
|
||||||
|
if (!fileRes.ok) throw new Error(`HTTP ${fileRes.status}`);
|
||||||
|
const blobUrl = window.URL.createObjectURL(await fileRes.blob());
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.href = blobUrl;
|
||||||
|
link.download = "试题导入模板.xlsx";
|
||||||
|
link.style.display = "none";
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
link.remove();
|
||||||
|
window.URL.revokeObjectURL(blobUrl);
|
||||||
|
} catch {
|
||||||
|
message.error("模板下载失败");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -186,7 +203,7 @@ function PaperManagePage(props) {
|
||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
icon={<DownloadOutlined />}
|
icon={<DownloadOutlined />}
|
||||||
loading={paper?.paperTemplateLoading}
|
loading={courseware?.paperTemplateLoading}
|
||||||
onClick={onDownloadTemplate}
|
onClick={onDownloadTemplate}
|
||||||
>
|
>
|
||||||
下载导入模板
|
下载导入模板
|
||||||
|
|
@ -261,10 +278,10 @@ function PaperManagePage(props) {
|
||||||
open={!!editRecord}
|
open={!!editRecord}
|
||||||
title="编辑试卷"
|
title="编辑试卷"
|
||||||
initial={editRecord}
|
initial={editRecord}
|
||||||
confirmLoading={paper?.paperUpdateLoading}
|
confirmLoading={courseware?.paperUpdateLoading}
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
setEditRecord(null);
|
setEditRecord(null);
|
||||||
props.resetModelState(NS_PAPER, { paperUpdateLoading: false });
|
props.resetModelState(NS_COURSEWARE, { paperUpdateLoading: false });
|
||||||
}}
|
}}
|
||||||
onSubmit={async (values) => {
|
onSubmit={async (values) => {
|
||||||
const res = await props.paperUpdateBasic({
|
const res = await props.paperUpdateBasic({
|
||||||
|
|
@ -285,10 +302,10 @@ function PaperManagePage(props) {
|
||||||
initial={
|
initial={
|
||||||
copyRecord && { ...copyRecord, paperName: `${copyRecord.paperName}-副本` }
|
copyRecord && { ...copyRecord, paperName: `${copyRecord.paperName}-副本` }
|
||||||
}
|
}
|
||||||
confirmLoading={paper?.paperCopyLoading}
|
confirmLoading={courseware?.paperCopyLoading}
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
setCopyRecord(null);
|
setCopyRecord(null);
|
||||||
props.resetModelState(NS_PAPER, { paperCopyLoading: false });
|
props.resetModelState(NS_COURSEWARE, { paperCopyLoading: false });
|
||||||
}}
|
}}
|
||||||
onSubmit={async (values) => {
|
onSubmit={async (values) => {
|
||||||
const res = await props.paperCopy({ id: copyRecord?.id, ...values });
|
const res = await props.paperCopy({ id: copyRecord?.id, ...values });
|
||||||
|
|
@ -525,6 +542,6 @@ function ImportPaperModal({ open, onCancel, onSuccess }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Connect([NS_PAPER], true)(
|
export default Connect([NS_COURSEWARE], true)(
|
||||||
AntdTableFuncControl(PaperManagePage),
|
AntdTableFuncControl(PaperManagePage),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
import { Form, Input, InputNumber, Row, Col, Select, Checkbox } from "antd";
|
import { Form, Input, InputNumber, Row, Col, Select, Checkbox } from "antd";
|
||||||
import { CHONGQING_DISTRICTS } from "~/enumerate/enterpriseOptions";
|
import { CHONGQING_DISTRICTS } from "~/enumerate/enterpriseOptions";
|
||||||
|
import { NATIONWIDE_DISTRICTS } from "~/enumerate/nationwideTerritory";
|
||||||
import useIndustryOptions from "~/hooks/useIndustryOptions";
|
import useIndustryOptions from "~/hooks/useIndustryOptions";
|
||||||
import { FILING_UNIT_TYPE_OPTIONS } from "~/enumerate/qualFilingOptions";
|
import { FILING_UNIT_TYPE_OPTIONS } from "~/enumerate/qualFilingOptions";
|
||||||
import AttachmentUpload from "~/components/AttachmentUpload";
|
import AttachmentUpload from "~/components/AttachmentUpload";
|
||||||
|
|
||||||
export default function BasicInfoStep({ form, disabled, mode }) {
|
export default function BasicInfoStep({ form, disabled, mode }) {
|
||||||
const industryOptions = useIndustryOptions();
|
const industryOptions = useIndustryOptions();
|
||||||
|
// 资质申请仅限重庆区县;备案/变更可选全国区县
|
||||||
|
const territoryOptions =
|
||||||
|
mode === "application" ? CHONGQING_DISTRICTS : NATIONWIDE_DISTRICTS;
|
||||||
return (
|
return (
|
||||||
<Form form={form} layout="vertical" disabled={disabled}>
|
<Form form={form} layout="vertical" disabled={disabled}>
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
|
|
@ -27,9 +31,12 @@ export default function BasicInfoStep({ form, disabled, mode }) {
|
||||||
rules={[{ required: !disabled, message: "请选择备案属地" }]}
|
rules={[{ required: !disabled, message: "请选择备案属地" }]}
|
||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
options={CHONGQING_DISTRICTS}
|
options={territoryOptions}
|
||||||
placeholder="请选择"
|
placeholder={
|
||||||
|
mode === "application" ? "请选择" : "请选择(支持搜索全国区县)"
|
||||||
|
}
|
||||||
showSearch
|
showSearch
|
||||||
|
allowClear
|
||||||
optionFilterProp="label"
|
optionFilterProp="label"
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue