Browse Source

Merge branch 'developer' of http://git.caimei365.com/caimei365/caimei365-manager-ui into developerC

xiebaomin 1 year ago
parent
commit
755cc7c4a0
29 changed files with 1174 additions and 53 deletions
  1. 1 1
      .env.development
  2. 1 1
      .env.staging
  3. BIN
      public/temp/供应商报表文件上传模板.zip
  4. BIN
      public/temp/供应商报表文件上传模板/SEO汇总图片/seo-图1.jpg
  5. BIN
      public/temp/供应商报表文件上传模板/SEO汇总图片/seo-图2.jpg
  6. BIN
      public/temp/供应商报表文件上传模板/SEO汇总图片/seo-图3.jpg
  7. BIN
      public/temp/供应商报表文件上传模板/SEO汇总图片/seo-图4.jpg
  8. BIN
      public/temp/供应商报表文件上传模板/SEO汇总图片/seo-图5.jpg
  9. BIN
      public/temp/供应商报表文件上传模板/advert广告图片/信息中心-图1.jpg
  10. BIN
      public/temp/供应商报表文件上传模板/advert广告图片/信息中心-图2.jpg
  11. BIN
      public/temp/供应商报表文件上传模板/advert广告图片/首页-图1.jpg
  12. BIN
      public/temp/供应商报表文件上传模板/advert广告图片/首页-图2.jpg
  13. BIN
      public/temp/供应商报表文件上传模板/供应商数据报表模板.xlsx
  14. 135 0
      src/api/user/customer/customer.js
  15. 21 0
      src/router/modules/user.js
  16. 0 8
      src/styles/index.scss
  17. 1 0
      src/views/library/tag/list.vue
  18. 0 3
      src/views/library/tag/tag-form.vue
  19. 6 12
      src/views/serviceSettlement/list/edit.vue
  20. 8 3
      src/views/user/customer/advertis-edit.vue
  21. 150 0
      src/views/user/customer/components/shop-market-dialog.vue
  22. 0 3
      src/views/user/customer/customer-ambition-edit.vue
  23. 0 3
      src/views/user/customer/customer-ambition-sum.vue
  24. 0 3
      src/views/user/customer/customer-popup-edit.vue
  25. 0 3
      src/views/user/customer/customer-remarks-add .vue
  26. 158 13
      src/views/user/customer/list.vue
  27. 212 0
      src/views/user/customer/market-edit.vue
  28. 293 0
      src/views/user/customer/market-list.vue
  29. 188 0
      src/views/user/customer/market-report-list.vue

+ 1 - 1
.env.development

@@ -10,7 +10,7 @@ VUE_APP_BASE_API = 'https://mapi-b.caimei365.com'
 VUE_APP_CORE_API = 'https://core-b.caimei365.com'
 
 # 采美网站url
-VUE_APP_CAIMEI_URL = 'https://zzjtest.gz.aeert.com'
+VUE_APP_CAIMEI_URL = 'http://120.79.25.27:8009'
 
 # 采美旧后台
 VUE_APP_ADMIN_URL = 'https://admin-b.caimei365.com'

+ 1 - 1
.env.staging

@@ -9,7 +9,7 @@ VUE_APP_BASE_API = 'https://mapi-b.caimei365.com'
 VUE_APP_CORE_API = 'https://core-b.caimei365.com'
 
 # 采美网站url
-VUE_APP_CAIMEI_URL = 'https://www.caimei365.com'
+VUE_APP_CAIMEI_URL = 'http://120.79.25.27:8009'
 
 # 采美旧后台
 VUE_APP_ADMIN_URL = 'https://admin-b.caimei365.com'

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


BIN
public/temp/供应商报表文件上传模板/SEO汇总图片/seo-图1.jpg


BIN
public/temp/供应商报表文件上传模板/SEO汇总图片/seo-图2.jpg


BIN
public/temp/供应商报表文件上传模板/SEO汇总图片/seo-图3.jpg


BIN
public/temp/供应商报表文件上传模板/SEO汇总图片/seo-图4.jpg


BIN
public/temp/供应商报表文件上传模板/SEO汇总图片/seo-图5.jpg


BIN
public/temp/供应商报表文件上传模板/advert广告图片/信息中心-图1.jpg


BIN
public/temp/供应商报表文件上传模板/advert广告图片/信息中心-图2.jpg


BIN
public/temp/供应商报表文件上传模板/advert广告图片/首页-图1.jpg


BIN
public/temp/供应商报表文件上传模板/advert广告图片/首页-图2.jpg


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


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

@@ -423,3 +423,138 @@ export function saveInformation(data) {
     data: data
   })
 }
