Bläddra i källkod

Merge branch 'dev' of http://192.168.1.245:11111/shanming/onlineEducation-front into dev

zhangsq 7 månader sedan
förälder
incheckning
3dfaa5986a

+ 28 - 0
src/api/paper/examPaperApi.js

@@ -0,0 +1,28 @@
+import { baseRequest } from '@/utils/request'
+
+const request = (url, ...arg) => baseRequest(`/api/webapp/` + url, ...arg)
+
+/**
+ * t_exam_paperApi接口管理器
+ *
+ * @author zss
+ * @date  2025/07/07 10:10
+ **/
+export default {
+	// 获取t_exam_paper分页
+	tExamPaperPage(data) {
+		return request('api/admin/exam/paper/page', data, 'post')
+	},
+	// 提交t_exam_paper表单 edit为true时为编辑,默认为新增
+	tExamPaperSubmitForm(data, edit = false) {
+		return request('api/admin/exam/paper/edit', data)
+	},
+	// 删除t_exam_paper
+	tExamPaperDelete(data) {
+		return request('delete', data)
+	},
+	// 获取t_exam_paper详情
+	tExamPaperDetail(data) {
+		return request('detail', data, 'get')
+	}
+}

+ 106 - 0
src/views/exm/exampaper/form.vue

@@ -0,0 +1,106 @@
+<template>
+    <xn-form-container
+        :title="formData.id ? '编辑t_exam_paper' : '增加t_exam_paper'"
+        :width="700"
+        :visible="visible"
+        :destroy-on-close="true"
+        @close="onClose"
+    >
+        <a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
+			<a-form-item label="年级:" name="level">
+				<a-select
+					v-model:value="formData.level"
+					:options="gradeLevelOptions"
+					style="width: 100%"
+					placeholder="请选择年级"
+				>
+				</a-select>
+			</a-form-item>
+			<a-form-item label="学科:" name="subjectId">
+				<a-select
+					v-model:value="formData.subjectId"
+					:options="susbjectOptions"
+					style="width: 100%"
+					placeholder="请选择学科"
+				>
+				</a-select>
+			</a-form-item>
+			<a-form-item label="试卷类型:" name="paperType">
+				<a-select
+					v-model:value="formData.paperType"
+					:options="paperTypeOptions"
+					style="width: 100%"
+					placeholder="请选择试卷类型"
+				>
+				</a-select>
+			</a-form-item>
+            <a-form-item label="试卷名称:" name="name">
+                <a-input v-model:value="formData.name" placeholder="请输入试卷名称" allow-clear />
+            </a-form-item>
+
+
+			<a-form-item label="建议时长:" name="suggestTime">
+				<a-input-number id="inputNumber" width="100%" v-model:value="formData.suggestTime" :min="1" :max="180" placeholder="请输入建议时长" allow-clear/>
+			</a-form-item>
+        </a-form>
+        <template #footer>
+			<a-button style="margin-right: 8px" @click="onClose">添加标题</a-button>
+            <a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
+            <a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
+        </template>
+    </xn-form-container>
+</template>
+
+<script setup name="tExamPaperForm">
+    import { cloneDeep } from 'lodash-es'
+    import { required } from '@/utils/formRules'
+    import tExamPaperApi from '@/api/paper/examPaperApi'
+	import tool from "@/utils/tool";
+    // 抽屉状态
+    const visible = ref(false)
+    const emit = defineEmits({ successful: null })
+    const formRef = ref()
+    // 表单数据
+    const formData = ref({})
+    const submitLoading = ref(false)
+	// 打开抽屉
+    const onOpen = (record) => {
+        visible.value = true
+        if (record) {
+            let recordData = cloneDeep(record)
+            formData.value = Object.assign({}, recordData)
+        }
+    }
+    // 关闭抽屉
+    const onClose = () => {
+        formRef.value.resetFields()
+        formData.value = {}
+        visible.value = false
+    }
+    // 默认要校验的
+    const formRules = {
+    }
+    // 验证并提交数据
+    const onSubmit = () => {
+        formRef.value.validate().then(() => {
+            submitLoading.value = true
+            const formDataParam = cloneDeep(formData.value)
+            tExamPaperApi
+                .tExamPaperSubmitForm(formDataParam, formDataParam.id)
+                .then(() => {
+                    onClose()
+                    emit('successful')
+                })
+                .finally(() => {
+                    submitLoading.value = false
+                })
+        })
+    }
+	const gradeLevelOptions = tool.dictList('SEMESTER')
+	const susbjectOptions = tool.dictList('SUBJECT')
+	const paperTypeOptions = tool.dictList('PAPER_TYPE')
+	// 抛出函数
+    defineExpose({
+        onOpen
+    })
+</script>

