Эх сурвалжийг харах

feat: 超级订阅送给朋友页面开发

Signed-off-by: tangshizhe <48740614+tangshizhe@users.noreply.github.com>
tangshizhe 4 сар өмнө
parent
commit
43f5a79836

+ 2 - 1
apps/bigmember_pc/package.json

@@ -16,10 +16,10 @@
     "@jianyu/easy-inject-qiankun": "^0.1.11",
     "@jianyu/icon": "^0.1.7",
     "@jianyu/reset.css": "~0.1.1",
-    "@jy/vue-anti": "workspace:^",
     "@jy/data-models": "workspace:^",
     "@jy/pc-ui": "workspace:^",
     "@jy/util": "workspace:^",
+    "@jy/vue-anti": "workspace:^",
     "@sentry/vue": "^7.64.0",
     "dayjs": "^1.11.7",
     "echarts": "4.8.0",
@@ -31,6 +31,7 @@
     "qs": "^6.11.2",
     "svga": "^2.0.6",
     "v-charts": "1.19.0",
+    "vue-clipboard2": "^0.3.3",
     "vue-cookies": "^1.7.4",
     "vue-meta-info": "^0.1.7",
     "vuex": "^3.6.2"

BIN
apps/bigmember_pc/src/assets/images/icon/postSet.png


BIN
apps/bigmember_pc/src/assets/images/tell-example.png


+ 63 - 38
apps/bigmember_pc/src/components/coupon/BuySubmit.vue

@@ -3,22 +3,34 @@
     <div class="price-preview">
       <slot name="preview">
         <div class="preview-item total">
-          <div class="p-label">商品总价:</div>
-          <div class="p-value">&yen; {{ calcTotal }}</div>
+          <div class="p-label">
+            商品总价:
+          </div>
+          <div class="p-value">
+            &yen; {{ calcTotal }}
+          </div>
         </div>
-        <div class="preview-item discount" v-if="productionDiscount">
-          <div class="p-label">优惠金额:</div>
-          <div class="p-value">-&yen; {{ calcDiscount }}</div>
+        <div v-if="productionDiscount" class="preview-item discount">
+          <div class="p-label">
+            优惠金额:
+          </div>
+          <div class="p-value">
+            -&yen; {{ calcDiscount }}
+          </div>
         </div>
         <div class="preview-item pay">
-          <div class="p-label">实付金额:</div>
-          <div class="p-value">&yen; {{ calcPay }}</div>
+          <div class="p-label">
+            实付金额:
+          </div>
+          <div class="p-value">
+            &yen; {{ calcPay }}
+          </div>
         </div>
       </slot>
     </div>
     <div class="price-buy-info-group">
       <div>
-        <slot name="buy-tip-group"></slot>
+        <slot name="buy-tip-group" />
       </div>
       <div>
         <div class="price-agreement">
@@ -26,25 +38,30 @@
             <span>已阅读并同意</span>
             <div class="links">
               <el-link
-                type="primary"
                 v-for="(link, index) in agreementLinks"
                 :key="index"
+                type="primary"
                 target="_black"
                 :underline="linkUnderline"
                 :href="link.url"
-                >{{ link.label }}</el-link
               >
+                {{ link.label }}
+              </el-link>
             </div>
           </el-checkbox>
         </div>
         <div class="price-submit-container">
+          <div class="submit-button-tip-text">
+            支持送好友超级订阅,快快购买后送给好友吧!
+          </div>
           <el-button
+            v-show="plainButtonText"
             plain
             class="submit-button preview-button"
             @click="onCancel"
-            v-show="plainButtonText"
-            >{{ plainButtonText }}</el-button
           >
+            {{ plainButtonText }}
+          </el-button>
           <el-button
             type="primary"
             class="submit-button price-submit"
@@ -52,46 +69,48 @@
             :loading="loading"
             @click="buySubmit"
           >
-            <div class="confirm-button-text">{{ submitText }}</div>
+            <div class="confirm-button-text">
+              {{ submitText }}
+            </div>
             <!-- <div class="confirm-button-tip-text" v-if="submitTipText">{{submitTipText}}</div> -->
           </el-button>
         </div>
-        <div class="confirm-button-tip-text in-page" v-if="submitTipText">
+        <div v-if="submitTipText" class="confirm-button-tip-text in-page">
           完成支付后可在【我的订单】中开电子发票
         </div>
       </div>
     </div>
     <BuySubmitSticky
-      v-model="agreement"
       v-if="useStickyBar"
-      :linkUnderline="linkUnderline"
-      :confirmButtonDisabled="confirmButtonDisabled"
-      :productionTotal="calcTotal"
-      :productionPay="calcPay"
-      :plainButtonText="plainButtonText"
-      :agreementLinks="agreementLinks"
+      v-model="agreement"
+      :link-underline="linkUnderline"
+      :confirm-button-disabled="confirmButtonDisabled"
+      :production-total="calcTotal"
+      :production-pay="calcPay"
+      :plain-button-text="plainButtonText"
+      :agreement-links="agreementLinks"
       :submit-text="submitText"
-      :submitTipText="submitTipText"
+      :submit-tip-text="submitTipText"
       :loading="loading"
-      :basicSelector="basicSelector"
-      :alwaysShowSticky= "alwaysShowSticky"
+      :basic-selector="basicSelector"
+      :always-show-sticky="alwaysShowSticky"
       @cancel="onCancel"
       @submit="buySubmit"
     >
       <template #sticky-footer-tip>
-        <slot name="sticky-footer-tip"></slot>
+        <slot name="sticky-footer-tip" />
       </template>
     </BuySubmitSticky>
   </div>
 </template>
 
 <script>
