xiongzhu 3 жил өмнө
parent
commit
655f525be7

+ 2 - 0
src/main/java/com/izouma/yags/domain/Room.java

@@ -57,6 +57,8 @@ public class Room extends BaseEntity {
     @Convert(converter = LongArrayConverter.class)
     private List<Long> winner;
 
+    private String winTeam;
+
     @ApiModelProperty("需要门票")
     @Enumerated(EnumType.STRING)
     @Column(length = 20)

+ 36 - 1
src/main/java/com/izouma/yags/service/RoomService.java

@@ -310,7 +310,11 @@ public class RoomService {
             }
 
             if (!win) {
-                throw new BusinessException("失败方无需上传截图");
+                JoinRoom j = joinRoomRepo.findFirstByRoomIdAndUserId(roomId, userId).orElseThrow(new BusinessException("无记录"));
+                j.setScreenShot(screenShot);
+                joinRoomRepo.save(j);
+                return;
+//                throw new BusinessException("失败方无需上传截图");
             }
             if (!gameMode.getName().equals(mode)) {
                 throw new BusinessException("游戏模式不一致");
@@ -331,6 +335,7 @@ public class RoomService {
                 }
             });
 
+            room.setWinTeam(joinRoom.getTeam());
             room.setStatus(RoomStatus.FINISH);
             room.setFinishAt(LocalDateTime.now());
             room.setWinner(joinRoomList.stream().filter(j -> j.getTeam().equals(joinRoom.getTeam()))
@@ -448,6 +453,36 @@ public class RoomService {
                 j.setStatus(JoinRoomStatus.LOSE);
             }
         }
