panhui 3 years ago
parent
commit
a8e30651af

BIN
src/assets/icon_fenxiang_close.png


BIN
src/assets/kong-pimg-zhanji.png


BIN
src/assets/png-guoqi.png


BIN
src/assets/png-jieshubisai.png


BIN
src/assets/png-liuju.png


BIN
src/assets/png-quxiaobaoming.png


BIN
src/assets/png-shiyong.png


BIN
src/assets/png-tuichu.png


+ 88 - 0
src/components/PassInfo.vue

@@ -0,0 +1,88 @@
+<template>
+    <div class="pass-info" :class="{ used: info.used || info.expired }">
+        <van-image width="136" height="64" :src="ticketInfo.img" fit="cover" />
+        <div class="pass-content">
+            <div class="text1">{{ ticketInfo.label }}</div>
+            <div class="flex1"></div>
+            <div class="text2">编号:{{ info.id }}</div>
+            <div class="text2">到期时间:{{ info.expireAt }}</div>
+        </div>
+        <img src="@assets/png-shiyong.png" v-if="info.used" alt="" class="status" />
+        <img src="@assets/png-guoqi.png" v-if="info.expired" alt="" class="status" />
+    </div>
+</template>
+
+<script>
+import room from '../mixins/room.js';
+export default {
+    props: {
+        info: {
+            type: Object,
+            default: () => {
+                return {};
+            }
+        }
+    },
+    mixins: [room],
+    computed: {
+        ticketInfo() {
+            let info = [...this.requireTicketOptions].find(item => {
+                return item.value === this.info.type;
+            });
+            return info ? info : {};
+        }
+    }
+};
+</script>
+
+<style lang="less" scoped>
+.pass-info {
+    .flex();
+    background-color: @bg2;
+    border-radius: 4px;
+    padding: 12px;
+    position: relative;
+    .pass-content {
+        margin-left: 10px;
+        .text1 {
+            font-size: 14px;
+            color: #ffffff;
+            line-height: 24px;
+        }
+
+        .text2 {
+            font-size: 12px;
+            color: #6a6d83;
+            line-height: 17px;
+        }
+        .text2 + .text2 {
+            margin-top: 2px;
+        }
+    }
+
+    &.used {
+        &::after {
+            content: '';
+            position: absolute;
+            top: 0;
+            left: 0;
+            right: 0;
+            bottom: 0;
+            background: rgba(37, 40, 61, 0.2);
+            z-index: 2;
+        }
+    }
+}
+.pass-info + .pass-info {
+    margin-top: 16px;
+}
+
+.status {
+    position: absolute;
+    width: 51px;
+    height: 46px;
+    right: 0;
+    top: 0;
+    z-index: 3;
+}
+</style>

+ 11 - 2
src/components/RoomInfo.vue

@@ -25,7 +25,9 @@
 
         <div class="ticket">{{ getLabelName(info.requireTicket, requireTicketOptions, 'saishi') }}</div>
 
-        <div class="status">{{ getLabelName(info.status, statusOptions) }}</div>
+        <div class="status" :class="{ status1: info.status === 'WAITING', status2: info.status === 'GAMING' }">
+            {{ getLabelName(info.status, statusOptions) }}
+        </div>
     </div>
 </template>
 <script>
@@ -148,7 +150,14 @@ export default {
     color: #ffffff;
     line-height: 18px;
     padding: 0 16px;
-    background: #5464e6;
+    background: #313346;
     border-radius: 0px 4px 0px 4px;
+
+    &.status1 {
+        background-color: #5464e6;
+    }
+    &.status2 {
+        background-color: #e24f4f;
+    }
 }
 </style>

+ 80 - 0
src/components/room/joinGame.vue