-import { Checkbox, Link, Button } from 'element-ui'
+import { Button, Checkbox, Link } from 'element-ui'
 import { formatPrice } from '@/utils/'
 import BuySubmitSticky from '@/components/coupon/BuySubmitSticky.vue'
 
 export default {
-  name: 'buy-submit',
+  name: 'BuySubmit',
   components: {
     [Checkbox.name]: Checkbox,
     [Link.name]: Link,
@@ -152,6 +171,17 @@ export default {
       default: '.sticky-basic'
     }
   },
+  data() {
+    return {
+      agreementLinks: [
+        {
+          label: '《剑鱼标讯线上购买与服务条款》',
+          url: '/front/staticPage/serviceterms.html'
+        }
+      ],
+      agreement: false
+    }
+  },
   computed: {
     calcTotal() {
       return this.useFormatPrice
@@ -173,17 +203,6 @@ export default {
       return !state
     }
   },
-  data() {
-    return {
-      agreementLinks: [
-        {
-          label: '《剑鱼标讯线上购买与服务条款》',
-          url: '/front/staticPage/serviceterms.html'
-        }
-      ],
-      agreement: false
-    }
-  },
   methods: {
     formatPrice,
     onCancel() {
@@ -266,6 +285,12 @@ $main: #2cb7ca;
     display: flex;
     align-items: center;
     justify-content: flex-end;
+    .submit-button-tip-text {
+      margin-right: 6px;
+      line-height: 24px;
+      font-size: 14px;
+      color: #2ABED1;
+    }
     .submit-button {
       display: flex;
       align-items: center;

+ 64 - 25
apps/bigmember_pc/src/components/coupon/BuySubmitSticky.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="buy-submit-sticky sticky-footer">
     <div class="sticky-footer-tip-container">
-      <slot name="sticky-footer-tip"></slot>
+      <slot name="sticky-footer-tip" />
     </div>
     <div class="sticky-content flex-r-c v-w1200">
       <div class="price-agreement">
@@ -9,37 +9,54 @@
           <span>已阅读并同意</span>
           <div class="links">
             <el-link
-              type="primary"
               v-for="(link, index) in agreementLinks"
               :key="index"
+              type="primary"
               target="_black"
               :underline="linkUnderline"
               :href="link.url"
-              >{{ link.label }}</el-link
             >
+              {{ link.label }}
+            </el-link>
           </div>
         </el-checkbox>
       </div>
       <div class="price-preview flex-r-c">
         <slot name="preview">
-          <div class="preview-item total">
-            <div class="p-label">商品总价:</div>
-            <div class="p-value">&yen; {{ productionTotal }}</div>
+          <div class="preview-item-top">
+            <div class="preview-item total">
+              <div class="p-label">
+                商品总价:
+              </div>
+              <div class="p-value">
+                &yen; {{ productionTotal }}
+              </div>
+            </div>
+            <div class="preview-item pay">
+              <div class="p-label">
+                实付金额:
+              </div>
+              <div class="p-value">
+                &yen; {{ productionPay }}
+              </div>
+            </div>
           </div>
-          <div class="preview-item pay">
-            <div class="p-label">实付金额:</div>
-            <div class="p-value">&yen; {{ productionPay }}</div>
+          <div class="preview-item-bottom">
+            <div class="preview-item-tip-text">
+              支持送好友超级订阅,快快购买后送给好友吧!
+            </div>
           </div>
         </slot>
       </div>
       <div class="price-submit-container">
         <el-button
+          v-show="plainButtonText"
           plain
           class="submit-button preview-button"
           @click="onCancel"
-          v-show="plainButtonText"
-          >{{ plainButtonText }}</el-button
         >
+          {{ plainButtonText }}
+        </el-button>
         <el-button
           type="primary"
           class="submit-button price-submit"
@@ -48,8 +65,10 @@
           @click="buySubmit"
         >
           <div class="button-content">
-            <div class="confirm-button-text">{{ submitText }}</div>
-            <div class="confirm-button-tip-text" v-if="submitTipText">
+            <div class="confirm-button-text">
+              {{ submitText }}
+            </div>
+            <div v-if="submitTipText" class="confirm-button-tip-text">
               {{ submitTipText }}
             </div>
           </div>
@@ -60,11 +79,11 @@
 </template>
 
 <script>
-import { Checkbox, Link, Button } from 'element-ui'
+import { Button, Checkbox, Link } from 'element-ui'
 import { debounce, throttle } from 'lodash'
 
 export default {
-  name: 'buy-submit-sticky',
+  name: 'BuySubmitSticky',
   components: {
     [Checkbox.name]: Checkbox,
     [Link.name]: Link,
@@ -167,7 +186,7 @@ export default {
       }
     }, 50),
     appendDomToContainer(el, selector) {
-      var container
+      let container
       if (selector) {
         container = this.$root.$el.querySelector(selector) || this.$root.$el
       }
@@ -177,7 +196,7 @@ export default {
       container.appendChild(el)
     },
     removeDomFromContainer(el, selector) {
-      var container
+      let container
       if (selector) {
         container = this.$root.$el.querySelector(selector)
       }
@@ -186,13 +205,15 @@ export default {
       }
       try {
         container.removeChild(el)
-      } catch (error) {
+      }
+      catch (error) {
         // console.log(error)
       }
     },
     // 是否某个dom有部分离开当前屏
     isDOMLeave(el) {
-      if (!el) return
+      if (!el)
+        return
       const x = 64 // 头部偏移
       const offset = el.getBoundingClientRect()
       const offsetTop = offset.top
@@ -203,7 +224,8 @@ export default {
       let leave = false
       if (offsetTop - x < 0) {
         leave = true
-      } else {
+      }
+      else {
         // window.innerHeight 视口高度
         if (offsetBottom > window.innerHeight) {
           leave = true
@@ -213,7 +235,8 @@ export default {
     },
     // 是否在el的一部分在可视区域
     isInViewport(el) {
-      if (!el) return
+      if (!el)
+        return
       const offset = el.getBoundingClientRect()
       const x = 64 // 头部偏移
       const offsetTop = offset.top + x
@@ -230,7 +253,8 @@ export default {
       const mainFooter = $(this.basicSelector)
       const stickyFooter = $(this.$el)
 
-      if (!mainFooter.length) return
+      if (!mainFooter.length)
+        return
 
       const show = this.alwaysShowSticky || !this.isInViewport(mainFooter[0])
       if (show) {
@@ -246,11 +270,13 @@ export default {
         // bottom出现在视口
         const bottom = window.innerHeight - ob.top
         if (bottom > 0 && ob.top !== 0) {
-          $(this.$el).css({ bottom: parseInt(bottom) })
-        } else {
+          $(this.$el).css({ bottom: Number.parseInt(bottom) })
+        }
+        else {
           $(this.$el).css({ bottom: 0 })
         }
-      } else {
+      }
+      else {
         stickyFooter.hide()
       }
     }, 300),
@@ -293,9 +319,22 @@ $color_main: #2cb7ca;
     padding: 12px 0;
   }
   .price-preview {
+    display: flex;
+    flex-direction: column;
     flex: 1;
     justify-content: flex-end;
     padding: 0 22px;
+    .preview-item-top {
+      display: flex;
+      justify-content: flex-end;
+      line-height: 32px;
+    }
+    .preview-item-bottom {
+      text-align: right;
+      line-height: 24px;
+      font-size: 14px;
+      color: #2ABED1;
+    }
     .preview-item {
       display: flex;
       align-items: center;

+ 5 - 5
apps/bigmember_pc/src/components/dialog/Dialog.vue

@@ -1,5 +1,6 @@
 <template>
   <el-dialog
+    v-component-change-mount="{ selector: comMount }"
     class="custom-dialog"
     :custom-class="customClass"
     v-bind="$props"
@@ -10,14 +11,13 @@
     :destroy-on-close="destroyOnClose"
     :before-close="beforeClose"
     @update:visible="update"
-    v-component-change-mount="{ selector: comMount }"
     @open="$emit('open')"
     @opened="$emit('opened')"
     @close="$emit('close')"
     @closed="$emit('closed')"
   >
-    <slot name="default"></slot>
-    <span slot="footer" v-if="showFooter" class="dialog-footer">
+    <slot name="default" />
+    <span v-if="showFooter" slot="footer" class="dialog-footer">
       <slot name="footer">
         <button class="action-button cancel" @click="onClickCancel">
           取消
@@ -35,7 +35,7 @@
 </template>
 
 <script>
-import { Dialog, Button } from 'element-ui'
+import { Button, Dialog } from 'element-ui'
 
 export default {
   name: 'CustomDialog',
@@ -66,7 +66,7 @@ export default {
       type: String,
       default: '30%'
     },
-    'show-close': {
+    showClose: {
       type: Boolean,
       default: false
     },

+ 154 - 0
apps/bigmember_pc/src/components/dialog/GiftSubmitDialog.vue

@@ -0,0 +1,154 @@
+<template>
+  <CustomDialog
+    width="600px"
+    top="18vh"
+    :title="title"
+    class="gift-submit-dialog"
+    :visible="visible"
+    @update:visible="update"
+  >
+    <div class="gift-submit-header">
+      <div class="gift-submit-header__item">
+        <span>订阅区域:</span>
+        <span>4个省</span>
+      </div>
+      <div class="gift-submit-header__item">
+        <span>可赠送时长(取整):</span>
+        <span>18个月</span>
+      </div>
+    </div>
+    <div class="gift-submit-body">
+      <div class="gift-person-list-button">
+        <span>人员列表</span>
+        <span class="gift-person-list-button__icon">+</span>
+      </div>
+      <div class="gift-person-tip">
+        说明:如手机号尚未注册剑鱼,赠送其超级订阅后,平台会自动帮其按照对应手机号注册。
+      </div>
+      <div class="gift-person-list">
+        <div class="gift-person-list__item">
+          <div class="gift-person-info">
+            <span>朋友手机号</span>
+            <el-input v-model="phone" class="custom-long-input" placeholder="请输入手机号" />
+          </div>
+          <div class="gift-person-info time">
+            <span>赠予时长</span>
+            <el-input v-model="monthnum" class="custom-long-input" placeholder="请输入整数" />
+            <span>个月</span>
+          </div>
+        </div>
+      </div>
+    </div>
+  </CustomDialog>
+</template>
+
+<script>
+import CustomDialog from '@/components/dialog/Dialog.vue'
+
+export default {
+  name: 'GiftSubmitDialog',
+  components: {
+    CustomDialog
+  },
+  props: {
+    visible: Boolean,
+    title: {
+      type: String,
+      default: '送给朋友'
+    },
+  },
+  data() {
+    return {
+    }
+  },
+  methods: {
+    update(e) {}
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  .gift-submit-dialog {
+    ::v-deep {
+      .el-dialog__header {
+        text-align: left;
+        .el-dialog__title {
+          padding-left: 10px;
+          line-height: 28px;
+        }
+        &::after {
+          content: '';
+          position: absolute;
+          left: 20px;
+          top: 26px;
+          display: inline-block;
+          width: 2px;
+          height: 16px;
+          background: #2ABED1;
+        }
+      }
+      .el-dialog__body {
+        padding: 0 20px 10px;
+        .gift-submit-header {
+          display: flex;
+          align-items: center;
+          padding-bottom: 10px;
+          border-bottom: 1px solid #2ABED1;
+          &__item {
+            margin-right: 24px;
+          }
+        }
+        .gift-submit-body {
+          padding: 10px 0;
+          .gift-person-list-button {
+            display: flex;
+            align-items: center;
+            font-size: 16px;
+            line-height: 24px;
+            color: #1D1D1D;
+          }
+          .gift-person-list-button__icon {
+            display: flex;
+            justify-content: center;
+            margin-left: 10px;
+            width: 20px;
+            height: 20px;
+            line-height: 18px;
+            border-radius: 50%;
+            background-color: #2ABED1;
+            color: #fff;
+            font-size: 18px;
+            cursor: pointer;
+          }
+          .gift-person-tip {
+            margin: 10px 0;
+            font-size: 14px;
+            line-height: 22px;
+            color: #2ABED1;
+          }
+          .gift-person-list {
+            max-height: 200px;
+            padding: 10px;
+            border: 1px solid #ECECEC;
+            border-radius: 8px;
+            .gift-person-list__item {
+              display: flex;
+              justify-content: space-between;
+              align-items: center;
+              padding: 10px 20px;
+              border-radius: 8px;
+              background: linear-gradient(to bottom, #F6F6F6, #fff);
+            }
+            .gift-person-info {
+              font-size: 14px;
+              color: #1D1D1D;
+            }
+            .custom-long-input {
+              margin-top: 8px;
+            }
+          }
+        }
+      }
+    }
+  }
+</style>

+ 166 - 0
apps/bigmember_pc/src/components/dialog/NotifyFriendsDialog.vue

@@ -0,0 +1,166 @@
+<template>
+  <CustomDialog
+    v-bind="$props"
+    width="564px"
+    top="18vh"
+    :title="title"
+    class="notify-friends-dialog"
+    :visible="visible"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    @update:visible="update"
+  >
+    <div class="methods-content">
+      <div class="methods-item">
+        <div class="methods-item-title">
+          方法1:复制链接后发给微信好友
+        </div>
+        <div class="methods-item-content">
+          <div class="methods-item-content-input">
+            <el-input v-model="linkText" :readonly="true" placeholder="请输入内容" />
+            <el-button class="copy-btn" type="primary" @click="copyLinkEvent">
+              复制链接
+            </el-button>
+          </div>
+        </div>
+      </div>
+      <div class="methods-item">
+        <div class="methods-item-title">
+          方法2:下载海报发给微信好友
+        </div>
+        <div class="methods-item-content">
+          <img src="@/assets/images/tell-example.png" alt="">
+        </div>
+      </div>
+    </div>
+    <template #footer>
+      <slot name="footer">
+        <button
+          class="action-button confirm"
+          @click="onClickConfirm"
+        >
+          我知道了
+        </button>
+      </slot>
+    </template>
+  </CustomDialog>
+</template>
+
+<script>
+import { Button, Input } from 'element-ui'
+import CustomDialog from '@/components/dialog/Dialog.vue'
+
+export default {
+  name: 'NotifyFriendsDialog',
+  components: {
+    [Button.name]: Button,
+    [Input.name]: Input,
+    CustomDialog
+  },
+  props: {
+    visible: Boolean,
+    title: {
+      type: String,
+      default: '告知好友'
+    },
+    telllink: {
+      type: String,
+      default: 'https://www.jianyu360.cn/swoswoswoswo...'
+    }
+  },
+  data() {
+    return {
+      linkText: ''
+    }
+  },
+  created() {
+    this.linkText = this.telllink
+  },
+  methods: {
+    update(e) {
+      this.$emit('update:visible', e)
+    },
+    onClickConfirm() {
+      this.update(false)
+    },
+    copyLinkEvent() {
+      this.$copyText(this.linkText).then(() => {
+        this.$message.success('复制成功')
+      })
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.notify-friends-dialog {
+  ::v-deep {
+    .el-dialog__header {
+      padding: 32px 32px 0;
+    }
+    .el-dialog__body {
+      padding: 0 32px 32px;
+    }
+    .el-dialog__footer {
+      padding: 0 0 32px;
+    }
+    .dialog-footer {
+      justify-content: center;
+      .action-button {
+        flex: none;
+        width: 132px;
+        height: 36px;
+        border-radius: 6px;
+        font-size: 16px;
+        line-height: 24px;
+        color: #FFFFFF;
+        background-color: #2ABED1;
+      }
+    }
+  }
+  .methods-content {
+    overflow: hidden;
+  }
+  .methods-item {
+    margin-top: 20px;
+  }
+  .methods-item-title {
+    margin-bottom: 12px;
+    line-height: 22px;
+    font-size: 14px;
+    color: #1D1D1D;
+  }
+  .methods-item-content {
+    .methods-item-content-input {
+      position: relative;
+      .el-input {
+        padding: 6px 20px;
+        border-radius: 30px;
+        border: 1px solid #E3E4E5;
+        line-height: 22px;
+        font-size: 14px;
+        color: #1D1D1D;
+        ::v-deep {
+          .el-input__inner {
+            border: none;
+            line-height: 22px;
+            height: 22px;
+            padding: 0;
+          }
+        }
+      }
+      .copy-btn {
+        position: absolute;
+        right: 0;
+        padding: 0;
+        width: 140px;
+        height: 36px;
+        border-radius: 21px;
+        font-size: 16px;
+        line-height: 24px;
+        color: #FFFFFF;
+      }
+    }
+  }
+}
+</style>

+ 7 - 5
apps/bigmember_pc/src/main.js

@@ -1,16 +1,13 @@
 // import '@jianyu/easy-inject-qiankun/src/pre-mount.js'
 import 'virtual:uno.css'
 import Vue from 'vue'
-import App from './App.vue'
-import store from './store/'
-import router from './router/'
 import '@jianyu/reset.css/reset-pc.scss'
-import ElementUI from 'element-ui'
+import ElementUI, { Loading, Message, MessageBox } from 'element-ui'
 import 'element-ui/lib/theme-chalk/index.css'
 import { easySubAppRegister } from '@jianyu/easy-inject-qiankun'
 import { fixGetComputedStyle } from '@jianyu/easy-fix-sub-app/lib/getComputedStyle.js'
 import VueCookies from 'vue-cookies'
-import { Loading, Message, MessageBox } from 'element-ui'
+
 import echarts from 'echarts'
 import './utils/jq-help'
 import ModalHelper from '@/utils/modelHlper'
@@ -21,6 +18,10 @@ import '@/utils/directive'
 import '@/utils/prototype'
 import MetaInfo from 'vue-meta-info'
 import JyIcon from '@jianyu/icon' // 需要单独引入icon/index.css
+import VueClipboard from 'vue-clipboard2'
+import App from './App.vue'
+import router from './router/'
+import store from './store/'
 import { initSentry } from './sentry'
 
 Vue.use(VueCookies)
@@ -28,6 +29,7 @@ Vue.use(Loading.directive)
 Vue.use(Toast)
 Vue.use(ElementUI)
 Vue.use(MetaInfo).use(JyIcon)
+Vue.use(VueClipboard)
 
 // # 修复v-charts 不适配 vue2.7x https://github.com/ElemeFE/v-charts/issues/934
 Vue._watchers = Vue.prototype._watchers = []

+ 23 - 13
apps/bigmember_pc/src/router/router-interceptors.js

@@ -18,6 +18,7 @@ const powerCheckPathWhiteRegList = [
   /pdf/,
   /doc\/api/,
   /data_pack/,
+  /giftrecord/
 ]
 // 权限控制白名单-路由名
 const powerCheckWhiteList = [
@@ -61,7 +62,8 @@ const powerCheckWhiteList = [
 ]
 
 const regListCheck = function (regList, path) {
-  if (!Array.isArray(regList)) return false
+  if (!Array.isArray(regList))
+    return false
   return regList.some((reg) => {
     return reg.test(path)
   })
@@ -82,20 +84,21 @@ router.beforeEach(async (to, from, next) => {
     // 调用商机管理权限接口 查用户有无画像分析系统权限 有则执行下一步 无则返回首页
     if (entNiche.privatedata) {
       next()
-    } else {
+    }
+    else {
       location.href = location.origin
     }
     return
   }
   if (
-    powerCheckWhiteList.includes(to.name) ||
-    regListCheck(powerCheckPathWhiteRegList, to.path)
+    powerCheckWhiteList.includes(to.name)
+    || regListCheck(powerCheckPathWhiteRegList, to.path)
   ) {
     // 权限列表:https://app-jytest.jydev.jianyu360.com/jyapp/big-member/js/main_root_data.js
     // 4.企业全景分析
     // 13.企业中标动态
-    const hasEntPortPower =
-      info.memberStatus > 0 && (power.includes(4) || power.includes(13))
+    const hasEntPortPower
+      = info.memberStatus > 0 && (power.includes(4) || power.includes(13))
     if (hasEntPortPower) {
       // 大会员有画像权限用户,访问超级订阅画像,则重定向到大会员画像
       if (to.name === 'ent_ser_portrait') {
@@ -108,10 +111,12 @@ router.beforeEach(async (to, from, next) => {
             resource: to.query.resource
           }
         })
-      } else {
+      }
+      else {
         next()
       }
-    } else {
+    }
+    else {
       if (to.name === 'ent_portrait') {
         // 其他无画像权限用户,访问大会员画像,则重定向到超级订阅画像
         next({
@@ -121,20 +126,24 @@ router.beforeEach(async (to, from, next) => {
             ...to.query
           }
         })
-      } else {
+      }
+      else {
         next()
       }
     }
-  } else {
+  }
+  else {
     let href = '/big/page/index'
     const { pass, anchor } = powerCheck(info, power, to, from)
     if (pass) {
       next()
-    } else {
+    }
+    else {
       // TODO 可优化 临时判断是否旧项目大会员支付路由,skip
       if (to.fullPath.startsWith('/front/member/memberDetail')) {
         // skip
-      } else {
+      }
+      else {
         if (anchor) {
           href = `${href}#${anchor}`
         }
@@ -152,7 +161,8 @@ router.beforeEach((to, from, next) => {
     // 标题设置
     if (to?.meta?.title) {
       document.title = to.meta.title
-    } else {
+    }
+    else {
       document.title = '剑鱼标讯'
     }
   }

+ 6 - 0
apps/bigmember_pc/src/router/svip-routers.js

@@ -41,5 +41,11 @@ export default [
     path: '/free/terms/activity',
     name: 'activityTerms',
     component: () => import('@/views/vipsubscribe/terms/activity.vue')
+  },
+  // 超级订阅赠送好友记录-我赠送的
+  {
+    path: '/giftrecord/index',
+    name: 'gift-record-index',
+    component: () => import('@/views/gift-record/index.vue')
   }
 ]

+ 105 - 0
apps/bigmember_pc/src/views/gift-record/components/MyGiftRecord.vue

@@ -0,0 +1,105 @@
+<template>
+  <div class="my-gift-record">
+    <div class="gift-time">
+      赠送时间:2019.11.01 11:42
+    </div>
+    <div class="gift-record-list">
+      <div class="gift-item">
+        <div class="gift-item-left">
+          <span class="gift-label">手机号:</span>
+          <span class="gift-value">138****0000</span>
+          <span class="gift-split">|</span>
+          <span class="gift-label">时长:</span>
+          <span class="gift-value">10分钟</span>
+        </div>
+        <div class="gift-item-right" @click="$emit('click', $event)">
+          <span>告知朋友</span>
+          <span class="icon-post-set" />
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+
+// const store = useStore()
+// const router = useRouter()
+// const isLogin = computed(() => {
+//   return store.getters['user/loginFlag']
+// })
+// function goLogin() {
+//   router.push({
+//     name: 'login'
+//   })
+// }
+// onMounted(() => {
+//   if (!isLogin.value) {
+//     goLogin()
+//   }
+// })
+</script>
+
+<style lang="scss">
+.my-gift-record {
+  max-width: 359px;
+  padding: 8px 12px;
+  background-color: #FFFFFF;
+  border-radius: 8px;
+  border: 1px solid #ECECEC;
+  box-shadow: 0 0 28px 0 rgba(0, 0, 0, 0.08);
+  .gift-time {
+    margin-bottom: 4px;
+    font-size: 12px;
+    line-height: 20px;
+    color: #5F5E64;
+  }
+  .gift-record-list {
+    display: flex;
+    flex-direction: column;
+    .gift-item {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-top: 4px;
+      .gift-item-left {
+        display: flex;
+        align-items: center;
+        .gift-label {
+          font-size: 12px;
+          line-height: 20px;
+          color: #5F5E64;
+        }
+        .gift-value {
+          font-size: 14px;
+          line-height: 24px;
+          color: #171826;
+        }
+        .gift-split {
+          margin: 0 8px;
+          width: 3px;
+          height: 20px;
+          color: #C0C4CC;
+        }
+      }
+      .gift-item-right {
+        display: flex;
+        align-items: center;
+        font-size: 14px;
+        line-height: 20px;
+        color: #2ABED1;
+        cursor: pointer;
+        .icon-post-set {
+          display: block;
+          margin-left: 4px;
+          width: 16px;
+          height: 16px;
+          background: url(@/assets/images/icon/postset.png) no-repeat;
+          background-size: 16px 16px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 67 - 0
apps/bigmember_pc/src/views/gift-record/components/MyReceiveRecord.vue

@@ -0,0 +1,67 @@
+<template>
+  <div class="my-receive-record">
+    <div class="receive-time">
+      赠送时间:2019.11.01 11:42
+    </div>
+    <div class="receive-item">
+      <span class="receive-label">来自好友:</span>
+      <span class="receive-value">138****0000</span>
+    </div>
+    <div class="receive-item">
+      <span class="receive-label">得赠市场:</span>
+      <span class="receive-value">3个月</span>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+
+// const store = useStore()
+// const router = useRouter()
+// const isLogin = computed(() => {
+//   return store.getters['user/loginFlag']
+// })
+// function goLogin() {
+//   router.push({
+//     name: 'login'
+//   })
+// }
+// onMounted(() => {
+//   if (!isLogin.value) {
+//     goLogin()
+//   }
+// })
+</script>
+
+<style lang="scss">
+.my-receive-record {
+  max-width: 359px;
+  padding: 8px 12px;
+  background-color: #FFFFFF;
+  border-radius: 8px;
+  border: 1px solid #ECECEC;
+  box-shadow: 0 0 28px 0 rgba(0, 0, 0, 0.08);
+  .receive-time {
+    margin-bottom: 4px;
+    font-size: 12px;
+    line-height: 20px;
+    color: #5F5E64;
+  }
+  .receive-item {
+    display: flex;
+    align-items: center;
+    margin-top: 4px;
+    .receive-label {
+      font-size: 12px;
+      line-height: 20px;
+      color: #5F5E64;
+    }
+    .receive-value {
+      font-size: 14px;
+      line-height: 24px;
+      color: #171826;
+    }
+  }
+}
+</style>

+ 130 - 0
apps/bigmember_pc/src/views/gift-record/index.vue

@@ -0,0 +1,130 @@
+<template>
+  <div class="gift-record-index">
+    <div class="gift-record-index__header">
+      <span>超级订阅赠送好友记录</span>
+    </div>
+    <div class="gift-record-index__content">
+      <el-tabs v-model="activeName" @tab-click="handleClick">
+        <el-tab-pane label="我赠送的" name="gift">
+          <div v-if="!giftList.length">
+            <!-- <MyGiftRecord
+              v-for="(item, index) in giftList"
+              :key="index"
+              :item="item"
+              @click="onClickShare(item)"
+            /> -->
+            <MyGiftRecord
+              @click="onClickShare"
+            />
+            <NotifyFriendsDialog :visible="showNotifyFriendsDialog" @update:visible="showNotifyFriendsDialog = false" />
+          </div>
+          <Empty v-else class="record-container">
+            <div>{{ giftEmptyInfo.defaultText }}</div>
+            <button slot="button" class="btn-primary">
+              {{ giftEmptyInfo.buttonText }}
+            </button>
+          </Empty>
+        </el-tab-pane>
+        <el-tab-pane label="我接收的" name="receive">
+          <div v-if="receiveList.length">
+            <MyReceiveRecord />
+          </div>
+          <Empty v-else class="record-container">
+            <div>{{ receiveEmptyInfo.defaultText }}</div>
+          </Empty>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { onMounted, reactive, ref } from 'vue'
+import MyGiftRecord from './components/MyGiftRecord.vue'
+import MyReceiveRecord from './components/MyReceiveRecord.vue'
+import Empty from '@/components/common/Empty.vue'
+import NotifyFriendsDialog from '@/components/dialog/NotifyFriendsDialog.vue'
+
+const activeName = ref('gift')
+const showNotifyFriendsDialog = ref(false)
+const giftList = ref([])
+const receiveList = ref([])
+const giftEmptyInfo = reactive({
+  defaultText: '您当前不是超级订阅用户,需购买后赠送好友。',
+  buttonText: '去购买'
+})
+const receiveEmptyInfo = reactive({
+  defaultText: '暂无好友赠送记录'
+})
+function handleClick(tab, event) {
+  console.log(tab, event)
+}
+
+function onClickShare() {
+  showNotifyFriendsDialog.value = true
+}
+
+onMounted(() => {
+  console.log('onMounted')
+})
+</script>
+
+<style lang="scss" scoped>
+  .gift-record-index {
+    padding: 24px;
+    .gift-record-index__header {
+      line-height: 36px;
+      font-size: 24px;
+    }
+    .gift-record-index__content {
+      margin-top: 24px;
+      background: #fff;
+      border-radius: 8px;
+      ::v-deep {
+        .el-tabs__header {
+          margin-bottom: 0;
+        }
+        .el-tabs__nav-scroll {
+          padding-left: 44px;
+          height: 50px;
+          .el-tabs__item {
+            height: 100%;
+            line-height: 50px;
+            font-size: 16px;
+            color: #686868;
+            &.is-active {
+              color: #2ABED1;
+            }
+          }
+          .el-tabs__nav {
+            height: 100%;
+          }
+        }
+        .el-tabs__nav-wrap::after{
+          height: 1px;
+          background-color: #ECECEC;
+        }
+        .el-tabs__content {
+          padding: 20px 32px;
+        }
+      }
+
+    }
+    .record-container {
+      ::v-deep {
+        .empty-main{
+          margin-top: 0;
+        }
+      }
+      .btn-primary {
+        margin-top: 40px;
+        width: 180px;
+        height: 46px;
+        border-radius: 8px;
+        background: #2ABED1;
+        color: #fff;
+        font-size: 16px;
+      }
+    }
+  }
+</style>

+ 118 - 57
apps/bigmember_pc/src/views/workspace/components/AccountInfo.vue

@@ -2,97 +2,112 @@
   <section class="user-info-card">
     <h4 class="user-info-title">
       <span>
-        <span class="user-info-title-fireworks"></span>
-        <span class="user-info-title-text highlight-text"
-        >欢迎您!<i class="user-nickname">{{ accountInfo.nickName }}</i></span>
+        <span class="user-info-title-fireworks" />
+        <span class="user-info-title-text highlight-text">欢迎您!<i class="user-nickname">{{ accountInfo.nickName }}</i></span>
       </span>
-      <span class="user-info-icon" v-if="accountInfo.vipType && (accountInfo.vipType === '超级订阅'  || accountInfo.vipType.includes('大会员'))">
-        <i :class="accountInfo.vipType === '超级订阅' ? 'vip-icon': 'bigmember-icon'"></i>
+      <span v-if="accountInfo.vipType && (accountInfo.vipType === '超级订阅' || accountInfo.vipType.includes('大会员'))" class="user-info-icon">
+        <i :class="accountInfo.vipType === '超级订阅' ? 'vip-icon' : 'bigmember-icon'" />
       </span>
     </h4>
     <p class="user-info-line user-info-type">
       <span class="user-info-line-label">账号类型:</span>
       <span class="user-info-line-value">{{ accountInfo.vipType }}</span>
-      <span class="u-i-line-tip" v-if="accountInfo.vipType === '注册用户'">您尚未开通会员</span>
+      <span v-if="accountInfo.vipType === '注册用户'" class="u-i-line-tip">您尚未开通会员</span>
     </p>
     <div
-      class="user-info-line user-info-free bg-gold"
       v-if="accountInfo.vipType === '注册用户'"
+      class="user-info-line user-info-free bg-gold"
     >
       <p>
         <span>
-          <i class="vip-icon"> </i>
+          <i class="vip-icon" />
           <span>开通超级订阅</span>
         </span>
-        <span class="activity-span" v-if="attr.subVipActMsg">
-          <i class="limit-time-icon"></i>
-          <span>{{attr.subVipActMsg}}</span>
+        <span v-if="attr.subVipActMsg" class="activity-span">
+          <i class="limit-time-icon" />
+          <span>{{ attr.subVipActMsg }}</span>
         </span>
       </p>
       <p class="handle-p">
         <span>立享27+项专属权益</span>
         <span
           class="handle-btn"
-          @click="buyVip('buy')">
+          @click="buyVip('buy')"
+        >
           立即开通</span>
       </p>
     </div>
     <div
-      class="user-info-line user-info-module"
       v-else-if="accountInfo.vipType === '超级订阅'"
+      class="user-info-line user-info-module"
     >
       <div class="user-info-line-value value-box bg-gold">
         <p>到期时间:{{ accountInfo.vipEntTime }}</p>
-        <p class="handle-btn  m-t-6"
-           @click="renewVip()">
-          去续费<i class="iconfont icon-more"></i>
+        <p
+          class="handle-btn  m-t-6"
+          @click="renewVip()"
+        >
+          去续费<i class="iconfont icon-more" />
         </p>
       </div>
-      <div class="gap"></div>
-      <div  class="user-info-line-value value-box bg-gold">
+      <div class="gap" />
+      <div class="user-info-line-value value-box bg-gold">
         <p>购买区域:{{ attr.buyMsg }}</p>
-        <p class="handle-btn m-t-6"
-           @click="updateVip">
-          {{ attr.upgrade ? '去升级' : '升级咨询'}}
-          <i class="iconfont icon-more"></i>
+        <p
+          class="handle-btn m-t-6"
+          @click="updateVip"
+        >
+          {{ attr.upgrade ? '去升级' : '升级咨询' }}
+          <i class="iconfont icon-more" />
         </p>
       </div>
     </div>
     <div
-      class="user-info-line user-info-module"
       v-else-if="accountInfo.vipType === '省份订阅包'"
+      class="user-info-line user-info-module"
     >
       <div class="user-info-line-value value-box bg-blue">
         <p>到期时间:{{ accountInfo.vipEntTime }}</p>
-        <p class="handle-btn m-t-6"
-           @click="openCustomer">
-          去续费<i class="iconfont icon-more"></i>
+        <p
+          class="handle-btn m-t-6"
+          @click="openCustomer"
+        >
+          去续费<i class="iconfont icon-more" />
         </p>
       </div>
-      <div class="gap"></div>
-      <div  class="user-info-line-value value-box" :class="attr.upgrade ? 'bg-blue' : 'bg-gold'">
+      <div class="gap" />
+      <div class="user-info-line-value value-box" :class="attr.upgrade ? 'bg-blue' : 'bg-gold'">
         <p>购买区域:{{ attr.buyMsg }}</p>
-        <p class="handle-btn m-t-6"  @click="areaVipUpdate">
-          {{attr.upgrade ? '去升级' : '开通超级订阅'}}
-          <i class="iconfont icon-more"></i>
+        <p class="handle-btn m-t-6" @click="areaVipUpdate">
+          {{ attr.upgrade ? '去升级' : '开通超级订阅' }}
+          <i class="iconfont icon-more" />
         </p>
       </div>
     </div>
-<!--    大会员或者商机管理-->
-    <div class="user-info-line user-info-module" v-else>
+    <!--    大会员或者商机管理 -->
+    <div v-else class="user-info-line user-info-module">
       <div class="user-info-line-value value-box bigmember bg-black">
         <p>到期时间:{{ accountInfo.vipEntTime }}</p>
-        <p class="handle-btn  m-t-6"
-           @click="renewConsult">续费咨询
-          <i class="iconfont icon-more"></i>
+        <p
+          class="handle-btn  m-t-6"
+          @click="renewConsult"
+        >
+          续费咨询
+          <i class="iconfont icon-more" />
         </p>
       </div>
     </div>
+    <!-- 引导赠送好友超级订阅 -->
+    <div v-if="isShowGift" class="gift-tip">
+      <span>支持送好友超级订阅</span>
+      <span class="gift-link" @click="goGiftLink">送给朋友></span>
+    </div>
   </section>
 </template>
 
 <script>
 import { getUserAccountShow } from '@/api/modules/'
+
 export default {
   name: 'UserAccount',
   data() {
@@ -103,51 +118,86 @@ export default {
     }
   },
   computed: {
-    attr () {
+    attr() {
       return this.accountInfo.attr || {}
+    },
+    isShowGift() {
+      return this.accountInfo.vipType === '注册用户' || this.accountInfo.vipType === '超级订阅'
     }
   },
   mounted() {
     this.getAccount()
   },
   methods: {
+    goGiftLink() {
+      const vipTypeBool = this.accountInfo.vipType === '注册用户'
+      if (vipTypeBool) {
+        // 弹窗提醒购买超级订阅后赠送好友
+        this.$emit('showGiftDialog', 'buy')
+      }
+      else if (this.accountInfo.vipType === '超级订阅') {
+        const isOneMonthPassed = this.isOneMonthPassed(this.accountInfo.vipEntTime)
+        if (isOneMonthPassed) {
+          // 弹窗提醒超级订阅不满一个月续费后赠送好友
+          this.$emit('showGiftDialog', 'renew')
+        }
+        else {
+          // 满足条件,可以直接赠送好友,打开送给朋友弹窗
+          this.$emit('showGiftDialog', 'gift')
+          // 赠送好友后,重新获取用户信息
+          this.getAccount()
+        }
+      }
+    },
+    isOneMonthPassed(givenDateString) {
+      const givenDate = new Date(givenDateString).getTime()
+      let currentDate = new Date()
+      // 增加一个月
+      currentDate.setMonth(currentDate.getMonth() + 1)
+      currentDate = new Date(currentDate).getTime()
+      // 比较增加一个月后的当前日期和给定日期
+      return currentDate >= givenDate
+    },
     async getAccount() {
       const { data, error_code } = await getUserAccountShow()
-      if(error_code === 0 && data) {
-        const { nickname, list = []} = data
+      if (error_code === 0 && data) {
+        const { nickname, list = [] } = data
         const info = list[0] || {}
         this.accountInfo = {
           nickName: nickname,
           vipType: info.name,
-          vipEntTime:  info.endTime ? new Date(info.endTime * 1000 ).pattern('yyyy-MM-dd') : '',
+          vipEntTime: info.endTime ? new Date(info.endTime * 1000).pattern('yyyy-MM-dd') : '',
           attr: info.attr || {}
         }
       }
     },
-    buyVip (type) {
-      window.open('/swordfish/page_big_pc/free/svip/buy?type=' + type)
+    buyVip(type) {
+      window.open(`/swordfish/page_big_pc/free/svip/buy?type=${type}`)
     },
     // 超级订阅去续费,企业分配的需要跳转客服,自主购买的跳续费
-    renewVip () {
-      if(this.attr.renew) {
+    renewVip() {
+      if (this.attr.renew) {
         this.buyVip('renew')
-      } else {
+      }
+      else {
         this.openCustomer()
       }
     },
     // 升级超级订阅
-    updateVip () {
-      if(this.attr.upgrade) {
+    updateVip() {
+      if (this.attr.upgrade) {
         this.buyVip('upgrade')
-      } else {
+      }
+      else {
         this.openCustomer()
       }
     },
     // 省份订阅包升级
-    areaVipUpdate () {
-      if(this.attr.upgrade) {
+    areaVipUpdate() {
+      if (this.attr.upgrade) {
         this.openCustomer()
-      } else {
+      }
+      else {
         this.buyVip('buy')
       }
     },
@@ -155,18 +205,18 @@ export default {
     openCustomer() {
       this.contactCustomer(this)
     },
-    jumpPage (link) {
-      if(link) {
+    jumpPage(link) {
+      if (link) {
         window.open(link)
       }
     },
-    renewConsult () {
-      if(this.accountInfo.vipType === '商机管理') {
+    renewConsult() {
+      if (this.accountInfo.vipType === '商机管理') {
         this.openCustomer()
-      } else {
+      }
+      else {
         this.jumpPage(this.attr.pc)
       }
-
     }
   }
 }
@@ -308,6 +358,17 @@ export default {
       }
     }
   }
+  .gift-tip {
+    margin-top: 8px;
+    line-height: 22px;
+    font-size: 14px;
+    color: #1D1D1D;
+    .gift-link {
+      margin-left: 7px;
+      color: #FF3A20;
+      cursor: pointer;
+    }
+  }
   .bg-gold{
     background: linear-gradient(90deg,#FFECCE 0%, #FCD7B2 100%);
   }

+ 97 - 19
apps/bigmember_pc/src/views/workspace/dashboard.vue

@@ -1,49 +1,69 @@
 <template>
   <el-container class="workspace-dashboard">
     <el-main>
-      <CommonUse class="main-module"></CommonUse>
+      <CommonUse class="main-module" />
       <div
-        class="main-module card-list-module"
         v-for="(moduleList, floor) in mainModuleList"
         :key="floor"
+        class="main-module card-list-module"
       >
         <component
+          :is="name"
           v-for="name in moduleList"
           :key="name"
-          :is="name"
-        ></component>
+        />
       </div>
-      <MyEquityList></MyEquityList>
+      <MyEquityList />
       <!-- <div class="main-module card-list-module" v-if="dataReportShow">
         <DataReport></DataReport>
       </div> -->
       <BusinessProfile
         v-if="businessProfileShow"
         class="main-module"
-      ></BusinessProfile>
+      />
     </el-main>
     <el-aside width="369px">
-      <AccountInfo></AccountInfo>
-      <ChatList></ChatList>
-      <MessageTips class="aside-module"></MessageTips>
-      <AsideOthers class="aside-module"></AsideOthers>
+      <AccountInfo @showGiftDialog="showGiftDialog" />
+      <ChatList />
+      <MessageTips class="aside-module" />
+      <AsideOthers class="aside-module" />
     </el-aside>
     <ActivityDialog
-      @initNext="initNextDialog('checkUserShow')"
       ad="jy-pc-index-tap"
+      @initNext="initNextDialog('checkUserShow')"
     />
     <GuideIntroDialog />
     <CheckUserDialog v-if="dialog.checkUserShow" />
+    <GiftDialog
+      class="gift-tip-dialog"
+      :visible="showGift"
+      :close-click-modal="true"
+      title="温馨提示"
+      @close="showGift = false"
+    >
+      <p class="gift-tip-content">
+        {{ giftContent.giftTipText }}
+      </p>
+      <span slot="footer" class="dialog-footer">
+        <button
+          class="action-button confirm"
+          @click="onClickConfirm"
+        >
+          {{ giftContent.buttonText }}
+        </button>
+      </span>
+    </GiftDialog>
+    <GiftSubmitDialog :visible="showGiftSubmit" />
   </el-container>
 </template>
 
 <script>
 import { mapGetters } from 'vuex'
 import { chunk } from 'lodash'
-import { Container, Aside, Main } from 'element-ui'
+import { Aside, Container, Main } from 'element-ui'
+import { tryCallHooks } from '@jianyu/easy-inject-qiankun'
 import MessageTips from './components/MessageTips.vue'
 import CommonUse from './components/CommonUse.vue'
-import CheckUserDialog from '@/components/dialog/CheckUserDialog'
 import SubscribeList from './components/SubscribeList.vue'
 // import MyCollections from './components/MyCollections.vue'
 // import ProjectFollow from './components/ProjectFollow.vue'
@@ -51,19 +71,22 @@ import SubscribeList from './components/SubscribeList.vue'
 // import DataReport from './components/DataReport.vue'
 import AsideOthers from './components/AsideOthers.vue'
 // import ClaimList from './components/ClaimList.vue'
-import ActivityDialog from '@/components/ad/activity-dialog.vue'
-import GuideIntroDialog from '@/components/ad/guide-intro-dialog.vue'
 import AccountInfo from './components/AccountInfo.vue'
 import ChatList from './components/ChatList.vue'
 import BusinessToDo from './components/BusinessToDo.vue'
 import NewsList from './components/NewsList.vue'
 import AnalysisReport from './components/AnalysisReport.vue'
 import MyEquityList from './components/MyEquityList.vue'
-const BusinessProfile = () => import('./components/BusinessProfile.vue')
+import GiftDialog from '@/components/dialog/Dialog.vue'
+import GiftSubmitDialog from '@/components/dialog/GiftSubmitDialog.vue'
+import GuideIntroDialog from '@/components/ad/guide-intro-dialog.vue'
+import ActivityDialog from '@/components/ad/activity-dialog.vue'
+import CheckUserDialog from '@/components/dialog/CheckUserDialog'
 // const MyCustomer = () => import('./components/MyCustomer.vue')
 // const CustomerWatcher = () => import('./components/CustomerWatcher.vue')
 import { showFunctionGuide } from '@/api/modules/'
-import { tryCallHooks } from '@jianyu/easy-inject-qiankun'
+
+const BusinessProfile = () => import('./components/BusinessProfile.vue')
 export default {
   name: 'WorkspaceDashboard',
   components: {
@@ -72,6 +95,8 @@ export default {
     [Aside.name]: Aside,
     ActivityDialog,
     GuideIntroDialog,
+    GiftDialog,
+    GiftSubmitDialog,
     MessageTips,
     CommonUse,
     BusinessProfile,
@@ -97,7 +122,14 @@ export default {
       dialog: {
         checkUserShow: false
       },
-      showSunshineGuide: false
+      showSunshineGuide: false,
+      showGift: false,
+      showGiftSubmit: false,
+      giftContent: {
+        giftTipText: '',
+        buttonText: '去购买',
+        type: 'buy'
+      }
     }
   },
   computed: {
@@ -148,6 +180,23 @@ export default {
     })
   },
   methods: {
+    showGiftDialog(data) {
+      if (data === 'gift') {
+        this.showGiftSubmit = true
+      }
+      else {
+        const freeText = '您当前不是超级订阅会员,无法赠送给好友。您可以先购买后再赠送给好友。'
+        const passText = '您当前剩余订阅周期不满1个月,无法赠送给好友。您可以先续费后再赠送给好友。'
+        this.giftContent.giftTipText = data === 'renew' ? passText : freeText
+        this.giftContent.buttonText = data === 'renew' ? '去续费' : '去购买'
+        this.giftContent.type = data
+        this.showGift = true
+      }
+    },
+    onClickConfirm() {
+      this.showGift = false
+      this.$router.push(`/free/svip/buy?type=${this.giftContent.type}`)
+    },
     initNextDialog(key) {
       this.dialog[key] = true
       // 获取引导
@@ -172,7 +221,8 @@ export default {
             title: '阳光直采上线了!',
             content: '海量企业直发采购需求,供应商可直接对接采购部门'
           })
-        } catch (error) {
+        }
+        catch (error) {
           console.log(error)
         }
       }
@@ -180,6 +230,7 @@ export default {
   }
 }
 </script>
+
 <style lang="scss" scoped>
 .workspace-dashboard {
   padding: 24px;
@@ -194,6 +245,33 @@ export default {
     margin-top: 16px;
   }
 }
+.gift-tip-dialog {
+  ::v-deep {
+    .el-dialog {
+      width: 380px!important;
+    }
+    .el-dialog__header {
+      padding: 32px 32px 0;
+    }
+    .el-dialog__body {
+      padding: 20px 32px 32px;
+    }
+    .el-dialog__footer {
+      display: flex;
+      justify-content: center;
+      padding: 0 32px 32px;
+    }
+    .gift-tip-content {
+      text-align: center;
+    }
+    .dialog-footer {
+      .action-button.confirm {
+        width: 132px;
+      }
+    }
+
+  }
+}
 .card-list-module {
   display: flex;
   justify-content: space-between;

+ 51 - 0
pnpm-lock.yaml

@@ -123,6 +123,9 @@ importers:
       v-charts:
         specifier: 1.19.0
         version: 1.19.0(echarts@4.8.0)(vue@2.7.16)(zrender@4.3.3)
+      vue-clipboard2:
+        specifier: ^0.3.3
+        version: 0.3.3
       vue-cookies:
         specifier: ^1.7.4
         version: 1.8.6
@@ -3413,6 +3416,7 @@ packages:
     engines: {node: '>= 10.0.0'}
     cpu: [arm]
     os: [linux]
+    libc: [glibc]
     requiresBuild: true
     dev: true
     optional: true
@@ -3422,6 +3426,7 @@ packages:
     engines: {node: '>= 10.0.0'}
     cpu: [arm]
     os: [linux]
+    libc: [musl]
     requiresBuild: true
     dev: true
     optional: true
@@ -3431,6 +3436,7 @@ packages:
     engines: {node: '>= 10.0.0'}
     cpu: [arm64]
     os: [linux]
+    libc: [glibc]
     requiresBuild: true
     dev: true
     optional: true
@@ -3440,6 +3446,7 @@ packages:
     engines: {node: '>= 10.0.0'}
     cpu: [arm64]
     os: [linux]
+    libc: [musl]
     requiresBuild: true
     dev: true
     optional: true
@@ -3449,6 +3456,7 @@ packages:
     engines: {node: '>= 10.0.0'}
     cpu: [x64]
     os: [linux]
+    libc: [glibc]
     requiresBuild: true
     dev: true
     optional: true
@@ -3458,6 +3466,7 @@ packages:
     engines: {node: '>= 10.0.0'}
     cpu: [x64]
     os: [linux]
+    libc: [musl]
     requiresBuild: true
     dev: true
     optional: true
@@ -3660,6 +3669,7 @@ packages:
     resolution: {integrity: sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==}
     cpu: [arm]
     os: [linux]
+    libc: [glibc]
     requiresBuild: true
     dev: true
     optional: true
@@ -3668,6 +3678,7 @@ packages:
     resolution: {integrity: sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==}
     cpu: [arm]
     os: [linux]
+    libc: [musl]
     requiresBuild: true
     dev: true
     optional: true
@@ -3676,6 +3687,7 @@ packages:
     resolution: {integrity: sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==}
     cpu: [arm64]
     os: [linux]
+    libc: [glibc]
     requiresBuild: true
     dev: true
     optional: true
@@ -3684,6 +3696,7 @@ packages:
     resolution: {integrity: sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==}
     cpu: [arm64]
     os: [linux]
+    libc: [musl]
     requiresBuild: true
     dev: true
     optional: true
@@ -3692,6 +3705,7 @@ packages:
     resolution: {integrity: sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==}
     cpu: [loong64]
     os: [linux]
+    libc: [glibc]
     requiresBuild: true
     dev: true
     optional: true
@@ -3700,6 +3714,7 @@ packages:
     resolution: {integrity: sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==}
     cpu: [ppc64]
     os: [linux]
+    libc: [glibc]
     requiresBuild: true
     dev: true
     optional: true
@@ -3708,6 +3723,7 @@ packages:
     resolution: {integrity: sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==}
     cpu: [riscv64]
     os: [linux]
+    libc: [glibc]
     requiresBuild: true
     dev: true
     optional: true
@@ -3716,6 +3732,7 @@ packages:
     resolution: {integrity: sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==}
     cpu: [s390x]
     os: [linux]
+    libc: [glibc]
     requiresBuild: true
     dev: true
     optional: true
@@ -3724,6 +3741,7 @@ packages:
     resolution: {integrity: sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==}
     cpu: [x64]
     os: [linux]
+    libc: [glibc]
     requiresBuild: true
     dev: true
     optional: true
@@ -3732,6 +3750,7 @@ packages:
     resolution: {integrity: sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==}
     cpu: [x64]
     os: [linux]
+    libc: [musl]
     requiresBuild: true
     dev: true
     optional: true
@@ -7060,6 +7079,14 @@ packages:
     engines: {node: '>= 12'}
     dev: true
 
+  /clipboard@2.0.11:
+    resolution: {integrity: sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==}
+    dependencies:
+      good-listener: 1.2.2
+      select: 1.1.2
+      tiny-emitter: 2.1.0
+    dev: false
+
   /clipboardy@2.3.0:
     resolution: {integrity: sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==}
     engines: {node: '>=8'}
@@ -7891,6 +7918,10 @@ packages:
     resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
     engines: {node: '>=0.4.0'}
 
+  /delegate@3.2.0:
+    resolution: {integrity: sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==}
+    dev: false
+
   /delegates@1.0.0:
     resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
     dev: false
@@ -10041,6 +10072,12 @@ packages:
       vue: 2.7.16
     dev: false
 
+  /good-listener@1.2.2:
+    resolution: {integrity: sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==}
+    dependencies:
+      delegate: 3.2.0
+    dev: false
+
   /gopd@1.2.0:
     resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
     engines: {node: '>= 0.4'}
@@ -14000,6 +14037,10 @@ packages:
     resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==}
     dev: true
 
+  /select@1.1.2:
+    resolution: {integrity: sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==}
+    dev: false
+
   /selfsigned@2.4.1:
     resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==}
     engines: {node: '>=10'}
@@ -14842,6 +14883,10 @@ packages:
     resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==}
     dev: true
 
+  /tiny-emitter@2.1.0:
+    resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==}
+    dev: false
+
   /tinybench@2.9.0:
     resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
     dev: true
@@ -15946,6 +15991,12 @@ packages:
       vue: 2.7.16
     dev: false
 
+  /vue-clipboard2@0.3.3:
+    resolution: {integrity: sha512-aNWXIL2DKgJyY/1OOeITwAQz1fHaCIGvUFHf9h8UcoQBG5a74MkdhS/xqoYe7DNZdQmZRL+TAdIbtUs9OyVjbw==}
+    dependencies:
+      clipboard: 2.0.11
+    dev: false
+
   /vue-cookies@1.8.6:
     resolution: {integrity: sha512-e2kYaHj1Y/zVsBSM3KWlOoVJ5o3l4QZjytNU7xdCgmkw3521CMUerqHekBGZKXXC1oRxYljBeeOK2SCel6cKuw==}
     dev: false