0.前言

HOJ默认是没有同步班级题单和同步班级题库的功能的,有时候用起来觉得不方便,于是就增加一个。

先来看实现的效果:

1.修改方式

一共三个步骤:

第一步:复制公共题单信息,插入到training表。

第二步:插入mapping_training_category表数据。

第三步:在training_problem表中插入数据。

原作者已经有题单插入的代码了,我们参考一下,主要使用它生成的id,修改一下原方法,让它可以返回id。

@Transactional(rollbackFor = Exception.class)
public Long addTraining(TrainingDTO trainingDto) throws StatusForbiddenException, StatusNotFoundException, StatusFailException {
trainingValidator.validateTraining(trainingDto.getTraining());
AccountProfile userRolesVo = (AccountProfile) SecurityUtils.getSubject().getPrincipal();
boolean isRoot = SecurityUtils.getSubject().hasRole("root");
Long gid = trainingDto.getTraining().getGid();
if (gid == null){
throw new StatusForbiddenException("添加失败,训练所属的团队ID不可为空!");
}
Group group = groupEntityService.getById(gid);
if (group == null || group.getStatus() == 1 && !isRoot) {
throw new StatusNotFoundException("添加训练失败,该团队不存在或已被封禁!");
}
if (!isRoot && !groupValidator.isGroupAdmin(userRolesVo.getUid(), gid)) {
throw new StatusForbiddenException("对不起,您无权限操作!");
}
trainingDto.getTraining().setIsGroup(true);
Training training = trainingDto.getTraining();
trainingEntityService.save(training);
TrainingCategory trainingCategory = trainingDto.getTrainingCategory();
if (trainingCategory.getGid() != null && !Objects.equals(trainingCategory.getGid(), gid)) {
throw new StatusForbiddenException("对不起,您无权限操作!");
}
if (trainingCategory.getId() == null) {
try {
trainingCategory.setGid(gid);
trainingCategoryEntityService.save(trainingCategory);
} catch (Exception ignored) {
QueryWrapper<TrainingCategory> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", trainingCategory.getName());
trainingCategory = trainingCategoryEntityService.getOne(queryWrapper, false);
}
}
boolean isOk = mappingTrainingCategoryEntityService.save(new MappingTrainingCategory()
.setTid(training.getId())
.setCid(trainingCategory.getId()));
if (!isOk) {
throw new StatusFailException("添加失败!");
}
return training.getId();
}
@Transactional(rollbackFor = Exception.class) public Long addTraining(TrainingDTO trainingDto) throws StatusForbiddenException, StatusNotFoundException, StatusFailException { trainingValidator.validateTraining(trainingDto.getTraining()); AccountProfile userRolesVo = (AccountProfile) SecurityUtils.getSubject().getPrincipal(); boolean isRoot = SecurityUtils.getSubject().hasRole("root"); Long gid = trainingDto.getTraining().getGid(); if (gid == null){ throw new StatusForbiddenException("添加失败,训练所属的团队ID不可为空!"); } Group group = groupEntityService.getById(gid); if (group == null || group.getStatus() == 1 && !isRoot) { throw new StatusNotFoundException("添加训练失败,该团队不存在或已被封禁!"); } if (!isRoot && !groupValidator.isGroupAdmin(userRolesVo.getUid(), gid)) { throw new StatusForbiddenException("对不起,您无权限操作!"); } trainingDto.getTraining().setIsGroup(true); Training training = trainingDto.getTraining(); trainingEntityService.save(training); TrainingCategory trainingCategory = trainingDto.getTrainingCategory(); if (trainingCategory.getGid() != null && !Objects.equals(trainingCategory.getGid(), gid)) { throw new StatusForbiddenException("对不起,您无权限操作!"); } if (trainingCategory.getId() == null) { try { trainingCategory.setGid(gid); trainingCategoryEntityService.save(trainingCategory); } catch (Exception ignored) { QueryWrapper<TrainingCategory> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("name", trainingCategory.getName()); trainingCategory = trainingCategoryEntityService.getOne(queryWrapper, false); } } boolean isOk = mappingTrainingCategoryEntityService.save(new MappingTrainingCategory() .setTid(training.getId()) .setCid(trainingCategory.getId())); if (!isOk) { throw new StatusFailException("添加失败!"); } return training.getId(); }
@Transactional(rollbackFor = Exception.class)
    public Long addTraining(TrainingDTO trainingDto) throws StatusForbiddenException, StatusNotFoundException, StatusFailException {

        trainingValidator.validateTraining(trainingDto.getTraining());

        AccountProfile userRolesVo = (AccountProfile) SecurityUtils.getSubject().getPrincipal();

        boolean isRoot = SecurityUtils.getSubject().hasRole("root");

        Long gid = trainingDto.getTraining().getGid();
        if (gid == null){
            throw new StatusForbiddenException("添加失败,训练所属的团队ID不可为空!");
        }

        Group group = groupEntityService.getById(gid);

        if (group == null || group.getStatus() == 1 && !isRoot) {
            throw new StatusNotFoundException("添加训练失败,该团队不存在或已被封禁!");
        }

        if (!isRoot && !groupValidator.isGroupAdmin(userRolesVo.getUid(), gid)) {
            throw new StatusForbiddenException("对不起,您无权限操作!");
        }

        trainingDto.getTraining().setIsGroup(true);

        Training training = trainingDto.getTraining();
        trainingEntityService.save(training);
        TrainingCategory trainingCategory = trainingDto.getTrainingCategory();

        if (trainingCategory.getGid() != null && !Objects.equals(trainingCategory.getGid(), gid)) {
            throw new StatusForbiddenException("对不起,您无权限操作!");
        }

        if (trainingCategory.getId() == null) {
            try {
                trainingCategory.setGid(gid);
                trainingCategoryEntityService.save(trainingCategory);
            } catch (Exception ignored) {
                QueryWrapper<TrainingCategory> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("name", trainingCategory.getName());
                trainingCategory = trainingCategoryEntityService.getOne(queryWrapper, false);
            }
        }

        boolean isOk = mappingTrainingCategoryEntityService.save(new MappingTrainingCategory()
                .setTid(training.getId())
                .setCid(trainingCategory.getId()));
        if (!isOk) {
            throw new StatusFailException("添加失败!");
        }
        return training.getId();
    }

传入的参数有两个,第一个就是班级/团队的id。

前端设计的一个子组件:

// 将公共题单的某一些题单同步到某个班级的题单中
<template>
<div>
<el-card>
<el-button
icon="el-icon-attract"
size="mini"
@click.native="syncProblem()"
type="primary"
>
{{$t('m.Sync_Train')}}
</el-button>
<vxe-table
border="inner"
:data="trainingList"
ref="xTable"
align="center"
@checkbox-change="handleSelectionChange"
@checkbox-all="handlechangeAll"
>
<vxe-table-column type="checkbox" width="60"></vxe-table-column>
<vxe-table-column
field="title"
:title="$t('m.Title')"
align="center"
></vxe-table-column>
<vxe-table-column
field="categoryName"
:title="$t('m.Category')"
align="center"
></vxe-table-column>
<vxe-table-column
field="problemCount"
:title="$t('m.Problem_Number')"
align="center"
></vxe-table-column>
</vxe-table>
<Pagination
:total="total"
:page-size="limit"
@on-change="currentChange"
:current.sync="currentPage"
@on-page-size-change="onPageSizeChange"
:layout="'prev, pager, next, sizes'"
></Pagination>
</el-card>
</div>
</template>
<script>
import api from "@/common/api";
import Pagination from "@/components/oj/common/Pagination";
import mMessage from "@/common/message";
export default {
name: "SyncGroupList",
components: {
Pagination,
mMessage,
},
props: {
// 班级/团队id
groupID: {
type: Number,
default: null,
},
},
data() {
return {
loading: false,
//默认查询,权限只能是公开的
query: {
keyword: "",
categoryId: null,
auth: "Public",
},
total: 0,
currentPage: 1,
limit: 10,
trainingList: [], //训练列表
selectedTrain:[], //选中的
};
},
methods: {
init() {
console.log("sync init");
this.getTrainingList();
},
// 获取所有题单列表
getTrainingList() {
console.log("getTrainingList");
console.log(this.groupID);
this.loading = true;
api.getTrainingList(this.currentPage, this.limit, this.query).then(
(res) => {
console.log(res);
this.trainingList = res.data.data.records;
this.total = res.data.data.total;
this.loading = false;
},
(err) => {
this.loading = false;
}
);
},
currentChange(page) {
this.currentPage = page;
this.getTrainingList();
},
onPageSizeChange(pageSize) {
this.limit = pageSize;
this.getTrainingList();
},
handleSelectionChange({ records }){
this.selectedTrain = [];
for (let num = 0; num < records.length; num++) {
this.selectedTrain.push(records[num].id);
}
},
//全选
handlechangeAll(){
let trainList = this.$refs.xTable.getCheckboxRecords();
this.selectedTrain = [];
for (let num = 0; num < trainList.length; num++) {
this.selectedTrain.push(trainList[num].id);
}
},
//选中同步题目
syncProblem(){
// console.log(this.selectedTrain)
if(this.selectedTrain.length==0){
mMessage.warning("没有选中任何题单");
}else{
let params={
groupID:this.groupID, //要同步到哪个班级
selectedTrain:this.selectedTrain //同步哪些题单
}
console.log(params)
api.syncPublicTrainToGroupTrain(params).then(
(res) => {
console.log(res);
if(res.data.msg=="success"){
mMessage.success(this.$i18n.t('m.Add_Success'));
}
this.syncGroupListClose()
},
(err) => {
mMessage.error(this.$i18n.t('m.Sync_Error'))
}
);
}
},
syncGroupListClose(){
console.log("syncGroupListClose")
this.$emit('syncGroupListClose');
}
},
};
</script>
// 将公共题单的某一些题单同步到某个班级的题单中 <template> <div> <el-card> <el-button icon="el-icon-attract" size="mini" @click.native="syncProblem()" type="primary" > {{t('m.Sync_Train')}}            </el-button>      <vxe-table       border="inner"       :data="trainingList"      ref="xTable"       align="center"      @checkbox-change="handleSelectionChange"      @checkbox-all="handlechangeAll"      >        <vxe-table-column type="checkbox" width="60"></vxe-table-column>        <vxe-table-column          field="title"          :title="t('m.Title')" align="center" ></vxe-table-column> <vxe-table-column field="categoryName" :title="t(m.Category)"align="center"></vxetablecolumn><vxetablecolumnfield="problemCount":title="t('m.Problem_Number')" align="center" ></vxe-table-column> </vxe-table> <Pagination :total="total" :page-size="limit" @on-change="currentChange" :current.sync="currentPage" @on-page-size-change="onPageSizeChange" :layout="'prev, pager, next, sizes'" ></Pagination> </el-card> </div> </template> <script> import api from "@/common/api"; import Pagination from "@/components/oj/common/Pagination"; import mMessage from "@/common/message"; export default { name: "SyncGroupList", components: { Pagination, mMessage, }, props: { // 班级/团队id groupID: { type: Number, default: null, }, }, data() { return { loading: false, //默认查询,权限只能是公开的 query: { keyword: "", categoryId: null, auth: "Public", }, total: 0, currentPage: 1, limit: 10, trainingList: [], //训练列表 selectedTrain:[], //选中的 }; }, methods: { init() { console.log("sync init"); this.getTrainingList(); }, // 获取所有题单列表 getTrainingList() { console.log("getTrainingList"); console.log(this.groupID); this.loading = true; api.getTrainingList(this.currentPage, this.limit, this.query).then( (res) => { console.log(res); this.trainingList = res.data.data.records; this.total = res.data.data.total; this.loading = false; }, (err) => { this.loading = false; } ); }, currentChange(page) { this.currentPage = page; this.getTrainingList(); }, onPageSizeChange(pageSize) { this.limit = pageSize; this.getTrainingList(); }, handleSelectionChange({ records }){ this.selectedTrain = []; for (let num = 0; num < records.length; num++) { this.selectedTrain.push(records[num].id); } }, //全选 handlechangeAll(){ let trainList = this.$refs.xTable.getCheckboxRecords(); this.selectedTrain = []; for (let num = 0; num < trainList.length; num++) { this.selectedTrain.push(trainList[num].id); } }, //选中同步题目 syncProblem(){ // console.log(this.selectedTrain) if(this.selectedTrain.length==0){ mMessage.warning("没有选中任何题单"); }else{ let params={ groupID:this.groupID, //要同步到哪个班级 selectedTrain:this.selectedTrain //同步哪些题单 } console.log(params) api.syncPublicTrainToGroupTrain(params).then( (res) => { console.log(res); if(res.data.msg=="success"){ mMessage.success(this.$i18n.t('m.Add_Success')); } this.syncGroupListClose() }, (err) => { mMessage.error(this.$i18n.t('m.Sync_Error')) } ); } }, syncGroupListClose(){ console.log("syncGroupListClose") this.$emit('syncGroupListClose'); } }, }; </script>
// 将公共题单的某一些题单同步到某个班级的题单中
<template>
  <div>
    <el-card>
       <el-button
              icon="el-icon-attract"
              size="mini"
              @click.native="syncProblem()"
              type="primary"
            >
            {{$t('m.Sync_Train')}}
            </el-button>
      <vxe-table 
      border="inner" 
      :data="trainingList"
      ref="xTable" 
      align="center"
      @checkbox-change="handleSelectionChange"
      @checkbox-all="handlechangeAll"
      >
        <vxe-table-column type="checkbox" width="60"></vxe-table-column>
        <vxe-table-column
          field="title"
          :title="$t('m.Title')"
          align="center"
        ></vxe-table-column>
        <vxe-table-column
          field="categoryName"
          :title="$t('m.Category')"
          align="center"
        ></vxe-table-column>
        <vxe-table-column
          field="problemCount"
          :title="$t('m.Problem_Number')"
          align="center"
        ></vxe-table-column>
      </vxe-table>
      <Pagination
        :total="total"
        :page-size="limit"
        @on-change="currentChange"
        :current.sync="currentPage"
        @on-page-size-change="onPageSizeChange"
        :layout="'prev, pager, next, sizes'"
      ></Pagination>
    </el-card>
  </div>
