Pārlūkot izejas kodu

Merge remote-tracking branch 'origin/developer' into developerC

zhengjinyi 1 mēnesi atpakaļ
vecāks
revīzija
e0547f8a49
33 mainītis faili ar 2990 papildinājumiem un 183 dzēšanām
  1. 1 0
      .eslintrc.js
  2. BIN
      public/temp/供应商报表文件上传模板.zip
  3. BIN
      public/temp/供应商报表文件上传模板/供应商数据报表模板.xlsx
  4. 39 0
      src/api/activity/activity.js
  5. 32 0
      src/api/serviceSettlement/goods.js
  6. 41 0
      src/api/user/club/club.js
  7. 12 0
      src/api/user/customer/customer.js
  8. 2 0
      src/router/index.js
  9. 31 0
      src/router/modules/activity.js
  10. 17 0
      src/router/modules/serviceSettlement.js
  11. 14 1
      src/router/modules/user.js
  12. 78 0
      src/views/operate/activity/components/zi-dialog.vue
  13. 402 0
      src/views/operate/activity/list.vue
  14. 201 0
      src/views/operate/activity/ziyalan-list.vue
  15. 172 0
      src/views/serviceSettlement/components/goods-dialog.vue
  16. 197 0
      src/views/serviceSettlement/goods/index.vue
  17. 9 0
      src/views/serviceSettlement/list/edit.vue
  18. 22 12
      src/views/serviceSettlement/list/index.vue
  19. 8 1
      src/views/serviceSettlement/mixin/index.js
  20. 179 0
      src/views/user/club-portrait/components/bar-echarts.vue
  21. 261 0
      src/views/user/club-portrait/components/club-dialog.vue
  22. 75 0
      src/views/user/club-portrait/components/hot-tips.vue
  23. 126 0
      src/views/user/club-portrait/components/pei-echarts.vue
  24. 124 0
      src/views/user/club-portrait/components/select-time.vue
  25. 455 0
      src/views/user/club-portrait/index.vue
  26. 134 0
      src/views/user/club-portrait/mixins/index.js
  27. 312 147
      src/views/user/club/list.vue
  28. 5 1
      src/views/user/customer/components/share-dialog.vue
  29. 3 3
      src/views/user/customer/customer-goods-list.vue
  30. 4 4
      src/views/user/customer/customer-popup-edit.vue
  31. 26 6
      src/views/user/customer/market-report-list.vue
  32. 7 7
      src/views/user/record/list.vue
  33. 1 1
      src/views/wechat/components/menusList.vue

+ 1 - 0
.eslintrc.js