@@ -0,0 +1,80 @@
+<template>
+    <van-dialog
+        v-model:show="show"
+        theme="round-button"
+        show-cancel-button
+        confirm-button-text="直接进入"
+        cancel-button-text="分享进入"
+        @confirm="confirm"
+        @cancel="cancel"
+    >
+        <div class="dialog-title">
+            <img src="@assets/icon-lijibaoming.png" alt="" />
+            <span>请选择进入游戏的方式</span>
+        </div>
+    </van-dialog>
+</template>
+
+<script>
+import room from '../../mixins/room.js';
+export default {
+    mixins: [room],
+    props: {
+        roomInfo: {
+            type: Object,
+            default: () => {
+                return {};
+            }
+        }
+    },
+    computed: {
+        requireTicketInfo() {
+            let info = [...this.requireTicketOptions].find(item => {
+                return item.value === this.roomInfo.requireTicket;
+            });
+            return info ? info : {};
+        }
+    },
+    data() {
+        return {
+            show: false,
+            message: ''
+        };
+    },
+    methods: {
+        init(url = '') {
+            this.show = true;
+        },
+        confirm() {},
+        cancel() {
+            this.$router.back();
+        }
+    }
+};
+</script>
+
+<style lang="less" scoped>
+.dialog-title {
+    .flex-col();
+    align-items: center;
+    padding: 20px 0 24px;
+    img {
+        width: 48px;
+        height: 48px;
+    }
+    span {
+        font-size: 18px;
+        font-weight: bold;
+        color: #ffffff;
+        line-height: 24px;
+        margin-top: 12px;
+    }
+}
+
+.dialog-tips {
+    font-size: 14px;
+    color: #6a6d83;
+    line-height: 20px;
+    padding: 0 20px 30px;
+}
+</style>

+ 3 - 1
src/components/room/joinRoom.vue

