瀏覽代碼

Merge branch 'master' of http://1.14.104.71:10880/root/ylrz_his_scrm_adminUI

caoliqin 3 天之前
父節點
當前提交
b699b85b1b
共有 36 個文件被更改,包括 6002 次插入49 次删除
  1. 37 0
      .env.prod-bly
  2. 2 2
      .env.prod-nmgyt
  3. 1 0
      package.json
  4. 14 0
      src/api/company/statistics.js
  5. 53 0
      src/api/his/articleViews.js
  6. 53 0
      src/api/his/homeArticle.js
  7. 62 0
      src/api/his/homeCategory.js
  8. 53 0
      src/api/his/homeView.js
  9. 7 7
      src/api/hisStore/integralGoods.js
  10. 6 6
      src/api/hisStore/menu.js
  11. 32 0
      src/api/hisStore/statistics.js
  12. 6 6
      src/api/hisStore/storeActivity.js
  13. 8 8
      src/api/hisStore/storeCoupon.js
  14. 6 6
      src/api/hisStore/storeCouponIssue.js
  15. 6 6
      src/api/hisStore/storeCouponIssueUser.js
  16. 6 6
      src/api/hisStore/storeCouponUser.js
  17. 62 0
      src/api/hisStore/userExtract.js
  18. 53 0
      src/api/hisStore/userPromoterApply.js
  19. 18 0
      src/api/statistics/report.js
  20. 二進制
      src/assets/logo/bly_logo.png
  21. 365 0
      src/views/company/statistics/tuiMoney.vue
  22. 200 0
      src/views/his/articleViews/index.vue
  23. 490 0
      src/views/his/homeArticle/index.vue
  24. 365 0
      src/views/his/homeCategory/index.vue
  25. 289 0
      src/views/his/homeView/index.vue
  26. 498 0
      src/views/hisStore/statistics/orderstatatic.vue
  27. 537 0
      src/views/hisStore/statistics/storeOrder.vue
  28. 467 0
      src/views/hisStore/statistics/storeOrderData.vue
  29. 320 0
      src/views/hisStore/statistics/storePayment.vue
  30. 512 0
      src/views/hisStore/statistics/storeProduct.vue
  31. 2 2
      src/views/hisStore/storeProduct/index.vue
  32. 316 0
      src/views/hisStore/userExtract/index.vue
  33. 227 0
      src/views/hisStore/userPromoterApply/index.vue
  34. 660 0
      src/views/statistics/member/index.vue
  35. 261 0
      src/views/statistics/report/index.vue
  36. 8 0
      src/views/system/config/config.vue

+ 37 - 0
.env.prod-bly

@@ -0,0 +1,37 @@
+# 页面标题
+VUE_APP_TITLE = 倍力优会员商城私域平台
+# 公司名称
+VUE_APP_COMPANY_NAME = 倍力优(北京)健康产业科技有限公司
+# ICP备案号
+VUE_APP_ICP_RECORD = 京ICP备18042618号-2
+# ICP网站访问地址
+VUE_APP_ICP_URL =https://beian.miit.gov.cn
+# 网站LOG
+VUE_APP_LOG_URL =@/assets/logo/bly_logo.png
+# 存储桶配置
+VUE_APP_OBS_ACCESS_KEY_ID = K2UTJGIN7UTZJR2XMXYG
+# 存储桶配置
+VUE_APP_OBS_SECRET_ACCESS_KEY = sbyeNJLbcYmH6copxeFP9pAoksM4NIT9Zw4x0SRX
+# 存储桶配置
+VUE_APP_OBS_SERVER = https://obs.cn-north-4.myhuaweicloud.com
+# 存储桶配置
+VUE_APP_OBS_BUCKET = bly-obs2025
+# 存储桶配置
+VUE_APP_COS_BUCKET = beliyo-1323137866
+# 存储桶配置
+VUE_APP_COS_REGION = ap-chongqing
+# 线路一地址
+VUE_APP_VIDEO_LINE_1 = https://blytcpv.ylrzcloud.com
+# 线路二地址
+VUE_APP_VIDEO_LINE_2 = https://blyobs.ylrztop.com
+# 生产环境配置
+ENV = 'production'
+
+#FS管理系统/生产环境
+VUE_APP_BASE_API = '/prod-api'
+
+#默认 1、会员 2、企微
+VUE_APP_COURSE_DEFAULT = 2
+
+# 路由懒加载
+VUE_CLI_BABEL_TRANSPILE_MODULES = true

+ 2 - 2
.env.prod-nmgyt

@@ -1,7 +1,7 @@
 # 页面标题
-VUE_APP_TITLE =内蒙古一医药
+VUE_APP_TITLE =内蒙古一医药
 # 首页菜单标题
-VUE_APP_TITLE_INDEX =内蒙古一医药
+VUE_APP_TITLE_INDEX =内蒙古一医药
 # 公司名称
 VUE_APP_COMPANY_NAME =内蒙古好药师蒙一堂大药房有限公司
 # ICP备案号

+ 1 - 0
package.json

@@ -14,6 +14,7 @@
     "build:prod-hcl": "vue-cli-service build --mode prod-hcl",
     "build:prod-myhk": "vue-cli-service build --mode prod-myhk",
     "build:prod-nmgyt": "vue-cli-service build --mode prod-nmgyt",
+    "build:prod-bly": "vue-cli-service build --mode prod-bly",
     "build:prod-sxjz": "vue-cli-service build --mode prod-sxjz",
     "build:prod-xfk": "vue-cli-service build --mode prod-xfk",
     "build:prod-jnmy": "vue-cli-service build --mode prod-jnmy",

+ 14 - 0
src/api/company/statistics.js

@@ -141,3 +141,17 @@ export function exportTokenStaticByTime(dateTime) {
   })
 }
 
+export function tuiMoney(query) {
+  return request({
+    url: '/company/statistics/tuiMoney',
+    method: 'get',
+    params: query
+  })
+}
+export function exportTuiMoney(query) {
+  return request({
+    url: '/company/statistics/exportTuiMoney',
+    method: 'get',
+    params: query
+  })
+}

+ 53 - 0
src/api/his/articleViews.js

