123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- <template>
- <div class="flex direction-column">
- <div class="flex items-center fill-blank p-medium-base">
- <span class="subject-name">{{ subjectInfo?.name }}</span>
- <confirm-button
- class="m-l-auto"
- size="small"
- ok-text="新增"
- cancel-text="返回"
- @confirm="onAddMainQuestion"
- @cancel="back"
- ></confirm-button>
- </div>
- <div class="flex-1 p-base">
- <el-card shadow="never">
- <base-table size="small" border stripe :data="tableData" :columns="columns">
- <template #column-mainNumber="{ row }">
- <p v-if="!!row.relationMainNumber" style="display: flex; align-items: center; justify-content: center">
- <span>{{ row.mainNumber }}</span>
- <el-icon :size="16" color="#0091ff" style="margin-left: 2px">
- <flag />
- </el-icon>
- </p>
- <span v-else>{{ row.mainNumber }}</span>
- </template>
- <template #column-operation="{ row }">
- <el-button type="primary" link @click="onEditSubQuestion(row)">编辑</el-button>
- <el-popconfirm :width="'220px'" hide-icon :title="`确认删除题目?`" @confirm="onDelete(row)">
- <template #reference>
- <el-button type="primary" link>删除</el-button>
- </template>
- </el-popconfirm>
- <el-button v-if="row.firstMain" type="primary" link @click="onEditMainQuestion(row)">大题设置</el-button>
- <el-button v-if="row.firstMain" type="primary" link @click="recovery(row)">手动回收</el-button>
- <el-button v-if="!row.relationMainNumber" type="primary" link @click="syncTask(row)">同步任务</el-button>
- </template>
- </base-table>
- </el-card>
- </div>
- <base-dialog v-model="visibleSubQuestionEditor" unless :footer="false" destroy-on-close>
- <base-form
- ref="formRef"
- :label-width="'72px'"
- :model="editSubInfo"
- :items="items"
- :rules="rules"
- :disabled="saving"
- >
- <template #form-item-mainQuestion> {{ [editSubInfo.mainNumber, editSubInfo.mainTitle].join('-') }} </template>
- <template #form-item-subQuestion> {{ editSubInfo.subNumber }} </template>
- <el-form-item class="m-t-base">
- <confirm-button :loading="saving" @confirm="onSubmit" @cancel="toggleVisible(false)"></confirm-button>
- </el-form-item>
- </base-form>
- </base-dialog>
- <base-dialog v-model="showSyncTaskDialog" destroy-on-close :width="400" title="同步任务">
- <div class="dialog-text">
- 待同步任务:<span class="red">{{ syncCount?.count }}</span>
- </div>
- <div class="dialog-text">是否确认从关联大题中 <b>同步人机仲裁</b> 任务</div>
- <template #footer>
- <div class="flex justify-center">
- <confirm-button @confirm="syncSubmit" @cancel="showSyncTaskDialog = false"></confirm-button>
- </div>
- </template>
- </base-dialog>
- </div>
- </template>
- <script setup lang="tsx" name="SubjectStructManage">
- /** 科目试卷结构管理 */
- import { reactive, ref, computed } from 'vue'
- import { useRouter } from 'vue-router'
- import { ElButton, ElCard, ElFormItem, ElPopconfirm, ElMessage, ElIcon } from 'element-plus'
- import ConfirmButton from '@/components/common/ConfirmButton.vue'
- import BaseTable from '@/components/element/BaseTable.vue'
- import BaseForm from '@/components/element/BaseForm.vue'
- import BaseDialog from '@/components/element/BaseDialog.vue'
- import useFetch from '@/hooks/useFetch'
- import useForm from '@/hooks/useForm'
- import { Flag } from '@element-plus/icons-vue'
- import type { EpTableColumn, EpFormItem, EpFormRules } from 'global-type'
- import type { ExtractApiResponse } from '@/api/api'
- const showSyncTaskDialog = ref(false)
- const { back, push } = useRouter()
- const props = defineProps<{ id: number | string }>()
- const { fetch: getSubjectInfo, result: subjectInfo } = useFetch('getSubjectInfo')
- const { fetch: getSubQuestionList, result: subQuestionList } = useFetch('getSubQuestionList')
- const { fetch: getSyncCount, result: syncCount } = useFetch('getSyncCount')
- type SubQuestion = ExtractArrayValue<ExtractApiResponse<'getSubQuestionList'>>
- type WithFirstMainTag = SubQuestion & { firstMain: boolean }
- const tableData = computed<any>(() => {
- const MainMap: Record<number | string, boolean> = {}
- return subQuestionList.value?.map((sub) => {
- const mainHas = !!MainMap[sub.mainNumber]
- if (!mainHas) {
- MainMap[sub.mainNumber] = true
- }
- return { ...sub, firstMain: !mainHas }
- })
- })
- const columns: EpTableColumn[] = [
- {
- label: '大题号',
- // prop: 'mainNumber',
- slotName: 'mainNumber',
- // formatter(row: any) {
- // return row.relationMainNumber ? (
- // row.mainNumber
- // ) : (
- // <p style="display:flex;align-items:center;justify-content:center">
- // <span>{row.mainNumber}</span>
- // <el-icon>
- // <Flag />
- // </el-icon>
- // </p>
- // )
- // },
- },
- { label: '大题名称', prop: 'mainTitle' },
- { label: '小题号', prop: 'subNumber' },
- { label: '小题满分', prop: 'totalScore' },
- { label: '间隔分', prop: 'intervalScore' },
- { label: '操作', slotName: 'operation', width: 320 },
- ]
- if (props.id) {
- getSubjectInfo({ id: +props.id }).then((info) => {
- getSubQuestionList({ subjectCode: info.code })
- })
- }
- /** 新增大题 */
- function onAddMainQuestion() {
- if (subjectInfo.value.code) {
- push({ name: 'EditStruct', params: { subjectCode: subjectInfo.value.code } })
- }
- }
- /** 编辑大题 */
- function onEditMainQuestion(row: ExtractArrayValue<ExtractApiResponse<'getSubQuestionList'>>) {
- if (subjectInfo.value.code) {
- push({ name: 'EditStruct', params: { subjectCode: subjectInfo.value.code, mainNumber: row.mainNumber } })
- }
- }
- function recovery(row: any) {
- useFetch('recoveryTask')
- .fetch({ subjectCode: subjectInfo.value.code, mainNumber: row.mainNumber })
- .then((res) => {
- ElMessage.success(`回收成功`)
- })
- }
- const curRow = ref<any>()
- function syncTask(row: any) {
- getSyncCount({
- mainNumber: row.mainNumber,
- subjectCode: subjectInfo.value.code,
- }).then(() => {
- showSyncTaskDialog.value = true
- curRow.value = row
- })
- }
- const { fetch: syncFetch, loading: syncLoading } = useFetch('syncSubmit')
- const syncSubmit = () => {
- syncFetch({
- mainNumber: curRow.value.mainNumber,
- subjectCode: subjectInfo.value.code,
- }).then(() => {
- showSyncTaskDialog.value = false
- ElMessage.success(`同步成功`)
- })
- }
- const { fetch: editSubQuestion, loading: saving } = useFetch('editSubQuestion')
- const editSubInfo = reactive<Partial<ExtractArrayValue<ExtractApiResponse<'getSubQuestionList'>>>>({})
- const { formRef, elFormRef } = useForm()
- const rules = computed<EpFormRules>(() => {
- return {
- intervalScore: [{ required: true, message: '请填写间隔分' }],
- }
- })
- const items = computed<EpFormItem[]>(() => {
- return [
- { label: '大题', slotName: 'mainQuestion' },
- { label: '小题号', slotName: 'subQuestion' },
- {
- label: '间隔分',
- prop: 'intervalScore',
- slotType: 'inputNumber',
- slot: { placeholder: '间隔分', stepStrictly: true, step: 1 },
- },
- ]
- })
- const visibleSubQuestionEditor = ref<boolean>(false)
- function toggleVisible(visible: boolean) {
- visibleSubQuestionEditor.value = visible
- }
- /** 编辑小题 */
- function onEditSubQuestion(row: ExtractArrayValue<ExtractApiResponse<'getSubQuestionList'>>) {
- Object.assign(editSubInfo, row)
- toggleVisible(true)
- }
- async function onSubmit() {
- try {
- const valid = await elFormRef?.value?.validate()
- valid && (await editSubQuestion({ id: editSubInfo.id, intervalScore: editSubInfo.intervalScore }))
- ElMessage.success(`保存成功`)
- subjectInfo?.value?.code && getSubQuestionList({ subjectCode: subjectInfo.value.code })
- toggleVisible(false)
- } catch (error) {
- console.error(error)
- }
- }
- /** 删除 */
- const { fetch: deleteSubQuestion } = useFetch('deleteSubQuestion')
- function onDelete(row: ExtractArrayValue<ExtractApiResponse<'getSubQuestionList'>>) {
- row.id &&
- deleteSubQuestion({ id: row.id }).then(() => {
- subjectInfo?.value?.code && getSubQuestionList({ subjectCode: subjectInfo.value.code })
- })
- }
- </script>
- <style scoped lang="scss">
- .dialog-text {
- font-size: 14px;
- color: #333;
- line-height: 1.8;
- .red {
- color: red;
- font-size: 16px;
- font-weight: bold;
- }
- }
- </style>
|