浏览代码

项目参数配置

Michael Wang 3 年之前
父节点
当前提交
4f5cd12c38

+ 4 - 0
components.d.ts

@@ -23,15 +23,19 @@ declare module 'vue' {
     ATable: typeof import('ant-design-vue/es')['Table']
     ATabPane: typeof import('ant-design-vue/es')['TabPane']
     ATabs: typeof import('ant-design-vue/es')['Tabs']
+    CourseSelect: typeof import('./src/components/CourseSelect.vue')['default']
     CourseTypeSelect: typeof import('./src/components/CourseTypeSelect.vue')['default']
     'CourseTypeSelect copy': typeof import('./src/components/CourseTypeSelect copy.vue')['default']
     Layout: typeof import('./src/components/Layout.vue')['default']
     PaperTypeSelect: typeof import('./src/components/PaperTypeSelect.vue')['default']
+    ProjectCourseSelect: typeof import('./src/components/ProjectCourseSelect.vue')['default']
+    'ProjectCourseSelect copy': typeof import('./src/components/ProjectCourseSelect copy.vue')['default']
     ProjectStatusSelect: typeof import('./src/components/ProjectStatusSelect.vue')['default']
     'ProjectStatusSelect copy': typeof import('./src/components/ProjectStatusSelect copy.vue')['default']
     QmButton: typeof import('./src/components/QmButton.vue')['default']
     RoleSelect: typeof import('./src/components/RoleSelect.vue')['default']
     RootOrgSelect: typeof import('./src/components/RootOrgSelect.vue')['default']
+    'RootOrgSelect copy': typeof import('./src/components/RootOrgSelect copy.vue')['default']
     StateSelect: typeof import('./src/components/StateSelect.vue')['default']
   }
 }

+ 39 - 0
src/api/projectParamsManagementPage.ts

@@ -0,0 +1,39 @@
+import { httpApp } from "@/plugins/axiosApp";
+
+/** 科目分页查询 */
+export function getProjectCourseList(params: {
+  courseId?: number;
+  projectId: number;
+  pageNo?: number;
+  pageSize?: number;
+}) {
+  return httpApp.post("/api/ess/projectCourse/list", params);
+}
+
+/** 导入项目参数配置 */
+export function importProjectParams(projectId: number, file: File) {
+  const f = new FormData();
+  f.append("projectId", projectId + "");
+  f.append("file", file);
+  return httpApp.post(`/api/ess/projectCourse/import`, f);
+}
+
+/** 导出项目参数配置 */
+export function exportProjectParams(projectId: number) {
+  return httpApp.post(
+    `/api/ess/course/export`,
+    new URLSearchParams({ projectId: projectId + "" })
+  );
+}
+
+/** 更新科目 */
+export function updateProjectCourse(params: {
+  id: number;
+  nationalScore: number;
+  nationalTotalScore: number;
+  retestScore: number;
+  retestTotalScore: number;
+  totalScoreLine: number;
+}) {
+  return httpApp.post("/api/ess/projectCourse/update", params);
+}

+ 51 - 0
src/components/CourseSelect.vue

@@ -0,0 +1,51 @@
+<template>
+  <a-select
+    placeholder="请选择科目"
+    allowClear
+    :value="valueStr"
+    @change="handleChange"
+    style="width: 140px"
+  >
+    <a-select-option
+      v-for="(item, index) in optionList"
+      :key="index"
+      :value="item.id"
+    >
+      {{ item.name }}
+    </a-select-option>
+  </a-select>
+</template>
+
+<script setup lang="ts">
+import { getCourseList } from "@/api/courseManagementPage";
+import { onMounted, computed, watch } from "vue-demi";
+
+const props =
+  defineProps<{ value?: null | number; rootOrgId?: null | number }>();
+const emit = defineEmits(["update:value"]);
+
+let optionList = $ref<{ id: number; name: string }[]>([]);
+
+watch(() => props.rootOrgId, fetchData);
+onMounted(fetchData);
+async function fetchData() {
+  if (typeof props.rootOrgId === "number") {
+    const res = await getCourseList({
+      rootOrgId: props.rootOrgId,
+      enable: true,
+      pageNo: 1,
+      pageSize: 100,
+    });
+    optionList = res.data.content;
+  }
+}
+const valueStr = computed(() => {
+  let res: undefined | number | string = props.value ?? undefined;
+  // if (typeof res === "number") res = props.value + "";
+  return res as undefined | string;
+});
+
+function handleChange(v: string) {
+  emit("update:value", v);
+}
+</script>

+ 46 - 0
src/components/ProjectCourseSelect.vue

