laosan2382995021@163.com 4 år sedan
förälder
incheckning
17938fcdb5
100 ändrade filer med 1935 tillägg och 237 borttagningar
  1. 22 0
      package-lock.json
  2. 2 0
      package.json
  3. BIN
      public/svga/38f2a852a1f46b4ce9645dd71833c6af.svga
  4. BIN
      public/svga/858ac8f9b02b1795878bb438257f5f17.svga
  5. BIN
      public/svga/da4694f267f9b5810fda9c32a606615a.svga
  6. 7 1
      src/App.vue
  7. 0 0
      src/assets/images/icon.gif
  8. 3 3
      src/components/flat-list/mixins/on.ts
  9. 3 1
      src/components/index.ts
  10. 3 0
      src/components/svg-animate/index.ts
  11. 28 0
      src/components/svg-animate/props.ts
  12. 125 0
      src/components/svg-animate/src/main.vue
  13. 0 0
      src/components/svg-animate/style.scss
  14. 11 3
      src/config/cate.ts
  15. 2 0
      src/config/config.ts
  16. 3 0
      src/layout/layout-avatar/index.ts
  17. 25 0
      src/layout/layout-avatar/props.ts
  18. 28 0
      src/layout/layout-avatar/src/main.vue
  19. 9 0
      src/layout/layout-avatar/style.scss
  20. 46 39
      src/layout/layout-order-item/mixins/handle.ts
  21. 19 15
      src/layout/layout-order-receive-item/mixins/handle.ts
  22. 15 0
      src/layout/layout-talking/props.ts
  23. 20 4
      src/layout/layout-talking/src/main.vue
  24. 25 6
      src/layout/layout-talking/style.scss
  25. 65 0
      src/mixins/queue.ts
  26. 13 0
      src/mixins/user.ts
  27. 5 5
      src/pages/home/data/tabData.ts
  28. 3 0
      src/pages/talking/components/room-admission/index.ts
  29. 9 0
      src/pages/talking/components/room-admission/mixins/handle.ts
  30. 4 0
      src/pages/talking/components/room-admission/mixins/index.ts
  31. 0 0
      src/pages/talking/components/room-admission/props.ts
  32. 25 0
      src/pages/talking/components/room-admission/src/main.vue
  33. 13 0
      src/pages/talking/components/room-admission/style.scss
  34. 0 4
      src/pages/talking/components/room-info/data/wheat.ts
  35. 9 2
      src/pages/talking/components/room-info/mixins/handle.ts
  36. 3 1
      src/pages/talking/components/room-info/src/main.vue
  37. 33 2
      src/pages/talking/mixins/control.ts
  38. 59 14
      src/pages/talking/mixins/handle.ts
  39. 2 1
      src/pages/talking/mixins/index.ts
  40. 138 0
      src/pages/talking/mixins/micro.ts
  41. 8 125
      src/pages/talking/mixins/utils.ts
  42. 6 1
      src/pages/talking/src/main.vue
  43. 3 1
      src/popup/popup-export/components.ts
  44. 7 1
      src/popup/popup-export/const/index.ts
  45. 1 1
      src/popup/popup-export/global.ts
  46. 3 0
      src/popup/popup-password/index.ts
  47. 86 0
      src/popup/popup-password/mixins/handle.ts
  48. 4 0
      src/popup/popup-password/mixins/index.ts
  49. 44 0
      src/popup/popup-password/props.ts
  50. 44 0
      src/popup/popup-password/src/main.vue
  51. 19 0
      src/popup/popup-password/style.scss
  52. 5 1
      src/popup/popup-personal/components/index.ts
  53. 9 0
      src/popup/popup-personal/components/my-dress-up/components/dress-up-list/data/config.ts
  54. 3 0
      src/popup/popup-personal/components/my-dress-up/components/dress-up-list/index.ts
  55. 20 0
      src/popup/popup-personal/components/my-dress-up/components/dress-up-list/mixins/handle.ts
  56. 4 0
      src/popup/popup-personal/components/my-dress-up/components/dress-up-list/mixins/index.ts
  57. 13 0
      src/popup/popup-personal/components/my-dress-up/components/dress-up-list/props.ts
  58. 94 0
      src/popup/popup-personal/components/my-dress-up/components/dress-up-list/src/main.vue
  59. 47 0
      src/popup/popup-personal/components/my-dress-up/components/dress-up-list/style.scss
  60. 14 0
      src/popup/popup-personal/components/my-dress-up/components/dress-up-tab/data/tab.ts
  61. 3 0
      src/popup/popup-personal/components/my-dress-up/components/dress-up-tab/index.ts
  62. 8 0
      src/popup/popup-personal/components/my-dress-up/components/dress-up-tab/props.ts
  63. 61 0
      src/popup/popup-personal/components/my-dress-up/components/dress-up-tab/src/main.vue
  64. 28 0
      src/popup/popup-personal/components/my-dress-up/components/dress-up-tab/style.scss
  65. 9 0
      src/popup/popup-personal/components/my-dress-up/const/have.ts
  66. 14 0
      src/popup/popup-personal/components/my-dress-up/const/type.ts
  67. 19 0
      src/popup/popup-personal/components/my-dress-up/data/tab.ts
  68. 3 0
      src/popup/popup-personal/components/my-dress-up/index.ts
  69. 3 0
      src/popup/popup-personal/components/my-dress-up/mixins/index.ts
  70. 10 0
      src/popup/popup-personal/components/my-dress-up/props.ts
  71. 66 0
      src/popup/popup-personal/components/my-dress-up/src/main.vue
  72. 27 0
      src/popup/popup-personal/components/my-dress-up/style.scss
  73. 3 0
      src/popup/popup-personal/components/my-follow/components/follow-room/index.ts
  74. 37 0
      src/popup/popup-personal/components/my-follow/components/follow-room/mixins/handle.ts
  75. 3 0
      src/popup/popup-personal/components/my-follow/components/follow-room/mixins/index.ts
  76. 45 0
      src/popup/popup-personal/components/my-follow/components/follow-room/src/main.vue
  77. 3 0
      src/popup/popup-personal/components/my-follow/components/follow-room/style.scss
  78. 1 0
      src/popup/popup-personal/components/my-follow/components/index.ts
  79. 4 4
      src/popup/popup-personal/components/my-follow/data/tab.ts
  80. 2 1
      src/popup/popup-personal/data/menu.ts
  81. 1 1
      src/popup/popup-personal/props.ts
  82. 12 0
      src/popup/popup-ranking/components/ranking-list/data/ranking.ts
  83. BIN
      src/popup/popup-ranking/components/ranking-list/images/ranking/1.png
  84. BIN
      src/popup/popup-ranking/components/ranking-list/images/ranking/2.png
  85. BIN
      src/popup/popup-ranking/components/ranking-list/images/ranking/3.png
  86. 3 0
      src/popup/popup-ranking/components/ranking-list/index.ts
  87. 3 0
      src/popup/popup-ranking/components/ranking-list/props.ts
  88. 64 0
      src/popup/popup-ranking/components/ranking-list/src/main.vue
  89. 56 0
      src/popup/popup-ranking/components/ranking-list/style.scss
  90. 14 0
      src/popup/popup-ranking/components/ranking-tab/data/tab.ts
  91. 3 0
      src/popup/popup-ranking/components/ranking-tab/index.ts
  92. 3 0
      src/popup/popup-ranking/components/ranking-tab/props.ts
  93. 64 0
      src/popup/popup-ranking/components/ranking-tab/src/main.vue
  94. 29 0
      src/popup/popup-ranking/components/ranking-tab/style.scss
  95. 14 0
      src/popup/popup-ranking/data/tab.ts
  96. 3 0
      src/popup/popup-ranking/index.ts
  97. 16 0
      src/popup/popup-ranking/mixins/handle.ts
  98. 4 0
      src/popup/popup-ranking/mixins/index.ts
  99. 5 0
      src/popup/popup-ranking/props.ts
  100. 81 0
      src/popup/popup-ranking/src/main.vue

+ 22 - 0
package-lock.json

@@ -14,9 +14,11 @@
         "core-js": "^3.6.5",
         "easemob-websdk": "^3.5.2",
         "recorder-js": "^1.0.7",
+        "svgaplayerweb": "^2.3.2",
         "swiper": "^5.4.5",
         "vue": "^3.0.0",
         "vue-class-component": "^8.0.0-0",
+        "vue-navigation": "^1.1.4",
         "vue-router": "^4.0.0-0",
         "vuex": "^4.0.0-0"
       },
@@ -13945,6 +13947,11 @@
       "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=",
       "dev": true
     },
+    "node_modules/svgaplayerweb": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/svgaplayerweb/-/svgaplayerweb-2.3.2.tgz",
+      "integrity": "sha512-QuTvNIgy3W6Mi4h74SczEHUtAwb8m3ax7Ai7xRLUuN6hjJh49RGtWOWq1IuF2I7ECcl0HAYn8FcTn99UDz9UiQ=="
+    },
     "node_modules/svgo": {
       "version": "1.3.2",
       "resolved": "https://registry.npm.taobao.org/svgo/download/svgo-1.3.2.tgz",
@@ -15060,6 +15067,11 @@
       "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
       "dev": true
     },
+    "node_modules/vue-navigation": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/vue-navigation/-/vue-navigation-1.1.4.tgz",
+      "integrity": "sha512-flOvttNizFmnAj73hxrvGEMyOrbUiS7omKOTs+My+7wYdDjcW6JB8emGijy26/HyzcuPaiXbaUjZmXKRPFGfow=="
+    },
     "node_modules/vue-router": {
       "version": "4.0.8",
       "resolved": "https://registry.nlark.com/vue-router/download/vue-router-4.0.8.tgz",
@@ -27905,6 +27917,11 @@
       "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=",
       "dev": true
     },