+ 139 - 0
src/views/exm/exampaper/index.vue

@@ -0,0 +1,139 @@
+<template>
+	<a-card :bordered="false">
+		<!-- 搜索和操作区域 -->
+		<a-row :gutter="60" style="margin-bottom: 16px">
+			<a-col>
+				<span>试卷名称:</span>
+				<a-input v-model:value="formState.name" placeholder="请输入试卷名称" style="width: 150px;" />
+			</a-col>
+			<a-col>
+				<span>学科名称:</span>
+				<a-input v-model:value="formState.fileName" placeholder="请输入学科名称" style="width: 150px" />
+			</a-col>
+			<a-col>
+				<a-button type="primary" style="margin-left: 8px" @click="handleSearch">查询</a-button>
+				<a-button style="margin-left: 8px" @click="handleReset">重置</a-button>
+			</a-col>
+		</a-row>
+
+		<s-table
+			ref="table"
+			:columns="columns"
+			:data="loadData"
+			:alert="options.alert.show"
+			bordered
+			:row-key="(record) => record.id"
+			:tool-config="toolConfig"
+			:row-selection="options.rowSelection"
+		>
+			<template #operator class="table-operator">
+				<a-space>
+					<a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('tExamPaperAdd')">
+						<template #icon><plus-outlined /></template>
+						新增
+					</a-button>
+					<xn-batch-delete
+						v-if="hasPerm('tExamPaperBatchDelete')"
+						:selectedRowKeys="selectedRowKeys"
+						@batchDelete="deleteBatchTExamPaper"
+					/>
+				</a-space>
+			</template>
+			<template #bodyCell="{ column, record }">
+				<template v-if="column.dataIndex === 'action'">
+					<a-space>
+						<a @click="formRef.onOpen(record)" v-if="hasPerm('tExamPaperEdit')">编辑</a>
+						<a-divider type="vertical" v-if="hasPerm(['tExamPaperEdit', 'tExamPaperDelete'], 'and')" />
+						<a-popconfirm title="确定要删除吗?" @confirm="deleteTExamPaper(record)">
+							<a-button type="link" danger size="small" v-if="hasPerm('tExamPaperDelete')">删除</a-button>
+						</a-popconfirm>
+					</a-space>
+				</template>
+			</template>
+		</s-table>
+	</a-card>
+	<Form ref="formRef" @successful="table.refresh(true)" />
+</template>
+
+<script setup name="exampaper">
+	import Form from './form.vue'
+	import tExamPaperApi from '@/api/paper/examPaperApi'
+	const formState = reactive({
+		id: null,
+		verifyStatus: '0',
+		resourcesId: null,
+	})
+    const table = ref()
+    const formRef = ref()
+    const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+    const columns = [
+        {
+            title: 'ID',
+            dataIndex: 'ID'
+        },
+        {
+            title: '学科',
+            dataIndex: 'subjectId'
+        },
+        {
+            title: '名称',
+            dataIndex: 'name'
+        },
+        {
+            title: '创建时间',
+            dataIndex: 'createTime'
+        }
+    ]
+    // 操作栏通过权限判断是否显示
+    if (hasPerm(['tExamPaperEdit', 'tExamPaperDelete'])) {
+        columns.push({
+            title: '操作',
+            dataIndex: 'action',
+            align: 'center',
+            width: '150px'
+        })
+    }
+    const selectedRowKeys = ref([])
+    // 列表选择配置
+    const options = {
+        // columns数字类型字段加入 needTotal: true 可以勾选自动算账
+        alert: {
+            show: true,
+            clear: () => {
+                selectedRowKeys.value = ref([])
+            }
+        },
+        rowSelection: {
+            onChange: (selectedRowKey, selectedRows) => {
+                selectedRowKeys.value = selectedRowKey
+            }
+        }
+    }
+    const loadData = (parameter) => {
+        return tExamPaperApi.tExamPaperPage(parameter).then((data) => {
+            return data
+        })
+    }
+    // 重置
+    const reset = () => {
+        searchFormRef.value.resetFields()
+        table.value.refresh(true)
+    }
+    // 删除
+    const deleteTExamPaper = (record) => {
+        let params = [
+            {
+                id: record.id
+            }
+        ]
+        tExamPaperApi.tExamPaperDelete(params).then(() => {
+            table.value.refresh(true)
+        })
+    }
+    // 批量删除
+    const deleteBatchTExamPaper = (params) => {
+		tExamPaperApi.tExamPaperDelete(params).then(() => {
+            table.value.clearRefreshSelected()
+        })
+    }
+</script>

+ 100 - 87
src/views/resourceCenter/components/ComplexChoices.vue

