Browse Source

窍笔的修改

zhuliu 2 months ago
parent
commit
fca115ed7d
42 changed files with 2458 additions and 36 deletions
  1. 16 0
      src/api/functionApi.js
  2. 54 0
      src/api/goods.js
  3. 7 1
      src/api/index.js
  4. 20 0
      src/api/payAndStat.js
  5. 49 3
      src/icons/iconfont/demo_index.html
  6. 11 3
      src/icons/iconfont/iconfont.css
  7. 1 1
      src/icons/iconfont/iconfont.js
  8. 14 0
      src/icons/iconfont/iconfont.json
  9. BIN
      src/icons/iconfont/iconfont.ttf
  10. BIN
      src/icons/iconfont/iconfont.woff
  11. BIN
      src/icons/iconfont/iconfont.woff2
  12. 1 0
      src/icons/svg/shouzhitongji.svg
  13. 1 0
      src/icons/svg/zhifujilu.svg
  14. 1 0
      src/icons/svg/zijinzhifutongjibaobiao.svg
  15. 1 0
      src/icons/svg/商品管理.svg
  16. 1 0
      src/icons/svg/应用功能.svg
  17. 65 0
      src/router/index.js
  18. 253 0
      src/utils/model/daterangePicker/index.vue
  19. 3 1
      src/utils/model/index.js
  20. 165 0
      src/views/backStageManage/application/function/function.vue
  21. 7 2
      src/views/backStageManage/application/function/index.vue
  22. 49 12
      src/views/backStageManage/application/vipType/components/form/vipType.vue
  23. 109 0
      src/views/backStageManage/application/vipType/components/views/table.vue
  24. 45 7
      src/views/backStageManage/application/vipType/vipType.vue
  25. 3 2
      src/views/backStageManage/application/vision/components/functionTable.vue
  26. 1 1
      src/views/backStageManage/application/vision/components/mixins/functionData.js
  27. 1 1
      src/views/backStageManage/application/vision/vision.vue
  28. 41 0
      src/views/backStageManage/goods/goods/addGoods.vue
  29. 595 0
      src/views/backStageManage/goods/goods/components/form/goods.vue
  30. 314 0
      src/views/backStageManage/goods/goods/components/goods.vue
  31. 22 0
      src/views/backStageManage/goods/goods/components/mixins/commonData.js
  32. 38 0
      src/views/backStageManage/goods/goods/components/mixins/getFunctionNames.js
  33. 30 0
      src/views/backStageManage/goods/goods/editGoods.vue
  34. 30 0
      src/views/backStageManage/goods/goods/goodsDetails.vue
  35. 26 0
      src/views/backStageManage/goods/goods/index.vue
  36. 1 1
      src/views/backStageManage/layout/Layout.vue
  37. 251 0
      src/views/backStageManage/paymentAndStat/paymentRecord/components/paymentRecord.vue
  38. 26 0
      src/views/backStageManage/paymentAndStat/paymentRecord/index.vue
  39. 11 0
      src/views/backStageManage/paymentAndStat/statPayRecord/components/mixins/commonData.js
  40. 168 0
      src/views/backStageManage/paymentAndStat/statPayRecord/components/statPayRecord.vue
  41. 26 0
      src/views/backStageManage/paymentAndStat/statPayRecord/index.vue
  42. 1 1
      src/views/backStageManage/paymentCode/paymentCode/components/paymentCode.vue

+ 16 - 0
src/api/functionApi.js

@@ -0,0 +1,16 @@
+import axios from '@/utils/axios'
+
+export default {
+    /**
+     * 获取窍笔所有功能
+     * @param {*} data 
+     * name-功能名称
+     * size-页大小
+     * current-页数
+     * @returns 
+     */
+    queryQiaoBiFunctionApi(data){
+        return axios.post('/permission/qiaoBi/qiaoBiApplication/queryQiaoBiFunction', data)
+    },
+
+}

+ 54 - 0
src/api/goods.js

@@ -0,0 +1,54 @@
+import axios from '@/utils/axios'
+
+export default {
+    /**
+     * 查询商品
+     * @param {*} data
+     * @returns 
+     */
+    queryGoods(data){
+        return axios.post('/permission/qiaoBi/goods/queryGoods', data)
+    },
+    /**
+     * 新增/编辑商品
+     * @param {*} data
+     * @returns 
+     */
+    addGoods(data){
+        return axios.post('/permission/qiaoBi/goods/addGoods', data)
+    },
+    /**
+     * 下架/上架商品
+     * @param {*} data
+     * @returns 
+     */
+    updateGoodsStatus(data){
+        return axios.post('/permission/qiaoBi/goods/updateGoodsStatus', data)
+    },
+    /**
+     * 删除商品
+     * @param {*} data
+     * @returns 
+     */
+    deleteGoods(data){
+        return axios.post('/permission/qiaoBi/goods/deleteGoods', data)
+    },
+
+    /**
+     * 查询商品购买限制列表
+     * @param {*} data
+     * @returns 
+     */
+    queryGoodsLimit(data){
+        return axios.get('/permission/qiaoBi/goods/queryGoodsLimit')
+    },
+    /**
+     * 查询商品营销策略
+     * @param {*} data
+     * @returns 
+     */
+    queryGoodsStrategy(data){
+        return axios.get('/permission/qiaoBi/goods/queryGoodsStrategy')
+    },
+
+}

+ 7 - 1
src/api/index.js

@@ -16,6 +16,9 @@ import examine from "./examine";
 import tenant from './tenant'
 import tenant from './tenant'
 
 
 import stat from './stat';
 import stat from './stat';
+import functionApi from './functionApi'
+import goods from './goods'
+import payAndStat from "./payAndStat";
 
 
 
 
 export default {
 export default {
@@ -34,5 +37,8 @@ export default {
   ...examine,
   ...examine,
   ...tenant,
   ...tenant,
   ...personnel,
   ...personnel,
-  ...stat
+  ...stat,
+  ...functionApi,
+  ...goods,
+  ...payAndStat
 }
 }

+ 20 - 0
src/api/payAndStat.js

@@ -0,0 +1,20 @@
+import axios from '@/utils/axios'
+
+export default {
+    /**
+     * 查询付款记录
+     * @param {*} data
+     * @returns 
+     */
+    queryPayRecord(data){
+        return axios.post('/permission/qiaoBi/pay/queryPayRecord', data)
+    },
+    /**
+     * 统计付款记录
+     * @param {*} data
+     * @returns 
+     */
+    groupPayRecord(data){
+        return axios.post('/permission/qiaoBi/pay/groupPayRecord', data)
+    },
+}

+ 49 - 3
src/icons/iconfont/demo_index.html

@@ -55,6 +55,18 @@
           <ul class="icon_lists dib-box">
           <ul class="icon_lists dib-box">
           
           
             <li class="dib">
             <li class="dib">
+              <span class="icon iconfont">&#xe664;</span>
+                <div class="name">上架</div>
+                <div class="code-name">&amp;#xe664;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe615;</span>
+                <div class="name">下架</div>
+                <div class="code-name">&amp;#xe615;</div>
+              </li>
+          
+            <li class="dib">
               <span class="icon iconfont">&#xe8ab;</span>
               <span class="icon iconfont">&#xe8ab;</span>
                 <div class="name">退款</div>
                 <div class="name">退款</div>
                 <div class="code-name">&amp;#xe8ab;</div>
                 <div class="code-name">&amp;#xe8ab;</div>
@@ -108,9 +120,9 @@
 <pre><code class="language-css"
 <pre><code class="language-css"
 >@font-face {
 >@font-face {
   font-family: 'iconfont';
   font-family: 'iconfont';
-  src: url('iconfont.woff2?t=1733738645363') format('woff2'),
-       url('iconfont.woff?t=1733738645363') format('woff'),
-       url('iconfont.ttf?t=1733738645363') format('truetype');
+  src: url('iconfont.woff2?t=1752217762560') format('woff2'),
+       url('iconfont.woff?t=1752217762560') format('woff'),
+       url('iconfont.ttf?t=1752217762560') format('truetype');
 }
 }
 </code></pre>
 </code></pre>
           <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
           <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@@ -137,6 +149,24 @@
         <ul class="icon_lists dib-box">
         <ul class="icon_lists dib-box">
           
           
           <li class="dib">
           <li class="dib">
+            <span class="icon iconfont icon-shangjia"></span>
+            <div class="name">
+              上架
+            </div>
+            <div class="code-name">.icon-shangjia
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-xiajia"></span>
+            <div class="name">
+              下架
+            </div>
+            <div class="code-name">.icon-xiajia
+            </div>
+          </li>
+          
+          <li class="dib">
             <span class="icon iconfont icon-tuikuan"></span>
             <span class="icon iconfont icon-tuikuan"></span>
             <div class="name">
             <div class="name">
               退款
               退款
@@ -219,6 +249,22 @@
           
           
             <li class="dib">
             <li class="dib">
                 <svg class="icon svg-icon" aria-hidden="true">
                 <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-shangjia"></use>
+                </svg>
+                <div class="name">上架</div>
+                <div class="code-name">#icon-shangjia</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-xiajia"></use>
+                </svg>
+                <div class="name">下架</div>
+                <div class="code-name">#icon-xiajia</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
                   <use xlink:href="#icon-tuikuan"></use>
                   <use xlink:href="#icon-tuikuan"></use>
                 </svg>
                 </svg>
                 <div class="name">退款</div>
                 <div class="name">退款</div>

+ 11 - 3
src/icons/iconfont/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
 @font-face {
   font-family: "iconfont"; /* Project id 4733871 */
   font-family: "iconfont"; /* Project id 4733871 */
-  src: url('iconfont.woff2?t=1733738645363') format('woff2'),
-       url('iconfont.woff?t=1733738645363') format('woff'),
-       url('iconfont.ttf?t=1733738645363') format('truetype');
+  src: url('iconfont.woff2?t=1752217762560') format('woff2'),
+       url('iconfont.woff?t=1752217762560') format('woff'),
+       url('iconfont.ttf?t=1752217762560') format('truetype');
 }
 }
 
 
 .iconfont {
 .iconfont {
@@ -13,6 +13,14 @@
   -moz-osx-font-smoothing: grayscale;
   -moz-osx-font-smoothing: grayscale;
 }
 }
 
 
+.icon-shangjia:before {
+  content: "\e664";
+}
+
+.icon-xiajia:before {
+  content: "\e615";
+}
+
 .icon-tuikuan:before {
 .icon-tuikuan:before {
   content: "\e8ab";
   content: "\e8ab";
 }
 }

File diff suppressed because it is too large
+ 1 - 1
src/icons/iconfont/iconfont.js


+ 14 - 0
src/icons/iconfont/iconfont.json