+        room.setWinTeam(team);
+        room.setStatus(RoomStatus.FINISH);
+        room.setFinishAt(LocalDateTime.now());
+        room.setWinner(joinRoomList.stream().filter(j -> j.getTeam().equals(team))
+                .map(JoinRoom::getUserId).collect(Collectors.toList()));
+        roomRepo.save(room);
+    }
+
+    public void changeJudge(Long roomId, String team) {
+        Room room = roomRepo.findById(roomId).orElseThrow(new BusinessException("房间无记录"));
+        if (room.getStatus() != RoomStatus.FINISH) {
+            throw new BusinessException("房间状态不正确");
+        }
+        List<JoinRoom> joinRoomList = joinRoomRepo.findByRoomIdAndStatusNotIn(room.getId(),
+                Arrays.asList(JoinRoomStatus.KICKED_OUT, JoinRoomStatus.QUIT));
+        String currentWinTeam = joinRoomList.stream().filter(j -> j.getStatus() == JoinRoomStatus.WIN)
+                .findAny().map(JoinRoom::getTeam).orElseThrow(new BusinessException("没有胜利的队伍"));
+        if (currentWinTeam.equals(team)) {
+            throw new BusinessException("当前队伍已经是胜利的队伍");
+        }
+        for (JoinRoom j : joinRoomList) {
+            j.setFinishAt(LocalDateTime.now());
+            if (j.getTeam().equals(team)) {
+                j.setStatus(JoinRoomStatus.WIN);
+                userBalanceService.modifyBalance(j.getUserId(), room.getBonus(), Constants.BalanceDesc.BONUS);
+            } else {
+                j.setStatus(JoinRoomStatus.LOSE);
+                userBalanceService.modifyBalance(j.getUserId(), room.getBonus(), Constants.BalanceDesc.BONUS);
+            }
+        }
         room.setStatus(RoomStatus.FINISH);
         room.setFinishAt(LocalDateTime.now());
         room.setWinner(joinRoomList.stream().filter(j -> j.getTeam().equals(team))

+ 6 - 0
src/main/java/com/izouma/yags/web/RoomController.java

@@ -129,5 +129,11 @@ public class RoomController extends BaseController {
     public void judge(@RequestParam Long roomId, @RequestParam String team) {
         roomService.judge(roomId, team);
     }
+
+    @PostMapping("/changeJudge")
+    @PreAuthorize("hasRole('ADMIN')")
+    public void changeJudge(@RequestParam Long roomId, @RequestParam String team) {
+        roomService.changeJudge(roomId, team);
+    }
 }
 

+ 1 - 0
src/main/vue/src/mixins/pageableTable.js

@@ -13,6 +13,7 @@ export default {
         };
     },
     created() {
+        this.beforeCreated && this.beforeCreated();
         this.page = Number(this.$route.query.page) || 1;
         if (this.$route.query.sort) {
             let sort = {};

+ 32 - 18
src/main/vue/src/views/Judge.vue

@@ -1,15 +1,6 @@
 <template>
     <div class="list-view">
         <page-title>
-            <el-button
-                @click="addRow"
-                type="primary"
-                icon="el-icon-plus"
-                :disabled="fetchingData || downloading"
-                class="filter-item"
-            >
-                新增
-            </el-button>
             <el-button
                 @click="download"
                 icon="el-icon-upload2"
@@ -21,6 +12,14 @@
             </el-button>
         </page-title>
         <div class="filters-container">
+            <el-select v-model="status" placeholder="状态" clearable @change="getData">
+                <el-option
+                    v-for="item in statusOptions"
+                    :key="item.value"
+                    :value="item.value"
+                    :label="item.label"
+                ></el-option>
+            </el-select>
             <el-input
                 placeholder="搜索..."
                 v-model="search"
@@ -47,16 +46,13 @@
             <el-table-column prop="userId" label="用户ID"> </el-table-column>
             <el-table-column prop="type" label="房间类型" :formatter="typeFormatter"> </el-table-column>
             <el-table-column prop="gameId" label="游戏ID"> </el-table-column>
-            <el-table-column prop="minPlayerNum" label="最小参赛人数"> </el-table-column>
-            <el-table-column prop="maxPlayerNum" label="最大参赛人数"> </el-table-column>
-            <el-table-column prop="url" label="游戏进入链接"> </el-table-column>
             <el-table-column prop="status" label="房间状态" :formatter="statusFormatter"> </el-table-column>
-            <el-table-column prop="winner" label="获胜用户"> </el-table-column>
             <el-table-column prop="requireTicket" label="需要门票" :formatter="requireTicketFormatter">
             </el-table-column>
             <el-table-column prop="gameModeId" label="游戏模式"> </el-table-column>
             <el-table-column prop="gameMapId" label="游戏地图"> </el-table-column>
             <el-table-column prop="bonus" label="奖金"> </el-table-column>
+            <el-table-column prop="createdAt" label="创建时间" width="150"></el-table-column>
             <el-table-column label="操作" align="center" fixed="right" width="150">
                 <template slot-scope="{ row }">
                     <el-button @click="editRow(row)" type="primary" size="mini" plain>查看</el-button>
@@ -142,7 +138,7 @@
                             :disabled="judging"
                             v-if="selected && selected.status === 'AUDIT'"
                         >
-                            队胜
+                            队胜
                         </el-button>
                     </div>
                 </el-col>
@@ -171,9 +167,9 @@ export default {
                 { label: '报名中', value: 'WAITING' },
                 { label: '进行中', value: 'GAMING' },
                 { label: '完成', value: 'FINISH' },
-                { label: '取消', value: 'CANCEL' },
                 { label: '待裁判', value: 'AUDIT' },
-                { label: '流局', value: 'PASSED' }
+                { label: '流局', value: 'PASSED' },
+                { label: '取消', value: 'CANCELLED' }
             ],
             requireTicketOptions: [
                 { label: '1', value: 'LEVEL_1' },
@@ -192,7 +188,8 @@ export default {
             guestTeam: [],
             hostPreview: [],
             guestPreview: [],
-            judging: false
+            judging: false,
+            status: null
         };
     },
     computed: {
@@ -201,6 +198,11 @@ export default {
         }
     },
     methods: {
+        beforeCreated() {
+            if (this.$route.query.status) {
+                this.status = this.$route.query.status;
+            }
+        },
         typeFormatter(row, column, cellValue, index) {
             let selectedOption = this.typeOptions.find(i => i.value === cellValue);
             if (selectedOption) {
@@ -223,7 +225,7 @@ export default {
             return '';
         },
         beforeGetData() {
-            return { search: this.search, query: { del: false, needAudit: true } };
+            return { search: this.search, query: { del: false, needAudit: true, status: this.status } };
         },
         toggleMultipleMode(multipleMode) {
             this.multipleMode = multipleMode;
@@ -301,6 +303,18 @@ export default {
                     this.$message.error(e.error || '失败');
                 });
         }
+    },
+    watch: {
+        status(val) {
+            this.$router
+                .replace({
+                    query: {
+                        ...this.$route.query,
+                        status: val
+                    }
+                })
+                .catch(_ => {});
+        }
     }
 };
 </script>

+ 150 - 47
src/main/vue/src/views/RoomList.vue

@@ -1,15 +1,6 @@
 <template>
     <div class="list-view">
         <page-title>
-            <el-button
-                @click="addRow"
-                type="primary"
-                icon="el-icon-plus"
-                :disabled="fetchingData || downloading"
-                class="filter-item"
-            >
-                新增
-            </el-button>
             <el-button
                 @click="download"
                 icon="el-icon-upload2"
@@ -21,6 +12,14 @@
             </el-button>
         </page-title>
         <div class="filters-container">
+            <el-select v-model="status" placeholder="状态" clearable @change="getData">
+                <el-option
+                    v-for="item in statusOptions"
+                    :key="item.value"
+                    :value="item.value"
+                    :label="item.label"
+                ></el-option>
+            </el-select>
             <el-input
                 placeholder="搜索..."
                 v-model="search"
@@ -42,26 +41,21 @@
             :height="tableHeight"
             v-loading="fetchingData"
         >
-            <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="userId" label="用户ID"> </el-table-column>
             <el-table-column prop="type" label="房间类型" :formatter="typeFormatter"> </el-table-column>
             <el-table-column prop="gameId" label="游戏ID"> </el-table-column>
-            <el-table-column prop="minPlayerNum" label="最小参赛人数"> </el-table-column>
-            <el-table-column prop="maxPlayerNum" label="最大参赛人数"> </el-table-column>
-            <el-table-column prop="url" label="游戏进入链接"> </el-table-column>
             <el-table-column prop="status" label="房间状态" :formatter="statusFormatter"> </el-table-column>
-            <el-table-column prop="winner" label="获胜用户"> </el-table-column>
             <el-table-column prop="requireTicket" label="需要门票" :formatter="requireTicketFormatter">
             </el-table-column>
             <el-table-column prop="gameModeId" label="游戏模式"> </el-table-column>
             <el-table-column prop="gameMapId" label="游戏地图"> </el-table-column>
             <el-table-column prop="bonus" label="奖金"> </el-table-column>
+            <el-table-column prop="createdAt" label="创建时间" width="150"></el-table-column>
             <el-table-column label="操作" align="center" fixed="right" width="150">
                 <template slot-scope="{ row }">
-                    <el-button @click="editRow(row)" type="primary" size="mini" plain>编辑</el-button>
-                    <el-button @click="deleteRow(row)" type="danger" size="mini" plain>删除</el-button>
+                    <el-button @click="editRow(row)" type="primary" size="mini" plain>查看</el-button>
                 </template>
             </el-table-column>
         </el-table>
@@ -86,6 +80,70 @@
             >
             </el-pagination>
         </div>
+        <el-dialog title="详情" :visible.sync="showDetail" width="1000px">
+            <el-row v-loading="loadingDetail">
+                <el-col :span="12">
+                    <h4 style="margin-left:30px;margin-top:0">主队</h4>
+                    <el-table :data="hostTeam">
+                        <el-table-column label="用户ID" prop="userId" width="80"> </el-table-column>
+                        <el-table-column label="用户昵称" prop="nickname"></el-table-column>
+                        <el-table-column label="游戏昵称" prop="gameNickname"></el-table-column>
+                        <el-table-column label="截图" width="80" align="center">
+                            <template v-slot="{ row }">
+                                <el-image
+                                    :src="row.screenShot"
+                                    class="screenshot"
+                                    :preview-src-list="hostPreview"
+                                    :z-index="3002"
+                                ></el-image>
+                            </template>
+                        </el-table-column>
+                    </el-table>
+                    <div style="margin-top:10px;text-align: center;">
+                        <el-button
+                            size="mini"
+                            type="primary"
+                            plain
+                            @click="judge('host')"
+                            :disabled="judging"
+                            v-if="selected && selected.status === 'FINISH'"
+                        >
+                            改判主队胜
+                        </el-button>
+                    </div>
+                </el-col>
+                <el-col :span="12">
+                    <h4 style="margin-left:30px;margin-top:0">客队</h4>
+                    <el-table :data="guestTeam">
+                        <el-table-column label="用户ID" prop="userId" width="80"> </el-table-column>
+                        <el-table-column label="用户昵称" prop="nickname"></el-table-column>
+                        <el-table-column label="游戏昵称" prop="gameNickname"></el-table-column>
+                        <el-table-column label="截图" width="80" align="center">
+                            <template v-slot="{ row }">
+                                <el-image
+                                    :src="row.screenShot"
+                                    class="screenshot"
+                                    :preview-src-list="guestPreview"
+                                    :z-index="3002"
+                                ></el-image>
+                            </template>
+                        </el-table-column>
+                    </el-table>
+                    <div style="margin-top:10px;text-align: center;">
+                        <el-button
+                            size="mini"
+                            type="primary"
+                            plain
+                            @click="judge('guest')"
+                            :disabled="judging"
+                            v-if="selected && selected.status === 'FINISH'"
+                        >
+                            改判客队胜
+                        </el-button>
+                    </div>
+                </el-col>
+            </el-row>
+        </el-dialog>
     </div>
 </template>
 <script>
@@ -109,9 +167,9 @@ export default {
                 { label: '报名中', value: 'WAITING' },
                 { label: '进行中', value: 'GAMING' },
                 { label: '完成', value: 'FINISH' },
-                { label: '取消', value: 'CANCEL' },
                 { label: '待裁判', value: 'AUDIT' },
-                { label: '流局', value: 'PASSED' }
+                { label: '流局', value: 'PASSED' },
+                { label: '取消', value: 'CANCELLED' }
             ],
             requireTicketOptions: [
                 { label: '1', value: 'LEVEL_1' },
@@ -122,7 +180,16 @@ export default {
                 { label: '6', value: 'LEVEL_6' },
                 { label: '7', value: 'LEVEL_7' },
                 { label: '8', value: 'LEVEL_8' }
-            ]
+            ],
+            loadingDetail: false,
+            showDetail: false,
+            selected: null,
+            hostTeam: [],
+            guestTeam: [],
+            hostPreview: [],
+            guestPreview: [],
+            judging: false,
+            status: null
         };
     },
     computed: {
@@ -131,6 +198,11 @@ export default {
         }
     },
     methods: {
+        beforeCreated() {
+            if (this.$route.query.status) {
+                this.status = this.$route.query.status;
+            }
+        },
         typeFormatter(row, column, cellValue, index) {
             let selectedOption = this.typeOptions.find(i => i.value === cellValue);
             if (selectedOption) {
@@ -153,7 +225,7 @@ export default {
             return '';
         },
         beforeGetData() {
-            return { search: this.search, query: { del: false } };
+            return { search: this.search, query: { del: false, status: this.status } };
         },
         toggleMultipleMode(multipleMode) {
             this.multipleMode = multipleMode;
@@ -170,12 +242,24 @@ export default {
             });
         },
         editRow(row) {
-            this.$router.push({
-                path: '/roomEdit',
-                query: {
-                    id: row.id
-                }
-            });
+            this.hostTeam = [];
+            this.guestTeam = [];
+            this.selected = row;
+            this.showDetail = true;
+            this.loadingDetail = true;
+            this.$http
+                .get(`/room/detail/${row.id}`)
+                .then(res => {
+                    this.loadingDetail = false;
+                    this.hostTeam = res.players.filter(i => i.team === 'host');
+                    this.guestTeam = res.players.filter(i => i.team === 'guest');
+                    this.hostPreview = this.hostTeam.map(i => i.screenShot).filter(i => i !== undefined);
+                    this.guestPreview = this.guestTeam.map(i => i.screenShot).filter(i => i !== undefined);
+                })
+                .catch(e => {
+                    this.loadingDetail = false;
+                    this.$message.error(e.error || '失败');
+                });
         },
         download() {
             this.downloading = true;
@@ -201,31 +285,50 @@ export default {
                     this.$message.error(e.error);
                 });
         },
-        operation1() {
-            this.$notify({
-                title: '提示',
-                message: this.selection
-            });
-        },
-        operation2() {
-            this.$message('操作2');
-        },
-        deleteRow(row) {
-            this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+        judge(team) {
+            this.$confirm(`确定改判为${'host' === team ? '主队' : '客队'}胜?`, '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            })
                 .then(() => {
-                    return this.$http.post(`/room/del/${row.id}`);
+                    this.judging = true;
+                    this.$http
+                        .post('/room/changeJudge', {
+                            roomId: this.selected.id,
+                            team
+                        })
+                        .then(res => {
+                            this.judging = false;
+                            this.$message.success('ok');
+                            this.showDetail = false;
+                            this.getData();
+                        })
+                        .catch(e => {
+                            this.judging = false;
+                            this.$message.error(e.error || '失败');
+                        });
                 })
-                .then(() => {
-                    this.$message.success('删除成功');
-                    this.getData();
-                })
-                .catch(e => {
-                    if (e !== 'cancel') {
-                        this.$message.error(e.error);
+                .catch(() => {});
+        }
+    },
+    watch: {
+        status(val) {
+            this.$router
+                .replace({
+                    query: {
+                        ...this.$route.query,
+                        status: val
                     }
-                });
+                })
+                .catch(_ => {});
         }
     }
 };
 </script>
-<style lang="less" scoped></style>
+<style lang="less" scoped>
+.screenshot {
+    width: 30px;
+    height: 30px;
+}
+</style>