licailing hace 4 años
padre
commit
3ddb097bae

+ 5 - 0
src/main/java/com/izouma/wenlvju/domain/performance/Programme.java

@@ -35,6 +35,8 @@ public class Programme extends BaseEntity {
     @ApiModelProperty(value = "节目名称")
     private String name;
 
+    private Long parentSpecialtyId;
+
     @ApiModelProperty(value = "参赛专业")
     private Long specialtyId;
 
@@ -112,6 +114,9 @@ public class Programme extends BaseEntity {
     @ApiModelProperty(value = "全部评分")
     private boolean allScore;
 
+    @ApiModelProperty(value = "奖项")
+    private Long awardId;
+
     public Programme(ProgrammeDTO dto) {
         BeanUtil.copyProperties(dto, this);
     }

+ 100 - 10
src/main/java/com/izouma/wenlvju/service/performance/ProgrammeAwardService.java

@@ -95,6 +95,64 @@ public class ProgrammeAwardService {
         return dtos;
     }
 
+    public List<ProgrammeAwardDTO> getAll1(Long performanceId) {
+        //找出所有节目奖项设置
+        PageQuery pageQuery = new PageQuery();
+        pageQuery.setSize(100);
+        pageQuery.setSort("specialtyId,asc");
+        pageQuery.getQuery().put("performanceId", performanceId);
+        List<ProgrammeAward> programmeAwards = this.all(pageQuery).getContent();
+
+        // 奖项
+        List<Award> awardList = awardRepo.findAll();
+
+        //专业
+        List<ArtType> all = artTypeRepo.findAll();
+        Map<Long, String> artTypeMap = all
+                .stream()
+                .collect(Collectors.toMap(ArtType::getId, ArtType::getName));
+
+        //已经设置完成
+        if (CollUtil.isNotEmpty(programmeAwards)) {
+            Map<Long, String> awardMap = awardList.stream().collect(Collectors.toMap(Award::getId, Award::getName));
+            return programmeAwards.stream()
+                    .map(award -> {
+                        ProgrammeAwardDTO dto = new ProgrammeAwardDTO(award);
+                        dto.setSpecialty(artTypeMap.get(award.getSpecialtyId()));
+                        dto.setAward(awardMap.get(award.getAwardId()));
+                        return dto;
+                    })
+                    .collect(Collectors.toList());
+        }
+
+        //总节目
+        List<Programme> programmeList = programmeRepo.findAllByPerformanceIdAndStatus(performanceId, 2);
+        List<ArtType> artTypes = all.stream()
+                .filter(artType -> ObjectUtil.isNull(artType.getParent()))
+                .collect(Collectors.toList());
+
+        List<ProgrammeAwardDTO> dtos = new ArrayList<>();
+
+        // 节目数量
+        Map<Long, Long> countProgramme = programmeList.stream()
+                .collect(Collectors.groupingBy(Programme::getParentSpecialtyId, Collectors.counting()));
+        artTypes.forEach(artType -> {
+            Long count = countProgramme.get(artType.getId());
+
+            awardList.forEach(award -> {
+                ProgrammeAwardDTO dto = new ProgrammeAwardDTO();
+                dto.setSpecialtyId(artType.getId());
+                dto.setSpecialty(artType.getName());
+                dto.setAwardId(award.getId());
+                dto.setAward(award.getName());
+                dto.setPerformanceId(performanceId);
+                dto.setProgrammeNum(ObjectUtil.isNotNull(count) ? count : 0);
+                dtos.add(dto);
+            });
+        });
+        return dtos;
+    }
+
 
     public List<ProgrammeAwardDTO> getAll2(Long performanceId) {
         PageQuery pageQuery = new PageQuery();
@@ -162,11 +220,6 @@ public class ProgrammeAwardService {
         return dtos;
     }
 
-    public void batchSave(List<ProgrammeAwardDTO> dtos) {
-        List<ProgrammeAward> programmeAwards = dtos.stream().map(ProgrammeAward::new).collect(Collectors.toList());
-        programmeAwardRepo.saveAll(programmeAwards);
-    }
-
     public void saveProgramme(List<ProgrammeAwardDTO> dtos) {
         List<Programme> programmeList = programmeRepo.findAllByPerformanceIdAndStatus(dtos.get(0)
                 .getPerformanceId(), 2);
@@ -185,10 +238,10 @@ public class ProgrammeAwardService {
                     .collect(Collectors.toList());
             List<Programme> programmes = programmeList.stream()
                     .filter(programme -> artTypeIds.contains(programme.getSpecialtyId()))
+                    .sorted(Comparator.comparingDouble(Programme::getScore))
                     .collect(Collectors.toList());
 
-            //按成绩排序
-            programmes.sort(Comparator.comparingDouble(Programme::getScore));
+            map.put(artType.getId(), programmes);
         });
 
 
@@ -203,14 +256,51 @@ public class ProgrammeAwardService {
 
         mapMap.forEach((k, v) -> {
             int start = 0;
-            awards.forEach(award -> {
+            for (Award award : awards) {
                 ProgrammeAwardDTO pa = v.get(award.getId()).get(0);
                 if (pa.getNum() > 0) {
-
+                    List<Programme> programmes = map.get(k);
+                    if (CollUtil.isNotEmpty(programmes)) {
+                        List<Programme> result = programmes.subList(start, start + pa.getNum().intValue());
+                        result.forEach(programme -> programme.setAwardId(award.getId()));
+                        start += pa.getNum().intValue();
+                    }
                 }
-            });
+            }
+        });
+    }
+
+    public void saveProgramme1(List<ProgrammeAwardDTO> dtos) {
+        List<Programme> programmeList = programmeRepo.findAllByPerformanceIdAndStatus(dtos.get(0)
+                .getPerformanceId(), 2);
+
+        Map<Long, List<Programme>> programmeMap = programmeList.stream()
+                .sorted(Comparator.comparingDouble(Programme::getScore))
+                .collect(Collectors.groupingBy(Programme::getParentSpecialtyId));
 
 
+        //获得奖项优先级
+        List<Award> awards = awardRepo.findAll();
+        awards.sort(Comparator.comparingInt(Award::getLevel));
+
+        //按专业区分再按奖项区分
+        Map<Long, Map<Long, List<ProgrammeAwardDTO>>> mapMap = dtos.stream()
+                .collect(Collectors.groupingBy(ProgrammeAwardDTO::getSpecialtyId, Collectors.groupingBy(ProgrammeAwardDTO::getAwardId)));
+
+
+        mapMap.forEach((k, v) -> {
+            int start = 0;
+            for (Award award : awards) {
+                ProgrammeAwardDTO pa = v.get(award.getId()).get(0);
+                if (pa.getNum() > 0) {
+                    List<Programme> programmes = programmeMap.get(k);
+                    if (CollUtil.isNotEmpty(programmes)) {
+                        List<Programme> result = programmes.subList(start, start + pa.getNum().intValue());
+                        result.forEach(programme -> programme.setAwardId(award.getId()));
+                        start += pa.getNum().intValue();
+                    }
+                }
+            }
         });
     }
 }

+ 40 - 3
src/main/java/com/izouma/wenlvju/service/performance/ProgrammeService.java

@@ -342,6 +342,46 @@ public class ProgrammeService {
         return map;
     }
 
+    @Transactional(rollbackOn = Exception.class)
+    public Map<String, String> group1(Arrange arrange) {
+        // 是否继续分组
+        boolean flag = true;
+
+        List<Programme> byPerformanceId = programmeRepo.findAllByPerformanceIdAndStatus(arrange.getPerformanceId(), 0);
+        int quantity = arrange.getQuantity();
+        if (byPerformanceId.size() < quantity) {
+            flag = false;
+        }
+
+        List<Programme> result = new ArrayList<>(quantity);
+        if (CollUtil.isNotEmpty(arrange.getSpecialtyId())) {
+
+//            List<Long> artTypeChild = artTypeService.getChild(arrange.getSpecialtyId(), new ArrayList<>(arrange.getSpecialtyId()));
+            List<Programme> programmeList = byPerformanceId.stream()
+                    .filter(programme -> arrange.getSpecialtyId().contains(programme.getParentSpecialtyId()))
+                    .collect(Collectors.toList());
+
+            int size = programmeList.size();
+            if (size < quantity) {
+                programmeList.addAll(byPerformanceId.stream()
+                        .filter(programme -> !arrange.getSpecialtyId().contains(programme.getSpecialtyId()))
+                        .limit(quantity - size)
+                        .collect(Collectors.toList()));
+                flag = false;
+            }
+
+            this.sort(programmeList);
+            result.addAll(programmeList.stream().limit(quantity).collect(Collectors.toList()));
+        } else {
+            this.sort(byPerformanceId);
+            result.addAll(byPerformanceId.stream().limit(quantity).collect(Collectors.toList()));
+        }
+        Map<String, String> map = new HashMap<>();
+        map.put("flag", Boolean.toString(flag));
+        map.put("programmes", JSONObject.toJSONString(result));
+        return map;
+    }
+
     public void saveAll(List<Programme> programmes, Long arrangeId) {
         programmes.forEach(programme -> {
             programme.setArrangeId(arrangeId);
@@ -406,9 +446,6 @@ public class ProgrammeService {
     查看按分组查看节目
      */
     public Page<ArrangeProgrammeDTO> byArrange(PageQuery pageQuery) {
-//        Specification<Programme> specification = JpaUtils.toSpecification(pageQuery, Programme.class);
-//        specification.and((root, criteriaQuery, criteriaBuilder) -> criteriaBuilder.and(criteriaBuilder.isNull(root.get("arrangeId"))));
-
         Page<Programme> all = programmeRepo.findAll((root, criteriaQuery, criteriaBuilder) -> {
             List<Predicate> and = JpaUtils.toPredicates(pageQuery, Programme.class, root, criteriaQuery, criteriaBuilder);
             and.add(criteriaBuilder.isNotNull(root.get("arrangeId")));

+ 8 - 1
src/main/java/com/izouma/wenlvju/web/performance/ProgrammeAwardController.java

@@ -18,6 +18,7 @@ import org.springframework.web.bind.annotation.*;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.util.List;
+import java.util.stream.Collectors;
 
 @RestController
 @RequestMapping("/programmeAward")
@@ -63,12 +64,18 @@ public class ProgrammeAwardController extends BaseController {
 
     @PostMapping("/getAll")
     public List<ProgrammeAwardDTO> getAll(@RequestParam Long performanceId) {
-        return programmeAwardService.getAll(performanceId);
+        return programmeAwardService.getAll1(performanceId);
     }
 
     @PostMapping("/getAll2")
     public List<ProgrammeAwardDTO> getAll2(@RequestParam Long performanceId) {
         return programmeAwardService.getAll2(performanceId);
     }
+
+    @PostMapping("/batchSave")
+    public void batchSave(@RequestBody List<ProgrammeAwardDTO> dtos) {
+        List<ProgrammeAward> programmeAwards = dtos.stream().map(ProgrammeAward::new).collect(Collectors.toList());
+        programmeAwardRepo.saveAll(programmeAwards);
+    }
 }
 

+ 11 - 0
src/main/vue/src/router.js

@@ -664,6 +664,17 @@ const router = new Router({
                         title: '节目列表'
                     }
                 },
+                {
+                    path: '/programmeResultList',
+                    name: 'ProgrammeResultList',
+                    component: () =>
+                        import(
+                            /* webpackChunkName: "programmeResultList" */ '@/views/performance/ProgrammeResultList.vue'
+                        ),
+                    meta: {
+                        title: '节目获奖'
+                    }
+                },
                 {
                     path: '/programmeOrgList',
                     name: 'ProgrammeOrgList',

+ 84 - 27
src/main/vue/src/views/performance/ProgrammeAwardList.vue

@@ -10,6 +10,7 @@
                             filterable
                             placeholder="活动名称"
                             style="width: 300px"
+                            @change="getData"
                         >
                             <el-option
                                 v-for="item in performances"
@@ -24,9 +25,10 @@
 
                 <el-form-item>
                     <el-button @click="canEdit = true" type="primary" v-if="!canEdit">编辑</el-button>
-                    <el-button @click="canEdit = false" type="warning" v-if="canEdit">取消</el-button>
-                    <el-button @click="getData" type="primary">批量生成各种奖项</el-button>
-                    <el-button @click="getData" type="primary">查看节目获奖情况</el-button>
+                    <el-button @click="saveAward" type="success" v-if="canEdit" :loading="saving">保存</el-button>
+                    <el-button @click="canEdit = false" type="warning" v-if="canEdit" :loading="saving">取消</el-button>
+                    <el-button @click="saveProgramme" type="primary">批量生成各种奖项</el-button>
+                    <el-button @click="resultRow" type="primary">查看节目获奖情况</el-button>
                 </el-form-item>
             </el-form>
         </div>
@@ -39,6 +41,7 @@
             row-class-name="table-row"
             cell-class-name="table-cell"
             :height="tableHeight"
+            :span-method="objectSpanMethod"
         >
             <el-table-column v-if="multipleMode" align="center" type="selection" width="50"> </el-table-column>
             <el-table-column prop="specialty" label="专业" min-width="80"> </el-table-column>
@@ -54,7 +57,7 @@
                         size="mini"
                         label=""
                         :min="0"
-                        :max="100"
+                        :max="getMaxPercentage(row)"
                         :step="1"
                         :controls="true"
                         controls-position="both"
@@ -72,7 +75,7 @@
                         size="mini"
                         label=""
                         :min="0"
-                        :max="row.max"
+                        :max="getMax(row)"
                         :step="1"
                         :controls="true"
                         controls-position="both"
@@ -134,16 +137,47 @@ export default {
             performances: [],
             tableData: [],
             tableHeight: 200,
-            columnKeys: ['specialty'],
-            canEdit: false
+            columnKeys: ['specialty', 'programmeNum'],
+            canEdit: false,
+            saving: false
         };
     },
     created() {
-        this.getData();
+        this.$http
+            .post(
+                '/performance/all',
+                {
+                    size: 1000,
+                    sort: 'year,desc',
+                    query: {
+                        publish: true
+                    }
+                },
+                { body: 'json' }
+            )
+            .then(res => {
+                if (res.content.length > 0) {
+                    res.content.forEach(item => {
+                        this.performances.push({
+                            label: item.name,
+                            value: item.id
+                        });
+                    });
+                    this.form.performanceId = res.content[0].id;
+                }
+                this.getData();
+            })
+            .catch(e => {
+                console.log(e);
+                this.$message.error(e.error);
+            });
     },
     computed: {
         selection() {
             return this.$refs.table.selection.map(i => i.id);
+        },
+        showTable() {
+            return this.backMap(this.tableData);
         }
     },
     mounted() {
@@ -155,7 +189,9 @@ export default {
         },
         getData() {
             this.$http
-                .post('/programmeAward/getAll', { performanceId: 1013 })
+                .post('/programmeAward/getAll', {
+                    performanceId: this.form.performanceId
+                })
                 .then(res => {
                     this.tableData = res;
                 })
@@ -170,9 +206,9 @@ export default {
                 this.$refs.table.clearSelection();
             }
         },
-        addRow() {
+        resultRow() {
             this.$router.push({
-                path: '/programmeAwardEdit',
+                path: '/programmeResultList',
                 query: {
                     ...this.$route.query
                 }
@@ -264,10 +300,9 @@ export default {
                     });
                 });
             }
-
             return _map;
         },
-        getInfo(mapInfo = new Map(), keys = ['specialtyId']) {
+        getInfo(mapInfo = new Map(), keys = ['specialty']) {
             let info = {};
             keys.forEach(item => {
                 if (mapInfo.has(item)) {
@@ -302,13 +337,14 @@ export default {
             }
         },
         changePercentage(row) {
-            row.num = (row.programmeNum * row.percentage) / 100;
-            let list = this.tableData.filter(item => {
-                return item.specialtyId == row.specialtyId;
-            });
-            console.log(list);
+            let num = (row.programmeNum * row.percentage) / 100;
+            row.num = Math.round(num);
+            row.percentage = (row.num / row.programmeNum) * 100;
         },
         changeNum(row) {
+            row.percentage = (row.num / row.programmeNum) * 100;
+        },
+        getMax(row) {
             let list = this.tableData.filter(item => {
                 return item.specialty == row.specialty;
             });
@@ -316,15 +352,36 @@ export default {
             list.forEach(item => {
                 total += item.num;
             });
-            row.max = row.programmeNum - total + row.num;
-
-            if (total > row.programmeNum) {
-                row.num = 0;
-            }
-            row.percentage = (row.num / row.programmeNum) * 100;
-
-            console.log(row.max);
-        }
+            let max = row.programmeNum - total + row.num;
+            return max;
+        },
+        getMaxPercentage(row) {
+            let list = this.tableData.filter(item => {
+                return item.specialty == row.specialty;
+            });
+            let total = 0;
+            list.forEach(item => {
+                total += item.percentage;
+            });
+            let max = 100 - total + row.percentage;
+            return max;
+        },
+        saveAward() {
+            let data = this.tableData;
+            this.$http
+                .post('/programmeAward/batchSave', data, { body: 'json' })
+                .then(res => {
+                    this.saving = false;
+                    this.$message.success('成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.saving = false;
+                    this.$message.error(e.error);
+                });
+        },
+        saveProgramme() {}
     }
 };
 </script>

+ 2 - 7
src/main/vue/src/views/performance/ProgrammeGroupList.vue

@@ -61,12 +61,7 @@
                 <template slot-scope="{ row }">
                     <el-button @click="showRow(row)" size="mini" plain>查看</el-button>
                     <el-button @click="removeRow(row)" type="danger" size="mini" plain>移除</el-button>
-                    <el-button
-                        type="warning"
-                        @click="playVideo(row)"
-                        size="mini"
-                        plain
-                        v-if="row.video && row.video.src"
+                    <el-button type="warning" @click="playVideo(row)" size="mini" plain v-if="row.video"
                         >浏览视频</el-button
                     >
                 </template>
@@ -104,7 +99,7 @@
             width="70%"
         >
             <video
-                :src="videoUrl.src"
+                :src="videoUrl"
                 controlsList="nodownload noremote footbar"
                 controls
                 style="height: 100%; max-width: 100%"

+ 1 - 1
src/main/vue/src/views/performance/ProgrammeList.vue

@@ -229,7 +229,7 @@
             width="70%"
         >
             <video
-                :src="videoUrl.src"
+                :src="videoUrl"
                 controlsList="nodownload noremote footbar"
                 controls
                 style="height: 100%; max-width: 100%"

+ 633 - 0
src/main/vue/src/views/performance/ProgrammeResultList.vue

@@ -0,0 +1,633 @@
+<template>
+    <div class="list-view">
+        <div class="filters-container">
+            <el-form :model="form" inline size="mini" label-width="100px">
+                <el-row>
+                    <el-col :span="8">
+                        <el-form-item label="活动名称">
+                            <el-select
+                                v-model="performanceId"
+                                clearable
+                                filterable
+                                placeholder="活动名称"
+                                style="width: 100%"
+                            >
+                                <el-option
+                                    v-for="item in performances"
+                                    :key="item.id"
+                                    :label="item.name"
+                                    :value="item.id"
+                                >
+                                </el-option>
+                            </el-select>
+                        </el-form-item>
+                    </el-col>
+                    <el-col :span="8">
+                        <el-form-item label="考级机构名称">
+                            <el-select
+                                v-model="gradingOrganizationId"
+                                clearable
+                                filterable
+                                placeholder="考级机构"
+                                style="width: 100%"
+                            >
+                                <el-option
+                                    v-for="item in gradingOrganizationIdOptions"
+                                    :key="item.value"
+                                    :label="item.label"
+                                    :value="item.value"
+                                >
+                                </el-option>
+                            </el-select>
+                        </el-form-item>
+                    </el-col>
+                    <el-col :span="8"
+                        ><el-form-item label="考级点名称">
+                            <el-input placeholder="考级点名称" v-model="search" clearable></el-input> </el-form-item
+                    ></el-col>
+                </el-row>
+                <el-row>
+                    <el-col :span="8">
+                        <el-form-item label="参赛专业">
+                            <el-cascader
+                                ref="artCascader"
+                                style="width: 100%"
+                                v-model="specialtyId"
+                                :props="optionProps"
+                                :options="artTypes"
+                                :show-all-levels="false"
+                                placeholder="请选择专业"
+                                clearable
+                            >
+                            </el-cascader>
+                        </el-form-item>
+                    </el-col>
+                    <el-col :span="8"
+                        ><el-form-item label="参赛组别">
+                            <el-select v-model="competitionGroup" clearable filterable placeholder="参赛组别">
+                                <el-option
+                                    v-for="item in competitionGroupOptions"
+                                    :key="item.value"
+                                    :label="item.label"
+                                    :value="item.value"
+                                >
+                                </el-option>
+                            </el-select> </el-form-item
+                    ></el-col>
+                    <el-col :span="8"
+                        ><el-form-item label="参赛级别" v-if="competitionGroup">
+                            <el-select
+                                v-model="levelSettingId"
+                                clearable
+                                filterable
+                                placeholder="参赛级别"
+                                style="width: 100%"
+                                v-if="competitionGroup == 'SINGLE'"
+                            >
+                                <el-option
+                                    v-for="item in levelSingleOptions"
+                                    :key="item.value"
+                                    :label="item.label"
+                                    :value="item.value"
+                                >
+                                    <span style="float: left">{{ item.label }}</span>
+                                    <span style="float: right; color: #8492a6; font-size: 13px">{{ item.desc }}</span>
+                                </el-option>
+                            </el-select>
+                            <el-select
+                                v-model="levelSettingId"
+                                clearable
+                                filterable
+                                placeholder="请选择"
+                                style="width: 100%"
+                                v-else
+                            >
+                                <el-option
+                                    v-for="item in levelCollectiveOptions"
+                                    :key="item.value"
+                                    :label="item.label"
+                                    :value="item.value"
+                                >
+                                    <span style="float: left">{{ item.label }}</span>
+                                    <span style="float: right; color: #8492a6; font-size: 13px">{{ item.desc }}</span>
+                                </el-option>
+                            </el-select>
+                        </el-form-item>
+                    </el-col>
+                </el-row>
+                <el-row>
+                    <el-col :span="8">
+                        <el-form-item label="节目名称">
+                            <el-input placeholder="节目名称" v-model="name" clearable></el-input>
+                        </el-form-item>
+                    </el-col>
+                    <el-col :span="8">
+                        <el-form-item label="指导老师">
+                            <el-input placeholder="指导老师" v-model="instructor" clearable></el-input>
+                        </el-form-item>
+                    </el-col>
+                </el-row>
+                <el-form-item>
+                    <el-button @click="canAdd" type="primary" icon="el-icon-search">搜索 </el-button>
+                    <el-button @click="addRow" type="primary" icon="el-icon-plus" v-if="add">添加 </el-button>
+                    <el-upload
+                        :action="uploadUrl"
+                        :before-upload="beforeUpload"
+                        :headers="headers"
+                        :show-file-list="false"
+                        ref="upload"
+                        :on-success="onSuccess"
+                        class="uploader"
+                        :on-error="onfail"
+                    >
+                        <el-button slot="trigger" type="primary" icon="el-icon-upload2" v-if="add">批量上传</el-button>
+                    </el-upload>
+                    <el-button
+                        @click="download"
+                        type="primary"
+                        icon="el-icon-download"
+                        :loading="downloading"
+                        :disabled="totalElements < 1"
+                        >导出
+                    </el-button>
+                    <el-button @click="downloadTemp" type="primary" icon="el-icon-tickets" :loading="downloading"
+                        >模版
+                    </el-button>
+                </el-form-item>
+            </el-form>
+        </div>
+        <el-table
+            :data="tableData"
+            row-key="id"
+            ref="table"
+            header-row-class-name="table-header-row"
+            header-cell-class-name="table-header-cell"
+            row-class-name="table-row"
+            cell-class-name="table-cell"
+            :height="tableHeight"
+        >
+            <el-table-column v-if="multipleMode" align="center" type="selection" width="50"> </el-table-column>
+            <!-- <el-table-column prop="id" label="ID" width="100"> </el-table-column> -->
+            <el-table-column prop="name" label="节目名称"> </el-table-column>
+            <el-table-column prop="specialty" label="参赛专业"> </el-table-column>
+            <el-table-column
+                prop="competitionGroup"
+                label="参赛组别"
+                :formatter="competitionGroupFormatter"
+                min-width="70"
+            >
+            </el-table-column>
+            <el-table-column prop="level" label="参赛级别" min-width="70"> </el-table-column>
+            <el-table-column prop="quantity" label="参赛人数" min-width="70"> </el-table-column>
+            <el-table-column prop="gradingOrganization" label="考级机构" show-overflow-tooltip min-width="160">
+            </el-table-column>
+            <el-table-column prop="organization" label="承办单位" min-width="160"> </el-table-column>
+            <el-table-column prop="examPoint" label="考级点" min-width="160"> </el-table-column>
+            <el-table-column prop="contact" label="联系人" min-width="68"> </el-table-column>
+            <el-table-column prop="phone" label="联系电话" min-width="95"> </el-table-column>
+            <el-table-column prop="award" label="获奖情况" min-width="95"> </el-table-column>
+        </el-table>
+        <div class="pagination-wrapper">
+            <!-- <div class="multiple-mode-wrapper">
+                <el-button v-if="!multipleMode" @click="toggleMultipleMode(true)">批量编辑</el-button>
+                <el-button-group v-else>
+                    <el-button @click="operation1">批量操作1</el-button>
+                    <el-button @click="operation2">批量操作2</el-button>
+                    <el-button @click="toggleMultipleMode(false)">取消</el-button>
+                </el-button-group>
+            </div> -->
+            <el-pagination
+                background
+                @size-change="onSizeChange"
+                @current-change="onCurrentChange"
+                :current-page="page"
+                :page-sizes="[10, 20, 30, 40, 50]"
+                :page-size="pageSize"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="totalElements"
+            >
+            </el-pagination>
+        </div>
+    </div>
+</template>
+<script>
+import delChild from '@/mixins/delChild';
+import { mapState } from 'vuex';
+import pageableTable from '@/mixins/pageableTable';
+import QrcodeVue from 'qrcode.vue';
+import resolveUrl from 'resolve-url';
+import { format } from 'date-fns';
+
+export default {
+    name: 'ProgrammeOrgList',
+    mixins: [pageableTable, delChild],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/programme/backAll',
+            downloading: false,
+            competitionGroupOptions: [
+                { label: '个人', value: 'SINGLE' },
+                { label: '集体', value: 'COLLECTIVE' }
+            ],
+            form: {},
+            competitionGroup: '',
+            levelSingleOptions: [],
+            levelCollectiveOptions: [],
+            levelSettingId: '',
+            dialogUrl: '',
+            dialogCode: false,
+            gradingOrganizationIdOptions: [],
+            gradingOrganizationId: '',
+            performanceId: '',
+            performances: [],
+            artTypes: [],
+            optionProps: {
+                value: 'id',
+                label: 'name',
+                children: 'children',
+                multiple: false,
+                emitPath: false,
+                checkStrictly: true,
+                expandTrigger: 'hover'
+            },
+            specialtyId: '',
+            showViedo: false,
+            videoUrl: '',
+            name: '',
+            instructor: '',
+            uploadUrl: '',
+            currentTime: '',
+            add: false
+        };
+    },
+    created() {
+        this.uploadUrl = resolveUrl(this.$baseUrl, 'programme/upload');
+        this.currentTime = format(new Date(), 'yyyy-MM-dd');
+        this.$http
+            .post('/setting/byFlag', { flag: 3 })
+            .then(res => {
+                if (res.length > 0) {
+                    res.forEach(item => {
+                        this.levelSingleOptions.push({
+                            label: item.name,
+                            value: item.id,
+                            desc: item.code
+                        });
+                    });
+                }
+            })
+            .catch(e => {
+                console.log(e);
+                this.$message.error(e.error);
+            });
+        if (this.$route.query.pid) {
+            this.performanceId = Number(this.$route.query.pid);
+        }
+        this.$http
+            .post('/setting/byFlag', { flag: 4 })
+            .then(res => {
+                if (res.length > 0) {
+                    res.forEach(item => {
+                        this.levelCollectiveOptions.push({
+                            label: item.name,
+                            value: item.id,
+                            desc: item.code
+                        });
+                    });
+                }
+            })
+            .catch(e => {
+                console.log(e);
+                this.$message.error(e.error);
+            });
+        this.$http
+            .post('/gradingOrganization/all', { size: 1000, query: { del: false } }, { body: 'json' })
+            .then(res => {
+                if (res.content.length > 0) {
+                    res.content.forEach(item => {
+                        this.gradingOrganizationIdOptions.push({
+                            label: item.name,
+                            value: item.id
+                        });
+                    });
+                }
+            })
+            .catch(e => {
+                console.log(e);
+                this.$message.error(e.error);
+            });
+        this.$http
+            .post(
+                '/performance/all',
+                {
+                    size: 1000,
+                    sort: 'year,desc',
+                    query: {
+                        publish: true
+                    }
+                },
+                { body: 'json' }
+            )
+            .then(res => {
+                if (res.content.length > 0) {
+                    // res.content.forEach(item => {
+                    //     this.performances.push({
+                    //         label: item.name,
+                    //         value: item.id
+                    //     });
+                    // });
+                    this.performances = res.content;
+                    if (!this.$route.query.pid) {
+                        this.performanceId = res.content[0].id;
+                        this.canAdd();
+                    }
+                }
+            })
+            .catch(e => {
+                console.log(e);
+                this.$message.error(e.error);
+            });
+        this.$http
+            .post('/artType/allList')
+            .then(res => {
+                this.artTypes = this.delChild(res);
+            })
+            .catch(e => {
+                console.log(e);
+            });
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        },
+        ...mapState(['organization']),
+        headers() {
+            return {
+                Authorization: 'Bearer ' + sessionStorage.getItem('token')
+            };
+        }
+    },
+    methods: {
+        competitionGroupFormatter(row, column, cellValue, index) {
+            let selectedOption = this.competitionGroupOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        beforeGetData() {
+            let data = {
+                sort: 'createdAt,desc',
+                query: {}
+            };
+            if (this.competitionGroup) {
+                data.query.competitionGroup = this.competitionGroup;
+            }
+            if (this.levelSettingId) {
+                data.query.levelSettingId = this.levelSettingId;
+            }
+            if (this.gradingOrganizationId) {
+                data.query.gradingOrganizationId = this.gradingOrganizationId;
+            }
+            if (this.performanceId) {
+                data.query.performanceId = this.performanceId;
+            }
+            if (this.specialtyId) {
+                data.query.code = this.getCode(this.specialtyId);
+            }
+            if (this.name) {
+                data.query.name = this.name;
+            }
+            if (this.instructor) {
+                data.query.instructor = this.instructor;
+            }
+            return data;
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        addRow() {
+            this.$router.push({
+                path: '/programmeEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+
+            let data = {
+                sort: 'createdAt,desc',
+                query: {
+                    organizationId: this.organization.id
+                }
+            };
+            if (this.competitionGroup) {
+                data.query.competitionGroup = this.competitionGroup;
+            }
+            if (this.levelSettingId) {
+                data.query.levelSettingId = this.levelSettingId;
+            }
+            if (this.gradingOrganizationId) {
+                data.query.gradingOrganizationId = this.gradingOrganizationId;
+            }
+            if (this.specialtyId) {
+                data.query.code = this.getCode(this.specialtyId);
+            }
+            if (this.name) {
+                data.query.name = this.name;
+            }
+            if (this.instructor) {
+                data.query.instructor = this.instructor;
+            }
+            if (this.performanceId) {
+                data.query.performanceId = this.performanceId;
+            }
+            this.$axios
+                .get('/programme/excel', {
+                    responseType: 'blob',
+                    params: data
+                })
+                .then(res => {
+                    console.log(res);
+                    this.downloading = false;
+                    const downloadUrl = window.URL.createObjectURL(new Blob([res.data]));
+                    const link = document.createElement('a');
+                    link.href = downloadUrl;
+                    link.setAttribute('download', res.headers['content-disposition'].split('filename=')[1]);
+                    document.body.appendChild(link);
+                    link.click();
+                    link.remove();
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.downloading = false;
+                    this.$message.error(e.error);
+                });
+        },
+        downloadTemp() {
+            this.$axios
+                .get('/programme/excelTemp', {
+                    responseType: 'blob'
+                })
+                .then(res => {
+                    this.downloading = false;
+                    const downloadUrl = window.URL.createObjectURL(new Blob([res.data]));
+                    const link = document.createElement('a');
+                    link.href = downloadUrl;
+                    link.setAttribute('download', res.headers['content-disposition'].split('filename=')[1]);
+                    document.body.appendChild(link);
+                    link.click();
+                    link.remove();
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.downloading = false;
+                    this.$message.error(e.error);
+                });
+        },
+        operation1() {
+            this.$notify({
+                title: '提示',
+                message: this.selection
+            });
+        },
+        operation2() {
+            this.$message('操作2');
+        },
+        deleteRow(row) {
+            this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+                .then(() => {
+                    return this.$http.post(`/programme/del/${row.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        },
+        clearSearch() {
+            this.competitionGroup = '';
+            this.levelSettingId = '';
+            this.gradingOrganizationId = '';
+            this.organizationId = '';
+            this.specialtyId = '';
+            this.getData();
+        },
+        getCode(value) {
+            return this.forTree(this.artTypes, value).code;
+        },
+        forTree(list, value) {
+            var result = null;
+            if (!list) {
+                return;
+            }
+            for (var i in list) {
+                if (result !== null) {
+                    break;
+                }
+                var item = list[i];
+                if (item.id == value) {
+                    result = item;
+                    break;
+                } else if (item.children && item.children.length > 0) {
+                    result = this.forTree(item.children, value);
+                }
+            }
+            return result;
+        },
+        onfail(e) {
+            console.log(e);
+            this.$message.error('失败');
+            this.getData();
+        },
+        onSuccess() {
+            this.$message.success('上传成功');
+            this.getData();
+        },
+        beforeUpload() {
+            return this.$confirm('确认要上传文件吗?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            });
+        },
+        canAdd() {
+            let data = this.performances.find(item => {
+                return item.id == this.performanceId;
+            });
+            if (data.endDate >= this.currentTime) {
+                this.add = true;
+            } else {
+                this.add = false;
+            }
+            this.getData();
+        }
+    }
+};
+</script>
+<style lang="less" scoped>
+.right {
+    float: right;
+}
+/deep/.el-form-item--mini.el-form-item,
+.el-form-item--small.el-form-item {
+    margin-bottom: 10px;
+}
+.videoDialog {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    .el-dialog {
+        max-width: 900px;
+        margin-top: 0px;
+
+        .close {
+            position: absolute;
+            right: 0px;
+            top: -42px;
+            width: 71px;
+            height: 32px;
+            background: #00000015;
+
+            font-size: 12px;
+            color: #fdffff;
+            line-height: 32px;
+            text-align: center;
+            cursor: pointer;
+
+            &:hover {
+                background: #00000055;
+            }
+        }
+    }
+    .el-dialog__header {
+        display: none;
+    }
+
+    .el-dialog__body {
+        padding: 0;
+
+        video {
+            display: block;
+            height: auto;
+            width: 100%;
+            outline: none;
+        }
+    }
+}
+.uploader {
+    display: inline-block;
+    margin: 0 10px;
+}
+</style>

+ 25 - 6
src/main/vue/src/views/performance/ProgrammeScoreList.vue

@@ -10,6 +10,7 @@
                             filterable
                             placeholder="活动名称"
                             style="width: 300px"
+                            @change="changeAddress"
                         >
                             <el-option
                                 v-for="item in performances"
@@ -21,8 +22,7 @@
                         </el-select>
                     </el-form-item>
                     <el-form-item label="活动日期">
-                        <el-date-picker @change="getData" v-model="date" type="date" placeholder="选择日期">
-                        </el-date-picker>
+                        <el-date-picker v-model="date" type="date" placeholder="选择日期"> </el-date-picker>
                     </el-form-item>
                     <el-form-item label="时间">
                         <el-radio-group v-model="morning" @change="getData">
@@ -35,8 +35,8 @@
                             <el-option
                                 v-for="(item, index) in addresses"
                                 :key="index"
-                                :value="item"
-                                :label="item"
+                                :value="item.value"
+                                :label="item.value"
                             ></el-option>
                         </el-select>
                     </el-form-item>
@@ -63,7 +63,9 @@
             <el-table-column prop="arrangeName" label="分组" min-width="160"> </el-table-column>
             <el-table-column prop="name" label="节目名称" min-width="70"> </el-table-column>
             <el-table-column prop="specialty" label="参赛专业"> </el-table-column>
-            <el-table-column prop="participant" label="参赛人员"> </el-table-column>
+            <el-table-column prop="participant" label="参赛人员" show-overflow-tooltip>
+                <template slot-scope="{ row }">{{ row.participant.join(',') }}</template>
+            </el-table-column>
             <el-table-column prop="quantity" label="表演人数" min-width="70"> </el-table-column>
             <el-table-column prop="signedIn" label="状态" :formatter="signedInFormatter"> </el-table-column>
             <el-table-column prop="score" label="成绩"> </el-table-column>
@@ -158,7 +160,8 @@ export default {
             addresses: [],
             morning: true,
             date: new Date(),
-            columnKeys: ['arrangeName']
+            columnKeys: ['arrangeName'],
+            addressList: []
         };
     },
     created() {
@@ -184,6 +187,22 @@ export default {
                             value: item.id
                         });
                     });
+                    this.$http
+                        .post('/performanceSchedule/all', { size: 100 }, { body: 'json' })
+                        .then(res => {
+                            if (res.content.length > 0) {
+                                res.content.forEach(item => {
+                                    this.addressList.push({
+                                        value: item.address,
+                                        pid: item.performanceId
+                                    });
+                                });
+                            }
+                        })
+                        .catch(e => {
+                            console.log(e);
+                            this.$message.error(e.error);
+                        });
                 }
             })
             .catch(e => {

+ 25 - 1
src/test/java/com/izouma/wenlvju/repo/RepoTest.java

@@ -5,8 +5,10 @@ import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.izouma.wenlvju.ApplicationTests;
 import com.izouma.wenlvju.domain.*;
+import com.izouma.wenlvju.domain.performance.Programme;
 import com.izouma.wenlvju.enums.RateStatus;
 import com.izouma.wenlvju.exception.BusinessException;
+import com.izouma.wenlvju.repo.performance.ProgrammeRepo;
 import com.izouma.wenlvju.service.storage.StorageService;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -33,6 +35,10 @@ public class RepoTest extends ApplicationTests {
     private RateAuditRepo    rateAuditRepo;
     @Autowired
     private SettingRepo      settingRepo;
+    @Autowired
+    private ProgrammeRepo    programmeRepo;
+    @Autowired
+    private ArtTypeRepo      artTypeRepo;
 
     @Test
     public void test() {
@@ -174,9 +180,27 @@ public class RepoTest extends ApplicationTests {
     }
 
     @Test
-    public void test4(){
+    public void test4() {
         Path path = Paths.get(System.getProperty("user.dir"), "src", "main", "resources", "templates", "Programme.xlsx");
         System.out.println(this.getClass().getResource("/templates/Programme.xlsx").getFile());
         System.out.println(this.getClass().getResource("Programme.xlsx").getPath());
     }
+
+    @Test
+    public void test5() {
+        List<Programme> programmes = programmeRepo.findAll();
+        List<ArtType> artTypes = artTypeRepo.findAll();
+        Map<String, ArtType> codeMap = artTypes.stream()
+                .collect(Collectors.toMap(ArtType::getCode, artType -> artType));
+        Map<Long, ArtType> idMap = artTypes.stream().collect(Collectors.toMap(ArtType::getId, artType -> artType));
+        programmes.forEach(programme -> {
+            ArtType artType = idMap.get(programme.getSpecialtyId());
+            String code = artType.getCode().substring(0, 2);
+            ArtType parent = codeMap.get(code);
+            programme.setParentSpecialtyId(parent.getId());
+//            programmeRepo.save(programme);
+//            System.out.println(artType.getId() + "--->" + artType.getCode() + "--->" + code + "---->" + parent.getId());
+        });
+        programmeRepo.saveAll(programmes);
+    }
 }