+    "svgaplayerweb": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/svgaplayerweb/-/svgaplayerweb-2.3.2.tgz",
+      "integrity": "sha512-QuTvNIgy3W6Mi4h74SczEHUtAwb8m3ax7Ai7xRLUuN6hjJh49RGtWOWq1IuF2I7ECcl0HAYn8FcTn99UDz9UiQ=="
+    },
     "svgo": {
       "version": "1.3.2",
       "resolved": "https://registry.npm.taobao.org/svgo/download/svgo-1.3.2.tgz",
@@ -28807,6 +28824,11 @@
         }
       }
     },
+    "vue-navigation": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/vue-navigation/-/vue-navigation-1.1.4.tgz",
+      "integrity": "sha512-flOvttNizFmnAj73hxrvGEMyOrbUiS7omKOTs+My+7wYdDjcW6JB8emGijy26/HyzcuPaiXbaUjZmXKRPFGfow=="
+    },
     "vue-router": {
       "version": "4.0.8",
       "resolved": "https://registry.nlark.com/vue-router/download/vue-router-4.0.8.tgz",

+ 2 - 0
package.json

@@ -14,9 +14,11 @@
     "core-js": "^3.6.5",
     "easemob-websdk": "^3.5.2",
     "recorder-js": "^1.0.7",
+    "svgaplayerweb": "^2.3.2",
     "swiper": "^5.4.5",
     "vue": "^3.0.0",
     "vue-class-component": "^8.0.0-0",
+    "vue-navigation": "^1.1.4",
     "vue-router": "^4.0.0-0",
     "vuex": "^4.0.0-0"
   },

BIN
public/svga/38f2a852a1f46b4ce9645dd71833c6af.svga


BIN
public/svga/858ac8f9b02b1795878bb438257f5f17.svga


BIN
public/svga/da4694f267f9b5810fda9c32a606615a.svga


+ 7 - 1
src/App.vue

@@ -1,6 +1,12 @@
 <template>
+
     <layout-entry>
-      <router-view></router-view>
+        <router-view v-slot="{Component}">
+          <keep-alive ref="keep" :include="$store.state.router.keepLiveRoute">
+              <component :is="Component"></component>
+          </keep-alive>
+        </router-view>
+
     </layout-entry>
 </template>
 <script>

+ 0 - 0
src/layout/layout-talking/images/icon.gif → src/assets/images/icon.gif


+ 3 - 3
src/components/flat-list/mixins/on.ts