@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询文章阅读列表
+export function listArticleViews(query) {
+  return request({
+    url: '/his/articleViews/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询文章阅读详细
+export function getArticleViews(viewId) {
+  return request({
+    url: '/his/articleViews/' + viewId,
+    method: 'get'
+  })
+}
+
+// 新增文章阅读
+export function addArticleViews(data) {
+  return request({
+    url: '/his/articleViews',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改文章阅读
+export function updateArticleViews(data) {
+  return request({
+    url: '/his/articleViews',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除文章阅读
+export function delArticleViews(viewId) {
+  return request({
+    url: '/his/articleViews/' + viewId,
+    method: 'delete'
+  })
+}
+
+// 导出文章阅读
+export function exportArticleViews(query) {
+  return request({
+    url: '/his/articleViews/export',
+    method: 'get',
+    params: query
+  })
+}

+ 53 - 0
src/api/his/homeArticle.js

@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询期刊列表
+export function listHomeArticle(query) {
+  return request({
+    url: '/his/homeArticle/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询期刊详细
+export function getHomeArticle(articleId) {
+  return request({
+    url: '/his/homeArticle/' + articleId,
+    method: 'get'
+  })
+}
+
+// 新增期刊
+export function addHomeArticle(data) {
+  return request({
+    url: '/his/homeArticle',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改期刊
+export function updateHomeArticle(data) {
+  return request({
+    url: '/his/homeArticle',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除期刊
+export function delHomeArticle(articleId) {
+  return request({
+    url: '/his/homeArticle/' + articleId,
+    method: 'delete'
+  })
+}
+
+// 导出期刊
+export function exportHomeArticle(query) {
+  return request({
+    url: '/his/homeArticle/export',
+    method: 'get',
+    params: query
+  })
+}

+ 62 - 0
src/api/his/homeCategory.js

@@ -0,0 +1,62 @@
+import request from '@/utils/request'
+
+// 查询期刊分类列表
+export function listHomeCategory(query) {
+  return request({
+    url: '/his/homeCategory/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询期刊分类详细
+export function getHomeCategory(categoryId) {
+  return request({
+    url: '/his/homeCategory/' + categoryId,
+    method: 'get'
+  })
+}
+
+// 新增期刊分类
+export function addHomeCategory(data) {
+  return request({
+    url: '/his/homeCategory',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改期刊分类
+export function updateHomeCategory(data) {
+  return request({
+    url: '/his/homeCategory',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除期刊分类
+export function delHomeCategory(categoryId) {
+  return request({
+    url: '/his/homeCategory/' + categoryId,
+    method: 'delete'
+  })
+}
+
+// 导出期刊分类
+export function exportHomeCategory(query) {
+  return request({
+    url: '/his/homeCategory/export',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询期刊分类列表(所有)
+export function allListHomeCategory(query) {
+  return request({
+    url: '/his/homeCategory/allList',
+    method: 'get',
+    params: query
+  })
+}

+ 53 - 0
src/api/his/homeView.js

@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询期刊阅读列表
+export function listHomeView(query) {
+  return request({
+    url: '/his/homeView/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询期刊阅读详细
+export function getHomeView(viewId) {
+  return request({
+    url: '/his/homeView/' + viewId,
+    method: 'get'
+  })
+}
+
+// 新增期刊阅读
+export function addHomeView(data) {
+  return request({
+    url: '/his/homeView',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改期刊阅读
+export function updateHomeView(data) {
+  return request({
+    url: '/his/homeView',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除期刊阅读
+export function delHomeView(viewId) {
+  return request({
+    url: '/his/homeView/' + viewId,
+    method: 'delete'
+  })
+}
+
+// 导出期刊阅读
+export function exportHomeView(query) {
+  return request({
+    url: '/his/homeView/export',
+    method: 'get',
+    params: query
+  })
+}

+ 7 - 7
src/api/hisStore/integralGoods.js

@@ -3,7 +3,7 @@ import request from '@/utils/request'
 // 查询积分商品列表
 export function listIntegralGoods(query) {
   return request({
-    url: '/store/his/integralGoods/list',
+    url: '/his/integralGoods/list',
     method: 'get',
     params: query
   })
@@ -12,20 +12,20 @@ export function listIntegralGoods(query) {
 // 查询积分商品详细
 export function getIntegralGoods(goodsId) {
   return request({
-    url: '/store/his/integralGoods/' + goodsId,
+    url: '/his/integralGoods/' + goodsId,
     method: 'get'
   })
 }
 export function importTemplate() {
   return request({
-    url: '/store/his/integralGoods/importTemplate',
+    url: '/his/integralGoods/importTemplate',
     method: 'get'
   })
 }
 // 新增积分商品
 export function addIntegralGoods(data) {
   return request({
-    url: '/store/his/integralGoods',
+    url: '/his/integralGoods',
     method: 'post',
     data: data
   })
@@ -34,7 +34,7 @@ export function addIntegralGoods(data) {
 // 修改积分商品
 export function updateIntegralGoods(data) {
   return request({
-    url: '/store/his/integralGoods',
+    url: '/his/integralGoods',
     method: 'put',
     data: data
   })
@@ -43,7 +43,7 @@ export function updateIntegralGoods(data) {
 // 删除积分商品
 export function delIntegralGoods(goodsId) {
   return request({
-    url: '/store/his/integralGoods/' + goodsId,
+    url: '/his/integralGoods/' + goodsId,
     method: 'delete'
   })
 }
@@ -51,7 +51,7 @@ export function delIntegralGoods(goodsId) {
 // 导出积分商品
 export function exportIntegralGoods(query) {
   return request({
-    url: '/store/his/integralGoods/export',
+    url: '/his/integralGoods/export',
     method: 'get',
     params: query
   })

+ 6 - 6
src/api/hisStore/menu.js

@@ -3,7 +3,7 @@ import request from '@/utils/request'
 // 查询用户端菜单管理列表
 export function listMenu(query) {
   return request({
-    url: '/store/store/store/menu/list',
+    url: '/store/store/menu/list',
     method: 'get',
     params: query
   })
@@ -12,7 +12,7 @@ export function listMenu(query) {
 // 查询用户端菜单管理详细
 export function getMenu(menuId) {
   return request({
-    url: '/store/store/store/menu/' + menuId,
+    url: '/store/store/menu/' + menuId,
     method: 'get'
   })
 }
@@ -20,7 +20,7 @@ export function getMenu(menuId) {
 // 新增用户端菜单管理
 export function addMenu(data) {
   return request({
-    url: '/store/store/store/menu',
+    url: '/store/store/menu',
     method: 'post',
     data: data
   })
@@ -29,7 +29,7 @@ export function addMenu(data) {
 // 修改用户端菜单管理
 export function updateMenu(data) {
   return request({
-    url: '/store/store/store/menu',
+    url: '/store/store/menu',
     method: 'put',
     data: data
   })
@@ -38,7 +38,7 @@ export function updateMenu(data) {
 // 删除用户端菜单管理
 export function delMenu(menuId) {
   return request({
-    url: '/store/store/store/menu/' + menuId,
+    url: '/store/store/menu/' + menuId,
     method: 'delete'
   })
 }
@@ -46,7 +46,7 @@ export function delMenu(menuId) {
 // 导出用户端菜单管理
 export function exportMenu(query) {
   return request({
-    url: '/store/store/store/menu/export',
+    url: '/store/store/menu/export',
     method: 'get',
     params: query
   })

+ 32 - 0
src/api/hisStore/statistics.js

@@ -0,0 +1,32 @@
+import request from '@/utils/request'
+
+
+export function storeOrder(query) {
+  return request({
+    url: '/store/store/statistics/storeOrder',
+    method: 'get',
+    params: query
+  })
+}
+export function storeProduct(query) {
+  return request({
+    url: '/store/store/statistics/storeProduct',
+    method: 'get',
+    params: query
+  })
+}
+export function storePayment(query) {
+  return request({
+    url: '/store/store/statistics/storePayment',
+    method: 'get',
+    params: query
+  })
+}
+
+ export function getOrderStatistics(params) {
+  return request({
+    url: '/store/store/storeOrder/statistics/getStoreOrderStatistics',
+    method: 'get',
+    params
+  });
+}

+ 6 - 6
src/api/hisStore/storeActivity.js

@@ -3,7 +3,7 @@ import request from '@/utils/request'
 // 查询活动列表
 export function listStoreActivity(query) {
   return request({
-    url: '/store/store/storeActivity/list',
+    url: '/store/storeActivity/list',
     method: 'get',
     params: query
   })
@@ -12,7 +12,7 @@ export function listStoreActivity(query) {
 // 查询活动详细
 export function getStoreActivity(activityId) {
   return request({
-    url: '/store/store/storeActivity/' + activityId,
+    url: '/store/storeActivity/' + activityId,
     method: 'get'
   })
 }
@@ -20,7 +20,7 @@ export function getStoreActivity(activityId) {
 // 新增活动
 export function addStoreActivity(data) {
   return request({
-    url: '/store/store/storeActivity',
+    url: '/store/storeActivity',
     method: 'post',
     data: data
   })
@@ -29,7 +29,7 @@ export function addStoreActivity(data) {
 // 修改活动
 export function updateStoreActivity(data) {
   return request({
-    url: '/store/store/storeActivity',
+    url: '/store/storeActivity',
     method: 'put',
     data: data
   })
@@ -38,7 +38,7 @@ export function updateStoreActivity(data) {
 // 删除活动
 export function delStoreActivity(activityId) {
   return request({
-    url: '/store/store/storeActivity/' + activityId,
+    url: '/store/storeActivity/' + activityId,
     method: 'delete'
   })
 }
@@ -46,7 +46,7 @@ export function delStoreActivity(activityId) {
 // 导出活动
 export function exportStoreActivity(query) {
   return request({
-    url: '/store/store/storeActivity/export',
+    url: '/store/storeActivity/export',
     method: 'get',
     params: query
   })

+ 8 - 8
src/api/hisStore/storeCoupon.js

@@ -3,7 +3,7 @@ import request from '@/utils/request'
 // 查询优惠券列表
 export function listStoreCoupon(query) {
   return request({
-    url: '/store/store/storeCoupon/list',
+    url: '/store/storeCoupon/list',
     method: 'get',
     params: query
   })
@@ -12,7 +12,7 @@ export function listStoreCoupon(query) {
 // 查询优惠券详细
 export function getStoreCoupon(couponId) {
   return request({
-    url: '/store/store/storeCoupon/' + couponId,
+    url: '/store/storeCoupon/' + couponId,
     method: 'get'
   })
 }
@@ -20,14 +20,14 @@ export function getStoreCoupon(couponId) {
 // 新增优惠券
 export function addStoreCoupon(data) {
   return request({
-    url: '/store/store/storeCoupon',
+    url: '/store/storeCoupon',
     method: 'post',
     data: data
   })
 }
 export function publishCoupon(data) {
   return request({
-    url: '/store/store/storeCoupon/publish',
+    url: '/store/storeCoupon/publish',
     method: 'post',
     data: data
   })
@@ -35,7 +35,7 @@ export function publishCoupon(data) {
 
 export function batchPublishCoupon(data) {
   return request({
-    url: '/store/store/storeCoupon/batchPublish',
+    url: '/store/storeCoupon/batchPublish',
     method: 'post',
     data: data
   })
@@ -46,7 +46,7 @@ export function batchPublishCoupon(data) {
 // 修改优惠券
 export function updateStoreCoupon(data) {
   return request({
-    url: '/store/store/storeCoupon',
+    url: '/store/storeCoupon',
     method: 'put',
     data: data
   })
@@ -55,7 +55,7 @@ export function updateStoreCoupon(data) {
 // 删除优惠券
 export function delStoreCoupon(couponId) {
   return request({
-    url: '/store/store/storeCoupon/' + couponId,
+    url: '/store/storeCoupon/' + couponId,
     method: 'delete'
   })
 }
@@ -63,7 +63,7 @@ export function delStoreCoupon(couponId) {
 // 导出优惠券
 export function exportStoreCoupon(query) {
   return request({
-    url: '/store/store/storeCoupon/export',
+    url: '/store/storeCoupon/export',
     method: 'get',
     params: query
   })

+ 6 - 6
src/api/hisStore/storeCouponIssue.js

@@ -3,7 +3,7 @@ import request from '@/utils/request'
 // 查询优惠券领取列表
 export function listStoreCouponIssue(query) {
   return request({
-    url: '/store/store/storeCouponIssue/list',
+    url: '/store/storeCouponIssue/list',
     method: 'get',
     params: query
   })
@@ -12,7 +12,7 @@ export function listStoreCouponIssue(query) {
 // 查询优惠券领取详细
 export function getStoreCouponIssue(id) {
   return request({
-    url: '/store/store/storeCouponIssue/' + id,
+    url: '/store/storeCouponIssue/' + id,
     method: 'get'
   })
 }
@@ -20,7 +20,7 @@ export function getStoreCouponIssue(id) {
 // 新增优惠券领取
 export function addStoreCouponIssue(data) {
   return request({
-    url: '/store/store/storeCouponIssue',
+    url: '/store/storeCouponIssue',
     method: 'post',
     data: data
   })
@@ -29,7 +29,7 @@ export function addStoreCouponIssue(data) {
 // 修改优惠券领取
 export function updateStoreCouponIssue(data) {
   return request({
-    url: '/store/store/storeCouponIssue',
+    url: '/store/storeCouponIssue',
     method: 'put',
     data: data
   })
@@ -38,7 +38,7 @@ export function updateStoreCouponIssue(data) {
 // 删除优惠券领取
 export function delStoreCouponIssue(id) {
   return request({
-    url: '/store/store/storeCouponIssue/' + id,
+    url: '/store/storeCouponIssue/' + id,
     method: 'delete'
   })
 }
@@ -46,7 +46,7 @@ export function delStoreCouponIssue(id) {
 // 导出优惠券领取
 export function exportStoreCouponIssue(query) {
   return request({
-    url: '/store/store/storeCouponIssue/export',
+    url: '/store/storeCouponIssue/export',
     method: 'get',
     params: query
   })

+ 6 - 6
src/api/hisStore/storeCouponIssueUser.js

@@ -3,7 +3,7 @@ import request from '@/utils/request'
 // 查询优惠券用户领取记录列表
 export function listStoreCouponIssueUser(query) {
   return request({
-    url: '/store/store/storeCouponIssueUser/list',
+    url: '/store/storeCouponIssueUser/list',
     method: 'get',
     params: query
   })
@@ -12,7 +12,7 @@ export function listStoreCouponIssueUser(query) {
 // 查询优惠券用户领取记录详细
 export function getStoreCouponIssueUser(id) {
   return request({
-    url: '/store/store/storeCouponIssueUser/' + id,
+    url: '/store/storeCouponIssueUser/' + id,
     method: 'get'
   })
 }
@@ -20,7 +20,7 @@ export function getStoreCouponIssueUser(id) {
 // 新增优惠券用户领取记录
 export function addStoreCouponIssueUser(data) {
   return request({
-    url: '/store/store/storeCouponIssueUser',
+    url: '/store/storeCouponIssueUser',
     method: 'post',
     data: data
   })
@@ -29,7 +29,7 @@ export function addStoreCouponIssueUser(data) {
 // 修改优惠券用户领取记录
 export function updateStoreCouponIssueUser(data) {
   return request({
-    url: '/store/store/storeCouponIssueUser',
+    url: '/store/storeCouponIssueUser',
     method: 'put',
     data: data
   })
@@ -38,7 +38,7 @@ export function updateStoreCouponIssueUser(data) {
 // 删除优惠券用户领取记录
 export function delStoreCouponIssueUser(id) {
   return request({
-    url: '/store/store/storeCouponIssueUser/' + id,
+    url: '/store/storeCouponIssueUser/' + id,
     method: 'delete'
   })
 }
@@ -46,7 +46,7 @@ export function delStoreCouponIssueUser(id) {
 // 导出优惠券用户领取记录
 export function exportStoreCouponIssueUser(query) {
   return request({
-    url: '/store/store/storeCouponIssueUser/export',
+    url: '/store/storeCouponIssueUser/export',
     method: 'get',
     params: query
   })

+ 6 - 6
src/api/hisStore/storeCouponUser.js

@@ -3,7 +3,7 @@ import request from '@/utils/request'
 // 查询优惠券发放记录列表
 export function listStoreCouponUser(query) {
   return request({
-    url: '/store/store/storeCouponUser/list',
+    url: '/store/storeCouponUser/list',
     method: 'get',
     params: query
   })
@@ -12,7 +12,7 @@ export function listStoreCouponUser(query) {
 // 查询优惠券发放记录详细
 export function getStoreCouponUser(id) {
   return request({
-    url: '/store/store/storeCouponUser/' + id,
+    url: '/store/storeCouponUser/' + id,
     method: 'get'
   })
 }
@@ -20,7 +20,7 @@ export function getStoreCouponUser(id) {
 // 新增优惠券发放记录
 export function addStoreCouponUser(data) {
   return request({
-    url: '/store/store/storeCouponUser',
+    url: '/store/storeCouponUser',
     method: 'post',
     data: data
   })
@@ -29,7 +29,7 @@ export function addStoreCouponUser(data) {
 // 修改优惠券发放记录
 export function updateStoreCouponUser(data) {
   return request({
-    url: '/store/store/storeCouponUser',
+    url: '/store/storeCouponUser',
     method: 'put',
     data: data
   })
@@ -38,7 +38,7 @@ export function updateStoreCouponUser(data) {
 // 删除优惠券发放记录
 export function delStoreCouponUser(id) {
   return request({
-    url: '/store/store/storeCouponUser/' + id,
+    url: '/store/storeCouponUser/' + id,
     method: 'delete'
   })
 }
@@ -46,7 +46,7 @@ export function delStoreCouponUser(id) {
 // 导出优惠券发放记录
 export function exportStoreCouponUser(query) {
   return request({
-    url: '/store/store/storeCouponUser/export',
+    url: '/store/storeCouponUser/export',
     method: 'get',
     params: query
   })

+ 62 - 0
src/api/hisStore/userExtract.js

@@ -0,0 +1,62 @@
+import request from '@/utils/request'
+
+// 查询用户提现列表
+export function listUserExtract(query) {
+  return request({
+    url: '/his/userExtract/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询用户提现详细
+export function getUserExtract(id) {
+  return request({
+    url: '/his/userExtract/' + id,
+    method: 'get'
+  })
+}
+
+// 新增用户提现
+export function addUserExtract(data) {
+  return request({
+    url: '/his/userExtract',
+    method: 'post',
+    data: data
+  })
+}
+export function audit(data) {
+  return request({
+    url: '/his/userExtract/audit',
+    method: 'post',
+    data: data
+  })
+}
+
+
+
+// 修改用户提现
+export function updateUserExtract(data) {
+  return request({
+    url: '/his/userExtract',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除用户提现
+export function delUserExtract(id) {
+  return request({
+    url: '/his/userExtract/' + id,
+    method: 'delete'
+  })
+}
+
+// 导出用户提现
+export function exportUserExtract(query) {
+  return request({
+    url: '/his/userExtract/export',
+    method: 'get',
+    params: query
+  })
+}

+ 53 - 0
src/api/hisStore/userPromoterApply.js

@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询推广员申请列表
+export function listUserPromoterApply(query) {
+  return request({
+    url: '/store/userPromoterApply/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询推广员申请详细
+export function getUserPromoterApply(applyId) {
+  return request({
+    url: '/store/userPromoterApply/' + applyId,
+    method: 'get'
+  })
+}
+
+// 新增推广员申请
+export function addUserPromoterApply(data) {
+  return request({
+    url: '/store/userPromoterApply',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改推广员申请
+export function updateUserPromoterApply(data) {
+  return request({
+    url: '/store/userPromoterApply',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除推广员申请
+export function delUserPromoterApply(applyId) {
+  return request({
+    url: '/store/userPromoterApply/' + applyId,
+    method: 'delete'
+  })
+}
+
+// 导出推广员申请
+export function exportUserPromoterApply(query) {
+  return request({
+    url: '/store/userPromoterApply/export',
+    method: 'get',
+    params: query
+  })
+}

+ 18 - 0
src/api/statistics/report.js

@@ -0,0 +1,18 @@
+import request from "@/utils/request";
+
+// 查询客户员工协作列表
+export function getReport(query) {
+  return request({
+    url: '/crm/report/reportList',
+    method: 'get',
+    params: query
+  })
+}
+export function exportReport(query) {
+  return request({
+    url: '/crm/report/export',
+    method: 'get',
+    params: query
+  })
+}
+

二進制
src/assets/logo/bly_logo.png


+ 365 - 0
src/views/company/statistics/tuiMoney.vue

@@ -0,0 +1,365 @@
+<template>
+        <div class="app-container">
+            <div class="app-content">
+                 <div class="title">
+                    佣金排行榜
+                </div>
+               <el-form class="search-form" :inline="true" >
+                <el-form-item >
+                  <el-select style="width: 220px" v-model="value" placeholder="请选择日期">
+                    <el-option
+                      v-for="item in options"
+                      :key="item.value"
+                      :label="item.label"
+                      :value="item.value">
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+                <el-form-item label="公司名" prop="companyId">
+                    <el-select filterable style="width: 220px" v-model="companyId" @change="companyChange" placeholder="请选择公司名" clearable size="small">
+                        <el-option
+                          v-for="item in companys"
+                          :key="item.companyId"
+                          :label="item.companyName"
+                          :value="item.companyId"
+                        />
+                  </el-select>
+                </el-form-item>
+                <el-form-item >
+                  <treeselect style="width: 220px" :clearable="false"  v-model="deptId"  :options="deptOptions" :show-count="true" placeholder="请选择归属部门" />
+                </el-form-item>
+                <el-form-item>
+                  <el-select filterable v-model="userIds" placeholder="请选择员工" clearable size="small">
+                      <el-option
+                        v-for="item in users"
+                        :key="item.userId"
+                        :label="item.nickName"
+                        :value="item.userId">
+                      </el-option>
+                    </el-select>
+                </el-form-item>
+
+                <el-form-item>
+                    <el-button type="cyan" icon="el-icon-search"   @click="getVoiceLogs">搜索</el-button>
+                </el-form-item>
+              </el-form>
+               <div class="data-box">
+                  <div class="echart-box">
+                    <div id="echart-customer"></div>
+                  </div>
+                  <div class="table-box">
+                        <el-button class="export" size="small"  @click="handleExport"   v-hasPermi="['statistics:customer:index']">导出</el-button>
+                        <el-table
+                        :data="list"
+                        border
+                        :summary-method="getSummaries"
+                        show-summary
+                        max-height="500"
+                        style="width: 100%;">
+                        <el-table-column
+                          prop="nickName"
+                          label="员工姓名">
+                        </el-table-column>
+                        <el-table-column
+                          prop="tuiMoneyCount"
+                          label="佣金订单数">
+                        </el-table-column>
+                        <el-table-column
+                          prop="tuiMoney"
+                          label="佣金总金额">
+                        </el-table-column>
+                      </el-table>
+                  </div>
+              </div>
+            </div>
+
+          </div>
+</template>
+
+<script>
+import { tuiMoney,exportTuiMoney } from "@/api/company/statistics";
+import { getUserListByDeptId} from "@/api/company/companyUser";
+import echarts from 'echarts'
+import resize from '../../dashboard/mixins/resize'
+import { treeselect } from "@/api/company/companyDept";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import { getCompanyList } from "@/api/company/company";
+export default {
+  name: 'Index',
+  mixins: [resize],
+  components: { Treeselect },
+  watch: {
+    // 监听deptId
+    'deptId': 'currDeptChange'
+  },
+  data() {
+    return {
+       companys:[],
+       deptOptions:[],
+       companyId:undefined,
+       deptId:undefined,
+       userIds:undefined,
+       users:[],
+       dateRange:[],
+       chart: null,
+       options: [{
+          value: '1',
+          label: '今天'
+        }, {
+          value: '2',
+          label: '昨天'
+        }, {
+          value: '3',
+          label: '本周'
+        }, {
+          value: '4',
+          label: '上周'
+        }, {
+          value: '5',
+          label: '本月'
+        }
+        , {
+          value: '6',
+          label: '上月'
+        }
+        , {
+          value: '7',
+          label: '本季度'
+        }
+        , {
+          value: '8',
+          label: '上季度'
+        }
+        , {
+          value: '9',
+          label: '本年'
+        }
+        , {
+          value: '10',
+          label: '上年'
+        }],
+        value: '5',
+        list:[],
+        dates:[],
+        billingTime:[],
+        tuiMoneyCount:[],
+        tuiMoney:[],
+        times:[]
+
+    }
+  },
+   created() {
+       getCompanyList().then(response => {
+        this.companys = response.data;
+        if(this.companys!=null&&this.companys.length>0){
+          this.companyId=this.companys[0].companyId;
+          this.getTreeselect();
+        }
+      });
+  },
+  methods: {
+    companyChange(val){
+      console.log(val);
+      this.companyId=val;
+      this.getTreeselect();
+    },
+    currDeptChange(val){
+      console.log(val)
+      this.deptId=val;
+       this.getUserListByDeptId();
+    },
+     /** 查询部门下拉树结构 */
+    getTreeselect() {
+      var that=this;
+      var param={companyId:this.companyId}
+      treeselect(param).then((response) => {
+        this.deptOptions = response.data;
+        console.log(this.deptOptions)
+        if(response.data!=null&&response.data.length>0){
+          this.deptId=response.data[0].id;
+          that.getVoiceLogs()
+        }
+      });
+    },
+    handleExport(){
+        var data;
+        if(this.userIds!=undefined){
+            data={type:this.value,userIds:this.userIds+"",deptId:this.deptId}
+        }
+        else{
+            data={type:this.value,deptId:this.deptId}
+        }
+        exportTuiMoney(data).then((response) => {
+            console.log(response)
+           this.download(response.msg);
+        });
+
+    },
+    getUserListByDeptId() {
+        this.userIds=undefined;
+        var data={deptId:this.deptId};
+        getUserListByDeptId(data).then(response => {
+          this.users = response.data;
+
+        });
+    },
+     getVoiceLogs(){
+          var data;
+          if(this.userIds!=undefined){
+              data={type:this.value,userIds:this.userIds+"",deptId:this.deptId}
+          }
+          else{
+              data={type:this.value,deptId:this.deptId}
+          }
+          tuiMoney(data).then((response) => {
+           this.list=response.list;
+           this.tuiMoney=response.tuiMoney;
+           this.tuiMoneyCount=response.tuiMoneyCount;
+
+           this.times=response.times;
+            setTimeout(() => {
+              this.initEchart();
+            }, 500);
+        });
+      },
+      initEchart(){
+        var option = {
+          tooltip: {
+              trigger: 'axis',
+              axisPointer: {            // 坐标轴指示器,坐标轴触发有效
+                  type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
+              }
+          },
+          legend: {
+              data: ['佣金订单数', '佣金总金额' ]
+          },
+          grid: {
+              left: '3%',
+              right: '4%',
+              bottom: '3%',
+              containLabel: true
+          },
+          xAxis: [
+              {
+                  type: 'category',
+                  data: this.dates
+              }
+          ],
+          yAxis: [
+              {
+                  type: 'value',
+                  axisLabel:{
+                    formatter:'{value}'
+                  }
+              }
+          ],
+          series: [
+              {
+
+                  name: '佣金订单数',
+                  type: 'line',
+                  emphasis: {
+                      focus: 'series'
+                  },
+                  data: this.tuiMoneyCount
+              },
+              {
+
+                  name: '佣金总金额',
+                  type: 'line',
+                  emphasis: {
+                      focus: 'series'
+                  },
+                  data: this.tuiMoney
+              }
+
+          ]
+        };
+        this.chart=echarts.init(document.getElementById("echart-customer"));
+        this.chart.setOption(option,true);
+      },
+       getSummaries(param) {
+        const { columns, data } = param;
+        const sums = [];
+        columns.forEach((column, index) => {
+          if (index === 0) {
+            sums[index] = '总计';
+            return;
+          }
+          const values = data.map(item => Number(item[column.property]));
+          if (!values.every(value => isNaN(value))) {
+            sums[index] = values.reduce((prev, curr) => {
+              const value = Number(curr);
+              if (!isNaN(value)) {
+                return prev + curr;
+              } else {
+                return prev;
+              }
+            }, 0);
+            sums[index] += ' ';
+          } else {
+            sums[index] = '';
+          }
+        });
+
+        return sums;
+      }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.app-container{
+    border: 1px solid #e6e6e6;
+    padding: 12px;
+
+    .app-content{
+      background-color: white;
+      .title{
+        padding: 20px 30px 0px 30px;
+        font-size: 18px;
+        font-weight: bold;
+        color: black;
+
+      }
+      .search-form{
+        margin: 20px 30px 0px 30px;
+      }
+      .data-box{
+        padding: 30px;
+        background-color:  rgb(255, 255, 255);
+        height: 100%;
+
+        .echart-box{
+          margin: 0 auto;
+          text-align: center;
+        }
+        .el-select{
+          margin: 5px 10px;
+        }
+        .table-box{
+          margin-top: 15px;
+          .export{
+            float: right;
+            margin: 10px 0px;
+          }
+        }
+      }
+    }
+}
+  #echart-customer{
+    width:100%;
+    height:320px
+  }
+.vue-treeselect{
+  width: 217px;
+  height: 36px;
+}
+
+</style>
+<style>
+.vue-treeselect__control{
+  display: block;
+}
+</style>

+ 200 - 0
src/views/his/articleViews/index.vue

@@ -0,0 +1,200 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="文章标题" prop="articleTitle">
+        <el-input
+          v-model="queryParams.articleTitle"
+          placeholder="请输入文章标题"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+    <el-table  height="500" border v-loading="loading" :data="articleViewsList" >
+      <el-table-column label="ID" align="center" prop="viewId" />
+      <el-table-column label="文章" align="center" prop="articleTitle" />
+      <el-table-column label="会员昵称" align="center" prop="nickname" />
+      <el-table-column label="会员头像" align="center" width="80">
+        <template slot-scope="scope">
+          <el-popover
+            placement="right"
+            title=""
+            trigger="hover"
+          >
+            <img slot="reference" :src="scope.row.avatar" width="50" >
+            <img :src="scope.row.avatar" style="max-width: 120px;">
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column label="浏览时间" align="center" prop="createTime" />
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+
+  </div>
+</template>
+
+<script>
+import { listArticleViews, getArticleViews, delArticleViews, addArticleViews, updateArticleViews, exportArticleViews } from "@/api/his/articleViews";
+
+export default {
+  name: "ArticleViews",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 文章阅读表格数据
+      articleViewsList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        articleId: null,
+        userId: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询文章阅读列表 */
+    getList() {
+      this.loading = true;
+      listArticleViews(this.queryParams).then(response => {
+        this.articleViewsList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        viewId: null,
+        articleId: null,
+        userId: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.viewId)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加文章阅读";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const viewId = row.viewId || this.ids
+      getArticleViews(viewId).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改文章阅读";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.viewId != null) {
+            updateArticleViews(this.form).then(response => {
+              if (response.code === 200) {
+                this.msgSuccess("修改成功");
+                this.open = false;
+                this.getList();
+              }
+            });
+          } else {
+            addArticleViews(this.form).then(response => {
+              if (response.code === 200) {
+                this.msgSuccess("新增成功");
+                this.open = false;
+                this.getList();
+              }
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const viewIds = row.viewId || this.ids;
+      this.$confirm('是否确认删除文章阅读编号为"' + viewIds + '"的数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return delArticleViews(viewIds);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(function() {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有文章阅读数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return exportArticleViews(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+        }).catch(function() {});
+    }
+  }
+};
+</script>

+ 490 - 0
src/views/his/homeArticle/index.vue

@@ -0,0 +1,490 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="分类" prop="categoryId">
+        <el-select v-model="queryParams.categoryId" placeholder="请选择分类" clearable size="small">
+          <el-option
+            v-for="dict in categoryOptions"
+            :key="dict.categoryId"
+            :label="dict.categoryName"
+            :value="dict.categoryId"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="标题" prop="title">
+        <el-input
+          v-model="queryParams.title"
+          placeholder="请输入标题"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="发布状态" prop="publicStatus">
+        <el-select v-model="queryParams.publicStatus" placeholder="请选择发布状态" clearable size="small">
+          <el-option label="已发布" value="1" />
+          <el-option label="草稿" value="2" />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['store:homeArticle:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['store:homeArticle:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['store:homeArticle:remove']"
+        >删除</el-button>
+      </el-col>
+<!--      <el-col :span="1.5">-->
+<!--        <el-button-->
+<!--          type="warning"-->
+<!--          icon="el-icon-download"-->
+<!--          size="mini"-->
+<!--          @click="handleExport"-->
+<!--          v-hasPermi="['store:homeArticle:export']"-->
+<!--        >导出</el-button>-->
+<!--      </el-col>-->
+	  <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="homeArticleList" @selection-change="handleSelectionChange" border>
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="分类" align="center" prop="categoryName" />
+      <el-table-column label="标题" align="center" prop="title" />
+      <el-table-column label="封面图片" align="center" prop="imageUrl">
+        <template slot-scope="scope">
+          <el-image
+            style="width: 80px; height: 50px"
+            :src="scope.row.imageUrl"
+            :preview-src-list="[scope.row.imageUrl]"
+            fit="cover">
+          </el-image>
+        </template>
+      </el-table-column>
+      <el-table-column label="浏览数" align="center" prop="views" width="80" />
+      <el-table-column label="发布时间" align="center" prop="publishTime" width="100">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.publishTime, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="160"/>
+      <el-table-column label="发布状态" align="center" prop="publicStatus" width="100">
+        <template slot-scope="scope">
+          <el-tag type="success" v-if="scope.row.publicStatus == 1">已发布</el-tag>
+          <el-tag type="info" v-else-if="scope.row.publicStatus == 2">草稿</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['store:homeArticle:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['store:homeArticle:remove']"
+          >删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改文章对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="900px" append-to-body :close-on-click-modal="false">
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="分类" prop="categoryId">
+          <el-select v-model="form.categoryId" placeholder="请选择分类" filterable>
+            <el-option
+              v-for="dict in categoryOptions"
+              :key="dict.categoryId"
+              :label="dict.categoryName"
+              :value="dict.categoryId"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="标题" prop="title">
+          <el-input v-model="form.title" placeholder="请输入标题" maxlength="100"/>
+        </el-form-item>
+        <el-form-item label="描述" prop="description">
+          <el-input v-model="form.description" placeholder="请输入描述内容" maxlength="200"/>
+        </el-form-item>
+        <el-form-item label="封面图片" prop="imageUrl">
+          <el-upload
+            class="avatar-uploader"
+            :action="uploadUrl"
+            :show-file-list="false"
+            :on-success="handleImageUrlSuccess"
+            :before-upload="beforeImageUrlUpload">
+            <img v-if="form.imageUrl" :src="form.imageUrl" class="avatar" width="200px">
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </el-upload>
+        </el-form-item>
+        <el-form-item label="是否推荐" prop="isTui">
+          <el-radio-group v-model="form.isTui">
+            <el-radio :label="1">是</el-radio>
+            <el-radio :label="0">否</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="视频地址" prop="videoUrl">
+          <div>
+            <el-upload
+              ref="upload"
+              class="upload-demo"
+              :action="uploadUrl"
+              :on-success="handleVideoSuccess"
+              :before-upload="beforeVideoUpload"
+              :limit="1"
+              :accept="videoAccept"
+            >
+              <el-button size="small" type="primary">点击上传视频</el-button>
+            </el-upload>
+            <video v-if="form.videoUrl" :src="form.videoUrl" controls style="max-width: 400px; max-height: 200px;"></video>
+          </div>
+        </el-form-item>
+        <el-form-item label="内容" prop="content">
+          <Editor ref="myeditor" @on-text-change="updateText"/>
+        </el-form-item>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="浏览数" prop="views">
+              <el-input-number v-model="form.views" :min="0" placeholder="请输入浏览数" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="排序" prop="sort">
+              <el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="发布状态" prop="publicStatus">
+          <el-select v-model="form.publicStatus" placeholder="请选择发布状态">
+            <el-option label="已发布" value="1" />
+            <el-option label="草稿" value="2" />
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listHomeArticle, getHomeArticle, delHomeArticle, addHomeArticle, updateHomeArticle, exportHomeArticle } from "@/api/his/homeArticle";
+import { listHomeCategory, allListHomeCategory } from "@/api/his/homeCategory";
+import Editor from '@/components/Editor/wang';
+
+export default {
+  name: "HomeArticle",
+  components: { Editor },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 文章表格数据
+      homeArticleList: [],
+      // 分类选项
+      categoryOptions: [],
+      // 上传URL
+      uploadUrl: process.env.VUE_APP_BASE_API + "/common/uploadOSS",
+      // 视频接受类型
+      videoAccept: "video/*",
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        categoryId: null,
+        title: null,
+        publicStatus: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        categoryId: [
+          { required: true, message: "分类不能为空", trigger: "change" }
+        ],
+        title: [
+          { required: true, message: "标题不能为空", trigger: "blur" }
+        ],
+        description: [
+          { required: true, message: "发布状态不能为空", trigger: "change" }
+        ],
+        imageUrl: [
+          { required: true, message: "封面图片不能为空", trigger: "change" }
+        ],
+        publicStatus: [
+          { required: true, message: "发布状态不能为空", trigger: "change" }
+        ]
+      }
+    };
+  },
+  created() {
+    this.getList();
+    this.getCategoryOptions();
+  },
+  methods: {
+    /** 获取分类选项 */
+    getCategoryOptions() {
+      allListHomeCategory().then(response => {
+        this.categoryOptions = response.rows;
+      });
+    },
+    /** 查询文章列表 */
+    getList() {
+      this.loading = true;
+      listHomeArticle(this.queryParams).then(response => {
+        this.homeArticleList = response.rows.list;
+        this.total = response.rows.total;
+        this.loading = false;
+      });
+    },
+    // 视频上传成功处理
+    handleVideoSuccess(response, file) {
+      if (response.code == 200) {
+        this.form.videoUrl = response.url;
+        this.$refs.upload.clearFiles();
+      } else {
+        this.msgError(response.msg);
+      }
+    },
+    // 视频上传前的验证
+    beforeVideoUpload(file) {
+      const isLt200M = file.size / 1024 / 1024 < 200;
+      if (!isLt200M) {
+        this.$message.error('上传视频文件大小不能超过200MB!');
+        return false;
+      }
+      return isLt200M;
+    },
+    // 更新富文本内容
+    updateText(text) {
+      this.form.content = text;
+    },
+    // 图片上传成功处理
+    handleImageUrlSuccess(res, file) {
+      if (res.code == 200) {
+        this.form.imageUrl = res.url;
+        this.$forceUpdate();
+      } else {
+        this.msgError(res.msg);
+      }
+    },
+    // 图片上传前的验证
+    beforeImageUrlUpload(file) {
+      const isLt1M = file.size / 1024 / 1024 < 1;
+      if (!isLt1M) {
+        this.$message.error('上传图片大小不能超过1MB!');
+      }
+      return isLt1M;
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        articleId: null,
+        categoryId: null,
+        title: null,
+        description: null,
+        imageUrl: null,
+        isTui: 0,
+        videoUrl: null,
+        content: null,
+        views: 0,
+        sort: 0,
+        publishTime: null,
+        publicStatus: "1"
+      };
+      this.resetForm("form");
+      if (this.$refs.myeditor) {
+        this.$refs.myeditor.setText("");
+      }
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.articleId)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加文章";
+      setTimeout(() => {
+        if (this.$refs.myeditor) {
+          this.$refs.myeditor.setText("");
+        }
+      }, 100);
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const articleId = row.articleId || this.ids
+      getHomeArticle(articleId).then(response => {
+        this.form = response.data;
+        // 确保状态是字符串类型
+        this.form.publicStatus = this.form.publicStatus ? this.form.publicStatus.toString() : "1";
+        this.open = true;
+        this.title = "修改文章";
+        setTimeout(() => {
+          if (this.$refs.myeditor) {
+            if (this.form.content == null) {
+              this.$refs.myeditor.setText("");
+            } else {
+              this.$refs.myeditor.setText(this.form.content);
+            }
+          }
+        }, 100);
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.articleId != null) {
+            updateHomeArticle(this.form).then(response => {
+              if (response.code === 200) {
+                this.msgSuccess("修改成功");
+                this.open = false;
+                this.getList();
+              }
+            });
+          } else {
+            addHomeArticle(this.form).then(response => {
+              if (response.code === 200) {
+                this.msgSuccess("新增成功");
+                this.open = false;
+                this.getList();
+              }
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const articleIds = row.articleId || this.ids;
+      this.$confirm('是否确认删除该文章?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return delHomeArticle(articleIds);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(function() {});
+    },
+    // /** 导出按钮操作 */
+    // handleExport() {
+    //   const queryParams = this.queryParams;
+    //   this.$confirm('是否确认导出所有文章数据项?', "警告", {
+    //       confirmButtonText: "确定",
+    //       cancelButtonText: "取消",
+    //       type: "warning"
+    //     }).then(function() {
+    //       return exportHomeArticle(queryParams);
+    //     }).then(response => {
+    //       this.download(response.msg);
+    //     }).catch(function() {});
+    // }
+  }
+};
+</script>
+
+<style>
+.avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+}
+.avatar-uploader .el-upload:hover {
+  border-color: #409EFF;
+}
+.avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 150px;
+  height: 150px;
+  line-height: 150px;
+  text-align: center;
+}
+.avatar {
+  width: 150px;
+  height: 150px;
+  display: block;
+}
+</style>

+ 365 - 0
src/views/his/homeCategory/index.vue

@@ -0,0 +1,365 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="分类名称" prop="categoryName">
+        <el-input
+          v-model="queryParams.categoryName"
+          placeholder="请输入分类名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
+          <el-option label="正常" value="1" />
+          <el-option label="禁用" value="0" />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['store:homeCategory:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['store:homeCategory:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['store:homeCategory:remove']"
+        >删除</el-button>
+      </el-col>
+<!--      <el-col :span="1.5">-->
+<!--        <el-button-->
+<!--          type="warning"-->
+<!--          icon="el-icon-download"-->
+<!--          size="mini"-->
+<!--          @click="handleExport"-->
+<!--          v-hasPermi="['store:homeCategory:export']"-->
+<!--        >导出</el-button>-->
+<!--      </el-col>-->
+	  <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="homeCategoryList" @selection-change="handleSelectionChange" border>
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="分类名称" align="center" prop="categoryName" />
+      <el-table-column label="封面图片" align="center" prop="imageUrl">
+        <template slot-scope="scope">
+          <el-image
+            style="width: 80px; height: 50px"
+            :src="scope.row.imageUrl"
+            :preview-src-list="[scope.row.imageUrl]"
+            fit="cover">
+          </el-image>
+        </template>
+      </el-table-column>
+      <el-table-column label="状态" align="center" prop="status">
+        <template slot-scope="scope">
+          <el-tag type="success" v-if="scope.row.status == 1">正常</el-tag>
+          <el-tag type="danger" v-else>禁用</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="排序" align="center" prop="sort" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['store:homeCategory:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['store:homeCategory:remove']"
+          >删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改文章分类对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body :close-on-click-modal="false">
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="分类名称" prop="categoryName">
+          <el-input v-model="form.categoryName" placeholder="请输入分类名称" />
+        </el-form-item>
+        <el-form-item label="封面图片" prop="imageUrl">
+          <el-upload
+            class="avatar-uploader"
+            :action="uploadUrl"
+            :show-file-list="false"
+            :on-success="handleImageUrlSuccess"
+            :before-upload="beforeImageUrlUpload">
+            <img v-if="form.imageUrl" :src="form.imageUrl" class="avatar" width="200px">
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </el-upload>
+        </el-form-item>
+        <el-form-item label="排序" prop="sort">
+          <el-input-number v-model="form.sort" placeholder="请输入排序" :min="0" controls-position="right" />
+        </el-form-item>
+        <el-form-item label="状态" prop="status">
+          <el-radio-group v-model="form.status">
+            <el-radio :label="1">正常</el-radio>
+            <el-radio :label="0">禁用</el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listHomeCategory, getHomeCategory, delHomeCategory, addHomeCategory, updateHomeCategory, exportHomeCategory } from "@/api/his/homeCategory";
+
+export default {
+  name: "HomeCategory",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 文章分类表格数据
+      homeCategoryList: [],
+      // 上传URL
+      uploadUrl: process.env.VUE_APP_BASE_API + "/common/uploadOSS",
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        categoryName: null,
+        status: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        categoryName: [
+          { required: true, message: "分类名称不能为空", trigger: "blur" }
+        ],
+        imageUrl: [
+          { required: true, message: "封面图片不能为空", trigger: "change" }
+        ],
+        status: [
+          { required: true, message: "状态不能为空", trigger: "change" }
+        ],
+        sort: [
+          { required: true, message: "排序不能为空", trigger: "blur" }
+        ]
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询文章分类列表 */
+    getList() {
+      this.loading = true;
+      listHomeCategory(this.queryParams).then(response => {
+        this.homeCategoryList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        categoryId: null,
+        categoryName: null,
+        imageUrl: null,
+        status: 1,
+        sort: 0
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.categoryId)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加文章分类";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const categoryId = row.categoryId || this.ids
+      getHomeCategory(categoryId).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改文章分类";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.categoryId != null) {
+            updateHomeCategory(this.form).then(response => {
+              if (response.code === 200) {
+                this.msgSuccess("修改成功");
+                this.open = false;
+                this.getList();
+              }
+            });
+          } else {
+            addHomeCategory(this.form).then(response => {
+              if (response.code === 200) {
+                this.msgSuccess("新增成功");
+                this.open = false;
+                this.getList();
+              }
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const categoryIds = row.categoryId || this.ids;
+      if (row.status === 1) {
+        this.$message.warning('非禁用的分类不能删除');
+      } else {
+        this.$confirm('是否确认删除该文章分类?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return delHomeCategory(categoryIds);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(function() {
+        });
+      }
+    },
+    // /** 导出按钮操作 */
+    // handleExport() {
+    //   const queryParams = this.queryParams;
+    //   this.$confirm('是否确认导出所有文章分类数据项?', "警告", {
+    //       confirmButtonText: "确定",
+    //       cancelButtonText: "取消",
+    //       type: "warning"
+    //     }).then(function() {
+    //       return exportHomeCategory(queryParams);
+    //     }).then(response => {
+    //       this.download(response.msg);
+    //     }).catch(function() {});
+    // },
+    // 图片上传成功处理
+    handleImageUrlSuccess(res, file) {
+      if (res.code == 200) {
+        this.form.imageUrl = res.url;
+        this.$forceUpdate();
+      } else {
+        this.msgError(res.msg);
+      }
+    },
+    // 图片上传前的验证
+    beforeImageUrlUpload(file) {
+      const isLt1M = file.size / 1024 / 1024 < 1;
+      if (!isLt1M) {
+        this.$message.error('上传图片大小不能超过1MB!');
+      }
+      return isLt1M;
+    }
+  }
+};
+</script>
+
+<style>
+.avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+}
+.avatar-uploader .el-upload:hover {
+  border-color: #409EFF;
+}
+.avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 150px;
+  height: 150px;
+  line-height: 150px;
+  text-align: center;
+}
+.avatar {
+  width: 150px;
+  height: 150px;
+  display: block;
+}
+</style>

+ 289 - 0
src/views/his/homeView/index.vue

@@ -0,0 +1,289 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="文章标题" prop="title">
+        <el-input
+          v-model="queryParams.title"
+          placeholder="请输入文章标题"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="用户电话" prop="phone">
+        <el-input
+          v-model="queryParams.phone"
+          placeholder="请输入用户电话"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+<!--    <el-row :gutter="10" class="mb8">-->
+<!--      <el-col :span="1.5">-->
+<!--        <el-button-->
+<!--          type="primary"-->
+<!--          icon="el-icon-plus"-->
+<!--          size="mini"-->
+<!--          @click="handleAdd"-->
+<!--          v-hasPermi="['store:homeView:add']"-->
+<!--        >新增</el-button>-->
+<!--      </el-col>-->
+<!--      <el-col :span="1.5">-->
+<!--        <el-button-->
+<!--          type="success"-->
+<!--          icon="el-icon-edit"-->
+<!--          size="mini"-->
+<!--          :disabled="single"-->
+<!--          @click="handleUpdate"-->
+<!--          v-hasPermi="['store:homeView:edit']"-->
+<!--        >修改</el-button>-->
+<!--      </el-col>-->
+<!--      <el-col :span="1.5">-->
+<!--        <el-button-->
+<!--          type="danger"-->
+<!--          icon="el-icon-delete"-->
+<!--          size="mini"-->
+<!--          :disabled="multiple"-->
+<!--          @click="handleDelete"-->
+<!--          v-hasPermi="['store:homeView:remove']"-->
+<!--        >删除</el-button>-->
+<!--      </el-col>-->
+<!--      <el-col :span="1.5">-->
+<!--        <el-button-->
+<!--          type="warning"-->
+<!--          icon="el-icon-download"-->
+<!--          size="mini"-->
+<!--          @click="handleExport"-->
+<!--          v-hasPermi="['store:homeView:export']"-->
+<!--        >导出</el-button>-->
+<!--      </el-col>-->
+<!--	  <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>-->
+<!--    </el-row>-->
+
+    <el-table v-loading="loading" :data="homeViewList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="文章标题" align="center" prop="title" :show-overflow-tooltip="true" />
+      <el-table-column label="用户昵称" align="center" prop="nickname" />
+      <el-table-column label="用户电话" align="center" prop="phone" />
+<!--      <el-table-column label="用户头像" align="center" prop="avatar">-->
+<!--        <template slot-scope="scope">-->
+<!--          <el-image-->
+<!--            style="width: 50px; height: 50px"-->
+<!--            :src="scope.row.avatar"-->
+<!--            fit="cover"-->
+<!--            :preview-src-list="[scope.row.avatar]">-->
+<!--          </el-image>-->
+<!--        </template>-->
+<!--      </el-table-column>-->
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180" />
+<!--      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">-->
+<!--        <template slot-scope="scope">-->
+<!--          <el-button-->
+<!--            size="mini"-->
+<!--            type="text"-->
+<!--            icon="el-icon-edit"-->
+<!--            @click="handleUpdate(scope.row)"-->
+<!--            v-hasPermi="['store:homeView:edit']"-->
+<!--          >修改</el-button>-->
+<!--          <el-button-->
+<!--            size="mini"-->
+<!--            type="text"-->
+<!--            icon="el-icon-delete"-->
+<!--            @click="handleDelete(scope.row)"-->
+<!--            v-hasPermi="['store:homeView:remove']"-->
+<!--          >删除</el-button>-->
+<!--        </template>-->
+<!--      </el-table-column>-->
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改倍力之家_文章阅读对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="文章标题" prop="title">
+          <el-input v-model="form.title" placeholder="请输入文章标题" />
+        </el-form-item>
+        <el-form-item label="用户昵称" prop="nickname">
+          <el-input v-model="form.nickname" placeholder="请输入用户昵称" />
+        </el-form-item>
+        <el-form-item label="用户头像" prop="avatar">
+          <el-input v-model="form.avatar" placeholder="请输入用户头像URL" />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listHomeView, getHomeView, delHomeView, addHomeView, updateHomeView, exportHomeView } from "@/api/his/homeView";
+
+export default {
+  name: "HomeView",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 倍力之家_文章阅读表格数据
+      homeViewList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        title: null,
+        nickname: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询倍力之家_文章阅读列表 */
+    getList() {
+      this.loading = true;
+      listHomeView(this.queryParams).then(response => {
+        console.log(response)
+        this.homeViewList = response.rows.list;
+        this.total = response.rows.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        viewId: null,
+        title: null,
+        nickname: null,
+        avatar: null,
+        createTime: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.viewId)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加倍力之家_文章阅读";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const viewId = row.viewId || this.ids
+      getHomeView(viewId).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改倍力之家_文章阅读";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.viewId != null) {
+            updateHomeView(this.form).then(response => {
+              if (response.code === 200) {
+                this.msgSuccess("修改成功");
+                this.open = false;
+                this.getList();
+              }
+            });
+          } else {
+            addHomeView(this.form).then(response => {
+              if (response.code === 200) {
+                this.msgSuccess("新增成功");
+                this.open = false;
+                this.getList();
+              }
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const viewIds = row.viewId || this.ids;
+      this.$confirm('是否确认删除倍力之家_文章阅读编号为"' + viewIds + '"的数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return delHomeView(viewIds);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(function() {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有倍力之家_文章阅读数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return exportHomeView(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+        }).catch(function() {});
+    }
+  }
+};
+</script>

+ 498 - 0
src/views/hisStore/statistics/orderstatatic.vue

@@ -0,0 +1,498 @@
+<template>
+  <div class="order-statistics-container">
+    <el-card class="search-card">
+      <div class="search-header">
+        <span class="title">订单统计</span>
+        <div class="search-actions">
+          <el-date-picker
+            v-model="dateRange"
+            type="daterange"
+            align="right"
+            unlink-panels
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            :picker-options="pickerOptions"
+            @change="handleDateChange"
+          />
+          <el-button type="primary" @click="handleSearch" :loading="loading">查询</el-button>
+        </div>
+      </div>
+    </el-card>
+
+    <el-row :gutter="20" class="statistics-row">
+      <el-col :span="6">
+        <el-card shadow="hover">
+          <div class="statistic-item">
+            <div class="statistic-title">订单总量</div>
+            <div class="statistic-value">{{ statistics.orderCount }}</div>
+          </div>
+        </el-card>
+      </el-col>
+
+      <el-col :span="6">
+        <el-card shadow="hover">
+          <div class="statistic-item" @click="fetchOrderDetails" style="cursor: pointer;">
+            <div class="statistic-title">总金额</div>
+            <div class="statistic-value">¥{{ statistics.totalAmount | formatMoney }}</div>
+          </div>
+        </el-card>
+      </el-col>
+
+      <el-col :span="6">
+        <el-card shadow="hover">
+          <div class="statistic-item">
+            <div class="statistic-title">成交率</div>
+            <div class="statistic-value">{{ statistics.successRate }}%</div>
+          </div>
+        </el-card>
+      </el-col>
+
+      <el-col :span="6">
+        <el-card shadow="hover">
+          <div class="statistic-item">
+            <div class="statistic-title">退货率</div>
+            <div class="statistic-value">{{ statistics.returnRate }}%</div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 订单详情对话框 -->
+    <el-dialog
+      title="订单详情"
+      :visible.sync="detailModalVisible"
+      width="85%"
+      top="5vh"
+      class="clean-dialog"
+    >
+      <div class="clean-container">
+        <el-table
+          :data="orderDetails"
+          border
+          style="width: 100%"
+          v-loading="detailLoading"
+          height="70vh"
+          class="clean-table"
+        >
+          <el-table-column
+            label="订单号"
+            align="center"
+            prop="orderCode"
+            width="180"
+            header-align="center"
+          />
+          <el-table-column
+            label="所属公司"
+            align="center"
+            prop="companyName"
+            header-align="center"
+            show-overflow-tooltip
+          />
+          <el-table-column
+            label="用户/收件人"
+            align="center"
+            header-align="center"
+            width="150"
+          >
+            <template slot-scope="scope">
+              <div class="compact-cell">
+                <div>{{ scope.row.nickname || '-' }}</div>
+                <div class="secondary-text">{{ scope.row.realName || '-' }}</div>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            label="金额(元)"
+            align="center"
+            header-align="center"
+            width="150"
+          >
+            <template slot-scope="scope">
+              <div class="compact-cell">
+                <div>总价: {{ scope.row.totalPrice ? scope.row.totalPrice.toFixed(2) : '0.00' }}</div>
+                <div>实付: {{ scope.row.payPrice ? scope.row.payPrice.toFixed(2) : '0.00' }}</div>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            label="时间"
+            align="center"
+            header-align="center"
+            width="220"
+          >
+            <template slot-scope="scope">
+              <div class="compact-cell">
+                <div>{{ scope.row.createTime }}</div>
+                <div class="secondary-text">{{ scope.row.payTime || '未支付' }}</div>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            label="支付/类型"
+            align="center"
+            header-align="center"
+            width="150"
+          >
+            <template slot-scope="scope">
+              <div class="compact-cell">
+                <el-tag
+                  size="small"
+                  style="display:block;margin:0 auto 4px;width:fit-content"
+                  v-for="item in payTypeOptions"
+                  v-if="scope.row.payType==item.dictValue"
+                >{{item.dictLabel}}</el-tag>
+                <el-tag
+                  size="small"
+                  style="display:block;margin:0 auto;width:fit-content"
+                  v-for="item in orderTypeOptions"
+                  v-if="scope.row.orderType==item.dictValue"
+                >{{item.dictLabel}}</el-tag>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            label="状态"
+            align="center"
+            header-align="center"
+            width="150"
+          >
+            <template slot-scope="scope">
+              <div class="compact-cell">
+                <el-tag
+                  size="small"
+                  style="display:block;margin:0 auto 4px;width:fit-content"
+                  v-for="item in statusOptions"
+                  v-if="scope.row.status==item.dictValue"
+                >{{item.dictLabel}}</el-tag>
+                <el-tag
+                  size="small"
+                  style="display:block;margin:0 auto;width:fit-content"
+                  v-for="item in deliveryStatusOptions"
+                  v-if="scope.row.deliveryStatus==item.dictValue"
+                >{{item.dictLabel}}</el-tag>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            label="操作"
+            fixed="right"
+            width="90"
+            align="center"
+            header-align="center"
+          >
+            <template slot-scope="scope">
+              <el-button
+                size="mini"
+                type="text"
+                style="color:#409EFF;padding:5px 0"
+                @click="handleDetails(scope.row)"
+                v-hasPermi="['store:storeOrder:query']"
+              >详情</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <div style="margin-top:15px">
+          <pagination
+            v-show="pagination.total>0"
+            :total="pagination.total"
+            :page.sync="pagination.currentPage"
+            :limit.sync="pagination.pageSize"
+            @pagination="fetchOrderDetails"
+          />
+        </div>
+      </div>
+
+      <el-drawer
+        :title="show.title"
+        :visible.sync="show.open"
+        size="65%"
+        :modal="false"
+        :wrapper-closable="false"
+        :append-to-body="true"
+        custom-class="safe-drawer"
+      >
+        <product-order ref="order" />
+      </el-drawer>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { getOrderStatistics } from "@/api/hisStore/statistics";
+import { listStoreOrder  } from "@/api/hisStore/storeOrder";
+import productOrder from "../components/productOrder";
+export default {
+  components: { productOrder  },
+  name: 'OrderStatistics',
+  data() {
+    return {
+      deliveryPayStatusOptions:[],
+      deliveryStatusOptions:[],
+      orderTypeOptions:[],
+      payTypeOptions:[],
+      show:{
+        open:false,
+        title:"订单详情"
+      },
+      statusOptions:[],
+      dateRange: [],
+      pickerOptions: {
+        shortcuts: [{
+          text: '最近一周',
+          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 * 30);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '最近三个月',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+            picker.$emit('pick', [start, end]);
+          }
+        }]
+      },
+      loading: false,
+      detailLoading: false,
+      statistics: {
+        orderCount: 0,
+        totalAmount: 0,
+        successRate: 0,
+        returnRate: 0
+      },
+      orderDetails: [],
+      detailModalVisible: false,
+      pagination: {
+        currentPage: 1,
+        pageSize: 10,
+        total: 0
+      },
+
+    };
+  },
+  filters: {
+    formatMoney(value) {
+      if (!value) return '0.00';
+      return parseFloat(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
+    }
+  },
+  created() {
+    this.getDicts("store_order_type").then((response) => {
+      this.orderTypeOptions = response.data;
+    });
+    this.getDicts("user_status").then((response) => {
+      this.userStatusOptions = response.data;
+    });
+    this.getDicts("store_pay_type").then((response) => {
+      this.payTypeOptions = response.data;
+    });
+    this.getDicts("store_order_status").then((response) => {
+      this.statusOptions = response.data;
+    });
+    this.getDicts("store_order_delivery_status").then((response) => {
+      this.deliveryStatusOptions = response.data;
+    });
+    this.getDicts("store_delivery_pay_status").then((response) => {
+      this.deliveryPayStatusOptions = response.data;
+    });
+    // 默认查询最近30天数据
+    const end = new Date();
+    const start = new Date();
+    start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+    this.dateRange = [start, end];
+    this.fetchStatistics();
+  },
+  methods: {
+    handleDetails(row){
+      this.show.open=true;
+      const orderId = row.id ;
+      setTimeout(() => {
+        this.$refs.order.getOrder(orderId);
+      }, 500);
+    },
+    /**
+     * 格式化日期(内置方法,替代外部工具函数)
+     * @param {Date|string} date 日期对象或字符串
+     * @param {string} [fmt='yyyy-MM-dd HH:mm:ss'] 格式字符串
+     * @returns {string} 格式化后的日期字符串
+     */
+    formatDate(date, fmt = 'yyyy-MM-dd HH:mm:ss') {
+      if (!date) return '';
+      if (typeof date === 'string') {
+        date = new Date(date.replace(/-/g, '/'));
+      }
+      if (!(date instanceof Date)) {
+        date = new Date(date);
+      }
+
+      const o = {
+        'M+': date.getMonth() + 1, // 月份
+        'd+': date.getDate(), // 日
+        'H+': date.getHours(), // 小时
+        'm+': date.getMinutes(), // 分
+        's+': date.getSeconds(), // 秒
+        'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
+        'S': date.getMilliseconds() // 毫秒
+      };
+
+      if (/(y+)/.test(fmt)) {
+        fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
+      }
+
+      for (const k in o) {
+        if (new RegExp('(' + k + ')').test(fmt)) {
+          fmt = fmt.replace(
+            RegExp.$1,
+            RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)
+          );
+        }
+      }
+
+      return fmt;
+    },
+
+
+    handleDateChange(val) {
+      this.dateRange = val;
+      this.fetchStatistics();
+    },
+
+    handleSearch() {
+      this.fetchStatistics();
+    },
+
+    async fetchStatistics() {
+      if (!this.dateRange || this.dateRange.length !== 2) {
+        this.$message.warning('请选择日期范围');
+        return;
+      }
+
+      this.loading = true;
+      try {
+        const params = {
+          startTime: this.formatDate(this.dateRange[0], 'yyyy-MM-dd'),
+          endTime: this.formatDate(this.dateRange[1], 'yyyy-MM-dd')
+        };
+        const response = await getOrderStatistics(params);
+        this.statistics = response.data;
+
+      } catch (error) {
+        this.$message.error('获取统计数据失败');
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    async fetchOrderDetails() {
+      if (!this.dateRange || this.dateRange.length !== 2) return;
+
+      this.detailLoading = true;
+      try {
+        const params = {
+          createTimeRange: this.formatDate(this.dateRange[0], 'yyyy-MM-dd')+"--"+this.formatDate(this.dateRange[1], 'yyyy-MM-dd'),
+          pageNum: this.pagination.currentPage,
+          pageSize: this.pagination.pageSize,
+          paidStatus:1
+        };
+        const response = await listStoreOrder(params);
+        this.orderDetails = response.rows;
+        this.pagination.total = response.total;
+        this.detailModalVisible = true;
+      } catch (error) {
+        this.$message.error('获取订单详情失败');
+      } finally {
+        this.detailLoading = false;
+      }
+    },
+
+    handleSizeChange(val) {
+      this.pagination.pageSize = val;
+      this.fetchOrderDetails();
+    },
+
+    handleCurrentChange(val) {
+      this.pagination.currentPage = val;
+      this.fetchOrderDetails();
+    }
+  }
+};
+</script>
+
+<style scoped>
+.order-statistics-container {
+  padding: 20px;
+}
+
+.search-card {
+  margin-bottom: 20px;
+}
+
+.search-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.title {
+  font-size: 18px;
+  font-weight: bold;
+}
+
+.statistics-row {
+  margin-bottom: 20px;
+}
+
+.statistic-item {
+  padding: 10px;
+}
+
+.statistic-title {
+  font-size: 14px;
+  color: #999;
+  margin-bottom: 10px;
+}
+
+.statistic-value {
+  font-size: 24px;
+  font-weight: bold;
+  margin-bottom: 10px;
+}
+
+
+.statistic-compare .up {
+  color: #f56c6c;
+  margin-left: 5px;
+}
+
+.statistic-compare .down {
+  color: #67c23a;
+  margin-left: 5px;
+}
+.clean-dialog {
+  border-radius: 8px;
+}
+.clean-table .el-table__header th {
+  background-color: #f8f8f9;
+}
+.compact-cell {
+  padding: 4px 0;
+  line-height: 1.4;
+}
+.secondary-text {
+  color: #909399;
+  font-size: 0.9em;
+}
+</style>

+ 537 - 0
src/views/hisStore/statistics/storeOrder.vue

@@ -0,0 +1,537 @@
+<template>
+  <div class="app-container">
+    <div class="app-content">
+      <div class="title">
+        商城订单统计
+      </div>
+               <el-form class="search-form" :inline="true" >
+
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="时间:">
+              <el-select v-model="value" placeholder="请选择日期">
+                <el-option
+                  v-for="item in options"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+             <el-form-item label="公司名:" prop="companyId">
+              <el-select filterable v-model="companyId" @change="companyChange" placeholder="请选择公司名" clearable size="small">
+                <el-option
+                  v-for="item in companys"
+                  :key="item.companyId"
+                  :label="item.companyName"
+                  :value="item.companyId"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="部门:">
+              <treeselect :clearable="false"  v-model="deptId"  :options="deptOptions" :show-count="true" placeholder="请选择归属部门" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="员工:">
+              <el-select filterable v-model="userIds" placeholder="请选择员工" clearable size="small">
+                <el-option
+                  v-for="item in users"
+                  :key="item.userId"
+                  :label="item.nickName"
+                  :value="item.userId">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="订单类型:">
+              <el-select v-model="orderType" placeholder="请选择订单类型" clearable size="small">
+                <el-option
+                  v-for="item in orderTypeOptions"
+                  :key="item.dictLabel"
+                  :label="item.dictLabel"
+                  :value="item.dictValue">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="媒体来源:">
+              <el-select v-model="orderMedium" placeholder="请选择媒体来源" clearable size="small">
+                <el-option
+                  v-for="item in orderMediumOptions"
+                  :key="item.dictLabel"
+                  :label="item.dictLabel"
+                  :value="item.dictValue">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+
+
+
+
+
+
+        <el-form-item label="筛选日期" prop="createTime">
+          <el-date-picker clearable size="small" style="width: 205.4px"
+            v-model="dateRange"
+            type="daterange"
+            value-format="yyyy-MM-dd"
+                    start-placeholder="开始日期" end-placeholder="结束日期"
+                    >
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item>
+                    <el-button type="primary" icon="el-icon-search" plain   @click="storeOrder">搜索</el-button>
+        </el-form-item>
+      </el-form>
+      <div class="data-box">
+        <div class="echart-box">
+          <div id="echart-customer"></div>
+        </div>
+
+        <!-- 新增的数据表格 -->
+        <div class="table-container">
+          <h3 class="table-title">员工下单汇总</h3>
+          <el-table
+            :data="tableData"
+            border
+            stripe
+            style="width: 100%; margin-top: 20px;"
+            :row-class-name="tableRowClassName"
+            :span-method="objectSpanMethod"
+            >
+            <el-table-column prop="name" label="姓名/工号" width="150" class-name="sticky-column">
+              <template slot-scope="scope">
+                <span :class="{'group-name': scope.row.isGroup}">{{ scope.row.name }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column prop="totalCalls" label="总单数" width="80" align="center"></el-table-column>
+            <el-table-column prop="totalAmount" label="总金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.totalAmount ? scope.row.totalAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="validAmount" label="成单金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.validAmount ? scope.row.validAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="waitingOrders" label="待付数" width="80" align="center"></el-table-column>
+            <el-table-column prop="waitingAmount" label="待付金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.waitingAmount ? scope.row.waitingAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="unPassedOrders" label="未过数" width="80" align="center"></el-table-column>
+            <el-table-column prop="unPassedAmount" label="未过金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.unpassedAmount ? scope.row.unpassedAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="cancelOrders" label="取消数" width="80" align="center"></el-table-column>
+            <el-table-column prop="cancelAmount" label="取消金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.cancelAmount ? scope.row.cancelAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="unshippedOrders" label="成交未发货数" width="120" align="center"></el-table-column>
+            <el-table-column prop="unshippedAmount" label="成交未发货金额" width="130" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.unshippedAmount ? scope.row.unshippedAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="shippedOrders" label="发货数" width="80" align="center"></el-table-column>
+            <el-table-column prop="shippedAmount" label="发货金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.shippedAmount ? scope.row.shippedAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="transitOrders" label="在途数" width="80" align="center"></el-table-column>
+            <el-table-column prop="transitAmount" label="在途金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.transitAmount ? scope.row.transitAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="receivedOrders" label="签收数" width="80" align="center"></el-table-column>
+            <el-table-column prop="receivedAmount" label="签收金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.receivedAmount ? scope.row.receivedAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="returnOrders" label="退货数" width="80" align="center"></el-table-column>
+            <el-table-column prop="returnAmount" label="退货金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.returnAmount ? scope.row.returnAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="paybackOrders" label="回款数" width="80" align="center"></el-table-column>
+            <el-table-column prop="paybackAmount" label="回款金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.paybackAmount ? scope.row.paybackAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </div>
+    </div>
+
+  </div>
+</template>
+
+<script>
+import { storeOrder } from "@/api/hisStore/statistics";
+import { getUserListByDeptId} from "@/api/company/companyUser";
+import echarts from 'echarts'
+import resize from '../../dashboard/mixins/resize'
+import { treeselect } from "@/api/company/companyDept";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import { getCompanyList } from "@/api/company/company";
+export default {
+  name: 'Index',
+  mixins: [resize],
+  components: { Treeselect },
+  watch: {
+    // 监听deptId
+    'deptId': 'currDeptChange'
+  },
+  data() {
+    return {
+      companys: [],
+      deptOptions: [],
+      companyId: undefined,
+      deptId: undefined,
+      userIds: undefined,
+      users: [],
+      dateRange: [],
+      chart: null,
+      orderTypeOptions:[],// 订单类型
+      orderType:'',
+      orderMediumOptions:[], // 媒体来源
+      orderMedium:'',
+      options: [{
+        value: '1',
+        label: '今天'
+      }, {
+        value: '2',
+        label: '昨天'
+      }, {
+        value: '3',
+        label: '本周'
+      }, {
+        value: '4',
+        label: '上周'
+      }, {
+        value: '5',
+        label: '本月'
+      }, {
+        value: '6',
+        label: '上月'
+      }, {
+        value: '7',
+        label: '本季度'
+      }, {
+        value: '8',
+        label: '上季度'
+      }, {
+        value: '9',
+        label: '本年'
+      }, {
+        value: '10',
+        label: '上年'
+      }],
+      value: '5',
+      list: [],
+      dates: [],
+      orderCount: [],
+      payPrice: [],
+      // 新增表格数据
+      tableData: []
+    }
+  },
+  created() {
+    getCompanyList().then(response => {
+      this.companys = response.data;
+      if (this.companys != null && this.companys.length > 0) {
+        this.companyId = this.companys[0].companyId;
+        this.getTreeselect();
+      }
+    });
+    // 获取订单类型
+    this.getDicts("store_order_type").then((response) => {
+      this.orderTypeOptions = response.data;
+    });
+    // 媒体来源
+    this.getDicts("crm_customer_source").then((response) => {
+      this.orderMediumOptions = response.data;
+    });
+  },
+  methods: {
+    companyChange(val) {
+      console.log(val);
+      this.companyId = val;
+      this.getTreeselect();
+    },
+    currDeptChange(val) {
+      console.log(val)
+      this.deptId = val;
+      this.getUserListByDeptId();
+    },
+    /** 查询部门下拉树结构 */
+    getTreeselect() {
+      var that = this;
+      var param = { companyId: this.companyId }
+      treeselect(param).then((response) => {
+        this.deptOptions = response.data;
+        console.log(this.deptOptions)
+        if (response.data != null && response.data.length > 0) {
+          this.deptId = response.data[0].id;
+          that.storeOrder()
+        }
+      });
+    },
+    handleExport() {
+      var data;
+      if (this.userIds != undefined) {
+        data = { type: this.value, userIds: this.userIds + "", deptId: this.deptId }
+      }
+      else {
+        data = { type: this.value, deptId: this.deptId }
+      }
+      exportVoiceLogs(data).then((response) => {
+        console.log(response)
+        this.download(response.msg);
+      });
+    },
+    getUserListByDeptId() {
+      this.userIds = undefined;
+      var data = { deptId: this.deptId };
+      getUserListByDeptId(data).then(response => {
+        this.users = response.data;
+      });
+    },
+    storeOrder() {
+      var data;
+      if (this.userIds != undefined) {
+        data = { type: this.value, userIds: this.userIds + "", deptId: this.deptId }
+      }
+      else {
+        data = { type: this.value, deptId: this.deptId }
+      }
+      if(this.dateRange && this.dateRange.length>0){
+        data.type = null
+        data.startTime = this.dateRange[0]
+        data.endTime = this.dateRange[1]
+      }
+      if(this.orderType){
+        data.orderType = this.orderType
+      }
+      if(this.orderMedium){
+        data.orderMedium = this.orderMedium
+      }
+      storeOrder(data).then((response) => {
+        this.dates = response.dates;
+        this.orderCount = response.orderCount;
+        this.payPrice = response.payPrice;
+        //表格数据
+        this.tableData = response.tableData || this.tableData;
+
+        setTimeout(() => {
+          this.initEchart();
+        }, 500);
+      });
+    },
+    initEchart() {
+      var option = {
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            // 坐标轴指示器,坐标轴触发有效
+            type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
+          }
+        },
+        legend: {
+          data: ['订单数', '订单金额']
+        },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '3%',
+          containLabel: true
+        },
+        xAxis: [
+          {
+            type: 'category',
+            data: this.dates
+          }
+        ],
+        yAxis: [
+          {
+            type: 'value',
+            axisLabel: {
+              formatter: '{value}个'
+            }
+          }
+        ],
+        series: [
+          {
+            name: '订单数',
+            type: 'bar',
+            emphasis: {
+              focus: 'series'
+            },
+            data: this.orderCount
+          },
+          {
+            name: '订单金额',
+            type: 'bar',
+            emphasis: {
+              focus: 'series'
+            },
+            data: this.payPrice
+          }
+        ]
+      };
+      this.chart = echarts.init(document.getElementById("echart-customer"));
+      this.chart.setOption(option, true);
+    },
+    // 表格行样式
+    tableRowClassName({ row, rowIndex }) {
+      if (row.isGroup) {
+        return 'group-row';
+      }
+      return '';
+    },
+    // 表格合并方法(如果需要的话)
+    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+      // 可以在这里实现单元格合并逻辑
+      return {
+        rowspan: 1,
+        colspan: 1
+      };
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.app-container {
+  border: 1px solid #e6e6e6;
+  padding: 12px;
+  .app-content {
+    background-color: white;
+    .title {
+      padding: 20px 30px 0px 30px;
+      font-size: 18px;
+      font-weight: bold;
+      color: black;
+    }
+    .search-form {
+      margin: 20px 30px 0px 30px;
+    }
+    .data-box {
+      padding: 30px;
+      background-color: rgb(255, 255, 255);
+      height: 100%;
+      .echart-box {
+        margin: 0 auto;
+        text-align: center;
+      }
+      .el-select {
+        margin: 5px 10px;
+      }
+      .table-box {
+        margin-top: 15px;
+        .export {
+          float: right;
+          margin: 10px 0px;
+        }
+      }
+      // 新增表格样式
+      .table-container {
+        margin-top: 30px;
+        .table-title {
+          font-size: 16px;
+          font-weight: bold;
+          color: #333;
+          margin-bottom: 10px;
+        }
+      }
+    }
+  }
+}
+
+#echart-customer {
+  width: 100%;
+  height: 320px
+}
+
+.vue-treeselect {
+  width: 217px;
+  height: 36px;
+}
+
+// 表格相关样式
+::v-deep .group-row {
+  background-color: #e8f5e8 !important;
+  font-weight: bold;
+}
+
+::v-deep .group-name {
+  font-weight: bold;
+  color: #333;
+}
+
+::v-deep .el-table {
+  font-size: 12px;
+
+  .el-table__header-wrapper {
+    th {
+      background-color: #f5f7fa;
+      font-weight: bold;
+      color: #333;
+    }
+  }
+
+  .el-table__body-wrapper {
+    td {
+      padding: 8px 0;
+    }
+  }
+}
+
+::v-deep .sticky-column {
+  position: sticky;
+  left: 0;
+  z-index: 2;
+  background-color: white;
+
+  // 为表头也添加样式
+  &.is-header-column {
+    background-color: #f5f7fa;
+  }
+}
+
+// 确保表格容器允许sticky定位
+::v-deep .el-table__body-wrapper {
+  overflow-x: auto;
+}
+</style>
+
+<style>
+.vue-treeselect__control {
+  display: block;
+}
+</style>

+ 467 - 0
src/views/hisStore/statistics/storeOrderData.vue

@@ -0,0 +1,467 @@
+<template>
+  <div class="app-container">
+    <div class="app-content">
+      <div class="title">
+        订单数据汇总
+      </div>
+        <el-form class="search-form" :inline="true">
+         <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="时间:">
+              <el-select v-model="value" placeholder="请选择日期">
+                <el-option
+                  v-for="item in options"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+             <el-form-item label="公司名:" prop="companyId">
+              <el-select filterable v-model="companyId" @change="companyChange" placeholder="请选择公司名" clearable size="small">
+                <el-option
+                  v-for="item in companys"
+                  :key="item.companyId"
+                  :label="item.companyName"
+                  :value="item.companyId"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="部门:">
+              <treeselect :clearable="false"  v-model="deptId"  :options="deptOptions" :show-count="true" placeholder="请选择归属部门" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="员工:">
+              <el-select filterable v-model="userIds" placeholder="请选择员工" clearable size="small">
+                <el-option
+                  v-for="item in users"
+                  :key="item.userId"
+                  :label="item.nickName"
+                  :value="item.userId">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="订单类型:">
+              <el-select v-model="orderType" placeholder="请选择订单类型" clearable size="small">
+                <el-option
+                  v-for="item in orderTypeOptions"
+                  :key="item.dictLabel"
+                  :label="item.dictLabel"
+                  :value="item.dictValue">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="媒体来源:">
+              <el-select v-model="orderMedium" placeholder="请选择媒体来源" clearable size="small">
+                <el-option
+                  v-for="item in orderMediumOptions"
+                  :key="item.dictLabel"
+                  :label="item.dictLabel"
+                  :value="item.dictValue">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        
+        <el-form-item label="筛选日期" prop="createTime">
+          <el-date-picker clearable size="small" style="width: 205.4px"
+            v-model="dateRange"
+            type="daterange"
+            value-format="yyyy-MM-dd"
+            start-placeholder="开始日期" end-placeholder="结束日期">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" icon="el-icon-search" plain @click="storeOrder">搜索</el-button>
+        </el-form-item>
+      </el-form>
+
+      <!-- 新增的数据表格 -->
+      <div class="data-box">
+        <el-table :data="tableData" border stripe style="width: 100%; margin-top: 20px;" 
+          :summary-method="getSummaries" show-summary>
+          <el-table-column prop="province" label="省份" width="120" fixed align="center"></el-table-column>
+          
+          <el-table-column label="订单总数" width="120" align="center">
+            <el-table-column prop="orderCount" label="数量" width="80" align="center"></el-table-column>
+            <el-table-column prop="orderAmount" label="金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.orderAmount ? scope.row.orderAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+          </el-table-column>
+          
+          <el-table-column label="取消单" align="center">
+            <el-table-column prop="cancelCount" label="数量" width="80" align="center"></el-table-column>
+            <el-table-column prop="cancelAmount" label="金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.cancelAmount ? scope.row.cancelAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="cancelCountRatio" label="数量比%" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.cancelCountRatio ? scope.row.cancelCountRatio.toFixed(2) : '0.00' }}%
+              </template>
+            </el-table-column>
+            <el-table-column prop="cancelAmountRatio" label="金额比%" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.cancelAmountRatio ? scope.row.cancelAmountRatio.toFixed(2) : '0.00' }}%
+              </template>
+            </el-table-column>
+          </el-table-column>
+          
+          <el-table-column label="发货单" align="center">
+            <el-table-column prop="shippedCount" label="数量" width="80" align="center"></el-table-column>
+            <el-table-column prop="shippedAmount" label="金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.shippedAmount ? scope.row.shippedAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="shippedCountRatio" label="数量比%" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.shippedCountRatio ? scope.row.shippedCountRatio.toFixed(2) : '0.00' }}%
+              </template>
+            </el-table-column>
+            <el-table-column prop="shippedAmountRatio" label="金额比%" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.shippedAmountRatio ? scope.row.shippedAmountRatio.toFixed(2) : '0.00' }}%
+              </template>
+            </el-table-column>
+          </el-table-column>
+          
+          <el-table-column label="在途单" align="center">
+            <el-table-column prop="transitCount" label="数量" width="80" align="center"></el-table-column>
+            <el-table-column prop="transitAmount" label="金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.transitAmount ? scope.row.transitAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="transitCountRatio" label="数量比%" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.transitCountRatio ? scope.row.transitCountRatio.toFixed(2) : '0.00' }}%
+              </template>
+            </el-table-column>
+            <el-table-column prop="transitAmountRatio" label="金额比%" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.transitAmountRatio ? scope.row.transitAmountRatio.toFixed(2) : '0.00' }}%
+              </template>
+            </el-table-column>
+          </el-table-column>
+          
+          <el-table-column label="退单" align="center">
+            <el-table-column prop="returnCount" label="数量" width="80" align="center"></el-table-column>
+            <el-table-column prop="returnAmount" label="金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.returnAmount ? scope.row.returnAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="returnCountRatio" label="数量比%" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.returnCountRatio ? scope.row.returnCountRatio.toFixed(2) : '0.00' }}%
+              </template>
+            </el-table-column>
+            <el-table-column prop="returnAmountRatio" label="金额比%" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.returnAmountRatio ? scope.row.returnAmountRatio.toFixed(2) : '0.00' }}%
+              </template>
+            </el-table-column>
+          </el-table-column>
+          
+          <el-table-column label="签收单" align="center">
+            <el-table-column prop="receivedCount" label="数量" width="80" align="center"></el-table-column>
+            <el-table-column prop="receivedAmount" label="金额" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.receivedAmount ? scope.row.receivedAmount.toFixed(2) : '0.00' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="receivedCountRatio" label="数量比%" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.receivedCountRatio ? scope.row.receivedCountRatio.toFixed(2) : '0.00' }}%
+              </template>
+            </el-table-column>
+            <el-table-column prop="receivedAmountRatio" label="金额比%" width="100" align="center">
+              <template slot-scope="scope">
+                {{ scope.row.receivedAmountRatio ? scope.row.receivedAmountRatio.toFixed(2) : '0.00' }}%
+              </template>
+            </el-table-column>
+          </el-table-column>
+        </el-table>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { getUserListByDeptId} from "@/api/company/companyUser";
+import { treeselect } from "@/api/company/companyDept";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import { getCompanyList } from "@/api/company/company";
+export default {
+  name: 'StoreOrderData',
+  components: {
+    Treeselect
+  },
+  data() {
+    return {
+      companys: [],
+      deptOptions: [],
+      companyId: undefined,
+      deptId: undefined,
+      userIds: undefined,
+      users: [],
+      dateRange: [],
+      options: [{
+        value: '1',
+        label: '今天'
+      }, {
+        value: '2',
+        label: '昨天'
+      }, {
+        value: '3',
+        label: '本周'
+      }, {
+        value: '4',
+        label: '上周'
+      }, {
+        value: '5',
+        label: '本月'
+      }, {
+        value: '6',
+        label: '上月'
+      }, {
+        value: '7',
+        label: '本季度'
+      }, {
+        value: '8',
+        label: '上季度'
+      }, {
+        value: '9',
+        label: '本年'
+      }, {
+        value: '10',
+        label: '上年'
+      }],
+      value: '5',
+      orderType: undefined,
+      orderMedium: undefined,
+      orderTypeOptions: [],
+      orderMediumOptions: [],
+      list: [],
+      dates: [],
+      orderCount: [],
+      payMoney: [],
+      tableData: [] // 新增表格数据
+    }
+  },
+    watch: {
+    // 监听deptId
+    'deptId': 'currDeptChange'
+    },
+   created() {
+    getCompanyList().then(response => {
+      this.companys = response.data;
+      if (this.companys != null && this.companys.length > 0) {
+        this.companyId = this.companys[0].companyId;
+        this.getTreeselect();
+      }
+    });
+    // 获取订单类型
+    this.getDicts("store_order_type").then((response) => {
+      this.orderTypeOptions = response.data;
+    });
+    // 媒体来源
+    this.getDicts("crm_customer_source").then((response) => {
+      this.orderMediumOptions = response.data;
+    });
+  },
+  methods: {
+    getUserListByDeptId() {
+      this.userIds = undefined;
+      var data = { deptId: this.deptId };
+      getUserListByDeptId(data).then(response => {
+        this.users = response.data;
+      });
+    },
+    // 获取表格合计行数据
+    getSummaries(param) {
+      const { columns, data } = param;
+      const sums = [];
+      if (data.length === 0) return sums;
+      
+      columns.forEach((column, index) => {
+        if (index === 0) {
+          sums[index] = '合计';
+          return;
+        }
+        
+        const values = data.map(item => Number(item[column.property]));
+        if (!values.every(value => isNaN(value))) {
+          const sum = values.reduce((prev, curr) => {
+            const value = Number(curr);
+            if (!isNaN(value)) {
+              return prev + curr;
+            } else {
+              return prev;
+            }
+          }, 0);
+          
+          sums[index] = sum.toFixed(2);
+        } else {
+          sums[index] = '';
+        }
+      });
+      
+      return sums;
+    },
+    currDeptChange(val) {
+      console.log(val)
+      this.deptId = val;
+      this.getUserListByDeptId();
+    },
+    // 模拟获取数据的方法
+    storeOrder() {
+      // 这里应该调用实际的API获取数据
+      // 示例数据格式如下:
+
+      console.log('模拟获取数据:', this.tableData);
+      
+      this.tableData = [
+        {
+          province: '北京市',
+          orderCount: 100,
+          orderAmount: 50000.00,
+          cancelCount: 5,
+          cancelAmount: 2500.00,
+          cancelCountRatio: 5.00,
+          cancelAmountRatio: 5.00,
+          shippedCount: 80,
+          shippedAmount: 40000.00,
+          shippedCountRatio: 80.00,
+          shippedAmountRatio: 80.00,
+          transitCount: 10,
+          transitAmount: 5000.00,
+          transitCountRatio: 10.00,
+          transitAmountRatio: 10.00,
+          returnCount: 3,
+          returnAmount: 1500.00,
+          returnCountRatio: 3.00,
+          returnAmountRatio: 3.00,
+          receivedCount: 75,
+          receivedAmount: 37500.00,
+          receivedCountRatio: 75.00,
+          receivedAmountRatio: 75.00
+        }
+      ];
+      
+    },
+    /** 查询部门下拉树结构 */
+    getTreeselect() {
+      var that = this;
+      var param = { companyId: this.companyId }
+      treeselect(param).then((response) => {
+        this.deptOptions = response.data;
+        console.log(this.deptOptions)
+        if (response.data != null && response.data.length > 0) {
+          this.deptId = response.data[0].id;
+          that.storeOrder()
+        }
+      });
+    },
+    companyChange(val) {
+      console.log(val);
+      this.companyId = val;
+      this.getTreeselect();
+    },
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.vue-treeselect {
+  width: 217px;
+  height: 36px;
+}
+
+.app-container {
+  border: 1px solid #e6e6e6;
+  padding: 12px;
+  
+  .app-content {
+    background-color: white;
+    
+    .title {
+      padding: 20px 30px 0px 30px;
+      font-size: 18px;
+      font-weight: bold;
+      color: black;
+    }
+    
+    .search-form {
+      margin: 20px 30px 0px 30px;
+    }
+    
+    .data-box {
+      padding: 30px;
+      background-color: rgb(255, 255, 255);
+      height: 100%;
+      
+      .echart-box {
+        margin: 0 auto;
+        text-align: center;
+      }
+      
+      .el-select {
+        margin: 5px 10px;
+      }
+      
+      .table-box {
+        margin-top: 15px;
+        
+        .export {
+          float: right;
+          margin: 10px 0px;
+        }
+      }
+      
+      // 新增表格样式
+      .table-container {
+        margin-top: 30px;
+        
+        .table-title {
+          font-size: 16px;
+          font-weight: bold;
+          color: #333;
+          margin-bottom: 10px;
+        }
+      }
+    }
+  }
+}
+
+// 表格相关样式优化
+::v-deep .el-table {
+  font-size: 12px;
+  
+  th {
+    background-color: #f5f7fa;
+  }
+  
+  td, th {
+    padding: 8px 0;
+  }
+}
+</style>

+ 320 - 0
src/views/hisStore/statistics/storePayment.vue

@@ -0,0 +1,320 @@
+<template>
+  <div class="app-container">
+      <div class="app-content">
+           <div class="title">
+              收款订单统计
+          </div>
+         <el-form class="search-form" :inline="true" >
+          <el-form-item >
+            <el-select v-model="value" placeholder="请选择日期">
+              <el-option
+                v-for="item in options"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="公司名" prop="companyId">
+              <el-select filterable v-model="companyId" @change="companyChange" placeholder="请选择公司名" clearable size="small">
+                  <el-option
+                    v-for="item in companys"
+                    :key="item.companyId"
+                    :label="item.companyName"
+                    :value="item.companyId"
+                  />
+            </el-select>
+          </el-form-item>
+          <el-form-item >
+            <treeselect :clearable="false"  v-model="deptId"  :options="deptOptions" :show-count="true" placeholder="请选择归属部门" />
+          </el-form-item>
+          <el-form-item>
+             <el-select filterable v-model="userIds" placeholder="请选择员工" clearable size="small">
+                <el-option
+                  v-for="item in users"
+                  :key="item.userId"
+                  :label="item.nickName"
+                  :value="item.userId">
+                </el-option>
+              </el-select>
+          </el-form-item>
+          <el-form-item label="筛选日期" prop="createTime">
+                  <el-date-picker clearable size="small" style="width: 205.4px"
+                    v-model="dateRange"
+                    type="daterange"
+                    value-format="yyyy-MM-dd"
+                    start-placeholder="开始日期" end-placeholder="结束日期"
+                    >
+                  </el-date-picker>
+                </el-form-item>
+          <el-form-item>
+              <el-button type="cyan" icon="el-icon-search"   @click="storePayment">搜索</el-button>
+          </el-form-item>
+        </el-form>
+         <div class="data-box">
+            <div class="echart-box">
+              <div id="echart-customer"></div>
+            </div>
+        </div>
+      </div>
+
+    </div>
+</template>
+
+<script>
+import { storePayment } from "@/api/hisStore/statistics";
+import { getUserListByDeptId} from "@/api/company/companyUser";
+import echarts from 'echarts'
+import resize from '../../dashboard/mixins/resize'
+import { treeselect } from "@/api/company/companyDept";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import { getCompanyList } from "@/api/company/company";
+export default {
+name: 'Index',
+mixins: [resize],
+components: { Treeselect },
+watch: {
+// 监听deptId
+'deptId': 'currDeptChange'
+},
+data() {
+return {
+ companys:[],
+ deptOptions:[],
+ companyId:undefined,
+ deptId:undefined,
+ userIds:undefined,
+ users:[],
+ dateRange:[],
+ chart: null,
+ options: [{
+    value: '1',
+    label: '今天'
+  }, {
+    value: '2',
+    label: '昨天'
+  }, {
+    value: '3',
+    label: '本周'
+  }, {
+    value: '4',
+    label: '上周'
+  }, {
+    value: '5',
+    label: '本月'
+  }
+  , {
+    value: '6',
+    label: '上月'
+  }
+  , {
+    value: '7',
+    label: '本季度'
+  }
+  , {
+    value: '8',
+    label: '上季度'
+  }
+  , {
+    value: '9',
+    label: '本年'
+  }
+  , {
+    value: '10',
+    label: '上年'
+  }],
+  value: '5',
+  list:[],
+  dates:[],
+  orderCount:[],
+  payMoney:[]
+
+
+}
+},
+created() {
+ getCompanyList().then(response => {
+  this.companys = response.data;
+  if(this.companys!=null&&this.companys.length>0){
+    this.companyId=this.companys[0].companyId;
+    this.getTreeselect();
+  }
+});
+},
+methods: {
+companyChange(val){
+console.log(val);
+this.companyId=val;
+this.getTreeselect();
+},
+currDeptChange(val){
+console.log(val)
+this.deptId=val;
+ this.getUserListByDeptId();
+},
+/** 查询部门下拉树结构 */
+getTreeselect() {
+var that=this;
+var param={companyId:this.companyId}
+treeselect(param).then((response) => {
+  this.deptOptions = response.data;
+  console.log(this.deptOptions)
+  if(response.data!=null&&response.data.length>0){
+    this.deptId=response.data[0].id;
+    that.storePayment()
+  }
+});
+},
+handleExport(){
+  var data;
+  if(this.userIds!=undefined){
+      data={type:this.value,userIds:this.userIds+"",deptId:this.deptId}
+  }
+  else{
+      data={type:this.value,deptId:this.deptId}
+  }
+  exportVoiceLogs(data).then((response) => {
+      console.log(response)
+     this.download(response.msg);
+  });
+
+},
+getUserListByDeptId() {
+  this.userIds=undefined;
+  var data={deptId:this.deptId};
+  getUserListByDeptId(data).then(response => {
+    this.users = response.data;
+
+  });
+},
+storePayment(){
+    var data;
+    if(this.userIds!=undefined){
+        data={type:this.value,userIds:this.userIds+"",deptId:this.deptId}
+    }
+    else{
+        data={type:this.value,deptId:this.deptId}
+    }
+    storePayment(data).then((response) => {
+      this.dates=response.dates;
+      this.orderCount=response.orderCount;
+      this.payMoney=response.payMoney;
+      setTimeout(() => {
+          this.initEchart();
+      }, 500);
+  });
+},
+initEchart(){
+  var option = {
+    tooltip: {
+        trigger: 'axis',
+        axisPointer: {            // 坐标轴指示器,坐标轴触发有效
+            type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
+        }
+    },
+    legend: {
+        data: ['订单数', '订单金额']
+    },
+    grid: {
+        left: '3%',
+        right: '4%',
+        bottom: '3%',
+        containLabel: true
+    },
+    xAxis: [
+        {
+            type: 'category',
+            data: this.dates
+        }
+    ],
+    yAxis: [
+        {
+            type: 'value',
+            axisLabel:{
+              formatter:'{value}个'
+            }
+        }
+    ],
+    series: [
+        {
+
+            name: '订单数',
+            type: 'bar',
+            emphasis: {
+                focus: 'series'
+            },
+            data: this.orderCount
+        },
+        {
+
+            name: '订单金额',
+            type: 'bar',
+            emphasis: {
+                focus: 'series'
+            },
+            data: this.payMoney
+        }
+    ]
+  };
+  this.chart=echarts.init(document.getElementById("echart-customer"));
+  this.chart.setOption(option,true);
+},
+}
+}
+</script>
+
+<style lang="scss" scoped>
+.app-container{
+border: 1px solid #e6e6e6;
+padding: 12px;
+
+.app-content{
+background-color: white;
+.title{
+  padding: 20px 30px 0px 30px;
+  font-size: 18px;
+  font-weight: bold;
+  color: black;
+
+}
+.search-form{
+  margin: 20px 30px 0px 30px;
+}
+.data-box{
+  padding: 30px;
+  background-color:  rgb(255, 255, 255);
+  height: 100%;
+
+  .echart-box{
+    margin: 0 auto;
+    text-align: center;
+  }
+  .el-select{
+    margin: 5px 10px;
+  }
+  .table-box{
+    margin-top: 15px;
+    .export{
+      float: right;
+      margin: 10px 0px;
+    }
+  }
+}
+}
+}
+#echart-customer{
+width:100%;
+height:320px
+}
+.vue-treeselect{
+width: 217px;
+height: 36px;
+}
+
+</style>
+<style>
+.vue-treeselect__control{
+display: block;
+}
+</style>

+ 512 - 0
src/views/hisStore/statistics/storeProduct.vue

@@ -0,0 +1,512 @@
+<template>
+  <div class="app-container">
+    <div class="app-content">
+      <div class="title">
+        产品销售统计
+      </div>
+
+      <el-form class="search-form" :inline="true">
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="时间:">
+              <el-select v-model="value" placeholder="请选择日期">
+                <el-option
+                  v-for="item in options"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+             <el-form-item label="公司名:" prop="companyId">
+              <el-select filterable v-model="companyId" @change="companyChange" placeholder="请选择公司名" clearable size="small">
+                <el-option
+                  v-for="item in companys"
+                  :key="item.companyId"
+                  :label="item.companyName"
+                  :value="item.companyId"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="部门:">
+              <treeselect :clearable="false" v-model="deptId" :options="deptOptions" :show-count="true" placeholder="请选择归属部门" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="员工:">
+              <el-select filterable v-model="userIds" placeholder="请选择员工" clearable size="small">
+                <el-option
+                  v-for="item in users"
+                  :key="item.userId"
+                  :label="item.nickName"
+                  :value="item.userId">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+
+
+
+
+
+        <el-form-item label="筛选日期" prop="createTime">
+          <el-date-picker clearable size="small" style="width: 205.4px"
+            v-model="dateRange"
+            type="daterange"
+            value-format="yyyy-MM-dd"
+            start-placeholder="开始日期" end-placeholder="结束日期">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="cyan" icon="el-icon-search" @click="storeProduct">搜索</el-button>
+        </el-form-item>
+      </el-form>
+
+      <div class="data-box">
+        <div class="echart-box">
+          <div id="echart-customer"></div>
+        </div>
+
+        <!-- 产品销售统计数据表格 -->
+        <div class="table-container">
+          <h3 class="table-title">产品销售汇总</h3>
+          <!-- <div class="export">
+            <el-button type="primary" @click="handleExport">导出数据</el-button>
+          </div> -->
+          <el-table
+            :data="tableData"
+            border
+            stripe
+            style="width: 100%; margin-top: 20px;"
+            :row-class-name="tableRowClassName"
+            :span-method="objectSpanMethod">
+
+            <!-- 产品名称列 -->
+            <el-table-column prop="name" label="产品名称" width="100" align="center" class-name="sticky-column">
+              <template slot-scope="scope">
+                <span :class="{'group-name': scope.row.isGroup}">{{ scope.row.name }}</span>
+              </template>
+            </el-table-column>
+
+            <!-- 动态生成订单类型列 - 使用多级表头 -->
+            <el-table-column
+              v-for="orderType in orderTypeOptions"
+              :key="orderType.dictValue"
+              :label="orderType.dictLabel"
+              align="center">
+
+              <!-- 数量子列 -->
+              <el-table-column
+                label="数量"
+                width="60"
+                align="center">
+                <template slot-scope="scope">
+                  {{ getOrderData(scope.row, orderType.dictValue, 'count') }}
+                </template>
+              </el-table-column>
+
+              <!-- 金额子列 -->
+              <el-table-column
+                label="金额"
+                width="80"
+                align="center">
+                <template slot-scope="scope">
+                  {{ getOrderData(scope.row, orderType.dictValue, 'amount') }}
+                </template>
+              </el-table-column>
+
+            </el-table-column>
+
+          </el-table>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { storeProduct } from "@/api/hisStore/statistics";
+import { getUserListByDeptId } from "@/api/company/companyUser";
+import echarts from 'echarts'
+import resize from '../../dashboard/mixins/resize'
+import { treeselect } from "@/api/company/companyDept";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import { getCompanyList } from "@/api/company/company";
+
+export default {
+  name: 'ContentStatistics',
+  mixins: [resize],
+  components: { Treeselect },
+  watch: {
+    // 监听deptId
+    'deptId': 'currDeptChange'
+  },
+  data() {
+    return {
+      companys: [],
+      deptOptions: [],
+      companyId: undefined,
+      deptId: undefined,
+      userIds: undefined,
+      users: [],
+      dateRange: [],
+      chart: null,
+      options: [{
+        value: '1',
+        label: '今天'
+      }, {
+        value: '2',
+        label: '昨天'
+      }, {
+        value: '3',
+        label: '本周'
+      }, {
+        value: '4',
+        label: '上周'
+      }, {
+        value: '5',
+        label: '本月'
+      }, {
+        value: '6',
+        label: '上月'
+      }, {
+        value: '7',
+        label: '本季度'
+      }, {
+        value: '8',
+        label: '上季度'
+      }, {
+        value: '9',
+        label: '本年'
+      }, {
+        value: '10',
+        label: '上年'
+      }],
+      value: '5',
+      list: [],
+      dates: [],
+      orderCount: [], // 修改变量名
+      payPrice: [], // 修改变量名
+      // 订单类型选项 - 用作表头
+      orderTypeOptions: [],
+      // 产品销售统计表格数据
+      tableData: []
+    }
+  },
+  created() {
+    getCompanyList().then(response => {
+      this.companys = response.data;
+      if (this.companys != null && this.companys.length > 0) {
+        this.companyId = this.companys[0].companyId;
+        this.getTreeselect();
+      }
+    });
+
+    // 获取订单类型字典
+    this.getDicts("store_order_type").then((response) => {
+      this.orderTypeOptions = response.data;
+    });
+  },
+  methods: {
+    companyChange(val) {
+      console.log(val);
+      this.companyId = val;
+      this.getTreeselect();
+    },
+    currDeptChange(val) {
+      console.log(val)
+      this.deptId = val;
+      this.getUserListByDeptId();
+    },
+    /** 查询部门下拉树结构 */
+    getTreeselect() {
+      var that = this;
+      var param = { companyId: this.companyId }
+      treeselect(param).then((response) => {
+        this.deptOptions = response.data;
+        console.log(this.deptOptions)
+        if (response.data != null && response.data.length > 0) {
+          this.deptId = response.data[0].id;
+          that.storeProduct()
+        }
+      });
+    },
+    handleExport() {
+      var data;
+      if (this.userIds != undefined) {
+        data = { type: this.value, userIds: this.userIds + "", deptId: this.deptId }
+      }
+      else {
+        data = { type: this.value, deptId: this.deptId }
+      }
+      // 导出产品销售统计数据
+      console.log('导出产品销售统计数据', data);
+    },
+    getUserListByDeptId() {
+      this.userIds = undefined;
+      var data = { deptId: this.deptId };
+      getUserListByDeptId(data).then(response => {
+        this.users = response.data;
+      });
+    },
+    storeProduct() {
+      var data;
+      if (this.userIds != undefined) {
+        data = { type: this.value, userIds: this.userIds + "", deptId: this.deptId }
+      }
+      else {
+        data = { type: this.value, deptId: this.deptId }
+      }
+      if(this.dateRange && this.dateRange.length > 0){
+        data.type = null
+        data.startTime = this.dateRange[0]
+        data.endTime = this.dateRange[1]
+      }
+
+      storeProduct(data).then((response) => {
+        this.dates = response.dates;
+        this.orderCount = response.orderCount;
+        this.payPrice = response.payPrice;
+
+        // 处理表格数据,补全缺失的订单类型数据
+        this.tableData = this.processTableData(response.tableData || []);
+
+        setTimeout(() => {
+          this.initEchart();
+        }, 500);
+      });
+    },
+
+    // 新增方法:处理表格数据,为每个产品补全所有订单类型的数据
+    processTableData(rawTableData) {
+      return rawTableData.map(item => {
+        // 创建一个新的 productCounts 对象,包含所有订单类型
+        const processedProductCounts = {};
+
+        // 遍历所有订单类型选项,为每个类型设置默认值
+        this.orderTypeOptions.forEach(orderType => {
+          const dictValue = orderType.dictValue;
+          if (item.productCounts && item.productCounts[dictValue]) {
+            // 如果原数据中存在该订单类型的数据,使用原数据
+            processedProductCounts[dictValue] = item.productCounts[dictValue];
+          } else {
+            // 如果原数据中不存在该订单类型的数据,设置默认值
+            processedProductCounts[dictValue] = {
+              count: 0,
+              amount: 0.0
+            };
+          }
+        });
+
+        return {
+          ...item,
+          productCounts: processedProductCounts
+        };
+      });
+    },
+
+    initEchart() {
+      var option = {
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          }
+        },
+        legend: {
+          data: ['订单数量', '金额']
+        },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '3%',
+          containLabel: true
+        },
+        xAxis: [
+          {
+            type: 'category',
+            data: this.dates
+          }
+        ],
+        yAxis: [
+          {
+            type: 'value',
+            axisLabel: {
+              formatter: '{value}'
+            }
+          }
+        ],
+        series: [
+          {
+            name: '订单数量',
+            type: 'bar',
+            emphasis: {
+              focus: 'series'
+            },
+            data: this.orderCount // 修改为正确的变量名
+          },
+          {
+            name: '金额',
+            type: 'bar',
+            emphasis: {
+              focus: 'series'
+            },
+            data: this.payPrice // 修改为正确的变量名
+          }
+        ]
+      };
+      this.chart = echarts.init(document.getElementById("echart-customer"));
+      this.chart.setOption(option, true);
+    },
+
+    // 修改获取订单数据的方法,适配新的数据结构
+    getOrderData(row, orderType, dataType) {
+      // 使用 productCounts 而不是 orderData
+      if (row.productCounts && row.productCounts[orderType]) {
+        const value = row.productCounts[orderType][dataType] || 0;
+        if (dataType === 'amount') {
+          return value.toFixed(2);
+        }
+        return value;
+      }
+      return dataType === 'amount' ? '0.00' : 0;
+    },
+
+    // 表格行样式
+    tableRowClassName({ row, rowIndex }) {
+      if (row.isGroup) {
+        return 'group-row';
+      }
+      return '';
+    },
+    // 表格合并方法
+    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+      return {
+        rowspan: 1,
+        colspan: 1
+      };
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.app-container {
+  border: 1px solid #e6e6e6;
+  padding: 12px;
+  .app-content {
+    background-color: white;
+    .title {
+      padding: 20px 30px 0px 30px;
+      font-size: 18px;
+      font-weight: bold;
+      color: black;
+    }
+    .search-form {
+      margin: 20px 30px 0px 30px;
+    }
+    .data-box {
+      padding: 30px;
+      background-color: rgb(255, 255, 255);
+      height: 100%;
+      .echart-box {
+        margin: 0 auto;
+        text-align: center;
+      }
+      .el-select {
+        margin: 5px 10px;
+      }
+      .table-box {
+        margin-top: 15px;
+        .export {
+          float: right;
+          margin: 10px 0px;
+        }
+      }
+      // 表格样式
+      .table-container {
+        margin-top: 30px;
+        .table-title {
+          font-size: 16px;
+          font-weight: bold;
+          color: #333;
+          margin-bottom: 10px;
+        }
+        .export {
+          float: right;
+          margin: 10px 0px;
+        }
+      }
+    }
+  }
+}
+
+#echart-customer {
+  width: 100%;
+  height: 320px;
+}
+
+.vue-treeselect {
+  width: 217px;
+  height: 36px;
+}
+
+// 表格相关样式
+::v-deep .group-row {
+  background-color: #e8f5e8 !important;
+  font-weight: bold;
+}
+
+::v-deep .group-name {
+  font-weight: bold;
+  color: #333;
+}
+
+::v-deep .el-table {
+  font-size: 12px;
+
+  .el-table__header-wrapper {
+    th {
+      background-color: #f5f7fa;
+      font-weight: bold;
+      color: #333;
+    }
+  }
+
+  .el-table__body-wrapper {
+    td {
+      padding: 8px 0;
+    }
+  }
+}
+
+::v-deep .sticky-column {
+  position: sticky;
+  left: 0;
+  z-index: 2;
+  background-color: white;
+
+  // 为表头也添加样式
+  &.is-header-column {
+    background-color: #f5f7fa;
+  }
+}
+
+// 确保表格容器允许sticky定位
+::v-deep .el-table__body-wrapper {
+  overflow-x: auto;
+}
+</style>
+
+<style>
+.vue-treeselect__control {
+  display: block;
+}
+</style>

+ 2 - 2
src/views/hisStore/storeProduct/index.vue

@@ -1546,8 +1546,8 @@ export default {
         if(this.form.tuiCateId!=null){
           this.form.tuiCateId = response.data.tuiCateId.toString();
         }
-
-        this.form.isDrug = response.data.isDrug ? response.data.isDrug.toString() : "1";
+        // this.form.isDrug = response.data.isDrug ? response.data.isDrug.toString() : "1";
+        this.form.isDrug = response.data.isDrug === 0 ? "0" : (response.data.isDrug ? response.data.isDrug.toString() : "1");
         if (this.form.drugImage != null) {
           this.drugImageArr = this.form.drugImage.split(",");
         }

+ 316 - 0
src/views/hisStore/userExtract/index.vue

@@ -0,0 +1,316 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+
+      <el-form-item label="会员昵称" prop="nickname">
+        <el-input
+
+          v-model="queryParams.nickname"
+          placeholder="请输入会员昵称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="手机号码" prop="phone">
+        <el-input
+
+          v-model="queryParams.phone"
+          placeholder="请输入手机号码"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="提交时间" prop="createTime">
+        <el-date-picker clearable size="small" style="width: 205.4px"
+          v-model="queryParams.createTime"
+          type="date"
+          value-format="yyyy-MM-dd"
+          placeholder="选择提交时间">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select style="width: 200px" v-model="queryParams.status" placeholder="请选择状态" clearable size="small" >
+         <el-option
+                v-for="item in statusOptions"
+                :key="item.dictValue"
+                :label="item.dictLabel"
+                :value="item.dictValue"
+              />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <!-- <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['store:userExtract:export']"
+        >导出</el-button>
+      </el-col>
+	  <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row> -->
+
+    <el-table  height="500" border v-loading="loading" :data="userExtractList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="ID" align="center" prop="id" />
+      <el-table-column label="会员昵称" align="center" prop="nickname" />
+      <el-table-column label="会员手机号" align="center" prop="phone" />
+      <el-table-column label="提现类型" align="center" prop="extractType" />
+      <!-- <el-table-column label="银行卡" align="center" prop="bankCode" />
+      <el-table-column label="开户地址" align="center" prop="bankAddress" />
+      <el-table-column label="支付宝账号" align="center" prop="alipayCode" /> -->
+      <el-table-column label="提现金额" align="center" prop="extractPrice" />
+      <el-table-column label="余额" align="center" prop="balance" />
+      <el-table-column label="审核原因" align="center" prop="failMsg" />
+      <el-table-column label="状态" align="center" prop="status" >
+          <template slot-scope="scope">
+              <el-tag prop="status" v-for="(item, index) in statusOptions"    v-if="scope.row.status==item.dictValue">{{item.dictLabel}}</el-tag>
+          </template>
+      </el-table-column>
+      <el-table-column label="提交时间" align="center" prop="createTime" />
+      <el-table-column label="审核时间" align="center" prop="updateTime" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            v-if="scope.row.status==0"
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleAudit(scope.row)"
+            v-hasPermi="['store:userExtract:audit']"
+          >审核</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改用户提现对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+
+        <el-form-item label="会员昵称" prop="nickname">
+          <el-input v-model="form.nickname" disabled   />
+        </el-form-item>
+        <el-form-item label="会员手机号" prop="phone">
+          <el-input v-model="form.phone" disabled />
+        </el-form-item>
+
+        <el-form-item label="提现金额" prop="extractPrice">
+          <el-input v-model="form.extractPrice" disabled placeholder="请输入提现金额" />
+        </el-form-item>
+
+        <el-form-item label="余额" prop="balance">
+          <el-input v-model="form.balance" disabled placeholder="请输入提现金额" />
+        </el-form-item>
+        <el-form-item label="审核状态">
+          <el-radio-group v-model="form.status">
+            <el-radio label="1">通过</el-radio>
+            <el-radio label="-1">驳回</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="审核原因" v-if="form.status==-1" prop="failMsg">
+          <el-input type="textarea" :row="5" v-model="form.failMsg" placeholder="请输入审核原因" />
+        </el-form-item>
+
+
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listUserExtract, getUserExtract, audit,delUserExtract, addUserExtract, updateUserExtract, exportUserExtract } from "@/api/hisStore/userExtract";
+
+export default {
+  name: "UserExtract",
+  data() {
+    return {
+      statusOptions:[],
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 用户提现表格数据
+      userExtractList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        userId: null,
+        realName: null,
+        extractType: null,
+        bankCode: null,
+        bankAddress: null,
+        alipayCode: null,
+        extractPrice: null,
+        mark: null,
+        balance: null,
+        failMsg: null,
+        failTime: null,
+        status: null,
+        wechat: null,
+        isDel: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        status: [
+          { required: true, message: "状态不能为空", trigger: "blur" }
+        ],
+        failMsg: [
+          { required: true, message: "原因不能为空", trigger: "blur" }
+        ],
+      }
+    };
+  },
+  created() {
+    this.getDicts("user_extract_status").then((response) => {
+      this.statusOptions = response.data;
+    });
+    this.getList();
+  },
+  methods: {
+    /** 查询用户提现列表 */
+    getList() {
+      this.loading = true;
+      listUserExtract(this.queryParams).then(response => {
+        this.userExtractList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        userId: null,
+        realName: null,
+        extractType: null,
+        bankCode: null,
+        bankAddress: null,
+        alipayCode: null,
+        extractPrice: null,
+        mark: null,
+        balance: null,
+        failMsg: null,
+        failTime: null,
+        createTime: null,
+        updateTime: null,
+        status: 0,
+        wechat: null,
+        isDel: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 修改按钮操作 */
+    handleAudit(row) {
+      this.reset();
+      const id = row.id;
+      console.log(id)
+      getUserExtract(id).then(response => {
+        this.form = response.data;
+        this.form.nickname=row.nickname
+        this.form.phone=row.phone
+        this.form.status="1"
+        this.open = true;
+        this.title = "审核提现";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          audit(this.form).then(response => {
+              if (response.code === 200) {
+                this.msgSuccess("操作成功");
+                this.open = false;
+                this.getList();
+              }
+          });
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm('是否确认删除用户提现编号为"' + ids + '"的数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return delUserExtract(ids);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(function() {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有用户提现数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return exportUserExtract(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+        }).catch(function() {});
+    }
+  }
+};
+</script>

+ 227 - 0
src/views/hisStore/userPromoterApply/index.vue

@@ -0,0 +1,227 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="会员昵称" prop="nickname">
+        <el-input
+          v-model="queryParams.nickname"
+          placeholder="请输入会员昵称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="手机号" prop="phone">
+        <el-input
+          v-model="queryParams.phone"
+          placeholder="请输入会员手机号"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+    <el-table  height="500" border v-loading="loading" :data="userPromoterApplyList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="ID" align="center" prop="applyId" />
+      <el-table-column label="会员昵称" align="center" prop="nickname" />
+      <el-table-column label="会员手机号" align="center" prop="phone" />
+      <el-table-column label="你为什么想成为果雨健康推广大使?"  align="center" prop="contentJson" >
+          <template slot-scope="scope">
+               {{JSON.parse(scope.row.contentJson).question1}}
+          </template>
+      </el-table-column>
+      <el-table-column label="你是否了解果雨健康推广大使?"  align="center" prop="contentJson" >
+          <template slot-scope="scope">
+               {{JSON.parse(scope.row.contentJson).question2}}
+          </template>
+      </el-table-column>
+      <el-table-column label="、你最有意向推广的产品是哪一款?"  align="center" prop="contentJson" >
+          <template slot-scope="scope">
+               {{JSON.parse(scope.row.contentJson).question3}}
+          </template>
+      </el-table-column>
+      <el-table-column label="提交时间" align="center" prop="createTime" />
+    </el-table>
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改推广员申请对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="会员ID" prop="userId">
+          <el-input v-model="form.userId" placeholder="请输入会员ID" />
+        </el-form-item>
+        <el-form-item label="提交内容" prop="contentJson">
+          <el-input v-model="form.contentJson" placeholder="请输入提交内容" />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listUserPromoterApply, getUserPromoterApply, delUserPromoterApply, addUserPromoterApply, updateUserPromoterApply, exportUserPromoterApply } from "@/api/hisStore/userPromoterApply";
+
+export default {
+  name: "UserPromoterApply",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 推广员申请表格数据
+      userPromoterApplyList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        userId: null,
+        contentJson: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询推广员申请列表 */
+    getList() {
+      this.loading = true;
+      listUserPromoterApply(this.queryParams).then(response => {
+        this.userPromoterApplyList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        applyId: null,
+        userId: null,
+        contentJson: null,
+        createTime: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.applyId)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加推广员申请";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const applyId = row.applyId || this.ids
+      getUserPromoterApply(applyId).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改推广员申请";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.applyId != null) {
+            updateUserPromoterApply(this.form).then(response => {
+              if (response.code === 200) {
+                this.msgSuccess("修改成功");
+                this.open = false;
+                this.getList();
+              }
+            });
+          } else {
+            addUserPromoterApply(this.form).then(response => {
+              if (response.code === 200) {
+                this.msgSuccess("新增成功");
+                this.open = false;
+                this.getList();
+              }
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const applyIds = row.applyId || this.ids;
+      this.$confirm('是否确认删除推广员申请编号为"' + applyIds + '"的数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return delUserPromoterApply(applyIds);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(function() {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有推广员申请数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return exportUserPromoterApply(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+        }).catch(function() {});
+    }
+  }
+};
+</script>

+ 660 - 0
src/views/statistics/member/index.vue

@@ -0,0 +1,660 @@
+<template>
+  <div class="member-statistics-page">
+  <!-- 会员统计页面容器 -->
+   <div class="member-statistics-container">
+    <!-- =================== 顶部查询区域 =================== -->
+      <el-form class="filter-container" :inline="true" :model="queryParams" ref="queryForm">
+        <div class="filter-item">
+          <!-- 按日/按月切换 -->
+          <el-radio-group v-model="queryParams.dateType" size="small" @input="handleChangeDateType">
+            <el-radio-button label="day">按每日</el-radio-button>
+            <el-radio-button label="month">按每月</el-radio-button>
+          </el-radio-group>
+        </div>
+
+        <div class="filter-item">
+          <!-- 日期选择器 -->
+          <el-date-picker
+            v-model="queryParams.dateRange"
+            :key="queryParams.dateType"
+            :type="queryParams.dateType === 'day' ? 'daterange' : 'monthrange'"
+            size="small"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            style="width: 260px;"
+            :clearable="false"
+          />
+        </div>
+
+        <!-- 经销商选择 -->
+        <el-form-item class="filter-item" label="经销商" prop="dealerId">
+          <!-- 经销商选择 -->
+          <el-select
+            v-model="queryParams.dealerId"
+            placeholder="请选择经销商"
+            size="small"
+            clearable filterable remote
+            :remote-method="loadCompanyOptions"
+            v-select-load-more="loadMoreCompanyOptions"
+            :loading="companyOptionsLoading"
+            @change="handleChangeDealer"
+            style="width: 140px;"
+          >
+            <el-option v-for="item in dealerOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item class="filter-item" label="群管" prop="groupId">
+          <!-- 分组选择 -->
+          <el-select
+            v-model="queryParams.groupId"
+            placeholder="请选择群管"
+            size="small"
+            clearable filterable remote
+            :remote-method="loadCompanyUserOptions"
+            v-select-load-more="loadMoreCompanyUserOptions"
+            :loading="companyUserOptionsLoading"
+            style="width: 140px;"
+          >
+            <el-option v-for="item in groupOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item class="filter-item" label="会员" prop="memberId">
+          <!-- 会员选择 -->
+          <el-select
+            v-model="queryParams.memberId"
+            placeholder="请选择会员"
+            size="small"
+            clearable filterable remote
+            :remote-method="loadUserOptions"
+            v-select-load-more="loadMoreUserOptions"
+            :loading="userOptionsLoading"
+            style="width: 140px;"
+          >
+            <el-option v-for="item in memberOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item class="filter-item" label="训练营" prop="trainerId">
+          <!-- 训练营选择 -->
+          <el-select
+            v-model="queryParams.trainerId"
+            placeholder="请选择训练营"
+            size="small"
+            clearable filterable remote
+            :remote-method="loadTrainerOptions"
+            v-select-load-more="loadMoreTrainerOptions"
+            :loading="trainerOptionsLoading"
+            @change="changeTrainer"
+            style="width: 140px;"
+          >
+            <el-option v-for="item in trainerOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item class="filter-item" label="营期" prop="campPeriod">
+          <!-- 营期选择 -->
+          <el-select
+            v-model="queryParams.campPeriod"
+            placeholder="请选择营期"
+            size="small"
+            clearable filterable remote
+            :remote-method="loadPeriodOptions"
+            v-select-load-more="loadMorePeriodOptions"
+            :loading="campPeriodOptionsLoading"
+            @change="changeCampPeriod"
+            style="width: 140px;"
+          >
+            <el-option v-for="item in campPeriodOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item class="filter-item" label="课程" prop="courseId">
+          <!-- 课程选择 -->
+          <el-select
+            v-model="queryParams.courseId"
+            placeholder="请选择课程"
+            size="small"
+            clearable filterable remote
+            :remote-method="loadCourseOptions"
+            v-select-load-more="loadMoreCourseOptions"
+            :loading="courseOptionsLoading"
+            style="width: 140px;"
+          >
+            <el-option v-for="item in courseOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item class="filter-item" label="手机号" prop="mobile">
+          <!-- 手机号输入框 -->
+          <el-input
+            v-model="queryParams.mobile"
+            placeholder="请输入手机号"
+            size="small"
+            clearable
+            style="width: 200px;"
+          />
+        </el-form-item>
+
+        <div class="filter-item">
+         <!-- 操作按钮组 -->
+         <el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">搜索</el-button>
+        </div>
+
+        <div class="filter-item" style="margin-left: auto; display: none;">
+         <el-button size="small">更换所属群管</el-button>
+         <el-button type="primary" size="small">导出全部</el-button>
+        </div>
+      </el-form>
+    </div>
+
+    <!-- =================== 表格数据展示区域 =================== -->
+    <div class="table-container">
+      <el-table
+        v-loading="loading"
+        :data="tableData"
+        border
+        style="width: 100%;"
+        show-summary
+        :summary-row-style="{ background: '#fafafa' }"
+      >
+        <!-- 选择列 -->
+        <el-table-column type="selection" width="50" align="center" />
+        <!-- 序号列 -->
+        <el-table-column label="序号" type="index" width="60" align="center" />
+        <!-- 统计日期列 -->
+        <el-table-column prop="statDate" label="统计日期" min-width="100" align="center" />
+        <!-- 会员名称列 -->
+        <el-table-column prop="nickName" label="会员名称" min-width="100" align="center" />
+        <!-- 手机号列 -->
+        <el-table-column prop="phone" label="手机号" min-width="100" align="center" />
+        <!-- 会员标签列 -->
+        <el-table-column prop="tag" label="会员标签" min-width="100" align="center" />
+        <!-- 所属群管列 -->
+        <el-table-column prop="companyUserName" label="所属群管" min-width="100" align="center" />
+        <!-- 所属经销商列 -->
+        <el-table-column prop="companyName" label="所属经销商" min-width="100" align="center" />
+        <!-- 观看课程列 -->
+        <el-table-column prop="count" label="观看课程" min-width="80" align="center" />
+        <!-- 完课课程列 -->
+        <el-table-column prop="overCount" label="完课课程" min-width="80" align="center" />
+        <!-- 完课率列 -->
+        <el-table-column prop="finishRate" label="完课率" min-width="80" align="center">
+          <template slot-scope="scope">
+            {{ getPercentage(scope.row.overCount,  scope.row.count) }}
+          </template>
+        </el-table-column>
+        <!-- 观看次数列 -->
+        <el-table-column prop="watchCount" label="观看次数" min-width="80" align="center" />
+        <!-- 完课次数列 -->
+        <el-table-column prop="overCount" label="完课次数" min-width="80" align="center" />
+        <!-- 视频率列 -->
+        <el-table-column prop="videoRate" label="视频率" min-width="80" align="center" >
+          <template slot-scope="scope">
+            {{ getPercentage(scope.row.overCount,  scope.row.watchCount) }}
+          </template>
+        </el-table-column>
+
+        <!-- 操作列 -->
+        <el-table-column label="操作" fixed="right" min-width="160" align="center">
+          <template slot-scope="scope">
+            <!-- 会员分析按钮 -->
+            <el-button type="text" size="small" style="color: #409EFF;">会员分析</el-button>
+            <!-- 红包记录按钮 -->
+            <el-button type="text" size="small" style="color: #409EFF;">红包记录</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination
+        v-show="queryParams.total > 0"
+        :total="queryParams.total"
+        :page.sync="queryParams.pageNum"
+        :limit.sync="queryParams.pageSize"
+        @pagination="getList"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import {dailyData} from '@/api/statistics/member'
+import {getCompanyListLikeName} from '@/api/company/company'
+import {getCompanyUserListLikeName} from '@/api/company/companyUser'
+import {getUserListLikeName} from '@/api/users/user'
+import {getCampListLikeName} from '@/api/course/userCourseCamp'
+import {getPeriodListLikeName} from '@/api/course/userCoursePeriod'
+import {getVideoListLikeName} from '@/api/course/userCourseVideo'
+import moment from "moment"
+
+export default {
+  // 组件名称
+  name: 'MemberStatistics',
+
+  // 组件数据
+  data() {
+    return {
+      // ============= 查询参数 =============
+      queryParams: {
+        dateType: 'day', // 日期类型:day-按日,month-按月
+        dateRange: [new Date(), new Date()], // 日期范围
+        dealerId: '', // 经销商ID
+        groupId: '', // 群组ID
+        memberId: '', // 会员ID
+        trainerId: '', // 训练官ID
+        campPeriod: '', // 营期
+        courseId: '', // 课程ID
+        mobile: '', // 手机号
+        pageNum: 1, // 当前页码
+        pageSize: 30, // 每页记录数
+        total: 0, // 总记录数
+      },
+
+      // ============= 页面状态 =============
+      loading: false, // 加载状态
+
+      // ============= 数据相关 =============
+      tableData: [], // 表格数据
+
+      // ============= 下拉选项数据 =============
+      companyOptionsParams: {
+        name: undefined,
+        hasNextPage: false,
+        pageNum: 1,
+        pageSize: 10
+      },
+      companyOptionsLoading: false,
+      dealerOptions: [], // 经销商选项
+      companyUserOptionsParams: {
+        name: undefined,
+        companyId: undefined,
+        hasNextPage: false,
+        pageNum: 1,
+        pageSize: 10
+      },
+      companyUserOptionsLoading: false,
+      groupOptions: [], // 群组选项
+      userOptionsParams: {
+        name: undefined,
+        hasNextPage: false,
+        pageNum: 1,
+        pageSize: 10
+      },
+      userOptionsLoading: false,
+      memberOptions: [], // 会员选项
+      trainerOptionsParams: {
+        name: undefined,
+        hasNextPage: false,
+        pageNum: 1,
+        pageSize: 10
+      },
+      trainerOptionsLoading: false,
+      trainerOptions: [], // 训练营选项
+      campPeriodOptionsParams: {
+        name: undefined,
+        campId: undefined,
+        hasNextPage: false,
+        pageNum: 1,
+        pageSize: 10
+      },
+      campPeriodOptionsLoading: false,
+      campPeriodOptions: [], // 营期选项
+      courseOptionsParams: {
+        name: undefined,
+        periodId: undefined,
+        hasNextPage: false,
+        pageNum: 1,
+        pageSize: 10
+      },
+      courseOptionsLoading: false,
+      courseOptions: [] // 课程选项
+    }
+  },
+
+  // ============= 生命周期钩子 =============
+  created() {
+    // 页面创建时初始化数据
+    this.getList() // 加载表格数据
+  },
+
+  // ============= 组件方法 =============
+  methods: {
+    getPercentage(part, total, precision = 2) {
+      if (total === 0) return '0%';
+      const percent = (part / total) * 100;
+      return percent.toFixed(precision) + '%';
+    },
+    /**
+     * 获取表格数据
+     * 根据查询参数从服务器获取会员统计数据
+     */
+    getList() {
+      this.loading = true // 显示加载中状态
+      // 模拟异步请求
+      let query = {
+        type: this.queryParams.dateType === 'day' ? 1 : 2,
+        startDate: moment(this.queryParams.dateRange[0]).format('YYYY-MM-DD'),
+        endDate: moment(this.queryParams.dateRange[1]).format('YYYY-MM-DD'),
+        companyId: this.queryParams.dealerId,
+        companyUserId: this.queryParams.groupId,
+        userId: this.queryParams.memberId,
+        phone: this.queryParams.mobile,
+        trainCampId: this.queryParams.trainerId,
+        periodId: this.queryParams.campPeriod,
+        videoId: this.queryParams.courseId,
+        pageNum: this.queryParams.pageNum,
+        pageSize: this.queryParams.pageSize
+      }
+      dailyData(query).then(response => {
+        if (response && response.code === 200) {
+          this.tableData = response.data.list
+          this.queryParams.total = response.data.total
+          this.loading = false // 隐藏加载中状态
+        }
+      })
+    },
+
+    // 切换日期类型
+    handleChangeDateType() {
+      this.queryParams.dateRange  = [new Date(), new Date()]
+
+      // 重新请求数据
+      this.getList()
+    },
+
+    /**
+     * 查询按钮点击事件
+     * 根据筛选条件重新查询数据
+     */
+    handleQuery() {
+      this.queryParams.pageNum = 1 // 重置为第一页
+      this.getList() // 重新获取数据
+    },
+
+    /**
+     * 重置查询条件
+     * 清空所有筛选条件并重新加载数据
+     */
+    resetQuery() {
+      // 重置所有查询条件
+      this.queryParams = {
+        dateType: 'day', // 重置日期类型为按天
+        dateRange: [], // 清空日期范围
+        publicId: '', // 清空公众号ID
+        dealerId: '', // 清空经销商ID
+        groupId: '', // 清空群组ID
+        memberId: '', // 清空会员ID
+        trainerId: '', // 清空训练官ID
+        campPeriod: '', // 清空营期
+        courseId: '', // 清空课程ID
+        mobile: '' // 清空手机号
+      }
+      this.getList() // 重新获取数据
+    },
+
+    // 加载经销商选项
+    loadCompanyOptions(query) {
+      this.dealerOptions = [];
+      if (query === '') {
+        return;
+      }
+
+      this.companyOptionsParams.pageNum = 1
+      this.companyOptionsParams.name = query
+      this.companyOptionsLoading = true;
+      this.getCompanyListLikeName()
+    },
+    getCompanyListLikeName() {
+      getCompanyListLikeName(this.companyOptionsParams).then(response => {
+        this.dealerOptions = [...this.dealerOptions, ...response.data.list]
+        this.companyOptionsParams.hasNextPage = response.data.hasNextPage
+        this.companyOptionsLoading = false;
+      });
+    },
+    loadMoreCompanyOptions() {
+      if (!this.companyOptionsParams.hasNextPage) {
+        return;
+      }
+
+      this.companyOptionsParams.pageNum += 1
+      this.getCompanyListLikeName()
+    },
+    handleChangeDealer(val) {
+      this.groupOptions = [];
+      this.companyUserOptionsLoading = true;
+      if (!val) {
+        this.companyUserOptionsParams.companyId = undefined
+        this.getCompanyUserListLikeName()
+        return
+      }
+
+      this.companyUserOptionsParams.companyId = val
+      this.companyUserOptionsParams.pageNum = 1
+      this.getCompanyUserListLikeName()
+    },
+
+    // 群组选项
+    loadCompanyUserOptions(query) {
+      this.groupOptions = [];
+      if (query === '') {
+        return;
+      }
+
+      this.companyUserOptionsParams.pageNum = 1
+      this.companyUserOptionsParams.name = query
+      this.companyUserOptionsLoading = true;
+      this.getCompanyUserListLikeName()
+    },
+    getCompanyUserListLikeName() {
+      getCompanyUserListLikeName(this.companyUserOptionsParams).then(response => {
+        this.groupOptions = [...this.groupOptions, ...response.data.list]
+        this.companyUserOptionsParams.hasNextPage = response.data.hasNextPage
+        this.companyUserOptionsLoading = false;
+      });
+    },
+    loadMoreCompanyUserOptions() {
+      if (!this.companyUserOptionsParams.hasNextPage) {
+        return;
+      }
+
+      this.companyUserOptionsParams.pageNum += 1
+      this.getCompanyUserListLikeName()
+    },
+
+    // 会员选项
+    loadUserOptions(query) {
+      this.memberOptions = [];
+      if (query === '') {
+        return;
+      }
+
+      this.userOptionsParams.pageNum = 1
+      this.userOptionsParams.name = query
+      this.userOptionsLoading = true;
+      this.getUserListLikeName()
+    },
+    getUserListLikeName() {
+      getUserListLikeName(this.userOptionsParams).then(response => {
+        this.memberOptions = [...this.memberOptions, ...response.data.list]
+        this.userOptionsParams.hasNextPage = response.data.hasNextPage
+        this.userOptionsLoading = false;
+      });
+    },
+    loadMoreUserOptions() {
+      if (!this.userOptionsParams.hasNextPage) {
+        return;
+      }
+
+      this.userOptionsParams.pageNum += 1
+      this.getUserListLikeName()
+    },
+
+    // 训练营选项
+    loadTrainerOptions(query) {
+      this.trainerOptions = [];
+      if (query === '') {
+        return;
+      }
+
+      this.trainerOptionsParams.pageNum = 1
+      this.trainerOptionsParams.name = query
+      this.trainerOptionsLoading = true;
+      this.getTrainerListLikeName()
+    },
+    getTrainerListLikeName() {
+      getCampListLikeName(this.trainerOptionsParams).then(response => {
+        this.trainerOptions = [...this.trainerOptions, ...response.data.list]
+        this.trainerOptionsParams.hasNextPage = response.data.hasNextPage
+        this.trainerOptionsLoading = false;
+      });
+    },
+    loadMoreTrainerOptions() {
+      if (!this.trainerOptionsParams.hasNextPage) {
+        return;
+      }
+
+      this.trainerOptionsParams.pageNum += 1
+      this.getTrainerListLikeName()
+    },
+    changeTrainer(val) {
+      this.campPeriodOptions = [];
+      this.campPeriodOptionsLoading = true;
+      if (!val) {
+        this.campPeriodOptionsParams.companyId = undefined
+        this.getPeriodListLikeName()
+        return
+      }
+
+      this.campPeriodOptionsParams.companyId = val
+      this.campPeriodOptionsParams.pageNum = 1
+      this.getPeriodListLikeName()
+    },
+
+    // 营期选项
+    loadPeriodOptions(query) {
+      this.campPeriodOptions = [];
+      if (query === '') {
+        return;
+      }
+
+      this.campPeriodOptionsParams.pageNum = 1
+      this.campPeriodOptionsParams.name = query
+      this.campPeriodOptionsLoading = true;
+      this.getPeriodListLikeName()
+    },
+    getPeriodListLikeName() {
+      getPeriodListLikeName(this.campPeriodOptionsParams).then(response => {
+        this.campPeriodOptions = [...this.campPeriodOptions, ...response.data.list]
+        this.campPeriodOptionsParams.hasNextPage = response.data.hasNextPage
+        this.campPeriodOptionsLoading = false;
+      });
+    },
+    loadMorePeriodOptions() {
+      if (!this.campPeriodOptionsParams.hasNextPage) {
+        return;
+      }
+
+      this.campPeriodOptionsParams.pageNum += 1
+      this.getPeriodListLikeName()
+    },
+    changeCampPeriod(val) {
+      this.courseOptions = []
+      this.courseOptionsLoading = true;
+      if (!val) {
+        this.courseOptionsParams.periodId = undefined
+        this.getCourseListLikeName()
+        return
+      }
+
+      this.courseOptionsParams.periodId = val
+      this.courseOptionsParams.pageNum = 1
+      this.getCourseListLikeName()
+    },
+
+    // 课程选项
+    loadCourseOptions(query) {
+      this.courseOptions = [];
+      if (query === '') {
+        return;
+      }
+
+      this.courseOptionsParams.pageNum = 1
+      this.courseOptionsParams.name = query
+      this.courseOptionsLoading = true;
+      this.getCourseListLikeName()
+    },
+    getCourseListLikeName() {
+      getVideoListLikeName(this.courseOptionsParams).then(response => {
+        this.courseOptions = [...this.courseOptions, ...response.data.list]
+        this.courseOptionsParams.hasNextPage = response.data.hasNextPage
+        this.courseOptionsLoading = false;
+      });
+    },
+    loadMoreCourseOptions() {
+      if (!this.courseOptionsParams.hasNextPage) {
+        return;
+      }
+
+      this.courseOptionsParams.pageNum += 1
+      this.getCourseListLikeName()
+    },
+  }
+}
+</script>
+
+<style scoped>
+.member-statistics-page {
+  padding: 10px;
+}
+/* 会员统计页面容器样式 */
+.member-statistics-container {
+  padding: 10px;
+  background-color: #fff;
+}
+
+/* 筛选区域样式 */
+.filter-container {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  background-color: #fff;
+  padding: 15px;
+  border-radius: 4px;
+}
+
+.filter-item {
+  margin-right: 15px;
+  margin-bottom: 10px;
+}
+
+/* 表格容器样式 */
+.table-container {
+  background-color: #FFF;
+  height: 72vh;
+}
+
+/* 表格深度样式 */
+::v-deep .el-table th {
+  color: #606266;
+  font-weight: bold;
+}
+
+::v-deep .el-table--border th, ::v-deep .el-table--border td {
+  border-right: 1px solid #EBEEF5;
+}
+
+::v-deep .el-table {
+  border: 1px solid #EBEEF5;
+  border-bottom: none;
+}
+
+::v-deep .el-input__inner {
+  border-radius: 4px;
+}
+
+::v-deep .el-button {
+  border-radius: 4px;
+}
+</style>

+ 261 - 0
src/views/statistics/report/index.vue

@@ -0,0 +1,261 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <!--<el-form-item label="下单日期" prop="payTime">
+        <el-date-picker
+          v-model="queryParams.payTime"
+          type="date"
+          size="small"
+          style="width: 205.4px"
+          value-format="yyyy-MM-dd"
+          placeholder="选择日期">
+        </el-date-picker>
+      </el-form-item>-->
+      <el-form-item label="公司名" prop="companyId">
+        <el-select filterable  v-model="queryParams.companyId" placeholder="请选择公司名"  clearable size="small">
+          <el-option
+            v-for="item in companys"
+            :key="item.companyId"
+            :label="item.companyName"
+            :value="item.companyId"
+          />
+        </el-select>
+      </el-form-item>
+      <!--<el-form-item label="是否共享客户" prop="status">
+          <el-select v-model="queryParams.status" placeholder="请选择是否共享客户" clearable size="small">
+              <el-option
+                v-for="dict in yseOrNoOptions"
+                :key="dict.dictValue"
+                :label="dict.dictLabel"
+                :value="dict.dictValue"
+              />
+        </el-select>
+      </el-form-item>-->
+      <el-form-item label="订单状态" prop="orderStatus">
+          <el-select v-model="queryParams.orderStatus" placeholder="订单请选择状态" clearable size="small">
+              <el-option
+                v-for="dict in orderStatusOptions"
+                :key="dict.dictValue"
+                :label="dict.dictLabel"
+                :value="dict.dictValue"
+              />
+        </el-select>
+      </el-form-item>
+
+      <el-form-item>
+        <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['crm:report:export']"
+        >导出</el-button>
+      </el-col>
+	  <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+    <!--<el-tabs type="card" v-model="activeName" @tab-click="handleClick">
+      <el-tab-pane label="日报表" name="1"></el-tab-pane>
+      <el-tab-pane label="总报表" name="2"></el-tab-pane>
+    </el-tabs>-->
+    <el-table height="500" border v-loading="loading" :data="reportList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="订单编号" align="center" prop="orderSn" />
+      <el-table-column label="成单金额" align="center" prop="money" />
+      <el-table-column label="支付时间" align="center" prop="payTime" />
+      <el-table-column label="订单状态" align="center" prop="orderStatus" >
+        <template slot-scope="scope">
+              <el-tag prop="status" v-for="(item, index) in orderStatusOptions"   v-if="scope.row.orderStatus==item.dictValue">{{item.dictLabel}}</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="客户名称" align="center" prop="userName" />
+       <el-table-column label="是否共享客户" align="center" prop="status" >
+        <template slot-scope="scope">
+              <el-tag prop="status" v-for="(item, index) in yseOrNoOptions"  :type="scope.row.status==1?'success':'danger'"  v-if="scope.row.status==item.dictValue">{{item.dictLabel}}</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="共享销售" align="center" prop="companyUserNames" />
+      <el-table-column label="分成比例(百分比)" align="center" prop="proportion" />
+      <el-table-column label="我的业绩" align="center" prop="myPerformance" />
+    </el-table>
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+  </div>
+</template>
+
+<script>
+import {getReport,exportReport} from "@/api/statistics/report"
+import { getCompanyList } from "@/api/company/company";
+export default {
+  name: "report",
+  data() {
+    return {
+      companys:[],
+      activeName:"1",
+      payTypeOptions:[],
+      statusOptions:[],
+      orderStatusOptions:[],
+      yseOrNoOptions:[],
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      dateRange: [],
+      // 充值表格数据
+      companyRechargeList: [],
+      reportList:[],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        companyId: null,
+        money: null,
+        rechargeNo: null,
+        payTime: null,
+        status: null,
+        orderStatus:null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+      },
+      recharge:{
+        open:false,
+        title:"后台充值"
+      },
+      // 表单校验
+      rechargeRules: {
+        money: [
+          { required: true, message: "充值金额不能为空", trigger: "blur" }
+        ],
+        imgs: [
+          { required: true, message: "凭证不能为空", trigger: "change" }
+        ],
+      },
+      // 表单参数
+      rechargeForm: {
+        money: 0,
+      },
+    };
+  },
+  created() {
+    getCompanyList().then(response => {
+      this.companys = response.data;
+      if(this.companys!=null&&this.companys.length>0){
+        this.companyId=this.companys[0].companyId;
+        //this.getTreeselect();
+      }
+    });
+    this.getDicts("company_pay_status").then((response) => {
+      this.statusOptions = response.data;
+    });
+    this.getDicts("common_order_status").then((response) => {
+      this.orderStatusOptions = response.data;
+    });
+    this.getDicts("sys_company_or").then((response) => {
+      this.yseOrNoOptions = response.data;
+    });
+    const today = new Date();
+    const y = today.getFullYear();
+    const m = String(today.getMonth() + 1).padStart(2, '0');
+    const d = String(today.getDate()).padStart(2, '0');
+    this.queryParams.payTime = `${y}-${m}-${d}`;
+    this.getList();
+  },
+  methods: {
+    /** 查询充值列表 */
+    getList() {
+      this.loading = true;
+      console.log(this.queryParams)
+      getReport(this.queryParams).then(response => {
+        this.reportList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    handleClick(tab, event) {
+      if (tab.name === "2") { // 总报表
+        this.queryParams.payTime = null;
+      } else if (tab.name === "1") { // 日报表
+        const today = new Date();
+        const y = today.getFullYear();
+        const m = String(today.getMonth() + 1).padStart(2, '0');
+        const d = String(today.getDate()).padStart(2, '0');
+        this.queryParams.payTime = `${y}-${m}-${d}`;
+      }
+      this.getList();
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        rechargeId: null,
+        companyId: null,
+        money: null,
+        rechargeNo: null,
+        createTime: null,
+        payTime: null,
+        status: 0
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.rechargeId)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所选日报数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return exportReport(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+        }).catch(function() {});
+    },
+  }
+};
+</script>

+ 8 - 0
src/views/system/config/config.vue

@@ -747,6 +747,14 @@
       <el-form-item   label="快递鸟地址url" prop="kdnAddressUrl">
           <el-input   v-model="form13.kdnAddressUrl"  label="请输入kdnAddressUrl"></el-input>
       </el-form-item>
+      <el-form-item label="最低定金金额" prop="shares">
+              <el-input-number v-model="form13.retainer" :min="100"   label="最低定金金额"></el-input-number>
+      </el-form-item>
+      <el-form-item   label="比率" prop="rate">
+          <el-input   v-model="form13.rate"  label="请输入比率">
+            <template slot="append">%</template>
+          </el-input>
+      </el-form-item>
       <el-form-item   label="是否开启erp">
           <el-switch
             v-model="form13.erpOpen"