@@ -15,6 +15,7 @@ module.exports = {
   //it is base on https://github.com/vuejs/eslint-config-vue
   //plugins: ['prettier'],
   rules: {
+    "quotes": ["warn", "single", { "avoidEscape": true }],
     //'prettier/prettier': 0, // 会优先采用prettierrc.json的配置,不符合规则会提示错误
     'vue/max-attributes-per-line': [
       2,

BIN
public/temp/供应商报表文件上传模板.zip


BIN
public/temp/供应商报表文件上传模板/供应商数据报表模板.xlsx


+ 39 - 0
src/api/activity/activity.js

@@ -0,0 +1,39 @@
+import request from '@/utils/request'
+
+/**
+ * 获取绑定紫亚兰门票机构列表
+ * @param {*} pageNum 页码
+ * @param {*} pageSize 条数
+ * @returns
+ */
+export function getZylTicketList(params) {
+  return request({
+    url: '/user/zyl/ticket/list',
+    method: 'get',
+    params
+  })
+}
+/**
+ * 门票打卡详情
+ * @param {*} userId 机构用户ID
+ * @returns
+ */
+export function getZylTicketDetail(params) {
+  return request({
+    url: '/user/zyl/ticket/detail',
+    method: 'get',
+    params
+  })
+}
+/**
+ * 修改礼品领取状态
+ * @param {*} userId 机构用户ID
+ * @returns
+ */
+export function postZylUpdateGift(params) {
+  return request({
+    url: '/user/zyl/update/gift',
+    method: 'get',
+    params
+  })
+}

+ 32 - 0
src/api/serviceSettlement/goods.js

@@ -0,0 +1,32 @@
+import request from '@/utils/request'
+
+export const getProductList = (params) => request({
+  url: '/providers/product/list',
+  method: 'get',
+  params
+})
+
+export const addProducts = (params) => request({
+  url: '/providers/add/products',
+  method: 'get',
+  params
+})
+
+export const getProvidersProducts = (params) => request({
+  url: '/providers/products',
+  method: 'get',
+  params
+})
+
+/**
+ * 删除供应商相关商品
+ * @param {*} id
+ * @returns
+ */
+export function delProduct(params) {
+  return request({
+    url: '/providers/del/products',
+    method: 'get',
+    params
+  })
+}

+ 41 - 0
src/api/user/club/club.js

@@ -0,0 +1,41 @@
+import request from '@/utils/request'
+
+/**
+ * 机构列表
+ * @param {*} clubId // 机构Id
+ * @param {*} name   // 机构名称
+ * @param {*} linkMan// 联系人
+ * @param {*} contractMobile// 手机号
+ * @param {*} status // 状态
+ * @param {*} userIdentity // 机构级别
+ * @param {*} startTime  // 注册开始时间
+ * @param {*} endTime    // 注册结束时间
+ * @param {*} newDeal    // 是否新分配机构
+ * @param {*} spId     // 协销Id
+ * @param {*} allocationStartTime // 分配开始时间
+ * @param {*} allocationEndTime   // 分配结束时间
+ * @param {*} trendsLabel    // 动态标签
+ * @param {*} stateLabel    // 静态标签
+ * @param {*} pageNum,
+ * @param {*} pageSize
+ * @returns
+ */
+export function getClubList(params) {
+  return request({
+    url: '/user/club/list',
+    method: 'get',
+    params
+  })
+}
+/**
+ * 静态动态标签筛选项
+ * @param {*} dynamicStatus 0:动态标签 1:静态标签
+ * @returns
+ */
+export function getClubLabel(params) {
+  return request({
+    url: '/user/club/label',
+    method: 'get',
+    params
+  })
+}

+ 12 - 0
src/api/user/customer/customer.js

@@ -640,3 +640,15 @@ export function getShopProductList(params) {
     params
   })
 }
+/**
+ * 生成预览码
+ * @param {*} id
+ * @returns
+ */
+export function getMarketPreviewCode(params) {
+  return request({
+    url: '/user/market/preview',
+    method: 'get',
+    params
+  })
+}

+ 2 - 0
src/router/index.js

@@ -17,6 +17,7 @@ import keywordLibraryRouter from './modules/keywordLibrary'
 import memberRouter from './modules/member'
 import mallProtraitRouter from './modules/mallPortrait'
 import serviceSettlement from './modules/serviceSettlement'
+import activity from './modules/activity'
 import dataBase from './modules/database'
 // import tableRouter from './modules/table'
 // import nestedRouter from './modules/nested'
@@ -107,6 +108,7 @@ export const asyncRoutes = [
   keywordLibraryRouter,
   mallProtraitRouter,
   serviceSettlement,
+  activity,
   dataBase
 ]
 

+ 31 - 0
src/router/modules/activity.js

@@ -0,0 +1,31 @@
+/** When your routing table is too long, you can split it into small modules **/
+
+import Layout from '@/layout'
+
+const keywordLibraryRouter = {
+  path: '/operate',
+  component: Layout,
+  redirect: '/operate/activity',
+  alwaysShow: true, // will always show the root menu
+  name: 'OperateActivity', // name必须和后台配置一致,不然匹配不到
+  meta: { title: '运营专区' },
+  children: [
+    {
+      path: 'activity',
+      name: 'ActivityMenu',
+      redirect: '/operate/activity/ziyalan-list',
+      alwaysShow: true,
+      component: () => import('@/views/index'),
+      meta: { title: '活动专题', useDefault: true },
+      children: [
+        {
+          path: 'ziyalan-list',
+          name: 'ZiyalanList',
+          component: () => import('@/views/operate/activity/ziyalan-list'),
+          meta: { title: '紫亚兰活动专栏' }
+        }
+      ]
+    }
+  ]
+}
+export default keywordLibraryRouter

+ 17 - 0
src/router/modules/serviceSettlement.js

@@ -29,6 +29,23 @@ export default {
           name: 'SettlementEdit',
           meta: { title: '编辑列表', noCache: true, activeMenu: '/service/settlement' }
         },
+        {
+          path: 'goods',
+          hidden: true,
+          component: () => import('@/views/index'),
+          name: 'SettlementGoods',
+          redirect: '/service/settlement/goods/list',
+          meta: { title: '商品管理', noCache: true, activeMenu: '/service/settlement' },
+          children: [
+            {
+              path: 'list',
+              hidden: true,
+              component: () => import('@/views/serviceSettlement/goods/index.vue'),
+              name: 'SettlementGoodsList',
+              meta: { title: '服务商商品列表', noCache: true, activeMenu: '/service/settlement' }
+            }
+          ]
+        },
         {
           path: 'contract',
           hidden: true,

+ 14 - 1
src/router/modules/user.js

@@ -10,11 +10,24 @@ const userRouter = {
   name: 'UserSitting', // name必须和后台配置一致,不然匹配不到
   meta: { title: '用户管理', icon: 'user' },
   children: [
+    {
+      path: 'club-list',
+      name: 'ClubList',
+      component: () => import('@/views/user/club/list'),
+      meta: { title: '机构列表', icon: 'international', activeMenu: '/user/list' }
+    },
     {
       path: 'record-list',
       name: 'RecordList',
       component: () => import('@/views/user/record/list'),
-      meta: { title: '用户行为记录', icon: 'international', activeMenu: '/user/list' }
+      meta: { title: '行为记录', icon: 'international', activeMenu: '/user/list' }
+    },
+    {
+      path: 'club-portrait',
+      name: 'ClubPortrait',
+      hidden: true,
+      component: () => import('@/views/user/club-portrait/index'),
+      meta: { title: '机构画像', noCache: true, activeMenu: '/user/list' }
     },
     {
       path: 'record-product-list',

+ 78 - 0
src/views/operate/activity/components/zi-dialog.vue

@@ -0,0 +1,78 @@
+<template>
+  <el-dialog
+    title="打卡详情"
+    :visible.sync="visible"
+    width="800px"
+    :close-on-click-modal="false"
+    :show-close="false"
+  >
+    <el-table
+      ref="table"
+      v-loading="isLoading"
+      :data="list"
+      height="400px"
+      border
+    >
+      <el-table-column label="供应商名称" prop="name" align="center" />
+      <el-table-column prop="signFlag" label="打卡进度" align="center">
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.signFlag === 0" type="info" size="small">未打卡</el-tag>
+          <el-tag v-else type="success" size="small">已打卡</el-tag>
+        </template>
+      </el-table-column>
+    </el-table>
+    <div slot="footer">
+      <el-button @click="handleCanle"> 关闭 </el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { getZylTicketDetail } from '@/api/activity/activity'
+
+export default {
+  name: 'ZiDialog',
+  props: {
+    userId: {
+      type: Number,
+      default: 0
+    }
+  },
+  data() {
+    return {
+      visible: true,
+      list: [],
+      total: 0,
+      isLoading: true
+    }
+  },
+  computed: {
+
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    // 获取所有供应商列表
+    async getList() {
+      this.list = []
+      this.getZylTicketDetail()
+    },
+    // 获取所有供应商列表
+    async getZylTicketDetail() {
+      try {
+        const res = await getZylTicketDetail({ userId: this.userId })
+        this.list = res.data
+        this.isLoading = false
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    handleCanle() {
+      // 取消弹窗
+      this.$emit('cancel')
+    }
+  }
+}
+</script>
+<style lang="scss" scoped></style>

+ 402 - 0
src/views/operate/activity/list.vue

@@ -0,0 +1,402 @@
+<template>
+  <div class="app-container">
+    <!-- 顶部操作区域 -->
+    <div class="filter-container">
+      <div class="filter-control">
+        <span>机构ID:</span>
+        <el-input
+          style="width: 120px"
+          v-model="listQuery.clubId"
+          placeholder="机构ID"
+          clearable
+          maxlength="10"
+          @keyup.enter.native="getList"
+          @clear="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <span>机构名称:</span>
+        <el-input
+          v-model="listQuery.name"
+          placeholder="机构名称"
+          clearable
+          @keyup.enter.native="getList"
+          @clear="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <span>手机号:</span>
+        <el-input
+          v-model="listQuery.contractMobile"
+          placeholder="手机号"
+          maxlength="11"
+          clearable
+          @keyup.enter.native="getList"
+          @clear="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <span>联系人:</span>
+        <el-input
+          v-model="listQuery.linkMan"
+          placeholder="联系人名称"
+          clearable
+          @keyup.enter.native="getList"
+          @clear="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <span>机构状态:</span>
+        <el-select v-model="listQuery.status" style="width: 150px" clearable @change="getList">
+          <el-option value="" label="请选择" />
+          <el-option :value="90" label="已上线" />
+          <el-option :value="91" label="已下线" />
+          <el-option :value="1" label="待审核" />
+          <el-option :value="92" label="审核未通过" />
+          <el-option :value="93" label="已确认" />
+          <el-option :value="94" label="已冻结" />
+        </el-select>
+      </div>
+      <div class="filter-control">
+        <span>机构级别:</span>
+        <el-select v-model="listQuery.userIdentity" style="width: 150px" clearable @change="getList">
+          <el-option value="" label="请选择" />
+          <el-option :value="4" label="个人机构" />
+          <el-option :value="2" label="资质机构" />
+          <el-option :value="8" label="超级会员" />
+        </el-select>
+      </div>
+      <div class="filter-control">
+        <span>协销:</span>
+        <el-select v-model="listQuery.spId" style="width: 150px"  filterable @change="getList">
+          <el-option value="" label="请选择" />
+          <el-option
+            v-for="item in sellerOption"
+            :key="item.serviceProviderId"
+            :label="item.linkMan"
+            :value="item.serviceProviderId"
+          />
+        </el-select>
+      </div>
+      <div class="filter-control">
+        <span>动态标签:</span>
+        <el-select v-model="listQuery.trendsLabel" filterable @change="getList">
+          <el-option value="" label="请选择" />
+          <el-option
+            v-for="(item,index) in trendsLabelOption"
+            :key="index"
+            :label="item.label"
+            :value="item.label"
+          />
+        </el-select>
+      </div>
+      <div class="filter-control">
+        <span>静态标签:</span>
+        <el-select v-model="listQuery.stateLabel" filterable @change="getList">
+          <el-option value="" label="请选择" />
+          <el-option
+            v-for="(item,index) in stateLabelOption"
+            :key="index"
+            :label="item.label"
+            :value="item.label"
+          />
+        </el-select>
+      </div>
+      <div class="filter-control">
+        <span>注册时间:</span>
+        <el-date-picker
+          v-model="time"
+          type="daterange"
+          unlink-panels
+          value-format="yyyy-MM-dd"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          :picker-options="pickerOptions"
+          @change="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <span>分配时间:</span>
+        <el-date-picker
+          v-model="time1"
+          type="daterange"
+          unlink-panels
+          value-format="yyyy-MM-dd"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          :picker-options="pickerOptions"
+          @change="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <el-button type="primary" @click="getList"> 查询 </el-button>
+      </div>
+    </div>
+    <!-- 列表 -->
+    <el-table v-loading="isLoading" :data="list" border style="width: 100%" height="660">
+      <el-table-column prop="clubId" fixed label="机构ID" align="center" width="80"/>
+      <el-table-column prop="name" fixed label="机构名称" align="center" />
+      <el-table-column prop="linkMan" label="联系人" align="center" width="100"/>
+      <el-table-column prop="spName" label="协销人员" align="center" width="120"/>
+      <el-table-column prop="contractMobile" label="手机号" align="center" width="150">
+        <template slot-scope="{ row }">
+          {{ row.contractMobile ? row.contractMobile : '---' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="status" label="机构状态" align="center" width="100">
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.status === 1" type="warning" size="small">待审核</el-tag>
+          <el-tag v-if="row.status === 90" type="success" size="small">已上线</el-tag>
+          <el-tag v-if="row.status === 91" type="info" size="small">已下线</el-tag>
+          <el-tag v-if="row.status === 92" type="danger" size="small">审核未通过</el-tag>
+          <el-tag v-if="row.status === 93" type="warning" size="small">已确认</el-tag>
+          <el-tag v-if="row.status === 94" type="danger" size="small">已冻结</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column prop="userIdentity" label="机构级别" align="center" width="150">
+        <template slot-scope="{ row }">
+          <template v-if="row.userIdentity === '4'">
+            <el-tag v-if="row.userIdentity === '4' && row.svipUserFlag === 1" type="success" size="small">个人机构(超级会员)</el-tag>
+            <el-tag v-else type="info" size="small">个人机构(普通会员)</el-tag>
+          </template>
+          <template v-if="row.userIdentity === '2'">
+            <el-tag v-if="row.userIdentity === '2' && row.svipUserFlag ===1" type="success" size="small">资质机构(超级会员)</el-tag>
+            <el-tag v-if="row.userIdentity === '2' && row.svipUserFlag !==1 && !row.medicalPracticeLicenseImg" type="warning" size="small">资质机构(高级会员)</el-tag>
+            <el-tag v-if="row.userIdentity === '2' && row.svipUserFlag !==1 && row.medicalPracticeLicenseImg" type="danger" size="small">资质机构(医美会员)</el-tag>
+          </template>
+        </template>
+      </el-table-column>
+      <el-table-column prop="source" label="注册IP" align="center" width="180">
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.source === '0'" effect="plain" type="warning" size="small">{{ row.registerIP }}(网站)</el-tag>
+          <el-tag v-if="row.source === '1'" effect="plain" type="warning" size="small">{{ row.registerIP }}(小程序)</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column prop="addTime" label="注册时间" align="center" width="100">
+        <template slot-scope="{ row }">
+          {{ row.addTime ? row.addTime : '---' }}
+        </template>
+      </el-table-column>
+      <el-table-column fixed="right" label="操作" align="center" >
+        <template slot-scope="{ row }">
+          <el-button type="success" size="mini" style="margin: 4px" @click="handleRecordDetail(3, row)">
+            机构画像
+          </el-button>
+          <el-button type="primary" size="mini" style="margin: 4px" @click="handleRecordDetail(2, row)">
+            行为记录
+          </el-button>
+          <el-button type="primary" size="mini" style="margin: 4px" @click="handleRecordDetail(1, row)">
+            咨询记录
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 页码 -->
+    <pagination
+      :total="total"
+      :page-sizes="[10, 20, 30, 100]"
+      :page-size="20"
+      :page.sync="listQuery.pageNum"
+      :limit.sync="listQuery.pageSize"
+      @pagination="getClubList"
+    />
+    <!-- 设置统计状态 -->
+    <el-dialog title="设置统计状态" :visible.sync="dialogFormVisible" width="500px">
+      <el-form ref="dataForm" :model="renewCustome" :rules="rules" label-position="right">
+        <el-form-item prop="status">
+          <el-radio v-model="renewCustome.status" :label="0">统计中</el-radio>
+          <el-radio v-model="renewCustome.status" :label="1">暂停统计</el-radio>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogFormVisible = false">取消</el-button>
+        <el-button type="primary" @click="handleConfirm">确定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { getClubList, getClubLabel, renewCustomerShop } from '@/api/user/club/club'
+import { getServiceList } from '@/api/library/keyword'
+import pickerOptions from '@/utils/time-picker.js'
+export default {
+  name: 'CustomerList',
+  filters: {},
+  data() {
+    return {
+      isLoading: true,
+      pickerOptions,
+      time: [],
+      time1: [],
+      listQuery: {
+        clubId: '',
+        name: '',
+        contractMobile: '',
+        userIdentity: '',
+        startTime: '',
+        endTime: '',
+        allocationStartTime: '',
+        allocationEndTime: '',
+        newDeal: '',
+        spId: '',
+        trendsLabel: '',
+        stateLabel: '',
+        status: '',
+        pageNum: 1,
+        pageSize: 20
+      },
+      list: [],
+      total: 0,
+      sellerOption:[],
+      trendsLabelOption:[],
+      stateLabelOption:[],
+      shopDialogVisible: false,
+      dialogFormVisible: false,
+      renewCustome: {
+        id: '',
+        status: ''
+      },
+      rules: {
+        status: [{ required: true, message: '请设置统计状态', trigger: 'blur' }]
+      }
+    }
+  },
+  computed: {},
+  created() {
+    this.getTrendsLabel()
+    this.getStateLabel()
+    this.getServiceList()
+    this.getList()
+  },
+  mounted() {},
+  methods: {
+    // 获取行为记录列表
+    getList() {
+      this.list = []
+      this.isLoading = true
+      this.listQuery.pageNum = 1
+      if (this.time && this.time.length > 0) {
+        this.listQuery.startTime = this.time[0]
+        this.listQuery.endTime = this.time[1]
+      } else {
+        this.listQuery.startTime = ''
+        this.listQuery.endTime = ''
+      }
+      if (this.time1 && this.time1.length > 0) {
+        this.listQuery.allocationStartTime = this.time1[0]
+        this.listQuery.allocationEndTime = this.time1[1]
+      } else {
+        this.listQuery.allocationStartTime = ''
+        this.listQuery.allocationEndTime = ''
+      }
+      this.getClubList()
+    },
+    // 确认设置统计状态
+    handleConfirm() {
+      this.$refs['dataForm'].validate((valid) => {
+        if (valid) {
+          this.renewCustomerShop(this.renewCustome)
+        } else {
+          return false
+        }
+      })
+    },
+    // 获取机构列表
+    async getClubList() {
+      try {
+        const res = await getClubList(this.listQuery)
+        this.list = res.data.results
+        this.total = res.data.totalRecord
+        this.isLoading = false
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 获取协销列表选项
+    async getServiceList() {
+      try {
+        const res = await getServiceList()
+        this.sellerOption = res.data
+      } catch (error) {
+        console.log(error)
+      }
+    },
+     // 获取动态标签
+     async getTrendsLabel() {
+      try {
+        const res = await getClubLabel({dynamicStatus:0})
+        const data = res.data
+        this.trendsLabelOption = data
+      } catch (error) {
+        console.log(error)
+      }
+    },
+     // 获取静态标签
+     async getStateLabel() {
+      try {
+        const res = await getClubLabel({dynamicStatus:1})
+        const data = res.data
+        this.stateLabelOption = data
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 统计状态
+    async renewCustomerShop(params) {
+      try {
+        await renewCustomerShop(params)
+        this.dialogFormVisible = false
+        this.$message.success('操作成功')
+        this.getList()
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 操作
+    handleRecordDetail(type, row) {
+      switch (type) {
+        case 1: // 咨询记录
+          this.$router.push({
+            path: '/user/consult/list',
+            query: { clubName:row.name,clubId: row.clubId }
+          })
+          break
+        case 2: // 行为记录
+          this.$router.push({
+            path: '/user/record-list',
+            query: { type:'first',corporateName:row.name,clubId: row.clubId }
+          })
+          break
+        case 3: // 机构画像
+          this.$router.push({
+            path: '/user/club-portrait',
+            query: { clubName:row.name,clubId: row.clubId }
+          })
+          break
+      }
+    }
+  }
+}
+</script>
+
+<style>
+.avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+  float: left;
+}
+.uploader-tips {
+  position: absolute;
+  bottom: 0;
+  left: 160px;
+  line-height: 28px;
+  color: red;
+  margin: 0;
+}
+</style>

+ 201 - 0
src/views/operate/activity/ziyalan-list.vue

@@ -0,0 +1,201 @@
+<template>
+  <div class="app-container">
+    <!-- 顶部操作区域 -->
+    <div class="filter-container">
+      <div class="filter-control">
+        <span>手机号:</span>
+        <el-input
+          style="width: 200px"
+          v-model="listQuery.mobile"
+          placeholder="手机号"
+          clearable
+          maxlength="11"
+          @keyup.enter.native="getList"
+          @clear="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <el-button type="primary" @click="getList"> 查询 </el-button>
+      </div>
+    </div>
+    <!-- 列表 -->
+    <el-table v-loading="isLoading" :data="list" border style="width: 100%" height="660">
+      <el-table-column prop="ticketId" label="票根号" align="center">
+        <template slot-scope="{ row }">
+          {{ row.ticketId ? row.ticketId : '---' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="name" label="姓名" align="center">
+        <template slot-scope="{ row }">
+          {{ row.name ? row.name : '---' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="mobile" label="手机号" align="center">
+        <template slot-scope="{ row }">
+          {{ row.mobile ? row.mobile : '---' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="userId" label="绑定状态" align="center">
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.ticketId && row.userId" type="success" size="small">已绑定</el-tag>
+          <el-tag v-else type="info" size="small">未绑定</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column prop="bindTime" label="绑定时间" align="center">
+        <template slot-scope="{ row }">
+          {{ row.bindTime ? row.bindTime : '---' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="giftFlag" label="礼品领取状态" align="center">
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.giftFlag === 0" type="info" size="small">未领取</el-tag>
+          <el-tag v-else type="success" size="small">已领取</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column prop="shopIds" label="打卡进度" align="center">
+        <template slot-scope="{ row }">
+          <el-tag v-if="handleShopIds(row.shopIds)" type="success" size="small">已完成</el-tag>
+          <el-tag v-else type="info" size="small">未完成</el-tag>
+        </template>
+      </el-table-column>
+
+      <el-table-column fixed="right" label="操作" align="center">
+        <template slot-scope="{ row }">
+          <el-button type="success" size="mini" style="margin: 4px" @click="handleShowDetail(row)">
+            打卡详情
+          </el-button>
+          <el-button v-if="row.giftFlag === 0" type="primary" size="mini" style="margin: 4px" @click="handleChangeState(row)">
+            修改领取状态
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 页码 -->
+    <pagination
+      :total="total"
+      :page-sizes="[10, 20, 30, 100]"
+      :page-size="20"
+      :page.sync="listQuery.pageNum"
+      :limit.sync="listQuery.pageSize"
+      @pagination="getZylTicketList"
+    />
+    <!--  查看打卡详情 -->
+    <zi-dialog v-if="dialogVisible" ref="ziDialog" :user-id="handleUserId" @cancel="handleCancel" />
+    <!-- 修改礼品领取状态 -->
+    <el-dialog title="修改礼品领取状态" :visible.sync="dialogFormVisible" width="500px">
+      <el-form ref="dataForm" label-position="right">
+        <el-form-item prop="status">
+          <el-radio v-model="giftFlag" :label="1" border>已领取</el-radio>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogFormVisible = false">取消</el-button>
+        <el-button type="primary" @click="handleConfirm">确定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { getZylTicketList, postZylUpdateGift,getZylTicketDetail } from '@/api/activity/activity'
+import ZiDialog from './components/zi-dialog'
+export default {
+  name: 'CustomerList',
+  components: { ZiDialog },
+  filters: {},
+  data() {
+    return {
+      isLoading: true,
+      listQuery: {
+        pageNum: 1,
+        pageSize: 20,
+        mobile:''
+      },
+      list: [],
+      total: 0,
+      dialogVisible: false,
+      dialogFormVisible: false,
+      handleUserId: '',
+      renewCustome: {
+        userId:0
+      },
+      giftFlag:0,
+      rules: {
+        status: [{ required: true, message: '请设置统计状态', trigger: 'blur' }]
+      }
+    }
+  },
+  computed: {},
+  created() {
+    this.getList()
+  },
+  mounted() {},
+  methods: {
+    // 获取行为记录列表
+    getList() {
+      this.list = []
+      this.isLoading = true
+      this.listQuery.pageNum = 1
+      this.getZylTicketList()
+    },
+    // 判断是否全部打卡
+    handleShopIds(shopIds){
+      let flag = false
+      const defaultShop = [2,3,4,5,7,8,9,10]
+      if(shopIds){
+        const shopIdsArr = shopIds.split(',').map(Number)
+        console.log('shopIdsArr',shopIdsArr)
+        if(shopIdsArr.length === defaultShop.length ){
+          flag = true
+        }else{
+          flag = false
+        }
+      }
+      return flag
+    },
+    // 获取机构列表
+    async getZylTicketList() {
+      try {
+        const res = await getZylTicketList(this.listQuery)
+        this.list = res.data.results
+        this.total = res.data.totalRecord
+        this.isLoading = false
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 查看打卡详情
+    handleShowDetail(row) {
+      this.handleUserId = row.userId
+      this.dialogVisible = true
+    },
+    // 修改礼品领取状态
+    handleChangeState(row) {
+      this.renewCustome.userId = row.userId
+      this.dialogFormVisible = true
+    },
+    // 确认修改礼品领取状态
+    handleConfirm() {
+      this.postZylUpdateGift(this.renewCustome)
+    },
+    // 统计状态
+    async postZylUpdateGift(params) {
+      try {
+        await postZylUpdateGift(params)
+        this.dialogFormVisible = false
+        this.$message.success('操作成功')
+        this.getList()
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 关闭
+    handleCancel() {
+      this.dialogVisible = false
+      this.$refs.ziDialog.visible = false
+    }
+  }
+}
+</script>
+
+<style></style>

+ 172 - 0
src/views/serviceSettlement/components/goods-dialog.vue

@@ -0,0 +1,172 @@
+<template>
+  <el-dialog title="添加商品" :visible.sync="visible" width="1200px" :close-on-click-modal="false" :show-close="false">
+    <div class="filter-container">
+      <div class="filter-control">
+        <span>商品ID:</span>
+        <el-input
+          v-model="listQuery.productId"
+          placeholder="商品ID"
+          clearable
+          style="width: 160px"
+          @keyup.enter.native="getList"
+          @clear="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <span>商品名称:</span>
+        <el-input
+          v-model="listQuery.productName"
+          placeholder="商品名称"
+          clearable
+          style="width: 160px"
+          @keyup.enter.native="getList"
+          @clear="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <span>供应商ID:</span>
+        <el-input
+          v-model="listQuery.shopId"
+          placeholder="供应商ID"
+          clearable
+          style="width: 160px"
+          @keyup.enter.native="getList"
+          @clear="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <span>供应商名称:</span>
+        <el-input
+          v-model="listQuery.shopName"
+          placeholder="供应商名称"
+          clearable
+          style="width: 160px"
+          @keyup.enter.native="getList"
+          @clear="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <el-button type="primary" @click="getList"> 查询 </el-button>
+      </div>
+    </div>
+    <el-table
+      ref="table"
+      v-loading="isLoading"
+      :data="list"
+      height="400px"
+      border
+      @selection-change="handleSelectionChange"
+    >
+      <el-table-column type="selection" width="55" />
+      <el-table-column label="商品ID" prop="productId" align="center" width="100" />
+      <el-table-column prop="mainImage" label="商品图片" align="center" width="120">
+        <template slot-scope="{ row }">
+          <img v-if="row.mainImage" :src="row.mainImage" alt="" style="width: 50px; height: 50px" />
+          <span v-else>---</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="商品名称" prop="productName" align="center" />
+      <el-table-column label="供应商" prop="shopName" align="center" />
+    </el-table>
+    <!-- 页码 -->
+    <pagination
+      :total="total"
+      :page-sizes="[10, 20]"
+      :page-size="10"
+      :page.sync="listQuery.pageNum"
+      :limit.sync="listQuery.pageSize"
+      @pagination="getProductList"
+    />
+    <div slot="footer">
+      <el-button @click="handleCanle"> 取 消 </el-button>
+      <el-button type="primary" :disabled="disabled" @click="handleConfirm"> 确 定 </el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { getProductList } from '@/api/serviceSettlement/goods'
+
+export default {
+  name: 'GoodsDialog',
+  data() {
+    return {
+      visible: true,
+      listQuery: {
+        providerId: this.$route.query.providersId,
+        shopId: '',
+        productId: '',
+        shopName: '',
+        productName: '',
+        pageNum: 1, // 页码
+        pageSize: 10 // 页面数据数
+      },
+      list: [],
+      total: 0,
+      shopsRadio: null,
+      isLoading: true
+    }
+  },
+  computed: {
+    disabled() {
+      return this.shopsRadio === null
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    // 获取所有供应商列表
+    async getList() {
+      this.list = []
+      this.listQuery.pageNum = 1
+      this.getProductList()
+    },
+    // 获取所有供应商列表
+    async getProductList() {
+      try {
+        const res = await getProductList(this.listQuery)
+        this.list = res.data.results
+        this.total = res.data.totalRecord
+        this.isLoading = false
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 选择供应商
+    handleSelectionChange(row) {
+      this.shopsRadio = row
+      console.log('row', row)
+    },
+    // 确认选择供应商
+    handleConfirm() {
+      this.$emit('confirm', this.shopsRadio)
+    },
+    handleCanle() {
+      // 取消弹窗
+      this.$emit('cancel')
+    },
+    // 已选择的禁用勾选框
+    selectable(row) {
+      if (row.flag) {
+        return true
+      } else {
+        return false
+      }
+    },
+    checkedInput(event, type) {
+      let pattern = ''
+      switch (type) {
+        case 1:
+          pattern = /[^\d]/g
+          break
+        case 2:
+          pattern = /[^u4E00-u9FA5|d|a-zA-Z|rns,.?!,。?!…—&$=()-+/*{}[]]|s/g
+          break
+      }
+      return event.replace(pattern, '')
+    }
+  }
+}
+</script>
+<style lang="scss" scoped></style>

+ 197 - 0
src/views/serviceSettlement/goods/index.vue

@@ -0,0 +1,197 @@
+<template>
+  <div class="app-container">
+    <!-- 顶部操作区域 -->
+    <div class="filter-container">
+      <div class="filter-control">
+        <span>商品ID:</span>
+        <el-input
+          v-model="listQuery.productId"
+          placeholder="商品ID"
+          clearable
+          @keyup.enter.native="getList"
+          @clear="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <span>商品名称:</span>
+        <el-input
+          v-model="listQuery.productName"
+          placeholder="商品名称"
+          clearable
+          @keyup.enter.native="getList"
+          @clear="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <el-button type="primary" @click="getList"> 查询 </el-button>
+        <el-button type="primary" @click="goodsDialogVisible = true"> 添加商品 </el-button>
+      </div>
+    </div>
+    <!-- 列表 -->
+    <el-table v-loading="isLoading" :data="list" border style="width: 100%" height="660">
+      <el-table-column prop="productId" label="商品ID" align="center" width="80" />
+      <el-table-column prop="mainImage" label="商品图片" align="center" width="120">
+        <template slot-scope="{ row }">
+          <img v-if="row.mainImage" :src="row.mainImage" alt="" style="width: 50px; height: 50px" />
+          <span v-else>---</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="productName" label="商品名称" align="center" />
+      <el-table-column prop="shopName" label="供应商名称" align="center" />
+      <el-table-column label="操作" align="center" width="200">
+        <template slot-scope="{ row }">
+          <el-button type="danger" size="mini" style="margin: 2px" @click="handleDelete(row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 页码 -->
+    <pagination
+      :total="total"
+      :page-sizes="[10, 20, 30, 100]"
+      :page-size="20"
+      :page.sync="listQuery.pageNum"
+      :limit.sync="listQuery.pageSize"
+      @pagination="getShopProduct"
+    />
+    <!--  选择商品弹窗 -->
+    <goods-dialog v-if="goodsDialogVisible" ref="shopDialog" @confirm="handleAddGoodsConfirm" @cancel="handleCancel" />
+  </div>
+</template>
+
+<script>
+import { getProvidersProducts, addProducts, delProduct } from '@/api/serviceSettlement/goods'
+import GoodsDialog from '../components/goods-dialog'
+export default {
+  name: 'RecordList',
+  components: { GoodsDialog },
+  filters: {},
+  data() {
+    return {
+      isLoading: true,
+      listQuery: {
+        providerId: this.$route.query.providersId,
+        productName: '',
+        productId: '',
+        pageNum: 1,
+        pageSize: 20
+      },
+      list: [],
+      total: 0,
+      goodsDialogVisible: false
+    }
+  },
+  computed: {
+    providersId() {
+      return this.$route.query.providersId || false
+    }
+  },
+  created() {
+    this.getList()
+  },
+  mounted() {},
+  methods: {
+    // 获取行为记录列表
+    getList() {
+      this.list = []
+      this.listQuery.pageNum = 1
+      this.getProvidersProducts()
+    },
+    // 确认选择商品
+    handleAddGoodsConfirm(data) {
+      console.log('data', data)
+      const productIds = []
+      data.forEach((ele) => {
+        productIds.push(ele.productId)
+      })
+      this.addProducts({ providerId: this.providersId, productIds: productIds.join(',') })
+    },
+    // 取消选择供商品
+    handleCancel() {
+      this.goodsDialogVisible = false
+      this.$refs.shopDialog.visible = false
+    },
+    // 获取服务商商品列表
+    async getProvidersProducts() {
+      try {
+        this.isLoading = true
+        const res = await getProvidersProducts(this.listQuery)
+        this.list = res.data.results
+        this.total = res.data.totalRecord
+        this.isLoading = false
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 保存添加商品
+    async addProducts(params) {
+      try {
+        await addProducts(params)
+        this.goodsDialogVisible = false
+        this.$notify({
+          title: '',
+          message: '添加成功',
+          type: 'success'
+        });
+        this.getList()
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 操作删除商品
+    async handleDelete(row) {
+      try {
+        await this.$confirm('确定删除该商品吗?', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        })
+        this.delProduct(row)
+      } catch (error) {
+        this.$message.info('已取消删除操作')
+      }
+    },
+    // 调用删除广告图
+    async delProduct(row) {
+      try {
+        await delProduct({ providerId: this.providersId, productId: row.productId })
+        this.$notify({
+          title: '',
+          message: '删除成功',
+          type: 'success'
+        });
+        this.getList()
+      } catch (error) {
+        console.log(error)
+      }
+    }
+  }
+}
+</script>
+
+<style>
+.tags-sms {
+  width: 100%;
+  height: auto;
+  font-size: 16px;
+  color: #333333;
+  line-height: 28px;
+  box-sizing: border-box;
+  padding: 5px;
+}
+.avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+  float: left;
+}
+.uploader-tips {
+  position: absolute;
+  bottom: 0;
+  left: 160px;
+  line-height: 28px;
+  color: red;
+  margin: 0;
+}
+</style>

+ 9 - 0
src/views/serviceSettlement/list/edit.vue

@@ -19,6 +19,9 @@
           />
         </el-select>
       </el-form-item>
+      <el-form-item label="服务商品牌:" prop="brandName" v-if="formLabelAlign.serviceLevel === 4 || formLabelAlign.serviceLevel === 5">
+        <el-input v-model="formLabelAlign.brandName" placeholder="服务商品牌" />
+      </el-form-item>
       <el-form-item label="服务商地区:" prop="address">
         <!--<el-cascader
           ref="cascader"
@@ -43,6 +46,9 @@
           />
         </el-select>
       </el-form-item>
+      <el-form-item label="服务商分帐号:" prop="splitCode">
+        <el-input v-model="formLabelAlign.splitCode" placeholder="请输入服务商分帐号" />
+      </el-form-item>
       <el-form-item label="联系人:" prop="linkMan">
         <el-input v-model="formLabelAlign.linkMan" placeholder="请输入联系人" />
       </el-form-item>
@@ -148,6 +154,7 @@ export default {
     return {
       formLabelAlign: {
         address: '',
+        brandName: '',
         infoRelateds: [],
         area: [],
         textRelateds: [],
@@ -165,10 +172,12 @@ export default {
           { required: true, message: '请输入服务商名称', trigger: 'blur' },
           { max: 50, message: '长度最多50个汉字', trigger: 'blur' }
         ],
+        brandName: [{ required: true, message: '请输入服务商品牌', trigger: 'blur' }],
         address: [{ required: true, message: '请输入地址', trigger: 'blur' }],
         serviceLevel: [
           { required: true, message: '请选择服务商级别', trigger: 'change' }
         ],
+        //splitCode: [{ required: true, message: '请输入联系服务商分账号', trigger: 'blur' }],
         mobile: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
         linkMan: [{ required: true, message: '请输入联系人', trigger: 'blur' }],
         serviceCategory: [

+ 22 - 12
src/views/serviceSettlement/list/index.vue

@@ -81,20 +81,16 @@
         type="index"
         sortable="custom"
         align="center"
-        width="80"
+        width="50"
       />
       <el-table-column prop="name" label="服务商名称" align="center" />
       <el-table-column prop="serviceLevel" label="服务商级别" align="center">
-        <template slot-scope="scope">
-          <div>
-            {{
-              scope.row.serviceLevel == "1"
-                ? "一级"
-                : scope.row.serviceLevel == "2"
-                  ? "二级"
-                  : "三级"
-            }}
-          </div>
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.serviceLevel === 1" type="success" effect="dark" size="mini">一级</el-tag>
+          <el-tag v-if="row.serviceLevel === 2" type="success" effect="dark" size="mini">二级</el-tag>
+          <el-tag v-if="row.serviceLevel === 3" type="success" effect="dark" size="mini">三级</el-tag>
+          <el-tag v-if="row.serviceLevel === 4" type="success" effect="dark" size="mini">品牌特约</el-tag>
+          <el-tag v-if="row.serviceLevel === 5" type="success" effect="dark" size="mini">品牌指定</el-tag>
         </template>
       </el-table-column>
       <el-table-column prop="serviceCategory" label="服务商类型" align="center">
@@ -104,9 +100,16 @@
           </div>
         </template>
       </el-table-column>
+      <el-table-column prop="serviceCategory" label="服务商分账号" align="center">
+        <template slot-scope="{ row }">
+          <div>
+            {{ row.splitCode ? row.splitCode : "--" }}
+          </div>
+        </template>
+      </el-table-column>
       <el-table-column prop="contractStartDate" label="授权起始日期" align="center" />
       <el-table-column prop="contractEndDate" label="授权截止日期" align="center" />
-      <el-table-column prop="status" label="状态" align="center">
+      <el-table-column prop="status" label="状态" align="center" width="100">
         <template slot-scope="scope">
           <div>
             已{{ scope.row.status === 90 ? "上线" : "下线" }}
@@ -136,6 +139,13 @@
                 $router.push('/service/settlement/contract/list?providersId=' + row.id)
               "
             >合同管理</el-button>
+            <el-button
+              type="primary"
+              size="mini"
+              @click="
+                $router.push('/service/settlement/goods/list?providersId=' + row.id)
+              "
+            >商品管理</el-button>
           </div>
         </template>
       </el-table-column>

+ 8 - 1
src/views/serviceSettlement/mixin/index.js

@@ -3,7 +3,14 @@ import { getToken } from '@/utils/auth'
 export default {
   data() {
     return {
-      serviceLevel: [{ id: '', value: '请选择' }, { id: 1, value: '一级' }, { id: 2, value: '二级' }, { id: 3, value: '三级' }],
+      serviceLevel: [
+        { id: '', value: '请选择' },
+        { id: 1, value: '一级' },
+        { id: 2, value: '二级' },
+        { id: 3, value: '三级' },
+        { id: 4, value: '品牌特约' },
+        { id: 5, value: '品牌指定' }
+      ],
       serviceCategoryList: [{ id: '', value: '请选择' }, { id: 1, value: '个人' }, { id: 2, value: '企业' }]
     }
   },

+ 179 - 0
src/views/user/club-portrait/components/bar-echarts.vue

@@ -0,0 +1,179 @@
+<template>
+  <div class="echarts-content">
+    <div ref="echarts" class="bar_echarts"></div>
+  </div>
+</template>
+
+<script>
+import echarts from "echarts";
+export default {
+  props: {
+    title: {
+      type: String,
+      default: () => "myEcharts",
+    },
+    optionData: {
+      type: Object,
+      default: () => ({}),
+    },
+  },
+  data() {
+    return {
+      timeTicket: null,
+      chart: null,
+      optionData1: {},
+    };
+  },
+  watch: {
+    optionData: {
+      handler(val) {
+        if (val) {
+          clearInterval(this.timeTicket);
+          this.timeTicket = null;
+          this.optionData1 = val;
+          console.log("option-data888888888", this.optionData1);
+          this.initChart()
+        }
+      },
+      deep: true,
+      immediate: true,
+    },
+  },
+  mounted() {
+    // 初始化图表
+    this.chart = echarts.init(this.$refs["echarts"]);
+    // 初始设置和配置...
+    this.initChart(); // 调用函数设置初始图表
+  },
+  methods: {
+    initChart() {
+      // 如果图表实例存在,先清空数据和配置项(可选)
+      if (this.chart) {
+        this.chart.clear(); // 清空当前图表
+      }
+      const option = {
+        title: {
+          text: this.optionData1.name,
+        },
+        tooltip: {
+          trigger: "axis",
+          axisPointer: {
+            type: "shadow",
+          },
+        },
+        legend: {
+          show: false,
+        },
+        grid: {
+          left: "3%",
+          right: "4%",
+          bottom: "3%",
+          containLabel: true,
+        },
+        xAxis: {
+          type: "value",
+          splitLine: {
+            show: true,
+            lineStyle: {
+              opacity: 0.2,
+              color: "#DCDCDC",
+            },
+          },
+          boundaryGap: [0, 0.01],
+          axisLabel: {
+            show: true,
+            textStyle: {
+              color: "#DCDCDC", //更改坐标轴文字颜色
+              fontSize: 12, //更改坐标轴文字大小
+            },
+          },
+          axisTick: {
+            //轴网格,在xAxis或yAxis根下
+            lineStyle: {
+              width: 1,
+              color: "#3333333",
+              type: "solid",
+            },
+          },
+        },
+        yAxis: {
+          type: "category",
+          splitLine: {
+            show: false,
+          },
+          axisLabel: {
+            show: true,
+            textStyle: {
+              color: "#333333", //更改坐标轴文字颜色
+              fontSize: 12, //更改坐标轴文字大小
+            },
+            margin: 8,
+            formatter: function (params) {
+              var val = "";
+              if (params.length > 6) {
+                val = params.substr(0, 6) + "...";
+                return val;
+              } else {
+                return params;
+              }
+            },
+          },
+          axisTick: {
+            //轴网格,在xAxis或yAxis根下
+            show: false,
+            lineStyle: {
+              width: 1,
+              color: "#333333",
+              type: "solid",
+            },
+          },
+          data: this.optionData1.yAxisData,
+        },
+        series: [
+          {
+            type: "bar",
+            name: this.optionData1.name,
+            data: this.optionData1.xAxisData,
+            barBorderRadius: [10, 0, 0, 0],
+            itemStyle: {
+              fontSize: 14,
+              color: this.optionData1.color,
+              barBorderRadius: 20, // 鼠标悬停时的圆角大小
+            },
+          },
+        ],
+      };
+      // 使用刚指定的配置项和数据显示图表。
+      if (this.chart) {
+        this.chart.setOption(option);
+      }
+    },
+  },
+  beforeDestroy() {
+    // 组件销毁前,销毁图表实例
+    if (this.chart) {
+      this.chart.dispose();
+    }
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.echarts-content {
+  width: 100%;
+  height: 400px;
+  border-radius: 12px;
+  border: 1px solid #ccc;
+  box-shadow: 0 0 4px #ccc;
+  overflow: hidden;
+  padding: 10px;
+  .title {
+    display: flex;
+    align-items: center;
+  }
+  .bar_echarts {
+    width: 100%;
+    height: 100%;
+  }
+}
+</style>

+ 261 - 0
src/views/user/club-portrait/components/club-dialog.vue

@@ -0,0 +1,261 @@
+<template>
+  <el-dialog :title="title" :visible.sync="visible" width="850px" :close-on-click-modal="false" :show-close="false">
+    <div class="dialog-main">
+      <template v-if="dialogType === 1">
+        <div class="dialog-main-left">
+          <div class="main-row">
+            <span>机构ID:</span>
+            <span class="none">4567</span>
+          </div>
+          <div class="main-row">
+            <span>机构名称:</span>
+            <span class="none">c采美信息技术有限公司</span>
+          </div>
+          <div class="main-row">
+            <span>机构类型:</span>
+            <span class="none">医美</span>
+          </div>
+          <div class="main-row">
+            <span>机构级别:</span>
+            <span class="none">资质机构</span>
+          </div>
+          <div class="main-row">
+            <span>注册时间:</span>
+            <span class="none">2024-05-17 16:42:44</span>
+          </div>
+          <div class="main-row">
+            <span>联系人:</span>
+            <span class="none">张先生</span>
+          </div>
+          <div class="main-row">
+            <span>手机号:</span>
+            <span class="none">13695444444</span>
+          </div>
+          <div class="main-row">
+            <span>性别:</span>
+            <span class="none">男</span>
+          </div>
+          <div class="main-row">
+            <span>年龄:</span>
+            <span class="none">28</span>
+          </div>
+          <div class="main-row">
+            <span>身份:</span>
+            <span class="none">运营</span>
+          </div>
+        </div>
+        <div class="dialog-main-left">
+          <div class="main-row">
+            <span>机构地址:</span>
+            <span class="none">广东省深圳市</span>
+          </div>
+          <div class="main-row">
+            <span>客户价值:</span>
+            <span class="none">低价值客户</span>
+          </div>
+          <div class="main-row">
+            <span>活跃状态:</span>
+            <span class="none">活跃用户</span>
+          </div>
+          <div class="main-row">
+            <span>资料完整度:</span>
+            <span class="none">40%</span>
+          </div>
+          <div class="main-row">
+            <span>客户来源:</span>
+            <span class="none">小程序</span>
+          </div>
+          <div class="main-row">
+            <span>入群状态:</span>
+            <span class="none">- -</span>
+          </div>
+          <div class="main-row">
+            <span>微信触达:</span>
+            <span class="none">- -</span>
+          </div>
+          <div class="main-row">
+            <span>电话触达:</span>
+            <span class="none">- -</span>
+          </div>
+          <div class="main-row">
+            <span>首次咨询时间:</span>
+            <span class="none">2024-05-17 16:42:44</span>
+          </div>
+          <div class="main-row">
+            <span>最近咨询时间:</span>
+            <span class="none">2024-05-17 16:42:44</span>
+          </div>
+        </div>
+      </template>
+      <template v-else>
+        <div class="dialog-main-left">
+          <div class="main-row">
+            <span>机构名称:</span>
+            <span class="none">c采美信息技术有限公司</span>
+          </div>
+          <div class="main-row">
+            <span>机构简称:</span>
+            <span class="none">阿斯达四大所</span>
+          </div>
+          <div class="main-row">
+            <span>机构类型:</span>
+            <span class="none">医美</span>
+          </div>
+          <div class="main-row">
+            <span>机构级别:</span>
+            <span class="none">资质机构 (普通会员)</span>
+          </div>
+          <div class="main-row">
+            <span>联系人:</span>
+            <span class="none">张先生</span>
+          </div>
+          <div class="main-row">
+            <span>手机号:</span>
+            <span class="none">13695444444</span>
+          </div>
+          <div class="main-row">
+            <span>门头照:</span>
+            <a href="https://img.caimei365.com/group1/M00/00/42/rB-lGGHEEDCAHRaLAAL6r7YS4OA918.jpg" target="_blank">
+              <img src="https://img.caimei365.com/group1/M00/00/42/rB-lGGHEEDCAHRaLAAL6r7YS4OA918.jpg" alt="">
+            </a>
+          </div>
+        </div>
+        <div class="dialog-main-left">
+          <div class="main-row">
+            <span>注册邮箱:</span>
+            <span class="none">493318772@qq.com</span>
+          </div>
+          <div class="main-row">
+            <span>注册时间:</span>
+            <span class="none">2024-05-17 16:42:44</span>
+          </div>
+          <div class="main-row">
+            <span>状态:</span>
+            <span class="none">已上线</span>
+          </div>
+          <div class="main-row">
+            <span>机构地址:</span>
+            <span class="none">广东省深圳市</span>
+          </div>
+          <div class="main-row">
+            <span>主营内容:</span>
+            <span class="none">美容,美体,美发,皮肤管理,光电</span>
+          </div>
+
+          <div class="main-row">
+            <span>营业执照编号:</span>
+            <span class="none">91440114MADJWWXJ59</span>
+          </div>
+          <div class="main-row">
+            <span>营业执照:</span>
+            <a href="https://img.caimei365.com/group1/M00/00/42/rB-lGGHEEDCAHRaLAAL6r7YS4OA918.jpg" target="_blank">
+              <img src="https://img.caimei365.com/group1/M00/00/42/rB-lGGHEEDCAHRaLAAL6r7YS4OA918.jpg" alt="">
+            </a>
+          </div>
+        </div>
+      </template>
+    </div>
+    <div slot="footer">
+      <el-button type="primary" @click="handleCanle">关闭</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { getCustomerShopList } from '@/api/user/customer/customer'
+
+export default {
+  name: 'ClubDialog',
+  filters: {
+    NumFormat(value) {
+      // 处理金额
+      return Number(value).toFixed(2)
+    }
+  },
+  props: {
+    dialogType:{
+        type:Number,
+        default:1
+    }
+  },
+  data() {
+    return {
+      visible: true,
+      title:'机构活跃信息',
+      form:{
+        name:'测试的热季卡',
+        linkMan:'ASDASD',
+        contractMobile:'13565444444',
+        address:'吉林省延边朝鲜族自治州延吉市',
+        businessLicenseImage:'https://img.caimei365.com/group1/M00/00/C9/rB-lF2YfnY2AImFYAAWYX3X0D6Q546.jpg',
+        medicalPracticeLicenseImg:'https://img.caimei365.com/group1/M00/00/C9/rB-lF2YfnY2AImFYAAWYX3X0D6Q546.jpg',
+      }
+    }
+  },
+  computed: {},
+  created() {
+    if(this.dialogType === 2){
+      this.title = '机构资料'
+    }
+  },
+  methods: {
+    // 获取所有供应商列表
+    async getCustomerShopList() {
+      try {
+        const res = await getCustomerShopList(this.listQuery)
+        this.list = res.data.results
+        this.total = res.data.totalRecord
+        this.isLoading = false
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    handleCanle() {
+      // 取消弹窗
+      this.$emit('cancel')
+    },
+  }
+}
+</script>
+<style lang="scss" scoped>
+::v-deep {
+  thead .el-checkbox {
+    display: none !important;
+  }
+}
+.dialog-main{
+  width: 100%;
+  height: auto;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  padding: 16px;
+  background: #F7F7F7;
+  box-sizing: border-box;
+  border-radius: 8px;
+  .dialog-main-left{
+    display: flex;
+    flex: 1;
+    flex-direction:column ;
+    .main-row{
+      display: flex;
+      flex: 1;
+      flex-direction: row;
+      align-items: center;
+      font-size: 16px;
+      line-height: 44px;
+      font-weight: 600;
+      color: #333333;
+      img{
+        width: 80px;
+        height: 80px;
+        display: block;
+      }
+      .none{
+        font-weight: 300;
+        color: #666666;
+      }
+    }
+  }
+}
+</style>

+ 75 - 0
src/views/user/club-portrait/components/hot-tips.vue

@@ -0,0 +1,75 @@
+<template>
+  <div class="hot-container">
+    <div class="content">
+      <el-tag v-for="(hot, i) in reloadData" :key="i" :effect="hot.label === 1 ? 'dark' : 'info'" style="margin: 5px">
+        {{ hot.text }}
+      </el-tag>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    keywordData: {
+      type: Array,
+      default: () => [
+        {
+          logo: "https://baidu.jpg",
+          bandName:
+            "百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度百度",
+          top: 1,
+        },
+      ],
+    },
+  },
+  computed: {
+    reloadData() {
+      const d = this.keywordData;
+      return d.map((e) => {
+        if (e) {
+          return e;
+        } else return {};
+      });
+    },
+  },
+  methods: {
+    isObj(str) {
+      return typeof str === "object";
+    },
+    is_picture(str) {
+      const r = new RegExp(/\.(png|jpe?g|gif|svg|JPEG)(\?.*)?$/);
+      return r.test(str);
+    },
+  },
+};
+</script>
+
+<style scoped lang="scss">
+.hot-container {
+  border-radius: 12px;
+  overflow: hidden;
+  border: 1px solid #ccc;
+  box-shadow: 0 0 4px #ccc;
+  .head {
+    padding: 10px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+  .content {
+    padding: 10px;
+    font-size: 14px;
+    .title {
+      display: grid;
+      align-items: center;
+      padding-bottom: 10px;
+      border-bottom: 1px solid #ccc;
+      align-items: center;
+      span {
+        text-align: center;
+      }
+    }
+  }
+}
+</style>

+ 126 - 0
src/views/user/club-portrait/components/pei-echarts.vue

@@ -0,0 +1,126 @@
+<template>
+  <div class="echarts-content">
+    <div ref="echarts" class="bar_echarts"></div>
+  </div>
+</template>
+
+<script>
+import echarts from "echarts";
+export default {
+  props: {
+    title: {
+      type: String,
+      default: () => "myEcharts",
+    },
+    optionData: {
+      type: Object,
+      default: () => ({}),
+    },
+  },
+  data() {
+    return {
+      timeTicket: null,
+      chart: null,
+      optionData1: {},
+    };
+  },
+  watch: {
+    optionData: {
+      handler(val) {
+        if (val) {
+          clearInterval(this.timeTicket)
+          this.timeTicket = null
+          this.optionData1 = val
+          console.log("option-data111111111", this.optionData1)
+          this.initChart()
+        }
+      },
+      deep: true,
+      immediate: true,
+    },
+  },
+  mounted() {
+    // 初始化图表
+    this.chart = echarts.init(this.$refs["echarts"])
+    // 初始设置和配置...
+    this.initChart() // 调用函数设置初始图表
+  },
+  methods: {
+    initChart() {
+      // 如果图表实例存在,先清空数据和配置项(可选)
+      if (this.chart) {
+        this.chart.clear() // 清空当前图表
+      }
+      const option = {
+        title: {
+          text: this.optionData1.name,
+        },
+        tooltip: {
+          trigger: "item",
+        },
+        legend: {
+          orient: "vertical",
+          right: "2%",
+          top: "20%",
+          textStyle: {
+            fontSize: 14,
+            color: "#333333",
+          },
+        },
+        color: this.optionData1.color,
+        series: [
+          {
+            name: this.optionData1.name,
+            type: "pie",
+            radius: "55%",
+            center: ["25%", "50%"],
+            avoidLabelOverlap: false,
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: "rgba(0, 0, 0, 0.5)",
+              },
+            },
+            label: {
+              show: false,
+              position: "center",
+            },
+            data: this.optionData1.seriesData,
+          },
+        ],
+      };
+      // 使用刚指定的配置项和数据显示图表。
+      if (this.chart) {
+        this.chart.setOption(option)
+      }
+    },
+  },
+  beforeDestroy() {
+    // 组件销毁前,销毁图表实例
+    if (this.chart) {
+      this.chart.dispose()
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.echarts-content {
+  width: 100%;
+  height: 400px;
+  border-radius: 12px;
+  border: 1px solid #ccc;
+  box-shadow: 0 0 4px #ccc;
+  overflow: hidden;
+  padding: 10px;
+  .title {
+    display: flex;
+    align-items: center;
+  }
+  .bar_echarts {
+    width: 100%;
+    height: 100%;
+  }
+}
+</style>

+ 124 - 0
src/views/user/club-portrait/components/select-time.vue

@@ -0,0 +1,124 @@
+<template>
+  <div class="time-select">
+    <div
+      v-for="i in timeList"
+      :key="i.id"
+      class="time-tap"
+      :class="activeId === i.id && 'active'"
+      @click="handleTimeSelct(i)"
+    >
+      {{ i.content }}
+    </div>
+    <el-date-picker
+      v-model="time"
+      type="daterange"
+      range-separator="至"
+      start-placeholder="开始日期"
+      end-placeholder="结束日期"
+      format="yyyy-MM-dd"
+      value-format="yyyy-MM-dd"
+    />
+  </div>
+</template>
+
+<script>
+import loopEchart from '../mixins/index'
+
+export default {
+  mixins: [loopEchart],
+  props: {
+    timeList: {
+      type: Array,
+      default: () => [
+        {
+          id: 1,
+          content: '昨天'
+        },
+        {
+          id: 2,
+          content: '近1月'
+        },
+        {
+          id: 3,
+          content: '近6月'
+        },
+        {
+          id: 4,
+          content: '近1年'
+        },
+        {
+          id: 0,
+          content: '全部'
+        }
+      ]
+    },
+    activeLinkId: {
+      type: Number,
+      default: 1
+    }
+  },
+  data() {
+    return {
+      time: [],
+      activeId: 1
+    }
+  },
+  watch: {
+    activeId: {
+      handler(e) {
+        const obj = {
+          1: () => this.getYesterDay(1),
+          2: () => this.getMonths(1),
+          3: () => this.getMonths(6),
+          4: () => this.getYears(1),
+          0: () => {
+            this.time = []
+          },
+          5: () => this.getWeeks(1)
+        }
+        this.time = e !== 0 ? [obj[e](), this.getDay()] : ['', '']
+      },
+      immediate: true
+    },
+    time: {
+      handler(e) {
+        this.$emit('handleSelectTime', e)
+      },
+      immediate: true
+    },
+    activeLinkId: {
+      handler(val) {
+        if (val) {
+          this.activeId = val
+        }
+      },
+      immediate: true
+    }
+  },
+  methods: {
+    handleTimeSelct($event) {
+      this.activeId = $event.id
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.time-select {
+  display: flex;
+  align-items: center;
+  padding: 0.5vw 0;
+  .time-tap {
+    margin-right: 1vw;
+    font-size: 14px;
+    color: #ccc;
+    cursor: pointer;
+    &.active {
+      color: rgb(0, 174, 255);
+    }
+  }
+}
+.el-picker-panel {
+  z-index: 9999999 !important;
+}
+</style>

+ 455 - 0
src/views/user/club-portrait/index.vue

@@ -0,0 +1,455 @@
+<template>
+  <div class="report">
+    <div class="ins_echart_headers">
+      <div class="ins_headers_flx">
+        <div class="nums n4">
+          客户需求:{{ dataValue.orderData.orderTotalNum || 0 }}个
+        </div>
+      </div>
+      <div class="ins_headers_flx">
+        <select-time @handleSelectTime="handleSelectTime($event, 0)" />
+      </div>
+      <el-button type="success" @click="handleClubDialog(1)">机构活跃信息</el-button>
+      <el-button type="success" @click="handleClubDialog(2)">机构资料</el-button>
+    </div>
+    <div class="ins_keword">
+      <hot-tips :keyword-data="keywordData" />
+    </div>
+    <div class="ins_rcharts_main">
+      <div class="ins_rcharts_item">
+        <div class="ins_echart_headers">
+          <div class="ins_headers_flx">
+            <div class="nums">
+              订单数量:{{ dataValue.orderData.orderTotalNum || 0 }}个
+            </div>
+          </div>
+          <div class="ins_headers_flx">
+            <select-time @handleSelectTime="handleSelectTime($event, 1)" />
+          </div>
+        </div>
+        <div class="ins_statistics">
+          <div class="content">
+            <pie-echarts :option-data="dataValue.orderData" :title="'订单'" />
+          </div>
+        </div>
+      </div>
+      <div class="ins_rcharts_item">
+        <div class="ins_echart_headers">
+          <div class="ins_headers_flx">
+            <div class="nums">
+              关键词数量:{{ dataValue.keyWordsData.count || 0 }}个
+            </div>
+          </div>
+          <div class="ins_headers_flx">
+            <select-time @handleSelectTime="handleSelectTime($event, 2)" />
+          </div>
+        </div>
+        <div class="ins_trends">
+          <bar-echarts :option-data="dataValue.keyWordsData.data" :title="'搜索关键词'" />
+        </div>
+      </div>
+    </div>
+    <div class="ins_rcharts_main">
+      <div class="ins_rcharts_item">
+        <div class="ins_echart_headers">
+          <div class="ins_headers_flx">
+            <div class="nums">咨询数量:
+              <span class="line" @click="handleRouter(1)">{{ dataValue.consultData.count || 0 }}个</span>
+            </div>
+          </div>
+          <div class="ins_headers_flx">
+            <select-time @handleSelectTime="handleSelectTime($event, 3)" />
+          </div>
+        </div>
+        <div class="ins_trends">
+          <bar-echarts :option-data="dataValue.consultData.data" :title="'咨询记录'" />
+        </div>
+      </div>
+      <div class="ins_rcharts_item">
+        <div class="ins_echart_headers">
+          <div class="ins_headers_flx">
+            <div class="nums">访问数量:
+              <span class="line" @click="handleRouter(2)">{{ dataValue.accessData.count || 0 }}个</span>
+            </div>
+          </div>
+          <div class="ins_headers_flx">
+            <select-time @handleSelectTime="handleSelectTime($event, 4)" />
+          </div>
+        </div>
+        <div class="ins_trends">
+          <bar-echarts :option-data="dataValue.accessData.data" :title="'访问记录'" />
+        </div>
+      </div>
+    </div>
+    <!--  信息弹窗 -->
+    <club-dialog v-if="dialogVisible" :dialog-type="dialogType" @cancel="handleCancel" />
+  </div>
+</template>
+
+<script>
+import SelectTime from "./components/select-time";
+import PieEcharts from "./components/pei-echarts.vue";
+import BarEcharts from "./components/bar-echarts.vue";
+import HotTips from "./components/hot-tips.vue";
+import ClubDialog from "./components/club-dialog.vue";
+import {
+  getIns_statistics,
+  getIns_orderTrends,
+  getIns_accessStatistics,
+} from "@/api/mallPortrait/disitrib";
+
+export default {
+  components: {
+    ClubDialog,
+    SelectTime,
+    PieEcharts,
+    BarEcharts,
+    HotTips,
+  },
+  data() {
+    return {
+      clubId:'',
+      clubName:'',
+      dialogVisible: false,
+      dialogType: 1,
+      keywordData: [
+        { text: "品牌logo", label: 1 },
+        { text: "品牌logo", label: 1 },
+        { text: "品牌logo", label: 1 },
+        { text: "品牌logo", label: 1 },
+        { text: "品牌logo", label: 1 },
+        { text: "品牌logo", label: 1 },
+        { text: "品牌logo", label: 1 },
+        { text: "品牌logo", label: 1 },
+        { text: "品牌logo", label: 1 },
+        { text: "品牌logo", label: 1 },
+        { text: "品牌logo", label: 1 },
+        { text: "品牌名称", label: 1 },
+        { text: "品牌名称", label: 1 },
+        { text: "品牌名称", label: 1 },
+        { text: "TOP", label: 0 },
+        { text: "TOP", label: 0 },
+        { text: "TOP", label: 0 },
+      ],
+      storeColumns: [
+        { text: "商品图片", label: "image", labelWidth: 80 },
+        { text: "商品名称", label: "name" },
+        { text: "TOP", label: "top", labelWidth: 80 },
+      ],
+      keyColumns: [
+        { text: "搜索词", labelWidth: 120 },
+        { text: "TOP", label: "top" },
+      ],
+      dataValue: {
+        // 机构活跃度统计
+        clubActivityCount: {
+          data: {
+            不活跃机构: 0,
+            活跃机构: 0,
+          },
+        },
+        // 订单统计
+        orderData: {
+          orderTotalNum: 1,
+          name: "订单总量",
+          color: ["#3aa0ff", "#36cbcb", "#fad337", "#4dcb73", "#f2637b", "#975fe4"],
+          seriesData: [
+            {
+              name: "普通订单 【100%】 【1个】",
+              value: 1,
+            },
+            {
+              name: "二手订单 【 0 %】 【0个】",
+              value: 0,
+            },
+          ],
+        },
+        // 咨询记录
+        consultData: {
+          data: {
+            name: "咨询记录",
+            yAxisData: [
+              "撒肯德基阿拉基",
+              "水阿斯达四大光",
+              "士大夫撒多发生的",
+              "asdas阿瑟的",
+              "奥术大师大所多",
+              "第三方士大夫",
+              "从VB餐补v",
+              "水电费",
+            ],
+            xAxisData: [1, 1, 2, 2, 2, 3, 5, 6],
+            color: "#FF5B00",
+          },
+          count: 11,
+        },
+        keyWordsData: {
+          data: {
+            name: "搜索关键词",
+            yAxisData: [
+              "热玛吉",
+              "水光",
+              "超清秀",
+              "黄金微针",
+              "LDM",
+              "皮秒",
+              "检测",
+              "水光仪",
+            ],
+            xAxisData: [1, 1, 2, 2, 2, 3, 5, 6],
+            color: "#07c160",
+          },
+          count: 11,
+        },
+        // 访问记录
+        accessData: {
+          data: {
+            name: "访问记录",
+            yAxisData: [
+              "玩儿玩儿",
+              "让他也让他也让他",
+              "日也同样",
+              "水电费",
+              "发挂号费",
+              "CVBS",
+              "不你们部门",
+              "电饭锅电饭锅",
+            ],
+            xAxisData: [1, 1, 2, 2, 2, 3, 5, 6],
+            color: "#6585fa",
+          },
+          count: 11,
+        },
+        // 机构新增趋势
+        addClubCount: {},
+        // 机构订单趋势
+        clubOrder: {},
+        // 机构访问统计
+        record: {},
+        // 机构咨询统计
+        remarks: {
+          data: {
+            游客咨询: 0,
+            机构咨询: 0,
+          },
+        },
+        // 热门品牌
+        brandProductSalesRecords: [],
+        // 热门商品
+        productSalesRecords: [],
+        // 热搜词
+        keywords: [],
+      },
+      timeList: [
+        {
+          id: 5,
+          content: "近一周",
+        },
+        {
+          id: 2,
+          content: "近1月",
+        },
+        {
+          id: 3,
+          content: "近6月",
+        },
+        {
+          id: 4,
+          content: "近1年",
+        },
+      ],
+    };
+  },
+  created() {
+    this.clubId = this.$route.query.clubId
+    this.clubName = this.$route.query.clubName
+
+  },
+  methods: {
+    handleRouter(type){
+      switch (type) {
+        case 1: // 咨询记录
+          this.$router.push({
+            path: '/user/consult/list',
+            query: { clubName:this.clubName,clubId: this.clubId }
+          })
+          break
+        case 2: // 行为记录
+          this.$router.push({
+            path: '/user/record-list',
+            query: { type:'first',corporateName:this.clubName,clubId: this.clubId }
+          })
+          break
+      }
+    },
+    handleClubDialog(type) {
+      this.dialogType = type;
+      this.dialogVisible = true;
+    },
+    handleCancel() {
+      this.dialogVisible = false;
+    },
+    /**
+     * 获取机构需求
+     */
+    async getCulbDemand(e) {
+      const { data } = await getCulbDemand({
+        startCreateTime: e[0],
+        endCreateTime: e[1],
+      });
+      this.dataValue.clubActivityCount = data.clubActivityCount;
+      this.dataValue.clubCount = data.clubCount;
+    },
+    /**
+     * 机构订单数据
+     */
+    async getIns_statistics(e) {
+      const { data } = await getIns_statistics({
+        startCreateTime: e[0],
+        endCreateTime: e[1],
+      });
+      this.dataValue.clubActivityCount = data.clubActivityCount;
+      this.dataValue.clubCount = data.clubCount;
+    },
+     /**
+     * 获取机构搜索词
+     */
+    async getIns_orderTrends(e) {
+      const { data } = await getIns_orderTrends({
+        startCreateTime: e[0],
+        endCreateTime: e[1],
+      });
+      this.dataValue.addClubCount = data.clubCount;
+      this.dataValue.clubOrder = data.clubOrder;
+    },
+     /**
+     * 获取机构咨询数据
+     */
+    async getIns_accessStatistics(e) {
+      const { data } = await getIns_accessStatistics({
+        startCreateTime: e[0],
+        endCreateTime: e[1],
+      });
+      this.dataValue.record = data.record;
+      this.dataValue.remarks = data.remarks;
+      this.dataValue.brandProductSalesRecords = data.brandProductSalesRecords;
+      this.dataValue.productSalesRecords = data.productSalesRecords;
+      this.dataValue.keywords = data.keywords;
+    },
+     /**
+     * 获取机构访问记录数据
+     */
+    async getIns_accessStatistics(e) {
+      const { data } = await getIns_accessStatistics({
+        startCreateTime: e[0],
+        endCreateTime: e[1],
+      });
+      this.dataValue.record = data.record;
+      this.dataValue.remarks = data.remarks;
+      this.dataValue.brandProductSalesRecords = data.brandProductSalesRecords;
+      this.dataValue.productSalesRecords = data.productSalesRecords;
+      this.dataValue.keywords = data.keywords;
+    },
+    handleSelectTime(e, num) {
+      const obj = {
+        0: () => this.getCulbDemand(e), // 机构需求
+        1: () => this.getIns_statistics(e),
+        2: () => this.getIns_orderTrends(e),
+        3: () => this.getIns_accessStatistics(e),
+        4: () => this.getIns_accessStatistics(e),
+      };
+      obj[num]();
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.report {
+  padding: 20px;
+
+  background-size: contain;
+  .ins_header {
+    width: 100%;
+    height: auto;
+    box-sizing: border-box;
+    .flex-header-main {
+      width: 100%;
+      height: 100%;
+      box-sizing: border-box;
+      padding: 10px 0;
+      text-align: right;
+    }
+  }
+  .ins_echart_headers {
+    width: 100%;
+    height: auto;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    .ins_headers_flx {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      margin: 0 10px;
+      .line{
+        text-decoration: underline;
+        cursor: pointer;
+      }
+    }
+  }
+  .ins_rcharts_main {
+    display: grid;
+    align-items: center;
+    grid-template-columns: 1fr 1fr;
+    grid-gap: 1vw;
+    margin-bottom: 14px;
+  }
+  .ins_keword {
+    display: grid;
+    align-items: center;
+    grid-template-columns: 1fr;
+    grid-gap: 1vw;
+    margin-bottom: 14px;
+  }
+  .ins_statistics {
+    display: grid;
+    align-items: center;
+    grid-template-columns: 1fr;
+    grid-gap: 1vw;
+    margin-bottom: 14px;
+  }
+  .ins_deStatistics {
+    display: grid;
+    align-items: center;
+    grid-template-columns: 1fr 1fr;
+    grid-gap: 1vw;
+    margin-bottom: 14px;
+  }
+}
+.label {
+  font-size: 16px;
+  font-weight: 600;
+  margin-right: 20px;
+}
+.nums {
+  font-size: 16px;
+  color: #00aeff;
+  font-weight: 600;
+
+}
+.tips {
+  font-size: 14px;
+  color: #ccc;
+}
+.e-title {
+  font-size: 14px;
+  color: #ccc;
+  text-align: center;
+}
+.hot-content {
+  display: grid;
+  grid-template-columns: 2fr 2fr 1.5fr;
+  grid-gap: 14px;
+}
+</style>

+ 134 - 0
src/views/user/club-portrait/mixins/index.js

@@ -0,0 +1,134 @@
+import moment from 'moment'
+
+export default {
+  data() {
+    return {
+      timeTicket: null,
+      currentIndex: -1
+    }
+  },
+  methods: {
+    handleChartLineLoop(option, myChart) {
+      if (!myChart) {
+        return
+      }
+      const selectPie = () => {
+        const dataLen = option.series[0].data.length
+        this.currentIndex = (this.currentIndex + 1) % dataLen
+        highlightLine()
+      }
+      this.timeTicket = setInterval(selectPie, 1500)
+
+      const highlightLine = () => {
+        // 遍历饼图数据,取消所有图形的高亮效果
+        for (const idx in option.series[0].data) {
+          myChart.dispatchAction({
+            type: 'downplay',
+            seriesIndex: 0,
+            dataIndex: idx
+          })
+        }
+        myChart.dispatchAction({
+          type: 'showTip',
+          seriesIndex: 0,
+          dataIndex: this.currentIndex
+        })
+        myChart.setOption(option)
+      }
+
+      this.handleMouseOver(myChart, () => {
+        clearInterval(this.timeTicket)
+      })
+
+      this.handleMouseOut(myChart, () => {
+        if (this.timeTicket) {
+          clearInterval(this.timeTicket)
+        }
+        this.timeTicket = setInterval(selectPie, 1500)
+      })
+    },
+
+    handleChartPieLoop(option, myChart, pieTimeTicket, currentIndex, showTips = false) {
+      if (!myChart) {
+        return
+      }
+      const selectPie = () => {
+        const dataLen = option.series[0].data.length
+        this[currentIndex] = (this[currentIndex] + 1) % dataLen
+        highlightPie()
+      }
+
+      this[pieTimeTicket] = setInterval(selectPie, 2000) // 设置自动切换高亮图形的定时器
+
+      // 取消所有高亮并高亮当前图形
+      const highlightPie = () => {
+        // 遍历饼图数据,取消所有图形的高亮效果
+        for (const idx in option.series[0].data) {
+          myChart.dispatchAction({
+            type: 'downplay',
+            seriesIndex: 0,
+            dataIndex: idx
+          })
+        }
+        // 高亮当前图形
+        myChart.dispatchAction({
+          type: 'highlight',
+          seriesIndex: 0,
+          dataIndex: this[currentIndex]
+        })
+        showTips && myChart.dispatchAction({
+          type: 'showTip',
+          seriesIndex: 0,
+          dataIndex: this[currentIndex]
+        })
+      }
+      myChart.on('mouseover', (params) => {
+        clearInterval(this[pieTimeTicket])
+        this[currentIndex] = params.dataIndex
+        highlightPie()
+      })
+
+      // 用户鼠标移出时,重新开始自动切换
+      myChart.on('mouseout', () => {
+        if (this[pieTimeTicket]) {
+          clearInterval(this[pieTimeTicket])
+        }
+        this[pieTimeTicket] = setInterval(selectPie, 2000)
+      })
+
+      this.handleMouseOver(myChart, () => {
+        clearInterval(this[pieTimeTicket])
+      })
+
+      this.handleMouseOut(myChart, () => {
+        if (this[pieTimeTicket]) {
+          clearInterval(this[pieTimeTicket])
+        }
+        this[pieTimeTicket] = setInterval(selectPie, 2000)
+      })
+    },
+    /**
+     * @returns 获取今天的时间
+     */
+    getDay() {
+      return moment().format('YYYY-MM-DD')
+    },
+    /**
+     * 获取从今天开始指定天数
+     * @param {Number} num
+     * @returns string
+     */
+    getYesterDay(num) {
+      return moment().subtract(num, 'days').format('YYYY-MM-DD')
+    },
+    getMonths(num) {
+      return moment().subtract(num, 'months').format('YYYY-MM-DD')
+    },
+    getYears(num) {
+      return moment().subtract(num, 'years').format('YYYY-MM-DD')
+    },
+    getWeeks(num) {
+      return moment().subtract(num, 'weeks').format('YYYY-MM-DD')
+    }
+  }
+}

+ 312 - 147
src/views/user/club/list.vue

@@ -1,113 +1,290 @@
 <template>
   <div class="app-container">
-    机构列表
+    <!-- 顶部操作区域 -->
+    <div class="filter-container">
+      <div class="filter-control">
+        <span>机构ID:</span>
+        <el-input
+          v-model="listQuery.clubId"
+          style="width: 120px"
+          placeholder="机构ID"
+          clearable
+          maxlength="10"
+          @keyup.enter.native="getList"
+          @clear="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <span>机构名称:</span>
+        <el-input
+          v-model="listQuery.name"
+          placeholder="机构名称"
+          clearable
+          @keyup.enter.native="getList"
+          @clear="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <span>手机号:</span>
+        <el-input
+          v-model="listQuery.contractMobile"
+          placeholder="手机号"
+          maxlength="11"
+          clearable
+          @keyup.enter.native="getList"
+          @clear="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <span>联系人:</span>
+        <el-input
+          v-model="listQuery.linkMan"
+          placeholder="联系人名称"
+          clearable
+          @keyup.enter.native="getList"
+          @clear="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <span>机构状态:</span>
+        <el-select v-model="listQuery.status" style="width: 150px" clearable @change="getList">
+          <el-option value="" label="请选择" />
+          <el-option :value="90" label="已上线" />
+          <el-option :value="91" label="已下线" />
+          <el-option :value="1" label="待审核" />
+          <el-option :value="92" label="审核未通过" />
+          <el-option :value="93" label="已确认" />
+          <el-option :value="94" label="已冻结" />
+        </el-select>
+      </div>
+      <div class="filter-control">
+        <span>机构级别:</span>
+        <el-select v-model="listQuery.userIdentity" style="width: 150px" clearable @change="getList">
+          <el-option value="" label="请选择" />
+          <el-option :value="4" label="个人机构" />
+          <el-option :value="2" label="资质机构" />
+          <el-option :value="8" label="超级会员" />
+        </el-select>
+      </div>
+      <div class="filter-control">
+        <span>协销:</span>
+        <el-select v-model="listQuery.spId" style="width: 150px" filterable @change="getList">
+          <el-option value="" label="请选择" />
+          <el-option
+            v-for="item in sellerOption"
+            :key="item.serviceProviderId"
+            :label="item.linkMan"
+            :value="item.serviceProviderId"
+          />
+        </el-select>
+      </div>
+      <div class="filter-control">
+        <span>动态标签:</span>
+        <el-select v-model="listQuery.trendsLabel" filterable @change="getList">
+          <el-option value="" label="请选择" />
+          <el-option
+            v-for="(item,index) in trendsLabelOption"
+            :key="index"
+            :label="item.label"
+            :value="item.label"
+          />
+        </el-select>
+      </div>
+      <div class="filter-control">
+        <span>静态标签:</span>
+        <el-select v-model="listQuery.stateLabel" filterable @change="getList">
+          <el-option value="" label="请选择" />
+          <el-option
+            v-for="(item,index) in stateLabelOption"
+            :key="index"
+            :label="item.label"
+            :value="item.label"
+          />
+        </el-select>
+      </div>
+      <div class="filter-control">
+        <span>注册时间:</span>
+        <el-date-picker
+          v-model="time"
+          type="daterange"
+          unlink-panels
+          value-format="yyyy-MM-dd"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          :picker-options="pickerOptions"
+          @change="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <span>分配时间:</span>
+        <el-date-picker
+          v-model="time1"
+          type="daterange"
+          unlink-panels
+          value-format="yyyy-MM-dd"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          :picker-options="pickerOptions"
+          @change="getList"
+        />
+      </div>
+      <div class="filter-control">
+        <el-button type="primary" @click="getList"> 查询 </el-button>
+      </div>
+    </div>
+    <!-- 列表 -->
+    <el-table v-loading="isLoading" :data="list" border style="width: 100%" height="660">
+      <el-table-column prop="clubId" fixed label="机构ID" align="center" width="80" />
+      <el-table-column prop="name" fixed label="机构名称" align="center" />
+      <el-table-column prop="linkMan" label="联系人" align="center" width="100" />
+      <el-table-column prop="spName" label="协销人员" align="center" width="120" />
+      <el-table-column prop="contractMobile" label="手机号" align="center" width="150">
+        <template slot-scope="{ row }">
+          {{ row.contractMobile ? row.contractMobile : '---' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="status" label="机构状态" align="center" width="100">
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.status === 1" type="warning" size="small">待审核</el-tag>
+          <el-tag v-if="row.status === 90" type="success" size="small">已上线</el-tag>
+          <el-tag v-if="row.status === 91" type="info" size="small">已下线</el-tag>
+          <el-tag v-if="row.status === 92" type="danger" size="small">审核未通过</el-tag>
+          <el-tag v-if="row.status === 93" type="warning" size="small">已确认</el-tag>
+          <el-tag v-if="row.status === 94" type="danger" size="small">已冻结</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column prop="userIdentity" label="机构级别" align="center" width="150">
+        <template slot-scope="{ row }">
+          <template v-if="row.userIdentity === '4'">
+            <el-tag v-if="row.userIdentity === '4' && row.svipUserFlag === 1" type="success" size="small">个人机构(超级会员)</el-tag>
+            <el-tag v-else type="info" size="small">个人机构(普通会员)</el-tag>
+          </template>
+          <template v-if="row.userIdentity === '2'">
+            <el-tag v-if="row.userIdentity === '2' && row.svipUserFlag ===1" type="success" size="small">资质机构(超级会员)</el-tag>
+            <el-tag v-if="row.userIdentity === '2' && row.svipUserFlag !==1 && !row.medicalPracticeLicenseImg" type="warning" size="small">资质机构(高级会员)</el-tag>
+            <el-tag v-if="row.userIdentity === '2' && row.svipUserFlag !==1 && row.medicalPracticeLicenseImg" type="danger" size="small">资质机构(医美会员)</el-tag>
+          </template>
+        </template>
+      </el-table-column>
+      <el-table-column prop="source" label="注册IP" align="center" width="180">
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.source === '0'" effect="plain" type="warning" size="small">{{ row.registerIP }}(网站)</el-tag>
+          <el-tag v-if="row.source === '1'" effect="plain" type="warning" size="small">{{ row.registerIP }}(小程序)</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column prop="addTime" label="注册时间" align="center" width="100">
+        <template slot-scope="{ row }">
+          {{ row.addTime ? row.addTime : '---' }}
+        </template>
+      </el-table-column>
+      <el-table-column fixed="right" label="操作" align="center">
+        <template slot-scope="{ row }">
+          <el-button type="success" size="mini" style="margin: 4px" @click="handleRecordDetail(3, row)">
+            机构画像
+          </el-button>
+          <el-button type="primary" size="mini" style="margin: 4px" @click="handleRecordDetail(2, row)">
+            行为记录
+          </el-button>
+          <el-button type="primary" size="mini" style="margin: 4px" @click="handleRecordDetail(1, row)">
+            咨询记录
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 页码 -->
+    <pagination
+      :total="total"
+      :page-sizes="[10, 20, 30, 100]"
+      :page-size="20"
+      :page.sync="listQuery.pageNum"
+      :limit.sync="listQuery.pageSize"
+      @pagination="getClubList"
+    />
   </div>
 </template>
 
 <script>
-import { parseTime } from '@/utils'
-import { fetchKeywordList, joinKeywordLibrary } from '@/api/library/keyword'
-import { export_json_to_excel } from '@/vendor/Export2Excel'
-
+import { getClubList, getClubLabel } from '@/api/user/club/club'
+import { getServiceList } from '@/api/library/keyword'
+import pickerOptions from '@/utils/time-picker.js'
 export default {
+  name: 'CustomerList',
+  filters: {},
   data() {
-    const pickerOptions = {
-      shortcuts: [
-        {
-          text: '近1年',
-          onClick(picker) {
-            const end = new Date()
-            const start = new Date()
-            start.setTime(start.getTime() - 3600 * 1000 * 24 * 365)
-            picker.$emit('pick', [start, end])
-          }
-        },
-        {
-          text: '近半年',
-          onClick(picker) {
-            const end = new Date()
-            const start = new Date()
-            start.setTime(start.getTime() - 3600 * 1000 * 24 * 183)
-            picker.$emit('pick', [start, end])
-          }
-        },
-        {
-          text: '近1月',
-          onClick(picker) {
-            const end = new Date()
-            const start = new Date()
-            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
-            picker.$emit('pick', [start, end])
-          }
-        },
-        {
-          text: '近1周',
-          onClick(picker) {
-            const end = new Date()
-            const start = new Date()
-            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
-            picker.$emit('pick', [start, end])
-          }
-        },
-        {
-          text: '昨天',
-          onClick(picker) {
-            const end = new Date()
-            const start = new Date()
-            start.setTime(start.getTime() - 3600 * 1000 * 24)
-            picker.$emit('pick', [start, end])
-          }
-        }
-      ]
-    }
     return {
       isLoading: true,
-      time: '',
+      pickerOptions,
+      time: [],
+      time1: [],
       listQuery: {
-        keyword: '',
-        beginTime: '',
+        clubId: '',
+        name: '',
+        contractMobile: '',
+        userIdentity: '',
+        startTime: '',
         endTime: '',
-        labelStatus: '',
-        searchTimeCode: '',
-        fromSearch: '',
+        allocationStartTime: '',
+        allocationEndTime: '',
+        newDeal: '',
+        spId: '',
+        trendsLabel: '',
+        stateLabel: '',
+        status: '',
         pageNum: 1,
-        pageSize: 10
+        pageSize: 20
       },
-      pickerOptions,
       list: [],
       total: 0,
-      currentList: [],
-      searchDialog: false,
-      visibleKeyword: ''
-    }
-  },
-  computed: {
-    disabled() {
-      return this.currentList.length === 0
+      sellerOption: [],
+      trendsLabelOption: [],
+      stateLabelOption: [],
+      shopDialogVisible: false,
+      dialogFormVisible: false,
+      renewCustome: {
+        id: '',
+        status: ''
+      },
+      rules: {
+        status: [{ required: true, message: '请设置统计状态', trigger: 'blur' }]
+      }
     }
   },
+  computed: {},
   created() {
+    this.getTrendsLabel()
+    this.getStateLabel()
+    this.getServiceList()
     this.getList()
   },
+  mounted() {},
   methods: {
-    // 获取关键词列表
+    // 获取行为记录列表
     getList() {
+      this.list = []
+      this.isLoading = true
       this.listQuery.pageNum = 1
       if (this.time && this.time.length > 0) {
-        this.listQuery.beginTime = this.time[0]
+        this.listQuery.startTime = this.time[0]
         this.listQuery.endTime = this.time[1]
       } else {
-        this.listQuery.beginTime = ''
+        this.listQuery.startTime = ''
         this.listQuery.endTime = ''
       }
-      this.fetchKeywordList()
+      if (this.time1 && this.time1.length > 0) {
+        this.listQuery.allocationStartTime = this.time1[0]
+        this.listQuery.allocationEndTime = this.time1[1]
+      } else {
+        this.listQuery.allocationStartTime = ''
+        this.listQuery.allocationEndTime = ''
+      }
+      this.getClubList()
     },
-
-    // 获取关键词列表
-    async fetchKeywordList() {
+    // 获取机构列表
+    async getClubList() {
       try {
-        this.isLoading = true
-        const res = await fetchKeywordList(this.listQuery)
+        const res = await getClubList(this.listQuery)
         this.list = res.data.results
         this.total = res.data.totalRecord
         this.isLoading = false
@@ -115,89 +292,77 @@ export default {
         console.log(error)
       }
     },
-
-    // 添加到标签库
-    async handleAddLibrary(row) {
+    // 获取协销列表选项
+    async getServiceList() {
       try {
-        await this.$confirm('确定将所选标签加入到标签库?', {
-          confirmButtonText: '确定',
-          cancelButtonText: '取消',
-          type: 'warning'
-        })
-        this.addLibrarySubmit(row)
+        const res = await getServiceList()
+        this.sellerOption = res.data
       } catch (error) {
-        this.$message.info('已取消操作')
+        console.log(error)
       }
     },
-
-    // 添加到标签库提交
-    async addLibrarySubmit(row) {
-      const keywords = row instanceof Event ? this.currentList : [].concat(row)
-      const ids = keywords.map((item) => item.id).join(',')
+    // 获取动态标签
+    async getTrendsLabel() {
       try {
-        await joinKeywordLibrary({ id: ids })
-        this.$message.success('添加关键词库成功')
-        keywords.forEach((item) => {
-          item.labelStatus = 1
-        })
+        const res = await getClubLabel({ dynamicStatus: 0 })
+        const data = res.data
+        this.trendsLabelOption = data
       } catch (error) {
         console.log(error)
       }
     },
-
-    // 选中列表项
-    handleSelectionChange(current) {
-      this.currentList = current
-    },
-
-    // 去搜索
-    handleSearch(keyword) {
-      this.visibleKeyword = keyword
-      this.searchDialog = true
-    },
-
-    // 导出
-    async handleExport() {
+    // 获取静态标签
+    async getStateLabel() {
       try {
-        await this.$confirm('确定将所选标签导出为xlsx?', {
-          confirmButtonText: '确定',
-          cancelButtonText: '取消',
-          type: 'warning'
-        })
-        // 导出数据格式化
-        const filterVal = ['index', 'keyword', 'frequency', 'searchTime', 'labelStatus']
-        const data = this.formatJson(filterVal, this.currentList.slice(0))
-        export_json_to_excel({
-          header: ['序号', '标签', '搜索次数', '最近搜索时间', '标签库状态'],
-          data,
-          filename: '关键词列表'
-        })
+        const res = await getClubLabel({ dynamicStatus: 1 })
+        const data = res.data
+        this.stateLabelOption = data
       } catch (error) {
-        this.$message.info('已取消导出操作')
+        console.log(error)
       }
     },
-
-    formatJson(filterVal, jsonData) {
-      return jsonData.map((v, index) =>
-        filterVal.map((key) => {
-          if (['searchTime'].includes(key)) {
-            return parseTime(v[key])
-          }
-          if (key === 'index') return index + 1
-          if (key === 'labelStatus') {
-            const t = ['未添加', '已添加', '导入']
-            return t[v[key]]
-          }
-          return v[key]
-        })
-      )
-    },
-
-    indexMethod(index) {
-      return index + this.listQuery.pageSize * (this.listQuery.pageNum - 1) + 1
+    // 操作
+    handleRecordDetail(type, row) {
+      switch (type) {
+        case 1: // 咨询记录
+          this.$router.push({
+            path: '/user/consult/list',
+            query: { clubName: row.name, clubId: row.clubId }
+          })
+          break
+        case 2: // 行为记录
+          this.$router.push({
+            path: '/user/record-list',
+            query: { type: 'first', corporateName: row.name, clubId: row.clubId }
+          })
+          break
+        case 3: // 机构画像
+          this.$router.push({
+            path: '/user/club-portrait',
+            query: { clubName: row.name, clubId: row.clubId }
+          })
+          break
+      }
     }
   }
 }
 </script>
 
-<style></style>
+<style>
+.avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+  float: left;
+}
+.uploader-tips {
+  position: absolute;
+  bottom: 0;
+  left: 160px;
+  line-height: 28px;
+  color: red;
+  margin: 0;
+}
+</style>

+ 5 - 1
src/views/user/customer/components/share-dialog.vue

@@ -39,6 +39,10 @@ export default {
       type: Number,
       default: 2345
     },
+    shareDirectLink: {
+      type: String,
+      default: ''
+    },
     shareLink: {
       type: String,
       default: ''
@@ -87,7 +91,7 @@ export default {
 
     // 直接预览
     handleConfirm() {
-      window.open(this.shareLink, '_blank')
+      window.open(this.shareDirectLink, '_blank')
     },
     handleCanle() {
       // 取消弹窗

+ 3 - 3
src/views/user/customer/customer-goods-list.vue

@@ -112,7 +112,7 @@
       :limit.sync="listQuery.pageSize"
       @pagination="getShopProduct"
     />
-    <!--  选择供应商弹窗 -->
+    <!--  选择商弹窗 -->
     <goods-dialog v-if="goodsDialogVisible" ref="shopDialog" @confirm="handleAddShopConfirm" @cancel="handleCancel" />
     <!-- 设置统计状态 -->
     <el-dialog title="设置统计状态" :visible.sync="dialogFormVisible" width="500px">
@@ -232,7 +232,7 @@ export default {
       this.listQuery.pageNum = 1
       this.getShopProduct()
     },
-    // 确认选择供应
+    // 确认选择商
     handleAddShopConfirm(data) {
       console.log('data', data)
       const productIds = []
@@ -241,7 +241,7 @@ export default {
       })
       this.saveShopProduct({ id: this.listQuery.id, productIds: productIds.join(',') })
     },
-    // 取消选择供
+    // 取消选择供商
     handleCancel() {
       this.goodsDialogVisible = false
       this.$refs.shopDialog.visible = false

+ 4 - 4
src/views/user/customer/customer-popup-edit.vue

@@ -32,16 +32,16 @@
       <el-form-item label="引导语1:" prop="guidingOne" :rules="rules.guidingOne">
         <el-input
           v-model="form.guidingOne"
-          placeholder="请输入第一句引导语,不多余15个汉字"
-          maxlength="15"
+          placeholder="请输入第一句引导语,不多余20个汉字"
+          maxlength="20"
           style="width: 350px"
         />
       </el-form-item>
       <el-form-item label="引导语2:" prop="guidingTwo" :rules="rules.guidingTwo">
         <el-input
           v-model="form.guidingTwo"
-          placeholder="请输入第二句引导语,不多余15个汉字"
-          maxlength="15"
+          placeholder="请输入第二句引导语,不多余20个汉字"
+          maxlength="20"
           style="width: 350px"
         />
       </el-form-item>

+ 26 - 6
src/views/user/customer/market-report-list.vue

@@ -77,7 +77,12 @@
 </template>
 
 <script>
-import { getMarketReportList, updateVisible, deleteMarketReport } from '@/api/user/customer/customer'
+import {
+  getMarketReportList,
+  updateVisible,
+  deleteMarketReport,
+  getMarketPreviewCode
+} from '@/api/user/customer/customer'
 import ShareDialog from './components/share-dialog'
 import { downloadWithUrl } from '@/utils'
 export default {
@@ -170,11 +175,26 @@ export default {
     },
     // 跳转预览
     handlePreview(row) {
-      const urls = `${process.env.VUE_APP_CAIMEI_URL}/charts-preview.html?type=1&shopId=${row.shopId}&marketReportId=${row.id}`
-      this.shareCode = 4567
-      this.shareLink = urls
-      this.shareInfo = row
-      this.dialogVisible = true
+      const urls = `${process.env.VUE_APP_CAIMEI_URL}/supplier/charts.html?type=1&shopId=${row.shopId}&marketReportId=${row.id}`
+      window.open(urls, '_blank')
+    },
+    // 跳转预览
+    handlePreview1(row) {
+      this.getMarketPreviewCode(row, { id: row.id })
+    },
+    // 调用生成预览码
+    async getMarketPreviewCode(row, params) {
+      try {
+        const res = await getMarketPreviewCode(params)
+        const data = res.data
+        this.shareCode = data.code
+        this.shareLink = `${process.env.VUE_APP_CAIMEI_URL}/charts-preview.html?type=1&shareType=share&shopId=${row.shopId}&marketReportId=${row.id}`
+        this.shareDirectLink = `${process.env.VUE_APP_CAIMEI_URL}/charts-preview.html?type=3&shopId=${row.shopId}&marketReportId=${row.id}`
+        this.shareInfo = row
+        this.dialogVisible = true
+      } catch (error) {
+        console.log(error)
+      }
     },
     // 取消预览
     handleCancel() {

+ 7 - 7
src/views/user/record/list.vue

@@ -223,7 +223,7 @@
         <el-table-column prop="corporateName" label="公司名称" align="center">
           <template slot-scope="{ row }">
             <template v-if="row.companyType === '2'">
-              <a style="color: #2fa4e7" target="_blank" :href="handleClubHrefLink(row)">
+              <a style="color: #2fa4e7" @click="handleClubHrefLink(row)">
                 {{ row.corporateName ? row.corporateName : "---" }}
               </a>
             </template>
@@ -235,7 +235,7 @@
         <el-table-column prop="contacts" label="联系人" align="center">
           <template slot-scope="{ row }">
             <template v-if="row.companyType === '2'">
-              <a style="color: #2fa4e7" target="_blank" :href="handleClubHrefLink(row)">
+              <a style="color: #2fa4e7" @click="handleClubHrefLink(row)">
                 {{ row.contacts ? row.contacts : "---" }}
               </a>
             </template>
@@ -566,14 +566,14 @@ export default {
     },
     // 机构跳转
     handleClubHrefLink(row) {
-      return (
-        process.env.VUE_APP_ADMIN_URL +
-        `/a/user/jumpLink/toOldAdmin?type=1&clubId=${row.clubId}&clubName=${row.corporateName}`
-      )
+      // window.open(`${process.env.VUE_APP_ADMIN_URL}/a/user/jumpLink/toOldAdmin?type=1&clubId=${row.clubId}&clubName=${row.corporateName}`)
+      this.$router.push({
+        path: '/user/club-portrait',
+        query: { clubId: row.clubId }
+      })
     },
     // 查看详情
     handleRecordDetail(row) {
-      console.log('111111111')
       this.detailQuery = { ip: row.ip, accessDate: row.accessDate, userId: row.userId }
       this.dialogVisible = true
       // this.$router.push({

+ 1 - 1
src/views/wechat/components/menusList.vue

@@ -161,7 +161,7 @@ export default {
       }).then(() => {
         pushWechatMenu(this.listQuery.type).then((response) => {
           this.$message({
-            message: '删除成功',
+            message: '发布成功',
             type: 'success',
             duration: 1000
           })