</template>

<script>
import api from "@/common/api";
import Pagination from "@/components/oj/common/Pagination";
import mMessage from "@/common/message";
export default {
  name: "SyncGroupList",
  components: {
    Pagination,
    mMessage,
  },
  props: {
    // 班级/团队id
    groupID: {
      type: Number,
      default: null,
    },
  },
  data() {
    return {
      loading: false,
      //默认查询,权限只能是公开的
      query: {
        keyword: "",
        categoryId: null,
        auth: "Public",
      },
      total: 0,
      currentPage: 1,
      limit: 10,
      trainingList: [], //训练列表
      selectedTrain:[], //选中的
    };
  },
  methods: {
    init() {
      console.log("sync init");
      this.getTrainingList();
    },
    // 获取所有题单列表
    getTrainingList() {
      console.log("getTrainingList");
      console.log(this.groupID);
      this.loading = true;
      api.getTrainingList(this.currentPage, this.limit, this.query).then(
        (res) => {
          console.log(res);
          this.trainingList = res.data.data.records;
          this.total = res.data.data.total;
          this.loading = false;
        },
        (err) => {
          this.loading = false;
        }
      );
    },
    currentChange(page) {
      this.currentPage = page;
      this.getTrainingList();
    },
    onPageSizeChange(pageSize) {
      this.limit = pageSize;
      this.getTrainingList();
    },

    handleSelectionChange({ records }){
       this.selectedTrain = [];
      for (let num = 0; num < records.length; num++) {
        this.selectedTrain.push(records[num].id);
      }
    },
    //全选
    handlechangeAll(){
      let trainList = this.$refs.xTable.getCheckboxRecords();
      this.selectedTrain = [];
      for (let num = 0; num < trainList.length; num++) {
        this.selectedTrain.push(trainList[num].id);
      }
    }, 
    //选中同步题目
    syncProblem(){
      // console.log(this.selectedTrain)
      if(this.selectedTrain.length==0){
        mMessage.warning("没有选中任何题单");
      }else{
        let params={
          groupID:this.groupID, //要同步到哪个班级
          selectedTrain:this.selectedTrain  //同步哪些题单
        }
        console.log(params)
        api.syncPublicTrainToGroupTrain(params).then(
        (res) => {
          console.log(res);
          if(res.data.msg=="success"){
            mMessage.success(this.$i18n.t('m.Add_Success'));
          }
          this.syncGroupListClose()
        },
        (err) => {
          mMessage.error(this.$i18n.t('m.Sync_Error'))
        }
      );
      }
    },

    syncGroupListClose(){
      console.log("syncGroupListClose")
      this.$emit('syncGroupListClose');
    }
  },
};
</script>

然后在父组件中引用:

<template>
<el-card>
<div class="filter-row">
<el-row>
<el-col :md="3" :xs="24">
<span class="title">{{ $t("m.Group_Training") }}</span>
</el-col>
<!-- 创建团队新题单 -->
<el-col
:md="18"
:xs="24"
v-if="
(isSuperAdmin || isGroupAdmin) && !problemPage && !editProblemPage
"
>
<el-button
v-if="!editPage"
:type="createPage ? 'warning' : 'primary'"
size="small"
@click="handleCreatePage"
:icon="createPage ? 'el-icon-back' : 'el-icon-plus'"
>{{
createPage ? $t("m.Back_To_Admin_Training_List") : $t("m.Create")
}}</el-button
>
<!-- 新增主题库同步到班级题库 -->
<el-button
v-if="!editPage && !createPage"
:type="createPage ? 'warning' : 'primary'"
size="small"
@click="handleTrainingToGroup"
:icon="createPage ? 'el-icon-back' : 'el-icon-plus'"
>{{ $t("m.Training_To_Group") }}</el-button
>
<el-button
v-if="editPage && adminPage"
type="warning"
size="small"
@click="handleEditPage"
icon="el-icon-back"
>{{ $t("m.Back_To_Admin_Training_List") }}</el-button
>
<el-button
:type="adminPage ? 'danger' : 'success'"
v-if="!editPage && !createPage"
size="small"
@click="handleAdminPage"
:icon="adminPage ? 'el-icon-back' : 'el-icon-s-opportunity'"
>{{
adminPage ? $t("m.Back_To_Training_List") : $t("m.Training_Admin")
}}</el-button
>
</el-col>
<el-col
:md="18"
:xs="24"
v-else-if="
(isSuperAdmin || isGroupAdmin) && problemPage && !editProblemPage
"
>
<el-button
type="primary"
size="small"
@click="publicPage = true"
icon="el-icon-plus"
>{{ $t("m.Add_From_Public_Problem") }}</el-button
>
<el-button
type="success"
size="small"
@click="handleGroupPage"
icon="el-icon-plus"
>{{ $t("m.Add_From_Group_Problem") }}</el-button
>
<el-button
type="warning"
size="small"
@click="handleProblemPage(null)"
icon="el-icon-back"
>{{ $t("m.Back_To_Admin_Training_List") }}</el-button
>
</el-col>
<el-col
:md="18"
:xs="24"
v-else-if="(isSuperAdmin || isGroupAdmin) && editProblemPage"
>
<el-button
type="primary"
size="small"
@click="handleEditProblemPage"
icon="el-icon-back"
>{{ $t("m.Back_Admin_Training_Problem_List") }}</el-button
>`
</el-col>
</el-row>
</div>
<template v-if="!adminPage && !createPage && !problemPage">
<vxe-table
border="inner"
stripe
auto-resize
highlight-hover-row
:data="trainingList"
:loading="loading"
align="center"
@cell-click="goGroupTraining"
>
<vxe-table-column
field="rank"
:title="$t('m.Number')"
min-width="60"
show-overflow
>
</vxe-table-column>
<vxe-table-column
field="title"
:title="$t('m.Title')"
min-width="200"
align="center"
>
</vxe-table-column>
<vxe-table-column
field="auth"
:title="$t('m.Auth')"
min-width="100"
align="center"
>
<template v-slot="{ row }">
<el-tag :type="TRAINING_TYPE[row.auth]['color']" effect="dark">
{{ $t("m.Training_" + row.auth) }}
</el-tag>
</template>
</vxe-table-column>
<vxe-table-column
field="categoryName"
:title="$t('m.Category')"
min-width="130"
align="center"
>
<template v-slot="{ row }">
<el-tag
size="large"
:style="
'background-color: #fff; color: ' +
row.categoryColor +
'; border-color: ' +
row.categoryColor +
';'
"
>{{ row.categoryName }}</el-tag
>
</template>
</vxe-table-column>
<vxe-table-column
field="acCount"
:title="$t('m.Progress')"
min-width="120"
align="center"
>
<template v-slot="{ row }">
<span>
<el-tooltip
effect="dark"
:content="row.acCount + '/' + row.problemCount"
placement="top"
>
<el-progress
:text-inside="true"
:stroke-width="20"
:percentage="getPassingRate(row.acCount, row.problemCount)"
></el-progress>
</el-tooltip>
</span>
</template>
</vxe-table-column>
<vxe-table-column
field="problemCount"
:title="$t('m.Problem_Number')"
min-width="70"
align="center"
>
</vxe-table-column>
<vxe-table-column
field="author"
:title="$t('m.Author')"
min-width="130"
align="center"
show-overflow
>
</vxe-table-column>
<vxe-table-column
field="gmtModified"
:title="$t('m.Recent_Update')"
min-width="96"
align="center"
show-overflow
>
<template v-slot="{ row }">
<span>
<el-tooltip
:content="row.gmtModified | localtime"
placement="top"
>
<span>{{ row.gmtModified | fromNow }}</span>
</el-tooltip>
</span>
</template>
</vxe-table-column>
</vxe-table>
<Pagination
:total="total"
:page-size="limit"
@on-change="currentChange"
:current.sync="currentPage"
@on-page-size-change="onPageSizeChange"
:layout="'prev, pager, next, sizes'"
></Pagination>
</template>
<TrainingList
ref="trainingList"
v-if="adminPage && !createPage && !problemPage"
@handleEditPage="handleEditPage"
@currentChange="currentChange"
@handleProblemPage="handleProblemPage"
></TrainingList>
<TrainingProblemList
v-if="problemPage"
:trainingId="trainingId"
@currentChangeProblem="currentChangeProblem"
@handleEditProblemPage="handleEditProblemPage"
ref="trainingProblemList"
>
</TrainingProblemList>
<Training
v-if="createPage && !editPage && !problemPage"
mode="add"
:title="$t('m.Create_Training')"
apiMethod="addGroupTraining"
@handleCreatePage="handleCreatePage"
@currentChange="currentChange"
></Training>
<!-- 团队添加公共题目 -->
<el-dialog
:title="$t('m.Add_Training_Problem')"
width="90%"
:visible.sync="publicPage"
:close-on-click-modal="false"
>
<AddPublicProblem
v-if="publicPage"
:trainingId="trainingId"
apiMethod="getGroupTrainingProblemList"
@currentChangeProblem="currentChangeProblem"
ref="addPublicProblem"
></AddPublicProblem>
</el-dialog>
<!-- 团队添加团队题目 -->
<el-dialog
:title="$t('m.Add_Training_Problem')"
width="350px"
:visible.sync="groupPage"
:close-on-click-modal="false"
>
<AddGroupProblem
:trainingId="trainingId"
@currentChangeProblem="currentChangeProblem"
@handleGroupPage="handleGroupPage"
></AddGroupProblem>
</el-dialog>
<!-- 打开公共题单弹窗 -->
<el-dialog
:title="$t('m.Training_To_Group')"
width="850px"
:visible.sync="groupListPage"
:close-on-click-modal="true"
>
<SyncGroupList
:groupID="groupID"
@syncGroupListClose="syncGroupListClose"
ref="SyncGroupListChild"
> </SyncGroupList>
</el-dialog>
</el-card>
</template>
<script>
import { mapGetters } from "vuex";
import { TRAINING_TYPE } from "@/common/constants";
import Pagination from "@/components/oj/common/Pagination";
import TrainingList from "@/components/oj/group/TrainingList";
import Training from "@/components/oj/group/Training";
import TrainingProblemList from "@/components/oj/group/TrainingProblemList";
import AddPublicProblem from "@/components/oj/group/AddPublicProblem.vue";
import AddGroupProblem from "@/components/oj/group/AddGroupProblem.vue";
import SyncGroupList from "@/components/oj/group/SyncGroupList.vue";
import api from "@/common/api";
export default {
name: "GroupTrainingList",
components: {
Pagination,
TrainingList,
Training,
TrainingProblemList,
AddPublicProblem,
AddGroupProblem,
SyncGroupList,
},
data() {
return {
total: 0,
currentPage: 1,
limit: 10,
trainingList: [],
TRAINING_TYPE: {},
loading: false,
adminPage: false,
createPage: false,
editPage: false,
problemPage: false,
publicPage: false,
groupPage: false,
groupListPage: false, //打开同步题单弹窗
editProblemPage: false,
trainingId: null,
groupID:"", //团队/班级id
};
},
mounted() {
this.TRAINING_TYPE = Object.assign({}, TRAINING_TYPE);
this.init();
},
methods: {
init() {
this.groupID=this.$route.params.groupID
this.getGroupTrainingList();
},
onPageSizeChange(pageSize) {
this.limit = pageSize;
this.init();
},
currentChange(page) {
this.currentPage = page;
this.init();
},
currentChangeProblem() {
this.$refs.trainingProblemList.currentChange(1);
},
getGroupTrainingList() {
this.trainingList = [];
this.loading = true;
api
.getGroupTrainingList(
this.currentPage,
this.limit,
this.$route.params.groupID
)
.then(
(res) => {
this.trainingList = res.data.data.records;
console.log("团队this.trainingList ", this.trainingList);
this.total = res.data.data.total;
this.loading = false;
},
(err) => {
this.loading = false;
}
);
},
goGroupTraining(event) {
this.$router.push({
name: "GroupTrainingDetails",
params: {
trainingID: event.row.id,
groupID: this.$route.params.groupID,
},
});
},
handleCreatePage() {
this.createPage = !this.createPage;
},
// 公共训练同步至班级
handleTrainingToGroup() {
console.log("公共训练同步至班级");
this.groupListPage = true;
setTimeout(() => {
this.$refs.SyncGroupListChild.getTrainingList();
});
},
//关闭弹窗
syncGroupListClose(){
this.groupListPage=false
this.getGroupTrainingList()
},
handleEditPage() {
this.editPage = !this.editPage;
this.$refs.trainingList.editPage = this.editPage;
},
handleAdminPage() {
this.adminPage = !this.adminPage;
this.createPage = false;
this.editPage = false;
},
handleProblemPage(trainingId) {
this.trainingId = trainingId;
this.problemPage = !this.problemPage;
},
handleGroupPage() {
this.groupPage = !this.groupPage;
},
handleEditProblemPage() {
this.editProblemPage = !this.editProblemPage;
this.$refs.trainingProblemList.editPage = this.editProblemPage;
},
getPassingRate(ac, total) {
if (!total) {
return 0;
}
return ((ac / total) * 100).toFixed(2);
},
},
computed: {
...mapGetters(["isAuthenticated", "isSuperAdmin", "isGroupAdmin"]),
},
};
</script>
<style scoped>
.title {
font-size: 20px;
vertical-align: middle;
float: left;
}
.filter-row {
margin-bottom: 5px;
text-align: center;
}
@media screen and (max-width: 768px) {
.filter-row span {
margin-left: 5px;
margin-right: 5px;
}
}
@media screen and (min-width: 768px) {
.filter-row span {
margin-left: 10px;
margin-right: 10px;
}
}
</style>
<template> <el-card> <div class="filter-row"> <el-row> <el-col :md="3" :xs="24"> <span class="title">{{ t("m.Group_Training") }}</span>        </el-col>        <!-- 创建团队新题单 -->        <el-col          :md="18"          :xs="24"          v-if="            (isSuperAdmin || isGroupAdmin) && !problemPage && !editProblemPage          "        >          <el-button            v-if="!editPage"            :type="createPage ? 'warning' : 'primary'"            size="small"            @click="handleCreatePage"            :icon="createPage ? 'el-icon-back' : 'el-icon-plus'"            >{{              createPage ? $t("m.Back_To_Admin_Training_List") : $t("m.Create")            }}</el-button          >          <!-- 新增主题库同步到班级题库 -->          <el-button            v-if="!editPage && !createPage"            :type="createPage ? 'warning' : 'primary'"            size="small"            @click="handleTrainingToGroup"            :icon="createPage ? 'el-icon-back' : 'el-icon-plus'"            >{{ $t("m.Training_To_Group") }}</el-button          >          <el-button            v-if="editPage && adminPage"            type="warning"            size="small"            @click="handleEditPage"            icon="el-icon-back"            >{{ $t("m.Back_To_Admin_Training_List") }}</el-button          >          <el-button            :type="adminPage ? 'danger' : 'success'"            v-if="!editPage && !createPage"            size="small"            @click="handleAdminPage"            :icon="adminPage ? 'el-icon-back' : 'el-icon-s-opportunity'"            >{{              adminPage ? $t("m.Back_To_Training_List") : $t("m.Training_Admin")            }}</el-button          >        </el-col>        <el-col          :md="18"          :xs="24"          v-else-if="            (isSuperAdmin || isGroupAdmin) && problemPage && !editProblemPage          "        >          <el-button            type="primary"            size="small"            @click="publicPage = true"            icon="el-icon-plus"            >{{ $t("m.Add_From_Public_Problem") }}</el-button          >          <el-button            type="success"            size="small"            @click="handleGroupPage"            icon="el-icon-plus"            >{{ $t("m.Add_From_Group_Problem") }}</el-button          >          <el-button            type="warning"            size="small"            @click="handleProblemPage(null)"            icon="el-icon-back"            >{{ $t("m.Back_To_Admin_Training_List") }}</el-button          >        </el-col>        <el-col          :md="18"          :xs="24"          v-else-if="(isSuperAdmin || isGroupAdmin) && editProblemPage"        >          <el-button            type="primary"            size="small"            @click="handleEditProblemPage"            icon="el-icon-back"            >{{ $t("m.Back_Admin_Training_Problem_List") }}</el-button          >`        </el-col>      </el-row>    </div>    <template v-if="!adminPage && !createPage && !problemPage">      <vxe-table        border="inner"        stripe        auto-resize        highlight-hover-row        :data="trainingList"        :loading="loading"        align="center"        @cell-click="goGroupTraining"      >        <vxe-table-column          field="rank"          :title="t('m.Number')" min-width="60" show-overflow > </vxe-table-column> <vxe-table-column field="title" :title="t(m.Title)"minwidth="200"align="center"></vxetablecolumn><vxetablecolumnfield="auth":title="t('m.Auth')" min-width="100" align="center" > <template v-slot="{ row }"> <el-tag :type="TRAINING_TYPE[row.auth]['color']" effect="dark"> {{ t("m.Training_" + row.auth) }}            </el-tag>          </template>        </vxe-table-column>        <vxe-table-column          field="categoryName"          :title="t('m.Category')" min-width="130" align="center" > <template v-slot="{ row }"> <el-tag size="large" :style=" 'background-color: #fff; color: ' + row.categoryColor + '; border-color: ' + row.categoryColor + ';' " >{{ row.categoryName }}</el-tag > </template> </vxe-table-column> <vxe-table-column field="acCount" :title="t(m.Progress)"minwidth="120"align="center"><templatevslot="row"><span><eltooltipeffect="dark":content="row.acCount+/+row.problemCount"placement="top"><elprogress:textinside="true":strokewidth="20":percentage="getPassingRate(row.acCount,row.problemCount)"></elprogress></eltooltip></span></template></vxetablecolumn><vxetablecolumnfield="problemCount":title="t('m.Problem_Number')" min-width="70" align="center" > </vxe-table-column> <vxe-table-column field="author" :title="t(m.Author)"minwidth="130"align="center"showoverflow></vxetablecolumn><vxetablecolumnfield="gmtModified":title="t('m.Recent_Update')" min-width="96" align="center" show-overflow > <template v-slot="{ row }"> <span> <el-tooltip :content="row.gmtModified | localtime" placement="top" > <span>{{ row.gmtModified | fromNow }}</span> </el-tooltip> </span> </template> </vxe-table-column> </vxe-table> <Pagination :total="total" :page-size="limit" @on-change="currentChange" :current.sync="currentPage" @on-page-size-change="onPageSizeChange" :layout="'prev, pager, next, sizes'" ></Pagination> </template> <TrainingList ref="trainingList" v-if="adminPage && !createPage && !problemPage" @handleEditPage="handleEditPage" @currentChange="currentChange" @handleProblemPage="handleProblemPage" ></TrainingList> <TrainingProblemList v-if="problemPage" :trainingId="trainingId" @currentChangeProblem="currentChangeProblem" @handleEditProblemPage="handleEditProblemPage" ref="trainingProblemList" > </TrainingProblemList> <Training v-if="createPage && !editPage && !problemPage" mode="add" :title="t(m.CreateTraining)"apiMethod="addGroupTraining"@handleCreatePage="handleCreatePage"@currentChange="currentChange"></Training><!><eldialog:title="t('m.Add_Training_Problem')" width="90%" :visible.sync="publicPage" :close-on-click-modal="false" > <AddPublicProblem v-if="publicPage" :trainingId="trainingId" apiMethod="getGroupTrainingProblemList" @currentChangeProblem="currentChangeProblem" ref="addPublicProblem" ></AddPublicProblem> </el-dialog> <!-- 团队添加团队题目 --> <el-dialog :title="t(m.AddTrainingProblem)"width="350px":visible.sync="groupPage":closeonclickmodal="false"><AddGroupProblem:trainingId="trainingId"@currentChangeProblem="currentChangeProblem"@handleGroupPage="handleGroupPage"></AddGroupProblem></eldialog><!><eldialog:title="t('m.Training_To_Group')" width="850px" :visible.sync="groupListPage" :close-on-click-modal="true" > <SyncGroupList :groupID="groupID" @syncGroupListClose="syncGroupListClose" ref="SyncGroupListChild" > </SyncGroupList> </el-dialog> </el-card> </template> <script> import { mapGetters } from "vuex"; import { TRAINING_TYPE } from "@/common/constants"; import Pagination from "@/components/oj/common/Pagination"; import TrainingList from "@/components/oj/group/TrainingList"; import Training from "@/components/oj/group/Training"; import TrainingProblemList from "@/components/oj/group/TrainingProblemList"; import AddPublicProblem from "@/components/oj/group/AddPublicProblem.vue"; import AddGroupProblem from "@/components/oj/group/AddGroupProblem.vue"; import SyncGroupList from "@/components/oj/group/SyncGroupList.vue"; import api from "@/common/api"; export default { name: "GroupTrainingList", components: { Pagination, TrainingList, Training, TrainingProblemList, AddPublicProblem, AddGroupProblem, SyncGroupList, }, data() { return { total: 0, currentPage: 1, limit: 10, trainingList: [], TRAINING_TYPE: {}, loading: false, adminPage: false, createPage: false, editPage: false, problemPage: false, publicPage: false, groupPage: false, groupListPage: false, //打开同步题单弹窗 editProblemPage: false, trainingId: null, groupID:"", //团队/班级id }; }, mounted() { this.TRAINING_TYPE = Object.assign({}, TRAINING_TYPE); this.init(); }, methods: { init() { this.groupID=this.$route.params.groupID this.getGroupTrainingList(); }, onPageSizeChange(pageSize) { this.limit = pageSize; this.init(); }, currentChange(page) { this.currentPage = page; this.init(); }, currentChangeProblem() { this.$refs.trainingProblemList.currentChange(1); }, getGroupTrainingList() { this.trainingList = []; this.loading = true; api .getGroupTrainingList( this.currentPage, this.limit, this.$route.params.groupID ) .then( (res) => { this.trainingList = res.data.data.records; console.log("团队this.trainingList ", this.trainingList); this.total = res.data.data.total; this.loading = false; }, (err) => { this.loading = false; } ); }, goGroupTraining(event) { this.$router.push({ name: "GroupTrainingDetails", params: { trainingID: event.row.id, groupID: this.$route.params.groupID, }, }); }, handleCreatePage() { this.createPage = !this.createPage; }, // 公共训练同步至班级 handleTrainingToGroup() { console.log("公共训练同步至班级"); this.groupListPage = true; setTimeout(() => { this.$refs.SyncGroupListChild.getTrainingList(); }); }, //关闭弹窗 syncGroupListClose(){ this.groupListPage=false this.getGroupTrainingList() }, handleEditPage() { this.editPage = !this.editPage; this.$refs.trainingList.editPage = this.editPage; }, handleAdminPage() { this.adminPage = !this.adminPage; this.createPage = false; this.editPage = false; }, handleProblemPage(trainingId) { this.trainingId = trainingId; this.problemPage = !this.problemPage; }, handleGroupPage() { this.groupPage = !this.groupPage; }, handleEditProblemPage() { this.editProblemPage = !this.editProblemPage; this.$refs.trainingProblemList.editPage = this.editProblemPage; }, getPassingRate(ac, total) { if (!total) { return 0; } return ((ac / total) * 100).toFixed(2); }, }, computed: { ...mapGetters(["isAuthenticated", "isSuperAdmin", "isGroupAdmin"]), }, }; </script> <style scoped> .title { font-size: 20px; vertical-align: middle; float: left; } .filter-row { margin-bottom: 5px; text-align: center; } @media screen and (max-width: 768px) { .filter-row span { margin-left: 5px; margin-right: 5px; } } @media screen and (min-width: 768px) { .filter-row span { margin-left: 10px; margin-right: 10px; } } </style>
<template>
  <el-card>
    <div class="filter-row">
      <el-row>
        <el-col :md="3" :xs="24">
          <span class="title">{{ $t("m.Group_Training") }}</span>
        </el-col>

        <!-- 创建团队新题单 -->
        <el-col
          :md="18"
          :xs="24"
          v-if="
            (isSuperAdmin || isGroupAdmin) && !problemPage && !editProblemPage
          "
        >
          <el-button
            v-if="!editPage"
            :type="createPage ? 'warning' : 'primary'"
            size="small"
            @click="handleCreatePage"
            :icon="createPage ? 'el-icon-back' : 'el-icon-plus'"
            >{{
              createPage ? $t("m.Back_To_Admin_Training_List") : $t("m.Create")
            }}</el-button
          >

          <!-- 新增主题库同步到班级题库 -->
          <el-button
            v-if="!editPage && !createPage"
            :type="createPage ? 'warning' : 'primary'"
            size="small"
            @click="handleTrainingToGroup"
            :icon="createPage ? 'el-icon-back' : 'el-icon-plus'"
            >{{ $t("m.Training_To_Group") }}</el-button
          >

          <el-button
            v-if="editPage && adminPage"
            type="warning"
            size="small"
            @click="handleEditPage"
            icon="el-icon-back"
            >{{ $t("m.Back_To_Admin_Training_List") }}</el-button
          >
          <el-button
            :type="adminPage ? 'danger' : 'success'"
            v-if="!editPage && !createPage"
            size="small"
            @click="handleAdminPage"
            :icon="adminPage ? 'el-icon-back' : 'el-icon-s-opportunity'"
            >{{
              adminPage ? $t("m.Back_To_Training_List") : $t("m.Training_Admin")
            }}</el-button
          >
        </el-col>

        <el-col
          :md="18"
          :xs="24"
          v-else-if="
            (isSuperAdmin || isGroupAdmin) && problemPage && !editProblemPage
          "
        >
          <el-button
            type="primary"
            size="small"
            @click="publicPage = true"
            icon="el-icon-plus"
            >{{ $t("m.Add_From_Public_Problem") }}</el-button
          >
          <el-button
            type="success"
            size="small"
            @click="handleGroupPage"
            icon="el-icon-plus"
            >{{ $t("m.Add_From_Group_Problem") }}</el-button
          >
          <el-button
            type="warning"
            size="small"
            @click="handleProblemPage(null)"
            icon="el-icon-back"
            >{{ $t("m.Back_To_Admin_Training_List") }}</el-button
          >
        </el-col>

        <el-col
          :md="18"
          :xs="24"
          v-else-if="(isSuperAdmin || isGroupAdmin) && editProblemPage"
        >
          <el-button
            type="primary"
            size="small"
            @click="handleEditProblemPage"
            icon="el-icon-back"
            >{{ $t("m.Back_Admin_Training_Problem_List") }}</el-button
          >`
        </el-col>
      </el-row>
    </div>
    <template v-if="!adminPage && !createPage && !problemPage">
      <vxe-table
        border="inner"
        stripe
        auto-resize
        highlight-hover-row
        :data="trainingList"
        :loading="loading"
        align="center"
        @cell-click="goGroupTraining"
      >
        <vxe-table-column
          field="rank"
          :title="$t('m.Number')"
          min-width="60"
          show-overflow
        >
        </vxe-table-column>
        <vxe-table-column
          field="title"
          :title="$t('m.Title')"
          min-width="200"
          align="center"
        >
        </vxe-table-column>

        <vxe-table-column
          field="auth"
          :title="$t('m.Auth')"
          min-width="100"
          align="center"
        >
          <template v-slot="{ row }">
            <el-tag :type="TRAINING_TYPE[row.auth]['color']" effect="dark">
              {{ $t("m.Training_" + row.auth) }}
            </el-tag>
          </template>
        </vxe-table-column>
        <vxe-table-column
          field="categoryName"
          :title="$t('m.Category')"
          min-width="130"
          align="center"
        >
          <template v-slot="{ row }">
            <el-tag
              size="large"
              :style="
                'background-color: #fff; color: ' +
                row.categoryColor +
                '; border-color: ' +
                row.categoryColor +
                ';'
              "
              >{{ row.categoryName }}</el-tag
            >
          </template>
        </vxe-table-column>

        <vxe-table-column
          field="acCount"
          :title="$t('m.Progress')"
          min-width="120"
          align="center"
        >
          <template v-slot="{ row }">
            <span>
              <el-tooltip
                effect="dark"
                :content="row.acCount + '/' + row.problemCount"
                placement="top"
              >
                <el-progress
                  :text-inside="true"
                  :stroke-width="20"
                  :percentage="getPassingRate(row.acCount, row.problemCount)"
                ></el-progress>
              </el-tooltip>
            </span>
          </template>
        </vxe-table-column>

        <vxe-table-column
          field="problemCount"
          :title="$t('m.Problem_Number')"
          min-width="70"
          align="center"
        >
        </vxe-table-column>
        <vxe-table-column
          field="author"
          :title="$t('m.Author')"
          min-width="130"
          align="center"
          show-overflow
        >
        </vxe-table-column>
        <vxe-table-column
          field="gmtModified"
          :title="$t('m.Recent_Update')"
          min-width="96"
          align="center"
          show-overflow
        >
          <template v-slot="{ row }">
            <span>
              <el-tooltip
                :content="row.gmtModified | localtime"
                placement="top"
              >
                <span>{{ row.gmtModified | fromNow }}</span>
              </el-tooltip>
            </span>
          </template>
        </vxe-table-column>
      </vxe-table>
      <Pagination
        :total="total"
        :page-size="limit"
        @on-change="currentChange"
        :current.sync="currentPage"
        @on-page-size-change="onPageSizeChange"
        :layout="'prev, pager, next, sizes'"
      ></Pagination>
    </template>
    <TrainingList
      ref="trainingList"
      v-if="adminPage && !createPage && !problemPage"
      @handleEditPage="handleEditPage"
      @currentChange="currentChange"
      @handleProblemPage="handleProblemPage"
    ></TrainingList>
    <TrainingProblemList
      v-if="problemPage"
      :trainingId="trainingId"
      @currentChangeProblem="currentChangeProblem"
      @handleEditProblemPage="handleEditProblemPage"
      ref="trainingProblemList"
    >
    </TrainingProblemList>
    <Training
      v-if="createPage && !editPage && !problemPage"
      mode="add"
      :title="$t('m.Create_Training')"
      apiMethod="addGroupTraining"
      @handleCreatePage="handleCreatePage"
      @currentChange="currentChange"
    ></Training>
    <!-- 团队添加公共题目 -->
    <el-dialog
      :title="$t('m.Add_Training_Problem')"
      width="90%"
      :visible.sync="publicPage"
      :close-on-click-modal="false"
    >
      <AddPublicProblem
        v-if="publicPage"
        :trainingId="trainingId"
        apiMethod="getGroupTrainingProblemList"
        @currentChangeProblem="currentChangeProblem"
        ref="addPublicProblem"
      ></AddPublicProblem>
    </el-dialog>
    <!-- 团队添加团队题目 -->
    <el-dialog
      :title="$t('m.Add_Training_Problem')"
      width="350px"
      :visible.sync="groupPage"
      :close-on-click-modal="false"
    >
      <AddGroupProblem
        :trainingId="trainingId"
        @currentChangeProblem="currentChangeProblem"
        @handleGroupPage="handleGroupPage"
      ></AddGroupProblem>
    </el-dialog>

    <!-- 打开公共题单弹窗 -->
    <el-dialog
      :title="$t('m.Training_To_Group')"
      width="850px"
      :visible.sync="groupListPage"
      :close-on-click-modal="true"
        >
      <SyncGroupList 
      :groupID="groupID"
      @syncGroupListClose="syncGroupListClose"
      ref="SyncGroupListChild"
      > </SyncGroupList>
    </el-dialog>
  </el-card>
</template>

<script>
import { mapGetters } from "vuex";
import { TRAINING_TYPE } from "@/common/constants";
import Pagination from "@/components/oj/common/Pagination";
import TrainingList from "@/components/oj/group/TrainingList";
import Training from "@/components/oj/group/Training";
import TrainingProblemList from "@/components/oj/group/TrainingProblemList";
import AddPublicProblem from "@/components/oj/group/AddPublicProblem.vue";
import AddGroupProblem from "@/components/oj/group/AddGroupProblem.vue";
import SyncGroupList from "@/components/oj/group/SyncGroupList.vue";
import api from "@/common/api";
export default {
  name: "GroupTrainingList",
  components: {
    Pagination,
    TrainingList,
    Training,
    TrainingProblemList,
    AddPublicProblem,
    AddGroupProblem,
    SyncGroupList,
  },
  data() {
    return {
      total: 0,
      currentPage: 1,
      limit: 10,
      trainingList: [],
      TRAINING_TYPE: {},
      loading: false,
      adminPage: false,
      createPage: false,
      editPage: false,
      problemPage: false,
      publicPage: false,
      groupPage: false,
      groupListPage: false, //打开同步题单弹窗
      editProblemPage: false,
      trainingId: null,
      groupID:"", //团队/班级id
    };
  },
  mounted() {
    this.TRAINING_TYPE = Object.assign({}, TRAINING_TYPE);
    this.init();
  },
  methods: {
    init() {
      this.groupID=this.$route.params.groupID
      this.getGroupTrainingList();
    },
    onPageSizeChange(pageSize) {
      this.limit = pageSize;
      this.init();
    },
    currentChange(page) {
      this.currentPage = page;
      this.init();
    },
    currentChangeProblem() {
      this.$refs.trainingProblemList.currentChange(1);
    },
    getGroupTrainingList() {
      this.trainingList = [];
      this.loading = true;
      api
        .getGroupTrainingList(
          this.currentPage,
          this.limit,
          this.$route.params.groupID
        )
        .then(
          (res) => {
            this.trainingList = res.data.data.records;
            console.log("团队this.trainingList ", this.trainingList);
            this.total = res.data.data.total;
            this.loading = false;
          },
          (err) => {
            this.loading = false;
          }
        );
    },
    goGroupTraining(event) {
      this.$router.push({
        name: "GroupTrainingDetails",
        params: {
          trainingID: event.row.id,
          groupID: this.$route.params.groupID,
        },
      });
    },
    handleCreatePage() {
      this.createPage = !this.createPage;
    },
    // 公共训练同步至班级
    handleTrainingToGroup() {
      console.log("公共训练同步至班级");
      this.groupListPage = true;
      setTimeout(() => {
        this.$refs.SyncGroupListChild.getTrainingList();
      });
    },
    //关闭弹窗
    syncGroupListClose(){
      this.groupListPage=false
      this.getGroupTrainingList()
    },


    handleEditPage() {
      this.editPage = !this.editPage;
      this.$refs.trainingList.editPage = this.editPage;
    },
    handleAdminPage() {
      this.adminPage = !this.adminPage;
      this.createPage = false;
      this.editPage = false;
    },
    handleProblemPage(trainingId) {
      this.trainingId = trainingId;
      this.problemPage = !this.problemPage;
    },
    handleGroupPage() {
      this.groupPage = !this.groupPage;
    },
    handleEditProblemPage() {
      this.editProblemPage = !this.editProblemPage;
      this.$refs.trainingProblemList.editPage = this.editProblemPage;
    },
    getPassingRate(ac, total) {
      if (!total) {
        return 0;
      }
      return ((ac / total) * 100).toFixed(2);
    },
  },
  computed: {
    ...mapGetters(["isAuthenticated", "isSuperAdmin", "isGroupAdmin"]),
  },
};
</script>

<style scoped>
.title {
  font-size: 20px;
  vertical-align: middle;
  float: left;
}
.filter-row {
  margin-bottom: 5px;
  text-align: center;
}
@media screen and (max-width: 768px) {
  .filter-row span {
    margin-left: 5px;
    margin-right: 5px;
  }
}
@media screen and (min-width: 768px) {
  .filter-row span {
    margin-left: 10px;
    margin-right: 10px;
  }
}
</style>

后台的实现也比较简单,原作者留下了很多现成的接口,直接使用就行。

String groupID=jsonObject.getStr("groupID"); //要同步到哪个班级
JSONArray trainingList= jsonObject.getJSONArray("selectedTrain"); //题单列表(id)
//循环遍历每一个题单数据
for(Object o:trainingList){
Long tid = Long.valueOf(o.toString());
//获取当前训练
Training training = trainingEntityService.getById(tid);
if (training == null) {
throw new StatusNotFoundException("该训练不存在!");
}
training.setGid(Long.valueOf(groupID));
//获取训练的类别
QueryWrapper<MappingTrainingCategory> mappingTrainingCategoryQueryWrapper = new QueryWrapper<>();
mappingTrainingCategoryQueryWrapper.eq("tid", tid);
MappingTrainingCategory mappingTrainingCategory = mappingTrainingCategoryEntityService.getOne(mappingTrainingCategoryQueryWrapper);
TrainingCategory trainingCategory = null;
if (mappingTrainingCategory != null) {
trainingCategory = trainingCategoryEntityService.getById(mappingTrainingCategory.getCid());
}
TrainingDTO trainingDto = new TrainingDTO();
trainingDto.setTraining(training);
trainingDto.setTrainingCategory(trainingCategory);
Long newTrainId = groupTrainingManager.addTraining(trainingDto); //新的训练id
//往新题单里插入题目
trainingProblemMapper.getOldProblemAndInsertNew(tid,newTrainId);
}
String groupID=jsonObject.getStr("groupID"); //要同步到哪个班级 JSONArray trainingList= jsonObject.getJSONArray("selectedTrain"); //题单列表(id) //循环遍历每一个题单数据 for(Object o:trainingList){ Long tid = Long.valueOf(o.toString()); //获取当前训练 Training training = trainingEntityService.getById(tid); if (training == null) { throw new StatusNotFoundException("该训练不存在!"); } training.setGid(Long.valueOf(groupID)); //获取训练的类别 QueryWrapper<MappingTrainingCategory> mappingTrainingCategoryQueryWrapper = new QueryWrapper<>(); mappingTrainingCategoryQueryWrapper.eq("tid", tid); MappingTrainingCategory mappingTrainingCategory = mappingTrainingCategoryEntityService.getOne(mappingTrainingCategoryQueryWrapper); TrainingCategory trainingCategory = null; if (mappingTrainingCategory != null) { trainingCategory = trainingCategoryEntityService.getById(mappingTrainingCategory.getCid()); } TrainingDTO trainingDto = new TrainingDTO(); trainingDto.setTraining(training); trainingDto.setTrainingCategory(trainingCategory); Long newTrainId = groupTrainingManager.addTraining(trainingDto); //新的训练id //往新题单里插入题目 trainingProblemMapper.getOldProblemAndInsertNew(tid,newTrainId); }
   String groupID=jsonObject.getStr("groupID");  //要同步到哪个班级
        JSONArray  trainingList= jsonObject.getJSONArray("selectedTrain"); //题单列表(id)
        //循环遍历每一个题单数据
        for(Object o:trainingList){
            Long tid = Long.valueOf(o.toString());
            //获取当前训练
            Training training = trainingEntityService.getById(tid);
            if (training == null) {
                throw new StatusNotFoundException("该训练不存在!");
            }
            training.setGid(Long.valueOf(groupID));
            //获取训练的类别
            QueryWrapper<MappingTrainingCategory> mappingTrainingCategoryQueryWrapper = new QueryWrapper<>();
            mappingTrainingCategoryQueryWrapper.eq("tid", tid);
            MappingTrainingCategory mappingTrainingCategory = mappingTrainingCategoryEntityService.getOne(mappingTrainingCategoryQueryWrapper);
            TrainingCategory trainingCategory = null;
            if (mappingTrainingCategory != null) {
                trainingCategory = trainingCategoryEntityService.getById(mappingTrainingCategory.getCid());
            }
            TrainingDTO trainingDto = new TrainingDTO();
            trainingDto.setTraining(training);
            trainingDto.setTrainingCategory(trainingCategory);
            Long newTrainId = groupTrainingManager.addTraining(trainingDto);  //新的训练id
            //往新题单里插入题目
            trainingProblemMapper.getOldProblemAndInsertNew(tid,newTrainId);
        }

大部分都是现成的,只有getOldProblemAndInsertNew这个是自己写的,也很简单:

<select id="getOldProblemAndInsertNew">
insert into training_problem(tid,pid,display_id)
SELECT #{newTrainId},pid,display_id from training_problem
WHERE tid=#{oldTrainId}
</select>
<select id="getOldProblemAndInsertNew"> insert into training_problem(tid,pid,display_id) SELECT #{newTrainId},pid,display_id from training_problem WHERE tid=#{oldTrainId} </select>
    <select id="getOldProblemAndInsertNew">
        insert into training_problem(tid,pid,display_id)
        SELECT #{newTrainId},pid,display_id from training_problem
        WHERE tid=#{oldTrainId}
    </select>

这里的oldTrainId对应上面的tid。

3.缺点

这个功能只能将公共训练的题单同步到班级内,每次都是新的,无法将原来一模一样的题单进行更新,好在做题记录都是通用的。

后面的文章再写一篇同步题库的。

分类: OnlineJudge