@@ -9,10 +9,10 @@ export default <LibMixins>{
     methods:{
 
         flat_clear_to_start(){
-          if (this.data.length > 0) {
+          if (this.data.length > 0 || this.status!==this.constStatus.default) {
               // 控制为 无状态
-              this.status = this.constStatus.none;
-              this._status = this.constStatus.none;
+              this.status = this.constStatus.default;
+              this._status = this.constStatus.default;
               this.setStart(true);
               return this.setData([],true);
           }

+ 3 - 1
src/components/index.ts

@@ -26,4 +26,6 @@ export { default as  stepper} from './stepper';
 
 export { default as  radio} from './radio';
 
-export { default as emptyItem } from './empty-item';
+export { default as emptyItem } from './empty-item';
+
+export { default as svgAnimate } from './svg-animate';

+ 3 - 0
src/components/svg-animate/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 28 - 0
src/components/svg-animate/props.ts

@@ -0,0 +1,28 @@
+export default {
+
+    src:{
+        type:String,
+        default:''
+    },
+
+    defaultSrc:{
+      type:String,
+      default:''
+    },
+
+    hover:{
+        type:Boolean,
+        default:false
+    },
+
+    size:{
+        type:String,
+        default:'60%'
+    },
+
+    loops:{
+        type:Number,
+        default:0
+    }
+
+}

+ 125 - 0
src/components/svg-animate/src/main.vue

@@ -0,0 +1,125 @@
+<template>
+  <div class="relative center" @mouseenter="enter" @mouseleave="leave">
+    <div v-if="draw" v-show="status" class="screen" ref="svg"></div>
+    <v-image v-show="!status" :style="{width:size,height:size}" v-if="defaultSrc" backgroundColor="transparent" :src="defaultSrc"></v-image>
+  </div>
+</template>
+
+<script>
+import * as SVGA from 'svgaplayerweb';
+import props from '../props';
+import {
+  vImage
+} from '$components';
+import {nextTick} from "vue";
+export default {
+  name: "svg-animate",
+
+  data(){
+    return {
+      draw:false,
+      status:false
+    }
+  },
+
+  watch:{
+    src:function (){
+
+      return this.play(this.loops);
+    }
+  },
+
+  methods:{
+
+    createPlay(){
+      if (this.player === undefined) this.player = new SVGA.Player(this.$refs.svg);
+      if (this.parser === undefined) this.parser = new SVGA.Parser();
+
+      if (this.$attrs.onStop) {
+        this.player.onFinished(()=> this.$emit('stop'));
+      }
+    },
+
+    // 清空帧
+    clear(){
+      if (this.player) {
+        this.player.clear();
+      }
+    },
+
+    // 暂停动画
+    pause(){
+      if (this.player) this.player.pauseAnimation();
+    },
+
+    // 播放动画
+    play(count=0){
+
+      if (!this.player) this.createPlay();
+
+      if (this.src && this.src !== this.play_src) {
+
+        this.play_src = this.src;
+        this.clear();
+        this.parser.load('http://localhost:8080/svga/'+this.play_src.split('/').pop(), (videoItem)=>{
+          this.player.loops = count;  // 设置循环播放次数是1
+          this.player.setVideoItem(videoItem);
+
+          this.player.setContentMode('AspectFill');
+
+          this.player.startAnimation();
+
+        });
+      } else if (this.src === this.play_src){
+        this.player.startAnimation();
+      }
+
+    },
+
+    // 进入
+    enter(){
+      if (!this.hover) return ;
+      if (!this.draw) this.draw = true;
+
+      this.status = true;
+
+      return nextTick(()=> this.play(0));
+    },
+
+    // 离开
+    leave(){
+      if (!this.hover) return ;
+      this.status = false;
+      this.pause();
+    }
+  },
+
+  beforeUnmount() {
+    if (this.player) {
+      this.player.clear();
+      this.player = undefined;
+      this.parser = undefined;
+    }
+  },
+
+  mounted() {
+    if (!this.hover){
+      this.play(this.loops);
+    }
+
+  },
+
+  created() {
+    this.draw = !this.hover;
+    this.status = !this.hover;
+  },
+
+  components:{
+    vImage
+  },
+
+  props
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 0 - 0
src/components/svg-animate/style.scss


+ 11 - 3
src/config/cate.ts

@@ -36,6 +36,7 @@ export default {
     },
 
     roomCate:{
+        object:{},
         config:{
             size:10,
             header:[
@@ -44,10 +45,17 @@ export default {
                     image:require('../views/view-cate/images/cate/1.png'),
                     tid:-999,
                     options:{
-                        collect:2,
-                        sort_type:'desc'
+                        collect:true
                     }
-                }
+                },
+                {
+                    label:'热门',
+                    image:require('../views/view-cate/images/cate/2.png'),
+                    tid:-998,
+                    options:{
+                        is_hot:2
+                    }
+                },
             ],
             footer:[
                 {

+ 2 - 0
src/config/config.ts

@@ -7,6 +7,8 @@ export default <Config>{
 
     app:undefined,
 
+    useRoutesName:[],
+
     register(vm){
         vm.$store.dispatch('initializationUserPromise');
         vm.$store.dispatch('initializationPayPromise');

+ 3 - 0
src/layout/layout-avatar/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 25 - 0
src/layout/layout-avatar/props.ts

@@ -0,0 +1,25 @@
+export default {
+
+    // 头像
+    src:{
+        type:String,
+        default:''
+    },
+
+    // 装扮
+    dressSrc:{
+        type:String,
+        default:''
+    },
+
+    dressPlaySrc:{
+        type:String,
+        default:''
+    },
+
+    radius:{
+        type:String,
+        default:'50%'
+    }
+
+}

+ 28 - 0
src/layout/layout-avatar/src/main.vue

@@ -0,0 +1,28 @@
+<template>
+  <div class="layout-avatar relative">
+    <v-image :src="src" class="screen" :radius="radius">
+      <svg-animate v-if="dressPlaySrc" :hover="true" size="100%" :default-src="dressSrc" :src="dressPlaySrc" class="absolute layout-avatar-dress"></svg-animate>
+      <div v-else-if="dressSrc" class="absolute layout-avatar-dress">
+        <v-image :src="dressSrc" mode="scaleToFill" backgroundColor="transparent" class="screen"></v-image>
+      </div>
+    </v-image>
+  </div>
+</template>
+
+<script>
+import {
+  vImage,
+  svgAnimate
+} from '$components';
+import props from '../props';
+export default {
+  name: "layout-avatar",
+  props,
+  components:{
+    vImage,
+    svgAnimate
+  }
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 9 - 0
src/layout/layout-avatar/style.scss

@@ -0,0 +1,9 @@
+/* 装扮 */
+$dress-width:-22px;
+.layout-avatar-dress{
+  top: $dress-width;
+  left: $dress-width;
+  right:$dress-width;
+  bottom: $dress-width;
+}
+/* 装扮 */

+ 46 - 39
src/layout/layout-order-item/mixins/handle.ts

@@ -20,21 +20,25 @@ export default <LibMixins>{
             return popup.$confirm({
                title:'确认该订单已完成?',
                confirm:()=>{
-                   this.$request({
-                       url:'player/confirm_palyer_order',
-                       data:{
-                           oid: this.item.oid
-                       },
-                       token:true,
-                       message:true,
-                       failMessage:true,
-                       loading:'确认中'
-                   }).then((data)=>{
-                       if (data.isSuccess) {
-                           // 设置订单已完成
-                           return this.updateOrderStatus(this.item,OrderPayStatus.completed);
-                       }
-                   })
+                   return new Promise((resolve, reject)=>{
+                       this.$request({
+                           url:'player/confirm_palyer_order',
+                           data:{
+                               oid: this.item.oid
+                           },
+                           token:true,
+                           message:true,
+                           failMessage:true,
+                           loading:'确认中'
+                       }).then((data)=>{
+                           resolve(false);
+                           if (data.isSuccess) {
+                               // 设置订单已完成
+                               return this.updateOrderStatus(this.item,OrderPayStatus.completed);
+                           }
+                       }).catch(reject);
+                   });
+
                }
             });
 
@@ -45,33 +49,36 @@ export default <LibMixins>{
                 title:'是否取消该订单?',
                 confirm:()=>{
 
-                    this.$request({
-                        url:'player/cancel_order',
-                        data:{
-                            oid: this.item.oid
-                        },
-                        token:true,
-                        message:true,
-                        failMessage:true,
-                        loading:'取消中'
-                    }).then((data)=>{
-                        if (data.isSuccess) {
-                            // 优先更新用户积分
-                            if (this.user.integral) {
-                                let integral =  parseFloat(this.user.integral) + this.item.total_amount;
-                                integral = integral <= 0 ? 0 : integral;
-                                this.user = {
-                                    integral
+                    return new Promise((resolve, reject)=>{
+                        this.$request({
+                            url:'player/cancel_order',
+                            data:{
+                                oid: this.item.oid
+                            },
+                            token:true,
+                            message:true,
+                            failMessage:true
+                        }).then((data)=>{
+                            resolve(false);
+                            if (data.isSuccess) {
+                                // 优先更新用户积分
+                                if (this.user.integral) {
+                                    let integral =  parseFloat(this.user.integral) + this.item.total_amount;
+                                    integral = integral <= 0 ? 0 : integral;
+                                    this.user = {
+                                        integral
+                                    }
                                 }
-                            }
-                            // 调用接口更新 防止出现意外
-                            this.$store.dispatch('updateUserMoneyPromise');
+                                // 调用接口更新 防止出现意外
+                                this.$store.dispatch('updateUserMoneyPromise');
 
-                            // 设置订单已取消
-                            return this.updateOrderStatus(this.item,OrderPayStatus.cancel);
+                                // 设置订单已取消
+                                return this.updateOrderStatus(this.item,OrderPayStatus.cancel);
+
+                            }
+                        }).catch(reject);
+                    });
 
-                        }
-                    })
                 }
             });
         }

+ 19 - 15
src/layout/layout-order-receive-item/mixins/handle.ts

@@ -20,21 +20,25 @@ export default <LibMixins>{
             return popup.$confirm({
                title:'是否确认接单?',
                confirm:()=>{
-                   this.$request({
-                       url:'player/take_player_order',
-                       data:{
-                           oid: this.item.oid
-                       },
-                       token:true,
-                       message:true,
-                       failMessage:true,
-                       loading:'接单中'
-                   }).then((data)=>{
-                       if (data.isSuccess) {
-                           // 设置订单已完成
-                           return this.updateOrderStatus(this.item,OrderPayStatus.have);
-                       }
-                   })
+                   return new Promise((resolve, reject)=>{
+                       this.$request({
+                           url:'player/take_player_order',
+                           data:{
+                               oid: this.item.oid
+                           },
+                           token:true,
+                           message:true,
+                           failMessage:true,
+                           loading:'接单中'
+                       }).then((data)=>{
+                           resolve(false);
+                           if (data.isSuccess) {
+                               // 设置订单已完成
+                               return this.updateOrderStatus(this.item,OrderPayStatus.have);
+                           }
+                       }).catch(reject);
+                   });
+
                }
             });
 

+ 15 - 0
src/layout/layout-talking/props.ts

@@ -5,6 +5,21 @@ export default {
         default:function (){
             return {}
         }
+    },
+
+    type:{
+        type:String,
+        default:''
+    },
+
+    index:{
+        type:Number,
+        default:0
+    },
+
+    nth:{
+        type:Number,
+        default:5
     }
 
 }

+ 20 - 4
src/layout/layout-talking/src/main.vue

@@ -1,13 +1,18 @@
 <template>
-  <aside class="layout-talking-item center cursor-pointer">
+  <aside class="layout-talking-item center cursor-pointer" @click="openDetail(item)"
+         :class="{
+            'layout-talking-clear-right': (index+1) % nth === 0,
+            ['layout-talking-'+type]:true
+         }"
+  >
     <div class="layout-talking-width row">
-      <div class="layout-talking-button center line-1">{{item.category_name}}</div>
+      <div v-if="item.category_name" class="layout-talking-button center line-1">{{item.category_name}}</div>
     </div>
     <v-image class="layout-talking-avatar" backgroundColor="transparent" :src="item.room_cover" radius="50%"></v-image>
     <div class="layout-talking-title line-1">{{item.room_name}}</div>
     <div class="rowACenter layout-talking-message">
-      <img src="../images/icon.gif" class="layout-talking-icon" />
-      <div class="layout-talking-number">{{item.visitor_num}}</div>
+      <img src="@/assets/images/icon.gif" class="layout-talking-icon" />
+      <div class="layout-talking-number">{{item.visitor_num || 0}}</div>
       <div>人正在语聊中</div>
     </div>
   </aside>
@@ -18,11 +23,22 @@ import {
   vImage
 } from '$components';
 import props from '../props';
+import personalDetail,{OpenType} from '$utils/control/personal-detail';
 export default {
   name: "layout-talking",
   components: {
     vImage
   },
+  methods:{
+
+    openDetail(item){
+      if (item.rid) {
+        return personalDetail.openDetail(item,OpenType.room);
+      }
+
+    }
+
+  },
   props
 }
 </script>

+ 25 - 6
src/layout/layout-talking/style.scss

@@ -6,14 +6,14 @@
   border-radius: 10px;
   padding: 0 20px;
   margin-right: 15px;
-  margin-bottom: 20px;
   transition: .3s;
+  margin-top: 20px;
 }
-.layout-talking-item:hover{
-  transform: translateY(10px);
+.layout-talking-clear-right{
+  margin-right: 0 !important;
 }
-.layout-talking-item:nth-of-type(5n){
-  margin-right: 0;
+.layout-talking-item:hover{
+  transform: translateY(-10px);
 }
 /* 容器 */
 
@@ -56,4 +56,23 @@
   font-size: 14px;
   margin: 0 3px;
 }
-/* 内容 */
+/* 内容 */
+
+/* 用户中心的样式 */
+.layout-talking-user{
+  width: 196px;
+  height: 254px;
+  margin-right: 13px;
+  margin-top: 10px;
+}
+.layout-talking-user:hover{
+  transform: translateY(-5px);
+}
+.layout-talking-user .layout-talking-title,.layout-talking-user  .layout-talking-message{
+  max-width: 100%;
+  width: auto;
+}
+.layout-talking-user .layout-talking-title{
+  margin-top: 20px;
+}
+/* 用户中心的样式 */

+ 65 - 0
src/mixins/queue.ts

@@ -0,0 +1,65 @@
+import { Queue,QueueItem } from '$utils/tool/queue';
+export default <LibMixins>{
+
+    data(){
+        return {
+            useQueueItem:null,
+            queueTime:3000,
+            triggerStatus:false
+        }
+    },
+
+    methods:{
+      pushQueue(data){
+
+          // @ts-ignore
+          data._id = new Date() * 1 + Math.floor(Math.random() * 1000);
+
+          this.queue.push(new QueueItem(data));
+
+          return this.triggerQueue();
+      },
+
+      // 执行队列
+      triggerQueue(){
+
+          if (!this.triggerStatus) {
+
+              clearTimeout(this.triggerTime);
+
+              this.triggerStatus = true;
+
+              return this.triggerQueueItem();
+          }
+
+      },
+
+      // 执行队列到具体的item
+      triggerQueueItem(){
+          // 获取第一个
+          let item = this.queue.shift();
+          if (item){
+              this.useQueueItem = item.data;
+          } else {
+              this.triggerStatus = false;
+              clearTimeout(this.triggerTime);
+          }
+
+          if (this.triggerStatus && this.queueTime) {
+              // 获取下一个
+              this.triggerTime = setTimeout(()=> this.triggerQueueItem(),this.queueTime);
+          }
+      }
+
+    },
+
+    created() {
+        // 创建队列
+        this.queue = new Queue();
+    },
+
+    beforeUnmount() {
+        clearTimeout(this.triggerTime);
+    }
+
+}

+ 13 - 0
src/mixins/user.ts

@@ -21,6 +21,19 @@ export default {
 
                 return this.$store.commit('setUserInfo',resultData);
             }
+        },
+        dress:{
+            get(){
+                return this.user.dress || {};
+            },
+            set(item){
+                let dress = this.dress;
+                item = JSON.parse(JSON.stringify(item));
+                this.user.dress = {
+                    ...dress,
+                    ...item
+                }
+            }
         }
     }
 

+ 5 - 5
src/pages/home/data/tabData.ts

@@ -1,12 +1,12 @@
 export default [
     {
-        label:'语聊厅',
-        component:'view-talking',
-        slot:'tab-1'
-    },
-    {
         label:'找陪玩',
         component:'view-play-with',
         slot:'tab-0'
+    },
+    {
+        label:'语聊厅',
+        component:'view-talking',
+        slot:'tab-1'
     }
 ] as LibDataArray

+ 3 - 0
src/pages/talking/components/room-admission/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 9 - 0
src/pages/talking/components/room-admission/mixins/handle.ts

@@ -0,0 +1,9 @@
+export default {
+
+    data(){
+        return {
+            queueTime:0
+        }
+    }
+
+}

+ 4 - 0
src/pages/talking/components/room-admission/mixins/index.ts

@@ -0,0 +1,4 @@
+import queue from '$mixins/queue';
+import handle from './handle';
+
+export default [queue,handle];

+ 0 - 0
src/pages/talking/components/room-admission/props.ts


+ 25 - 0
src/pages/talking/components/room-admission/src/main.vue

@@ -0,0 +1,25 @@
+<template>
+  <div v-show="triggerStatus" class="room-admission-container absolute">
+    <svg-animate
+        class="room-admission-svg"
+        v-if="useQueueItem"
+        :src="useQueueItem.zq_play_image+'?id='+useQueueItem._id"
+        :loops="1"
+        @stop="triggerQueueItem"
+    ></svg-animate>
+  </div>
+</template>
+
+<script>
+import {
+  svgAnimate
+} from '$components';
+import mixins from '../mixins';
+export default {
+  name: "room-admission",
+  components: {svgAnimate},
+  mixins
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 13 - 0
src/pages/talking/components/room-admission/style.scss

@@ -0,0 +1,13 @@
+/* 进场模块 */
+$room-size:350px;
+.room-admission-container{
+  @include square($room-size);
+  z-index: 99;
+  right: 350px;
+  bottom: 250px;
+  //pointer-events: none;
+}
+.room-admission-svg{
+  @include square($room-size);
+}
+/* 进场模块 */

+ 0 - 4
src/pages/talking/components/room-info/data/wheat.ts

@@ -18,10 +18,6 @@ export default {
             label:'上麦'
         },
 
-        [RowWheat.queuing]:{
-            label:'排麦中'
-        },
-
         [RowWheat.wheat]:{
             label:'下麦'
         }

+ 9 - 2
src/pages/talking/components/room-info/mixins/handle.ts

@@ -1,5 +1,9 @@
 import Throttle from '$utils/tool/throttle';
 import user from "$config/user";
+
+import socket from '$utils/socket';
+import {NoticeType} from "$utils/socket/const";
+
 export default <LibMixins>{
 
     data(){
@@ -48,8 +52,11 @@ export default <LibMixins>{
                     },
                     token:true
                 });
-
-
+                socket.triggerNotice(NoticeType.followRoom, {
+                    rid: this.info.rid,
+                    status: this._collect,
+                    data: this.info
+                });
 
             }
         }

+ 3 - 1
src/pages/talking/components/room-info/src/main.vue

@@ -122,7 +122,7 @@ export default {
     }
   },
 
-  inject:['applyForWheat','exitForWheat'],
+  inject:['applyForWheat','exitForWheat','cancelForWheat'],
 
   methods:{
 
@@ -135,6 +135,8 @@ export default {
 
       if (this.status === RowWheat.none) {
         this.applyForWheat();
+      } else if (this.status === RowWheat.queuing) {
+        this.cancelForWheat();
       } else if (this.status === RowWheat.wheat) {
         this.exitForWheat();
       }

+ 33 - 2
src/pages/talking/mixins/control.ts

@@ -19,7 +19,8 @@ export default <LibMixins>{
         return {
             openUserInfo:(event,userInfo)=> this.openUserInfo(event,userInfo),
             applyForWheat:(index:number|undefined)=> this.applyForWheat(index),
-            exitForWheat:()=> this.exitForWheat()
+            exitForWheat:()=> this.exitForWheat(),
+            cancelForWheat:()=> this.cancelForWheat()
         }
     },
 
@@ -36,6 +37,7 @@ export default <LibMixins>{
 
         // 申请上麦
         applyForWheat(index:number|undefined){
+
             if (this.wheat_status === RowWheat.queuing) {
                 return  popup.$toast('正在排麦中');
             } else if (!this.applyForWheatStatus) {
@@ -149,7 +151,36 @@ export default <LibMixins>{
             }
         },
 
-        //
+        // 取消排麦
+        cancelForWheat(){
+            if (this.wheat_status === RowWheat.queuing && !this.cancelForWheatStatus) {
+                popup.$confirm({
+                    title: '是否取消排麦?',
+                    successAsyncText: '取消成功',
+                    confirm:()=>{
+                        return new Promise((resolve, reject)=>{
+                            return this.$request({
+                                url:'room/quit_room_mc_queue',
+                                data:{
+                                    rid: this.$params.rid
+                                },
+                                token:true,
+                                failMessage:true,
+                                next:({status})=> this.cancelForWheatStatus = status,
+                                message: InstructionsMessageType.other
+                            }).then((data)=>{
+                                if (data.isSuccess) {
+                                    this.setMicroStatus(RowWheat.none);
+                                    return resolve(true);
+                                } else {
+                                    resolve(false);
+                                }
+                            }).catch(reject);
+                        });
+                    }
+                });
+            }
+        }
 
     }
 

+ 59 - 14
src/pages/talking/mixins/handle.ts

@@ -1,6 +1,10 @@
 import {InstructionsCacheType, InstructionsMessageType} from "$utils/request";
 import user from "$config/user";
 
+import cate from '$config/cate';
+
+import * as SVGA from 'svgaplayerweb';
+
 export default <LibMixins>{
 
 
@@ -32,27 +36,63 @@ export default <LibMixins>{
     methods:{
         // 房间信息
         fetchRoomInfo(){
+            if (this.$params.infoData) {
+                return this.setRoomInfo(JSON.parse(this.$params.infoData));
+            } else {
+                return this.$request({
+                    url:'room/enter_room_info',
+                    data:{
+                        rid: this.$params.rid,
+                        password: this.$params.password
+                    },
+                    token:true,
+                    cache:{
+                        type: InstructionsCacheType.memory
+                    },
+                    failMessage:true,
+                    message:InstructionsMessageType.other
+                }).then((data)=>{
+                    if (data.isSuccess) {
+                        this.setRoomInfo(data.data);
+                    } else {
+                        return this.$router.back();
+                    }
+
+                });
+            }
+        },
+
+        setRoomInfo(data){
+            this.roomInfo = data;
+        },
+
+        // 获取用户排麦状态
+        getUserRowWheat(){
             return this.$request({
-                url:'room/enter_room_info',
+                url:'room/get_user_mc_queue_status',
                 data:{
                     rid: this.$params.rid
                 },
-                token:true,
-                cache:{
-                    type: InstructionsCacheType.storage
-                },
-                failMessage:true,
-                message:InstructionsMessageType.other
+                token:true
             }).then((data)=>{
                 console.log(data);
-                if (data.isSuccess) {
-                    this.roomInfo = data.data;
-                } else {
-                    return this.$router.back();
-                }
-
             });
+        },
 
+        // 获取用户进入房间特权信息
+        getUserAdmission(){
+          return this.$request({
+              url:'room/get_room_user_vip',
+              data:{
+                  rid: this.$params.rid
+              },
+              cache:{
+                  type: InstructionsCacheType.memory
+              },
+              token:true
+          }).then((data)=>{
+              return this.addAdmission(data.data);
+          })
         },
 
         // 获取麦位详情
@@ -84,13 +124,18 @@ export default <LibMixins>{
             this.fetchRoomInfo();
             // 请求麦位信息
             this.getRoomMicroInfo();
-        }
+            // 获取用户排麦信息
+            this.getUserRowWheat();
+            // 获取用户入场特效
+            this.getUserAdmission();
+        },
     },
 
     created(){
         // new WebIM().install(this.$store.state.user.user);
         this.roomInfo = this.$params || {};
         this.install();
+
     }
 
 

+ 2 - 1
src/pages/talking/mixins/index.ts

@@ -2,6 +2,7 @@ import params from '$mixins/params';
 import handle from './handle';
 import control from './control';
 import agora from "./agora";
+import micro from './micro';
 import utils from './utils';
 
-export default [params,handle,control,agora,utils];
+export default [params,handle,control,agora,micro,utils];

+ 138 - 0
src/pages/talking/mixins/micro.ts

@@ -0,0 +1,138 @@
+import user from '$config/user';
+import {RowWheat} from "@/pages/talking/const";
+
+export default <LibMixins>{
+
+    methods:{
+
+        // 初始化麦位信息之后触发
+        installMicroInfo(){
+
+            let data = [this.microInfo.host_info,...this.microInfo.mc_list];
+
+            let resultData = {};
+            // 循环处理
+            data.map((item)=>{
+                if (item && item.mc_user_info && item.mc_user_info.uid) {
+                    resultData[item.mc_user_info.uid] = item;
+                }
+            });
+
+
+            this.micro_info = resultData;
+        },
+
+        // 查看用户是否出现在麦位信息中
+        hasMicroInfo(){
+            if (user.isLogin()) {
+                return this.micro_info[user.uid()];
+            }
+        },
+
+        // 获取空缺麦位的位置
+        getMicroIndex(uid =undefined){
+            let mcList = this.microInfo.mc_list || [];
+            for (let i=0,count=mcList.length;i<count;i++) {
+                if (uid) {
+                    if (mcList[i] && mcList[i].mc_user_info && mcList[i].mc_user_info.uid === uid) {
+                        return  i;
+                    }
+                } else {
+                    if (!mcList[i] || !mcList[i].mc_user_info || !mcList[i].mc_user_info.uid) {
+                        return i;
+                    }
+                }
+
+            }
+
+            return null;
+        },
+
+        // 进入麦位坐下
+        updateMicro(index:number | undefined,user){
+
+            if (index === undefined) index = this.getMicroIndex();
+
+            if (typeof index === 'number' && this.microInfo.mc_list) {
+
+                // 如果存在于其他麦位直接退出
+                this.exitMicro(user.uid);
+
+                this.microInfo.mc_list[index].mc_status = 3;
+                this.microInfo.mc_list[index].mc_user_info = user;
+
+                // 更新麦位信息
+                this.installMicroInfo();
+            }
+
+        },
+
+        // 进入主持麦位
+        updateHostMicro(user){
+            // 如果满足以下条件触发
+            if (this.microInfo && this.microInfo.host_info && !this.microInfo.host_info.uid) {
+                // 如果存在于其他麦位直接退出
+                this.exitMicro(user.uid);
+                this.microInfo.host_info.mc_status = 3;
+                this.microInfo.host_info.mc_user_info = user;
+                // 更新麦位信息
+                this.installMicroInfo();
+            }
+        },
+
+        // 设置坐下麦位
+        downMicro({
+            index,
+            host,
+            user
+        }:Record<string, any> = {}){
+
+            if (user) {
+                if (host) {
+                    this.updateHostMicro(user);
+                } else {
+                    this.updateMicro(index,user);
+                }
+            }
+
+            this.setMicroStatus(RowWheat.wheat);
+            return this.useAgora.joinPublished();
+        },
+
+        // 离开麦位
+        upMicro({
+            uid
+        } = {}){
+            if (uid) {
+                this.exitMicro(uid);
+            }
+            this.setMicroStatus(RowWheat.none);
+            return this.useAgora.unPublish();
+        },
+
+        exitMicro(uid){
+            if (uid) {
+                let item = this.micro_info[uid];
+                if (item) {
+                    item.mc_status = 2;
+                    item.mc_user_info = {};
+                    // 更新麦位信息
+                    this.installMicroInfo();
+                }
+            }
+
+        },
+
+        setMicroStatus(status){
+            if (this.wheat_status !== status) {
+                this.wheat_status = status;
+            }
+        }
+
+    },
+
+    created(){
+        this.micro_info = {};
+    }
+
+}

+ 8 - 125
src/pages/talking/mixins/utils.ts

@@ -1,138 +1,21 @@
-import user from '$config/user';
-import {RowWheat} from "@/pages/talking/const";
+import user from '$utils/control/user';
+import {Shield, UserConfigType} from "$utils/control/user/const";
 
 export default <LibMixins>{
 
     methods:{
 
-        // 初始化麦位信息之后触发
-        installMicroInfo(){
+        // 入场
+        addAdmission(item){
 
-            let data = [this.microInfo.host_info,...this.microInfo.mc_list];
-
-            let resultData = {};
-            // 循环处理
-            data.map((item)=>{
-                if (item && item.mc_user_info && item.mc_user_info.uid) {
-                    resultData[item.mc_user_info.uid] = item;
-                }
-            });
-
-
-            this.micro_info = resultData;
-        },
-
-        // 查看用户是否出现在麦位信息中
-        hasMicroInfo(){
-            if (user.isLogin()) {
-                return this.micro_info[user.uid()];
-            }
-        },
-
-        // 获取空缺麦位的位置
-        getMicroIndex(uid =undefined){
-            let mcList = this.microInfo.mc_list || [];
-            for (let i=0,count=mcList.length;i<count;i++) {
-                if (uid) {
-                    if (mcList[i] && mcList[i].mc_user_info && mcList[i].mc_user_info.uid === uid) {
-                        return  i;
-                    }
-                } else {
-                    if (!mcList[i] || !mcList[i].mc_user_info || !mcList[i].mc_user_info.uid) {
-                        return i;
-                    }
-                }
-
-            }
-
-            return null;
-        },
-
-        // 进入麦位坐下
-        updateMicro(index:number | undefined,user){
-
-            if (index === undefined) index = this.getMicroIndex();
-
-            if (typeof index === 'number' && this.microInfo.mc_list) {
-
-                // 如果存在于其他麦位直接退出
-                this.exitMicro(user.uid);
-
-                this.microInfo.mc_list[index].mc_status = 3;
-                this.microInfo.mc_list[index].mc_user_info = user;
-
-                // 更新麦位信息
-                this.installMicroInfo();
+            // 检查权限是否屏蔽了进场特效
+            if (!user.getDataItem(UserConfigType.shield,Shield.approach) && item.zq_play_image) {
+                // 添加入场动画
+                this.$refs.admission && this.$refs.admission.pushQueue(item);
             }
 
-        },
-
-        // 进入主持麦位
-        updateHostMicro(user){
-            // 如果满足以下条件触发
-            if (this.microInfo && this.microInfo.host_info && !this.microInfo.host_info.uid) {
-                // 如果存在于其他麦位直接退出
-                this.exitMicro(user.uid);
-                this.microInfo.host_info.mc_status = 3;
-                this.microInfo.host_info.mc_user_info = user;
-                // 更新麦位信息
-                this.installMicroInfo();
-            }
-        },
-
-        // 设置坐下麦位
-        downMicro({
-            index,
-            host,
-            user
-        }:Record<string, any> = {}){
-
-            if (user) {
-                if (host) {
-                    this.updateHostMicro(user);
-                } else {
-                    this.updateMicro(index,user);
-                }
-            }
-
-            this.setMicroStatus(RowWheat.wheat);
-            return this.useAgora.joinPublished();
-        },
-
-        // 离开麦位
-        upMicro({
-            uid
-        } = {}){
-            if (uid) {
-                this.exitMicro(uid);
-            }
-            this.setMicroStatus(RowWheat.none);
-            return this.useAgora.unPublish();
-        },
-
-        exitMicro(uid){
-            if (uid) {
-                let item = this.micro_info[uid];
-                if (item) {
-                    item.mc_status = 2;
-                    item.mc_user_info = {};
-                    // 更新麦位信息
-                    this.installMicroInfo();
-                }
-            }
-
-        },
-
-        setMicroStatus(status){
-            if (this.wheat_status !== status) {
-                this.wheat_status = status;
-            }
         }
 
-    },
-
-    created(){
-        this.micro_info = {};
     }
 
 }

+ 6 - 1
src/pages/talking/src/main.vue

@@ -1,5 +1,7 @@
 <template>
   <section class="screen flex talking-container" >
+    <!--  进场特效  -->
+    <room-admission ref="admission"></room-admission>
     <view-talking-header></view-talking-header>
     <section class="flex-1 container" :style="{background:'url('+roomInfo.room_background_image+') 0 0'}">
       <section class="flex talking-content screen">
@@ -34,6 +36,8 @@ import roomGift from '../components/room-gift';
 
 import roomRanking from '../components/room-ranking';
 
+import roomAdmission from '../components/room-admission';
+
 import mixins from '../mixins';
 
 export default {
@@ -49,7 +53,8 @@ export default {
     roomFooter,
     roomWheat,
     roomGift,
-    roomRanking
+    roomRanking,
+    roomAdmission
   },
   mixins
 }

+ 3 - 1
src/popup/popup-export/components.ts

@@ -23,5 +23,7 @@ export default {
     [PopupExportComponent.giftBubble]: defineAsyncComponent(()=> import('$popup/popup-gift-bubble')),
     [PopupExportComponent.giftIntroduce]: defineAsyncComponent(()=> import('$popup/popup-gift-introduce')),
     [PopupExportComponent.user]: defineAsyncComponent(()=> import('$popup/popup-user')),
-    [PopupExportComponent.select]: defineAsyncComponent(()=> import('$popup/popup-select'))
+    [PopupExportComponent.select]: defineAsyncComponent(()=> import('$popup/popup-select')),
+    [PopupExportComponent.password]: defineAsyncComponent(()=> import('$popup/popup-password')),
+    [PopupExportComponent.ranking]: defineAsyncComponent(()=> import('$popup/popup-ranking'))
 }

+ 7 - 1
src/popup/popup-export/const/index.ts

@@ -64,7 +64,13 @@ const enum PopupExportComponent {
     user='popup-user',
 
     // 选择框
-    select='popup-select'
+    select='popup-select',
+
+    // 密码
+    password='popup-password',
+
+    // 排行榜
+    ranking='popup-ranking'
 
 }
 

+ 1 - 1
src/popup/popup-export/global.ts

@@ -25,7 +25,7 @@ export default {
                 }
             }
 
-            // popup.$popup.open(PopupExportComponent.select);
+            // popup.$popup.open(PopupExportComponent.personal);
 
         });
 

+ 3 - 0
src/popup/popup-password/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 86 - 0
src/popup/popup-password/mixins/handle.ts

@@ -0,0 +1,86 @@
+import verification, {VerificationType} from '$utils/verification';
+import popup from "$utils/tool/popup";
+export default <LibMixins>{
+
+    data(){
+      return {
+          buttonAsync:false,
+          passwordValue:''
+      }
+    },
+
+    watch:{
+      title:function () {
+          if (!this.title) {
+              return this.triggerCancel();
+          }
+      },
+        password:function () {
+          this.changePassword(this.password);
+        },
+    },
+
+    methods:{
+
+        changePassword(value){
+            if (this.passwordValue !== value) {
+                this.passwordValue = value;
+            }
+        },
+
+        triggerCancel(){
+
+            if (this.value) {
+
+                this.$attrs.cancel && this.$attrs.cancel();
+
+                return this.close();
+            }
+
+        },
+
+        triggerConfirm(callback){
+
+            if (this.trim && !verification.trigger[VerificationType.empty](this.passwordValue)) {
+                return popup.$toast(this.placeholder);
+            }
+
+            if (this.value) {
+
+                let resultData = this.$attrs.confirm && this.$attrs.confirm(this.passwordValue);
+
+                if (resultData instanceof Promise) {
+                    this.storageResultData = resultData;
+                    this.buttonAsync = true;
+                    callback();
+                } else {
+                    return this.close();
+                }
+            }
+
+        },
+
+        triggerWaiting(obj){
+            this.storageResultData.then((value)=>{
+
+                if (value === false) {
+                    obj.none();
+                    return this.close();
+                } else {
+                    obj.success();
+                    this.triggerWaitingTime = setTimeout(()=> this.close(),this.successAsyncTime);
+                }
+
+            }).catch(()=>{
+                obj.none();
+                this.buttonAsync = false;
+            });
+        }
+
+    },
+
+    beforeUnmount() {
+        clearTimeout(this.triggerWaitingTime);
+    }
+
+}

+ 4 - 0
src/popup/popup-password/mixins/index.ts

@@ -0,0 +1,4 @@
+import popup from "$mixins/popup";
+import handle from './handle';
+
+export default [popup,handle];

+ 44 - 0
src/popup/popup-password/props.ts

@@ -0,0 +1,44 @@
+export default {
+
+    title:{
+      type:String,
+      default:'此房间已上锁请输入密码'
+    },
+
+    password:{
+      type:String,
+      default:''
+    },
+
+    placeholder:{
+      type:String,
+      default:'请输入密码'
+    },
+
+    trim:{
+        type:Boolean,
+        default:true
+    },
+
+    // 确认按钮的文字
+    confirmText:{
+        type:String
+    },
+
+    // 取消按钮的文字
+    cancelText:{
+        type:String
+    },
+
+    // 成功的按钮
+    successAsyncText:{
+        type:String
+    },
+
+    successAsyncTime:{
+        type:Number,
+        default:2000
+    },
+
+
+}

+ 44 - 0
src/popup/popup-password/src/main.vue

@@ -0,0 +1,44 @@
+<template>
+  <popup v-model:value="value" style="z-index: 999" content-animate="scale" @close="$emit('destroy-popup')">
+
+    <div class="confirm-container relative">
+
+      <div @click="close" v-if="!buttonAsync" class="absolute confirm-icon cursor-pointer animate-rotate-hover">
+        <icon type="close" class="confirm-icon-target"></icon>
+      </div>
+
+      <article class="confirm-title">{{title}}</article>
+
+      <section class="center">
+        <input class="password-input" v-model="passwordValue" type="text" :placeholder="placeholder" />
+      </section>
+
+      <section class="rowCenter">
+        <v-button @submit-verify="triggerConfirm" :success-text="successAsyncText" @submit="triggerWaiting" class="confirm-button" :class="{'confirm-button-screen':buttonAsync}">{{confirmText||'确定'}}</v-button>
+      </section>
+    </div>
+
+  </popup>
+</template>
+
+<script>
+import {
+  Popup,
+  vButton,
+  icon
+} from '$components';
+import mixins from '../mixins';
+import props from '../props';
+export default {
+  name: "popup-password",
+  components:{
+    Popup,
+    vButton,
+    icon
+  },
+  mixins,
+  props
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 19 - 0
src/popup/popup-password/style.scss

@@ -0,0 +1,19 @@
+@import "../popup-confirm/style";
+
+/* 输入框 */
+.password-input{
+  width: 230px;
+  height: 40px;
+  margin-bottom: 30px;
+  background-color: rgba(255,255,255,0.1);
+  border-radius: 20px !important;
+  padding: 0 20px;
+  font-size: 16px;
+  line-height: 20px;
+  text-align: center;
+  color: #fff;
+}
+.password-input::placeholder{
+  color: rgba(255,255,255,0.5);
+}
+/* 输入框 */

+ 5 - 1
src/popup/popup-personal/components/index.ts

@@ -15,6 +15,10 @@ export default {
     myFollow: defineAsyncComponent(()=> import('./my-follow')),
 
     // 我的礼物
-    myGift: defineAsyncComponent(()=> import('./my-gift'))
+    myGift: defineAsyncComponent(()=> import('./my-gift')),
+
+    // 个性装扮
+    myDressUp: defineAsyncComponent(()=> import('./my-dress-up'))
+
 
 }

+ 9 - 0
src/popup/popup-personal/components/my-dress-up/components/dress-up-list/data/config.ts

@@ -0,0 +1,9 @@
+import DressUpType from "$popup/popup-personal/components/my-dress-up/const/type";
+
+export default {
+
+    [DressUpType.avatar]:{
+        userAvatar:true
+    }
+
+}

+ 3 - 0
src/popup/popup-personal/components/my-dress-up/components/dress-up-list/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 20 - 0
src/popup/popup-personal/components/my-dress-up/components/dress-up-list/mixins/handle.ts

@@ -0,0 +1,20 @@
+export default <LibMixins>{
+
+    methods:{
+
+        fetch(obj){
+            return this.$request({
+                url:'user/get_user_decorate_list',
+                data:{
+                    type:this.type
+                },
+                token:true
+            }).then((data)=>{
+                console.log(data);
+                return obj.success(data.data);
+            });
+        }
+
+    }
+
+}

+ 4 - 0
src/popup/popup-personal/components/my-dress-up/components/dress-up-list/mixins/index.ts

@@ -0,0 +1,4 @@
+import handle from './handle';
+import user from '$mixins/user';
+
+export default [handle,user];

+ 13 - 0
src/popup/popup-personal/components/my-dress-up/components/dress-up-list/props.ts

@@ -0,0 +1,13 @@
+export default {
+
+    type:{
+        type:String,
+        default:'1'
+    },
+
+    have:{
+        type:[String,Number],
+        default:''
+    }
+
+}

+ 94 - 0
src/popup/popup-personal/components/my-dress-up/components/dress-up-list/src/main.vue

@@ -0,0 +1,94 @@
+<template>
+  <section class="screen row wrap">
+    <flat-list
+      @fetch="fetch"
+    >
+      <template v-slot:item="{item,index}">
+        <aside class="dress-up-item flex overflow">
+          <div class="flex-1 center">
+            <layout-avatar v-if="config.userAvatar" class="dress-up-avatar" :dress-play-src="item.play_image" :dress-src="item.base_image" :src="$store.state.user.user.head_pic"></layout-avatar>
+            <svg-animate v-else-if="item.play_image" :hover="true" :default-src="item.base_image" class="screen" :src="item.play_image"></svg-animate>
+            <v-image v-else class="dress-up-image" mode="aspectFit" backgroundColor="transparent" :src="item.base_image"></v-image>
+          </div>
+          <footer class="dress-up-footer center" v-if="have===DressHaveType.all">
+            <div class="dress-up-title line-1">{{item.title}}</div>
+            <div class="dress-up-introduce line-1">限时活动奖励</div>
+          </footer>
+          <footer class="dress-up-footer center" v-else>
+            <div class="dress-up-title line-1">{{item.title}}</div>
+            <div @click="setUseDress(item)" class="dress-up-use-button center button"
+              :class="{
+              'button-disabled':dress[type] && dress[type].udid === item.udid
+              }"
+            >{{ dress[type] && dress[type].udid === item.udid?'使用中':'使用' }}</div>
+          </footer>
+        </aside>
+      </template>
+
+    </flat-list>
+  </section>
+</template>
+
+<script>
+import {
+  FlatList,
+  vImage,
+  svgAnimate
+} from '$components';
+import layoutAvatar from '$layout/layout-avatar';
+import props from '../props.ts';
+import mixins from '../mixins';
+import config from '../data/config';
+import DressHaveType from "$popup/popup-personal/components/my-dress-up/const/have";
+import popup from "$utils/tool/popup";
+export default {
+  name: "dress-up-list",
+  components:{
+    FlatList,
+    vImage,
+    layoutAvatar,
+    svgAnimate
+  },
+
+  data(){
+    return {
+      DressHaveType:DressHaveType,
+
+    }
+  },
+
+  methods:{
+    setUseDress(item){
+      if (this.dress[this.type] && this.dress[this.type].udid === item.udid) return ;
+      return popup.$confirm({
+        title:'是否使用'+item.title+'装扮',
+        confirm:()=>{
+          this.$request({
+            url:'user/set_user_decorate',
+            data:{
+              udid: item.udid
+            },
+            token:true
+          });
+
+          this.dress = {
+            [this.type]:item
+          }
+
+        }
+      });
+    }
+  },
+
+  computed:{
+    config(){
+      return config[this.type] || {};
+    }
+  },
+
+  props,
+  mixins
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 47 - 0
src/popup/popup-personal/components/my-dress-up/components/dress-up-list/style.scss

@@ -0,0 +1,47 @@
+/* 模块 */
+.dress-up-item{
+  border: 1px solid #6F82F7;
+  border-radius: 10px;
+  width: 153px;
+  height: 200px;
+  background-color: rgba(255, 255, 255, 0.08);
+  margin-top: 10px;
+  margin-right: 15px;
+}
+.dress-up-item:nth-of-type(5n){
+  margin-right: 0;
+}
+.dress-up-image{
+  @include square(110px);
+}
+/* 模块 */
+
+/* 底部 */
+.dress-up-footer{
+  padding: 0 15px;
+  height: 70px;
+  background-color: rgba(246, 246, 246, 0.1);
+}
+.dress-up-title,.dress-up-introduce{
+  font-size: 16px;
+  line-height: 20px;
+}
+
+.dress-up-introduce{
+  margin-top: 6px;
+  color: #FFB239;
+}
+.dress-up-avatar{
+  @include square(80px);
+}
+.dress-up-use-button{
+  width: 60px;
+  height: 26px;
+  background: $main-linear;
+  font-size: 12px;
+  line-height: 14px;
+  border-radius: 13px;
+  margin-top: 5px;
+  font-weight: 400;
+}
+/* 底部 */

+ 14 - 0
src/popup/popup-personal/components/my-dress-up/components/dress-up-tab/data/tab.ts

@@ -0,0 +1,14 @@
+import DressHaveType from "$popup/popup-personal/components/my-dress-up/const/have";
+
+export default [
+    {
+        label:'全部',
+        slot:'0',
+        have:DressHaveType.all
+    },
+    {
+        label: '已拥有',
+        slot:'1',
+        have:DressHaveType.user
+    }
+];

+ 3 - 0
src/popup/popup-personal/components/my-dress-up/components/dress-up-tab/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 8 - 0
src/popup/popup-personal/components/my-dress-up/components/dress-up-tab/props.ts

@@ -0,0 +1,8 @@
+export default {
+
+    type:{
+        type:[String,Number],
+        default:''
+    }
+
+}

+ 61 - 0
src/popup/popup-personal/components/my-dress-up/components/dress-up-tab/src/main.vue

@@ -0,0 +1,61 @@
+<template>
+  <section class="dress-up-tab-container screen">
+    <tab
+        :data="tabData"
+    >
+      <template v-slot:header="{data,select,trigger}">
+        <header class="rowACenter dress-up-tab-header">
+          <aside
+              v-for="(item,index) in data"
+              :key="'view-tab-'+index"
+              class="dress-up-tab-item-button  center"
+              :class="{
+                'dress-up-item-active': index === select,
+                'cursor-pointer': index !== select
+             }"
+              @click="trigger(index)"
+          >{{item.label}}</aside>
+
+        </header>
+      </template>
+
+      <template
+          v-for="(item,index) in tabData"
+          v-slot:[item.slot]
+      >
+        <dress-up-list
+          :key="'dress-up-list-'+index"
+          :type="type"
+          :have="item.have"
+        ></dress-up-list>
+      </template>
+    </tab>
+  </section>
+
+</template>
+
+<script>
+import {
+  tab
+} from '$components';
+import tabData from '../data/tab';
+import dressUpList from '../../dress-up-list';
+import props from '../props';
+export default {
+  name: "dress-up-tab",
+
+  data(){
+    return {
+      tabData
+    }
+  },
+
+  components:{
+    tab,
+    dressUpList
+  },
+  props
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 28 - 0
src/popup/popup-personal/components/my-dress-up/components/dress-up-tab/style.scss

@@ -0,0 +1,28 @@
+/* 容器 */
+.dress-up-tab-container{
+  padding: 20px;
+}
+/* 容器 */
+
+/* tab头部 */
+.dress-up-tab-header{
+  margin-bottom: 10px;
+}
+.dress-up-tab-item-button{
+  width: 86px;
+  margin-left: 10px;
+  padding: 0 10px;
+  height: 26px;
+  border-radius: 13px;
+  background-color: rgba(255,255,255,0.1);
+  font-size: 14px;
+  line-height: 18px;
+  color: #fff;
+}
+.dress-up-tab-item-button:first-child{
+  margin-left: 0;
+}
+.dress-up-item-active{
+  background: $main-linear;
+}
+/* tab头部 */

+ 9 - 0
src/popup/popup-personal/components/my-dress-up/const/have.ts

@@ -0,0 +1,9 @@
+enum DressHaveType {
+
+    all='1',
+
+    user='2'
+
+}
+
+export default DressHaveType;

+ 14 - 0
src/popup/popup-personal/components/my-dress-up/const/type.ts

@@ -0,0 +1,14 @@
+enum DressUpType {
+
+    // 头像框
+    avatar='1',
+
+    // 气泡
+    bubble='2',
+
+    // 坐骑
+    mount='3'
+
+}
+
+export default DressUpType;

+ 19 - 0
src/popup/popup-personal/components/my-dress-up/data/tab.ts

@@ -0,0 +1,19 @@
+import DressUpType from "../const/type";
+
+export default [
+    {
+        label:'头像框',
+        slot:'1',
+        type:DressUpType.avatar
+    },
+    {
+        label:'气泡',
+        slot:'2',
+        type:DressUpType.bubble
+    },
+    {
+        label:'坐骑',
+        slot:'3',
+        type:DressUpType.mount
+    }
+]

+ 3 - 0
src/popup/popup-personal/components/my-dress-up/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 3 - 0
src/popup/popup-personal/components/my-dress-up/mixins/index.ts

@@ -0,0 +1,3 @@
+import order from '$mixins/order/index';
+
+export default [order];

+ 10 - 0
src/popup/popup-personal/components/my-dress-up/props.ts

@@ -0,0 +1,10 @@
+import {OrderStatus} from "$utils/control/order/const/order";
+
+export default {
+
+    orderStatus:{
+        type: [Number,String],
+        default: OrderStatus.placeOrder
+    }
+
+}

+ 66 - 0
src/popup/popup-personal/components/my-dress-up/src/main.vue

@@ -0,0 +1,66 @@
+<template>
+  <section class="screen dress-up-container">
+    <tab
+        :data="tabData"
+    >
+      <template v-slot:header="{data,trigger,select}" >
+        <header class="dress-up-item-header relative rowACenter">
+          <aside
+              v-for="(item,index) in data"
+              :key="'my-order-'+index"
+              class="order-item-aside center flex-1"
+              :class="{
+              'my-order-button-select': index === select,
+              'cursor-pointer': index !== select
+            }"
+              @click="trigger(index)"
+          >{{item.label}}</aside>
+          <aside class="absolute center dress-up-item-line"
+                 :style="{
+            width: 100 / data.length  +'%',
+            left: (100 / data.length * select)+'%'
+          }"
+          >
+            <div></div>
+          </aside>
+        </header>
+      </template>
+
+      <template
+        v-for="(item,index) in tabData"
+        v-slot:[item.slot]
+      >
+        <dress-up-tab
+          :key="'dress-up-tab-'+index"
+          v-bind="item"
+        ></dress-up-tab>
+      </template>
+    </tab>
+  </section>
+</template>
+
+<script>
+import {
+  tab
+} from '$components';
+import tabData from "../data/tab";
+import mixins from '../mixins';
+import props from '../props';
+import dressUpTab from '../components/dress-up-tab';
+export default {
+  name: "my-dress-up",
+  data(){
+    return {
+      tabData
+    }
+  },
+  components:{
+    tab,
+    dressUpTab
+  },
+  props,
+  mixins
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 27 - 0
src/popup/popup-personal/components/my-dress-up/style.scss

@@ -0,0 +1,27 @@
+/* 容器 */
+.dress-up-container{
+  background-color: rgba(255,255,255,0.1);
+  border-radius: 10px;
+}
+/* 容器 */
+/* 装扮 tab */
+.dress-up-item-header {
+  background: rgba(85, 154, 223, 0.1);
+  height: 44px;
+  padding-bottom: 6px;
+}
+.dress-up-item-header aside{
+  font-size: 16px;
+}
+.dress-up-item-header .dress-up-item-line{
+  left: 0;
+  bottom: 8px;
+  transition: .3s;
+}
+.dress-up-item-header .dress-up-item-line div{
+  width: 40px;
+  height: 6px;
+  background: $main-linear;
+  border-radius: 3px;
+}
+/* 装扮 tab */

+ 3 - 0
src/popup/popup-personal/components/my-follow/components/follow-room/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 37 - 0
src/popup/popup-personal/components/my-follow/components/follow-room/mixins/handle.ts

@@ -0,0 +1,37 @@
+import socket from '$utils/socket';
+import {NoticeType} from "$utils/socket/const";
+
+import personalDetail from '$utils/control/personal-detail';
+
+import roomList from '$utils/control/roomList';
+
+export default <LibMixins>{
+
+    methods:{
+
+        fetch(obj){
+          return roomList.getFollowRoomList(obj.data).then(function (data){
+              return obj.success(data.data);
+          }).catch(obj.fail);
+        },
+
+        openUserDetail(item){
+            return personalDetail.openDetail({
+                uid: item.uid
+            });
+        }
+
+    },
+
+    created(){
+        roomList.on('view-room',{
+            vm:this
+        });
+    },
+    beforeUnmount() {
+        roomList.on('view-room',{
+            vm:this
+        });
+    }
+
+}

+ 3 - 0
src/popup/popup-personal/components/my-follow/components/follow-room/mixins/index.ts

@@ -0,0 +1,3 @@
+import handle from './handle';
+
+export default [handle];

+ 45 - 0
src/popup/popup-personal/components/my-follow/components/follow-room/src/main.vue

@@ -0,0 +1,45 @@
+<template>
+  <section class="screen follow-room-container">
+
+    <flat-list
+      @fetch="fetch"
+      :security-size="20"
+      :pageSize="12"
+      indexes="rid"
+      ref="flat"
+      emptyText="暂无关注列表"
+    >
+      <template v-slot:item="{item,index}">
+        <layout-talking
+            :item="item"
+            :key="'layout-talking-'+item.rid"
+            type="user"
+            :index="index"
+            :nth="4"
+        ></layout-talking>
+      </template>
+    </flat-list>
+  </section>
+</template>
+
+<script>
+import {
+  FlatList,
+  vImage,
+  vButton
+} from '$components';
+import layoutTalking from '$layout/layout-talking';
+import mixins from '../mixins';
+export default {
+  name: "follow-room",
+  components:{
+    vButton,
+    FlatList,
+    vImage,
+    layoutTalking
+  },
+  mixins
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 3 - 0
src/popup/popup-personal/components/my-follow/components/follow-room/style.scss

@@ -0,0 +1,3 @@
+.follow-room-container{
+  padding: 10px 20px;
+}

+ 1 - 0
src/popup/popup-personal/components/my-follow/components/index.ts

@@ -1,2 +1,3 @@
 export { default as followUser } from './follow-user';
 
+export { default as followRoom } from './follow-room';

+ 4 - 4
src/popup/popup-personal/components/my-follow/data/tab.ts

@@ -1,8 +1,8 @@
 export default [
-    // {
-    //     label:'关注的房间',
-    //     slot:'follow-user'
-    // },
+    {
+        label:'关注的房间',
+        slot:'follow-room'
+    },
     {
         label:'关注的主播',
         slot:'follow-user'

+ 2 - 1
src/popup/popup-personal/data/menu.ts

@@ -21,7 +21,8 @@ export default [
     },
     {
         label:'个性装扮',
-        icon:require('../images/dress.png')
+        icon:require('../images/dress.png'),
+        component:'myDressUp'
     },
     {
         label:'我的关注',

+ 1 - 1
src/popup/popup-personal/props.ts

@@ -8,7 +8,7 @@ export default {
     // 默认选中的
     page:{
         type: String,
-        default:'myGift'
+        default:'myDressUp'
     }
 
 }

+ 12 - 0
src/popup/popup-ranking/components/ranking-list/data/ranking.ts

@@ -0,0 +1,12 @@
+export default [
+    {
+        icon: require('../images/ranking/1.png')
+    },
+    {
+        icon: require('../images/ranking/2.png')
+    },
+    {
+        icon: require('../images/ranking/3.png'),
+        line:true
+    }
+]

BIN
src/popup/popup-ranking/components/ranking-list/images/ranking/1.png


BIN
src/popup/popup-ranking/components/ranking-list/images/ranking/2.png


BIN
src/popup/popup-ranking/components/ranking-list/images/ranking/3.png


+ 3 - 0
src/popup/popup-ranking/components/ranking-list/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 3 - 0
src/popup/popup-ranking/components/ranking-list/props.ts

@@ -0,0 +1,3 @@
+export default {
+
+}

+ 64 - 0
src/popup/popup-ranking/components/ranking-list/src/main.vue

@@ -0,0 +1,64 @@
+<template>
+  <section class="screen ranking-list-container">
+
+    <template
+        v-for="(item,index) in 6"
+        :key="'ranking-item-'+item"
+    >
+      <aside class="ranking-list-item rowACenter"
+
+             :class="{
+        'ranking-item-front': rankingData[index]
+      }"
+      >
+        <div class="ranking-list-number-wrap">
+          <img v-if="rankingData[index]" :src="rankingData[index].icon" class="ranking-list-number-icon" />
+          <div v-else class="ranking-list-number center">{{item}}</div>
+        </div>
+
+        <v-image class="ranking-list-avatar" radius="50%"></v-image>
+
+        <div class="flex-1 ranking-list-content">
+          <header class="rowACenter">
+            <div class="ranking-list-username line-1">甜甜的密码</div>
+            <layout-sex></layout-sex>
+          </header>
+          <div class="ranking-list-id">ID:10087</div>
+        </div>
+
+        <article class="center">
+          <div class="ranking-list-value">25.8w</div>
+          <div class="ranking-list-introduce">财富值</div>
+        </article>
+
+      </aside>
+      <div v-if="rankingData[index] && rankingData[index].line" class="ranking-item-line"></div>
+    </template>
+
+
+  </section>
+</template>
+
+<script>
+import {
+  vImage
+} from '$components';
+import props from '../props';
+import rankingData from '../data/ranking';
+import layoutSex from '$layout/layout-sex';
+export default {
+  name: "ranking-tab",
+  data(){
+    return {
+      rankingData
+    }
+  },
+  props,
+  components:{
+    vImage,
+    layoutSex
+  }
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 56 - 0
src/popup/popup-ranking/components/ranking-list/style.scss

@@ -0,0 +1,56 @@
+/* 容器 */
+.ranking-list-container{
+  padding: 10px 0;
+}
+/* 容器 */
+/* 视图部分 */
+.ranking-list-item{
+  height: 60px;
+  padding: 0 30px;
+}
+.ranking-item-front{
+  height: 70px;
+}
+.ranking-item-line{
+  height: 1px;
+  margin: 0 30px 5px;
+  background-color: rgba(255,255,255,0.1);
+}
+.ranking-list-number-wrap{
+  width: 45px;
+  font-size: 14px;
+  line-height: 16px;
+}
+.ranking-list-number,.ranking-list-number-icon{
+  width: 27px;
+}
+.ranking-list-number-icon{
+  height: 34px;
+}
+/* 视图部分 */
+
+/* 头像 */
+.ranking-list-avatar{
+  @include square(40px);
+  margin-right: 8px;
+}
+/* 头像 */
+
+/* 内容信息部分 */
+.ranking-list-content,.ranking-list-value{
+  font-size: 14px;
+  line-height: 18px;
+}
+.ranking-list-username{
+  margin-right: 3px;
+  width: auto !important;
+  max-width: 50%;
+}
+.ranking-list-id,.ranking-list-introduce{
+  font-size: 12px;
+  line-height: 16px;
+  color: rgba(255,255,255,0.5);
+  margin-top: 5px;
+}
+/* 内容信息部分 */
+

+ 14 - 0
src/popup/popup-ranking/components/ranking-tab/data/tab.ts

@@ -0,0 +1,14 @@
+export default [
+    {
+        label:'日榜',
+        slot:'0'
+    },
+    {
+        label: '周榜',
+        slot:'1'
+    },
+    {
+        label: '总榜',
+        slot:'2'
+    }
+]

+ 3 - 0
src/popup/popup-ranking/components/ranking-tab/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 3 - 0
src/popup/popup-ranking/components/ranking-tab/props.ts

@@ -0,0 +1,3 @@
+export default {
+
+}

+ 64 - 0
src/popup/popup-ranking/components/ranking-tab/src/main.vue

@@ -0,0 +1,64 @@
+<template>
+  <tab
+    :data="tabData"
+  >
+    <template v-slot:header="{data,select,trigger}">
+      <div class="center">
+        <header class="use-ranking-tab row relative">
+          <aside
+              v-for="(item,index) in data"
+              :key="'ranking-tab-'+index"
+              class="center relative"
+              :class="{
+                'use-ranking-tab-active': index === select,
+                'cursor-pointer': index !== select
+             }"
+              @click="trigger(index)"
+          >{{item.label}}</aside>
+          <div class="use-ranking-tab-line absolute"
+            :style="{width:avgWidth+'%',left: select * avgWidth+'%'}"
+          ></div>
+        </header>
+      </div>
+
+    </template>
+
+    <template
+      v-for="(item,index) in tabData"
+      v-slot:[item.slot]
+    >
+      <ranking-list
+        :key="'use-ranking-tab-'+index"
+      ></ranking-list>
+    </template>
+  </tab>
+</template>
+
+<script>
+import {
+  tab,
+} from '$components';
+import props from '../props';
+import tabData from '../data/tab';
+import rankingList from '../../ranking-list';
+export default {
+  name: "ranking-tab",
+  data(){
+    return {
+      tabData
+    }
+  },
+  computed:{
+    avgWidth(){
+      return 100/this.tabData.length;
+    }
+  },
+  props,
+  components:{
+    tab,
+    rankingList
+  }
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 29 - 0
src/popup/popup-ranking/components/ranking-tab/style.scss

@@ -0,0 +1,29 @@
+/* 头部 */
+.use-ranking-tab{
+  background-color: rgba(255,255,255,0.1);
+  border-radius: 13px;
+  height: 25px;
+  margin-top: 6px;
+}
+.use-ranking-tab aside{
+  width: 60px;
+  height: 100%;
+  font-size: 14px;
+  line-height: 16px;
+  color: rgba(255,255,255,0.5);
+  z-index: 2;
+}
+.use-ranking-tab aside,.use-ranking-tab-line{
+  transition: .3s;
+}
+.use-ranking-tab aside.use-ranking-tab-active{
+  color: #fff;
+}
+.use-ranking-tab-line{
+  top: 0;
+  bottom: 0;
+  background: $main-linear;
+  border-radius: 13px;
+  z-index: 1;
+}
+/* 头部 */

+ 14 - 0
src/popup/popup-ranking/data/tab.ts

@@ -0,0 +1,14 @@
+export default [
+    {
+        label:'财富榜',
+        slot:'0'
+    },
+    {
+        label: '魅力榜',
+        slot:'1'
+    },
+    {
+        label: '等级榜',
+        slot:'2'
+    }
+]

+ 3 - 0
src/popup/popup-ranking/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 16 - 0
src/popup/popup-ranking/mixins/handle.ts

@@ -0,0 +1,16 @@
+import tabData from '../data/tab';
+export default <LibMixins>{
+
+    data(){
+        return {
+            tabData
+        }
+    },
+
+    computed:{
+        avgWidth(){
+            return 100/this.tabData.length;
+        }
+    }
+
+}

+ 4 - 0
src/popup/popup-ranking/mixins/index.ts

@@ -0,0 +1,4 @@
+import handle from './handle';
+import popup from "$mixins/popup";
+
+export default [handle,popup];

+ 5 - 0
src/popup/popup-ranking/props.ts

@@ -0,0 +1,5 @@
+export default {
+
+
+
+}

+ 81 - 0
src/popup/popup-ranking/src/main.vue

@@ -0,0 +1,81 @@
+<template>
+  <popup v-model:value="value" content-animate="scale" @close="$emit('destroy-popup')">
+    <section class="popup-ranking-container flex relative">
+      <div @click="close" class="ranking-close-wrap cursor-pointer absolute animate-rotate-hover">
+        <icon type="close" class="ranking-close"></icon>
+      </div>
+      <!--  头部   -->
+      <header class="popup-ranking-header"></header>
+      <!--  标题   -->
+      <div class="popup-ranking-title">排行榜</div>
+      <!--  剩余的tab   -->
+      <section class="flex-1">
+        <tab
+          :data="tabData"
+        >
+          <template v-slot:header="{data,select,trigger}">
+            <article class="ranking-tab-padding">
+              <header class="ranking-tab-header rowACenter relative">
+                <aside
+                    class="flex-1 center"
+                    v-for="(item,index) in data"
+                    :key="'ranking-tab-'+index"
+                    :class="{
+                      'ranking-tab-active': index === select
+                    }"
+                >
+                  <span
+                    :class="{
+                    'cursor-pointer': index !== select
+                    }"
+                    @click="trigger(index)"
+                  >{{item.label}}</span>
+                </aside>
+                <div class="absolute tanking-tab-line center"
+                  :style="{width:avgWidth+'%',left:select * avgWidth+'%'}"
+                >
+                  <div></div>
+                </div>
+              </header>
+            </article>
+
+          </template>
+
+          <template
+            v-for="(item,index) in tabData"
+            v-slot:[item.slot]
+          >
+            <ranking-tab
+              :key="'tanking-tab-'+index"
+            ></ranking-tab>
+          </template>
+
+        </tab>
+      </section>
+    </section>
+  </popup>
+</template>
+
+<script>
+import {
+  Popup,
+  icon,
+  tab
+} from '$components';
+import mixins from '../mixins';
+import props from '../props';
+import rankingTab from '../components/ranking-tab';
+export default {
+  name: "popup-ranking",
+  components:{
+    Popup,
+    icon,
+    tab,
+    rankingTab
+  },
+  mixins,
+  props
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

Vissa filer visades inte eftersom för många filer har ändrats