+/**
+ * 选择已上线供应商列表
+ * @param {*} shopName
+ * @param {*} pageNum,
+ * @param {*} pageSize
+ * @returns
+ */
+export function getMarketShopList(params) {
+  return request({
+    url: '/user/market/getShop',
+    method: 'get',
+    params
+  })
+}
+/**
+ * 营销供应商列表
+ * @param {*} shopName
+ * @param {*} pageNum,
+ * @param {*} pageSize
+ * @returns
+ */
+export function getMarkShopList(params) {
+  return request({
+    url: '/user/market/getMarkShopList',
+    method: 'get',
+    params
+  })
+}
+/**
+ * 保存数据报表供应商
+ * @param {*} shopIds
+ * @returns
+ */
+export function saveMarketShop(params) {
+  return request({
+    url: '/user/market/saveMarketShop',
+    method: 'get',
+    params
+  })
+}
+/**
+ * 保存logo
+ * @param {*} id
+ * @param {*} logo
+ * @returns
+ */
+export function uploadShopLogo(params) {
+  return request({
+    url: '/user/market/uploadShopLogo	',
+    method: 'get',
+    params
+  })
+}
+/**
+ * 数据报表列表
+ * @param {*} marketId
+ * @param {*} reportName
+ * @param {*} pageNum,
+ * @param {*} pageSize
+ * @returns
+ */
+export function getMarketReportList(params) {
+  return request({
+    url: '/user/market/getMarketReport',
+    method: 'get',
+    params
+  })
+}
+/**
+ * 数据报表编辑回显
+ * @param {*} id
+ * @returns
+ */
+export function getMarketReportById(params) {
+  return request({
+    url: '/user/market/getMarketReportById',
+    method: 'get',
+    params
+  })
+}
+/**
+ * 生成报表
+ * @param {*} id
+ * @returns
+ */
+export function updateVisible(params) {
+  return request({
+    url: '/user/market/updateVisible',
+    method: 'get',
+    params
+  })
+}
+/**
+ * 删除报表
+ * @param {*} id
+ * @returns
+ */
+export function deleteMarketReport(params) {
+  return request({
+    url: '/user/market/deleteMarketReport',
+    method: 'get',
+    params
+  })
+}
+/**
+ * 上传数据文件
+ * @param {*} reportDate 报表月份
+ * @param {*} reportName 报表名称
+ * @param {*} reportFile 文件
+ * @returns
+ */
+export function saveMarketReport(data) {
+  return request({
+    url: '/user/market/saveMarketReport',
+    method: 'post',
+    data,
+    headers: {
+      'Content-Type': 'multipart/form-data'
+    }
+  })
+}
+/**
+ * 保存报表
+ * @param {*} reportDate 报表月份
+ * @param {*} reportName 报表名称
+ * @param {*} filePath 文件
+ * @returns
+ */
+export function saveReport(params) {
+  return request({
+    url: '/user/market/saveReport',
+    method: 'get',
+    params
+  })
+}

+ 21 - 0
src/router/modules/user.js

@@ -36,6 +36,27 @@ const userRouter = {
           component: () => import('@/views/user/customer/list'),
           meta: { title: '供应商列表' }
         },
+        {
+          path: 'market-list',
+          name: 'MarketList',
+          component: () => import('@/views/user/customer/market-list'),
+          meta: { title: '营销数据报表' },
+          hidden: true
+        },
+        {
+          path: 'market-report-list',
+          name: 'MarketReportList',
+          component: () => import('@/views/user/customer/market-report-list'),
+          meta: { title: '数据报表' },
+          hidden: true
+        },
+        {
+          path: 'market-edit',
+          name: 'MarketEdit',
+          component: () => import('@/views/user/customer/market-edit'),
+          meta: { title: '数据报表上传/编辑' },
+          hidden: true
+        },
         {
           path: 'customer-stat-list',
           name: 'CustomerStatsList',

+ 0 - 8
src/styles/index.scss

@@ -252,11 +252,3 @@ aside {
 .el-submenu [class^='el-icon-'] {
   font-size: 16px;
 }
-.uploader-tips {
-  position: absolute;
-  bottom: 0;
-  left: 160px;
-  line-height: 28px;
-  color: red;
-  margin: 0;
-}

+ 1 - 0
src/views/library/tag/list.vue

@@ -403,6 +403,7 @@ export default {
     handleUploadSuccess(response, file, fileList) {
       this.importForm.fileUrl = response.url
       this.fileList = fileList
+      console.log('fileList', this.fileList)
     },
 
     // 上传文件删除

+ 0 - 3
src/views/library/tag/tag-form.vue

@@ -168,9 +168,6 @@ export default {
   line-height: 20px;
   color: red;
   text-align: left;
-  position: absolute;
-  right: -50%;
-  bottom: 0;
 }
 .span_tip {
   font-size: 12px;

+ 6 - 12
src/views/serviceSettlement/list/edit.vue

@@ -19,8 +19,8 @@
           />
         </el-select>
       </el-form-item>
-      <el-form-item label="服务商地区:" prop="area">
-        <el-cascader
+      <el-form-item label="服务商地区:" prop="address">
+        <!--<el-cascader
           ref="cascader"
           :key="areaKey"
           v-model="formLabelAlign.area"
@@ -30,7 +30,8 @@
           style="width: 100%"
           :placeholder="cascaderPlaceholder"
           @change="handleChange"
-        />
+        />-->
+        <el-input v-model="formLabelAlign.address" placeholder="请服务商地区" />
       </el-form-item>
       <el-form-item label="服务商类型:" prop="serviceCategory">
         <el-select v-model="formLabelAlign.serviceCategory" placeholder="服务商类型">
@@ -164,13 +165,12 @@ export default {
           { required: true, message: '请输入服务商名称', trigger: 'blur' },
           { max: 50, message: '长度最多50个汉字', trigger: 'blur' }
         ],
-        area: [{ required: true, message: '请选择地址', trigger: 'change' }],
+        address: [{ required: true, message: '请输入地址', trigger: 'blur' }],
         serviceLevel: [
           { required: true, message: '请选择服务商级别', trigger: 'change' }
         ],
         mobile: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
         linkMan: [{ required: true, message: '请输入联系人', trigger: 'blur' }],
-        text: [{ required: true, message: '请输入简介', trigger: 'blur' }],
         serviceCategory: [
           { required: true, message: '请选择服务商类型', trigger: 'change' }
         ],
@@ -186,10 +186,7 @@ export default {
           contractRelateds: [
             { required: true, message: '请上传合同文件', trigger: 'change' }
           ]
-        },
-        infoRelateds: [
-          { required: true, message: '请上传资料文件', trigger: 'change' }
-        ]
+        }
       }
     }
   },
