123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394 |
- <template>
- <div class="exam-manage">
- <Block class="header-block tw-flex tw-items-center tw-justify-between">
- <a-form layout="inline">
- <a-form-item label="学校名称">
- <!-- <a-select
- v-model:value="query.schoolId"
- show-search
- :filterOption="false"
- @search="(name:string) => querySchoolList(name, 'list')"
- placeholder="学校名称"
- > -->
- <a-select
- v-model:value="query.schoolId"
- show-search
- placeholder="学校名称"
- :options="schoolTableData.result"
- :fieldNames="{ label: 'name', value: 'id' }"
- optionFilterProp="name"
- >
- <!-- <a-select-option
- v-for="school in schoolTableData.result"
- :key="school.id"
- :value="school.id"
- >{{ school.name }}</a-select-option
- > -->
- </a-select>
- </a-form-item>
- <a-form-item label="考试批次">
- <a-input
- v-model:value="query.name"
- placeholder="考试批次"
- :maxlength="50"
- ></a-input>
- </a-form-item>
- <a-form-item>
- <a-button
- class="search-button"
- type="primary"
- @click="
- query.pageNumber == 1 ? queryExamList() : (query.pageNumber = 1)
- "
- >查询</a-button
- >
- </a-form-item>
- </a-form>
- <!-- <a-button
- type="primary"
- class="tw-flex tw-items-center operation-button"
- @click="syncExamData"
- >
- <template #icon>
- <CloudSyncOutlined />
- </template>
- 同步
- </a-button> -->
- <a-button
- type="primary"
- class="tw-flex tw-items-center operation-button"
- @click="toggleAddExamModal"
- >
- <template #icon>
- <PlusCircleOutlined />
- </template>
- 新增
- </a-button>
- </Block>
- <Block class="exam-table">
- <a-table
- :columns="columns"
- :data-source="examTableData.result"
- emptyText="暂无考试信息"
- :loading="tableLoading"
- :pagination="pagination"
- @change="currentPageChange"
- :row-class-name="
- (_:any, index:number) => (index % 2 === 1 ? 'table-striped' : null)
- "
- >
- <template #bodyCell="{ column, record, index }">
- <template v-if="column.dataIndex === 'index'">
- {{ index + 1 }}
- </template>
- <template v-else-if="column.dataIndex === 'examStatus'">
- {{ EXAM_STATUS[record.examStatus as keyof typeof EXAM_STATUS] }}
- </template>
- <template v-else-if="column.dataIndex === 'operation'">
- <div class="tw-flex tw-items-center">
- <span
- class="tw-cursor-pointer tw-p-2 tw-ml-1"
- @click="onEdit(record)"
- >编辑</span
- >
- </div>
- </template>
- </template>
- </a-table>
- </Block>
- <a-modal
- v-model:visible="showModal"
- :title="`${examInfo.id ? '编辑' : '新增'}考试`"
- okText="确定"
- cancelText="取消"
- :maskClosable="false"
- @ok="onAddNewExam"
- :afterClose="resetFields"
- >
- <a-form :labelCol="{ span: 6 }">
- <a-form-item label="学校名称" v-bind="validateInfos.schoolId">
- <!-- <a-select
- v-model:value="examInfo.schoolId"
- show-search
- :disabled="!!examInfo.id"
- @search="(name: string) => querySchoolList(name,'form')"
- :filterOption="false"
- placeholder="学校名称"
- > -->
- <a-select
- v-model:value="examInfo.schoolId"
- show-search
- placeholder="学校名称"
- :options="examInfo.schoolTableData.result"
- :fieldNames="{ label: 'name', value: 'id' }"
- optionFilterProp="name"
- >
- <!-- <a-select-option
- v-for="school in examInfo.schoolTableData.result"
- :key="school.id"
- :value="school.id"
- >{{ school.name }}</a-select-option
- > -->
- </a-select>
- </a-form-item>
- <a-form-item label="考试批次" v-bind="validateInfos.name">
- <a-input
- v-model:value="examInfo.name"
- :maxlength="50"
- placeholder="请输入考试批次"
- ></a-input>
- </a-form-item>
- <a-form-item label="状态" v-bind="validateInfos.examStatus">
- <a-select
- v-model:value="examInfo.examStatus"
- placeholder="选择考试状态"
- >
- <a-select-option value="EDIT">{{
- EXAM_STATUS.EDIT
- }}</a-select-option>
- <a-select-option value="FINISH">{{
- EXAM_STATUS.FINISH
- }}</a-select-option>
- <a-select-option value="CLOSE">{{
- EXAM_STATUS.CLOSE
- }}</a-select-option>
- </a-select>
- </a-form-item>
- </a-form>
- </a-modal>
- </div>
- </template>
- <script setup lang="ts" name="PageExam">
- import { reactive, ref, watch, unref, markRaw, toRaw, computed } from "vue";
- import { PlusCircleOutlined } from "@ant-design/icons-vue";
- import { getSchoolListHttp } from "@/apis/school";
- import {
- getExamListHttp,
- editExamInfoHttp,
- syncExamDataHttp,
- } from "@/apis/exam";
- import Block from "@/components/block/index.vue";
- import { message, TableColumnType } from "ant-design-vue";
- import { Form } from "ant-design-vue";
- import { throttle } from "lodash-es";
- import { EXAM_STATUS } from "@/constants/dicts";
- import { useMainStore } from "@/store/main";
- const mainStore = useMainStore();
- const showModal = ref(false);
- const tableLoading = ref(false);
- /** 请求参数 */
- const query = reactive<FetchExamListQuery>({
- name: "",
- // schoolId: mainStore.systemUserInfo?.schoolId || "",
- schoolId: "",
- pageNumber: 1,
- pageSize: 10,
- });
- /** table配置 */
- const columns: TableColumnType[] = [
- { title: "序号", dataIndex: "index", align: "center", width: 60 },
- { title: "考试ID", dataIndex: "id", width: 100, ellipsis: true },
- { title: "考试批次", dataIndex: "name", ellipsis: true },
- {
- title: "状态",
- dataIndex: "examStatus",
- align: "center",
- width: 160,
- ellipsis: true,
- },
- {
- title: "科目数量",
- dataIndex: "paperCount",
- align: "center",
- width: 100,
- ellipsis: true,
- },
- { title: "操作", dataIndex: "operation", align: "center", width: 100 },
- ];
- /** 学校列表信息 */
- const schoolTableData = reactive<MultiplePageData<SchoolListInfo>>({
- totalCount: 0,
- result: [],
- });
- /** 考试列表信息 */
- const examTableData = reactive<MultiplePageData<ExamListInfo>>({
- totalCount: 0,
- result: [],
- });
- const examInfo = reactive<
- BaseExamInfo & { schoolTableData: MultiplePageData<SchoolListInfo> }
- >({
- schoolTableData: { totalCount: 0, result: [] },
- examStatus: void 0,
- name: "",
- schoolId: void 0,
- id: void 0,
- });
- const examRules = {
- name: [{ required: true, message: "请填写考试批次" }],
- examStatus: [{ required: true, message: "请选择考试状态" }],
- schoolId: [{ required: true, message: "请选择学校" }],
- };
- const { validate, validateInfos, resetFields } = Form.useForm(
- examInfo,
- examRules
- );
- /** 查询学校列表 */
- const querySchoolList = throttle(
- async (name: string = "", type: "list" | "form" = "list") => {
- const isList = type === "list";
- try {
- const { result = [], totalCount } = await getSchoolListHttp({
- pageNumber: 1,
- pageSize: 1000,
- name,
- });
- Object.assign(isList ? schoolTableData : examInfo.schoolTableData, {
- result,
- totalCount,
- });
- } catch (error) {
- console.error(error);
- }
- },
- 100
- );
- /** 显示新增考试弹窗 */
- const toggleAddExamModal = (show: boolean = true) => {
- showModal.value = show;
- if (show) {
- if (!examInfo.id) {
- Object.assign(examInfo, {
- schoolId: query.schoolId || mainStore.systemUserInfo?.schoolId,
- });
- }
- querySchoolList("", "form");
- }
- };
- /** 查询考试列表 */
- const queryExamList = async () => {
- try {
- tableLoading.value = true;
- const { result = [], totalCount } = await getExamListHttp(query);
- Object.assign(examTableData, { result, totalCount });
- } catch (error) {
- console.error(error);
- }
- tableLoading.value = false;
- };
- watch(() => query.pageNumber, queryExamList);
- watch(
- () => query.pageSize,
- () => {
- query.pageNumber = 1;
- queryExamList();
- }
- );
- /** 编辑考试 */
- const onEdit = (record: ExamListInfo) => {
- Object.assign(examInfo, {
- id: record.id,
- examStatus: record.examStatus,
- name: record.name,
- schoolId: record.schoolId,
- });
- toggleAddExamModal(true);
- };
- /** 新增考试 */
- const onAddNewExam = () => {
- validate().then((valid) => {
- if (valid) {
- const { schoolTableData, ...info } = examInfo;
- editExamInfoHttp(info).then(() => {
- message.success(`${info.id ? "修改" : "添加"}成功`);
- toggleAddExamModal(false);
- query.schoolId && queryExamList();
- });
- }
- });
- };
- const currentPageChange = ({
- current,
- pageSize,
- }: {
- current: number;
- pageSize: number;
- }) => {
- console.log(current, pageSize);
- query.pageNumber = current;
- query.pageSize = pageSize;
- };
- /** 同步考试数据 */
- const syncExamData = () => {
- if (!query.schoolId) {
- return message.error("请选择需要同步数据的学校");
- }
- syncExamDataHttp({ schoolId: query.schoolId }).then(queryExamList);
- };
- querySchoolList();
- /** effect */
- if (query.schoolId) {
- queryExamList();
- }
- const pagination = computed(() => {
- return {
- showSizeChanger: true,
- total: examTableData.totalCount,
- pageSize: query.pageSize,
- current: query.pageNumber,
- showTotal: (total: any) => `共 ${total} 条`,
- };
- });
- </script>
- <style scoped lang="less">
- .exam-manage {
- .header-block {
- :deep(.ant-select-selector) {
- width: 160px;
- }
- .search-button {
- background-color: @font-color;
- color: @white;
- border: none;
- width: 56px;
- padding: 0;
- &:after {
- display: none;
- opacity: 0;
- }
- }
- .operation-button {
- width: 72px;
- padding: 0;
- margin-left: auto;
- & ~ .operation-button {
- margin-left: 8px;
- }
- }
- }
- .exam-table {
- }
- }
- </style>
|