@@ -63,7 +63,9 @@ export default {
                         })
                         .then(res => {
                             this.$toast.success('加入成功');
-                            this.$emit('update');
+                            setTimeout(() => {
+                                this.$emit('update');
+                            }, 1000);
                         })
                         .catch(e => {
                             console.log(e);

+ 32 - 4
src/components/room/playerInfo.vue

@@ -1,10 +1,10 @@
 <template>
-    <van-dialog v-model:show="show" theme="round-button" confirm-button-text="知道了">
+    <van-dialog v-model:show="show" theme="round-button" :showConfirmButton="false">
         <div class="dialog-title">
             <span>玩家信息</span>
         </div>
         <div class="player-list">
-            <div class="player" v-for="(item, index) in players" :key="index">
+            <div class="player" v-for="(item,index) in players" :key="index">
                 <van-image
                     width="40"
                     height="40"
@@ -16,8 +16,12 @@
                     <div class="text1">{{ item.nickname }}</div>
                     <div class="text2">ID:{{ item.userId }}</div>
                 </div>
+                <div class="btn">踢出</div>
             </div>
         </div>
+        <template #footer>
+            <img class="close-img" @click="show = false" src="@assets/icon_fenxiang_close.png" alt="" />
+        </template>
     </van-dialog>
 </template>
 
@@ -33,7 +37,8 @@ export default {
     },
     data() {
         return {
-            show: true
+            show: false,
+            playerInfo: {}
         };
     },
     computed: {
@@ -42,8 +47,9 @@ export default {
         }
     },
     methods: {
-        init(url = '') {
+        init(info) {
             this.show = true;
+            this.playerInfo = info;
         }
     }
 };
@@ -73,6 +79,9 @@ export default {
     line-height: 20px;
     padding: 0 20px 30px;
 }
+.player-list {
+    padding-bottom: 100px;
+}
 .player {
     .flex();
     padding: 10px 20px;
@@ -90,5 +99,24 @@ export default {
             line-height: 17px;
         }
     }
+    .btn {
+        width: 52px;
+        border-radius: 4px;
+        border: 1px solid #ff4f50;
+        font-size: 12px;
+        font-weight: bold;
+        color: #ff4f50;
+        line-height: 24px;
+        text-align: center;
+    }
+}
+
+.close-img {
+    position: absolute;
+    width: 40px;
+    height: 40px;
+    left: 50%;
+    margin-left: -20px;
+    bottom: -60px;
 }
 </style>

+ 120 - 0
src/components/room/result.vue

@@ -0,0 +1,120 @@
+<template>
+    <van-dialog v-model:show="show" theme="round-button" show-cancel-button @confirm="confirm">
+        <div class="dialog-title">
+            <span>上传比赛截图</span>
+        </div>
+        <div class="dialog-tips">
+            <van-uploader
+                :max-count="1"
+                v-model="pic"
+                preview-size="132px"
+                upload-text="点击上传"
+                upload-icon=" "
+                :after-read="afterRead"
+            />
+        </div>
+    </van-dialog>
+</template>
+
+<script>
+export default {
+    props: {
+        roomId: {
+            type: String,
+            default: ''
+        }
+    },
+    data() {
+        return {
+            show: false,
+            pic: []
+        };
+    },
+    methods: {
+        init(url = '') {
+            this.show = true;
+        },
+        confirm() {
+            if (this.pic.length === 0) {
+                this.$toast('请上传比赛截图');
+                return;
+            }
+            this.$toast.loading({
+                message: '加载中...',
+                forbidClick: true
+            });
+            this.$http
+                .post('/room/uploadResult', {
+                    roomId: this.roomId,
+                    screenShot: this.pic[0].url
+                })
+                .then(res => {
+                    this.$toast.success('上传成功');
+                    setTimeout(() => {
+                        this.$emit('update');
+                    }, 1000);
+                })
+                .catch(e => {
+                    this.$toast.clear();
+                    this.$dialog.alert({
+                        title: '温馨提示',
+                        message: e.error,
+                        confirmButtonText: '知道了'
+                    });
+                });
+        },
+        cancel() {
+            this.$router.back();
+        },
+        afterRead(file, e) {
+            file.status = 'uploading';
+            this.updateFile(file, 'id', 1000).then(img => {
+                console.log(img);
+                file.url = img;
+                file.status = 'done';
+            });
+        }
+    }
+};
+</script>
+
+<style lang="less" scoped>
+.dialog-title {
+    .flex-col();
+    align-items: center;
+    padding: 20px 0 24px;
+    img {
+        width: 48px;
+        height: 48px;
+    }
+    span {
+        font-size: 18px;
+        font-weight: bold;
+        color: #ffffff;
+        line-height: 24px;
+        margin-top: 12px;
+    }
+}
+
+.dialog-tips {
+    .flex();
+    justify-content: center;
+    padding-bottom: 30px;
+}
+/deep/.van-uploader {
+    .van-uploader__upload {
+        border: 1px dashed #6a6d83;
+        background: rgba(255, 255, 255, 0.1);
+        height: 100px !important;
+        margin: 0 0;
+    }
+    .van-uploader__upload-text {
+        margin-top: 0;
+        color: #6a6d83;
+        font-size: 14px;
+    }
+    .van-uploader__preview-image {
+        height: 100px !important;
+    }
+}
+</style>

+ 1 - 1
src/mixins/common.js

@@ -53,7 +53,7 @@ export default {
             formData.append('width', size);
             formData.append('height', size);
             formData.append('size', size);
-            return http.axios.post('/upload/user', formData).then(res => {
+            return http.axios.post('/upload/file', formData).then(res => {
                 return Promise.resolve(res.data);
             });
         },

+ 1 - 1
src/mixins/room.js

@@ -2,7 +2,7 @@ export default {
     data() {
         return {
             statusOptions: [
-                { label: '报名中', value: 'WAITING' },
+                { label: '匹配中', value: 'WAITING' },
                 { label: '进行中', value: 'GAMING' },
                 { label: '完成', value: 'FINISH' },
                 { label: '取消', value: 'CANCEL' },

+ 2 - 2
src/styles/app.less

@@ -160,8 +160,8 @@ input:-webkit-autofill {
 }
 
 .van-empty__image {
-    width: 235px;
-    height: 170px;
+    width: 200px;
+    height: 160px;
 }
 
 .van-tabs__line {

+ 104 - 37
src/views/Home.vue

@@ -24,39 +24,50 @@
                 创建房间
             </van-button>
 
-            <van-search v-model="search" left-icon=" " show-action placeholder="输入房间号码" action-text="搜索" />
+            <van-search
+                v-model="search"
+                left-icon=" "
+                @search="searchList"
+                @cancel="searchList"
+                show-action
+                placeholder="输入房间号码"
+                action-text="搜索"
+            />
         </div>
 
         <div class="room-list">
             <div class="room-title">房间列表</div>
+            <van-sticky>
+                <div class="tab-content">
+                    <van-tabs
+                        swipeable
+                        v-model:active="active"
+                        @change="changeTab"
+                        shrink
+                        line-width="34px"
+                        line-height="2px"
+                    >
+                        <van-tab title="对局大厅"> </van-tab>
+                        <van-tab title="我的房间"> </van-tab>
+                        <template #nav-right>
+                            <van-tabs class="tabs" v-model:active="zone" @change="changeTab" type="card">
+                                <van-tab title="QQ区" name="QQ"></van-tab>
+                                <van-tab title="微信区" name="微信"></van-tab>
+                            </van-tabs>
+                        </template>
+                    </van-tabs>
+                </div>
+            </van-sticky>
 
-            <div class="tab-content">
-                <van-tabs swipeable sticky v-model:active="active" shrink line-width="34px" line-height="2px">
-                    <van-tab title="对局大厅">
-                        <van-list
-                            class="list"
-                            v-model:loading="loading"
-                            :immediate-check="false"
-                            :finished="finished"
-                            finished-text=""
-                            @load="getData"
-                        >
-                            <room-info v-for="(item, index) in list" :key="index" :info="item"></room-info>
-                        </van-list>
-                    </van-tab>
-                    <van-tab title="我的房间">
-                        <div class="van-list">
-                            <room-info></room-info>
-                        </div>
-                    </van-tab>
-                    <template #nav-right>
-                        <van-tabs class="tabs" v-model:active="type" type="card">
-                            <van-tab title="QQ区"></van-tab>
-                            <van-tab title="微信区"></van-tab>
-                        </van-tabs>
-                    </template>
-                </van-tabs>
-            </div>
+            <van-list
+                v-model:loading="loading"
+                :immediate-check="false"
+                :finished="finished"
+                finished-text=""
+                @load="getData"
+            >
+                <room-info v-for="(item, index) in list" :key="index" :info="item"></room-info>
+            </van-list>
         </div>
     </van-pull-refresh>
 </template>
@@ -89,7 +100,14 @@ export default {
         RoomInfo
     },
     computed: {
-        ...mapState(['userInfo'])
+        ...mapState(['userInfo']),
+        url() {
+            if (this.active === 0) {
+                return '/room/roomList';
+            } else {
+                return '/room/my';
+            }
+        }
     },
     data() {
         return {
@@ -98,13 +116,22 @@ export default {
             search: '',
             active: 0,
             type: 0,
-            url: '/room/roomList',
             list: [],
-            httpType: 'get'
+            httpType: 'get',
+            zone: 'QQ'
         };
     },
     mounted() {
         this.getInit();
+        this.emitter.on('updateList', info => {
+            let list = [...this.list];
+            list.forEach((item, index) => {
+                if (info.id === item.id) {
+                    list[index] = info;
+                }
+            });
+            this.list = list;
+        });
 
         // this.$http.get('sysConfig/get/home_bg').then(res => {
         //     this.bgImg = res.value || '';
@@ -116,15 +143,30 @@ export default {
                 message: '加载中...',
                 forbidClick: true
             });
-            this.$toast.clear();
-            return this.getData();
+            return this.getData().then(() => {
+                this.$toast.clear();
+            });
             // return Promise.all([this.getBanner()]).then(() => {
             //     this.$toast.clear();
             //     return Promise.resolve();
             // });
             // this.getNews();
         },
-        beforeData() {},
+        beforeData() {
+            if (this.active === 0) {
+                return {
+                    zone: this.zone,
+                    status: 'WAITING,GAMING',
+                    id: this.search
+                };
+            } else {
+                return {
+                    query: {
+                        zone: this.zone
+                    }
+                };
+            }
+        },
         getProduct() {
             return Promise.resolve();
         },
@@ -159,6 +201,29 @@ export default {
         },
         goCreate() {
             this.$router.push('/roomCreate');
+        },
+        changeTab() {
+            this.$nextTick(() => {
+                this.$toast.loading({
+                    message: '加载中...',
+                    forbidClick: true
+                });
+                this.getData(true).then(() => {
+                    this.$toast.clear();
+                });
+            });
+        },
+        searchList() {
+            this.active = 0;
+            this.$nextTick(() => {
+                this.$toast.loading({
+                    message: '加载中...',
+                    forbidClick: true
+                });
+                this.getData(true).then(() => {
+                    this.$toast.clear();
+                });
+            });
         }
     },
     activated() {
@@ -170,9 +235,7 @@ export default {
         });
     },
     beforeRouteLeave(to, from, next) {
-        this.$el.parentNode.childNodes[1].className =
-            this.$el.parentNode.childNodes[1].className.replace(/ bgBack/, '') + ' bgBack';
-        if (!to.meta.menuPage && to.path !== '/agreement') {
+        if (to.path === '/room') {
             this.scrollTop = this.scrollWrapper.scrollTop;
             this.setKeeps(['index', 'home']);
         } else {
@@ -300,4 +363,8 @@ export default {
         margin-top: 16px;
     }
 }
+
+/deep/.van-sticky--fixed {
+    padding-top: var(--safe-top);
+}
 </style>

+ 23 - 2
src/views/Mine.vue

@@ -46,7 +46,7 @@
                 <div class="text2">绿洲石</div>
             </div>
             <div class="menu-card" @click="$router.push('/userPass')">
-                <div class="text1">1</div>
+                <div class="text1">{{ userTickets }}</div>
                 <div class="text2">通行证</div>
             </div>
         </div>
@@ -86,7 +86,8 @@ import { mapState } from 'vuex';
 export default {
     data() {
         return {
-            faceAuth: true
+            faceAuth: true,
+            userTickets: 0
         };
     },
     computed: {
@@ -97,6 +98,26 @@ export default {
         }
     },
     inject: ['safeTop'],
+    mounted() {
+        if (this.isLogin) {
+            this.$http
+                .post(
+                    '/userTicket/my',
+                    {
+                        size: 1,
+                        query: {
+                            used: false,
+                            expired: false,
+                            del: false
+                        }
+                    },
+                    { body: 'json' }
+                )
+                .then(res => {
+                    this.userTickets = res.totalElements;
+                });
+        }
+    },
     methods: {
         goAuth() {
             this.$router.push('/faceAuth');

+ 131 - 35
src/views/Room.vue

@@ -53,12 +53,7 @@
                         <div class="player-item">
                             <div class="title">客队</div>
                             <template v-if="info.maxPlayerNum === 2">
-                                <div
-                                    class="list1 not"
-                                    @click="choosePerson(item)"
-                                    v-for="(item, index) in guests"
-                                    :key="index"
-                                >
+                                <div class="list1 not" v-for="(item, index) in guests" :key="index">
                                     <van-image
                                         width="58"
                                         height="58"
@@ -70,12 +65,7 @@
                                 </div>
                             </template>
                             <div class="list" v-else>
-                                <div
-                                    class="person"
-                                    @click="choosePerson(item)"
-                                    v-for="(item, index) in guests"
-                                    :key="index"
-                                >
+                                <div class="person" v-for="(item, index) in guests" :key="index">
                                     <van-image
                                         width="24"
                                         height="24"
@@ -105,6 +95,14 @@
         </div>
 
         <div class="help">
+            <div class="help-btn" v-if="isJoin" @click="back">
+                <img src="@assets/png-tuichu.png" alt="" />
+                <span>退出</span>
+            </div>
+            <div class="help-btn" v-if="isHost" @click="$refs.failed.init()">
+                <img src="@assets/png-liuju.png" alt="" />
+                <span>流局</span>
+            </div>
             <div class="help-btn" @click="$refs.description.init()">
                 <img src="@assets/png-shuoming.png" alt="" />
                 <span>说明</span>
@@ -112,17 +110,33 @@
         </div>
 
         <div class="bottom" v-if="isJoin">
-            <div class="btn" @click="changeUrl" v-if="isHost">
-                <img src="@assets/png-xiugaidizhi.png" alt="" />
-                <span>修改地址</span>
+            <div class="join-btn" v-if="isFull">
+                <van-button type="primary" v-if="info.status == 'WAITING'" block @click="start">开始比赛</van-button>
+                <van-button type="primary" v-else-if="info.status == 'GAMING'" block @click="$refs.joinGame.init()"
+                    >进入比赛</van-button
+                >
             </div>
-            <div class="btn" @click="$router.push('/exceptionLogAdd?roomId=' + roomId)">
-                <img src="@assets/png-yicangshenbao.png" alt="" />
-                <span>异常申报</span>
-            </div>
-            <div class="btn">
-                <img src="@assets/png-quxiaosaishi.png" alt="" />
-                <span>取消赛事</span>
+            <div class="btns">
+                <div class="btn" v-if="!isHost" @click="quit">
+                    <img src="@assets/png-quxiaobaoming.png" alt="" />
+                    <span>取消报名</span>
+                </div>
+                <div class="btn" @click="changeUrl" v-if="isHost">
+                    <img src="@assets/png-xiugaidizhi.png" alt="" />
+                    <span>修改地址</span>
+                </div>
+                <div class="btn" @click="$router.push('/exceptionLogAdd?roomId=' + roomId)">
+                    <img src="@assets/png-yicangshenbao.png" alt="" />
+                    <span>异常申报</span>
+                </div>
+                <div class="btn" v-if="isHost && info.status == 'WAITING'">
+                    <img src="@assets/png-quxiaosaishi.png" alt="" />
+                    <span>取消赛事</span>
+                </div>
+                <div class="btn" v-if="info.status == 'GAMING'" @click="$refs.result.init()">
+                    <img src="@assets/png-jieshubisai.png" alt="" />
+                    <span>结束比赛</span>
+                </div>
             </div>
         </div>
         <change-url ref="url" :roomId="roomId"></change-url>
@@ -130,6 +144,8 @@
         <description ref="description"></description>
         <failed ref="failed"></failed>
         <player-info ref="player" :roomInfo="info"></player-info>
+        <join-game ref="joinGame" :roomInfo="info"></join-game>
+        <result ref="result" :roomId="roomId" @update="getInfo"></result>
     </div>
 </template>
 
@@ -137,9 +153,11 @@
 import room from '../mixins/room.js';
 import changeUrl from '../components/room/changeUrl.vue';
 import joinRoom from '../components/room/joinRoom.vue';
+import joinGame from '../components/room/joinGame.vue';
 import description from '../components/room/description.vue';
 import failed from '../components/room/failed.vue';
 import playerInfo from '../components/room/playerInfo.vue';
+import result from '../components/room/result.vue';
 export default {
     data() {
         return {
@@ -188,7 +206,7 @@ export default {
             return list;
         },
         isHost() {
-            return this.host.id === this.$store.state.userInfo.id;
+            return this.host.userId === this.$store.state.userInfo.id;
         },
         isJoin() {
             if (this.isHost) {
@@ -207,7 +225,7 @@ export default {
         }
     },
     mixins: [room],
-    components: { changeUrl, joinRoom, description, failed, playerInfo },
+    components: { changeUrl, joinRoom, description, failed, playerInfo, joinGame, result },
     mounted() {
         if (this.$route.query.id) {
             this.roomId = this.$route.query.id;
@@ -220,13 +238,20 @@ export default {
                 message: '加载中...',
                 forbidClick: true
             });
-            this.$http.get('/room/detail/' + this.roomId).then(res => {
-                this.$toast.clear();
-                this.info = res;
-                if (!this.isFull && !this.isJoin && res.status === 'WAITING') {
-                    this.$refs.join.init();
-                }
-            });
+            this.$http
+                .get('/room/detail/' + this.roomId)
+                .then(res => {
+                    this.$toast.clear();
+                    this.info = res;
+                    if (!this.isFull && !this.isJoin && res.status === 'WAITING') {
+                        this.$refs.join.init();
+                    }
+                })
+                .catch(e => {
+                    if (e && e.error) {
+                        this.$toast(e.error);
+                    }
+                });
         },
         changeUrl() {
             this.$refs.url.init(this.info.url);
@@ -235,8 +260,70 @@ export default {
             this.$router.back();
         },
         choosePerson(info) {
-            console.log(info);
+            if (this.isHost) {
+                this.$refs.player.init();
+            }
+        },
+        quit() {
+            this.$dialog
+                .confirm({
+                    title: '提示',
+                    message: '确认要取消报名吗?',
+                    confirmButtonText: '立即取消'
+                })
+                .then(() => {
+                    this.$toast.loading({
+                        message: '加载中...',
+                        forbidClick: true
+                    });
+                    return this.$http.post('/room/quit', {
+                        roomId: this.roomId
+                    });
+                })
+                .then(() => {
+                    this.$toast.success('取消成功');
+                    setTimeout(() => {
+                        this.back();
+                    }, 1000);
+                })
+                .catch(e => {
+                    if (e && e.error) {
+                        this.$toast(e.error);
+                    }
+                });
+        },
+        start() {
+            this.$dialog
+                .confirm({
+                    title: '提示',
+                    message: '确认要开始比赛吗?',
+                    confirmButtonText: '立即开始'
+                })
+                .then(() => {
+                    this.$toast.loading({
+                        message: '加载中...',
+                        forbidClick: true
+                    });
+                    return this.$http.post('/room/startGame', {
+                        roomId: this.roomId
+                    });
+                })
+                .then(() => {
+                    this.getInfo();
+                })
+                .catch(e => {
+                    if (e && e.error) {
+                        this.$toast(e.error);
+                    }
+                });
+        }
+    },
+
+    beforeRouteLeave(to, from, next) {
+        if (this && this.emitter) {
+            this.emitter.emit('updateList', this.info);
         }
+        next();
     }
 };
 </script>
@@ -444,12 +531,15 @@ export default {
     bottom: 0;
     left: 0;
     right: 0;
-    height: 56px;
     .bottom(0px);
-    .flex();
+    .btns {
+        .flex();
+        height: 56px;
+        padding: 0 32px;
+        justify-content: space-between;
+    }
 
     .btn {
-        flex-grow: 1;
         .flex();
         justify-content: center;
         img {
@@ -464,6 +554,9 @@ export default {
             margin-left: 4px;
         }
     }
+    .join-btn {
+        padding: 16px 32px 0;
+    }
 }
 
 .help {
@@ -492,6 +585,9 @@ export default {
             line-height: 10px;
         }
     }
+    .help-btn + .help-btn {
+        margin-top: 24px;
+    }
 }
 
 .person {

+ 1 - 1
src/views/RoomCreate.vue

@@ -6,7 +6,7 @@
                     <template #input>
                         <div class="tabs">
                             <div class="tab" :class="{ prim: form.zone === 'QQ' }" @click="form.zone = 'QQ'">QQ区</div>
-                            <div class="tab" :class="{ prim: form.zone === 'wechat' }" @click="form.zone = 'wechat'">
+                            <div class="tab" :class="{ prim: form.zone === '微信' }" @click="form.zone = '微信'">
                                 微信区
                             </div>
                         </div>

+ 64 - 48
src/views/user/Pass.vue

@@ -1,34 +1,80 @@
 <template>
     <div class="pass">
-        <van-tabs sticky swipeable v-model:active="active" shrink line-width="34" line-height="2" scrollspy>
-            <van-tab title="未使用">
-                <div class="van-list">
-                    <div class="pass-info">
-                        <van-image width="136" height="64" :src="require('@assets/qingtong.png')" fit="cover" />
-                        <div class="pass-content">
-                            <div class="text1">青铜通行证</div>
-                            <div class="flex1"></div>
-                            <div class="text2">编号:78738373788</div>
-                            <div class="text2">到期时间:2022-7-20</div>
-                        </div>
-                    </div>
-                </div>
-            </van-tab>
-            <van-tab title="已使用">内容 2</van-tab>
-            <van-tab title="已过期">内容 3</van-tab>
-        </van-tabs>
+        <van-sticky :offset-top="barHeight">
+            <van-tabs
+                swipeable
+                v-model:active="active"
+                @change="changeTab"
+                shrink
+                line-width="34"
+                line-height="2"
+                scrollspy
+            >
+                <van-tab title="未使用"> </van-tab>
+                <van-tab title="已使用"></van-tab>
+                <van-tab title="已过期"></van-tab>
+            </van-tabs>
+        </van-sticky>
+        <van-list v-model:loading="loading" :finished="finished" finished-text="" @load="getData">
+            <pass-info v-for="(item, index) in list" :key="index" :info="item"></pass-info>
+            <van-empty
+                v-if="empty"
+                description="当前没有战绩哦~"
+                :image="require('../../assets/kong-pimg-zhanji.png')"
+            />
+        </van-list>
     </div>
 </template>
 
 <script>
+import list from '../../mixins/list.js';
+import passInfo from '../../components/PassInfo.vue';
 export default {
     data() {
         return {
-            active: 0
+            active: 0,
+            url: '/userTicket/my'
         };
     },
+    inject: ['barHeight'],
+    mixins: [list],
+    components: { passInfo },
     mounted() {
         this.emitter.emit('setRightBar', { text: '明细', path: '/userPassList' });
+    },
+    methods: {
+        beforeData() {
+            if (this.active === 0) {
+                return {
+                    query: {
+                        used: false,
+                        expired: false,
+                        del: false
+                    }
+                };
+            } else if (this.active == 1) {
+                return {
+                    query: {
+                        used: true,
+                        expired: false,
+                        del: false
+                    }
+                };
+            } else {
+                return {
+                    query: {
+                        used: false,
+                        expired: true,
+                        del: false
+                    }
+                };
+            }
+        },
+        changeTab() {
+            this.$nextTick(() => {
+                this.getData(true);
+            });
+        }
     }
 };
 </script>
@@ -43,34 +89,4 @@ export default {
 .van-list {
     padding: 16px;
 }
-.pass-info {
-    .flex();
-    background-color: @bg2;
-    border-radius: 4px;
-    padding: 12px;
-    .pass-content {
-        margin-left: 10px;
-        .text1 {
-            font-size: 14px;
-            color: #ffffff;
-            line-height: 24px;
-        }
-
-        .text2 {
-            font-size: 12px;
-            color: #6a6d83;
-            line-height: 17px;
-        }
-        .text2 + .text2 {
-            margin-top: 2px;
-        }
-    }
-}
-.pass-info + .pass-info {
-    margin-top: 16px;
-}
-
-/deep/.van-swipe__track {
-    min-height: calc(var(--app-height) - var(--safe-top) - var(--safe-bottom) - 90px);
-}
 </style>

+ 64 - 39
src/views/user/Records.vue

@@ -1,48 +1,68 @@
 <template>
     <div class="record">
-        <van-tabs v-model:active="active" line-width="28px" line-height="2px" shrink swipeable swipe-threshold="3">
-            <van-tab title="全部">
-                <div class="van-list">
-                    <div class="record-info">
-                        <van-image
-                            width="58"
-                            height="58"
-                            radius="4"
-                            fit="cover"
-                            src="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
-                        />
-                        <div class="record-content">
-                            <div class="text1">
-                                <span>1v1</span>
-                                <span>不限英雄</span>
-                                <span>墨家机关道</span>
-                            </div>
-                            <div class="text2">
-                                <span>QQ区</span>
-                                <span>房间号 8783737</span>
-                            </div>
-                            <div class="text3">
-                                <img src="@assets/png-time.png" alt="" />
-                                <span>07-05 14:56</span>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </van-tab>
-            <van-tab title="匹配中">内容 2</van-tab>
-            <van-tab title="进行中">内容 3</van-tab>
-            <van-tab title="已结束">内容 4</van-tab>
-            <van-tab title="已流局">内容 4</van-tab>
-        </van-tabs>
+        <van-sticky :offset-top="barHeight">
+            <van-tabs v-model:active="status" line-width="28px" line-height="2px" shrink swipeable swipe-threshold="3">
+                <van-tab :title="item.label" :name="item.value" v-for="(item, index) in tabs" :key="index"> </van-tab>
+            </van-tabs>
+        </van-sticky>
+
+        <van-list v-model:loading="loading" :finished="finished" finished-text="" @load="getData">
+            <room-info v-for="(item, index) in showList" :key="index" :info="item"></room-info>
+            <van-empty
+                v-if="!loading && showList.length === 0"
+                description="当前没有战绩哦~"
+                :image="require('../../assets/kong-pimg-zhanji.png')"
+            />
+        </van-list>
     </div>
 </template>
 
 <script>
+import list from '../../mixins/list.js';
+import room from '../../mixins/room.js';
+import RoomInfo from '../../components/RoomInfo.vue';
 export default {
+    name: 'records',
+    inject: ['barHeight', 'setKeeps', 'scrollWrapper', 'changeScroll'],
     data() {
         return {
-            active: 0
+            status: '',
+            url: '/room/my',
+            httpType: 'get',
+            list: [],
+            scrollTop: 0
         };
+    },
+    computed: {
+        tabs() {
+            return [{ label: '全部', value: '' }, ...this.statusOptions];
+        },
+        showList() {
+            let list = [...this.list];
+            if (this.status) {
+                list = list.filter(item => {
+                    return item.status === this.status;
+                });
+            }
+            return list;
+        }
+    },
+    components: { RoomInfo },
+    mixins: [list, room],
+    activated() {
+        this.$nextTick(() => {
+            this.changeScroll(this.scrollTop || 0);
+        });
+    },
+    beforeRouteLeave(to, from, next) {
+        if (to.path === '/room') {
+            this.scrollTop = this.scrollWrapper.scrollTop;
+            this.setKeeps(['records']);
+        } else {
+            this.scrollTop = 0;
+            this.setKeeps(['irecords'], false);
+        }
+        next();
     }
 };
 </script>
@@ -58,10 +78,6 @@ export default {
     margin-left: 10px;
 }
 
-.van-list {
-    padding: 16px;
-}
-
 .record-info {
     .flex();
     align-items: flex-end;
@@ -100,4 +116,13 @@ export default {
         }
     }
 }
+
+.van-list {
+    padding: 16px;
+    min-height: var(--app-height);
+
+    .room + .room {
+        margin-top: 16px;
+    }
+}
 </style>