@@ -6,6 +6,20 @@
   "description": "",
   "description": "",
   "glyphs": [
   "glyphs": [
     {
     {
+      "icon_id": "2755965",
+      "name": "上架",
+      "font_class": "shangjia",
+      "unicode": "e664",
+      "unicode_decimal": 58980
+    },
+    {
+      "icon_id": "6322620",
+      "name": "下架",
+      "font_class": "xiajia",
+      "unicode": "e615",
+      "unicode_decimal": 58901
+    },
+    {
       "icon_id": "2076345",
       "icon_id": "2076345",
       "name": "退款",
       "name": "退款",
       "font_class": "tuikuan",
       "font_class": "tuikuan",

BIN
src/icons/iconfont/iconfont.ttf


BIN
src/icons/iconfont/iconfont.woff


BIN
src/icons/iconfont/iconfont.woff2


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/shouzhitongji.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/zhifujilu.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/zijinzhifutongjibaobiao.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/商品管理.svg


File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/应用功能.svg


+ 65 - 0
src/router/index.js

@@ -196,6 +196,12 @@ export const defaultBackStageManageRouterItem = [
       //   meta: { title: '应用功能清单', icon: 'apply' }
       //   meta: { title: '应用功能清单', icon: 'apply' }
       // },
       // },
       {
       {
+        path: 'function',
+        name: 'Administrator_function',
+        component: () => import('@/views/backStageManage/application/function/index.vue'),
+        meta: { title: '应用功能清单', icon: '应用功能',sign:'administrator/function'}
+      },
+      {
         path: 'vision',
         path: 'vision',
         name: 'Administrator_vision',
         name: 'Administrator_vision',
         component: () => import('@/views/backStageManage/application/vision/index.vue'),
         component: () => import('@/views/backStageManage/application/vision/index.vue'),
@@ -255,6 +261,65 @@ export const defaultBackStageManageRouterItem = [
   },
   },
   {
   {
     path: '/administrator',
     path: '/administrator',
+    name: 'Administrator_goodsManage',
+    component: administrator_layout,
+    redirect: '/administrator/goods',
+    meta: { title: '商品管理', icon: '商品管理'},
+    children: [
+      {
+        path: 'goods',
+        name: 'Administrator_goods',
+        component: () => import('@/views/backStageManage/goods/goods/index.vue'),
+        meta: {title: '商品管理', icon: '商品管理',sign:'administrator/goods'},
+        
+      },
+      {
+        path: 'addGoods',
+        name: 'Administrator_addGoods',
+        component: () => import('@/views/backStageManage/goods/goods/addGoods.vue'),
+        meta: {title: '添加商品',keepAlive:true},
+        hidden:true
+      },
+      {
+        path: 'editGoods',
+        name: 'Administrator_editGoods',
+        component: () => import('@/views/backStageManage/goods/goods/editGoods.vue'),
+        meta: {title: '修改商品', keepAlive:true},
+        hidden:true
+      },
+      {
+        path: 'goodsDetails',
+        name: 'Administrator_goodsDetails',
+        component: () => import('@/views/backStageManage/goods/goods/goodsDetails.vue'),
+        meta: {title: '商品详情'},
+        hidden:true
+      },
+    ]
+  },
+  {
+    path: '/administrator',
+    name: 'Administrator_paymentAndStat',
+    component: administrator_layout,
+    redirect: '/administrator/paymentRecord',
+    meta: { title: '支付与统计', icon: 'shouzhitongji'},
+    children: [
+      {
+        path: 'paymentRecord',
+        name: 'Administrator_paymentRecord',
+        component: () => import('@/views/backStageManage/paymentAndStat/paymentRecord/index.vue'),
+        meta: {title: '支付记录', icon: 'zhifujilu',sign:'administrator/payRecord'},
+        
+      },
+      {
+        path: 'statPayRecord',
+        name: 'Administrator_statPayRecord',
+        component: () => import('@/views/backStageManage/paymentAndStat/statPayRecord/index.vue'),
+        meta: {title: '支付统计', icon: 'zijinzhifutongjibaobiao',sign:'administrator/payCount'},
+      },
+    ]
+  },
+  {
+    path: '/administrator',
     name: 'Administrator_paymentCodeManage',
     name: 'Administrator_paymentCodeManage',
     component: administrator_layout,
     component: administrator_layout,
     redirect: '/administrator/paymentCode',
     redirect: '/administrator/paymentCode',

+ 253 - 0
src/utils/model/daterangePicker/index.vue

@@ -0,0 +1,253 @@
+<template>
+  <div class="flexible-date-range-picker" ref="flexible">
+    <el-date-picker
+    class="startDate"
+      v-model="startDate"
+      :style="customStyle"
+      :type="type"
+      :placeholder="startPlaceholder"
+      v-bind="$attrs"
+      :picker-options="startPickerOptions"
+      @change="handleStartChange"
+      :clearable="startClearable"
+    ></el-date-picker>
+    
+    <!-- <span class="separator">-</span> -->
+    <div class="separator" ref="separator">至</div>
+     
+    <el-date-picker
+    class="endDate"
+    :style="customStyle"
+      v-model="endDate"
+      :type="type"
+      :placeholder="endPlaceholder"
+      v-bind="$attrs"
+      :picker-options="endPickerOptions"
+      @change="handleEndChange"
+    ></el-date-picker>
+    
+    <!-- <div class="quick-options">
+      <el-button size="mini" @click="setToday">今天</el-button>
+      <el-button size="mini" @click="setYesterday">昨天</el-button>
+      <el-button size="mini" @click="setLast7Days">最近7天</el-button>
+      <el-button size="mini" @click="setLast30Days">最近30天</el-button>
+      <el-button size="mini" @click="clearAll">清空</el-button>
+    </div> -->
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'FlexibleDateRangePicker',
+  props: {
+    // 可以从父组件接收初始值
+    value: {
+      type: Object,
+      default: () => ({})
+    },
+    type:{
+        type: String,
+        default: 'date'
+    },
+    startPlaceholder:{
+        type: String,
+        default: '开始日期'
+    },
+    startClearable:{
+        type: Boolean,
+        default: true
+    },
+    endPlaceholder:{
+        type: String,
+        default: '结束日期'
+    },
+    customStyle:{
+        type: String,
+        default: 'width:130px;'
+    }
+  },
+  data() {
+    return {
+      startDate: null,
+      endDate: null,
+      // 禁用结束日期的可选范围(不能早于开始日期)
+      startPickerOptions: {
+        disabledDate: (time) => {
+          if (this.endDate) {
+            return time.getTime() > new Date(this.endDate).getTime();
+          }
+          return false;
+        }
+      },
+      // 禁用开始日期的可选范围(不能晚于结束日期)
+      endPickerOptions: {
+        disabledDate: (time) => {
+          if (this.startDate) {
+            return time.getTime() < new Date(this.startDate).getTime();
+          }
+          return false;
+        }
+      }
+    };
+  },
+  computed: {
+    displayTime() {
+      if (this.startDate && this.endDate) {
+        return `${this.formatDate(this.startDate)} 至 ${this.formatDate(this.endDate)}`;
+      } else if (this.startDate) {
+        return `从 ${this.formatDate(this.startDate)} 开始`;
+      } else if (this.endDate) {
+        return `至 ${this.formatDate(this.endDate)} 结束`;
+      }
+      return '选择日期范围';
+    }
+  },
+  watch: {
+    // 监听内部值变化,向父组件 emit 事件
+    startDate(val) {
+      this.$emit('input', { startDate: val, endDate: this.endDate });
+      this.$emit('change', { startDate: val, endDate: this.endDate });
+    },
+    endDate(val) {
+      this.$emit('input', { startDate: this.startDate, endDate: val });
+      this.$emit('change', { startDate: this.startDate, endDate: val });
+    },
+    // 监听外部传入的 value 变化
+    value: {
+      handler(newVal) {
+        if (newVal) {
+          this.startDate = newVal.startDate || null;
+          this.endDate = newVal.endDate || null;
+        }
+      },
+      immediate: true,
+      deep: true
+    }
+  },
+  mounted(){
+    let dom = this.$refs.flexible
+    let height = dom.clientHeight
+    let dom2 = this.$refs.separator
+    dom2.style.height = (height - 4) + 'px'
+  },
+  methods: {
+    formatDate(date) {
+      if (!date) return '';
+      const d = new Date(date);
+      return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
+    },
+    handleStartChange(date) {
+      // 如果开始日期晚于结束日期,自动清空结束日期
+      if(!date){
+        return
+      }
+      if (this.endDate && new Date(date) > new Date(this.endDate)) {
+        this.endDate = null;
+      }
+    },
+    handleEndChange(date) {
+      // 如果结束日期早于开始日期,自动清空开始日期
+      if(!date){
+        return
+      }
+      if (this.startDate && new Date(date) < new Date(this.startDate)) {
+        this.startDate = null;
+      }
+    },
+    setToday() {
+      const today = new Date();
+      today.setHours(0, 0, 0, 0);
+      this.startDate = new Date(today);
+      this.endDate = new Date(today);
+    },
+    setYesterday() {
+      const yesterday = new Date();
+      yesterday.setDate(yesterday.getDate() - 1);
+      yesterday.setHours(0, 0, 0, 0);
+      this.startDate = new Date(yesterday);
+      this.endDate = new Date(yesterday);
+    },
+    setLast7Days() {
+      const end = new Date();
+      end.setHours(23, 59, 59, 999);
+      
+      const start = new Date();
+      start.setDate(start.getDate() - 6);
+      start.setHours(0, 0, 0, 0);
+      
+      this.startDate = start;
+      this.endDate = end;
+    },
+    setLast30Days() {
+      const end = new Date();
+      end.setHours(23, 59, 59, 999);
+      
+      const start = new Date();
+      start.setDate(start.getDate() - 29);
+      start.setHours(0, 0, 0, 0);
+      
+      this.startDate = start;
+      this.endDate = end;
+    },
+    clearAll() {
+      this.startDate = null;
+      this.endDate = null;
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+    .flexible-date-range-picker{
+        .el-input__inner:focus{
+            border-color: #DCDFE6 !important;;
+            outline: 0;
+            
+        }
+        .startDate{
+            .el-input__inner{
+                border-color: #DCDFE6 !important;
+                border-right: 0 !important;
+                border-top-right-radius: 0 !important;
+                border-bottom-right-radius: 0 !important;
+            } 
+        }
+        .endDate{
+            .el-input__inner{
+                border-color: #DCDFE6 !important;
+                border-left: 0 !important;
+                border-top-left-radius: 0 !important;
+                border-bottom-left-radius: 0 !important;
+            } 
+        }
+    }
+</style>
+
+<style lang="scss" scoped>
+.flexible-date-range-picker {
+  display: inline-flex;
+  align-items: center;
+  flex-wrap: wrap;
+  height:calc(100% - 0px);
+}
+
+
+.separator {
+    padding: 0 10px;
+    height:calc(100% - 2px);
+    background: #ffffff;
+    border: 1px solid #DCDFE6;
+    border-left: 0;
+    border-right: 0;
+}
+
+.quick-options {
+  margin-top: 10px;
+  width: 100%;
+}
+
+.quick-options .el-button {
+  margin-right: 10px;
+  margin-top: 5px;
+}
+</style>

+ 3 - 1
src/utils/model/index.js

@@ -5,13 +5,15 @@ import myUpload from './upload/index.vue'
 import myTooltip from './tooltip/index.vue'
 import myTooltip from './tooltip/index.vue'
 import valueInput from './valueInput'
 import valueInput from './valueInput'
 import myVideo from './video'
 import myVideo from './video'
+import myDateRangePicker from './daterangePicker'
 
 
 var models = {
 var models = {
   myInput,
   myInput,
   myUpload,
   myUpload,
   myTooltip,
   myTooltip,
   valueInput,
   valueInput,
-  myVideo
+  myVideo,
+  myDateRangePicker
 }
 }
 export default {
 export default {
   install(Vue) {
   install(Vue) {

+ 165 - 0
src/views/backStageManage/application/function/function.vue

@@ -0,0 +1,165 @@
+<template>
+  <div class="height_100">
+    <el-container>
+      <el-header>
+        <div class="header">
+          <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="100px">
+            <el-form-item label="功能名称" prop="name">
+              <el-input
+                v-model="queryParams.name"
+                placeholder="请输入功能名称"
+                clearable
+              />
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" icon="el-icon-search" size="mini" @click="search">搜索</el-button>
+              <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+            </el-form-item>
+          </el-form>
+          
+          <el-row :gutter="10">
+            <el-col :span="1.5">
+              <!-- <el-button icon="el-icon-plus" size="small" @click="handleAdd">新增</el-button> -->
+            </el-col>
+          </el-row>
+        </div>
+      </el-header>
+      <el-main class="padding_10">
+        <funTable ref="functionTable" :tableData="tableData" :loading="loading">
+            <template slot="column">
+                <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="140px">
+                    <template slot-scope="scope" v-if="!scope.row.children || scope.row.children == 0">
+                        <el-button
+                            size="mini"
+                            type="text"
+                            icon="el-icon-goods"
+                            @click="handleAddGoods(scope.row)"
+                        >添加为商品</el-button>
+                    </template>
+                </el-table-column>
+            </template>
+        </funTable>
+      </el-main>
+      <el-footer class="pagination">
+        <el-pagination background layout="total, sizes, prev, pager, next, jumper"
+          :current-page.sync="queryParams.current" :page-size.sync="queryParams.size"
+          @current-change="handleCurrentChange" @size-change="changeSize" :total="total">
+        </el-pagination>
+      </el-footer>
+    </el-container>
+  </div>
+</template>
+
+<script>
+const searchForm = {
+  name:null
+}
+
+import funTable from '@/views/backStageManage/application/vision/components/functionTable.vue';
+export default {
+  components: {
+    funTable
+  },
+  props: {},
+  data() {
+    return {
+      // 遮罩层
+      loading: false,
+      tableData: {},
+      // 查询参数
+      queryParams: {
+        current: 1,
+        size: 10,
+        ...searchForm
+      },
+      total:0,
+    };
+  },
+  watch: {},
+  computed: {},
+  created() {},
+  mounted() {
+    this.getList()
+  },
+  methods: {
+    /** 查询功能列表 */
+    getList() {
+      this.loading = true;
+      this.$api.queryQiaoBiFunctionApi(this.queryParams).then(response=>{
+        if(response.code == 200){
+            this.tableData = response.data
+            this.total = response.pageColumn.total || 0
+            var a = response.data.children
+            for(var j = 0;j<a.length;j++){
+                function l(data){
+                    if(data.hasOwnProperty('children')){
+                        for(var i = 0;i<data.children.length;i++){
+                        
+                            if(data.hasOwnProperty('last')){
+                                data.children[i].last=data.last+'/'+data.name
+                            }else{
+                                data.children[i].last=data.name
+                            }
+                            l(data.children[i])
+                        }
+                    }
+                }
+                l(a[j])
+            }
+            this.loading = false
+        }
+      }).catch(error=>{
+          this.tableData = {}
+          this.total = 0
+          this.loading = false
+      })
+    },
+    //切换分页
+    handleCurrentChange(value){
+      this.queryParams.current = value
+      this.getList()
+    },
+    //切换页大小
+    changeSize(value){
+      this.queryParams.size = value
+      this.queryParams.current = 1
+      this.getList()
+    },
+    //添加为商品
+    handleAddGoods(row){
+      this.$router.push({ 
+        path: '/administrator/addGoods', 
+        query: {
+            goodId: row.id,
+            type:2
+        }
+      });
+    },
+    /** 搜索按钮操作 */
+    search() {
+      this.queryParams.current = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      for(let key in searchForm){
+        this.$set(this.queryParams,key,searchForm[key])
+      }
+      this.search();
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.header{
+  width: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+.foot{
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+}
+</style>

+ 7 - 2
src/views/backStageManage/application/function/index.vue

@@ -1,10 +1,15 @@
 <template>
 <template>
-  <div></div>
+  <div class="height_100">
+    <functionVue></functionVue>
+  </div>
 </template>
 </template>
 
 
 <script>
 <script>
+import functionVue from './function.vue';
 export default {
 export default {
-  components: {},
+  components: {
+    functionVue
+  },
   props: {},
   props: {},
   data() {
   data() {
     return {
     return {

+ 49 - 12
src/views/backStageManage/application/vipType/components/form/vipType.vue

@@ -1,5 +1,5 @@
 <template>
 <template>
-    <div>
+    <div class="vipTypeForm">
         <div class="button-container" v-if="model != 'detail'">
         <div class="button-container" v-if="model != 'detail'">
                 <el-button type="primary" size="small" :loading="btnLoading" @click="submitForm">提 交</el-button>
                 <el-button type="primary" size="small" :loading="btnLoading" @click="submitForm">提 交</el-button>
                 <el-button size="small"  @click="init">重 置</el-button>
                 <el-button size="small"  @click="init">重 置</el-button>
@@ -7,21 +7,28 @@
         <div class="form_center" >
         <div class="form_center" >
             <el-form ref="form" :model="form" :rules="rules" label-position="left" label-width="120px" :class="model == 'detail'?'pointer_events_none':''">
             <el-form ref="form" :model="form" :rules="rules" label-position="left" label-width="120px" :class="model == 'detail'?'pointer_events_none':''">
                 <el-form-item label="会员类型名称:" prop="vipTypeName" >
                 <el-form-item label="会员类型名称:" prop="vipTypeName" >
-                    <el-input v-model="form.vipTypeName" placeholder="请输入会员类型名称" maxlength="20" />
+                    <el-input v-if="model != 'detail'" v-model="form.vipTypeName" placeholder="请输入会员类型名称" maxlength="20" />
+                    <div v-else>{{form.vipTypeName}}</div>
                 </el-form-item>
                 </el-form-item>
-                <el-form-item label="持续时长:" prop="lastTime">
+                <!-- <el-form-item label="持续时长:" prop="lastTime">
                     <el-input v-model="form.lastTime" placeholder="请输入持续时长" >
                     <el-input v-model="form.lastTime" placeholder="请输入持续时长" >
                         <template slot="append">月</template>
                         <template slot="append">月</template>
                     </el-input>
                     </el-input>
+                </el-form-item> -->
+                <el-form-item label="会员等级:" prop="vipLevel">
+                     <el-input-number v-if="model != 'detail'" v-model="form.vipLevel" controls-position="right" :min="1" style="width: 100%;"></el-input-number>
+                     <div v-else>{{form.vipLevel}}</div>
                 </el-form-item>
                 </el-form-item>
                 <el-form-item label="是否启用:" prop="enable">
                 <el-form-item label="是否启用:" prop="enable">
-                    <el-radio-group v-model="form.enable">
+                    <el-radio-group v-if="model != 'detail'" v-model="form.enable" >
                         <el-radio :label="1">是</el-radio>
                         <el-radio :label="1">是</el-radio>
                         <el-radio :label="0">否</el-radio>
                         <el-radio :label="0">否</el-radio>
                     </el-radio-group>
                     </el-radio-group>
+                    <div v-else>{{form.enable==1?'是':'否'}}</div>
                 </el-form-item>
                 </el-form-item>
                 <el-form-item label="备注:" prop="remark">
                 <el-form-item label="备注:" prop="remark">
-                    <el-input v-model="form.remark" placeholder="请输入备注" maxlength="50" />
+                    <el-input v-if="model != 'detail'" v-model="form.remark" placeholder="请输入备注" maxlength="50" />
+                    <div v-else>{{form.remark}}</div>
                 </el-form-item>
                 </el-form-item>
             </el-form>
             </el-form>
             <div style="border:1px solid white;padding:10px;margin:10px 0;border-radius:8px;">
             <div style="border:1px solid white;padding:10px;margin:10px 0;border-radius:8px;">
@@ -29,7 +36,22 @@
                     <p>
                     <p>
                         {{model=='detail'?'功能清单':'选择功能'}}
                         {{model=='detail'?'功能清单':'选择功能'}}
                     </p>
                     </p>
-                    <funTable ref="functionTable" :tableData="tableData" :loading="loading" :reload="reload" :expandAll="model=='edit'?true:false" :canChoose="model=='detail'?false:true" :defaultChecked="true"></funTable>
+                    <funTable ref="functionTable" :tableData="tableData" :loading="loading" :reload="reload" :expandAll="model !=='detail'?true:false" :canChoose="model=='detail'?false:true" :defaultChecked="true">
+                        <template slot="column">
+                             <el-table-column label="可使用次数 / 月" align="left" width="150px">
+                                <template slot="header">
+                                    <div>可使用次数 / 月</div>
+                                    <div style="font-size:10px;color:red;">不填默认不限次数</div>
+                                </template>
+                                <template slot-scope="scope" v-if="!scope.row.children || scope.row.children == 0">
+                                    <div>
+                                        <el-input-number v-if="model != 'detail'" size="small" v-model="scope.row.canUseCount" controls-position="right" :min="0" style="width: 100%;"></el-input-number>
+                                        <div v-else>{{scope.row.canUseCount}}</div>
+                                    </div>
+                                </template>
+                             </el-table-column>
+                        </template>
+                    </funTable>
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
@@ -41,7 +63,8 @@ import funTable from '@/views/backStageManage/application/vision/components/func
 const currentForm = {
 const currentForm = {
     id:null,
     id:null,
     vipName:null,
     vipName:null,
-    lastTime:1,
+    // lastTime:1,
+    vipLevel:1,
     applicationCode:'4e95e3d926a2a4befa5d913acc0aa9f5',
     applicationCode:'4e95e3d926a2a4befa5d913acc0aa9f5',
     applyId:14,
     applyId:14,
     remark:null,
     remark:null,
@@ -70,9 +93,9 @@ export default {
                 vipTypeName: [
                 vipTypeName: [
                     { required: true, message: "会员类型不能为空", trigger: "blur" }
                     { required: true, message: "会员类型不能为空", trigger: "blur" }
                 ],
                 ],
-                lastTime: [
-                    { required: true, message: "持续时长不能为空", trigger: "blur" }
-                ]
+                // lastTime: [
+                //     { required: true, message: "持续时长不能为空", trigger: "blur" }
+                // ]
             },
             },
             tableData:{},
             tableData:{},
             loading:false,
             loading:false,
@@ -139,7 +162,13 @@ export default {
         getAllFunId(data,funId){
         getAllFunId(data,funId){
             for(var i = 0;i<data.length;i++){
             for(var i = 0;i<data.length;i++){
                 if(data[i].isSelect != 2){
                 if(data[i].isSelect != 2){
-                    funId.push(data[i].id)
+                    // funId.push(data[i].id)
+                    funId.push(
+                        {
+                            functionId:data[i].id,
+                            canUseCount:data[i].canUseCount
+                        }
+                    )
                 }
                 }
                 if(data[i].children && data[i].children.length){
                 if(data[i].children && data[i].children.length){
                     this.getAllFunId(data[i].children,funId)
                     this.getAllFunId(data[i].children,funId)
@@ -152,7 +181,7 @@ export default {
                 if (valid) {
                 if (valid) {
                     var functionIds = []
                     var functionIds = []
                     this.getAllFunId(this.tableData.children,functionIds)
                     this.getAllFunId(this.tableData.children,functionIds)
-                    this.form.functionIds = functionIds
+                    this.form.functionAddVOs = functionIds
                     this.btnLoading = true
                     this.btnLoading = true
                     var a = '添加'
                     var a = '添加'
                     var api = 'addVipType'
                     var api = 'addVipType'
@@ -213,6 +242,14 @@ export default {
 };
 };
 </script>
 </script>
 <style lang="scss">
 <style lang="scss">
+.vipTypeForm{
+    .el-input-number{
+        .el-input__inner{
+            text-align: left !important;
+        }
+    }
+    
+}
 .form_center {
 .form_center {
     width: 800px;
     width: 800px;
     margin: 30px auto;
     margin: 30px auto;

+ 109 - 0
src/views/backStageManage/application/vipType/components/views/table.vue

@@ -0,0 +1,109 @@
+<template>
+  <div class="height_100">
+    <el-table 
+          :data="tableData"
+          border
+          row-key="id"
+          style="width: 100%"
+          height="calc(100% - 0px)"
+          v-loading="loading"
+      >
+        <slot name="start_column"></slot>
+          <el-table-column type="index" label="序号" align="center" width="120px" v-if="!canChoose">
+            <template slot-scope="scope">
+                <div>
+                    <!-- <el-checkbox-group v-model="checkList">
+                        <el-checkbox :label="scope.row.id">{{(scope.$index + 1) + ((queryParams.current - 1) * queryParams.size)}}</el-checkbox>
+                    </el-checkbox-group> -->
+                    {{(scope.$index + 1) + ((queryParams.current - 1) * queryParams.size)}}
+                </div>
+            </template>
+          </el-table-column>
+          <el-table-column prop="vipTypeName" label="会员类型名称" width="120px">
+            <template slot-scope="scope">
+                <div>
+                  <el-link type="primary" @click="handleDetail(scope.row)">{{ scope.row.vipTypeName }}</el-link>
+                </div>
+              </template>
+          </el-table-column>
+          <el-table-column prop="vipLevel" label="会员等级" width="80px"></el-table-column>
+          <!-- <el-table-column prop="lastTime" label="持续时长">
+            <template slot-scope="scope">
+              <div>
+                {{ scope.row.lastTime }}月
+              </div>
+            </template>
+          </el-table-column> -->
+          <el-table-column prop="functions" label="功能">
+            <template slot-scope="scope">
+              <div>
+                {{ getFunctionNames(scope.row.functions) }}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column prop="enable" label="是否启用" width="80px">
+            <template slot-scope="scope">
+              <div>
+                {{ scope.row.enable?'是':"否" }}
+              </div>
+            </template>
+          </el-table-column>
+          <template v-if="showCreateMessage">
+            <el-table-column prop="createName" label="创建人" width="120px"></el-table-column>
+            <el-table-column prop="createTime" label="创建时间" width="180px"></el-table-column>
+          </template>
+          
+          <el-table-column prop="remark" label="备注" width="150px"></el-table-column>
+          <slot name="end_column"></slot>
+      </el-table>
+  </div>
+</template>
+
+<script>
+import getFunctionNames from '@/views/backStageManage/goods/goods/components/mixins/getFunctionNames';
+export default {
+  components: {},
+  mixins:[getFunctionNames],
+  props: {
+    tableData:{
+        type:Array,
+        default:()=>{
+            return []
+        }
+    },
+    loading:{
+        type:Boolean,
+        default:false
+    },
+    canChoose:{
+        type:Boolean,
+        default:false,
+    },
+    queryParams:{
+        type:Object,
+        default:()=>{
+            return {}
+        }
+    },
+    showCreateMessage:{
+        type:Boolean,
+        default:true,
+    }
+  },
+  data() {
+    return {
+    };
+  },
+  watch: {},
+  computed: {},
+  created() {},
+  mounted() {},
+  methods: {
+    handleDetail(row){
+        this.$emit('handleDetail',row)
+    }
+  },
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 45 - 7
src/views/backStageManage/application/vipType/vipType.vue

@@ -25,7 +25,35 @@
         </div>
         </div>
       </el-header>
       </el-header>
       <el-main class="padding_10">
       <el-main class="padding_10">
-        <el-table 
+        <viewTable :tableData="tableData" :queryParams="queryParams" :loading="loading" @handleDetail="handleDetail">
+          <template slot="end_column">
+            <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="140px">
+              <template slot-scope="scope">
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-edit"
+                  @click="handleEdit(scope.row)"
+                >修改</el-button>
+                <el-button
+                  v-if="scope.row.id != 0"
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handleDelete(scope.row)"
+                >删除</el-button>
+                <el-button
+                  v-if="scope.row.id != 0"
+                  size="mini"
+                  type="text"
+                  icon="el-icon-goods"
+                  @click="handleAddGoods(scope.row)"
+                >添加为商品</el-button>
+              </template>
+            </el-table-column>
+          </template>
+        </viewTable>
+        <!-- <el-table 
           :data="tableData"
           :data="tableData"
           border
           border
           row-key="id"
           row-key="id"
@@ -36,9 +64,6 @@
           <el-table-column type="index" label="序号" align="center" width="120px">
           <el-table-column type="index" label="序号" align="center" width="120px">
             <template slot-scope="scope">
             <template slot-scope="scope">
                 <div>
                 <div>
-                    <!-- <el-checkbox-group v-model="checkList">
-                        <el-checkbox :label="scope.row.id">{{(scope.$index + 1) + ((queryParams.current - 1) * queryParams.size)}}</el-checkbox>
-                    </el-checkbox-group> -->
                     {{(scope.$index + 1) + ((queryParams.current - 1) * queryParams.size)}}
                     {{(scope.$index + 1) + ((queryParams.current - 1) * queryParams.size)}}
                 </div>
                 </div>
             </template>
             </template>
@@ -84,7 +109,7 @@
               >删除</el-button>
               >删除</el-button>
             </template>
             </template>
           </el-table-column>
           </el-table-column>
-      </el-table>
+      </el-table> -->
       </el-main>
       </el-main>
       <el-footer class="pagination">
       <el-footer class="pagination">
         <el-pagination background layout="total, sizes, prev, pager, next, jumper"
         <el-pagination background layout="total, sizes, prev, pager, next, jumper"
@@ -100,8 +125,11 @@
 const searchForm = {
 const searchForm = {
   vipTypeName:null
   vipTypeName:null
 }
 }
+import viewTable from './components/views/table.vue'
 export default {
 export default {
-  components: {},
+  components: {
+    viewTable
+  },
   props: {},
   props: {},
   data() {
   data() {
     return {
     return {
@@ -171,6 +199,16 @@ export default {
         }
         }
       });
       });
     },
     },
+    //添加为商品
+    handleAddGoods(row){
+      this.$router.push({ 
+        path: '/administrator/addGoods', 
+        query: {
+            goodId: row.id,
+            type:1
+        }
+      });
+    },
     /** 搜索按钮操作 */
     /** 搜索按钮操作 */
     search() {
     search() {
       this.queryParams.current = 1;
       this.queryParams.current = 1;
@@ -179,7 +217,7 @@ export default {
     /** 重置按钮操作 */
     /** 重置按钮操作 */
     resetQuery() {
     resetQuery() {
       for(let key in searchForm){
       for(let key in searchForm){
-        this.$set(this.queryParams,key,'')
+        this.$set(this.queryParams,key,searchForm[key])
       }
       }
       this.search();
       this.search();
     },
     },

+ 3 - 2
src/views/backStageManage/application/vision/components/functionTable.vue

@@ -11,6 +11,7 @@
             :row-class-name="rowClassNameFun"
             :row-class-name="rowClassNameFun"
             :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
             :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
         >
         >
+            <slot name="start_column"></slot>
             <el-table-column v-if="canChoose" type="index" align="center" width="50px">
             <el-table-column v-if="canChoose" type="index" align="center" width="50px">
                 <template slot-scope="scope">
                 <template slot-scope="scope">
                     <div v-if="reload">
                     <div v-if="reload">
@@ -21,13 +22,13 @@
                     </div>
                     </div>
                 </template>
                 </template>
             </el-table-column>
             </el-table-column>
-            <el-table-column prop="name" label="功能名称" align="" show-overflow-tooltip></el-table-column>
+            <el-table-column prop="name" label="功能名称" align="left" show-overflow-tooltip></el-table-column>
             <!-- <el-table-column label="所属应用" align="center" show-overflow-tooltip>
             <!-- <el-table-column label="所属应用" align="center" show-overflow-tooltip>
                 <template slot-scope="scope">
                 <template slot-scope="scope">
                     <span >{{tableData.applyName}}</span>
                     <span >{{tableData.applyName}}</span>
                     </template>
                     </template>
             </el-table-column> -->
             </el-table-column> -->
-            <el-table-column prop="describe" label="功能描述" align="center" show-overflow-tooltip></el-table-column>
+            <el-table-column prop="describe" label="功能描述" align="left" show-overflow-tooltip></el-table-column>
             <!-- <el-table-column prop="sign" label="路径" align="center" show-overflow-tooltip></el-table-column> -->
             <!-- <el-table-column prop="sign" label="路径" align="center" show-overflow-tooltip></el-table-column> -->
             <!-- <el-table-column label="是否可选" align="center" show-overflow-tooltip>
             <!-- <el-table-column label="是否可选" align="center" show-overflow-tooltip>
                 <template slot-scope="scope">
                 <template slot-scope="scope">

+ 1 - 1
src/views/backStageManage/application/vision/components/mixins/functionData.js

@@ -82,7 +82,7 @@ export default{
                 sign:form.sign,
                 sign:form.sign,
                 function: type == 2?form.id : 0,
                 function: type == 2?form.id : 0,
                 functionType:1,
                 functionType:1,
-                last:form.path?(form.last+'/'+form.name):form.name
+                last:form.last?(form.last+'/'+form.name):form.name
             }
             }
             this.$refs.addFunctionDialog.open(ruleForm)
             this.$refs.addFunctionDialog.open(ruleForm)
         },
         },

+ 1 - 1
src/views/backStageManage/application/vision/vision.vue

@@ -298,7 +298,7 @@ export default {
     /** 重置按钮操作 */
     /** 重置按钮操作 */
     resetQuery() {
     resetQuery() {
       for(let key in searchForm){
       for(let key in searchForm){
-        this.$set(this.queryParams,key,'')
+        this.$set(this.queryParams,key,searchForm[key])
       }
       }
       this.handleQuery();
       this.handleQuery();
     },
     },

+ 41 - 0
src/views/backStageManage/goods/goods/addGoods.vue

@@ -0,0 +1,41 @@
+<template>
+    <div>
+        <goodsForm model="add" :type="type" :goodId="goodId"></goodsForm>
+    </div>
+</template>
+
+<script>
+import goodsForm from './components/form/goods.vue';
+export default {
+    name:'Administrator_addGoods',
+    components: {
+        goodsForm
+    },
+    props: {},
+    data() {
+        return {};
+    },
+    watch: {},
+    computed: {
+        type(){
+            let type = this.$route.query.type
+            if(type){
+                return Number(type)
+            }
+            return null
+        },
+        goodId(){
+            let goodId = this.$route.query.goodId
+            if(goodId){
+                return Number(goodId)
+            }
+            return null
+        },
+    },
+    created() {},
+    mounted() {},
+    methods: {},
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 595 - 0
src/views/backStageManage/goods/goods/components/form/goods.vue

@@ -0,0 +1,595 @@
+<template>
+    <div class="goodsForm">
+        <div class="button-container" v-if="model != 'detail'">
+                <el-button type="primary" size="small" :loading="btnLoading" @click="submitForm">提 交</el-button>
+                <el-button size="small"  @click="init">重 置</el-button>
+        </div>
+        <div class="form_center" v-loading="formLoading" element-loading-text="拼命加载中"  element-loading-spinner="el-icon-loading">
+            <el-form v-if="model !== 'detail'" ref="form" :model="form" :rules="rules" label-position="left" label-width="110px" :class="model == 'detail'?'pointer_events_none':''">
+                <el-form-item label="名称:" prop="goodName">
+                    <el-input
+                        v-model="form.goodName"
+                        placeholder="请输入商品名称"
+                    ></el-input>
+                </el-form-item>
+                <el-form-item label="类型:" prop="goodType">
+                    <el-select v-model="form.goodType" placeholder="请选择商品类型" @change="changeGoodsType" style="width: 100%;">
+                        <el-option v-for="(item, key) in goodTypes" :key="key" :label="item" :value="Number(key)"></el-option>
+                    </el-select>
+                </el-form-item>
+                <!-- 会员/功能清单 -->
+                <template v-if="form.goodType">
+                    <div class="vipOrFunList">
+                        <div class="warp">
+                            <template v-if="form.goodType == 1">
+                                <p class="title">
+                                    会员清单
+                                </p>
+                                <div style="height:calc(100% - 50px)">
+                                    <div>
+                                        <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="100px">
+                                            <el-form-item label="会员名称" prop="vipTypeName">
+                                                <el-input
+                                                    v-model="queryParams.vipTypeName"
+                                                    placeholder="请输入会员名称"
+                                                    clearable
+                                                />
+                                            </el-form-item>
+                                            <el-form-item>
+                                                <el-button type="primary" icon="el-icon-search" size="mini" @click="handleCurrentChange(1)">搜索</el-button>
+                                            </el-form-item>
+                                        </el-form>
+                                    </div>
+                                    <vipTable :tableData="tableData" :queryParams="queryParams" :loading="loading" :canChoose="true" :showCreateMessage="false">
+                                        <template slot="start_column" v-if="model != 'detail'">
+                                            <el-table-column type="index" label="序号" align="center" width="80px">
+                                                <template slot-scope="scope" v-if="reload">
+                                                    <el-radio-group v-model="goodId1" >
+                                                        <el-radio :label="scope.row.id">{{(scope.$index + 1) + ((queryParams.current - 1) * queryParams.size)}}</el-radio>
+                                                    </el-radio-group>
+                                                </template>
+                                            </el-table-column>
+                                        </template>
+                                    </vipTable>
+                                </div>
+                            </template>
+                            <!-- 功能清单 -->
+                            <template v-if="form.goodType == 2">
+                                <p class="title">
+                                    功能清单
+                                </p>
+                                <div style="height:calc(100% - 20px)">
+                                    <div>
+                                        <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="100px">
+                                            <el-form-item label="功能名称" prop="name">
+                                                <el-input
+                                                    v-model="queryParams.name"
+                                                    placeholder="请输入功能名称"
+                                                    clearable
+                                                />
+                                            </el-form-item>
+                                            <el-form-item>
+                                                <el-button type="primary" icon="el-icon-search" size="mini" @click="handleCurrentChange(1)">搜索</el-button>
+                                            </el-form-item>
+                                        </el-form>
+                                    </div>
+                                    <functionTable :tableData="tableData1" :loading="loading" :expandAll="true">
+                                        <template slot="start_column" v-if="model != 'detail'">
+                                            <template slot="start_column">
+                                            <el-table-column type="index" label="序号" align="center" width="80px">
+                                                <template slot-scope="scope" v-if="!scope.row.children || scope.row.children == 0">
+                                                    <el-radio-group v-model="goodId2" v-if="reload">
+                                                        <el-radio :label="scope.row.id">{{ }}</el-radio>
+                                                    </el-radio-group>
+                                                </template>
+                                            </el-table-column>
+                                        </template>
+                                        </template>
+                                    </functionTable>
+                                </div>
+                            </template>
+                            
+                        </div>
+                        <div class="pagination" style="margin-top:10px">
+                            <el-pagination background layout="total, prev, pager, next"
+                                :current-page.sync="queryParams.current"
+                                @current-change="handleCurrentChange" :total="total">
+                            </el-pagination>
+                        </div>
+                    </div>
+                    
+                </template>
+               
+                <el-form-item label="商品单位:" prop="goodUnit">
+                    <el-select v-model="form.goodUnit" placeholder="请选择商品单位" style="width: 100%;">
+                        <el-option v-for="(item, key) in goodsUnits" :key="key" :label="item" :value="Number(key)"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="单次售卖数量:" prop="goodCount">
+                    <el-input-number v-model="form.goodCount" controls-position="right" :min="1" style="width: 100%;"></el-input-number>
+                </el-form-item>
+                <el-form-item label="单价(元):" prop="price">
+                    <el-input-number v-model="form.price" :precision="2" controls-position="right" :min="0" style="width: 100%;"></el-input-number>
+                </el-form-item>
+                <el-form-item label="购买限制:" prop="goodLimits">
+                    <el-select v-model="form.goodLimits" clearable multiple  placeholder="请选择购买限制" style="width: 100%;">
+                        <el-option v-for="(item, index) in goodsLimit" :key="index" :label="item.limitName" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="营销策略:" prop="goodStrategies">
+                    <el-select v-model="form.goodStrategies" clearable multiple  placeholder="请选择营销策略" style="width: 100%;">
+                        <el-option v-for="(item, index) in goodsStrategy" :key="index" :label="item.strategyName" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="售卖时间:">
+                    <div class="saleTime">
+                      <myDateRangePicker type="datetime" value-format="yyyy-MM-dd HH:mm:ss" v-model="dataRange" customStyle="width:220px;" :startClearable="false" startPlaceholder="开始售卖时间" endPlaceholder="截止售卖时间"></myDateRangePicker> 
+                      <div class="description">截止售卖时间可不填,不填为永久</div> 
+                    </div>
+                </el-form-item>
+                <el-form-item label="是否上架:" prop="status">
+                     <el-radio-group v-model="form.status">
+                        <el-radio :label="0">下架</el-radio>
+                        <el-radio :label="1">上架</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+                <el-form-item label="备注:" prop="remark">
+                    <el-input type="textarea"
+                        v-model="form.remark"
+                        placeholder="请输入备注"
+                    ></el-input>
+                </el-form-item>
+            </el-form>
+            <el-form v-else ref="form" :model="form" :rules="rules" label-position="left" label-width="110px">
+                <el-form-item label="名称:" prop="goodName">
+                    <div>{{ form.goodName }}</div>
+                </el-form-item>
+                <el-form-item label="类型:" prop="goodType">
+                    <div>{{ form.goodTypeStr }}</div>
+                </el-form-item>
+                <!-- 会员清单 -->
+                <el-form-item label="商品信息:" prop="goodType">
+                    <div v-if="form.goodType == 1">
+                        <div v-if="form.vipMessage">
+                            <div v-if="form.vipMessage.vipTypeName"><b>会员名称:</b>{{ form.vipMessage.vipTypeName }}</div>
+                            <div v-if="form.vipMessage.remark"><b>备注:</b> {{ form.vipMessage.remark }}</div> 
+                            <div v-if="form.vipMessage.functions && form.vipMessage.functions.length">
+                                <b>会员功能:</b>{{ getFunctionNames(form.vipMessage.functions) }}
+                            </div>
+                        </div>
+                    </div>
+                    <div v-else-if="form.goodType == 2">
+                        <div v-if="form.functionMessage">
+                            <div v-if="form.functionMessage.name"><b>功能名称:</b>{{ form.functionMessage.name }}</div>
+                        </div>
+                    </div>
+                </el-form-item>
+               
+                <el-form-item label="单次售卖:" prop="goodCount">
+                    <div>{{ form.goodCount }}{{ form.goodUnitStr }}</div>
+                </el-form-item>
+                <el-form-item label="单价:" prop="price">
+                    <div v-if="form.price">
+                        {{ form.price }}元                      
+                    </div>
+                </el-form-item>
+                <el-form-item label="购买限制:" prop="goodLimits">
+                    <div v-if="form.goodByLimitVos && form.goodByLimitVos.length">
+                        {{ form.goodByLimitVos.map(item=>item.limitName).join('、') }}                        
+                    </div>
+                </el-form-item>
+                <el-form-item label="营销策略:" prop="goodStrategies">
+                    <div v-if="form.goodStrategyVos && form.goodStrategyVos.length">
+                        {{ form.goodStrategyVos.map(item=>item.strategyName).join('、') }}    
+                    </div>
+                </el-form-item>
+                <el-form-item label="售卖时间:">
+                    <div v-if="form.startSaleTime">
+                        {{ form.startSaleTime }} 至 {{ form.expireTime || '永久' }}
+                    </div>
+                    <div v-else>
+                        永久
+                    </div>
+                </el-form-item>
+                <el-form-item label="商品状态:" prop="status">
+                     <div>{{ form.statusStr }}</div>
+                </el-form-item>
+                <el-form-item label="备注:" prop="remark">
+                     <div>{{ form.remark }}</div>
+                </el-form-item>
+            </el-form>
+        </div>
+    </div>
+</template>
+
+<script>
+const currentForm = {
+    id:null,
+    goodName:'',
+    goodType:1,
+    goodId:null,
+    startSaleTime:'',
+    expireTime:'',
+    goodCount:1,
+    price:1.00,
+    goodUnit:2,
+    goodLimits:[],
+    goodStrategies:[],
+    status:1,
+    remark:''
+}
+import commonData from '../mixins/commonData'
+import {formatDate } from "@/utils";
+import vipTable from '@/views/backStageManage/application/vipType/components/views/table.vue'
+import functionTable from '@/views/backStageManage/application/vision/components/functionTable.vue'
+export default {
+    components: {
+        vipTable,
+        functionTable
+    },
+    mixins:[commonData],
+    props: {
+        id:"",
+        model:{
+            type:String,
+            default:"add"
+        },
+        type:{
+            type:Number,
+            default:null
+        },
+        goodId:{
+            type:Number,
+            default:null
+        }
+    },
+    data() {
+        return {
+            formLoading:false,
+            btnLoading: false,
+            // 表单参数
+            form: {},
+            // 表单校验
+            rules: {},
+            tableData:[],
+            goodId1:null,
+            goodId2:null,
+            tableData1:{},
+            goodsLimit:[],
+            goodsStrategy:[],
+            dataRange:{
+                startDate:null,
+                endDate:null
+            },
+            queryParams:{
+                current:1,
+                size:10
+            },
+            total:0,
+            loading:false,
+            reload:true
+        };
+    },
+    watch: {
+        id(){
+            if(this.$route.path != '/administrator/editGoods'){
+                return
+            }
+            if(this.form.id == this.id){
+                return
+            }
+            
+            this.init()
+        },
+        type(){
+           this.init() 
+        },
+        goodId(){
+           this.init() 
+        },
+    },
+    computed: {},
+    created() {},
+    async mounted() {
+        if(this.model !== 'detail'){
+            await this.queryGoodsLimit()
+            await this.queryGoodsStrategy()
+        }
+        this.init()
+    },
+    methods: {
+        //获取当前时间
+        getCurrentDate(){
+            return formatDate(new Date(),'YYYY-MM-DD HH:mm:ss')
+        },
+        //初始化当前页面
+        async init(){
+            this.formLoading = true
+            if(this.model == 'add'){
+                this.resetForm()
+            }else if(this.model == 'edit' || this.model == 'detail'){
+                await this.getById()
+            }
+            await this.changeGoodsType()
+            this.formLoading = false
+        },
+        //获取商品营销策略
+        async queryGoodsStrategy(){
+            await this.$api.queryGoodsStrategy().then(response=>{
+                if(response.code == 200){
+                    this.goodsStrategy = response.data
+                }
+            }).catch(error=>{
+                this.goodsStrategy = []
+            })
+        },
+        //获取商品购买限制
+        async queryGoodsLimit(){
+            await this.$api.queryGoodsLimit().then(response=>{
+                if(response.code == 200){
+                    this.goodsLimit = response.data
+                }
+            }).catch(error=>{
+                this.goodsLimit = []
+            })
+        },
+        //切换类型
+        changeGoodsType(){
+            this.queryParams = {
+                current:1,
+                size:10
+            }
+            this.getVipOrFunctionList()
+        },
+        //切换分页
+        handleCurrentChange(val){
+            this.queryParams.current = val
+            this.getVipOrFunctionList()
+        },
+        //获取会员或者功能列表
+        getVipOrFunctionList(){
+            if(this.form.goodType == 1){
+                this.getVipList()
+            }else if(this.form.goodType == 2){
+                this.getFunctionList()
+            }
+        },
+        //获取会员列表
+        getVipList(){
+            this.loading = true
+            this.$api.getVipList(this.queryParams).then(response=>{
+                if(response.code == 200){
+                    this.tableData = response.data.records
+                    this.total = response.data.total || 0
+                    this.loading = false
+                }
+            }).catch(error=>{
+                this.tableData = []
+                this.total = 0
+                this.loading = false
+            })
+        },
+        //获取功能列表
+        getFunctionList(){
+            this.loading = true;
+            this.$api.queryQiaoBiFunctionApi(this.queryParams).then(response=>{
+                if(response.code == 200){
+                    this.tableData1 = response.data
+                    this.total = response.pageColumn.total || 0
+                    var a = response.data.children
+                    for(var j = 0;j<a.length;j++){
+                        function l(data){
+                            if(data.hasOwnProperty('children')){
+                                for(var i = 0;i<data.children.length;i++){
+                                
+                                    if(data.hasOwnProperty('last')){
+                                        data.children[i].last=data.last+'/'+data.name
+                                    }else{
+                                        data.children[i].last=data.name
+                                    }
+                                    l(data.children[i])
+                                }
+                            }
+                        }
+                        l(a[j])
+                    }
+                    this.loading = false
+                }
+            }).catch(error=>{
+                this.tableData1 = {}
+                this.total = 0
+                this.loading = false
+            })
+        },
+
+        //查询商品信息
+        async getById(){
+            if(!this.id){
+                this.$message.error('编辑缺少参数')
+                return
+            }
+            var params = {
+                ids: this.id,
+            };
+            await this.$api.queryGoods(params).then(response=>{
+                if(response.code == 200){
+                    var data = response.data.records
+                    if(data && data.length>0){
+                        this.form = data[0]
+                        if(this.model == 'details'){
+                            return
+                        }
+                        //转载售卖时间
+                        this.dataRange = {
+                            startDate:this.form.startSaleTime || null,
+                            endDate:this.form.expireTime || null
+                        }
+                        //装载购买限制
+                        if(this.form.goodByLimitVos && this.form.goodByLimitVos.length>0){
+                            this.form.goodLimits = this.form.goodByLimitVos.map(item=>{
+                                return item.id
+                            })
+                        }else{
+                            this.$set(this.form,'goodLimits',[])
+                        }
+                        //装载营销策略
+                        if(this.form.goodStrategyVos && this.form.goodStrategyVos.length>0){
+                            this.form.goodStrategies = this.form.goodStrategyVos.map(item=>{
+                                return item.id
+                            })
+                        }else{
+                            this.$set(this.form,'goodStrategies',[])
+                        }
+                        //装载状态
+                        if(this.form.status != 0){
+                            this.$set(this.form,'status',1)
+                        }
+                        //装载商品id
+                        if(this.form.goodType == 1){
+                            if(this.form.vipMessage && this.form.vipMessage.id){
+                                this.$set(this,'goodId1',this.form.vipMessage.id)
+                            }
+                        }else if(this.form.goodType == 2){
+                            if(this.form.functionMessage && this.form.functionMessage.id){
+                                this.$set(this,'goodId2',this.form.functionMessage.id)
+                            }
+                        }
+                    }
+                }
+            }).catch(error=>{
+                this.resetForm()
+            })
+        },
+        //重置表单
+        resetForm(){
+            this.form = Object.assign({}, currentForm)
+            this.dataRange={
+                startDate:this.getCurrentDate(),
+                endDate:null
+            }
+            if(this.type){
+                this.$set(this.form,'goodType',this.type)
+            }
+            if(this.goodId){
+                if(this.type == 1){
+                    this.$set(this,'goodId1',this.goodId)
+                }else if(this.type == 2){
+                    this.$set(this,'goodId2',this.goodId)
+                }
+            }else{
+                this.$set(this,'goodId1',null)
+                this.$set(this,'goodId2',null)
+            }
+            
+            this.$refs['form'].resetFields();
+            this.reload = false
+            this.$nextTick(()=>{
+                this.reload = true
+            })
+        },
+        /** 提交按钮 */
+        submitForm: function() {
+            this.$refs['form'].validate((valid) => {
+                if (valid) {
+                    this.form.startSaleTime = this.dataRange.startDate
+                    this.form.expireTime = this.dataRange.endDate
+                    if(this.form.goodType == 1){
+                        this.form.goodId = this.goodId1
+                    }else if(this.form.goodType == 2){
+                        this.form.goodId = this.goodId2
+                    }
+                    this.btnLoading = true
+                    var a = '添加'
+                    var api = 'addGoods'
+                    if(this.model == "edit"){
+                        a = '编辑'
+                    }
+                    this.$api[api](this.form).then(response => {
+                        if (response.code === 200) {
+                            this.btnLoading = false
+                            this.$message.success( a + '成功');
+                            this.finish()
+                        }
+                    })
+                    .catch(error => {
+                        this.$message.error(a + '失败')
+                        this.btnLoading = false
+                    });
+                }
+            });
+        },
+        finish(){
+            if(this.model == 'add'){
+                this.resetForm()
+            }else{
+                this.$store.commit('removeHistoryPath',this.$route.path);
+                this.$store.commit('removeHistory',this.$route.path);
+                this.$router.push(
+                    {
+                        path:'/administrator/goods'
+                    }
+                )
+            }
+        },
+       
+    },
+};
+</script>
+<style lang="scss">
+.goodsForm{
+    .el-input-number{
+        .el-input__inner{
+            text-align: left !important;
+        }
+    }
+    
+}
+.form_center {
+    width: 900px;
+    margin: 0px auto;
+}
+.saleTime{
+    display: flex;
+    align-items: center;
+    .description{
+        color: red;
+        font-size: 12px;
+    }
+}
+
+.button-container {
+    max-width: 1200px;
+    display: flex;
+    justify-content:flex-end;
+    margin: 10px auto;
+    position:sticky;
+    top:10px,
+}
+.form_item_title{
+    color: black;
+    font-weight: bold;
+    font-size: 14px;
+    padding: 5px 0;
+    border-bottom: 1px solid white;
+}
+</style>
+<style lang="scss" scoped>
+    .vipOrFunList{
+        border:1px solid white;
+        padding:10px;
+        margin:10px 0;
+        border-radius:8px;
+        .warp{
+            height: 550px;
+            position: relative;
+            .title{
+                font-weight: bold;
+                margin: 0;
+                padding: 0 5px;
+                position: absolute;
+                top:-20px;
+                background: #c4c4df;
+            }
+        }
+    }
+</style>

+ 314 - 0
src/views/backStageManage/goods/goods/components/goods.vue

@@ -0,0 +1,314 @@
+<template>
+    <div class="height_100">
+      <el-container>
+        <el-header>
+          <div class="header">
+            <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="100px">
+                <el-form-item label="商品名称" prop="goodName">
+                    <el-input
+                        v-model="queryParams.goodName"
+                        placeholder="请输入商品名称"
+                        clearable
+                    />
+                </el-form-item>
+                <el-form-item label="商品类型" prop="goodType">
+                    <el-select v-model="queryParams.goodType" placeholder="请选择" clearable >
+                        <el-option v-for="(item, key) in goodTypes" :key="key" :label="item" :value="Number(key)"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="商品状态" prop="status">
+                    <el-select v-model="queryParams.status" placeholder="请选择" clearable >
+                        <el-option v-for="(item, key) in status" :key="key" :label="item" :value="Number(key)"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item>
+                    <el-button type="primary" icon="el-icon-search" size="mini" @click="search">搜索</el-button>
+                    <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+                </el-form-item>
+            </el-form>
+            
+            <el-row :gutter="10">
+              <el-col :span="1.5">
+                <el-button icon="el-icon-plus" size="small" @click="handleAdd">新增</el-button>
+              </el-col>
+            </el-row>
+          </div>
+        </el-header>
+        <el-main class="padding_10">
+          <el-table 
+            :data="tableData"
+            border
+            row-key="id"
+            style="width: 100%"
+            height="calc(100% - 0px)"
+            v-loading="loading"
+        >
+            <el-table-column type="index" label="序号" align="center" width="80px">
+              <template slot-scope="scope">
+                  <div>
+                      {{(scope.$index + 1) + ((queryParams.current - 1) * queryParams.size)}}
+                  </div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="goodName" label="商品名称" width="100px">
+              <template slot-scope="scope">
+                  <div>
+                    <el-link type="primary" @click="handleDetail(scope.row)">{{ scope.row.goodName }}</el-link>
+                  </div>
+                </template>
+            </el-table-column>
+            <el-table-column prop="goodTypeStr" label="商品类型" width="80px">
+              <template slot-scope="scope">
+                <div>
+                    {{ scope.row.goodTypeStr }}
+                  </div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="goodsMessage" label="商品信息" min-width="180px">
+              <template slot-scope="scope">
+                <div>
+                    <div v-if="scope.row.goodType == 1">
+                        <div v-if="scope.row.vipMessage">
+                            <div v-if="scope.row.vipMessage.vipTypeName"><b>会员名称:</b>{{ scope.row.vipMessage.vipTypeName }}</div>
+                            <div v-if="scope.row.vipMessage.remark"><b>备注:</b> {{ scope.row.vipMessage.remark }}</div> 
+                            <div v-if="scope.row.vipMessage.functions && scope.row.vipMessage.functions.length">
+                                <b>会员功能:</b>{{ getFunctionNames(scope.row.vipMessage.functions) }}
+                            </div>
+                        </div>
+                        
+                    </div>
+                    <div v-else-if="scope.row.goodType == 2">
+                        <div v-if="scope.row.functionMessage">
+                            <div v-if="scope.row.functionMessage.name"><b>功能名称:</b>{{ scope.row.functionMessage.name }}</div>
+                        </div>
+                    </div>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="购买相关信息" width="250px">
+              <template slot-scope="scope">
+                <div>
+                    <div v-if="scope.row.goodByLimitVos && scope.row.goodByLimitVos.length">
+                        <b>购买限制:</b>{{ scope.row.goodByLimitVos.map(item=>item.limitName).join('、') }}                        
+                    </div>
+                    <div v-if="scope.row.goodStrategyVos && scope.row.goodStrategyVos.length">
+                        <b>营销策略:</b>{{ scope.row.goodStrategyVos.map(item=>item.strategyName).join('、') }}    
+                    </div>
+                    <div>
+                        <b>单次售卖:</b>{{ scope.row.goodCount }}{{ scope.row.goodUnitStr }}    
+                    </div>
+                    <div v-if="scope.row.price">
+                        <b>单价:</b>{{ scope.row.price }}元   
+                    </div>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="startSaleTime" label="售卖时间范围" min-width="100px">
+                <template slot-scope="scope">
+                    <div v-if="scope.row.startSaleTime">
+                        {{ scope.row.startSaleTime }} 至 {{ scope.row.expireTime || '永久' }}
+                    </div>
+                </template>
+            </el-table-column>
+            <el-table-column prop="statusStr" label="状态" width="100px"></el-table-column>
+            <el-table-column prop="createName" label="创建人" width="100px"></el-table-column>
+            <el-table-column prop="createTime" label="创建时间" width="160px"></el-table-column>
+            <el-table-column prop="remark" label="备注" width="160px"></el-table-column>
+            <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+              <template slot-scope="scope">
+                <el-button
+                    v-if="scope.row.status == 0"
+                    size="mini"
+                    type="text"
+                    icon="iconfont icon-shangjia"
+                    @click="updateGoodsStatus(scope.row,1)"
+                >上架</el-button>
+                <el-button
+                    v-else
+                    size="mini"
+                    type="text"
+                    icon="iconfont icon-xiajia"
+                    @click="updateGoodsStatus(scope.row,0)"
+                >下架</el-button>
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-edit"
+                  @click="handleEdit(scope.row)"
+                >修改</el-button>
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handleDelete(scope.row)"
+                >  删除</el-button>
+              </template>
+            </el-table-column>
+        </el-table>
+        </el-main>
+        <el-footer class="pagination">
+          <el-pagination background layout="total, sizes, prev, pager, next, jumper"
+            :current-page.sync="queryParams.current" :page-size.sync="queryParams.size"
+            @current-change="handleCurrentChange" @size-change="changeSize" :total="total">
+          </el-pagination>
+        </el-footer>
+      </el-container>
+    </div>
+</template>
+  
+<script>
+  const searchForm = {
+    status:null,
+    goodType:null,
+    goodName:''
+  }
+  import commonData from './mixins/commonData'
+  export default {
+    components: {},
+    props: {},
+    mixins:[commonData],
+    data() {
+      return {
+        // 遮罩层
+        loading: false,
+        tableData: [],
+        // 查询参数
+        queryParams: {
+          current: 1,
+          size: 10,
+          ...searchForm
+        },
+        total:0,
+      };
+    },
+    watch: {},
+    computed: {},
+    created() {},
+    mounted() {
+      this.getList()
+    },
+    methods: {
+        
+        /** 查询vip类型列表 */
+        getList() {
+            this.loading = true;
+            this.$api.queryGoods(this.queryParams).then(response=>{
+            if(response.code == 200){
+                this.tableData = response.data.records
+                this.total = response.data.total || 0
+                this.loading = false
+            }
+            }).catch(error=>{
+                this.tableData = []
+                this.total = 0
+                this.loading = false
+            })
+        },
+        //切换分页
+        handleCurrentChange(value){
+            this.queryParams.current = value
+            this.getList()
+        },
+        //切换页大小
+        changeSize(value){
+            this.queryParams.size = value
+            this.queryParams.current = 1
+            this.getList()
+        },
+        /** 新增按钮操作 */
+        handleAdd(row) {
+            this.$router.push('/administrator/addGoods');
+        },
+        //上架下架
+        updateGoodsStatus(row,status){
+            this.upperOrLowerShelves([row.id],status)
+        },
+        upperOrLowerShelves(ids,status){
+            var str = '下架'
+            if(status == 1){
+                str = '上架'
+            }
+            this.$confirm(`确认${str}选择的数据吗?`, '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            }).then(() => {
+                var params = {
+                    ids:ids,
+                    status:status
+                }
+                this.$api.updateGoodsStatus(params).then(response=>{
+                    if(response.code == 200){
+                        this.$message.success(`${str}成功`)
+                        this.getList()
+                    }
+                }).catch(error=>{
+                    this.$message.error(`${str}失败`)
+                })
+            })
+        },
+        // 删除商品
+        handleDelete(row) {
+            this.removeGoods([row.id]);
+        },
+        removeGoods(ids){
+            this.$confirm('确认删除选择数据吗?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            }).then(() => {
+                var params = ids
+                this.$api.deleteGoods(params).then(response=>{
+                    if(response.code == 200){
+                        this.$message.success('删除成功')
+                        this.getList()
+                    }
+                }).catch(error=>{
+                    this.$message.error('删除失败')
+                })
+            })
+        },
+        handleEdit(row) {
+            this.$router.push({ 
+            path: '/administrator/editGoods', 
+            query: {
+                id: row.id
+            }
+            });
+        },
+        handleDetail(row) {
+            this.$router.push({ 
+                path: '/administrator/goodsDetails', 
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        /** 搜索按钮操作 */
+        search() {
+            this.queryParams.current = 1;
+            this.getList();
+        },
+        /** 重置按钮操作 */
+        resetQuery() {
+            for(let key in searchForm){
+            this.$set(this.queryParams,key,searchForm[key])
+            }
+            this.search();
+        },
+    },
+  };
+</script>
+<style lang="scss" scoped>
+  .header{
+    width: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+  }
+  .foot{
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+  }
+</style>

+ 22 - 0
src/views/backStageManage/goods/goods/components/mixins/commonData.js

@@ -0,0 +1,22 @@
+import getFunctionNames from './getFunctionNames'
+export default{
+    mixins:[getFunctionNames],
+    data() {
+        return {
+            goodTypes:{
+                1:'会员',
+                2:'功能',
+            }
+        }
+    },
+    computed:{
+        status(){
+            return this.$commonJS.arrToObjByDict('GOOD_STATUS')
+        },
+        goodsUnits(){
+            return this.$commonJS.arrToObjByDict('GOOD_UNIT')
+        },
+    },
+    methods: {
+    },
+}

+ 38 - 0
src/views/backStageManage/goods/goods/components/mixins/getFunctionNames.js

@@ -0,0 +1,38 @@
+
+export default{
+    data() {
+        return {
+        }
+    },
+    computed:{},
+    methods: {
+        getFunctionNamesDeeps(data,last,names){
+            for(var i = 0;i<data.length;i++){
+                if(last){
+                    data[i].last=last+'/'+data[i].name
+                }else{
+                    data[i].last=data[i].name
+                }
+                if(data[i].canUseCount || data[i].canUseCount == 0){
+                    names.push(data[i].last + `(${data[i].canUseCount}次/月)`)
+                }else{
+                    names.push(data[i].last)
+                }
+                
+                if(data[i].hasOwnProperty('children')){
+                  this.getFunctionNamesDeeps(data[i].children,data[i].last,names)  
+                }
+            }
+        },
+        //获取功能名称字符串
+        getFunctionNames(functions){
+            var arr = []
+            if(!functions || functions.length == 0){
+                return ''
+            }
+            this.getFunctionNamesDeeps(functions,'',arr)  
+            return arr.join(',')
+            
+        },
+    },
+}

+ 30 - 0
src/views/backStageManage/goods/goods/editGoods.vue

@@ -0,0 +1,30 @@
+<template>
+    <div>
+        <goodsForm :id="id" model="edit"></goodsForm>
+    </div>
+</template>
+
+<script>
+import goodsForm from './components/form/goods.vue';
+export default {
+    name:'Administrator_editGoods',
+    components: {
+        goodsForm
+    },
+    props: {},
+    data() {
+        return {};
+    },
+    watch: {},
+    computed: {
+        id() {
+            return this.$route.query.id;
+        },
+    },
+    created() {},
+    mounted() {},
+    methods: {},
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 30 - 0
src/views/backStageManage/goods/goods/goodsDetails.vue

@@ -0,0 +1,30 @@
+<template>
+    <div>
+        <goodsForm :id="id" model="detail"></goodsForm>
+    </div>
+</template>
+
+<script>
+import goodsForm from './components/form/goods.vue';
+export default {
+    name:'Administrator_goodsDetails',
+    components: {
+        goodsForm
+    },
+    props: {},
+    data() {
+        return {};
+    },
+    watch: {},
+    computed: {
+        id() {
+            return this.$route.query.id;
+        },
+    },
+    created() {},
+    mounted() {},
+    methods: {},
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 26 - 0
src/views/backStageManage/goods/goods/index.vue

@@ -0,0 +1,26 @@
+<template>
+  <div class="height_100">
+    <goods></goods>
+  </div>
+</template>
+
+<script>
+import goods from './components/goods.vue';
+export default {
+  components: {
+    goods
+  },
+  props: {},
+  data() {
+    return {
+    };
+  },
+  watch: {},
+  computed: {},
+  created() {},
+  mounted() {},
+  methods: {},
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 1 - 1
src/views/backStageManage/layout/Layout.vue

@@ -150,7 +150,7 @@ export default {
     },
     },
     getDict() {
     getDict() {
       var params = {
       var params = {
-        types:['TENANT_TYPE','QIAO_BI_VERSION_STATUS','QIAO_BI_PAID_CODE_STATUS','QIAO_BI_BUSINESS_TASK_TYPE','QIAO_BI_BUSINESS_TASK_STATE','QIAO_BI_BUSINESS_TASK_RESULT','QIAO_BI_VERSION_UPDATE_TYPE']
+        types:['TENANT_TYPE','QIAO_BI_VERSION_STATUS','QIAO_BI_PAID_CODE_STATUS','QIAO_BI_BUSINESS_TASK_TYPE','QIAO_BI_BUSINESS_TASK_STATE','QIAO_BI_BUSINESS_TASK_RESULT','QIAO_BI_VERSION_UPDATE_TYPE','GOOD_STATUS','GOOD_UNIT','GOOD_GROUP_BY']
       }
       }
       this.$api.getSysDictByType(params).then(response => {
       this.$api.getSysDictByType(params).then(response => {
         this.$store.commit('SET_TENANT_TYPE', response.data.TENANT_TYPE)
         this.$store.commit('SET_TENANT_TYPE', response.data.TENANT_TYPE)

+ 251 - 0
src/views/backStageManage/paymentAndStat/paymentRecord/components/paymentRecord.vue

@@ -0,0 +1,251 @@
+<template>
+    <div class="height_100">
+      <el-container>
+        <el-header>
+          <div class="header">
+            <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="100px">
+                <el-form-item label="企业名称" prop="tenantName">
+                    <el-input
+                        v-model="queryParams.tenantName"
+                        placeholder="请输入企业名称"
+                        clearable
+                    />
+                </el-form-item>
+                <el-form-item label="用户" prop="personName">
+                    <el-input
+                        v-model="queryParams.personName"
+                        placeholder="请输入用户名称或手机号"
+                        clearable
+                    />
+                </el-form-item>
+                <el-form-item label="支付时间">
+                    <myDateRangePicker value-format="yyyy-MM-dd" v-model="dataRange"></myDateRangePicker>
+                </el-form-item>
+                <el-form-item>
+                    <el-button type="primary" icon="el-icon-search" size="mini" @click="search">搜索</el-button>
+                    <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+                </el-form-item>
+            </el-form>
+            
+            <el-row :gutter="10">
+            </el-row>
+          </div>
+        </el-header>
+        <el-main class="padding_10">
+          <el-table 
+            :data="tableData"
+            border
+            row-key="id"
+            style="width: 100%"
+            height="calc(100% - 0px)"
+            v-loading="loading"
+        >
+            <el-table-column type="index" label="序号" align="center" width="80px">
+              <template slot-scope="scope">
+                  <div>
+                      {{(scope.$index + 1) + ((queryParams.current - 1) * queryParams.size)}}
+                  </div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="tradeNo" label="订单号" width="150px">
+              <template slot-scope="scope">
+                  <div>
+                    <el-link type="primary" @click="handleDetail(scope.row)">{{ scope.row.tradeNo }}</el-link>
+                  </div>
+                </template>
+            </el-table-column>
+            <el-table-column prop="goodsMessage" label="订单信息" min-width="180px">
+              <template slot-scope="scope">
+                <div v-if="scope.row.goodList && scope.row.goodList.length">
+                    <div v-for="(item, index) in scope.row.goodList" :key="index" class="goodsMessage">
+                        <div class="left">
+                            <div class="goodName" :title="item.goods.goodName">{{item.goods.goodName}}</div>
+                            <div class="goodNum">x{{item.num}}</div>
+                        </div>
+                        <div class="right">
+                            <div class="payPrice">¥{{item.totalPrice || 0}}</div>
+                            <div class="originalPrice" v-if="item.orgPrice && (item.orgPrice > item.totalPrice)">¥{{item.orgPrice || 0}}</div>
+                        </div>
+                    </div>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="orgPrice" label="原始价格" width="100px">
+                <template slot-scope="scope" >
+                    <div>
+                        {{scope.row.orgPrice}}<span v-if="scope.row.orgPrice">元</span>
+                    </div>
+                </template>
+            </el-table-column>
+            <el-table-column prop="orderStatusStr" label="状态" width="100px"></el-table-column>
+            <el-table-column prop="truePrice" label="支付价格" width="100px">
+                <template slot-scope="scope" >
+                    <div>
+                        {{scope.row.truePrice}}<span v-if="scope.row.truePrice">元</span>
+                    </div>
+                </template>
+            </el-table-column>
+            <el-table-column prop="payTime" label="支付时间" width="160px"></el-table-column>
+            <el-table-column prop="createName" label="用户" width="160px"></el-table-column>
+            <el-table-column prop="createTime" label="创建时间" width="160px"></el-table-column>
+            <!-- <el-table-column label="操作" align="center" class-name="small-padding fixed-width"></el-table-column> -->
+        </el-table>
+        </el-main>
+        <el-footer class="pagination">
+          <el-pagination background layout="total, sizes, prev, pager, next, jumper"
+            :current-page.sync="queryParams.current" :page-size.sync="queryParams.size"
+            @current-change="handleCurrentChange" @size-change="changeSize" :total="total">
+          </el-pagination>
+        </el-footer>
+      </el-container>
+    </div>
+</template>
+  
+<script>
+  const searchForm = {
+    tenantName:'',
+    personName:'',
+    startTime:'',
+    endTime:'',
+    invitePersonName:''
+  }
+  export default {
+    components: {},
+    props: {},
+    mixins:[],
+    data() {
+      return {
+        // 遮罩层
+        loading: false,
+        dataRange:{
+            startDate:null,
+            endDate:null
+        },
+        tableData: [],
+        // 查询参数
+        queryParams: {
+          current: 1,
+          size: 10,
+          ...searchForm
+        },
+        total:0,
+      };
+    },
+    watch: {},
+    computed: {},
+    created() {},
+    mounted() {
+      this.getList()
+    },
+    methods: {
+
+        /** 查询支付记录 */
+        getList() {
+            this.loading = true;
+            this.queryParams.startTime = this.dataRange.startDate
+            this.queryParams.endTime = this.dataRange.endDate
+            this.$api.queryPayRecord(this.queryParams).then(response=>{
+                if(response.code == 200){
+                    this.tableData = response.data.records
+                    this.total = response.data.total || 0
+                    this.loading = false
+                }
+            }).catch(error=>{
+                this.tableData = []
+                this.total = 0
+                this.loading = false
+            })
+        },
+        //切换分页
+        handleCurrentChange(value){
+            this.queryParams.current = value
+            this.getList()
+        },
+        //切换页大小
+        changeSize(value){
+            this.queryParams.size = value
+            this.queryParams.current = 1
+            this.getList()
+        },
+       
+        handleDetail(row) {
+            // this.$router.push({ 
+            // path: '/administrator/paymentCodeDetail', 
+            // query: {
+            //     id: row.id
+            // }
+            // });
+        },
+        /** 搜索按钮操作 */
+        search() {
+            this.queryParams.current = 1;
+            this.getList();
+        },
+        /** 重置按钮操作 */
+        resetQuery() {
+            for(let key in searchForm){
+                this.$set(this.queryParams,key,searchForm[key])
+            }
+            this.dataRange = {
+                startDate:null,
+                endDate:null
+            }
+            this.search();
+        },
+    },
+  };
+</script>
+<style lang="scss" scoped>
+  .header{
+    width: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+  }
+  .foot{
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+  }
+  .goodsMessage{
+    display: flex;
+    justify-content: space-between;
+    background: rgb(250, 248, 248);
+    padding: 5px;
+    border-radius: 5px;
+    margin: 5px 0;
+    .left{
+        width: calc(100% - 100px);
+        min-width: 120px;
+        display: flex;
+        align-items: center;
+        .goodName{
+            color: black;
+            max-width: calc(100% - 10px);
+            overflow: hidden;
+            white-space: nowrap;
+            text-overflow:ellipsis;
+        }
+        .goodNum{
+            // font-size: 10px;
+            margin-left: 5px;
+            color: rgb(184, 181, 181);
+        }
+    }
+    .right{
+        margin-left: 5px;
+        display: flex;
+        align-items: center;
+        min-width: 70px;
+        .payPrice{
+            color: black;
+        }
+        .originalPrice{
+            margin-left: 5px;
+            font-size: 10px;
+            color: rgb(184, 181, 181);
+            text-decoration: line-through;
+        }
+    }
+  }
+</style>

+ 26 - 0
src/views/backStageManage/paymentAndStat/paymentRecord/index.vue

@@ -0,0 +1,26 @@
+<template>
+  <div class="height_100">
+    <paymentRecord></paymentRecord>
+  </div>
+</template>
+
+<script>
+import paymentRecord from './components/paymentRecord.vue';
+export default {
+  components: {
+    paymentRecord
+  },
+  props: {},
+  data() {
+    return {
+    };
+  },
+  watch: {},
+  computed: {},
+  created() {},
+  mounted() {},
+  methods: {},
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 11 - 0
src/views/backStageManage/paymentAndStat/statPayRecord/components/mixins/commonData.js

@@ -0,0 +1,11 @@
+export default{
+    data() {
+        return {
+        }
+    },
+    computed:{
+        groupBys(){
+            return this.$commonJS.arrToObjByDict('GOOD_GROUP_BY')
+        },
+    }
+}

+ 168 - 0
src/views/backStageManage/paymentAndStat/statPayRecord/components/statPayRecord.vue

@@ -0,0 +1,168 @@
+<template>
+    <div class="height_100">
+      <el-container>
+        <el-header>
+          <div class="header">
+            <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="100px">
+                <el-form-item label="支付时间">
+                    <myDateRangePicker value-format="yyyy-MM-dd" v-model="dataRange"></myDateRangePicker>
+                </el-form-item>
+                <el-form-item label="统计类型" prop="groupBy">
+                    <el-select v-model="queryParams.groupBy" placeholder="请选择" @change="search">
+                        <el-option v-for="(item, key) in groupBys" :key="key" :label="item" :value="Number(key)"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item>
+                    <el-button type="primary" icon="el-icon-search" size="mini" @click="search">搜索</el-button>
+                    <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+                </el-form-item>
+            </el-form>
+            
+            <el-row :gutter="10">
+            </el-row>
+          </div>
+        </el-header>
+        <el-main class="padding_10">
+          <el-table 
+            :data="tableData"
+            border
+            row-key="id"
+            style="width: 100%"
+            height="calc(100% - 0px)"
+            v-loading="loading"
+        >
+            <el-table-column type="index" label="序号" align="center" width="80px">
+              <template slot-scope="scope">
+                  <div>
+                      {{(scope.$index + 1) + ((queryParams.current - 1) * queryParams.size)}}
+                  </div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="groupKey" :label="queryParams.groupBy == 5?'邀请人':'时间'"></el-table-column>
+            <el-table-column prop="personNum" :label="queryParams.groupBy == 5?'被邀请人数量':'付款人数'"></el-table-column>
+            <el-table-column prop="groupPrice" label="付款金额">
+                <template slot-scope="scope" >
+                    <div>
+                        {{scope.row.groupPrice}}<span v-if="scope.row.groupPrice">元</span>
+                    </div>
+                </template>
+            </el-table-column>
+           
+        </el-table>
+        </el-main>
+        <el-footer class="pagination">
+          <el-pagination background layout="total, sizes, prev, pager, next, jumper"
+            :current-page.sync="queryParams.current" :page-size.sync="queryParams.size"
+            @current-change="handleCurrentChange" @size-change="changeSize" :total="total">
+          </el-pagination>
+        </el-footer>
+      </el-container>
+    </div>
+</template>
+  
+<script>
+  const searchForm = {
+    startTime:null,
+    endTime:null,
+    groupBy:2
+  }
+    import commonData from './mixins/commonData'
+  export default {
+    components: {},
+    props: {},
+    mixins:[commonData],
+    data() {
+      return {
+        // 遮罩层
+        loading: false,
+        dataRange:{
+            startDate:null,
+            endDate:null
+        },
+        tableData: [],
+        // 查询参数
+        queryParams: {
+          current: 1,
+          size: 10,
+          ...searchForm
+        },
+        total:0,
+      };
+    },
+    watch: {},
+    computed: {},
+    created() {},
+    mounted() {
+      this.getList()
+    },
+    methods: {
+
+        /** 查询支付记录 */
+        getList() {
+            this.loading = true;
+            this.queryParams.startTime = this.dataRange.startDate
+            this.queryParams.endTime = this.dataRange.endDate
+            this.$api.groupPayRecord(this.queryParams).then(response=>{
+                if(response.code == 200){
+                    this.tableData = response.data.records
+                    this.total = response.data.total || 0
+                    this.loading = false
+                }
+            }).catch(error=>{
+                this.tableData = []
+                this.total = 0
+                this.loading = false
+            })
+        },
+        //切换分页
+        handleCurrentChange(value){
+            this.queryParams.current = value
+            this.getList()
+        },
+        //切换页大小
+        changeSize(value){
+            this.queryParams.size = value
+            this.queryParams.current = 1
+            this.getList()
+        },
+       
+        handleDetail(row) {
+            // this.$router.push({ 
+            // path: '/administrator/paymentCodeDetail', 
+            // query: {
+            //     id: row.id
+            // }
+            // });
+        },
+        /** 搜索按钮操作 */
+        search() {
+            this.queryParams.current = 1;
+            this.getList();
+        },
+        /** 重置按钮操作 */
+        resetQuery() {
+            for(let key in searchForm){
+                this.$set(this.queryParams,key,searchForm[key])
+            }
+            this.dataRange = {
+                startDate:null,
+                endDate:null
+            }
+            this.search();
+        },
+    },
+  };
+</script>
+<style lang="scss" scoped>
+  .header{
+    width: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+  }
+  .foot{
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+  }
+</style>

+ 26 - 0
src/views/backStageManage/paymentAndStat/statPayRecord/index.vue

@@ -0,0 +1,26 @@
+<template>
+  <div class="height_100">
+    <statPayRecord></statPayRecord>
+  </div>
+</template>
+
+<script>
+import statPayRecord from './components/statPayRecord.vue';
+export default {
+  components: {
+    statPayRecord
+  },
+  props: {},
+  data() {
+    return {
+    };
+  },
+  watch: {},
+  computed: {},
+  created() {},
+  mounted() {},
+  methods: {},
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 1 - 1
src/views/backStageManage/paymentCode/paymentCode/components/paymentCode.vue

@@ -208,7 +208,7 @@
       /** 重置按钮操作 */
       /** 重置按钮操作 */
       resetQuery() {
       resetQuery() {
         for(let key in searchForm){
         for(let key in searchForm){
-          this.$set(this.queryParams,key,'')
+          this.$set(this.queryParams,key,searchForm[key])
         }
         }
         this.search();
         this.search();
       },
       },