Browse Source

no message

laosan2382995021@163.com 4 years ago
parent
commit
d7246af840
86 changed files with 2428 additions and 22 deletions
  1. 1 1
      public/font/font.css
  2. 1 0
      src/App.vue
  3. BIN
      src/assets/images/popup-header.png
  4. 1 1
      src/components/flat-list/src/main.vue
  5. 3 1
      src/components/index.ts
  6. 1 1
      src/components/popup/src/main.vue
  7. 1 0
      src/components/popup/style.scss
  8. 1 1
      src/components/sound-recording/mixins/audio.ts
  9. 3 0
      src/components/stepper/index.ts
  10. 23 0
      src/components/stepper/props.ts
  11. 75 0
      src/components/stepper/src/main.vue
  12. 39 0
      src/components/stepper/style.scss
  13. 5 0
      src/components/swiper/props.ts
  14. 39 1
      src/components/swiper/src/main.vue
  15. 18 0
      src/components/tab/mixins/handle.ts
  16. 12 0
      src/components/tab/props.ts
  17. 4 2
      src/components/tab/src/main.vue
  18. 6 0
      src/components/tab/style.scss
  19. 1 0
      src/components/v-image/mixins/status.ts
  20. 83 0
      src/layout/layout-play/mixins/handle.ts
  21. 1 0
      src/layout/layout-play/src/main.vue
  22. 29 0
      src/mixins/pay/data/payData.ts
  23. BIN
      src/mixins/pay/images/alipay.png
  24. BIN
      src/mixins/pay/images/weChat.png
  25. 62 0
      src/mixins/pay/index.ts
  26. 1 1
      src/popup/popup-choosing/mixins/handle.ts
  27. 1 1
      src/popup/popup-confirm/src/main.vue
  28. 3 0
      src/popup/popup-detail/components/game/components/skill/index.ts
  29. 8 0
      src/popup/popup-detail/components/game/components/skill/props.ts
  30. 25 0
      src/popup/popup-detail/components/game/components/skill/src/main.vue
  31. 16 0
      src/popup/popup-detail/components/game/components/skill/style.scss
  32. 52 0
      src/popup/popup-detail/components/game/data/button.ts
  33. 14 0
      src/popup/popup-detail/components/game/data/describe.ts
  34. 11 0
      src/popup/popup-detail/components/game/data/option.ts
  35. 15 0
      src/popup/popup-detail/components/game/data/tab.ts
  36. 22 0
      src/popup/popup-detail/components/game/data/transaction.ts
  37. BIN
      src/popup/popup-detail/components/game/images/chat.png
  38. BIN
      src/popup/popup-detail/components/game/images/comment.png
  39. BIN
      src/popup/popup-detail/components/game/images/confirm.png
  40. BIN
      src/popup/popup-detail/components/game/images/pay.png
  41. BIN
      src/popup/popup-detail/components/game/images/service.png
  42. 3 0
      src/popup/popup-detail/components/game/index.ts
  43. 118 0
      src/popup/popup-detail/components/game/mixins/handle.ts
  44. 4 0
      src/popup/popup-detail/components/game/mixins/index.ts
  45. 13 0
      src/popup/popup-detail/components/game/props.ts
  46. 168 0
      src/popup/popup-detail/components/game/src/main.vue
  47. 209 0
      src/popup/popup-detail/components/game/style.scss
  48. 10 0
      src/popup/popup-detail/data/game.ts
  49. 10 0
      src/popup/popup-detail/data/tab.ts
  50. BIN
      src/popup/popup-detail/images/bakcground.png
  51. BIN
      src/popup/popup-detail/images/gift.png
  52. BIN
      src/popup/popup-detail/images/vip.png
  53. 3 0
      src/popup/popup-detail/index.ts
  54. 62 0
      src/popup/popup-detail/mixins/handle.ts
  55. 5 0
      src/popup/popup-detail/mixins/index.ts
  56. 8 0
      src/popup/popup-detail/props.ts
  57. 204 0
      src/popup/popup-detail/src/main.vue
  58. 196 0
      src/popup/popup-detail/style.scss
  59. 4 2
      src/popup/popup-export/components.ts
  60. 11 2
      src/popup/popup-export/const/index.ts
  61. 1 1
      src/popup/popup-export/global.ts
  62. 1 1
      src/popup/popup-loading/src/main.vue
  63. 14 0
      src/popup/popup-order/global.scss
  64. 3 0
      src/popup/popup-order/index.ts
  65. 81 0
      src/popup/popup-order/mixins/handle.ts
  66. 5 0
      src/popup/popup-order/mixins/index.ts
  67. 9 0
      src/popup/popup-order/props.ts
  68. 120 0
      src/popup/popup-order/src/main.vue
  69. 180 0
      src/popup/popup-order/style.scss
  70. 28 0
      src/popup/popup-recharge/global.scss
  71. 3 0
      src/popup/popup-recharge/index.ts
  72. 39 0
      src/popup/popup-recharge/mixins/handle.ts
  73. 5 0
      src/popup/popup-recharge/mixins/index.ts
  74. 90 0
      src/popup/popup-recharge/src/main.vue
  75. 118 0
      src/popup/popup-recharge/style.scss
  76. 1 1
      src/popup/popup-toast/style.scss
  77. 3 1
      src/store/modules/index.ts
  78. 74 0
      src/store/modules/pay.ts
  79. 11 1
      src/store/modules/user.ts
  80. 6 0
      src/utils/request/cache/cache.ts
  81. 6 1
      src/utils/request/cache/index.ts
  82. 2 0
      src/utils/request/types/lib.request.d.ts
  83. 17 0
      src/utils/tool/money.ts
  84. 5 0
      src/utils/unit/unit.ts
  85. 1 1
      src/views/view-header/src/main.vue
  86. 0 1
      src/views/view-play-with/mixins/handle.ts

+ 1 - 1
public/font/font.css

@@ -22,7 +22,7 @@
   content: "\e6b0";
 }
 
-.icon-jian:before {
+.icon-reduce:before {
   content: "\e621";
 }
 

+ 1 - 0
src/App.vue

@@ -13,6 +13,7 @@ export default {
 
   created() {
     this.$store.dispatch('initializationUserPromise');
+    this.$store.dispatch('initializationPayPromise');
   }
 
 }

BIN
src/assets/images/popup-header.png


+ 1 - 1
src/components/flat-list/src/main.vue

@@ -20,7 +20,7 @@
       @scroll-lower="pagingLoading"
       :lowerThreshold="lowerThreshold"
     >
-      <slot name="slot" :data="data">
+      <slot name="layout" :data="data">
 
         <div class="row wrap">
           <slot

+ 3 - 1
src/components/index.ts

@@ -20,4 +20,6 @@ export { default as vUpload } from './upload';
 
 export { default as soundRecording } from './sound-recording';
 
-export { default as FlatList } from './flat-list';
+export { default as FlatList } from './flat-list';
+
+export { default as  stepper} from './stepper';

+ 1 - 1
src/components/popup/src/main.vue

@@ -1,5 +1,5 @@
 <template>
-  <section v-show="vValue" class="absolute popup-screen center"
+  <section v-show="vValue" class="popup-screen center"
            @click="trigger && changeValue"
            :class="{'center':center}"
   >

+ 1 - 0
src/components/popup/style.scss

@@ -4,6 +4,7 @@
   bottom: 0;
   left: 0;
   right: 0;
+  position: fixed;
   z-index: 999;
   background-color: rgba(0,0,0,0.3);
 }

+ 1 - 1
src/components/sound-recording/mixins/audio.ts

@@ -69,7 +69,7 @@ export default <LibMixins>{
                     this.setAudioStatus(AudioStatus.fail);
                 })
                 .addListener(TriggerAudioListener.speed, ({currDuration,duration})=>{
-                    let useDuration = duration - currDuration -1;
+                    let useDuration = duration - currDuration;
 
                     this.audioCurrentDuration = useDuration < 0 ? 0 : useDuration;
                 })

+ 3 - 0
src/components/stepper/index.ts

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

+ 23 - 0
src/components/stepper/props.ts

@@ -0,0 +1,23 @@
+export default {
+
+    min:{
+        type:Number,
+        default:1
+    },
+
+    max:{
+        type:Number,
+        default:999
+    },
+
+    value:{
+        type:Number,
+        default:1
+    },
+
+    type:{
+        type:String,
+        default:''
+    }
+
+}

+ 75 - 0
src/components/stepper/src/main.vue