@@ -6,52 +6,54 @@
 			<!-- <a-radio-group v-model:value="selectedDept" >
 				<a-radio-button v-for="dept in selectedDepts" :key="dept" :value="dept">{{ dept }}</a-radio-button>
 			</a-radio-group> -->
-			<div style="display: flex; flex-direction: column">
-				<MyRadioButtonGroup
-					ref="Dept"
-					v-show="selectedDepts.length > 0"
-					v-model="selectedDept"
-					@change="handleSelectedDept"
-				>
-					<MyRadioButtonOffOut
-						v-for="(item, index) in selectedDepts"
-						:key="index"
-						:value="index"
-						:label="item.name"
-						:index="index"
-					></MyRadioButtonOffOut>
-				</MyRadioButtonGroup>
-				<div style="height: 10px"></div>
-				<MyRadioButtonGroup
-					ref="Big"
-					v-show="selectedDeptBigs.length > 0"
-					v-model="selectedDeptBig"
-					@change="handleSelectedCourses"
-				>
-					<MyRadioButton
-						v-for="(item, index) in selectedDeptBigs"
-						:key="index"
-						:value="index"
-						:label="item.name"
-						:index="index"
-					></MyRadioButton>
-				</MyRadioButtonGroup>
-				<div style="height: 10px"></div>
-				<MyRadioButtonGroup
-					ref="Smail"
-					v-show="selectedDeptSmails.length > 0"
-					v-model="selectedDeptSmail"
-					@change="handleSelectedSmails"
-				>
-					<MyRadioButton
-						v-for="(item, index) in selectedDeptSmails"
-						:key="index"
-						:value="index"
-						:label="item.name"
-						:index="index"
-					></MyRadioButton>
-				</MyRadioButtonGroup>
-			</div>
+			<a-spin :spinning="spinningSelectedDepts" tip="">
+				<div style="display: flex; flex-direction: column">
+					<MyRadioButtonGroup
+						ref="Dept"
+						v-show="selectedDepts.length > 0"
+						v-model="selectedDept"
+						@change="handleSelectedDept"
+					>
+						<MyRadioButtonOffOut
+							v-for="(item, index) in selectedDepts"
+							:key="index"
+							:value="index"
+							:label="item.name"
+							:index="index"
+						></MyRadioButtonOffOut>
+					</MyRadioButtonGroup>
+					<div style="height: 10px"></div>
+					<MyRadioButtonGroup
+						ref="Big"
+						v-show="selectedDeptBigs.length > 0"
+						v-model="selectedDeptBig"
+						@change="handleSelectedCourses"
+					>
+						<MyRadioButton
+							v-for="(item, index) in selectedDeptBigs"
+							:key="index"
+							:value="index"
+							:label="item.name"
+							:index="index"
+						></MyRadioButton>
+					</MyRadioButtonGroup>
+					<div style="height: 10px"></div>
+					<MyRadioButtonGroup
+						ref="Smail"
+						v-show="selectedDeptSmails.length > 0"
+						v-model="selectedDeptSmail"
+						@change="handleSelectedSmails"
+					>
+						<MyRadioButton
+							v-for="(item, index) in selectedDeptSmails"
+							:key="index"
+							:value="index"
+							:label="item.name"
+							:index="index"
+						></MyRadioButton>
+					</MyRadioButtonGroup>
+				</div>
+			</a-spin>
 		</div>
 		<div style="height: 10px"></div>
 		<div class="line"></div>
@@ -78,36 +80,38 @@
 			<!-- <a-radio-group v-model:value="selectedType" @change="handleTypeChange">
 				<a-radio-button v-for="dept in selectedTypes" :key="dept" :value="dept">{{ dept }}</a-radio-button>
 			</a-radio-group> -->