@@ -0,0 +1,46 @@
+<template>
+  <a-select
+    placeholder="请选择科目"
+    allowClear
+    :value="valueStr"
+    @change="handleChange"
+    style="width: 140px"
+  >
+    <a-select-option
+      v-for="(item, index) in optionList"
+      :key="index"
+      :value="item.courseId"
+    >
+      {{ item.courseName }}
+    </a-select-option>
+  </a-select>
+</template>
+
+<script setup lang="ts">
+import { getProjectCourseList } from "@/api/projectParamsManagementPage";
+import { onMounted, computed } from "vue-demi";
+
+const props = defineProps<{ value?: null | number; projectId: number }>();
+const emit = defineEmits(["update:value"]);
+
+let optionList = $ref<{ courseId: number; courseName: string }[]>([]);
+
+onMounted(async () => {
+  const res = await getProjectCourseList({
+    projectId: props.projectId,
+    pageNo: 1,
+    pageSize: 100,
+  });
+  optionList = res.data.content;
+});
+
+const valueStr = computed(() => {
+  let res: undefined | number | string = props.value ?? undefined;
+  // if (typeof res === "number") res = props.value + "";
+  return res as undefined | string;
+});
+
+function handleChange(v: string) {
+  emit("update:value", v);
+}
+</script>

+ 1 - 4
src/features/projectDataManagement/ProjectDataManagement.vue

@@ -43,17 +43,14 @@
 
 <script setup lang="ts">
 import {
-  cancelProject,
-  deleteProjects,
   getProjectList,
   importProjectDataSource,
   logsOfProject,
-  updateProject,
 } from "@/api/projectManagementPage";
 import { useMainStore } from "@/store";
 import { downloadFileURL, goBack } from "@/utils/utils";
 import { message } from "ant-design-vue";
-import { watch, onMounted, ref, reactive, toRaw, computed } from "vue-demi";
+import { onMounted, computed } from "vue-demi";
 import { useRoute } from "vue-router";
 
 const store = useMainStore();

+ 5 - 1
src/features/projectManagement/ProjectManagement.vue

@@ -70,7 +70,7 @@
             </a-button>
             <a-button
               v-if="record.status !== 'PROCESSING'"
-              @click="handleDeleteProjects([record.id])"
+              @click="goProjectParams(record.id)"
             >
               参数配置
             </a-button>