@@ -0,0 +1,75 @@
+<template>
+  <div class="row stepper overflow"
+    :class="['steeper-'+type]"
+  >
+    <aside class="center stepper-control"
+      :class="{
+        'cursor-pointer': vValue > min
+      }"
+           @click="trigger(false)"
+    >
+      <icon type="reduce" class="stepper-control-icon stepper-control-reduce-icon"></icon>
+    </aside>
+    <aside class="flex-1 overflow stepper-content">{{vValue}}</aside>
+    <aside class="center stepper-control"
+      :class="{
+        'cursor-pointer': vValue < max
+      }"
+           @click="trigger(true)"
+    >
+      <icon type="add" class="stepper-control-icon stepper-control-add-icon"></icon>
+    </aside>
+  </div>
+</template>
+
+<script>
+import props from '../props';
+import icon from '$components/icon';
+export default {
+  name: "stepper",
+
+  data(){
+    return {
+      vValue:0
+    }
+  },
+
+  watch:{
+    value:{
+      handler:function (){
+        this.setValue(this.value);
+      },
+      immediate:true
+    }
+  },
+
+  methods:{
+
+    setValue(value){
+
+      value = value <= this.min ? this.min : value;
+
+      value = value >= this.max ? this.max : value;
+
+      if (this.vValue !== value) {
+        this.vValue = value;
+        if (this.value !== value) {
+          return this.$emit('update:value',value);
+        }
+      }
+    },
+
+    trigger(status){
+      return this.setValue(this.vValue + (status ? 1 : -1));
+    }
+
+  },
+  props,
+  components:{
+    icon
+  }
+
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 39 - 0
src/components/stepper/style.scss

@@ -0,0 +1,39 @@
+/* 步进器 */
+.stepper{
+  width: 90px;
+  height: 26px;
+  border: 1px solid #999;
+  border-radius: 5px;
+}
+.stepper-content{
+  border-left: 1px solid #999;
+  border-right: 1px solid #999;
+  height: 26px;
+  text-align: center;
+  font-size: 14px;
+  color: #999;
+}
+.stepper-control{
+  width: 24px;
+  height: 100%;
+}
+.stepper-control-reduce-icon{
+  font-weight: bold;
+  font-size: 12px;
+}
+.stepper-control-add-icon{
+  transform: scale(0.7);
+}
+/* 步进器 */
+
+/* 订单类型的 */
+.steeper-order{
+  width: 110px;
+}
+.steeper-order,.steeper-order .stepper-content{
+  border-color: #fff;
+}
+.steeper-order .stepper-content{
+  color: #fff;
+}
+/* 订单类型的 */

+ 5 - 0
src/components/swiper/props.ts

@@ -2,6 +2,11 @@ export default {
 
     swiperOption:{
         type:Object
+    },
+
+    value:{
+        type: [Number,String],
+        default: 0
     }
 
 }

+ 39 - 1
src/components/swiper/src/main.vue

@@ -12,13 +12,51 @@ import props from '../props';
 import Swiper from 'swiper';
 export default {
   name: "swiper",
+  emits:['change'],
+
+  watch:{
+    value:function () {
+
+      if (this.swiper && this.value !== this.swiper.realIndex) {
+        return this.slideTo(this.value);
+      }
+
+    }
+  },
+
   methods:{
     installSwiper(){
       if (this.$refs.swiper) {
-        return new Swiper(this.$refs.swiper,this.swiperOption || this.$attrs);
+
+        let options = {
+          initialSlide: this.value || 0,
+          ...(this.swiperOption || this.$attrs),
+          on:{
+            slideChange: ()=> this.change()
+          }
+        };
+
+        return new Swiper(this.$refs.swiper,options);
       } else {
         return  undefined;
       }
+    },
+    next(){
+      return this.swiper && this.swiper.slideNext();
+    },
+    prev(){
+      return this.swiper && this.swiper.slidePrev();
+    },
+    slideTo(index,speed) {
+      return this.swiper && this.swiper.slideTo(index,speed);
+    },
+    change(){
+
+      let index = this.swiper.realIndex;
+      if (index !== this.value) {
+        this.swiper && this.$emit('update:value',index);
+        return this.swiper && this.$emit('change',index);
+      }
     }
   },
   mounted() {

+ 18 - 0
src/components/tab/mixins/handle.ts

@@ -1,3 +1,4 @@
+import { nextTick } from 'vue';
 export default <LibMixins>{
 
     data(){
@@ -96,7 +97,22 @@ export default <LibMixins>{
             if (this.vUseTabSelect !== index) {
                 this.vTabSelect = index;
             }
+        },
+
+        updateAutoHeight(){
+            if (this.autoHeight) {
+
+                nextTick(()=> {
+                    this.swiper && this.swiper.updateAutoHeight();
+                })
+
+            }
         }
+    },
+
+    mounted() {
+
+        this.updateAutoHeight();
 
     },
 
@@ -106,6 +122,8 @@ export default <LibMixins>{
             initialSlide: this.vTabSelect,
             allowTouchMove: this.touchMove,
             speed: this.speed,
+            autoHeight: this.autoHeight,
+            resizeObserver: this.autoHeight,
             on:{
                 slideChangeTransitionStart: (swiper: any)=>{
                     // 设置执行下标

+ 12 - 0
src/components/tab/props.ts

@@ -35,6 +35,18 @@ export default {
     speed:{
         type: Number,
         default:300
+    },
+
+    // 自动设置高度
+    autoHeight:{
+        type:Boolean,
+        default: false
+    },
+
+    // 自定义设置高度但是需要保持 auto
+    autoHeightFixed:{
+        type: Boolean,
+        default: false
     }
 
 }

+ 4 - 2
src/components/tab/src/main.vue

@@ -2,7 +2,7 @@
   <section class="tab-container flex">
 
     <!--   头部组件   -->
-    <slot name="header" :data="vTabData" :trigger="triggerTo">
+    <slot name="header" :data="vTabData" :trigger="triggerTo" :select="vTabSelect">
       <header class="rowACenter tab-header">
         <slot
           name="header-item"
@@ -25,7 +25,9 @@
       </header>
     </slot>
     <!--   内容组件   -->
-    <article class="flex-1 overflow">
+    <article class="overflow"
+      :class="{'flex-1': !autoHeight && !autoHeightFixed,'auto-height-fixed':autoHeightFixed}"
+    >
       <swiper v-if="swipeOption" ref="swiper" :swiperOption="swipeOption">
         <swiper-item
           v-for="item in vTabData"

+ 6 - 0
src/components/tab/style.scss

@@ -33,4 +33,10 @@
   height: 13px;
   border-radius: 7px;
 }
+.auto-height-fixed{
+  width: 100% !important;
+  height: auto !important;
+  max-height: 100% !important;
+  overflow: hidden;
+}
 /* 头部样式 */

+ 1 - 0
src/components/v-image/mixins/status.ts

@@ -18,6 +18,7 @@ export default <LibMixins> {
                 this.status = status;
 
                 if (status === imageStatus.success){
+
                     this.$emit('success');
                 } else if (status === imageStatus.fail) {
                     this.$emit('fail');

+ 83 - 0
src/layout/layout-play/mixins/handle.ts

@@ -1,6 +1,8 @@
 import audio, {TriggerAudioListener,PlayStatus} from "$utils/tool/audio";
 
 import popup from "$utils/tool/popup";
+import {InstructionsCacheType} from "$utils/request";
+import {PopupExportComponent} from "$popup/popup-export/const";
 
 export default <LibMixins>{
 
@@ -73,6 +75,87 @@ export default <LibMixins>{
 
 
 
+        },
+
+        triggerDetail(){
+
+            this.clearTargetDetail();
+
+            this.detailTime = setTimeout(()=>{
+                popup.$loading('获取中');
+            },500);
+
+            Promise.all([this.getPlayInfo(),this.getPlayList()]).then(([info,playData])=>{
+                this.clearTargetDetail();
+
+                playData = playData.data.palyer_game_list || [];
+
+                playData = playData.map((item,index)=>{
+                    return {
+                        label: item.game_name,
+                        slot: 'tab-'+index,
+                        pid: item.pid,
+                        price: item.price
+                    }
+                });
+
+                info = info.data || {};
+
+                info.gameList = playData;
+
+                console.log(info);
+
+                // info
+                if (!info.images) {
+                    info.images = [this.item.cover_image];
+                } else {
+                    info.images = info.images.split(',');
+                }
+
+                popup.$popup.open(PopupExportComponent.detail,{
+                    option: info
+                });
+
+            }).catch(()=> this.clearTargetDetail('服务繁忙'));
+
+        },
+
+        clearTargetDetail(fail?:string){
+          clearTimeout(this.detailTime);
+          popup.hideLoading();
+
+          if (fail) {
+              popup.$toast(fail);
+          }
+
+        },
+
+        // 获取陪玩基本信息
+        getPlayInfo() {
+            return this.$request({
+                url:'hxuser/get_base_user_info',
+                data:{
+                    uid: this.item.uid
+                },
+                cache:{
+                    type: InstructionsCacheType.memory
+                },
+                token:true
+            });
+        },
+
+        // 获取陪玩下的游戏列表
+        getPlayList(){
+            return this.$request({
+                url:'player/get_player_game_lists',
+                data:{
+                    pid: this.item.pid
+                },
+                cache:{
+                    type: InstructionsCacheType.memory
+                },
+                token:true
+            })
         }
 
     },

+ 1 - 0
src/layout/layout-play/src/main.vue

@@ -4,6 +4,7 @@
       'play-item-clear-right': rowLast,
       'play-item-clear-top': row === 0
     }"
+       @click="triggerDetail"
   >
     <div class="play-item-image-wrap overflow">
       <v-image

+ 29 - 0
src/mixins/pay/data/payData.ts

@@ -0,0 +1,29 @@
+import popup from '$utils/tool/popup';
+
+export default {
+
+    weChat:{
+        label:'微信',
+        icon: require('../images/weChat.png')
+    },
+
+    alipay:{
+        label:'支付宝',
+        icon: require('../images/alipay.png')
+    },
+
+    balance:{
+        label:'钱包金币余额',
+        format:'balanceIntroduce',
+        check:function (vm,payMoney) {
+
+            if (vm.$store.getters.integral < payMoney) {
+                popup.$toast('余额不足');
+            }
+
+            return vm.$store.getters.integral >= payMoney;
+
+        }
+    }
+
+}

BIN
src/mixins/pay/images/alipay.png


BIN
src/mixins/pay/images/weChat.png


+ 62 - 0
src/mixins/pay/index.ts

@@ -0,0 +1,62 @@
+import payData from './data/payData';
+import Status from "$mixins/status/const/status";
+
+export default <LibMixins>{
+
+    data(){
+        return {
+            payData,
+            payCheck:0,
+            triggerPayName:'payOrderInfo',
+            payStatus: Status.none,
+            payOrder:['weChat','alipay','balance'],
+        }
+    },
+
+    computed:{
+        payFormat(){
+
+            return {
+                balanceIntroduce: this.$store.state.pay && this.$store.state.pay.payRatio ? '('+this.$store.state.pay.payRatio + '巧鱼币=1.00元)' : ''
+            }
+        },
+        payTotal(){
+            if (this.payOrder[this.payCheck] === 'balance' && this.$store.state.pay && this.$store.state.pay.payRatio) {
+                return  this.total * this.$store.state.pay.payRatio;
+            } else {
+                return this.total;
+            }
+        },
+        payTotalFormat(){
+            if (this.payOrder[this.payCheck] === 'balance' && this.$store.state.pay && this.$store.state.pay.payRatio) {
+                return  this.payTotal + '巧鱼币';
+            } else {
+                return '¥'+this.payTotal;
+            }
+        }
+    },
+
+    methods:{
+
+        triggerPayType(index:number){
+            if (this.payCheck !== index) {
+                this.payCheck = index;
+            }
+        },
+
+        triggerPayOrder(){
+
+            if (this.payStatus === Status.loading) return;
+
+            let item = this.payData[this.payOrder[this.payCheck]];
+            if (!item || item.check && !item.check(this,this.payTotal)) return ;
+
+            return this[this.triggerPayName] && this[this.triggerPayName]({
+                password:'123456'
+            });
+        },
+
+
+    }
+
+}

+ 1 - 1
src/popup/popup-choosing/mixins/handle.ts

@@ -27,7 +27,7 @@ export default <LibMixins>{
 
         getGame(item){
 
-            if (this.statusData[item.status] && this.statusData[item.status].disabeld) return ;
+            if (this.statusData[item.status] && this.statusData[item.status].disabled) return ;
 
             if (this.loadingSatus) return ;
             this.setLoadingStatus(true);

+ 1 - 1
src/popup/popup-confirm/src/main.vue

@@ -1,5 +1,5 @@
 <template>
-  <popup v-model:value="value" style="z-index: 99999" content-animate="scale" @close="$emit('destroy-popup')">
+  <popup v-model:value="value" style="z-index: 99991" content-animate="scale" @close="$emit('destroy-popup')">
 
     <div class="confirm-container relative">
 

+ 3 - 0
src/popup/popup-detail/components/game/components/skill/index.ts

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

+ 8 - 0
src/popup/popup-detail/components/game/components/skill/props.ts

@@ -0,0 +1,8 @@
+export default {
+
+    config:{
+        type:Object,
+        default:{}
+    }
+
+}

+ 25 - 0
src/popup/popup-detail/components/game/components/skill/src/main.vue

@@ -0,0 +1,25 @@
+<template>
+  <section class="skill-introduce">
+    <div>{{config.introduction}}</div>
+    <aside v-if="config.skill_image" class="skill-image-container overflow">
+      <v-image @success="updateAutoHeight" mode="widthFix" class="skill-image" :src="config.skill_image"></v-image>
+    </aside>
+  </section>
+</template>
+
+<script>
+import props from '../props';
+import {
+  vImage
+} from '$components';
+export default {
+  name: "skill",
+  components:{
+    vImage
+  },
+  inject:['updateAutoHeight'],
+  props
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 16 - 0
src/popup/popup-detail/components/game/components/skill/style.scss

@@ -0,0 +1,16 @@
+/* 介绍 */
+.skill-introduce{
+  padding-top:15px;
+  font-size: 16px;
+  line-height: 24px;
+  color: #333;
+  font-weight: bold;
+}
+.skill-image-container{
+  border-radius: 10px;
+  margin-top: 10px;
+}
+.skill-image{
+  width: 100%;
+}
+/* 介绍 */

+ 52 - 0
src/popup/popup-detail/components/game/data/button.ts

@@ -0,0 +1,52 @@
+import { FunctionTrigger } from '$mixins/trigger/class/index';
+
+import popup from "$utils/tool/popup";
+import {PopupExportComponent} from "$popup/popup-export/const";
+
+export default [
+    {
+        label:'聊一聊',
+        reverse:true
+    },
+    {
+        label: '立即下单',
+        trigger: new FunctionTrigger(function (){
+
+            let currentItem = {};
+            let options = {
+              number: this.number,
+              gameList: this.config.gameList.map((item)=>{
+
+                  let price = parseFloat(item.price);
+                  let intPrice = parseInt(item.price);
+
+                  if (intPrice === price) {
+                      price = intPrice;
+                  }
+
+                  let target = {
+                      label: item.label,
+                      value: item.pid,
+                      price: price,
+                      number: 1
+                  };
+                  if (item.pid === this.item.pid) {
+                      currentItem = target;
+                      target.number = this.number;
+                  }
+                  return target
+              }),
+              item:currentItem,
+              value: this.item.pid,
+              user: {
+                  header_pic: this.item.head_pic,
+                  nick_name: this.item.nick_name
+              }
+            };
+
+            return popup.$popup && popup.$popup.open(PopupExportComponent.order,{
+                option:options
+            });
+        })
+    }
+]

+ 14 - 0
src/popup/popup-detail/components/game/data/describe.ts

@@ -0,0 +1,14 @@
+export default [
+    {
+        label:'未开始随时退',
+        icon:'<path d="M224 864v-64h96v-184.448a64 64 0 0 1 30.848-54.72L448 512l-92.608-46.304A64 64 0 0 1 320 408.416L319.968 224H224V160h576v64h-96.032L704 408.448a64 64 0 0 1-35.392 57.248L576 512l92.64 46.304a64 64 0 0 1 35.2 52.096L704 800h96v64H224z m288-312.448l-128 64V800h256v-184.448l-128-64zM639.968 224h-256L384 408.448l128 64 128-64L639.968 224z" p-id="8653" fill="#999999"></path>'
+    },
+    {
+        label:'超时随时退',
+        icon:'<path d="M739.712 81.322667l196.565333 163.968-54.656 65.536-196.608-163.968 54.698667-65.536z m-455.424 0L338.986667 146.773333 142.378667 310.826667 87.722667 245.290667l196.565333-164.010667zM512 174.677333a384 384 0 1 0 0.042667 768.042667 384 384 0 0 0 0-768.042667z m0 682.666667c-164.693333 0-298.666667-133.973333-298.666667-298.666667s133.973333-298.666667 298.666667-298.666666 298.666667 133.973333 298.666667 298.666666-133.973333 298.666667-298.666667 298.666667zM469.333333 341.333333h85.333334v256h-85.333334V341.333333z m0 341.333334h85.333334v85.333333h-85.333334v-85.333333z" p-id="7294"></path>'
+    },
+    {
+        label:'不满意可退单',
+        icon:'<path d="M501.828 45.931c-244.753 0-442.64 197.885-442.64 442.64-0.65 244.099 197.885 442.635 442.64 442.635 244.754 0 442.64-198.535 442.64-442.635 0-244.753-198.537-442.64-442.64-442.64v0zM243.407 426.732c0-45.569 37.104-82.018 82.018-82.018 44.916 0 81.369 37.103 81.369 82.018 0 45.567-36.452 82.018-81.369 82.018-44.914 0-81.367-37.103-82.018-82.018v0zM677.583 718.348c-11.067 14.971-32.547 18.227-47.518 7.162-36.452-26.689-80.066-42.31-128.235-42.31-48.169 0-92.432 15.62-128.235 42.31-14.97 11.067-36.452 7.811-47.518-7.162-11.066-15.622-7.811-36.452 7.163-47.518 46.868-35.15 105.452-55.978 168.591-55.978 63.141 0 121.726 20.825 168.591 55.978 14.97 11.066 18.226 32.547 7.161 47.518v0zM677.583 508.75c-44.914 0-81.369-37.103-82.018-82.018 0-45.567 36.452-82.017 82.018-82.017 45.567 0 82.017 37.103 82.017 82.017 0 45.566-37.103 82.018-82.017 82.018v0z" p-id="7586"></path>'
+    }
+] as LibDataArray

+ 11 - 0
src/popup/popup-detail/components/game/data/option.ts

@@ -0,0 +1,11 @@
+export default [
+    {
+        label:'接单数量',
+        em:'次',
+        key: 'order_count'
+    },
+    {
+        label: '技能等级',
+        key:'game_level_name'
+    }
+]

+ 15 - 0
src/popup/popup-detail/components/game/data/tab.ts

@@ -0,0 +1,15 @@
+export default [
+    {
+        label:'技能介绍',
+        slot:'0',
+        component:'skill'
+    },
+    {
+        label: '用户评价',
+        slot:'1'
+    },
+    {
+        label: '礼物墙',
+        slot:'2'
+    }
+]

+ 22 - 0
src/popup/popup-detail/components/game/data/transaction.ts

@@ -0,0 +1,22 @@
+export default [
+    {
+        label:'找大神聊一聊',
+        icon:require('../images/chat.png')
+    },
+    {
+        label: '下单支付',
+        icon:require('../images/pay.png')
+    },
+    {
+        label: '确认接单',
+        icon:require('../images/confirm.png')
+    },
+    {
+        label: '确认服务',
+        icon:require('../images/service.png')
+    },
+    {
+        label: '评论',
+        icon:require('../images/comment.png')
+    }
+] as LibDataArray

BIN
src/popup/popup-detail/components/game/images/chat.png


BIN
src/popup/popup-detail/components/game/images/comment.png


BIN
src/popup/popup-detail/components/game/images/confirm.png


BIN
src/popup/popup-detail/components/game/images/pay.png


BIN
src/popup/popup-detail/components/game/images/service.png


+ 3 - 0
src/popup/popup-detail/components/game/index.ts

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

+ 118 - 0
src/popup/popup-detail/components/game/mixins/handle.ts

@@ -0,0 +1,118 @@
+import optionData from '../data/option';
+
+import buttonData from '../data/button';
+
+import transactionData from '../data/transaction';
+
+import describeData from "../data/describe";
+
+import tabData from '../data/tab';
+
+import audio, {PlayStatus, TriggerAudioListener} from "$utils/tool/audio";
+import popup from "$utils/tool/popup";
+
+export default <LibMixins>{
+
+    data(){
+      return {
+          item:{},
+          number:1,
+          optionData,
+          buttonData,
+          transactionData,
+          describeData,
+          PlayStatus,
+          tabData,
+          playStatus: PlayStatus.none,
+          duration:0
+      }
+    },
+
+    provide(){
+      return {
+          updateAutoHeight:()=> {
+              return this.$refs.tab && this.$refs.tab.updateAutoHeight();
+          }
+      }
+    },
+
+
+    methods:{
+
+        getDetail(obj){
+            return this.$request({
+                url:'player/get_player_info',
+                data:{
+                    pid: this.pid
+                },
+                token:true
+            }).then((data)=>{
+                data = data.data || {};
+
+                data.game_info.skill_level_list.map((item)=>{
+                    if (item.lid === data.lid) {
+                        data.game_level_name = item.game_level_name;
+                    }
+                });
+
+                this.item = data;
+
+                return  obj.success([1]);
+
+            }).catch(obj.fail);
+        },
+
+        setPlayStatus(status){
+            if (this._playStatus !== status) {
+                this._playStatus = status;
+                clearTimeout(this._playStatusTime);
+
+                if (status === PlayStatus.playBefore) {
+
+                    this._playStatusTime = setTimeout(()=>{
+                       this.playStatus = this._playStatus;
+                    },300);
+
+                } else {
+                    this.playStatus = status;
+                }
+
+            }
+        },
+
+        triggerPlay(){
+
+            if (this.playStatus !== PlayStatus.play && this.playStatus !== PlayStatus.none && this.playStatus !== PlayStatus.pause) {
+                audio.paused();
+            } else {
+
+                if (this.item.sound) {
+                    audio.setSrc(this.item.sound).addListener(TriggerAudioListener.fail, (data)=> {
+                        this.setPlayStatus(PlayStatus.none);
+                        return data.message && popup.$toast(data.message);
+                    })
+                        .addListener(TriggerAudioListener.clear, (data)=> {
+                            this.setPlayStatus(PlayStatus.none);
+                        })
+                        .addListener(TriggerAudioListener.status, (status)=> {
+                            this.setPlayStatus(status);
+                        }).addListener(TriggerAudioListener.speed, ({currDuration,duration})=> {
+                        let useDuration = duration - currDuration;
+
+                        this.duration = useDuration < 0 ? 0 :useDuration;
+                    }).replay()
+                }
+            }
+
+
+
+        },
+
+    },
+
+    created(){
+        this._playStatus = PlayStatus.none;
+    }
+
+
+}

+ 4 - 0
src/popup/popup-detail/components/game/mixins/index.ts

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

+ 13 - 0
src/popup/popup-detail/components/game/props.ts

@@ -0,0 +1,13 @@
+export default {
+
+    pid:{
+        type:Number,
+        default:0
+    },
+
+    config:{
+        type:Object,
+        default:{}
+    }
+
+}

+ 168 - 0
src/popup/popup-detail/components/game/src/main.vue

@@ -0,0 +1,168 @@
+<template>
+  <section
+    class="screen flex"
+  >
+
+    <flat-list :paging="false" @fetch="getDetail" >
+
+      <template v-slot:layout>
+        <header class="game-header rowACenter">
+          <v-image class="game-avatar" mode="center" :src="item.game_info.game_ico" radius="50%"></v-image>
+          <div class="flex-1 game-content">
+            <section
+              class="rowACenter"
+            >
+              <div class="flex-1 overflow rowACenter">
+                <div class="game-title ">{{item.game_info.game_name}}</div>
+                <div @click="triggerPlay" class="game-audio cursor-pointer rowCenter overflow">
+                  <section class="row game-audio-group">
+                    <svg v-if="playStatus === PlayStatus.playBefore" class="game-audio-loading" viewBox="0 0 100 100" enable-background="new 0 0 0 0" xml:space="preserve">
+                        <path fill="#fff" d="M73,50c0-12.7-10.3-23-23-23S27,37.3,27,50 M30.9,50c0-10.5,8.5-19.1,19.1-19.1S69.1,39.5,69.1,50">
+                          <animateTransform attributeName="transform" attributeType="XML" type="rotate" dur="1s" from="0 50 50" to="360 50 50" repeatCount="indefinite"></animateTransform>
+                      </path>
+                   </svg>
+                    <div
+                        v-for="item in 9"
+                        :key="item"
+                        v-else
+                        class="play-audio-item"
+                        :class="['play-audio-'+item%3,playStatus === PlayStatus.play?'play-audio-animate-'+item%3:'']"
+                    ></div>
+                  </section>
+                  <span v-if="playStatus === PlayStatus.play">{{duration}}s</span>
+                  <span v-else-if="playStatus !== PlayStatus.playBefore">{{item.sound_duration}}s</span>
+                </div>
+              </div>
+              <div class="game-price-group">¥<span>{{item.price * number}}</span>/局</div>
+            </section>
+            <section class="rowACenter game-option">
+              <aside
+                v-for="(optionItem,index) in optionData"
+                :key="'option-'+index"
+              >{{optionItem.label}}: {{item[optionItem.key]}}{{optionItem.em}}</aside>
+            </section>
+            <section class="rowACenter game-option game-number">
+              <section class="rowACenter flex-1">
+                <span>数量:</span>
+                <stepper v-model:value="number" class="stepper-margin"></stepper>
+              </section>
+              <div class="game-button center overflow cursor-pointer"
+                   :class="{'game-reverse': item.reverse}"
+                v-for="(item,index) in buttonData"
+                :key="'button-game-'+index"
+                   @click="trigger(item,index)"
+              >{{item.label}}</div>
+            </section>
+
+          </div>
+        </header>
+        <!--    交易流程    -->
+        <section class="game-transaction rowACenter between">
+          <div class="game-introduce">
+            交易流程
+          </div>
+            <section
+                v-for="(item,index) in transactionData"
+                :key="'transaction-'+index"
+                class="rowACenter"
+            >
+              <svg v-if="index!==0" class="transaction-right" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6020" width="200" height="200"><path d="M672 512L352 232v560l320-280z" fill="#cfcfcf" p-id="6021"></path></svg>
+              <aside
+
+                  class="transaction-item center"
+              >
+                <v-image :src="item.icon" mode="center" class="transaction-icon" />
+                <div>{{item.label}}</div>
+              </aside>
+            </section>
+        </section>
+        <!--    描述    -->
+        <section class="game-describe rowACenter between">
+          <aside
+            v-for="(item,index) in describeData"
+            :key="'describe-'+index"
+            class="rowACenter"
+          >
+            <svg t="1623067452203" class="game-describe-icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7732" width="200" height="200" v-html="item.icon"></svg>
+            <div>{{item.label}}</div>
+          </aside>
+        </section>
+        <!--    分类    -->
+        <tab
+          :data="tabData"
+          :auto-height="true"
+          ref="tab"
+        >
+          <template v-slot:header="{data,trigger,select}">
+            <header class="rowACenter game-tab-header">
+              <section class="flex-1 row">
+                <aside
+                  v-for="(item,index) in data"
+                  :key="'tab-'+index"
+                  class="game-tab-item relative center"
+                  :class="{
+                    'cursor-pointer': index !== select,
+                    'game-tab-item-select': index === select
+                  }"
+                  @click="trigger(index)"
+                >{{item.label}}<div v-if="index === select" class="absolute game-tab-line"></div></aside>
+              </section>
+              <div class="rowACenter game-tab-score">
+                <div>评分</div>
+                <div class="game-score-number">5.0</div>
+              </div>
+            </header>
+          </template>
+          <template
+              v-slot:[cItem.slot]
+              v-for="(cItem,index) in tabData"
+          >
+            <component
+              :is="cItem.component"
+              v-if="cItem.component"
+              :key="'tab-component-'+index"
+              :config="item"
+            ></component>
+          </template>
+        </tab>
+      </template>
+
+    </flat-list>
+
+  </section>
+</template>
+
+<script>
+import {
+  scrollView,
+  vImage,
+  FlatList,
+  stepper,
+  tab
+} from '$components';
+import skill from '../components/skill';
+import props from '../props';
+import mixins from '../mixins';
+export default {
+  name: "game",
+
+  components:{
+    scrollView,
+    vImage,
+    FlatList,
+    stepper,
+    tab,
+    skill
+  },
+  props,
+  mixins
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>
+
+<style>
+.game-describe-icon path{
+  fill: #999 !important;
+}
+</style>

+ 209 - 0
src/popup/popup-detail/components/game/style.scss

@@ -0,0 +1,209 @@
+/* 游戏头部 */
+.game-header{
+  padding: 20px 0;
+  border-top: 1px solid #EEEEEE;
+  border-bottom: 1px solid #EEEEEE;
+}
+.game-avatar{
+  @include square(77px);
+}
+.game-content{
+  margin-left: 14px;
+}
+.game-title{
+  font-size: 30px;
+  line-height: 36px;
+  max-width: 60%;
+  color: #666;
+  font-weight: 500;
+}
+.game-price-group{
+  color: #FF9023;
+  font-size: 18px;
+  line-height: 40px;
+  max-width: 35%;
+}
+.game-price-group span{
+  font-size: 40px;
+  font-weight: bold;
+  margin: 0 4px;
+}
+.game-option{
+  color: #999;
+}
+.game-option aside{
+  margin-left: 14px;
+}
+
+.game-option aside:first-child{
+  margin-left: 0;
+}
+/* 游戏头部 */
+
+/* 步进器 */
+.game-number{
+  margin-top: 8px;
+}
+.stepper-margin{
+  margin-left: 10px;
+}
+/* 步进器 */
+
+/* 按钮 */
+.game-button{
+  width: 80px;
+  height: 30px;
+  background: linear-gradient(90deg, #FF58E7, #FF9023);
+  border-radius: 15px;
+  font-size: 14px;
+  color: #fff;
+  margin-left: 18px;
+}
+.game-reverse{
+  background: #FFF1FD!important;
+  color: #FF58E7;
+  border: 1px solid #FF58E7;
+}
+/* 按钮 */
+
+/* 音频 */
+.game-audio{
+  width: 112px;
+  height: 34px;
+  border-radius: 5px;
+  margin-left: 8px;
+  background: linear-gradient(90deg, #FF58E7, #FF54B0);
+  font-size: 20px;
+  line-height: 24px;
+}
+.game-audio span{
+  margin-left: 6px;
+}
+.game-audio-loading{
+  @include square(36px);
+}
+/* 音频 */
+.game-audio-group{
+  align-items: flex-end;
+}
+$audio-height:10px;
+$audio-diff-height:2px;
+.play-audio-item{
+  width: 2px;
+  height: $audio-height;
+  background-color: #fff;
+  margin-right: 3px;
+  border-radius: 30px;
+  flex-shrink: 0;
+}
+.play-audio-1{
+  height: $audio-height - ($audio-diff-height * 2);
+}
+.play-audio-2{
+  height: $audio-height - $audio-diff-height;
+}
+/* 陪玩模块 */
+
+/* 语音播放的动画模块 */
+$animate:1s;
+.play-audio-animate-1 {
+  animation: $animate animateAudio infinite linear 0.6s;
+}
+.play-audio-animate-2 {
+  animation: $animate animateAudio infinite linear 0.3s;
+}
+.play-audio-animate-0 {
+  animation: $animate animateAudio infinite linear;
+}
+
+@keyframes animateAudio {
+  0%{
+    opacity: 1;
+  }
+  50%{
+    opacity: 0.2;
+  }
+  100%{
+    opacity: 1;
+  }
+}
+/* 语音播放的动画模块 */
+
+
+/* 交易流程 */
+.game-transaction{
+  padding: 15px 0;
+}
+.game-introduce{
+  font-size: 16px;
+  width: 36px;
+  line-height: 30px;
+  color: #999;
+}
+.transaction-item{
+  font-size: 15px;
+  color: #999;
+  line-height: 20px;
+}
+.transaction-icon{
+  @include square(30px);
+  margin-bottom: 10px;
+}
+.transaction-right{
+  @include square(20px);
+  margin: 0 8px;
+}
+/* 交易流程 */
+
+/* 描述 */
+.game-describe{
+  height: 44px;
+  background-color: #F4F4F4;
+  margin-top: 2px;
+  padding: 0 20px;
+  font-size: 14px;
+  color: #999;
+  line-height: 20px;
+}
+.game-describe-icon{
+  @include square(24px);
+  margin-right: 10px;
+}
+
+/* 描述 */
+
+/* tab分类 */
+.game-tab-header{
+  height: 50px;
+  border-bottom: 1px solid #eee;
+}
+.game-tab-item{
+  font-size: 16px;
+  color: #999;
+  font-weight: 400;
+  margin-right: 50px;
+  height: 50px
+}
+.game-tab-item-select{
+  color: #333;
+  font-weight: bold;
+}
+.game-tab-score{
+  font-size: 14px;
+  color: #999;
+  line-height: 18px;
+}
+.game-tab-line{
+  left: 0;
+  right: 0;
+  height: 2px;
+  bottom: 0;
+  background-color: #FF58E7;
+}
+.game-score-number{
+  font-size: 16px;
+  color: #FF9024;
+  margin-left: 5px;
+  font-weight: bold;
+}
+/* tab分类 */

+ 10 - 0
src/popup/popup-detail/data/game.ts

@@ -0,0 +1,10 @@
+export default [
+    {
+        label:'王者荣耀',
+        slot:'1'
+    },
+    {
+        label:'和平精英',
+        slot:'2'
+    }
+]

+ 10 - 0
src/popup/popup-detail/data/tab.ts

@@ -0,0 +1,10 @@
+export default [
+    {
+        label:'礼物',
+        icon:require('../images/gift.png')
+    },
+    {
+        label:'冠名',
+        icon:require('../images/vip.png')
+    }
+]

BIN
src/popup/popup-detail/images/bakcground.png


BIN
src/popup/popup-detail/images/gift.png


BIN
src/popup/popup-detail/images/vip.png


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

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

+ 62 - 0
src/popup/popup-detail/mixins/handle.ts

@@ -0,0 +1,62 @@
+import unit from '$utils/unit/unit';
+
+import tabData from '../data/tab';
+
+export default <LibMixins>{
+
+    data(){
+        return {
+            swiperOption:{
+                slidesPerView:'auto',
+                spaceBetween:unit.unitPx(12)
+            },
+            gameOption:{
+                slidesPerView:'auto',
+                spaceBetween:unit.unitPx(15)
+            },
+            banner:0,
+            game:0,
+            tabData
+        }
+    },
+
+    methods:{
+
+        bannerPrev(){
+            let banner = this.banner;
+            banner--;
+            if (banner >= 0) {
+                this.banner = banner;
+            }
+        },
+
+        bannerNext(){
+            let banner = this.banner;
+            banner++;
+
+            if (banner < this.option.images.length) {
+                this.banner = banner;
+            }
+
+        },
+
+        gamePrev(){
+            let game = this.game;
+            game--;
+            if (game >= 0) {
+                this.game = game;
+            }
+        },
+
+        gameNext(){
+            let game = this.game;
+            game++;
+
+            if (game < this.option.gameList.length) {
+                this.game = game;
+            }
+        }
+
+    }
+
+}

+ 5 - 0
src/popup/popup-detail/mixins/index.ts

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

+ 8 - 0
src/popup/popup-detail/props.ts

@@ -0,0 +1,8 @@
+export default {
+
+    option:{
+        type: Object,
+        default:{}
+    }
+
+}

+ 204 - 0
src/popup/popup-detail/src/main.vue

@@ -0,0 +1,204 @@
+<template>
+  <popup v-model:value="value" content-animate="scale" @close="$emit('destroy-popup')">
+    <section class="center">
+      <section class="detail-container flex overflow">
+        <!-- 头部 -->
+        <header class="rowACenter detail-header" >
+          <aside class="flex-1 rowACenter">
+            <v-image class="detail-avatar" radius="50%" :src="option.head_pic"></v-image>
+            <section>
+              <div>{{option.nick_name}}</div>
+              <div class="detail-header-id">ID:{{option.uid}}</div>
+            </section>
+          </aside>
+
+          <!-- 关注 -->
+          <div class="detail-follow-container overflow row">
+            <div class="detail-follow-item detail-follow-number center">{{option.follow_num}}</div>
+            <div class="detail-follow-item detail-follow-span cursor-pointer rowCenter">
+              <svg t="1623031446983" class="detail-follow-icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2552" width="200" height="200"><path d="M753.266187 77.352518A270.218129 270.218129 0 0 0 512 230.510504 270.218129 270.218129 0 0 0 270.733813 77.352518C121.480288 77.352518 0 203.105612 0 357.663309c0 240.750504 257.841727 460.431655 498.444892 585.669065a29.467626 29.467626 0 0 0 27.110216 0c240.971511-125.23741 498.444892-344.918561 498.444892-585.669065 0-154.557698-121.480288-280.310791-270.733813-280.310791z" fill="#ffffff" p-id="2553"></path></svg>
+              <span>关注</span>
+            </div>
+          </div>
+
+          <!-- 关闭按钮 -->
+          <div @click="close" class="detail-close-wrap relative cursor-pointer animate-rotate-hover">
+            <icon type="close" class="detail-close"></icon>
+          </div>
+        </header>
+        <!-- 内容部分 -->
+        <section class="detail-content flex-1 overflow row">
+          <scroll-view>
+            <section class="detail-content-scroll row overflow">
+              <aside class="detail-left">
+                <section class="detail-banner">
+                  <section class="detail-banner-image overflow">
+                    <v-image class="screen" :src="option.images[banner]"></v-image>
+                  </section>
+                  <!-- 循环的banner -->
+                  <section class="rowACenter">
+                    <div @click="bannerPrev" class="detail-banner-trigger center cursor-pointer">
+                      <svg t="1623035534357" class="trigger-icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3411" width="200" height="200"><path d="M670.6 861.6c-7.6 0-15.1-2.9-20.9-8.6L329.4 532.7c-11.6-11.5-11.6-30.3 0-41.8l320.2-320.2c5.8-5.8 13.3-8.6 20.9-8.6 7.5 0 15.1 2.9 20.9 8.6 11.5 11.5 11.5 30.2 0 41.8L392 511.8l299.4 299.4c11.5 11.6 11.5 30.3 0 41.8-5.7 5.7-13.3 8.6-20.8 8.6z" p-id="3412" fill="#ffffff"></path></svg>
+                    </div>
+                    <aside class="flex-1 overflow detail-banner-images">
+                      <swiper
+                          :swiperOption="swiperOption"
+                          class="screen"
+                          v-model:value="banner"
+                          ref="banner"
+                      >
+                        <swiper-item
+                            v-for="(item,index) in option.images"
+                            class="detail-banner-icon overflow"
+                            :key="'image-item-'+item"
+                            :class="{
+                         'detail-banner-select': index === banner
+                      }"
+                        >
+                          <v-image
+                              class="screen"
+                              :src="item"
+                          ></v-image>
+                        </swiper-item>
+                      </swiper>
+                    </aside>
+                    <div @click="bannerNext" class="detail-banner-trigger center cursor-pointer">
+                      <svg t="1623035654891" class="trigger-icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1920" width="200" height="200"><path d="M671.5392 512L332.1344 172.544a32 32 0 0 1 45.2608-45.2096l358.4 358.4a37.12 37.12 0 0 1 0 52.5312l-358.4 358.4a32 32 0 0 1-45.2608-45.2608L671.5904 512z" fill="#ffffff" p-id="1921"></path></svg>
+                    </div>
+                  </section>
+                  <!-- 简介 -->
+                  <div class="detail-introduction jCenter">
+                    <div class="line-1">简介:{{option.autograph ||  '暂未设置签名'}}</div>
+                  </div>
+                </section>
+                <!-- 礼物 -->
+                <section class="detail-gift">
+                  <tab
+                      class="screen"
+                      :data="tabData"
+                  >
+                    <template v-slot:header="{data,trigger,select}">
+                      <section class="center">
+                        <header class="detail-tab-header rowACenter">
+                          <aside
+                              v-for="(item,index) in data"
+                              :key="'detail-tab-'+index"
+                              class="detail-tab-item rowCenter"
+                              :class="{
+                        'detail-tab-select': index === select,
+                        'cursor-pointer': index !== select
+                      }"
+                              @click="trigger(index)"
+                          >
+                            <v-image
+                                :src="item.icon"
+                                mode="center"
+                                class="detail-tab-icon"
+                            />
+                            <span>{{item.label}}</span>
+                          </aside>
+                        </header>
+                      </section>
+                    </template>
+
+                  </tab>
+                </section>
+
+              </aside>
+              <!-- 游戏 -->
+              <aside class="flex-1 overflow detail-game">
+                <tab
+                    :data="option.gameList"
+                    v-model:value="game"
+                >
+                  <template v-slot:header="{data,trigger,select}">
+                    <section class="detail-game-header-warp">
+                      <header class="detail-game-header rowACenter">
+                        <div @click="gamePrev" class="detail-game-trigger center cursor-pointer">
+                          <svg t="1623035534357" class="trigger-icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3411" width="200" height="200"><path d="M670.6 861.6c-7.6 0-15.1-2.9-20.9-8.6L329.4 532.7c-11.6-11.5-11.6-30.3 0-41.8l320.2-320.2c5.8-5.8 13.3-8.6 20.9-8.6 7.5 0 15.1 2.9 20.9 8.6 11.5 11.5 11.5 30.2 0 41.8L392 511.8l299.4 299.4c11.5 11.6 11.5 30.3 0 41.8-5.7 5.7-13.3 8.6-20.8 8.6z" p-id="3412" fill="#ffffff"></path></svg>
+                        </div>
+                        <aside class="flex-1 overflow detail-game-swiper">
+                          <swiper
+                              :swiperOption="gameOption"
+                              class="screen"
+                              v-model:value="game"
+                              ref="game"
+                          >
+                            <swiper-item
+                                v-for="(item,index) in data"
+                                class="detail-game-item center overflow"
+                                :key="'image-item-'+item"
+                                :class="{
+                       'detail-game-select': index === select,
+                       'cursor-pointer': index !== select
+                    }"
+                                @click="trigger(index)"
+                            >
+                              <span>{{item.label}}</span>
+                            </swiper-item>
+                          </swiper>
+                        </aside>
+                        <div @click="gameNext" class="detail-game-trigger center cursor-pointer">
+                          <svg t="1623035654891" class="trigger-icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1920" width="200" height="200"><path d="M671.5392 512L332.1344 172.544a32 32 0 0 1 45.2608-45.2096l358.4 358.4a37.12 37.12 0 0 1 0 52.5312l-358.4 358.4a32 32 0 0 1-45.2608-45.2608L671.5904 512z" fill="#ffffff" p-id="1921"></path></svg>
+                        </div>
+                      </header>
+                    </section>
+
+                  </template>
+
+                  <template
+                      v-for="(item,index) in option.gameList"
+                      v-slot:[item.slot]
+                  >
+                    <game
+                        :key="'tab-component-'+index"
+                        :pid="item.pid"
+                        :config="option"
+                    ></game>
+                  </template>
+
+
+                </tab>
+              </aside>
+
+            </section>
+          </scroll-view>
+        </section>
+
+
+      </section>
+    </section>
+  </popup>
+</template>
+
+<script>
+import {
+  Popup,
+  icon,
+  vImage,
+  scrollView,
+  swiper,
+  swiperItem,
+  tab
+} from '$components';
+import mixins from '../mixins';
+import props from '../props';
+import game from '../components/game';
+export default {
+  name: "popup-detail",
+  components:{
+    Popup,
+    icon,
+    vImage,
+    scrollView,
+    swiper,
+    swiperItem,
+    tab,
+    game
+  },
+  props,
+  mixins
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 196 - 0
src/popup/popup-detail/style.scss

@@ -0,0 +1,196 @@
+/* 容器 */
+.detail-container{
+  width: 1100px;
+  max-height: 90%;
+  height: 1010px;
+  background-color: #F1F1F1;
+  border-radius: 20px;
+}
+/* 容器 */
+
+/* 头部 */
+.detail-header{
+  height: 110px;
+  background: linear-gradient(90deg, #7B388F, #3F269A);
+  font-size: 18px;
+  line-height: 20px;
+  font-weight: 400;
+  padding: 0 30px;
+}
+.detail-avatar{
+  @include square(84px);
+  margin-right: 10px;
+}
+.detail-header-id{
+  margin-top: 15px;
+}
+$detail-follow:160px;
+.detail-follow-container{
+  width: $detail-follow;
+  background-color: #FF9023;
+  border-radius: 21px;
+  height: 42px;
+  margin-right: 50px;
+}
+.detail-follow-item{
+  width: $detail-follow / 2;
+}
+.detail-follow-number{
+  background-color: #fff;
+  color: #FF9023;
+  font-size: 16px;
+  line-height: 18px;
+  padding: 0 5px;
+}
+.detail-follow-icon{
+  @include square(18px);
+  margin-right: 4px;
+}
+.detail-follow-span{
+  font-size: 16px;
+  line-height: 18px;
+  font-weight: 400;
+}
+.detail-close-wrap{
+  top: -32px;
+  right: -10px;
+}
+.detail-close{
+  font-size: 14px;
+  color: #fff;
+}
+/* 头部 */
+
+/* 内容部分 */
+.detail-content-scroll {
+  height: 880px;
+}
+.detail-content{
+  padding: 10px;
+}
+/* 内容部分 */
+
+/* 左侧内容 */
+.detail-left{
+  width: 450px;
+}
+/* 左侧内容 */
+
+/* 轮播 */
+.detail-banner{
+  height: 586px;
+  width: 100%;
+  border-radius: 10px;
+  padding: 10px;
+  background-color: #fff;
+}
+.detail-banner-image{
+  width: 100%;
+  height: 430px;
+  border-radius: 20px;
+  margin-bottom: 10px;
+}
+.detail-banner-icon{
+  @include square(85px);
+  border: 1px solid transparent;
+  flex-shrink: 0;
+  border-radius: 5px;
+}
+.detail-banner-select{
+  border-color: #FF1E8C;
+}
+.detail-banner-trigger{
+  width: 16px;
+  height: 85px;
+  border-radius: 7px;
+  background-color: #eee;
+}
+.detail-banner-images{
+  padding: 0 10px;
+}
+.detail-introduction{
+  height: 50px;
+  font-size: 16px;
+  line-height: 18px;
+  color: #333;
+  font-weight: 400;
+}
+.trigger-icon{
+  @include square(15px);
+}
+/* 轮播 */
+
+/* 礼物 */
+.detail-gift{
+  height: 288px;
+  width: 100%;
+  margin-top: 8px;
+  background-color: #fff;
+  border-radius: 10px;
+  padding: 10px;
+}
+/* 礼物 */
+
+/* tab */
+.detail-tab-header{
+  background-color: #F6F6f6;
+  height: 32px;
+  margin-bottom: 10px;
+}
+.detail-tab-item,.detail-tab-header{
+  border-radius: 16px;
+}
+.detail-tab-item{
+  width: 100px;
+  height: 100%;
+  color: #333;
+}
+.detail-tab-icon{
+  @include square(20px);
+  margin-right: 7px;
+}
+.detail-tab-select{
+  background: linear-gradient(90deg, #FF58E7, #FF54B1);
+  color: #fff;
+}
+/* tab */
+
+/* 游戏 */
+.detail-game{
+  margin-left: 8px;
+  background-color: #fff;
+  border-radius: 10px;
+  padding: 20px;
+}
+.detail-game-header-warp{
+  padding-bottom: 20px;
+}
+.detail-game-header{
+  height: 30px;
+}
+.detail-game-swiper{
+  padding: 0 10px;
+  height: 30px;
+}
+.detail-game-trigger{
+  width: 12px;
+  height: 30px;
+  border-radius: 7px;
+  background-color: #eee;
+}
+.detail-game-item{
+  width: 80px;
+  height: 30px;
+  border-radius: 15px;
+  color: #666;
+  font-size: 14px;
+  line-height: 18px;
+}
+.detail-game-trigger .trigger-icon{
+  @include square(12px);
+}
+.detail-game-select{
+  background: linear-gradient(90deg, #FF58E7, #FF54B0);
+  color: #fff;
+}
+/* 游戏 */

+ 4 - 2
src/popup/popup-export/components.ts

@@ -9,6 +9,8 @@ export default {
     [PopupExportComponent.confirm]: defineAsyncComponent(()=> import('$popup/popup-confirm')),
     [PopupExportComponent.realName]:defineAsyncComponent(()=> import('$popup/popup-real-name')),
     [PopupExportComponent.choosingSkill]: defineAsyncComponent(()=> import('$popup/popup-choosing')),
-    [PopupExportComponent.settle]: defineAsyncComponent(()=> import('$popup/popup-settle'))
-
+    [PopupExportComponent.settle]: defineAsyncComponent(()=> import('$popup/popup-settle')),
+    [PopupExportComponent.detail]: defineAsyncComponent(()=> import('$popup/popup-detail')),
+    [PopupExportComponent.order]: defineAsyncComponent(()=> import('$popup/popup-order')),
+    [PopupExportComponent.recharge]: defineAsyncComponent(()=> import('$popup/popup-recharge'))
 }

+ 11 - 2
src/popup/popup-export/const/index.ts

@@ -21,8 +21,17 @@ const enum PopupExportComponent {
     // 选择技能
     choosingSkill='popup-choosing-skill',
 
-    //大神入驻
-    settle='popup-settle'
+    // 大神入驻
+    settle='popup-settle',
+
+    // 详情
+    detail='popup-detail',
+
+    // 订单
+    order = 'popup-order',
+
+    // 充值
+    recharge='popup-recharge'
 
 }
 

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

@@ -25,7 +25,7 @@ export default {
                 }
             }
 
-            popup.$popup.open(PopupExportComponent.choosingSkill);
+            popup.$popup.open(PopupExportComponent.recharge);
 
         });
 

+ 1 - 1
src/popup/popup-loading/src/main.vue

@@ -1,5 +1,5 @@
 <template>
-  <popup :value="!!loadingTitle" style="z-index: 9999;background-color: transparent"
+  <popup :value="!!loadingTitle" style="z-index: 99999;background-color: transparent"
     :class="{
       'loading-mask': mask
     }"

+ 14 - 0
src/popup/popup-order/global.scss

@@ -0,0 +1,14 @@
+.order-select{
+  width: 186px;
+  height: 31px;
+}
+
+.order-select .ant-select-selector{
+  background-color: transparent !important;
+  border-color: rgba(255,255,255,0.4) !important;
+  border-radius: 5px  !important;
+}
+
+.order-select .ant-select-selection-item,.order-select .ant-select-arrow{
+  color: #fff;
+}

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

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

+ 81 - 0
src/popup/popup-order/mixins/handle.ts

@@ -0,0 +1,81 @@
+import transactionData from "$popup/popup-detail/components/game/data/transaction";
+import Status from "$mixins/status/const/status";
+
+export default <LibMixins>{
+
+    data(){
+      return {
+          transactionData,
+          item:{},
+          value:0,
+          payOrder:['balance'],
+      }
+    },
+
+    computed:{
+      total(){
+          return this.item.number * this.item.price || 0;
+      }
+    },
+
+    methods:{
+
+        installConfig(config){
+
+            this.value = config.value;
+
+            let dataObject = {};
+            this.option.gameList.map((item,index)=>{
+                dataObject[item.value] = item;
+            });
+
+            this.dataObject = dataObject;
+
+            this.item = this.dataObject[this.value];
+        },
+
+        changeGameType(pid){
+
+            if (pid !== this.value) {
+                this.value = pid;
+                if (this.dataObject && this.dataObject[pid]){
+                    this.item = this.dataObject[pid];
+                }
+
+            }
+
+        },
+
+        // 点击确认支付触发
+        payOrderInfo(data){
+
+            return this.$request({
+                url:'player/create_player_order',
+                token:true,
+                data:{
+                    pid: this.item.value,
+                    buy_num:this.item.number,
+                    trade_password:data.password
+                },
+                loading:'支付中',
+                next:({status})=>{
+                    this.payStatus = status ? Status.loading : Status.none
+                },
+                message:true,
+                failMessage:true
+            }).then((data)=>{
+                console.log(data);
+                if (data.isSuccess) {
+                    return this.close();
+                }
+            });
+
+        }
+
+    },
+
+    created() {
+        this.installConfig(this.option);
+    }
+
+}

+ 5 - 0
src/popup/popup-order/mixins/index.ts

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

+ 9 - 0
src/popup/popup-order/props.ts

@@ -0,0 +1,9 @@
+export default {
+
+    // 配置
+    option:{
+        type:Object,
+        default: {}
+    }
+
+}

+ 120 - 0
src/popup/popup-order/src/main.vue

@@ -0,0 +1,120 @@
+<template>
+  <popup v-model:value="value" content-animate="scale" @close="$emit('destroy-popup')">
+    <section class="order-container flex relative">
+      <header class="order-header rowACenter between">
+        <div class="order-process">交易流程</div>
+        <section
+            v-for="(item,index) in transactionData"
+            :key="'order-'+index"
+            class="rowACenter"
+        >
+          <svg v-if="index!==0" class="order-describe-right" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6020" width="200" height="200"><path d="M672 512L352 232v560l320-280z" fill="#ffffff" p-id="6021"></path></svg>
+          <aside
+              class="order-describe-item center"
+          >
+            <v-image class="order-describe-icon" mode="center" :src="item.icon" backgroundColor="transparent"></v-image>
+            <div class="order-describe-label">{{item.label}}</div>
+          </aside>
+        </section>
+      </header>
+      <section class="flex-1 overflow order-content">
+        <div class="order-content-title">确认订单信息</div>
+        <section class="order-table overflow">
+          <div class="order-table-tr order-table-header rowACenter">
+            <aside class="center">陪玩大神</aside>
+            <aside class="center">服务品类</aside>
+            <aside class="center">单价</aside>
+            <aside class="center">订单总价</aside>
+            <aside class="center">购买数量</aside>
+          </div>
+          <div class="order-table-tr order-table-content rowACenter">
+            <aside class="rowCenter">
+              <v-image class="order-user-avatar" :src="option.user.header_pic" radius="50%"></v-image>
+              <div class="order-user-name">{{option.user.nick_name}}</div>
+            </aside>
+            <aside class="center">
+              <a-select :value="value" @change="changeGameType" class="order-select">
+                <a-select-option
+                    v-for="(item) in option.gameList"
+                    :key="'options-'+item.pid"
+                    :value="item.value"
+                >{{item.label}}</a-select-option>
+              </a-select>
+            </aside>
+            <aside class="center order-table-price">¥{{item.price}}/局</aside>
+            <aside class="center order-table-all-price">¥{{total}}</aside>
+            <aside class="center">
+              <stepper v-model:value="item.number" type="order"></stepper>
+            </aside>
+          </div>
+        </section>
+        <section class="order-pay-info">
+          <aside class="rowACenter order-pay-item">
+            <div class="order-pay-label">支付方式:</div>
+            <section class="flex-1 overflow rowACenter">
+              <aside
+                v-for="(item,index) in payOrder"
+                :key="'pay-'+index"
+                class="center order-pay-info-item"
+                :class="{
+                  'cursor-pointer': payCheck !== index,
+                  'order-pay-info-check': payCheck === index,
+                  'order-pay-info-format': payData[item].format && payFormat[payData[item].format]
+                }"
+                @click="triggerPayType(index)"
+              >
+                <div class="">{{payData[item].label}}</div>
+                <div class="order-pay-format" v-if="payData[item].format && payFormat[payData[item].format]">{{payFormat[payData[item].format]}}</div>
+              </aside>
+            </section>
+          </aside>
+          <aside class="rowACenter order-pay-item order-pay-item-margin">
+            <div class="order-pay-label">实付款:</div>
+            <section class="flex-1 order-pay-price">
+              <div class="line-1">{{payTotalFormat}}</div>
+            </section>
+          </aside>
+        </section>
+      </section>
+      <!--   底部     -->
+      <footer class="order-footer center">
+        <div class="order-footer-info">15分钟未接退单 服务保障</div>
+        <div class="order-button-group rowACenter">
+          <aside class="order-button center cursor-pointer" @click="close">返回大神首页</aside>
+          <aside class="order-button order-main-button center cursor-pointer" @click="triggerPayOrder">确认支付</aside>
+        </div>
+      </footer>
+    </section>
+  </popup>
+</template>
+
+<script>
+import {
+  Popup,
+  icon,
+  vImage,
+  stepper
+} from '$components';
+import {
+  Select
+} from 'ant-design-vue';
+import props from '../props';
+import mixins from '../mixins';
+export default {
+  name: "popup-order",
+  components:{
+    Popup,
+    icon,
+    vImage,
+    stepper,
+    [Select.name]:Select,
+    [Select.Option.displayName]:Select.Option,
+  },
+  props,
+  mixins
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>
+
+<style lang="scss" src="../global.scss"></style>

+ 180 - 0
src/popup/popup-order/style.scss

@@ -0,0 +1,180 @@
+/* 容器 */
+.order-container{
+  width: 1014px;
+  height: 660px;
+  background-color: #1A1735;
+  border-radius: 10px;
+}
+/* 容器 */
+
+/* 头部 */
+.order-header{
+  height: 140px;
+  width: 100%;
+  padding: 0 26px;
+  background: linear-gradient(90deg, #23266E, #37248F);
+}
+.order-process{
+  font-size: 20px;
+  line-height: 30px;
+  color: rgba(255,255,255,0.5);
+  width: 40px;
+  margin-right: 40px;
+}
+.order-describe-item{
+  width: 134px;
+  height: 117px;
+  border-radius: 10px;
+  background-color: rgba(255,255,255,0.1);
+}
+.order-describe-icon{
+  @include square(34px);
+}
+.order-describe-label{
+  font-size: 14px;
+  line-height: 20px;
+  color: rgba(255,255,255,0.5);
+  margin-top: 15px;
+}
+.order-describe-right{
+  @include square(24px);
+  margin-right:14px;
+}
+/* 头部 */
+
+/* 订单内容 */
+.order-content{
+  padding: 28px;
+}
+.order-content-title{
+  font-size: 18px;
+  line-height: 22px;
+  color: #fff;
+}
+.order-table{
+  margin-top: 15px;
+  border-radius: 10px;
+  font-size: 16px;
+  line-height: 20px;
+
+}
+.order-table-content {
+  background-color: #46445c;
+  height: 98px;
+}
+.order-table-header{
+  height: 48px;
+  background-color: #312f4a;
+}
+.order-table-tr aside{
+  width: 237px;
+}
+.order-table-tr aside:nth-of-type(2n) {
+  width: 250px;
+}
+.order-table-tr aside:nth-of-type(3n) {
+  width: 130px;
+}
+.order-table-tr aside:nth-of-type(4n) {
+  width: 155px;
+}
+.order-table-tr aside:nth-of-type(5n) {
+  width: 195px;
+  border-right: none;
+}
+.order-table-content aside{
+  height: 100%;
+  border-right: 2px solid #1A1735;
+  padding: 0 10px;
+}
+.order-user-avatar{
+  @include square(50px);
+  flex-shrink: 0;
+}
+.order-table-all-price {
+  font-size: 20px;
+  line-height: 26px;
+  color: #FF0000;
+  font-weight: bold;
+}
+.order-user-name{
+  margin-left: 12px;
+}
+.order-table-header {
+  font-size: 14px;
+  color: rgba(255,255,255,0.5);
+  line-height: 18px;
+}
+/* 订单内容 */
+
+/* 订单支付信息 */
+.order-pay-info{
+  padding: 55px 55px 0;
+}
+.order-pay-item-margin{
+  margin-top: 30px;
+}
+.order-pay-label{
+  width: 70px;
+  text-align: right;
+  font-size: 14px;
+  font-weight: bold;
+  line-height: 20px;
+  margin-right: 27px;
+}
+.order-pay-info-item{
+  width: 136px;
+  height: 40px;
+  border: 1px solid rgba(255,255,255,0.5);
+  border-radius: 5px;
+  color: rgba(255,255,255,0.5);
+  font-size: 14px;
+  line-height: 16px;
+  margin-right: 11px;
+}
+.order-pay-info-format{
+  font-size: 12px;
+}
+.order-pay-info-item:last-child{
+  margin-right: 0;
+}
+.order-pay-info-check{
+  border-color: #717DF5;
+  color: #717DF5;
+}
+.order-pay-price{
+  font-size: 20px;
+  color: #FF0000;
+  font-weight: bold;
+}
+/* 订单支付信息 */
+
+/* 底部 */
+.order-footer{
+  height: 110px;
+  border-top: 1px solid rgba(255,255,255,0.5);
+}
+.order-footer-info{
+  font-size: 12px;
+  line-height: 16px;
+  color: rgba(255,255,255,0.5);
+}
+.order-button-group{
+  margin-top: 13px;
+}
+.order-button {
+  width: 126px;
+  height: 36px;
+  border-radius: 18px;
+  color: #6D85F8;
+  font-size: 14px;
+  line-height: 18px;
+  border: 1px solid #6B88F9;
+}
+.order-main-button{
+  background: $main-linear;
+  border: none;
+  color: #fff;
+  margin-left: 40px;
+}
+/* 底部 */

+ 28 - 0
src/popup/popup-recharge/global.scss

@@ -0,0 +1,28 @@
+.recording-input{
+  background-color: transparent;
+  border: none !important;
+  border-bottom: 2px solid #fff !important;
+  box-shadow: none !important;
+  font-size: 18px;
+  line-height: 20px;
+  color: #fff;
+  height: 28px;
+
+}
+.recording-input input {
+  height: 26px;
+  padding: 0;
+}
+.recording-item-active .recording-input{
+  border-bottom-color: #00D39E !important;
+}
+.recording-item-active input {
+  color: #00D39E;
+}
+.recording-input .ant-input-number-input-wrap {
+  outline: none !important;
+}
+
+.recording-input .ant-input-number-handler-wrap{
+  display: none;
+}

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

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

+ 39 - 0
src/popup/popup-recharge/mixins/handle.ts

@@ -0,0 +1,39 @@
+export default <LibMixins>{
+
+    data(){
+      return {
+          inputPayItem:{
+              integral:'其他余额',
+              format:false,
+              input:true,
+              value:''
+          },
+          paySelect:0,
+          payOrder:['weChat','alipay'],
+      }
+    },
+
+    computed:{
+
+        payList(){
+            return [
+                ...this.$store.state.pay.payList,
+                this.inputPayItem
+            ]
+        }
+
+    },
+
+    methods:{
+
+        triggerPayNumber(index){
+
+            if (this.paySelect !== index) {
+                this.paySelect = index;
+            }
+
+        }
+
+    }
+
+}

+ 5 - 0
src/popup/popup-recharge/mixins/index.ts

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

+ 90 - 0
src/popup/popup-recharge/src/main.vue

@@ -0,0 +1,90 @@
+<template>
+  <popup v-model:value="value" content-animate="scale" @close="$emit('destroy-popup')">
+    <section class="recharge-container relative">
+      <div @click="close" class="recharge-close-wrap cursor-pointer absolute animate-rotate-hover">
+        <icon type="close" class="recharge-close"></icon>
+      </div>
+
+     <!--   内容   -->
+      <section class="screen recharge-content">
+        <div class="recharge-title">巧鱼币充值</div>
+        <!--   余额   -->
+        <section class="recording-info rowACenter">
+          <div class="recording-label">账户余额:</div>
+          <aside class="flex-1 rowACenter recording-integral">
+            <img src="@/assets/images/currency.png" class="recording-currency" />
+            <span>{{$store.getters.integral}}</span>
+          </aside>
+        </section>
+        <!--   充值   -->
+        <section class="recording-info row">
+          <div class="recording-label">充值巧鱼币:</div>
+          <section class="flex-1 rowACenter recording-money wrap">
+            <aside
+              v-for="(item,index) in payList"
+              class="recording-item center"
+              :key="'recording-'+index"
+              @click="triggerPayNumber(index)"
+              :class="{
+                'recording-item-active': index === paySelect,
+                'cursor-pointer': index !== paySelect
+              }"
+            >
+              <div>{{item.integral}}{{ item.format === false ? '':'巧鱼币' }}</div>
+              <div v-if="item.input" class="rowACenter recording-price-input">
+                <span>¥</span>
+                <a-input-number v-model:value="item.value" class="recording-input"></a-input-number>
+              </div>
+              <div v-else class="recording-price">¥{{item.money}}元</div>
+            </aside>
+          </section>
+        </section>
+        <!--   支付方式   -->
+        <section class="recording-info row recording-pay-margin">
+          <div class="recording-label">支付方式:</div>
+          <section class="flex-1 rowACenter recording-pay wrap">
+            <aside
+                v-for="(item,index) in payOrder"
+                class="recording-pay-item rowCenter"
+                :key="'recording-pay-'+index"
+                :class="{
+                'recording-pay-active': index === payCheck,
+                'cursor-pointer': index !== payCheck
+              }"
+            >
+              <img :src="payData[item].icon" class="recording-pay-icon" />
+              <span>{{payData[item].label}}</span>
+            </aside>
+          </section>
+        </section>
+      </section>
+
+    </section>
+  </popup>
+</template>
+
+<script>
+import {
+  Popup,
+  icon,
+  vImage
+} from '$components';
+import {
+  InputNumber
+} from 'ant-design-vue';
+import mixins from '../mixins';
+export default {
+  name: "popup-recharge",
+  components:{
+    Popup,
+    icon,
+    vImage,
+    [InputNumber.name]:InputNumber
+  },
+  mixins
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>
+
+<style lang="scss" src="../global.scss"></style>

+ 118 - 0
src/popup/popup-recharge/style.scss

@@ -0,0 +1,118 @@
+/* 充值 */
+.recharge-container{
+  width: 856px;
+  height: 635px;
+  border: 4px solid #F191AC;
+  background-color: #342971;
+  border-radius: 10px;
+}
+/* 充值 */
+
+/* 头部 */
+.recharge-header{
+  width: 395px;
+  height: 56px;
+}
+/* 头部 */
+
+/* 关闭按钮 */
+.recharge-close-wrap{
+  right: 20px;
+  top: 15px;
+}
+.recharge-close{
+  font-size: 18px;
+}
+/* 关闭按钮 */
+
+/* 内容模块 */
+.recharge-content{
+  padding: 0 56px;
+}
+.recharge-title{
+  font-size: 24px;
+  line-height: 28px;
+  margin-top: 50px;
+}
+.recording-info{
+  margin-top: 30px;
+}
+.recording-label{
+  width: 100px;
+  margin-right: 20px;
+  font-size: 18px;
+  line-height: 22px;
+}
+.recording-currency{
+  @include square(21px);
+  margin-right: 10px;
+}
+.recording-integral{
+  font-size: 24px;
+  color: #EC6941;
+  font-weight: bold;
+  line-height: 26px;
+}
+.recording-item{
+  width: 132px;
+  height: 72px;
+  background-color: rgba(255,255,255,0.1);
+  border-radius: 10px;
+  margin-right: 25px;
+  margin-bottom: 16px;
+  font-size: 16px;
+  color: #FFFFFF;
+  line-height: 22px;
+  border: 2px solid transparent;
+}
+.recording-item:nth-of-type(4n) {
+  margin-right: 0;
+}
+.recording-price{
+  margin-top: 8px;
+}
+.recording-price-input{
+  font-size: 18px;
+  line-height: 20px;
+  margin-top: 4px;
+}
+.recording-price-input span{
+  position: relative;
+  top: 4px;
+}
+.recording-input{
+  margin-left: 6px;
+  width: 80px;
+}
+.recording-item-active{
+  border-color: #DE6DA0;
+  color: #00D39E;
+}
+.recording-pay-margin{
+  margin-top: 10px;
+}
+/* 内容模块 */
+
+/* 支付类型 */
+.recording-pay-item {
+  width: 160px;
+  height: 60px;
+  margin-right: 15px;
+  margin-bottom: 15px;
+  background-color: rgba(255,255,255,0.1);
+  border-radius: 10px;
+  border: 2px solid transparent;
+  font-size: 18px;
+  line-height: 20px;
+  color: #fff;
+  font-weight: 400;
+}
+.recording-pay-icon{
+  @include square(36px);
+  margin-right: 12px;
+}
+.recording-pay-active {
+  border-color: #DE6DA0;
+  color: #00BE00;
+}
+/* 支付类型 */

+ 1 - 1
src/popup/popup-toast/style.scss

@@ -14,6 +14,6 @@
   letter-spacing: 1px;
   opacity: 1 !important;
   pointer-events: all;
-  z-index: 99999;
+  z-index: 9999;
 }
 /* toast */

+ 3 - 1
src/store/modules/index.ts

@@ -1,8 +1,10 @@
 import user from './user';
 import cate from './cate';
+import pay from './pay';
 import {ModuleTree} from "vuex";
 
 export default <ModuleTree<any>>{
     user,
-    cate
+    cate,
+    pay
 };

+ 74 - 0
src/store/modules/pay.ts

@@ -0,0 +1,74 @@
+import {Module} from "vuex";
+
+import $request from '$utils/request';
+
+export default <Module<any,any>>{
+
+    state:{
+        payList:[],
+        payRatio:0
+    },
+
+    mutations:{
+
+        setPayInfo(state,data){
+
+            console.log(data);
+
+            state.payList = data.config;
+
+            state.payRatio = data.ratio;
+
+        }
+
+    },
+
+    actions:{
+
+        initializationPayPromise({commit}){
+
+
+
+            return new Promise(function (resolve, reject) {
+                Promise.all([$request({
+                    url:'pay/get_can_recharge_list',
+                    cache:true,
+                    failMessage:true,
+                    token:true,
+                    login:false
+                }),$request({
+                    url:'user/exchange_check',
+                    data:{
+                      money:1
+                    },
+                    cache:true,
+                    failMessage:true,
+                    token:true,
+                    login:false
+                })]).then(([reList,check])=>{
+
+                    let data ={
+                        config: reList.data || [],
+                        ratio: check.data.money
+                    }
+
+                    commit('setPayInfo',data);
+                    return resolve(data);
+                });
+                // $request({
+                //     url:'pay/get_can_recharge_list',
+                //     cache:true,
+                //     failMessage:true,
+                //     token:true,
+                //     login:false
+                // }).then((data)=>{
+                //     commit('setPayInfo',data);
+                //     return resolve(data);
+                // }).catch(reject)
+            });
+
+        }
+
+    }
+
+}

+ 11 - 1
src/store/modules/user.ts

@@ -10,6 +10,8 @@ import $utils from '$utils/tool/utils';
 
 import $request from '$utils/request';
 
+import money from '$utils/tool/money';
+
 export default <Module<any,any>>{
 
     state:{
@@ -56,7 +58,15 @@ export default <Module<any,any>>{
           } else {
               return [];
           }
-      }
+      },
+
+     integral(state){
+         if (state.user.integral) {
+             return money.checkIntMoney(state.user.integral || 0) || 0;
+         } else {
+             return 0;
+         }
+     }
     },
 
     mutations:{

+ 6 - 0
src/utils/request/cache/cache.ts

@@ -50,6 +50,8 @@ export default  class Cache {
 
 			let data:InstructionsCache = storage.getItem(Cache.key+':'+sign);
 
+
+
 			if (data) {
 
 				data.first = undefined;
@@ -73,6 +75,7 @@ export default  class Cache {
 			resultCache = {...cache};
 		}
 
+		resultCache.expireTime = resultCache.expireTime || 0;
 		// 设置过期时间
 		resultCache.expireTime = !resultCache.expireTime || resultCache.expireTime<=0 ? resultCache.expireTime : Cache.getNowTime() + resultCache.expireTime;
 
@@ -84,11 +87,14 @@ export default  class Cache {
 
 		this.caches[sign] = resultCache;
 
+
 		// 设置缓存
 		if (
 			resultCache.type === undefined || resultCache.type === InstructionsCacheType.storage
 
 		) {
+
+
 			if (resultCache.expireTime != null) {
 				storage.setItem(Cache.key + ':' + sign, resultCache, resultCache.expireTime);
 			}

+ 6 - 1
src/utils/request/cache/index.ts

@@ -8,6 +8,7 @@ import {
     InstructionsWhere,
     InstructionsTypes,
     LibRequestStatus,
+    InstructionsCacheSync
 } from '../const/request';
 
 instructions.push('cache',{
@@ -15,6 +16,8 @@ instructions.push('cache',{
 
         let sign:string = data.sign ? data.sign : Cache.sign(data.requestData);
 
+
+
         if (!data.sign) {
             data.sign = sign;
         }
@@ -34,6 +37,7 @@ instructions.push('cache',{
 
                 let storageCache = data.requestData.cache;
 
+
                 delete data.requestData.cache;
 
                 instructions.trigger(data,InstructionsTypes.end);
@@ -73,11 +77,12 @@ instructions.push('cache',{
                 // 存储必要参数
                 resultData.data = {
                     // @ts-ignore
-                    statusCode: data.responseData.statusCode,
+                    statusCode: data.responseData.status,
                     // @ts-ignore
                     data: JSON.parse(JSON.stringify(data.responseData.data))
                 };
 
+
                 return cache.setCache(sign,resultData);
             }
 

+ 2 - 0
src/utils/request/types/lib.request.d.ts

@@ -13,6 +13,8 @@ interface LibRequestOptions extends LibRequestConfig,LibRequestInstructionsOptio
 
     file?:Boolean,
 
+    login?:boolean,
+
     name?:string,
 
     header?:Record<string, string>,

+ 17 - 0
src/utils/tool/money.ts

@@ -0,0 +1,17 @@
+export default {
+
+    checkIntMoney(number:any){
+
+        let intNumber = parseInt(number);
+
+        number = parseFloat(parseFloat(number).toFixed(2));
+
+        if (intNumber === number) {
+            return intNumber;
+        } else {
+            return  number;
+        }
+
+    }
+
+}

+ 5 - 0
src/utils/unit/unit.ts

@@ -9,6 +9,11 @@ export default {
     unitRem(value:number):string {
         // @ts-ignore
         return  value / window.screen_conf.proportion / screen_conf.multiple + 'rem';
+    },
+
+    unitPx(value:number):number {
+        // @ts-ignore
+        return  value * window.screen_conf.proportion;
     }
 
 }

+ 1 - 1
src/views/view-header/src/main.vue

@@ -25,7 +25,7 @@
           <div class="user-name line-1">{{user.nick_name}}</div>
           <section class="rowACenter user-number">
             <img src="@/assets/images/currency.png" class="user-currency" />
-            <div class="overflow line-1 user-login-text">0</div>
+            <div class="overflow line-1 user-login-text">{{$store.getters.integral}}</div>
             <aside class="user-number-button button-active center">充值</aside>
           </section>
         </div>

+ 0 - 1
src/views/view-play-with/mixins/handle.ts

@@ -27,7 +27,6 @@ export default <LibMixins>{
                     });
                 }
 
-
                 return  obj.success(data.data);
 
             }).catch(obj.fail);