-			<div style="display: flex; flex-direction: column">
-				<MyRadioButtonGroup
-					ref="TypeBig"
-					v-show="selectedTypesBig.length > 0"
-					v-model="selectedTypeBig"
-					@change="handleTypeChangeBig"
-				>
-					<MyRadioButton
-						v-for="(item, index) in selectedTypesBig"
-						:key="index"
-						:value="index"
-						:label="item.name"
-						:index="index"
-					></MyRadioButton>
-				</MyRadioButtonGroup>
-				<MyRadioButtonGroup
-					ref="Type"
-					v-show="selectedTypes.length > 0"
-					v-model="selectedType"
-					@change="handleTypeChange"
-				>
-					<MyRadioButton
-						v-for="(item, index) in selectedTypes"
-						:key="index"
-						:value="index"
-						:label="item.name"
-						:index="index"
-					></MyRadioButton>
-				</MyRadioButtonGroup>
-			</div>
+			<a-spin :spinning="spinningSelectedTypesBig" tip="">
+				<div style="display: flex; flex-direction: column">
+					<MyRadioButtonGroup
+						ref="TypeBig"
+						v-show="selectedTypesBig.length > 0"
+						v-model="selectedTypeBig"
+						@change="handleTypeChangeBig"
+					>
+						<MyRadioButton
+							v-for="(item, index) in selectedTypesBig"
+							:key="index"
+							:value="index"
+							:label="item.name"
+							:index="index"
+						></MyRadioButton>
+					</MyRadioButtonGroup>
+					<MyRadioButtonGroup
+						ref="Type"
+						v-show="selectedTypes.length > 0"
+						v-model="selectedType"
+						@change="handleTypeChange"
+					>
+						<MyRadioButton
+							v-for="(item, index) in selectedTypes"
+							:key="index"
+							:value="index"
+							:label="item.name"
+							:index="index"
+						></MyRadioButton>
+					</MyRadioButtonGroup>
+				</div>
+			</a-spin>
 		</div>
 		<div style="height: 10px"></div>
 		<div class="line"></div>
@@ -117,16 +121,17 @@
 			<!-- <a-radio-group v-model:value="selectedFormat" @change="handleFormatChange">
 				<a-radio-button v-for="dept in selectedFormats" :key="dept" :value="dept">{{ dept }}</a-radio-button>
 			</a-radio-group> -->
-
-			<MyRadioButtonGroup ref="Format" v-model="selectedFormat" @change="handleFormatChange">
-				<MyRadioButton
-					v-for="(item, index) in selectedFormats"
-					:key="item"
-					:value="index"
-					:label="item.fileExtendName"
-					:index="index"
-				></MyRadioButton>
-			</MyRadioButtonGroup>
+			<a-spin :spinning="spinningSelectedFormats" tip="">
+				<MyRadioButtonGroup ref="Format" v-model="selectedFormat" @change="handleFormatChange">
+					<MyRadioButton
+						v-for="(item, index) in selectedFormats"
+						:key="item"
+						:value="index"
+						:label="item.fileExtendName"
+						:index="index"
+					></MyRadioButton>
+				</MyRadioButtonGroup>
+			</a-spin>
 		</div>
 		<div style="height: 10px"></div>
 		<div class="line"></div>
@@ -190,6 +195,7 @@
 	const selectedTagKeys = ref([])
 
 	const selectedDepts = ref([])
+	const spinningSelectedDepts = ref(false)
 	const selectedDeptBigs = ref([])
 
 	const selectedDeptBigsList = ref([])
@@ -219,8 +225,10 @@
 		'应急程序训练'
 	])
 	const selectedTypesBig = ref([])
+	const spinningSelectedTypesBig = ref(false)
 	const selectedTypes = ref([])
 	const selectedFormats = ref([])
+	const spinningSelectedFormats = ref(false)
 
 	const selectedTypesBigList = ref([])
 	const selectedTypesList = ref([])
@@ -531,7 +539,7 @@
 		// Course.value.setClean('全部')
 		// Type.value.setClean('全部')
 		// Format.value.setClean('全部')
-
+		spinningSelectedDepts.value = true
 		collegeApi.treeAll().then((data) => {
 			selectedDepts.value = data
 			selectedDepts.value.forEach((item) => {
@@ -544,11 +552,13 @@
 					})
 				}
 			})
+			spinningSelectedDepts.value = false
 			console.log('看看最小的', selectedDeptSmailsList.value)
 			// Dept.value.setClean(0)
 			// handleSelectedDept(0)
 			// handleSelectedCourses(0)
 		})
+		spinningSelectedTypesBig.value = true
 		getQueryTreeAll().then((data) => {
 			selectedTypesBig.value = data.data
 			selectedTypesBig.value.forEach((item) => {
@@ -561,9 +571,12 @@
 					})
 				}
 			})
+			spinningSelectedTypesBig.value = false
 		})
+		spinningSelectedFormats.value = true
 		getAllListFileFormat().then((data) => {
 			selectedFormats.value = data.data
+			spinningSelectedFormats.value = false
 		})
 
 		// selectedDepts.value.unshift({ name: '全部' })

+ 2 - 1
src/views/resourceDetails/components/VideoDetails.vue

@@ -271,7 +271,8 @@
 
 					videoFormat.value = itemData.value.suffix
 
-					releaseTime.value = tool.formatTimestamp(itemData.value.uploadTime)
+					// releaseTime.value = tool.formatTimestamp(itemData.value.uploadTime)
+					releaseTime.value = itemData.value.uploadTime
 
 					videoSize.value = itemData.value.FILESIZE ? itemData.value.FILESIZE + 'b' : ''