@@ -270,4 +270,8 @@ async function handleLogsOfProject(id: number) {
 function goProjectDataSource(id: number) {
   router.push("datasource/" + id);
 }
+
+function goProjectParams(id: number) {
+  router.push("params/" + id);
+}
 </script>

+ 237 - 0
src/features/projectParamsManagement/ProjectParamsManagement.vue

@@ -0,0 +1,237 @@
+<template>
+  <div>
+    <div class="tw-bg-white tw-p-5 tw-rounded-xl tw-mb-5">
+      <span class="tw-mr-4"></span>
+      <CourseSelect :root-org-id="rootOrgId" v-model:value="courseId" />
+      <span class="tw-mr-4"></span>
+      <span class="tw-mr-4"></span>
+      <a-button @click="search">查询</a-button>
+
+      <div class="tw-mt-4">
+        <a-button @click="importModalVisible = true">批量导入</a-button>
+        <a-button @click="handleExport">批量导出</a-button>
+        <a-button @click="goBack">返回</a-button>
+      </div>
+    </div>
+
+    <div class="tw-bg-white tw-p-5 tw-rounded-xl">
+      <a-table
+        row-key="id"
+        :columns="columns"
+        :data-source="data"
+        :pagination="{
+          pageSize: pageSize,
+          current: pageNo,
+          total: totalElements,
+          showTotal: (total: number) => `总数:${total}`,
+          onChange: (pageNoChanged: number, pageSizeChanged: number) => {
+            pageNo = pageNoChanged; 
+            pageSize = pageSizeChanged;
+          }
+        }"
+      >
+        <template #course="{ record }">
+          <a>{{ `${record.courseName}(${record.courseCode})` }}</a>
+        </template>
+        <template #action="{ record }">
+          <span>
+            <a-button @click="showModal(record)">编辑</a-button>
+          </span>
+        </template>
+      </a-table>
+    </div>
+
+    <a-modal
+      v-model:visible="visible"
+      title="单科线设置页"
+      @ok="handleOk"
+      ok-text="确定"
+      cancel-text="取消"
+    >
+      <a-form>
+        <a-form-item label="项目名称">
+          <a-input disabled v-model:value="projectObj.projectName"></a-input>
+        </a-form-item>
+        <a-form-item label="项目名称">
+          <a-input
+            disabled
+            :value="projectObj.courseName + '(' + projectObj.courseCode + ')'"
+          ></a-input>
+        </a-form-item>
+        <a-form-item label="项目名称">
+          <CourseTypeSelect :value="projectObj.courseType" disabled />
+        </a-form-item>
+
+        <a-form-item label="国家单科线">
+          <a-input v-model:value="projectObj.nationalScore"></a-input>
+        </a-form-item>
+        <a-form-item label="复试科目线">
+          <a-input v-model:value="projectObj.retestScore"></a-input>
+        </a-form-item>
+        <a-form-item label="国家总分线">
+          <a-input v-model:value="projectObj.nationalTotalScore"></a-input>
+        </a-form-item>
+        <a-form-item label="复试总分线">
+          <a-input v-model:value="projectObj.retestTotalScore"></a-input>
+        </a-form-item>
+        <a-form-item label="总分满分线">
+          <a-input v-model:value="projectObj.totalScoreLine"></a-input>
+        </a-form-item>
+      </a-form>
+    </a-modal>
+
+    <a-modal
+      v-model:visible="importModalVisible"
+      title="单科线批量导入"
+      @ok="handleImport"
+      ok-text="确定"
+      cancel-text="取消"
+    >
+      <a-form>
+        <a-form-item label="文件地址">
+          <input id="file-input" :multiple="false" type="file" />
+        </a-form-item>
+        <a-form-item label="下载模板">
+          <a-button @click="downloadTpl">下载模板</a-button>
+        </a-form-item>
+      </a-form>
+    </a-modal>
+  </div>
+</template>
+
+<script setup lang="ts">
+import {
+  exportProjectParams,
+  getProjectCourseList,
+  importProjectParams,
+  updateProjectCourse,
+} from "@/api/projectParamsManagementPage";
+import { useMainStore } from "@/store";
+import { downloadFileURL, goBack } from "@/utils/utils";
+import { message } from "ant-design-vue";
+import { watch, onMounted, ref, reactive, toRaw } from "vue-demi";
+import { useRoute } from "vue-router";
+
+const store = useMainStore();
+store.currentLocation = "基础管理 / 项目列表";
+
+let rootOrgId = $ref(undefined as unknown as number);
+let name = $ref("");
+let courseId = $ref(undefined as undefined | number);
+const route = useRoute();
+const projectId = +route.params.id;
+
+let data = $ref([]);
+let pageSize = $ref(10);
+let pageNo = $ref(1);
+let totalElements = $ref(0);
+
+async function search() {
+  await fetchData();
+}
+
+watch(() => [pageNo, pageSize], fetchData);
+
+async function fetchData() {
+  const res = await getProjectCourseList({
+    projectId,
+    pageSize,
+    pageNo,
+  });
+  // console.log(res);
+  data = res.data.content;
+  pageNo = res.data.pageNo;
+  pageSize = res.data.pageSize;
+  totalElements = res.data.totalElements;
+}
+
+const columns = [
+  {
+    title: "科目",
+    dataIndex: "course",
+    slots: { customRender: "course" },
+  },
+  {
+    title: "国家单科线",
+    dataIndex: "nationalScore",
+  },
+  {
+    title: "复试科目线",
+    dataIndex: "retestScore",
+  },
+  {
+    title: "国家总分线",
+    dataIndex: "nationalTotalScore",
+  },
+  {
+    title: "复试总分线",
+    dataIndex: "retestTotalScore",
+  },
+  {
+    title: "总分满分线",
+    dataIndex: "totalScoreLine",
+  },
+  {
+    title: "操作",
+    key: "action",
+    slots: { customRender: "action" },
+  },
+];
+
+onMounted(async () => {
+  rootOrgId = store.userInfo.rootOrgId;
+  await search();
+});
+
+const visible = ref<boolean>(false);
+
+const showModal = (record: any) => {
+  Object.assign(projectObj, record);
+  visible.value = true;
+};
+
+const handleOk = async (e: MouseEvent) => {
+  await updateProjectCourse(toRaw(projectObj));
+  visible.value = false;
+  await search();
+};
+
+const initProject = {
+  id: 0,
+  nationalScore: 0,
+  nationalTotalScore: 0,
+  retestScore: 0,
+  retestTotalScore: 0,
+  totalScoreLine: 0,
+  projectName: "",
+  courseName: "",
+  courseCode: "",
+  courseType: undefined,
+};
+const projectObj = reactive({ ...initProject });
+
+/** <handleImport> */
+let importModalVisible = ref<boolean>(false);
+async function handleImport() {
+  const files = (document.querySelector("#file-input") as HTMLInputElement)
+    .files;
+  const fileToImport = files && files[0];
+  if (!fileToImport) {
+    message.warn({ content: "请选择文件" });
+    return;
+  }
+
+  await importProjectParams(projectId, fileToImport);
+  message.success({ content: "导入成功" });
+}
+/** </handleImport> */
+
+async function handleExport() {
+  await exportProjectParams(projectId);
+  message.success({ content: "导出成功" });
+}
+
+async function downloadTpl() {
+  downloadFileURL("/api/ess/projectCourse/template");
+}
+</script>

+ 7 - 0
src/router/index.ts

@@ -56,6 +56,13 @@ const routes = [
         component: () =>
           import("@/features/projectDataManagement/ProjectDataManagement.vue"),
       },
+      {
+        path: "params/:id",
+        component: () =>
+          import(
+            "@/features/projectParamsManagement/ProjectParamsManagement.vue"
+          ),
+      },
     ],
     component: Layout,
   },