| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752 |
- <template>
- <div class="page_item step_1_content">
- <!-- 顶部操作栏 -->
- <div class="page_search">
- <div class="search_content">
- <div class="content_left">
- <el-checkbox v-model="isHeadTeacherInvolved" >班主任参与评价</el-checkbox>
- </div>
- <div class="content_right">
- <el-button class="button_border" @click="OpenAddGradeForm">新增年级</el-button>
- <el-button class="button_background" @click="SaveEvaluationData">完成</el-button>
- </div>
- </div>
- </div>
- <div class="page_jg_20" style="flex-shrink: 0;"></div>
- <!-- 年级列表配置 -->
- <div class="option_container">
- <div class="grade_list_option" v-for="(gradeOpt) in gradeOptions" :key="gradeOpt.id">
-
- <!-- 年级头部 -->
- <div class="page_item grade_list_header" >
- <div class="page_search">
- <div class="search_content">
- <div class="content_left">
- <div class="grade_title">
- {{ gradeOpt.gradeName }} (共{{ gradeOpt.subjectCount }}科)
- </div>
- <el-checkbox v-model="gradeOpt.selectionStatus" >选科</el-checkbox>
- <div class="selection_params" v-if="gradeOpt.selectionStatus">
- <span class="param_text">一共 </span>
- <el-input type="number"
- :max="gradeOpt.subjectCount" :min="1"
- v-model="gradeOpt.selectionCount"
- @blur="HandleInputBlur(gradeOpt.subjectCount,gradeOpt,'selectionCount')">
- </el-input>
- <span class="param_text"> 科,需要选择 </span>
- <el-input type="number"
- :max="gradeOpt.subjectCount" :min="1"
- v-model="gradeOpt.needCount"
- @blur="HandleInputBlur(gradeOpt.selectionCount,gradeOpt,'needCount')">
- </el-input>
- <span class="param_text"> 科</span>
- </div>
-
- </div>
- <div class="content_right table_row_option">
- <span class="button_delete" @click="HandleDeleteOpen(gradeOpt,'grade')"> 删除</span>
- </div>
- </div>
- </div>
- </div>
- <!-- 年级内容 -->
- <div class="page_item grade_list_content">
- <el-form
- :inline="false"
- :model="gradeOpt"
- ref="formRef"
- >
- <!-- 科目 -->
- <el-form-item
- label="科目:"
- prop="subjectData"
- :rules="[]"
- >
- <div class="tag_list">
- <el-tag
- v-for="tag in gradeOpt.subjectData"
- :key="tag"
- closable
- :disable-transitions="false"
- @close="HandleDeleteOpen(tag,'subject')"
- >
- {{ tag.name }}
- </el-tag>
- <el-button class="button_border"
- @click="OpenAddSubjectForm(gradeOpt,'subject')">
- + 新增
- </el-button>
- </div>
- </el-form-item>
-
- <!-- 选科 -->
- <el-form-item
- v-if="gradeOpt.selectionStatus"
- label="选科:"
- prop="selectSubjectData"
- :rules="[]"
- >
- <div class="tag_list">
- <el-tag
- v-for="tag in gradeOpt.selectSubjectData"
- :key="tag"
- closable
- :disable-transitions="false"
- @close="HandleDeleteOpen(tag,'selectedSubject')"
- >
- {{ tag.name }}
- </el-tag>
-
- <el-button class="button_border"
- @click="OpenAddSubjectForm(gradeOpt,'selectedSubject')">
- + 新增
- </el-button>
- </div>
- </el-form-item>
-
- <!-- 班级 -->
- <el-form-item
- label="班级:"
- prop="classData"
- :rules="[]"
- >
- <el-checkbox
- v-if="gradeOpt?.classData?.length > 0"
- :indeterminate="gradeOpt?.selectedClassData?.length > 0 && gradeOpt?.selectedClassData?.length < gradeOpt?.classData?.length"
- style="margin-right: 20px;"
- :model-value="(gradeOpt?.selectedClassData?.length == gradeOpt?.classData?.length)"
- @change="(val)=>handleSelectAllClassOrNot(val,gradeOpt)"
- >全选</el-checkbox>
- <el-checkbox-group
- class="check_group_list"
- v-model="gradeOpt.selectedClassData"
- >
- <el-checkbox
- v-for="checkItem in gradeOpt.classData"
- :key="checkItem.id"
- :label="checkItem.name"
- :value="checkItem.id"
- />
- </el-checkbox-group>
- </el-form-item>
-
- </el-form>
- </div>
- </div>
- </div>
-
- <!-- 新增年级弹窗 -->
- <FormDialog
- :submitLoading="addGradeDialogLoading"
- title="选择年级"
- :defaultFormData="defaultGradeFormData"
- :formItemList="addGradeFormItemList"
- :visible="addGradeDialogVisible"
- @close="CloseAddGradeForm"
- @confirm="EditSelectedGrade"
- >
- </FormDialog>
- <!-- 配置科目/选科 弹窗 -->
- <FormDialog
- class="subject_add_form_dialog"
- width="420px"
- :submitLoading="addSubjectDialogLoading"
- :title="subjectTitle"
- :defaultFormData="{}"
- :formItemList="addSubjectFormItemList"
- :visible="addSubjectDialogVisible"
- @close="CloseAddSubjectForm"
- @confirm="SaveGradeSubjectOpt"
- >
- <template #subject>
- <div class="subject_option_container">
- <div class="subject_all_list">
- <div class="description">
- <span class="subject_desc">可选科目</span>
- <span class="operation">新增科目</span>
- </div>
- <div class="tree">
- <TreeList
- v-model:treeRef="optionalSubjetTreeDom"
- :defaultTreeData="allTreeData"
- :showCheckBox="true"
- operation="none"
- @updateSelectedTreeNode="UpdataCheckedSubject"
- >
- </TreeList>
- </div>
- </div>
-
- <div class="subject_selected_list">
- <div class="description">
- <span class="subject_desc">已选科目</span>
- </div>
- <div class="tree">
- <TreeList
- :defaultTreeData="selectedTreeData"
- :showCheckBox="false"
- operation="close"
- @deleteTreeNode="DeleteCheckedSubject"
- >
- </TreeList>
- </div>
- </div>
- </div>
- </template>
- </FormDialog>
- <!-- 删除确认弹窗 -->
- <Dialog
- :submit-loading="deleteDialogLoading"
- :visible="deleteDialogVisible"
- @close="HandleDeleteClose"
- @confirm="HandleDeleteConfirm">
- </Dialog>
-
- </div>
- </template>
- <script setup lang="ts">
- import { ref,onMounted } from 'vue';
- import { useRoute } from 'vue-router';
- import FormDialog from '@/baseComponents/FormDialog.vue';
- import TreeList from '@/baseComponents/TreeList.vue';
- import {addGradeFormItemList, addSubjectFormItemList} from './formDialog'
- import Dialog from '@/baseComponents/Dialog.vue';
- import {
- getEvaluationDataDetailApi, getEvaluationTaskDetailApi,
- addGradeSubjectApi,addGradeSelectedSubjectApi,
- deleteGradeSubjectApi,deleteGradeSelectedSubjectApi,
- addCustomSubjectApi,editCustomSubjectApi,editGradeApi,
- deleteGradeApi,
- getGradeListApi,getSubjectDataApi,getSubjectSelectedDataApi,
- saveEvaluationDataDetailApi
- } from '@/api/step1Component.ts'
- import { ElMessage } from 'element-plus';
- interface subjectOrClassDataItm {
- id:string,
- name:string
- }
- interface gradeOptItm {
- id:string,
- gradeId: string,
- gradeName:string,
- subjectCount:string,
- selectionStatus:number |string, // 0——未勾选 1——已勾选
- selectionCount:number,
- needCount: number, //
- subjectData:subjectOrClassDataItm[],
- selectSubjectData: subjectOrClassDataItm[],
- classData: subjectOrClassDataItm[],
- selectedClassData: subjectOrClassDataItm[],
- }
- const route = useRoute();
- //1.查询评价任务详情 信息
- // 班主任是否参与评价
- const isHeadTeacherInvolved = ref(false);
- // 查询评价管理 任务详情
- const GetEvaluationTaskDetail = async ()=>{
- let res = await getEvaluationTaskDetailApi(route.query.id)
- if(res?.code === 200){
- isHeadTeacherInvolved.value = Boolean(res.data.classMasterStatus); // 0 否 不勾选 || 1 是 勾选
- }
- }
- //2. 获取评价数据详情
- const gradeOptions = ref<gradeOptItm[]>([]); // 年级配置列表数据
- const GetEvaluationDataDetail = async () => {
- let evaluationId = route.query.id;
- let res = await getEvaluationDataDetailApi(evaluationId);
- if(res?.code === 200){
- gradeOptions.value = res.data.map(item=>{
- return {
- ...item,
- // 寻找默认选中的班级 selectStatus 1 选中 0 未选中
- selectedClassData:item.classData?.filter(classItm=>{
- return Number(classItm?.selectStatus) === 1
- }).map(aim=>aim.id),
- selectionStatus: item.selectionStatus ? true : false
- }
- })
- defaultGradeFormData.value.grade = res?.data?.map(item=>{
- return item.id
- }) || []
- }
- };
- //3. 新增年级弹窗操作
- const addGradeDialogVisible = ref(false);
- const addGradeDialogLoading = ref(false);
- const defaultGradeFormData = ref({ grade:[]})
- // 获取可选年级信息
- const GetGradeList = async ()=>{
- let res = await getGradeListApi(route.query.id)
- if(res?.code == 200){
- let gradeOpt = res?.data?.map(itm=>{
- return {
- label:itm.gradeName,
- value:itm.id
- }
- })
- addGradeFormItemList.value = addGradeFormItemList.value.map(item=>{
- if(item.key == 'grade'){
- item.selectList = gradeOpt
- }
- return item
- })
- }
- }
- // 打开新增年级弹窗
- const OpenAddGradeForm = async () => {
- console.log('点击了新增年级');
- addGradeDialogVisible.value = true
- await GetGradeList()
- };
- // 关闭新增年级弹窗
- const CloseAddGradeForm = () => {
- addGradeDialogLoading.value = false
- addGradeDialogVisible.value = false
- };
- // 保存修改后的年级
- const EditSelectedGrade = async()=>{
- addGradeDialogLoading.value = true
- let params = {
- evaluationId: route.query.id,
- gradeData: defaultGradeFormData.value.grade?.map(item=>{
- return {id:item}
- }) || []
- }
- let res = undefined
- try{
- res = await editGradeApi(params)
- }catch{}
- if(res?.code == 200){
- ElMessage.success(res?.msg)
- CloseAddGradeForm()
- // 重新查询评价数据
- await GetEvaluationDataDetail()
- }else{
- addGradeDialogLoading.value = false
- }
- }
- // 4. 配置科目/选科 弹窗操作
- const optionalSubjetTreeDom = ref() //可选列表Tree Dom
- const addSubjectDialogVisible = ref(false);
- const addSubjectDialogLoading = ref(false);
- const subjectTitle = ref('配置科目/选科');
- const currentOpenType = ref('') //当前打开的弹窗类型 subject 、selectedSubject ,grade ,
- const currentOperationRow = ref() //当前操作的行
- const selectedTreeData = ref([]) //已选列表
- const allTreeData = ref([]) //可选列表
- const selectedSubjectIds = ref<any[]>([]) // 当前勾选的科目ids
- // 可选科目列表赋值 和 已选科目列表赋值
- const RenderOptionalAndSubjectTree = async (type,row)=>{
- let res = undefined
- switch(type){
- case 'subject':{
- res = await getSubjectDataApi(row.id)
- break
- }
- case 'selectedSubject':{
- res = await getSubjectSelectedDataApi(row.id)
- break
- }
- }
- if(res?.code == 200){
- allTreeData.value = res.data.map(item=>{
- return {
- label:item.name,
- id:item.id
- }
- })
- selectedTreeData.value = res.data.filter(item=>{
- return item.selectStatus === 1
- })?.map(selectedItm=>{
- return {
- label:selectedItm.name,
- id:selectedItm.id
- }
- }) || []
- }
- }
- // 打开配置科目/选科 弹窗
- const OpenAddSubjectForm = async (row,type) => {
- console.log('点击了配置科目/选科',row);
- addSubjectDialogVisible.value = true
- currentOpenType.value = type
- currentOperationRow.value = row
- switch(type){
- case 'subject':{
- subjectTitle.value = row.gradeName + ' 配置科目'
- break
- }
- case 'selectedSubject':{
- subjectTitle.value = row.gradeName + ' 配置选科'
- break
- }
- }
- await RenderOptionalAndSubjectTree(type,row)
- // 可选科目的默认勾选赋值
- let checkedKeys = selectedTreeData.value.map(item=>item?.id)
- selectedSubjectIds.value = checkedKeys
- optionalSubjetTreeDom.value.setCheckedKeys(checkedKeys)
- };
- // 关闭配置科目/选科 弹窗
- const CloseAddSubjectForm = () => {
- addSubjectDialogVisible.value = false
- allTreeData.value = []
- selectedTreeData.value = []
- currentOpenType.value = ''
- currentOperationRow.value = null
- selectedSubjectIds.value = []
- addSubjectDialogLoading.value = false
- };
- // 更新勾选的 可选科目
- const UpdataCheckedSubject = async (params)=>{
- console.log('当前勾选参数',params)
- selectedSubjectIds.value = params?.map(item=>{
- return item.id
- }) || []
- selectedTreeData.value = params
- }
- // 删除勾选的可选科目
- const DeleteCheckedSubject = async (param)=>{
- const {node,id} = param
- console.log('准备删除的id',id)
- selectedTreeData.value = selectedTreeData.value.filter(item=>{
- return item?.id !== id
- })
- selectedSubjectIds.value = selectedTreeData.value?.map(item=>{
- return item.id
- }) || []
- optionalSubjetTreeDom.value.setCheckedKeys(selectedSubjectIds.value)
- }
- // 保存配置的年级科目
- const SaveGradeSubjectOpt = async ()=>{
- addSubjectDialogLoading.value = true
- let res = undefined
- let addOrUpdateParams = {
- evaluationId:route.query.id,
- evaluationGradeId: currentOperationRow.value.id,
- selectionStatus: currentOperationRow.value.selectionStatus ? 1 : 0,
- selectionCount:currentOperationRow.value.selectionCount,
- needCount:currentOperationRow.value.needCount,
- subjectIds: selectedSubjectIds.value
- }
- try{
- switch(currentOpenType.value){
- case 'subject':{
- res = await addGradeSubjectApi(addOrUpdateParams)
- break
- }
- case 'selectedSubject':{
- res = await addGradeSelectedSubjectApi(addOrUpdateParams)
- break
- }
- }
- }catch{}
-
- if(res?.code == 200){
- ElMessage.success(res?.msg)
- CloseAddSubjectForm()
- await GetEvaluationDataDetail()
- }else{
- addSubjectDialogLoading.value = false
- }
- }
- // 5. 处理班级的全选和全不选
- const handleSelectAllClassOrNot = (selectedValue: any[], gradeOption: any) => {
- console.log('选中的值:', selectedValue);
- console.log('已选的值',gradeOption.selectedClassData)
-
- let selectedClassData = []
- if(selectedValue){
- // 全选
- selectedClassData = gradeOption.classData.map(item => item.id);
- }else{
- // 取消全选
- selectedClassData = []
- }
- console.log('全选/取消后的选项值',selectedClassData)
- gradeOptions.value = gradeOptions.value.map(item => {
- if(item.id === gradeOption.id){
- return {
- ...item,
- selectedClassData,
- }
- }
- return item;
- })
- };
- // 6. 删除弹窗处理逻辑
- const deleteDialogVisible = ref(false);
- const deleteDialogLoading = ref(false);
- const currentDeleteRow = ref(); // 当前编辑的行数据
- // 删除弹窗 确认逻辑
- const HandleDeleteConfirm = async () => {
- deleteDialogLoading.value = true
- let res = undefined
- switch(currentOpenType.value){
- case 'grade': // 年级删除
- res = await deleteGradeApi(currentDeleteRow.value?.id)
- break
- case 'subject': // 科目删除
- res = await deleteGradeSubjectApi(currentDeleteRow.value?.id)
- break
- case 'selectedSubject': // 选科删除
- res = await deleteGradeSelectedSubjectApi(currentDeleteRow.value?.id)
- break
- }
- if(res?.code == 200){
- ElMessage.success(res?.msg)
- HandleDeleteClose()
- // 重查评价数据
- await GetEvaluationDataDetail()
- }else{
- deleteDialogLoading.value = false
- }
- };
- // 关闭 删除弹窗
- const HandleDeleteClose = () => {
- console.log('关闭删除弹窗');
- // 在这里处理关闭删除弹窗的逻辑
- deleteDialogVisible.value = false;
- currentDeleteRow.value = null
- currentOpenType.value = ''
- deleteDialogLoading.value = false
- };
- // 打开 删除弹窗
- const HandleDeleteOpen = (row: any,type) => {
- console.log('打开删除弹窗');
- currentOpenType.value = type
- // 在这里处理打开删除弹窗的逻辑
- deleteDialogVisible.value = true;
- currentDeleteRow.value = row;
- };
- // 7. 保存评价数据
- const SaveEvaluationData = async ()=>{
- let params = {
- evaluationId: route.query.id,
- classMasterStatus: isHeadTeacherInvolved.value ? 1 : 0,
- gradeData: gradeOptions.value.map(item=>{
- if(item.selectionStatus){
- return {
- id: item.id,
- gradeName:item.gradeName,
- selectionStatus: item.selectionStatus ? 1 : 0,
- selectionCount: item.selectionCount,
- needCount:item.needCount,
- classIds: item.selectedClassData
- }
- }else{
- return {
- id: item.id,
- gradeName:item.gradeName,
- selectionStatus: item.selectionStatus ? 1 : 0,
- classIds: item.selectedClassData
- }
- }
- })
- }
- let res = await saveEvaluationDataDetailApi(params)
- if(res?.code == 200){
- ElMessage.success(res?.msg)
- await GetEvaluationDataDetail()
- }
- }
- // input 输入框最大值限制
- const HandleInputBlur = (maxNum:number,row,key)=>{
- if(row[key] > maxNum){
- row[key] = maxNum
- }
- }
- onMounted(async() => {
- console.log('组件挂载完成');
- await GetEvaluationTaskDetail()
- await GetEvaluationDataDetail()
- });
- </script>
- <style lang="scss" scoped>
- /* 右侧内容区样式 */
- .step_1_content {
- flex: 1;
- display: flex;
- flex-direction: column;
- overflow: hidden;
- .option_container{
- display: flex;
- flex-direction: column;
- gap:20px;
- overflow-y: auto;
- .grade_list_option{
- .grade_list_header{
- padding:16px;
- border:solid #E4E7ED 1px;
- border-bottom:none;
- border-radius:10px 10px 0 0;
- .search_content{
- .content_left{
- align-items: center;
- .selection_params{
- font-size: 14px;
- color: #333333;
- }
- }
- }
- }
- .grade_list_content{
- border:solid #E4E7ED 1px;
- border-radius:0 0 10px 10px;
- .tag_list{
- display: flex;
- flex-wrap: wrap;
- gap: 16px;
- align-items: center;
- :deep(.el-tag){
- border:solid #2E64FA 1px;
- background-color: white;
- color:#2E64FA;
- font-size: 14px;
- padding:0px 12px;
- height:36px;
- cursor: pointer;
- }
- .button-new-tag{
- background-color: #F5F7FA;
- color:#2E64FA;
- border:none;
- height: 28px;
- padding:0 10px;
- font-size: 12px;
- }
- }
-
-
- }
- }
- }
- .subject_option_container{
- display: flex;
- gap: 20px;
- width: 100%;
- color:#333333;
- .subject_all_list,
- .subject_selected_list{
- flex: 1;
- display: flex;
- flex-direction: column;
- gap: 10px;
- >div.description{
- display: flex;
- justify-content: space-between;
- .subject_desc{
- font-weight: 600;
- font-size: 16px;
- color: #333333;
- }
- .operation{
- font-weight: 600;
- font-size: 14px;
- color: #2E64FA;
- }
- }
- >.tree{
- border:solid #E4E7ED 1px;
- }
- }
- }
- }
- .subject_add_form_dialog{
- :deep(.el-dialog){
- .el-dialog__body{
- padding: 20px;
- .el-form .el-form-item{
- margin: 0px;
- }
- }
- }
- }
- </style>
|