@@ -236,9 +233,6 @@ export default {
       this.textRelateds = data.textRelateds.map((e, i) => ({ uid: i, url: e.image }))
       this.formLabelAlign.area = data.address.split('/').map(e => e.trim())
       this.qualificationImage = data.qualificationImage
-      setTimeout(() => {
-        this.areaKey = Math.random() * 1000
-      }, 500)
     },
     // 地区选择
     handleChange($event) {

+ 8 - 3
src/views/user/customer/advertis-edit.vue

@@ -285,9 +285,6 @@ export default {
   line-height: 20px;
   color: red;
   text-align: left;
-  position: absolute;
-  right: -50%;
-  bottom: 0;
 }
 .span_tip {
   font-size: 12px;
@@ -297,4 +294,12 @@ export default {
 .filter-item-temp {
   width: 100px;
 }
+.uploader-tips {
+  position: absolute;
+  bottom: 0;
+  left: 160px;
+  line-height: 28px;
+  color: red;
+  margin: 0;
+}
 </style>

+ 150 - 0
src/views/user/customer/components/shop-market-dialog.vue

@@ -0,0 +1,150 @@
+<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>供应商名称:</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" :selectable="selectable" />
+      <el-table-column label="供应商名称" prop="name" align="center" />
+      <el-table-column label="联系人" prop="linkMan" align="center" />
+      <el-table-column label="手机号" prop="contractMobile" align="center">
+        <template slot-scope="{ row }">
+          {{ row.contractMobile ? row.contractMobile : '---' }}
+        </template>
+      </el-table-column>
+      <el-table-column label="供应商状态" prop="status" align="center">
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.status === 90" type="success" size="small">已上线</el-tag>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 页码 -->
+    <pagination
+      :total="total"
+      :page-sizes="[100, 200]"
+      :page-size="100"
+      :page.sync="listQuery.pageNum"
+      :limit.sync="listQuery.pageSize"
+      @pagination="getShopList"
+    />
+    <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 { getMarketShopList } from '@/api/user/customer/customer'
+
+export default {
+  name: 'ShopDialog',
+  filters: {
+    NumFormat(value) {
+      // 处理金额
+      return Number(value).toFixed(2)
+    }
+  },
+  data() {
+    return {
+      visible: true,
+      listQuery: {
+        pageNum: 1, // 页码
+        pageSize: 100, // 页面数据数
+        shopName: '' // 供应商公司名称
+      },
+      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.getShopList()
+    },
+    // 获取所有供应商列表
+    async getShopList() {
+      try {
+        const res = await getMarketShopList(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>

+ 0 - 3
src/views/user/customer/customer-ambition-edit.vue

@@ -196,9 +196,6 @@ export default {
   line-height: 20px;
   color: red;
   text-align: left;
-  position: absolute;
-  right: -50%;
-  bottom: 0;
 }
 .span_tip {
   font-size: 12px;

+ 0 - 3
src/views/user/customer/customer-ambition-sum.vue

@@ -150,9 +150,6 @@ export default {
   line-height: 20px;
   color: red;
   text-align: left;
-  position: absolute;
-  right: -50%;
-  bottom: 0;
 }
 .span_tip {
   font-size: 12px;

+ 0 - 3
src/views/user/customer/customer-popup-edit.vue

@@ -192,9 +192,6 @@ export default {
   line-height: 20px;
   color: red;
   text-align: left;
-  position: absolute;
-  right: -50%;
-  bottom: 0;
 }
 .span_tip {
   font-size: 12px;

+ 0 - 3
src/views/user/customer/customer-remarks-add .vue

@@ -273,9 +273,6 @@ export default {
   line-height: 20px;
   color: red;
   text-align: left;
-  position: absolute;
-  right: -50%;
-  bottom: 0;
 }
 .span_tip {
   font-size: 12px;

+ 158 - 13
src/views/user/customer/list.vue

@@ -45,16 +45,30 @@
           <el-tag v-if="row.status === 1" type="danger" size="small">暂停统计</el-tag>
         </template>
       </el-table-column>
-      <el-table-column prop="addTime" label="添加时间" align="center">
+      <el-table-column prop="status" label="logo" align="center" width="180">
+        <template slot-scope="{ row }">
+          <el-popover v-if="row.logo" placement="top-start" title="" width="180" trigger="hover">
+            <img :src="row.logo" alt="" style="width: 94px; height: 50px" />
+            <img slot="reference" :src="row.logo" alt="" style="width: 94px; height: 50px" />
+          </el-popover>
+          <span v-else>---</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="recentlyTime" label="最近报表时间" align="center">
+        <template slot-scope="{ row }">
+          {{ row.recentlyTime ? row.recentlyTime : '---' }}
+        </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" width="400">
         <template slot-scope="{ row }">
-          <!-- <el-button type="primary" size="mini" style="margin: 4px" @click="handleRecordDetail(7, row)">
-            意向客户数据
-          </el-button> -->
+          <el-button type="primary" size="mini" style="margin: 4px" @click="handleRecordDetail(7, row)">
+            营销数据报表
+          </el-button>
           <el-button type="primary" size="mini" style="margin: 4px" @click="handleRecordDetail(1, row)">
             潜客统计列表
           </el-button>
@@ -64,6 +78,9 @@
           <el-button type="primary" size="mini" style="margin: 4px" @click="handleRecordDetail(3, row)">
             相关搜索词
           </el-button>
+          <el-button type="success" size="mini" style="margin: 4px" @click="handleRecordDetail(8, row)">
+            上传LOGO
+          </el-button>
           <el-button type="success" size="mini" style="margin: 4px" @click="handleRecordDetail(4, row)">
             页面访问统计
           </el-button>
@@ -79,8 +96,8 @@
     <!-- 页码 -->
     <pagination
       :total="total"
-      :page-sizes="[100]"
-      :page-size="100"
+      :page-sizes="[10, 20, 30, 100]"
+      :page-size="20"
       :page.sync="listQuery.pageNum"
       :limit.sync="listQuery.pageSize"
       @pagination="getCustomerShopList"
@@ -100,11 +117,48 @@
         <el-button type="primary" @click="handleConfirm">确定</el-button>
       </div>
     </el-dialog>
+    <!-- 上传LOGO -->
+    <el-dialog title="上传LOGO" :visible.sync="logoFormVisible" width="500px">
+      <el-form ref="logoForm" :model="logoForm" :rules="rules" label-position="right">
+        <el-form-item prop="logo" label="logo">
+          <div class="form-el-upload" style="width: 126px; height: 126px">
+            <el-upload
+              class="avatar-uploader"
+              :action="actionUrl"
+              :headers="getToken"
+              :show-file-list="false"
+              :on-success="handleSuccess"
+              :before-upload="beforeUpload"
+            >
+              <div v-loading="loadImgLoading" class="avatar" style="width: 126px; height: 126px; display: block">
+                <img
+                  v-if="logoForm.logo"
+                  :src="logoForm.logo"
+                  style="width: 126px; height: 126px; display: block"
+                  @error="reloadImage"
+                  @load="loadSucess"
+                />
+                <i
+                  v-else
+                  class="el-icon-plus avatar-uploader-icon"
+                  style="width: 126px; height: 126px; line-height: 126px"
+                ></i>
+              </div>
+            </el-upload>
+            <p class="uploader-tips">注:请尽量上传126*50(px)尺寸的图片。</p>
+          </div>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="logoFormVisible = false">取消</el-button>
+        <el-button type="primary" @click="handleConfirmLogo">确定</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script>
-import { getCustomerShopList, saveCustomerShop, renewCustomerShop } from '@/api/user/customer/customer'
+import { getCustomerShopList, saveCustomerShop, renewCustomerShop, uploadShopLogo } from '@/api/user/customer/customer'
 import ShopDialog from './components/shop-dialog'
 export default {
   name: 'RecordList',
@@ -123,16 +177,32 @@ export default {
       total: 0,
       shopDialogVisible: false,
       dialogFormVisible: false,
+      logoFormVisible: false,
+      loadImgLoading: false,
       renewCustome: {
         id: '',
         status: ''
       },
+      logoForm: {
+        id: '',
+        logo: ''
+      },
       rules: {
-        status: [{ required: true, message: '请设置统计状态', trigger: 'blur' }]
+        status: [{ required: true, message: '请设置统计状态', trigger: 'blur' }],
+        logo: [{ required: true, message: '请上传弹窗图片', trigger: 'blur' }]
       }
     }
   },
-  computed: {},
+  computed: {
+    getToken() {
+      return {
+        token: this.$store.getters.token
+      }
+    },
+    actionUrl() {
+      return process.env.VUE_APP_BASE_API + '/formData/MultiPictareaddData'
+    }
+  },
   created() {
     this.getList()
   },
@@ -202,6 +272,28 @@ export default {
         console.log(error)
       }
     },
+    // 上传logo
+    handleConfirmLogo() {
+      this.$refs['logoForm'].validate((valid) => {
+        if (valid) {
+          this.uploadShopLogo(this.logoForm)
+        } else {
+          return false
+        }
+      })
+    },
+    // 上传logo
+    async uploadShopLogo(params) {
+      try {
+        await uploadShopLogo(params)
+        this.logoFormVisible = false
+        this.$message.success('操作成功')
+        this.$refs['logoForm'].clearValidate()
+        this.getList()
+      } catch (error) {
+        console.log(error)
+      }
+    },
     // 查看详情
     handleRecordDetail(type, row) {
       switch (type) {
@@ -241,16 +333,69 @@ export default {
           console.log('renewCustome', this.renewCustome)
           this.dialogFormVisible = true
           break
-        case 7: // 意向客户数据
+        case 7: // 跳转数据报表
           this.$router.push({
-            path: '/user/customer/customer-ambition-list',
-            query: { shopId: row.shopId }
+            path: '/user/customer/market-report-list',
+            query: { marketId: row.id, shopName: row.shopName }
           })
           break
+        case 8: // 上传LOGO
+          this.logoForm.id = row.id
+          this.logoFormVisible = true
+          break
+      }
+    },
+    // 上传图标事件
+    handleSuccess(res, file) {
+      this.loadImgLoading = true
+      this.$nextTick(() => {
+        setTimeout(() => {
+          this.logoForm.logo = res.data
+        }, 1000 * 2)
+      })
+    },
+    // 对上传图片的大小、格式进行限制
+    beforeUpload(file) {
+      const isJPG = file.type === 'image/jpeg'
+      const isJPG2 = file.type === 'image/jpg'
+      const isPNG = file.type === 'image/png'
+      const isLt5M = file.size / 1024 / 1024 < 5
+      if (!isJPG && !isJPG2 && !isPNG) {
+        this.$message.error('只支持jpg或png格式图片')
       }
+      if (!isLt5M) {
+        this.$message.error('请上传5MB以内的图片!')
+      }
+      return (isJPG || isJPG2 || isPNG) && isLt5M
+    },
+    reloadImage() {
+      this.loadImgLoading = true
+      setTimeout(() => {
+        this.logoForm.logo = this.logoForm.logo.split('?')[0] + '?r=' + Math.floor(Math.random() * 1000)
+      }, 1000 * 2)
+    },
+    loadSucess() {
+      this.loadImgLoading = false
     }
   }
 }
 </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>

+ 212 - 0
src/views/user/customer/market-edit.vue

@@ -0,0 +1,212 @@
+<template>
+  <div class="app-container" style="width: 800px; margin: 0 auto">
+    <div class="form-tips">
+      <p>文件上传完成,保存后进行预览报表。等数据最终确定了,可重新上传新文件,最后再生成报表。</p>
+    </div>
+    <el-form ref="importForm" :model="form" label-width="100px">
+      <el-form-item label="报表月份:" prop="reportDate" :rules="rules.reportDate">
+        <el-date-picker
+          v-model="form.reportDate"
+          type="month"
+          format="yyyy-MM"
+          value-format="yyyy-MM"
+          placeholder="选择月份"
+          style="width: 280px"
+        />
+      </el-form-item>
+      <el-form-item label="报表名称:" prop="reportName" :rules="rules.reportName">
+        <el-input v-model="form.reportName" placeholder="请输入报表名称" maxlength="30" style="width: 280px" />
+      </el-form-item>
+      <el-form-item label="报表文件" prop="filePath" :rules="rules.filePath">
+        <el-upload
+          ref="upload"
+          accept=".zip, .rar"
+          action="https://jsonplaceholder.typicode.com/posts/"
+          :limit="1"
+          :file-list="fileList"
+          :on-success="handleUploadSuccess"
+          :on-remove="handleUploadRemove"
+          :on-change="handleUploadChange"
+          :auto-upload="false"
+        >
+          <el-button slot="trigger" size="small" type="primary"> 选取文件 </el-button>
+          <div slot="tip" class="el-upload__tip">只支持.zip 和 .rar 格式的压缩包文件</div>
+        </el-upload>
+        <input v-show="false" v-model="form.filePath" type="text" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="handleImportConfirm"> 保存 </el-button>
+        <el-button plain @click="backToList"> 返回 </el-button>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import { saveMarketReport, saveReport, getMarketReportById } from '@/api/user/customer/customer'
+
+export default {
+  name: 'MarketEdit',
+  data() {
+    return {
+      form: {
+        marketId: this.$route.query.marketId,
+        id: '',
+        filePath: '', // 数据文件
+        reportDate: '', // 报表月份
+        reportName: '' // 报表月份
+      },
+      loadImgLoading: false,
+      fileList: [],
+      rules: {
+        filePath: [{ required: true, message: '请选择压缩包文件', trigger: ['change'] }],
+        reportDate: [{ required: true, message: '请选择报表数据月份', trigger: 'blur' }],
+        reportName: [{ required: true, message: '请输入报表名称', trigger: 'blur' }]
+      }
+    }
+  },
+  computed: {
+    getToken() {
+      return {
+        token: this.$store.getters.token
+      }
+    },
+    actionUrl() {
+      return process.env.VUE_APP_BASE_API + '/formData/MultiPictareaddData'
+    }
+  },
+  created() {
+    if (this.$route.query.type === 'edit') {
+      this.getMarketReportById({ id: this.$route.query.id })
+    }
+  },
+  methods: {
+    // 获取供应商弹窗详情
+    async getMarketReportById(params) {
+      try {
+        const res = await getMarketReportById(params)
+        this.form = { ...this.form, ...res.data }
+        const file = {
+          name: res.data.fileName,
+          url: ''
+        }
+        this.fileList.push(file)
+      } catch (error) {
+        console.log('error', error)
+      }
+    },
+    // 确定保存
+    async handleImportConfirm() {
+      try {
+        await this.$refs.importForm.validate()
+        this.saveReport()
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 保存数据报表
+    async saveReport() {
+      try {
+        await saveReport(this.form)
+        this.fileList = []
+        this.$message.success('数据报表保存成功')
+        this.backToList()
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 文件上传成功
+    handleUploadSuccess(response, file, fileList) {
+      this.form.filePath = response.url
+      this.fileList = fileList
+    },
+    // 上传文件删除
+    handleUploadRemove(file, fileList) {
+      this.fileList = fileList
+    },
+    handleUploadChange(file, fileList) {
+      this.fileList = fileList
+      this.form.filePath = file.name
+      console.log('222222222222', this.fileList)
+      this.saveMarketReport()
+    },
+    // 上传文件
+    async saveMarketReport() {
+      const file = this.fileList.length > 0 && this.fileList[0]
+      if (!file) return
+      try {
+        const formData = new FormData()
+        formData.append('reportFile', file.raw)
+        const res = await saveMarketReport(formData)
+        this.form.filePath = res.data
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    backToList() {
+      this.$store.dispatch('tagsView/delView', this.$route).then(() => {
+        this.$nextTick(() => {
+          this.$router.replace({
+            path: '/user/customer/market-report-list',
+            query: { marketId: this.$route.query.marketId, shopName: this.$route.query.shopName }
+          })
+        })
+      })
+    }
+  }
+}
+</script>
+
+<style>
+.form-tips {
+  width: 100%;
+  height: 48px;
+  line-height: 48px;
+  background: #f7f7f7;
+  font-size: 12px;
+  color: #333333;
+  border-radius: 8px;
+  box-sizing: border-box;
+  padding: 0 10px;
+  margin-bottom: 40px;
+}
+.avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+  float: left;
+}
+.avatar-uploader .el-upload:hover {
+  border-color: #409eff;
+}
+.avatar-uploader-icon {
+  font-size: 30px;
+  color: #999999;
+}
+.el-form-item__label {
+  text-align: right !important;
+}
+.el-upload__tip {
+  line-height: 20px;
+  color: red;
+  text-align: left;
+}
+.span_tip {
+  font-size: 12px;
+  color: red;
+  margin-left: 5px;
+}
+.filter-item-temp {
+  width: 100px;
+}
+.uploader-tips {
+  position: absolute;
+  bottom: 0;
+  left: 160px;
+  line-height: 28px;
+  color: red;
+  margin: 0;
+}
+</style>

+ 293 - 0
src/views/user/customer/market-list.vue

@@ -0,0 +1,293 @@
+<template>
+  <div class="app-container">
+    <!-- 顶部操作区域 -->
+    <div class="filter-container">
+      <div class="filter-control">
+        <span>供应商名称:</span>
+        <el-input
+          v-model="listQuery.shopName"
+          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="shopDialogVisible = true"> 添加供应商 </el-button>
+      </div>
+    </div>
+    <!-- 列表 -->
+    <el-table v-loading="isLoading" :data="list" border style="width: 100%" height="660">
+      <el-table-column prop="shopName" fixed label="供应商名称" align="center" />
+      <el-table-column prop="linkMan" label="联系人" align="center" />
+      <el-table-column prop="contractMobile" label="手机号" align="center">
+        <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 === 90" type="success" size="small">已上线</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column prop="status" label="logo" align="center" width="180">
+        <template slot-scope="{ row }">
+          <el-popover v-if="row.logo" placement="top-start" title="" width="180" trigger="hover">
+            <img :src="row.logo" alt="" style="width: 94px; height: 50px" />
+            <img slot="reference" :src="row.logo" alt="" style="width: 94px; height: 50px" />
+          </el-popover>
+          <span v-else>---</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="recentlyTime" label="最近报表时间" align="center">
+        <template slot-scope="{ row }">
+          {{ row.recentlyTime ? row.recentlyTime : '---' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="addTime" label="添加时间" align="center">
+        <template slot-scope="{ row }">
+          {{ row.addTime ? row.addTime : '---' }}
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" width="400">
+        <template slot-scope="{ row }">
+          <el-button type="success" size="mini" style="margin: 4px" @click="handleRecordDetail(1, row)">
+            上传LOGO
+          </el-button>
+          <el-button type="primary" size="mini" style="margin: 4px" @click="handleRecordDetail(2, row)">
+            数据报表
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 页码 -->
+    <pagination
+      :total="total"
+      :page-sizes="[100]"
+      :page-size="100"
+      :page.sync="listQuery.pageNum"
+      :limit.sync="listQuery.pageSize"
+      @pagination="getMarkShopList"
+    />
+    <!--  选择供应商弹窗 -->
+    <shop-dialog v-if="shopDialogVisible" ref="shopDialog" @confirm="handleAddShopConfirm" @cancel="handleCancel" />
+    <!-- 上传LOGO -->
+    <el-dialog title="上传LOGO" :visible.sync="dialogFormVisible" width="500px">
+      <el-form ref="dataForm" :model="renewCustome" :rules="rules" label-position="right">
+        <el-form-item prop="logo" label="logo">
+          <div class="form-el-upload" style="width: 148px; height: 148px">
+            <el-upload
+              class="avatar-uploader"
+              :action="actionUrl"
+              :headers="getToken"
+              :show-file-list="false"
+              :on-success="handleSuccess"
+              :before-upload="beforeUpload"
+            >
+              <div v-loading="loadImgLoading" class="avatar" style="width: 148px; height: 148px; display: block">
+                <img
+                  v-if="renewCustome.logo"
+                  :src="renewCustome.logo"
+                  style="width: 148px; height: 148px; display: block"
+                  @error="reloadImage"
+                  @load="loadSucess"
+                />
+                <i
+                  v-else
+                  class="el-icon-plus avatar-uploader-icon"
+                  style="width: 148px; height: 148px; line-height: 148px"
+                ></i>
+              </div>
+            </el-upload>
+            <p class="uploader-tips">注:请尽量上传126*50(px)尺寸的图片。</p>
+          </div>
+        </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 { getMarkShopList, saveMarketShop, uploadShopLogo } from '@/api/user/customer/customer'
+import ShopDialog from './components/shop-market-dialog'
+export default {
+  name: 'RecordList',
+  components: { ShopDialog },
+  filters: {},
+  data() {
+    return {
+      isLoading: true,
+      listQuery: {
+        shopName: '',
+        status: '',
+        pageNum: 1,
+        pageSize: 20
+      },
+      list: [],
+      total: 0,
+      shopDialogVisible: false,
+      dialogFormVisible: false,
+      loadImgLoading: false,
+      renewCustome: {
+        id: '',
+        logo: ''
+      },
+      rules: {
+        logo: [{ required: true, message: '请上传弹窗图片', trigger: 'blur' }]
+      }
+    }
+  },
+  computed: {
+    getToken() {
+      return {
+        token: this.$store.getters.token
+      }
+    },
+    actionUrl() {
+      return process.env.VUE_APP_BASE_API + '/formData/MultiPictareaddData'
+    }
+  },
+  created() {
+    this.getList()
+  },
+  mounted() {},
+  methods: {
+    // 获取行为记录列表
+    getList() {
+      this.list = []
+      this.listQuery.pageNum = 1
+      this.getMarkShopList()
+    },
+    // 确认选择供应商
+    handleAddShopConfirm(data) {
+      console.log('data', data)
+      const shopIds = []
+      data.forEach((ele) => {
+        shopIds.push(ele.shopId)
+      })
+      this.saveMarketShop({ shopIds: shopIds.join(',') })
+    },
+    // 取消选择供应商
+    handleCancel() {
+      this.shopDialogVisible = false
+      this.$refs.shopDialog.visible = false
+    },
+    // 上传logo
+    handleConfirm() {
+      this.$refs['dataForm'].validate((valid) => {
+        if (valid) {
+          this.uploadShopLogo(this.renewCustome)
+        } else {
+          return false
+        }
+      })
+    },
+    // 获取潜客搜集供应商列表
+    async getMarkShopList() {
+      try {
+        this.isLoading = true
+        const res = await getMarkShopList(this.listQuery)
+        this.list = res.data.results
+        this.total = res.data.totalRecord
+        this.isLoading = false
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 保存添加统计供应商
+    async saveMarketShop(params) {
+      try {
+        await saveMarketShop(params)
+        this.shopDialogVisible = false
+        this.$message.success('操作成功')
+        this.getList()
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 上传logo
+    async uploadShopLogo(params) {
+      try {
+        await uploadShopLogo(params)
+        this.dialogFormVisible = false
+        this.$message.success('操作成功')
+        this.getList()
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 操作
+    handleRecordDetail(type, row) {
+      switch (type) {
+        case 1: // 上传logo
+          this.renewCustome.id = row.id
+          console.log('renewCustome', this.renewCustome)
+          this.dialogFormVisible = true
+          break
+        case 2: // 跳转数据报表
+          this.$router.push({
+            path: '/user/customer/market-report-list',
+            query: { marketId: row.id, shopName: row.shopName }
+          })
+          break
+      }
+    },
+    // 上传图标事件
+    handleSuccess(res, file) {
+      this.loadImgLoading = true
+      this.$nextTick(() => {
+        setTimeout(() => {
+          this.renewCustome.logo = res.data
+        }, 1000 * 2)
+      })
+    },
+    // 对上传图片的大小、格式进行限制
+    beforeUpload(file) {
+      const isJPG = file.type === 'image/jpeg'
+      const isJPG2 = file.type === 'image/jpg'
+      const isPNG = file.type === 'image/png'
+      const isLt5M = file.size / 1024 / 1024 < 5
+      if (!isJPG && !isJPG2 && !isPNG) {
+        this.$message.error('只支持jpg或png格式图片')
+      }
+      if (!isLt5M) {
+        this.$message.error('请上传5MB以内的图片!')
+      }
+      return (isJPG || isJPG2 || isPNG) && isLt5M
+    },
+    reloadImage() {
+      this.loadImgLoading = true
+      setTimeout(() => {
+        this.renewCustome.logo = this.renewCustome.logo.split('?')[0] + '?r=' + Math.floor(Math.random() * 1000)
+      }, 1000 * 2)
+    },
+    loadSucess() {
+      this.loadImgLoading = false
+    }
+  }
+}
+</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>

+ 188 - 0
src/views/user/customer/market-report-list.vue

@@ -0,0 +1,188 @@
+<template>
+  <div class="app-container">
+    <!-- 顶部操作区域 -->
+    <div class="filter-container">
+      <div class="filter-control">
+        <span>报表名称:</span>
+        <el-input
+          v-model="listQuery.reportName"
+          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="handleUpdate('add')"> 上传报表 </el-button>
+        <el-button type="primary" @click="handleDownloadTemp"> 下载模板 </el-button>
+      </div>
+    </div>
+    <div class="tags-sms">
+      <span class="tags-sms-span">供应商:{{ shopName }}</span>
+    </div>
+    <!-- 列表 -->
+    <el-table v-loading="isLoading" :data="list" border style="width: 100%" height="600">
+      <el-table-column label="序号" align="center" width="60">
+        <template slot-scope="scope">{{ scope.$index + 1 }}</template>
+      </el-table-column>
+      <el-table-column prop="reportDate" label="报表数据日期" align="center" width="200" />
+      <el-table-column prop="reportName" label="报表名称" align="center" />
+      <el-table-column prop="visible" label="报表生成状态" align="center">
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.visible === 1" type="success" size="small">已生成</el-tag>
+          <el-tag v-if="row.visible === 2" type="danger" size="small">未生成</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column prop="reportTime" label="最近生成时间" align="center">
+        <template slot-scope="{ row }">
+          {{ row.reportTime ? row.reportTime : '---' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="addTime" label="添加时间" align="center">
+        <template slot-scope="{ row }">
+          {{ row.addTime ? row.addTime : '---' }}
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center">
+        <template slot-scope="{ row }">
+          <el-button type="primary" size="mini" style="margin: 2px" @click="handleSitting(row)">生成报表</el-button>
+          <el-button type="primary" size="mini" style="margin: 2px" @click="handleUpdate('edit', row)"> 编辑</el-button>
+          <el-button type="success" size="mini" style="margin: 2px" @click="handlePreview(row)">预览</el-button>
+          <el-button type="danger" size="mini" style="margin: 2px" @click="handleDeleteTag(row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 页码 -->
+    <pagination
+      :total="total"
+      :page-sizes="[100]"
+      :page-size="100"
+      :page.sync="listQuery.pageNum"
+      :limit.sync="listQuery.pageSize"
+      @pagination="getMarketReportList"
+    />
+  </div>
+</template>
+
+<script>
+import { getMarketReportList, updateVisible, deleteMarketReport } from '@/api/user/customer/customer'
+import { downloadWithUrl } from '@/utils'
+export default {
+  name: 'CustomerStatList',
+  filters: {},
+  data() {
+    return {
+      shopName: this.$route.query.shopName,
+      isLoading: true,
+      time: '',
+      listQuery: {
+        marketId: this.$route.query.marketId,
+        reportName: '',
+        pageNum: 1,
+        pageSize: 100
+      },
+      list: [],
+      total: 0
+    }
+  },
+  computed: {},
+  created() {
+    this.getList()
+  },
+  mounted() {},
+  methods: {
+    // 获取列表
+    async getList() {
+      // this.list = []
+      this.listQuery.pageNum = 1
+      this.getMarketReportList()
+    },
+    // 获取列表
+    async getMarketReportList() {
+      try {
+        this.isLoading = true
+        const res = await getMarketReportList(this.listQuery)
+        this.list = res.data.results
+        this.total = res.data.totalRecord
+        this.isLoading = false
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 生成报表
+    handleSitting(row) {
+      this.updateVisible({ id: row.id })
+    },
+    // 调用生成报表API
+    async updateVisible(params) {
+      try {
+        await updateVisible(params)
+        this.$message.success('报表生成成功')
+        this.getList()
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 删除报表
+    async handleDeleteTag(row) {
+      try {
+        await this.$confirm('确定删除该报表数据吗?', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        })
+        this.deleteMarketReport({ id: row.id })
+      } catch (error) {
+        this.$message.info('已取消删除操作')
+      }
+    },
+    // 调用删除报备
+    async deleteMarketReport(params) {
+      try {
+        await deleteMarketReport(params)
+        this.$message.success('报表删除成功')
+        this.getList()
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 下载数据报表模板
+    handleDownloadTemp() {
+      downloadWithUrl('/temp/供应商报表文件上传模板.zip', '供应商报表文件上传模板.zip')
+    },
+    // 跳转预览
+    handlePreview(row) {
+      const urls = `${process.env.VUE_APP_CAIMEI_URL}/supplier/charts.html?type=1&shopId=${row.shopId}&marketReportId=${row.id}`
+      window.open(urls, '_blank')
+    },
+    // 添加/编辑
+    handleUpdate(type, row) {
+      if (type === 'add') {
+        this.$router.push({
+          path: '/user/customer/market-edit',
+          query: { marketId: this.listQuery.marketId, type: type, shopName: this.$route.query.shopName }
+        })
+      } else {
+        this.$router.push({
+          path: '/user/customer/market-edit',
+          query: { marketId: this.listQuery.marketId, type: type, id: row.id, shopName: this.$route.query.shopName }
+        })
+      }
+    }
+  }
+}
+</script>
+
+<style>
+.tags-sms {
+  width: 100%;
+  height: auto;
+  font-size: 16px;
+  color: #333333;
+  line-height: 28px;
+  box-sizing: border-box;
+  padding: 5px;
+}
+</style>