Просмотр исходного кода

Merge branch 'refs/heads/master' into ScrmStores

chenguo 13 часов назад
Родитель
Сommit
d176d9233d
56 измененных файлов с 7970 добавлено и 717 удалено
  1. 39 0
      .env.prod-bly
  2. 1 1
      .env.prod-jzzx
  3. 2 2
      .env.prod-nmgyt
  4. 1 0
      package.json
  5. 14 0
      src/api/company/statistics.js
  6. 53 0
      src/api/his/articleViews.js
  7. 68 8
      src/api/his/complaint.js
  8. 53 0
      src/api/his/homeArticle.js
  9. 62 0
      src/api/his/homeCategory.js
  10. 53 0
      src/api/his/homeView.js
  11. 9 0
      src/api/his/user.js
  12. 8 8
      src/api/hisStore/city.js
  13. 7 7
      src/api/hisStore/integralGoods.js
  14. 6 6
      src/api/hisStore/menu.js
  15. 40 0
      src/api/hisStore/statistics.js
  16. 6 6
      src/api/hisStore/storeActivity.js
  17. 8 8
      src/api/hisStore/storeCoupon.js
  18. 6 6
      src/api/hisStore/storeCouponIssue.js
  19. 6 6
      src/api/hisStore/storeCouponIssueUser.js
  20. 6 6
      src/api/hisStore/storeCouponUser.js
  21. 62 0
      src/api/hisStore/userExtract.js
  22. 53 0
      src/api/hisStore/userPromoterApply.js
  23. 18 0
      src/api/statistics/report.js
  24. BIN
      src/assets/logo/bly_logo.png
  25. 1 1
      src/store/modules/user.js
  26. 365 0
      src/views/company/statistics/tuiMoney.vue
  27. 26 0
      src/views/components/his/packageDetails.vue
  28. 2 0
      src/views/components/his/storeOrderDetails.vue
  29. 31 0
      src/views/course/coursePlaySourceConfig/index.vue
  30. 1 1
      src/views/course/userWatchCourseStatistics/index.vue
  31. 1 0
      src/views/course/userWatchCourseTotalStatistics/index.vue
  32. 27 6
      src/views/course/videoResource/index.vue
  33. 200 0
      src/views/his/articleViews/index.vue
  34. 130 557
      src/views/his/complaint/index.vue
  35. 475 0
      src/views/his/complaint/template.vue
  36. 490 0
      src/views/his/homeArticle/index.vue
  37. 365 0
      src/views/his/homeCategory/index.vue
  38. 289 0
      src/views/his/homeView/index.vue
  39. 39 5
      src/views/his/package/index.vue
  40. 51 63
      src/views/his/storeOrder/order1.vue
  41. 3 3
      src/views/his/storeProduct/index.vue
  42. 6 6
      src/views/his/user/indexProject.vue
  43. 199 0
      src/views/hisStore/components/OrderSummaryTable.vue
  44. 498 0
      src/views/hisStore/statistics/orderstatatic.vue
  45. 537 0
      src/views/hisStore/statistics/storeOrder.vue
  46. 467 0
      src/views/hisStore/statistics/storeOrderData.vue
  47. 561 0
      src/views/hisStore/statistics/storeOrderStatistics.vue
  48. 320 0
      src/views/hisStore/statistics/storePayment.vue
  49. 512 0
      src/views/hisStore/statistics/storeProduct.vue
  50. 9 8
      src/views/hisStore/storeProduct/index.vue
  51. 265 0
      src/views/hisStore/userBill/index.vue
  52. 316 0
      src/views/hisStore/userExtract/index.vue
  53. 227 0
      src/views/hisStore/userPromoterApply/index.vue
  54. 660 0
      src/views/statistics/member/index.vue
  55. 261 0
      src/views/statistics/report/index.vue
  56. 55 3
      src/views/system/config/config.vue

+ 39 - 0
.env.prod-bly

@@ -0,0 +1,39 @@
+# 页面标题
+VUE_APP_TITLE =倍力优会员商城平台
+# 首页菜单标题
+VUE_APP_TITLE_INDEX =倍力优会员商城平台
+# 公司名称
+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

+ 1 - 1
.env.prod-jzzx

@@ -1,7 +1,7 @@
 # 页面标题
 VUE_APP_TITLE =九州在线管理系统
 # 首页菜单标题
-VUE_APP_TITLE_INDEX =九州在线
+VUE_APP_TITLE_INDEX =九州好医生
 # 公司名称
 VUE_APP_COMPANY_NAME =成都双流九州在线互联网医院有限公司
 # ICP备案号

+ 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
+  })
+}

+ 68 - 8
src/api/his/complaint.js

@@ -1,19 +1,79 @@
 import request from '@/utils/request'
 
+// 查询投诉模板列表
+export function listTemplate(query) {
+  return request({
+    url: '/his/template/list',
+    method: 'get',
+    params: query
+  })
+}
 
-// 查询用户投诉列表
-export function listComplaint(data) {
+// 查询投诉模板列表
+export function treeListTemplate(query) {
   return request({
-    url: '/user/complaint/list',
+    url: '/his/template/treeList',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询投诉模板详细
+export function getTemplate(id) {
+  return request({
+    url: '/his/template/' + id,
+    method: 'get'
+  })
+}
+
+// 新增投诉模板
+export function addTemplate(data) {
+  return request({
+    url: '/his/template',
     method: 'post',
     data: data
   })
 }
 
+// 修改投诉模板
+export function updateTemplate(data) {
+  return request({
+    url: '/his/template',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除投诉模板
+export function delTemplate(id) {
+  return request({
+    url: '/his/template/' + id,
+    method: 'delete'
+  })
+}
+
+// 导出投诉模板
+export function exportTemplate(query) {
+  return request({
+    url: '/his/template/export',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询用户投诉列表
+export function listComplaint(query) {
+  return request({
+    url: '/his/complaint/list',
+    method: 'get',
+    params: query
+  })
+}
+
 // 查询用户投诉详细
 export function getComplaint(id) {
   return request({
-    url: '/user/complaint/' + id,
+    url: '/his/complaint/' + id,
     method: 'get'
   })
 }
@@ -21,7 +81,7 @@ export function getComplaint(id) {
 // 新增用户投诉
 export function addComplaint(data) {
   return request({
-    url: '/user/complaint',
+    url: '/his/complaint',
     method: 'post',
     data: data
   })
@@ -30,7 +90,7 @@ export function addComplaint(data) {
 // 修改用户投诉
 export function updateComplaint(data) {
   return request({
-    url: '/user/complaint',
+    url: '/his/complaint',
     method: 'put',
     data: data
   })
@@ -39,7 +99,7 @@ export function updateComplaint(data) {
 // 删除用户投诉
 export function delComplaint(id) {
   return request({
-    url: '/user/complaint/' + id,
+    url: '/his/complaint/' + id,
     method: 'delete'
   })
 }
@@ -47,7 +107,7 @@ export function delComplaint(id) {
 // 导出用户投诉
 export function exportComplaint(query) {
   return request({
-    url: '/user/complaint/export',
+    url: '/his/complaint/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
+  })
+}

+ 9 - 0
src/api/his/user.js

@@ -73,6 +73,15 @@ export function exportUser(query) {
   })
 }
 
+// 导出项目用户
+export function exportListProject(query) {
+  return request({
+    url: '/his/user/exportListProject',
+    method: 'get',
+    params: query
+  })
+}
+
 // 获取小黑屋用户列表
 export function darkRoomList(query) {
   return request({

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

@@ -3,14 +3,14 @@ import request from '@/utils/request'
 // 查询城市列表
 export function listCity(query) {
   return request({
-    url: '/store/store/city/list',
+    url: '/store/city/list',
     method: 'get',
     params: query
   })
 }
 export function getAllList(query) {
   return request({
-    url: '/store/store/city/getAllList',
+    url: '/store/city/getAllList',
     method: 'get',
     params: query
   })
@@ -18,7 +18,7 @@ export function getAllList(query) {
 
 export function getCitys() {
   return request({
-    url: '/store/store/city/getCitys',
+    url: '/store/city/getCitys',
     method: 'get'
   })
 }
@@ -28,7 +28,7 @@ export function getCitys() {
 // 查询城市详细
 export function getCity(id) {
   return request({
-    url: '/store/store/city/' + id,
+    url: '/store/city/' + id,
     method: 'get'
   })
 }
@@ -36,7 +36,7 @@ export function getCity(id) {
 // 新增城市
 export function addCity(data) {
   return request({
-    url: '/store/store/city',
+    url: '/store/city',
     method: 'post',
     data: data
   })
@@ -45,7 +45,7 @@ export function addCity(data) {
 // 修改城市
 export function updateCity(data) {
   return request({
-    url: '/store/store/city',
+    url: '/store/city',
     method: 'put',
     data: data
   })
@@ -54,7 +54,7 @@ export function updateCity(data) {
 // 删除城市
 export function delCity(id) {
   return request({
-    url: '/store/store/city/' + id,
+    url: '/store/city/' + id,
     method: 'delete'
   })
 }
@@ -62,7 +62,7 @@ export function delCity(id) {
 // 导出城市
 export function exportCity(query) {
   return request({
-    url: '/store/store/city/export',
+    url: '/store/city/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
   })

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

@@ -0,0 +1,40 @@
+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
+  });
+}
+
+ export function storeOrderStatistics(params) {
+    return request({
+      url: '/store/store/statistics/storeOrderStatistics',
+      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
+  })
+}
+

BIN
src/assets/logo/bly_logo.png


+ 1 - 1
src/store/modules/user.js

@@ -10,7 +10,7 @@ const user = {
     roles: [],
     permissions: [],
     isAdmin: false,
-    medicalMallConfig: {medicalMall: false,statics: false,audit:false,resource:false}
+    medicalMallConfig: {medicalMall: false,statics: false,audit:false,resource:false,stores:false}
   },
 
   mutations: {

+ 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>

+ 26 - 0
src/views/components/his/packageDetails.vue

@@ -60,6 +60,15 @@
             :src="img"
             :preview-src-list="[img]">
         </el-image>
+    </el-descriptions-item>
+    <el-descriptions-item label="所属小程序">
+      <el-tag
+        v-for="name in appNames"
+        :key="name"
+        style="margin-right: 4px"
+      >
+        {{ name }}
+      </el-tag>
     </el-descriptions-item>
         </el-descriptions>
             </div>
@@ -116,6 +125,7 @@
 
 <script>
 import { listPackage, getPackage, delPackage, addPackage, updatePackage, exportPackage } from "@/api/his/package";
+import {list as getAppMallOptions} from '@/api/course/coursePlaySourceConfig';
   export default {
     name: "patientdetails",
     props:["data"],
@@ -129,6 +139,7 @@ import { listPackage, getPackage, delPackage, addPackage, updatePackage, exportP
        orOptions:[],
        packageTypeOptions: [],
        diseaseTypeOptions: [],
+       appMallOptions:[],
        // 是否删除字典
        isDelOptions: [],
        packageSubTypeOptions:[],
@@ -136,6 +147,15 @@ import { listPackage, getPackage, delPackage, addPackage, updatePackage, exportP
         productJson:[],
       }
     },
+    computed: {
+      appNames() {
+        if (!this.item.appIds) return [];
+        const ids = this.item.appIds.split(',');
+        return ids
+          .map(id => this.appMallOptions.find(opt => opt.appid === id)?.name)
+          .filter(Boolean); // 过滤掉找不到的
+      }
+    },
     created() {
      this.getDicts("sys_company_status").then(response => {
        this.statusOptions = response.data;
@@ -159,9 +179,15 @@ import { listPackage, getPackage, delPackage, addPackage, updatePackage, exportP
      this.getDicts("sys_prescribe_disease_type").then(response => {
        this.diseaseTypeOptions = response.data;
      });
+     this.getAppMallOptions();
 
     },
     methods: {
+      getAppMallOptions() {
+        getAppMallOptions({pageNum:1,pageSize:100,isMall:1}).then(response => {
+          this.appMallOptions = response.rows;
+        })
+      },
       getDetails(orderId) {
           this.item=null;
           getPackage(orderId).then(response => {

+ 2 - 0
src/views/components/his/storeOrderDetails.vue

@@ -694,6 +694,8 @@ import {getCitys} from "@/api/store/city";
           this.express = response.data;
           if(this.express!=null&&this.express.Traces!=null){
               this.traces=this.express.Traces
+          } else {
+            this.traces = []
           }
       });
     },

+ 31 - 0
src/views/course/coursePlaySourceConfig/index.vue

@@ -137,6 +137,11 @@
           <dict-tag  :options="typesOptions" :value="scope.row.type"/>
         </template>
       </el-table-column>
+      <el-table-column label="互医/商城小程序" align="center" prop="isMall" width="80px">
+        <template slot-scope="scope">
+          <el-tag prop="isMall" v-for="(item, index) in isMallOptions" v-if="scope.row.isMall==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">
@@ -203,6 +208,21 @@
         <el-form-item label="所属公司" prop="companyId">
           <treeselect v-model="form.companyId" :options="deptOptions" :normalizer="normalizer" placeholder="选择上级部门" />
         </el-form-item>
+        <el-form-item label="是否是互医/商城小程序" prop="isMall">
+          <el-select
+            v-model="form.isMall"
+            style="width: 220px"
+            clearable
+            size="small"
+          >
+            <el-option
+              v-for="item in isMallOptions"
+              :key="item.dictValue"
+              :label="item.dictLabel"
+              :value="item.dictValue"
+            />
+          </el-select>
+        </el-form-item>
         <el-form-item label="图标" prop="img">
           <image-upload v-model="form.img" :file-type='["png", "jpg", "jpeg"]' :limit="1"/>
         </el-form-item>
@@ -284,6 +304,16 @@ export default {
       list: [],
       total: 0,
       typesOptions: [],
+      isMallOptions:[
+        {
+          dictLabel: "是",
+          dictValue: 1
+        },
+        {
+          dictLabel: "否",
+          dictValue: 0
+        }
+      ],
       title: null,
       open: false,
       form: {},
@@ -454,6 +484,7 @@ export default {
     handleAdd() {
       this.reset()
       this.open = true
+        this.form.isMall = 0;
       this.title = "添加小程序配置"
     },
     handleUpdate(row) {

+ 1 - 1
src/views/course/userWatchCourseStatistics/index.vue

@@ -97,7 +97,7 @@
       <el-table-column label="正确人数" align="center" prop="answerRightNum" />
       <el-table-column label="正确率" align="center" prop="answerRightRatePercent" />
       <el-table-column label="红包领取个数" align="center" prop="redPacketNum" />
-      <el-table-column label="红包领取额" align="center" prop="redPacketAmount" />
+      <el-table-column label="红包领取额" align="center" prop="redPacketAmount" />
     </el-table>
 
     <pagination

+ 1 - 0
src/views/course/userWatchCourseTotalStatistics/index.vue

@@ -102,6 +102,7 @@
       <el-table-column label="完播人数" align="center" prop="completeWatchNum" />
       <el-table-column label="完播率" align="center" prop="completeWatchRatePercent" />
       <el-table-column label="红包领取个数" align="center" prop="redPacketNum" />
+      <el-table-column label="红包领取总额" align="center" prop="redPacketAmount" />
     </el-table>
 
     <pagination

+ 27 - 6
src/views/course/videoResource/index.vue

@@ -332,7 +332,7 @@
       </el-form>
       <div slot="footer" class="dialog-footer">
         <el-button @click="cancel">取消</el-button>
-        <el-button type="primary" @click="submitForm" :disabled="isUploading">
+        <el-button type="primary" @click="submitForm" :loading="add" :disabled="isUploading || add">
           {{ isUploading ? '上传中...' : '保存' }}
         </el-button>
       </div>
@@ -406,6 +406,11 @@
             {{ getTypeName(scope.row.typeId) }}
           </template>
         </el-table-column>
+        <el-table-column label="子分类" align="center" min-width="100">
+          <template slot-scope="scope">
+            {{ getTypeName(scope.row.typeSubId) }}
+          </template>
+        </el-table-column>
         <el-table-column label="关联项目" align="center" min-width="100">
           <template slot-scope="scope">
           <a
@@ -522,7 +527,7 @@
 
       <div class="dialog-footer">
         <el-button @click="cancelBatch">取 消</el-button>
-        <el-button type="primary" @click="submitBatchAdd">保 存</el-button>
+        <el-button type="primary" :loading="add" :disabled="add || isUploading" @click="submitBatchAdd">保 存</el-button>
       </div>
       <!-- 批量上传视频弹窗 -->
       <el-dialog
@@ -1098,9 +1103,10 @@ export default {
       this.$refs["form"].validate(valid => {
         if (valid) {
           if (this.add){
-            this.$message.warning("文件上传中,请稍后再试")
+            this.$message.warning("请勿重复提交")
             return
           }
+          this.add = true
 
           const params = Object.assign({}, this.form);
           params.projectIds = this.form.projectIds.join(',');
@@ -1111,7 +1117,7 @@ export default {
                 this.open = false;
                 this.getList();
               }
-            });
+            })
           } else {
             addVideoResource(params).then(response => {
               if (response.code === 200) {
@@ -1119,7 +1125,7 @@ export default {
                 this.open = false;
                 this.getList();
               }
-            });
+            })
           }
         }
       });
@@ -1418,6 +1424,7 @@ export default {
     /** 批量新增 */
     handleBatchAdd() {
       this.batchAddVisible = true;
+      this.add =false
       this.videoList = []; // 清空之前的视频列表
     },
     /** 批量修改 */
@@ -1490,12 +1497,24 @@ export default {
     },
     /** 提交批量添加 */
     submitBatchAdd() {
+      if (this.videoList.length === 0) {
+        this.$message.warning("请选择视频");
+        return;
+      }
+
       // 检查是否所有选中的视频都已上传完成
       const incompleteVideos = this.videoList.filter(item => (item.progress || 0) < 100);
       if (incompleteVideos.length > 0) {
         this.$message.warning('有未完成上传的视频,请先完成上传');
         return;
       }
+
+      if (this.add){
+        this.$message.warning("请勿重复提交")
+        return
+      }
+      this.add = true
+
       // 调用批量添加API
       const videoList = JSON.parse(JSON.stringify(this.videoList));
       videoList.forEach(item => {
@@ -1507,7 +1526,7 @@ export default {
           this.batchAddVisible = false;
           this.getList();
         }
-      });
+      })
     },
     /** 获取分类名称 */
     getTypeName(typeId) {
@@ -1720,6 +1739,7 @@ export default {
         return;
       }
 
+      this.isUploading = true;
       this.isProcessingBatch = true;
 
       while (this.uploadQueue.length > 0) {
@@ -1754,6 +1774,7 @@ export default {
       }
 
       this.isProcessingBatch = false;
+      this.isUploading = false;
       this.$message.success('所有视频上传队列处理完成!');
     },
 

+ 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>

+ 130 - 557
src/views/his/complaint/index.vue

@@ -10,6 +10,15 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
+      <!-- <el-form-item label="用户名字" prop="userName">
+        <el-input
+          v-model="queryParams.userName"
+          placeholder="请输入用户名字"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item> -->
       <el-form-item label="联系方式" prop="phone">
         <el-input
           v-model="queryParams.phone"
@@ -19,6 +28,7 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
+      <!-- 添加处理状态筛选 -->
       <el-form-item label="处理状态" prop="isHandle">
         <el-select
           v-model="queryParams.isHandle"
@@ -31,7 +41,7 @@
         </el-select>
       </el-form-item>
       <el-form-item label="投诉时间" prop="complaintTime">
-        <el-date-picker v-model="complaintTime" size="small" style="width: 220px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" @change="changeTime"></el-date-picker>
+            <el-date-picker v-model="complaintTime" size="small" style="width: 220px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" @change="changeTime"></el-date-picker>
       </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
@@ -40,6 +50,38 @@
     </el-form>
 
     <el-row :gutter="10" class="mb8">
+      <!-- <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['his:complaint:add']"
+        >新增</el-button>
+      </el-col> -->
+      <!-- <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['his:complaint:edit']"
+        >修改</el-button>
+      </el-col> -->
+      <!-- <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['his:complaint:remove']"
+        >删除</el-button>
+      </el-col> -->
       <el-col :span="1.5">
         <el-button
           type="warning"
@@ -57,53 +99,21 @@
     <el-table border v-loading="loading" :data="complaintList" @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="complaintType" >
-        <template slot-scope="scope">
-          <template v-for="item in complaintTypeOptions">
-            <el-tag v-if="item.dictValue === scope.row.complaintType" :key="item.dictValue">
-              {{ item.dictLabel }}
-            </el-tag>
-          </template>
-        </template>
-      </el-table-column>
-      <el-table-column label="投诉类型" align="center" prop="type" >
-        <template slot-scope="scope">
-            <dict-tag :options="typeOptions" :value="scope.row.type"/>
-        </template>
-      </el-table-column>
+      <el-table-column label="用户" align="center" prop="userName" />
+      <!-- <el-table-column label="联系方式" align="center" prop="phone" /> -->
       <el-table-column label="投诉时间" align="center" prop="createTime" />
-      <el-table-column
-        label="是否处理"
-        align="center"
-        prop="isHandlePlatform"
-        :render-header="renderHandleHeader"
-      >
-        <template slot-scope="scope">
-          <el-tag
-            :type="scope.row.isHandlePlatform == 1 ? 'success' : 'warning'"
-            disable-transitions
-          >
-            {{ formatHandleStatus(scope.row.isHandle) }}
-          </el-tag>
-        </template>
-      </el-table-column>
-      <el-table-column 
-        label="店铺是否处理"
-        align="center"
-        prop="isHandlePlatform"
-        :render-header="renderHandleHeader"
-      >
+      <!-- 修改处理状态列显示 -->
+      <el-table-column label="是否处理" align="center" prop="isHandle">
         <template slot-scope="scope">
           <el-tag
-            :type="(scope.row.isHandleStore == 1)? 'success' : 'warning'"
+            :type="scope.row.isHandle == 1 ? 'success' : 'warning'"
             disable-transitions
           >
             {{ formatHandleStatus(scope.row.isHandle) }}
           </el-tag>
         </template>
       </el-table-column>
-      <el-table-column label="备注" align="center" prop="remarks" />
+       <el-table-column label="备注" align="center" prop="remarks" />
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
           <el-button
@@ -113,6 +123,13 @@
             v-hasPermi="['his:complaint:edit']"
             @click="handleUpdate(scope.row)"
           >投诉详情</el-button>
+          <!-- <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['his:complaint:edit']"
+          >修改</el-button> -->
           <el-button
             size="mini"
             type="text"
@@ -133,238 +150,60 @@
     />
 
     <!-- 修改用户投诉对话框 -->
-    <el-dialog :title="title" :visible.sync="open" width="900px" append-to-body>
-      <!-- 修改tab-click事件处理器名称 -->
-      <el-tabs v-model="activeTab" type="card" @tab-click="handleClick">
-        <!-- 投诉详情标签页 -->
-        <el-tab-pane label="投诉详情" name="complaint">
-          <el-form ref="form" :model="form" :rules="rules" label-width="80px">
-            <el-form-item label="投诉内容" prop="name">
-              <el-input v-model="form.name" :disabled="true" />
-            </el-form-item>
-            <el-form-item label="详细内容" v-if="form.content && form.content!=''">
-              <el-input type="textarea" v-model="form.content" :disabled="true"/>
-            </el-form-item>
-            <el-form-item label="联系方式" prop="phone" v-if="form.phone && form.phone!=''">
-              <el-input v-model="form.phone" :disabled="true"/>
-            </el-form-item>
-            <el-form-item label="图片" v-if="form.images && form.images!=''">
-              <div v-for="(url, index) in imageUrls(form.images)" :key="index" class="image-container">
-                <el-image :src="url" :preview-src-list="[url]" style="width: 100px; height: 100px;"></el-image>
-              </div>
-            </el-form-item>
-            <!-- <el-form-item label="交易截图" v-if="form.tradeImage && form.tradeImage!=''">
-              <div v-for="(url, index) in imageUrls(form.tradeImage)" :key="index" class="image-container">
-                <el-image :src="url" :preview-src-list="[url]" style="width: 100px; height: 100px;"></el-image>
-              </div>
-            </el-form-item> -->
-            <el-form-item label="用户" prop="nickName">
-              <el-input v-model="form.nickName" :disabled="true"/>
-            </el-form-item>
-            <el-form-item label="是否处理" prop="isHandle">
-              <el-select v-model="form.isHandlePlatform" placeholder="请选择处理状态" :disabled="true">
-                <el-option label="未处理" :value="0"></el-option>
-                <el-option label="已处理" :value="1"></el-option>
-              </el-select>
-            </el-form-item>
-            <el-form-item label="备注" prop="remarks" >
-              <el-input type="textarea" v-model="form.remarks" :maxlength="250" :disabled="true"/>
-            </el-form-item>
-          </el-form>
-        </el-tab-pane>
-
-        <!-- 回复详情标签页 -->
-        <el-tab-pane label="回复详情" name="replies">
-          <div class="reply-section">
-            <!-- 添加回复表单 -->
-            <el-card class="add-reply-card" shadow="never">
-              <div slot="header">
-                <span>添加回复</span>
-              </div>
-              <el-form :model="replyForm" ref="replyForm" label-width="80px">
-                <el-form-item label="回复内容" prop="content" :rules="[{ required: true, message: '请输入回复内容', trigger: 'blur' }]">
-                  <el-input
-                    type="textarea"
-                    v-model="replyForm.content"
-                    placeholder="请输入回复内容"
-                    :rows="3"
-                    maxlength="500"
-                    show-word-limit
-                  />
-                </el-form-item>
-                
-                <!-- 添加图片上传功能 -->
-                <el-form-item label="上传图片" prop="images">
-                  <!-- <div class="image-upload-container">
-                     <el-upload
-                      ref="imageUpload"
-                      :action="uploadUrl"
-                      :show-file-list="false"
-                      :file-list="replyImageList"
-                      :on-success="handleSuccess"
-                      :before-upload="beforeUpload"
-                      :limit="4"
-                      list-type="picture-card"
-                      accept="image/*"
-                    >
-                      <i class="el-icon-plus"></i>
-                      <div slot="tip" class="el-upload__tip">
-                        最多上传4张图片,单张图片不超过2MB
-                      </div>
-                    </el-upload>
-                  </div> -->
-                  <ImageUpload v-model="replyForm.images" type="image" :num="4" :width="150" :height="150"/>  
-
-                </el-form-item>
-
-                <el-form-item>
-                  <el-button type="primary" size="small" @click="submitReply" :loading="replyLoading">
-                    <i class="el-icon-s-promotion"></i> 发送回复
-                  </el-button>
-                </el-form-item>
-              </el-form>
-            </el-card>
-
-            <!-- 回复列表 -->
-            <el-card class="reply-list-card" shadow="never">
-              <div slot="header">
-                <span>回复记录 ({{ replyTotal }}条)</span>
-              </div>
-              
-              <div v-loading="replyLoading" class="reply-list">
-                <div v-if="replyList.length === 0" class="empty-replies">
-                  <el-empty description="暂无回复记录" :image-size="100"></el-empty>
-                </div>
-                
-                <div v-else>
-                  <div v-for="reply in replyList" :key="reply.id" class="reply-item">
-                    <div class="reply-header">
-                      <div class="reply-user">
-                        <el-avatar :size="32" :src="reply.avatar || '/default-avatar.png'">
-                          {{ reply.userName ? reply.userName.charAt(0) : 'U' }}
-                        </el-avatar>
-                        <!-- <span class="user-name">{{ reply.userName || '系统管理员' }}</span> -->
-                        <el-tag size="mini" :type="reply.sendType != 1 ? 'success' : 'info'">
-                          {{ reply.sendType === 1 ? '用户' : reply.sendType === 2 ? '系统平台':'店铺平台' }}
-                        </el-tag>
-                      </div>
-                      <div class="reply-time">
-                        {{ reply.createTime }}
-                      </div>
-                    </div>
-                    <div class="reply-content">
-                      {{ reply.content }}
-                    </div>
-                    
-                    <!-- 显示回复中的图片 -->
-                    <div class="reply-images" v-if="reply.images && reply.images !== ''">
-                      <div v-for="(url, index) in imageUrls(reply.images)" :key="index" class="reply-image-container">
-                        <el-image 
-                          :src="url" 
-                          :preview-src-list="imageUrls(reply.images)" 
-                          style="width: 80px; height: 80px;"
-                          fit="cover"
-                        ></el-image>
-                      </div>
-                    </div>
-
-                    <div class="reply-actions" v-if="reply.userType === 'admin'">
-                      <el-button type="text" size="mini" @click="editReply(reply)">
-                        <i class="el-icon-edit"></i> 编辑
-                      </el-button>
-                      <el-button type="text" size="mini" @click="deleteReply(reply)" style="color: #f56c6c;">
-                        <i class="el-icon-delete"></i> 删除
-                      </el-button>
-                    </div>
-                  </div>
-                </div>
-              </div>
-
-              <!-- 回复分页 -->
-              <div class="reply-pagination" v-if="replyTotal > 0">
-                <el-pagination
-                  @size-change="handleReplySizeChange"
-                  @current-change="handleReplyCurrentChange"
-                  :current-page="replyQueryParams.pageNum"
-                  :page-sizes="[5, 10, 20]"
-                  :page-size="replyQueryParams.pageSize"
-                  layout="total, sizes, prev, pager, next, jumper"
-                  :total="replyTotal"
-                  small
-                />
-              </div>
-            </el-card>
+    <el-dialog :title="title" :visible.sync="open" width="700px" 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="name">
+          <el-input v-model="form.name" :disabled="true" />
+        </el-form-item>
+        <el-form-item label="详细内容" v-if="form.content && form.content!=''">
+          <el-input type="textarea" v-model="form.content" :disabled="true"/>
+        </el-form-item>
+        <el-form-item label="联系方式" prop="phone" v-if="form.phone && form.phone!=''">
+          <el-input v-model="form.phone"  :disabled="true"/>
+        </el-form-item>
+        <el-form-item label="图片" v-if="form.urls && form.urls!=''">
+          <div v-for="(url, index) in imageUrls(form.urls)" :key="index" class="image-container">
+            <el-image :src="url" :preview-src-list="[url]" style="width: 100px; height: 100px;"></el-image>
           </div>
-        </el-tab-pane>
-      </el-tabs>
-
-      <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="submitForm" v-if="activeTab === 'complaint' && form.id==null">确 定</el-button>
-        <el-button @click="cancel">取 消</el-button>
-      </div>
-    </el-dialog>
-
-
-    <!-- 编辑回复对话框 -->
-    <el-dialog title="编辑回复" :visible.sync="editReplyVisible" width="500px" append-to-body>
-      <el-form :model="editReplyForm" ref="editReplyForm" label-width="80px">
-        <el-form-item label="回复内容" prop="content" :rules="[{ required: true, message: '请输入回复内容', trigger: 'blur' }]">
-          <el-input
-            type="textarea"
-            v-model="editReplyForm.content"
-            placeholder="请输入回复内容"
-            :rows="4"
-            maxlength="500"
-            show-word-limit
-          />
+        </el-form-item>
+        <el-form-item label="交易截图" v-if="form.tradeImage && form.tradeImage!=''">
+          <!-- <ImageUpload v-model="form.tradeImage" type="image" :num="10" :width="150" :height="150" /> -->
+          <div v-for="(url, index) in imageUrls(form.tradeImage)" :key="index" class="image-container">
+            <el-image :src="url" :preview-src-list="[url]" style="width: 100px; height: 100px;"></el-image>
+          </div>
+        </el-form-item>
+        <el-form-item label="被投诉人信息" prop="account" v-if="form.account && form.account!=''">
+          <el-input v-model="form.account"  :disabled="true"/>
+        </el-form-item>
+        <!-- 修改处理状态为下拉选择 -->
+        <el-form-item label="是否处理" prop="isHandle">
+          <el-select v-model="form.isHandle" placeholder="请选择处理状态">
+            <el-option label="未处理" :value="0"></el-option>
+            <el-option label="已处理" :value="1"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="备注" prop="remarks">
+              <el-input type="textarea" v-model="form.remarks" :maxlength="250" />
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="updateReply" :loading="replyLoading">确 定</el-button>
-        <el-button @click="editReplyVisible = false">取 消</el-button>
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
       </div>
     </el-dialog>
   </div>
 </template>
 
 <script>
-import { listComplaint, getComplaint, delComplaint, addComplaint, updateComplaint, exportComplaint,listMsg,addMsg } from "@/api/his/complaint";
-import ImageUpload from '@/components/ImageUpload/index';
+import { listComplaint, getComplaint, delComplaint, addComplaint, updateComplaint, exportComplaint } from "@/api/his/complaint";
+
 export default {
   name: "Complaint",
-  components: {
-     ImageUpload
-  },
   data() {
     return {
-      replyImageList: [],
-      uploadUrl:process.env.VUE_APP_BASE_API+"/common/uploadOSS",
-      complaintId:null,
-      activeName:"0",
-      typeOptions:[
-        {
-          dictValue:'0',
-          dictLabel:'默认'
-        },
-        {
-          dictValue:'1',
-          dictLabel:'店铺'
-        },
-        {
-          dictValue:'2',
-          dictLabel:'商品'
-        },
-      ],
-      complaintTypeOptions:[
-        {
-          dictValue:1,
-          dictLabel:'咨询'
-        },
-        {
-          dictValue:2,
-          dictLabel:'投诉/举报'
-        },
-      ],
       complaintTime:null,
       // 遮罩层
       loading: true,
@@ -386,14 +225,12 @@ export default {
       title: "",
       // 是否显示弹出层
       open: false,
-      // 当前激活的标签页
-      activeTab: 'complaint',
       // 查询参数
       queryParams: {
         pageNum: 1,
         pageSize: 10,
         userId: null,
-        userName: null,
+        userName: null, // 添加用户名查询参数
         templateId: null,
         content: null,
         phone: null,
@@ -411,92 +248,43 @@ export default {
         templateId: [
           { required: true, message: "投诉模板id不能为空", trigger: "blur" }
         ],
-      },
-      // 回复相关数据
-      replyList: [],
-      replyTotal: 0,
-      replyLoading: false,
-      replyQueryParams: {
-        pageNum: 1,
-        pageSize: 10,
-        complaintId: null
-      },
-      replyForm: {
-        content: '',
-        complaintId: null
-      },
-      // 编辑回复
-      editReplyVisible: false,
-      editReplyForm: {
-        id: null,
-        content: ''
       }
     };
   },
   created() {
     this.getList();
   },
+
   methods: {
-    handleClick(tab) {
-      if (tab.name === 'replies') {
-        this.getReplyList();
-      }
-    },
-    renderHandleHeader(h, { column }) {
-      if (column.label === '是否处理') {
-        return h('div', [
-          '是否处理',
-          h('el-tooltip', {
-            props: {
-              content: '仅需要处理投诉/举报类',
-              placement: 'top'
-            }
-          }, [
-            h('i', {
-              class: 'el-icon-question',
-              style: 'margin-left: 5px; cursor: pointer; color: #909399;'
-            })
-          ])
-        ]);
-      } else if (column.label === '店铺是否处理') {
-        return h('div', [
-          '店铺是否处理',
-          h('el-tooltip', {
-            props: {
-              content: '仅需要处理咨询类',
-              placement: 'top'
-            }
-          }, [
-            h('i', {
-              class: 'el-icon-question',
-              style: 'margin-left: 5px; cursor: pointer; color: #909399;'
-            })
-          ])
-        ]);
-      }
-      return column.label;
-    },
     imageUrls(urls) {
       return String(urls).split(",");
     },
+    /**
+     * 格式化处理状态显示
+     * @param {Number} status - 处理状态 0:未处理 1:已处理
+     * @returns {String} - 格式化后的状态文本
+     */
     formatHandleStatus(status) {
       return status == 1 ? '已处理' : '未处理';
     },
+
     /** 查询用户投诉列表 */
     getList() {
       this.loading = true;
+      console.log(this.queryParams);
       listComplaint(this.queryParams).then(response => {
         this.complaintList = response.rows;
         this.total = response.total;
         this.loading = false;
       });
     },
+    
     // 取消按钮
     cancel() {
       this.open = false;
       this.reset();
-      this.resetReplyData();
     },
+    
     // 表单重置
     reset() {
       this.form = {
@@ -508,71 +296,54 @@ export default {
         urls: null,
         account: null,
         createTime: null,
-        isHandle: 0,
+        isHandle: 0, // 默认设置为未处理
         remarks:null
       };
       this.resetForm("form");
     },
-    // 重置回复数据
-    resetReplyData() {
-      this.activeTab = 'complaint';
-      this.replyList = [];
-      this.replyTotal = 0;
-      this.replyQueryParams = {
-        pageNum: 1,
-        pageSize: 10,
-        complaintId: null
-      };
-      this.replyForm = {
-        content: '',
-        complaintId: null,
-        images: '' // 重置图片字段
-      };
-      this.replyImageList = [];
-      this.editReplyImageList = [];
-    },
+    
     /** 搜索按钮操作 */
     handleQuery() {
       this.queryParams.pageNum = 1;
       this.getList();
     },
+    
     /** 重置按钮操作 */
     resetQuery() {
+      
       this.complaintTime = null;
       this.queryParams.complaintsTime=null;
       this.queryParams.complainteTime=null;
+      
       this.resetForm("queryForm");
       this.handleQuery();
     },
+    
     // 多选框选中数据
     handleSelectionChange(selection) {
       this.ids = selection.map(item => item.id)
       this.single = selection.length !== 1
       this.multiple = !selection.length
     },
+    
     /** 新增按钮操作 */
     handleAdd() {
       this.reset();
       this.open = true;
       this.title = "添加用户投诉";
     },
+    
     /** 修改按钮操作 */
     handleUpdate(row) {
       this.reset();
-      this.resetReplyData();
-      // const id = row.id || this.ids
-      const complaintId = row.id || this.complaintId
-      this.complaintId = complaintId;
-      getComplaint(complaintId).then(response => {
+      const id = row.id || this.ids
+      getComplaint(id).then(response => {
         this.form = response.data;
-        this.replyForm.complaintId = complaintId;
-        this.replyQueryParams.complaintId = complaintId;
         this.open = true;
         this.title = "投诉详情";
-        // 加载回复列表
-        this.getReplyList();
       });
     },
+    
     /** 提交按钮 */
     submitForm() {
       this.$refs["form"].validate(valid => {
@@ -593,6 +364,7 @@ export default {
         }
       });
     },
+    
     /** 删除按钮操作 */
     handleDelete(row) {
       const ids = row.id || this.ids;
@@ -607,6 +379,7 @@ export default {
           this.msgSuccess("删除成功");
         }).catch(() => {});
     },
+    
     /** 导出按钮操作 */
     handleExport() {
       const queryParams = this.queryParams;
@@ -623,216 +396,16 @@ export default {
         }).catch(() => {});
     },
     changeTime(){
-      if(this.complaintTime!=null){
-        this.queryParams.complaintsTime=this.complaintTime[0];
-        this.queryParams.complainteTime=this.complaintTime[1];
-      }else{
-        this.queryParams.complaintsTime=null;
-        this.queryParams.complainteTime=null;
-      }
-    },
-    // 获取回复列表
-    getReplyList() {
-      this.replyLoading = true;
-      // 模拟API调用 - 你需要替换为实际的API
-      setTimeout(() => {
-        // 模拟数据
-        listMsg(this.replyQueryParams).then(response => {
-              this.replyList = response.rows;
-              this.replyTotal = response.total;
-              this.replyLoading = false;
-            });
-      }, 500);
-    },
-    // 提交回复
-    submitReply() {
-      this.$refs.replyForm.validate(valid => {
-        if (valid) {
-          this.replyLoading = true;
-          // const imageUrls = this.replyImageList.map(file => file.url || file.response?.url).filter(url => url);
-          // this.replyForm.images = imageUrls.join(',');
-          // 模拟API调用
-          setTimeout(() => {
-            const newReply = {
-              content: this.replyForm.content,
-              complaintId:this.replyForm.complaintId,
-              images: this.replyForm.images, // 包含图片数据
-              sendType: 2
-            };
-            addMsg(newReply).then(response => {
-              this.replyLoading = false;
-              this.$message.success('回复发送成功');
-              this.replyForm.content = '';
-              this.replyForm.images = ''; // 重置图片字段
-              this.replyImageList = []; // 重置图片列表
-              this.getReplyList()
-            });
-            
-          }, 500);
+        if(this.complaintTime!=null){
+          this.queryParams.complaintsTime=this.complaintTime[0];
+          this.queryParams.complainteTime=this.complaintTime[1];
+        }else{
+          this.queryParams.complaintsTime=null;
+          this.queryParams.complainteTime=null;
         }
-      });
-    },
-    // 编辑回复
-    editReply(reply) {
-      this.editReplyForm = {
-        id: reply.id,
-        content: reply.content,
-        images: reply.images || '' // 包含图片数据
-      };
-      this.editReplyImageList = reply.images ? 
-        reply.images.split(',').map((url, index) => ({
-          uid: index,
-          name: `image-${index}`,
-          url: url
-        })) : [];
-      this.editReplyVisible = true;
-    },
-    
-    // 更新回复
-    updateReply() {
-      this.$refs.editReplyForm.validate(valid => {
-        if (valid) {
-          this.replyLoading = true;
-          // const imageUrls = this.editReplyImageList.map(file => file.url || file.response?.url).filter(url => url);
-          // this.editReplyForm.images = imageUrls.join(',');
-          
-          // 模拟API调用
-          setTimeout(() => {
-            const index = this.replyList.findIndex(item => item.id === this.editReplyForm.id);
-            if (index !== -1) {
-              this.replyList[index].content = this.editReplyForm.content;
-              this.replyList[index].images = this.editReplyForm.images; // 更新图片
-            }
-            this.editReplyVisible = false;
-            this.replyLoading = false;
-            this.$message.success('回复更新成功');
-          }, 500);
-        }
-      });
-    },
-    // 删除回复
-    deleteReply(reply) {
-      this.$confirm('确定要删除这条回复吗?', '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        type: 'warning'
-      }).then(() => {
-        const index = this.replyList.findIndex(item => item.id === reply.id);
-        if (index !== -1) {
-          this.replyList.splice(index, 1);
-          this.replyTotal--;
-          this.$message.success('删除成功');
-        }
-      });
-    },
-    // 回复分页大小改变
-    handleReplySizeChange(val) {
-      this.replyQueryParams.pageSize = val;
-      this.getReplyList();
-    },
-    // 回复当前页改变
-    handleReplyCurrentChange(val) {
-      this.replyQueryParams.pageNum = val;
-      this.getReplyList();
-    },
-    handleSuccess(res, file) {
-        if(res.code==200){
-          this.form.licenseImages=res.url;
-          this.$forceUpdate()
-        }
-        else{
-          this.msgError(res.msg);
-        }
-    },
-    
-    beforeUpload(file) {
-      const isLt1M = file.size / 1024 / 1024 < 1;
-      if (!isLt1M) {
-        this.$message.error('上传图片大小不能超过 1MB!');
-      }
-      return   isLt1M;
-    },
+        
+
+      },
   }
 };
-</script>
-
-<style scoped>
-.reply-section {
-  margin-top: 10px;
-}
-
-.add-reply-card {
-  margin-bottom: 20px;
-}
-
-.reply-list-card {
-  min-height: 400px;
-}
-
-.reply-list {
-  min-height: 300px;
-}
-
-.empty-replies {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  height: 200px;
-}
-
-.reply-item {
-  border-bottom: 1px solid #f0f0f0;
-  padding: 15px 0;
-}
-
-.reply-item:last-child {
-  border-bottom: none;
-}
-
-.reply-header {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  margin-bottom: 10px;
-}
-
-.reply-user {
-  display: flex;
-  align-items: center;
-  gap: 8px;
-}
-
-.user-name {
-  font-weight: 500;
-  color: #303133;
-}
-
-.reply-time {
-  color: #909399;
-  font-size: 12px;
-}
-
-.reply-content {
-  background-color: #f8f9fa;
-  padding: 12px;
-  border-radius: 6px;
-  margin-bottom: 8px;
-  line-height: 1.5;
-  color: #606266;
-}
-
-.reply-actions {
-  text-align: right;
-}
-
-.reply-pagination {
-  margin-top: 20px;
-  text-align: center;
-}
-
-.image-container {
-  display: inline-block;
-  margin-right: 10px;
-  margin-bottom: 10px;
-}
-</style>
+</script>

+ 475 - 0
src/views/his/complaint/template.vue

@@ -0,0 +1,475 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      
+      <el-form-item label="投诉分类" prop="name">
+        <el-input
+          v-model="queryParams.name"
+          placeholder="请输入投诉分类"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </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"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['his:template:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          :loading="exportLoading"
+          @click="handleExport"
+          v-hasPermi="['his:template: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="templateList"
+      row-key="id"
+      :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
+    >
+      <el-table-column label="ID" align="left" prop="id" />
+      <el-table-column label="投诉分类" align="left" prop="name" />
+      <el-table-column label="排序" sortable align="center" prop="sort" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            v-if="isLeafNode(scope.row)"
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleDesc(scope.row)"
+            v-hasPermi="['his:template:edit']"
+          >填写字段</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['his:template:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['his:template:remove']"
+          >删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <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="parentId">
+          <treeselect 
+            v-model="form.parentId" 
+            :options="categoryOptions" 
+            :show-count="true" 
+            :normalizer="normalizer" 
+            :disable-branch-nodes="false"
+            :searchable="true"
+            :clearable="true"
+            placeholder="请选择上级分类" 
+          />
+        </el-form-item>
+        <el-form-item label="投诉分类" prop="name">
+          <el-input v-model="form.name" placeholder="请输入标签名称" />
+        </el-form-item>
+        <el-form-item label="排序" prop="sort">
+          <el-input-number v-model="form.sort" 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>
+
+    <el-dialog title="选择填写字段" :visible.sync="descOpen" width="600px" append-to-body>
+      <!-- 添加表头说明 -->
+      <div class="field-header">
+        <div class="field-name-header">字段名称</div>
+        <div class="field-required-header">是否必填</div>
+      </div>
+      
+      <el-checkbox-group v-model="descForm">
+        <div v-for="(item, index) in fields" :key="index" class="field-item">
+          <div class="field-checkbox-wrapper">
+            <el-checkbox :label="item.label" name="desc" v-model="item.checked"></el-checkbox>
+          </div>
+          <div class="field-switch-wrapper">
+            <el-switch
+              v-model="item.isRequire"
+              active-value="1"
+              inactive-value="0"
+              :disabled="!item.checked"
+              class="require-switch"
+            ></el-switch>
+          </div>
+        </div>
+      </el-checkbox-group>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitDescForm">确 定</el-button>
+        <el-button @click="descCancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { treeListTemplate, listTemplate, getTemplate, delTemplate, addTemplate, updateTemplate, exportTemplate } from "@/api/his/complaint";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+
+export default {
+  name: "Template",
+  components: {
+    Treeselect
+  },
+  data() {
+    return {
+      descId: null,
+      fields: [
+        { label: "详细内容", checked: false, isRequire: 0, desc: "content",type:"文本框" },
+        { label: "联系方式", checked: false, isRequire: 0, desc: "phone",type:"文本框"},
+        { label: "上传图片", checked: false, isRequire: 0, desc: "urls",type:"图片" },
+        { label: "交易截图", checked: false, isRequire: 0, desc: "tradeImage",type:"图片" },
+        { label: "被投诉人账号信息", checked: false, isRequire: 0, desc: "account",type:"文本框" },
+      ],
+      descOpen: false,
+      categoryOptions: [],
+      loading: true,
+      exportLoading: false,
+      ids: [],
+      single: true,
+      multiple: true,
+      showSearch: true,
+      total: 0,
+      templateList: [],
+      title: "",
+      open: false,
+      queryParams: {
+        name: null,
+        isDel: null
+      },
+      form: {},
+      rules: {
+        parentId: [
+          { required: true, message: "上级编码不能为空", trigger: "blur" }
+        ],
+        sort: [
+          { required: true, message: "同级下排序不能为空", trigger: "blur" }
+        ],
+        name: [
+          { required: true, message: "投诉分类不能为空", trigger: "blur" }
+        ],
+      }
+    };
+  },
+  computed: {
+    descForm: {
+      get() {
+        return this.fields.filter(item => item.checked).map(item => item.label);
+      },
+      set(value) {
+        this.fields.forEach(item => {
+          item.checked = value.includes(item.label);
+        });
+      },
+    },
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /**
+     * 判断是否为叶子节点(最后一级)
+     */
+    isLeafNode(row) {
+      return !row.children || row.children.length === 0;
+    },
+
+    submitDescForm() {
+      const result = this.fields
+        .filter(item => item.checked)
+        .map(item => ({
+          name: item.label,
+          isRequire: item.isRequire,
+          desc: item.desc,
+          type: item.type,
+        }));
+      console.log("提交的数据:", result);
+      const param = { id: this.descId, description: JSON.stringify(result) }
+      updateTemplate(param).then(response => {
+        this.msgSuccess("修改成功");
+        this.descOpen = false;
+        this.getList();
+      });
+    },
+    
+    /** 转换标签数据结构 */
+    normalizer(node) {
+      if (node.children && !node.children.length) {
+        delete node.children;
+      }
+      return {
+        id: node.id,
+        label: node.name,
+        children: node.children
+      };
+    },
+    
+    /** 查询部门下拉树结构 */
+    getTreeselect() {
+      treeListTemplate().then(response => {
+        const rootOption = { id: 0, name: '根目录', children: response.data || [] };
+        this.categoryOptions = [rootOption];
+      });
+    },
+    
+    /** 查询投诉模板列表 */
+    getList() {
+      this.loading = true;
+      treeListTemplate(this.queryParams).then(response => {
+        this.templateList = response.data;
+        this.total = response.data.length;
+        this.loading = false;
+      });
+    },
+    
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    
+    descCancel() {
+      this.descOpen = false;
+      this.descReset();
+    },
+    
+    descReset() {
+      this.descForm = [];
+    },
+    
+    reset() {
+      this.form = {
+        id: null,
+        parentId: 0,
+        sort: null,
+        name: null,
+        updateTime: null,
+        createTime: null,
+        isDel: null
+      };
+      this.resetForm("form");
+    },
+    
+    handleQuery() {
+      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
+    },
+    
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.getTreeselect();
+      this.open = true;
+      this.title = "添加投诉模板";
+    },
+    
+    handleDesc(row) {
+      if (!this.isLeafNode(row)) {
+        this.msgWarning("只有最后一级分类才能配置填写字段");
+        return;
+      }
+      
+      this.descOpen = true;
+      this.descId = row.id
+      if (row.description) {
+        const description = JSON.parse(row.description);
+        
+        this.fields.forEach(field => {
+          // 修复:添加 return 语句或者直接使用箭头函数的简写形式
+          const found = description.find(item => item.name === field.label);
+          
+          if (found) {
+            field.checked = true;
+            field.isRequire = found.isRequire;
+          } else {
+            field.checked = false;
+            field.isRequire = 0;
+          }
+        });
+      } else {
+        // 重置所有字段
+        this.fields.forEach(field => {
+          field.checked = false;
+          field.isRequire = 0;
+        });
+      }
+      
+      // 添加调试信息,查看最终的 fields 状态
+      console.log("最终 fields 状态:", JSON.stringify(this.fields));
+    },
+    
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      this.getTreeselect();
+      const id = row.id || this.ids
+      getTemplate(id).then(response => {
+        this.form = response.data;
+        if (this.form.parentId === null || this.form.parentId === undefined) {
+          this.form.parentId = 0;
+        }
+        this.open = true;
+        this.title = "修改投诉模板";
+      });
+    },
+    
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateTemplate(this.form).then(response => {
+              this.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addTemplate(this.form).then(response => {
+              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 delTemplate(ids);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("删除成功");
+      }).catch(() => {});
+    },
+    
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有投诉模板数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        this.exportLoading = true;
+        return exportTemplate(queryParams);
+      }).then(response => {
+        this.download(response.msg);
+        this.exportLoading = false;
+      }).catch(() => {});
+    }
+  }
+};
+</script>
+
+<style scoped>
+/* 表头样式 */
+.field-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  margin-bottom: 15px;
+  padding: 10px 0;
+  border-bottom: 1px solid #e4e7ed;
+  font-weight: bold;
+  color: #606266;
+}
+
+.field-name-header {
+  flex: 1;
+  text-align: left;
+  padding-left: 20px;
+}
+
+.field-required-header {
+  width: 120px;
+  text-align: center;
+}
+
+/* 字段项样式 */
+.field-item {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  margin-bottom: 15px;
+  padding: 8px 0;
+  border-bottom: 1px solid #f0f0f0;
+}
+
+.field-checkbox-wrapper {
+  flex: 1;
+  display: flex;
+  align-items: center;
+}
+
+.field-checkbox-wrapper .el-checkbox {
+  margin-right: 20px;
+}
+
+.field-switch-wrapper {
+  width: 120px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.require-switch {
+  margin: 0;
+}
+
+/* 对话框内容区域样式调整 */
+.el-dialog__body {
+  padding: 20px;
+}
+</style>

+ 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>

+ 39 - 5
src/views/his/package/index.vue

@@ -91,6 +91,16 @@
           />
         </el-select>
       </el-form-item>
+      <el-form-item label="所属小程序" prop="appName" >
+        <el-select v-model="queryParams.appId" placeholder="请选择" clearable>
+          <el-option
+            v-for="dict in appMallOptions"
+            :key="dict.appid"
+            :label="dict.name + '(' + dict.appid + ')'"
+            :value="dict.appid"
+          />
+        </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>
@@ -538,6 +548,16 @@
                   />
           </el-select>
         </el-form-item>
+        <el-form-item label="所属小程序" prop="appId">
+          <el-select v-model="appId" placeholder="请选择所属小程序" clearable size="small" multiple>
+            <el-option
+              v-for="dict in appMallOptions"
+              :key="dict.appid"
+              :label="dict.name + '(' + dict.appid + ')'"
+              :value="dict.appid"
+            />
+          </el-select>
+        </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
         <el-button type="primary" @click="submitForm">确 定</el-button>
@@ -620,7 +640,8 @@ import { getToken } from "@/utils/auth";
 import Material from '@/components/Material'
 import ImageUpload from '@/components/ImageUpload'
 import { Loading } from 'element-ui';
-import { getOptions } from '@/api/his/packageSolarTerm'
+import { getOptions } from '@/api/his/packageSolarTerm';
+import {list as getAppMallOptions} from '@/api/course/coursePlaySourceConfig';
 export default {
   name: "Package",
   components: { packageDetails,Editor,productAttrValueSelect,Material },
@@ -634,6 +655,7 @@ export default {
   },
   data() {
     return {
+      appId:[],
       open1: false,
       form1:{},
       finalQuality:1,
@@ -718,6 +740,7 @@ export default {
       isDelOptions: [],
       packageSubTypeOptions:[],
       solarTermOptions: [],
+      appMallOptions:[],
       photoArr:[],
       // 查询参数
       queryParams: {
@@ -807,7 +830,8 @@ export default {
       this.privateTypeOptions = response.data.privateType;
     });
     this.getTemp();
-    this.getSolarTermOptions()
+    this.getSolarTermOptions(),
+    this.getAppMallOptions();
     listStore().then(response => {
       this.storeOPtions = response.rows;
     });
@@ -824,6 +848,11 @@ export default {
         this.solarTermOptions = response.data;
       })
     },
+    getAppMallOptions() {
+      getAppMallOptions({pageNum:1,pageSize:100,isMall:1}).then(response => {
+        this.appMallOptions = response.rows;
+      })
+    },
     handleUpdateMore(row){
       this.reset1();
       this.title = "批量修改套餐状态";
@@ -1105,6 +1134,7 @@ export default {
         if(this.form.followNum!=null ){
           this.form.followNum=JSON.stringify(this.form.followNum)
         }
+        this.appId=this.form.appIds ? this.form.appIds.split(',') : [];
         setTimeout(() => {
                   if(this.form.desc==null){
                     this.$refs.myeditor.setText("");
@@ -1138,14 +1168,18 @@ export default {
             this.form.productJson=JSON.stringify(this.drugList)
           }
           this.form.describeJson = JSON.stringify(this.describeJson);
-          if (this.form.packageId != null) {
-            updatePackage(this.form).then(response => {
+          const params = {
+            ...this.form,
+            appIds: this.appId.join(',') // 数组转字符串
+          };
+          if (params.packageId != null) {
+            updatePackage(params).then(response => {
               this.msgSuccess("修改成功");
               this.open = false;
               this.getList();
             });
           } else {
-            addPackage(this.form).then(response => {
+            addPackage(params).then(response => {
               this.msgSuccess("新增成功");
               this.open = false;
               this.getList();

+ 51 - 63
src/views/his/storeOrder/order1.vue

@@ -433,16 +433,38 @@
             >创建erp</el-button>
           </el-tooltip>
         </el-col>
-        <!-- <el-col :span="1.5">
-          <el-tooltip content="批量推送erp" placement="top">
-            <el-tag
-              plain
-              size="mini"
-              effect="plain"
-            v-hasPermi="['his:storeOrder:createErpOrder']"
-          >创建erp</el-tag>
-          </el-tooltip>
-        </el-col> -->
+        <el-col :span="1.5">
+          <el-button
+            disabled
+            plain
+            type="primary"
+            size="mini"
+        >应付金额: {{ payPriceTotal}}</el-button>
+      </el-col>
+        <el-col :span="1.5">
+          <el-button
+            disabled
+            plain
+            type="primary"
+            size="mini"
+        >实付金额: {{payMoneyTotal}}</el-button>
+        </el-col>
+        <el-col :span="1.5">
+          <el-button
+            disabled
+            plain
+            type="primary"
+            size="mini"
+        >物流代收金额: {{payRemainTotal }}</el-button>
+        </el-col>
+        <el-col :span="1.5">
+          <el-button
+            disabled
+            plain
+            type="primary"
+            size="mini"
+        >订单量/金额: {{ total }}/{{payPriceTotal }}</el-button>
+        </el-col>
         <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
       </el-row>
       <el-tabs type="card" v-model="actName" @tab-click="handleClickX">
@@ -523,6 +545,9 @@
           </template>
         </el-table-column>
       </el-table>
+      <div>
+        商品数量合计:{{ productInfo }}
+      </div>
       <pagination
         v-show="total>0"
         :total="total"
@@ -788,6 +813,10 @@ export default {
   },
   data() {
     return {
+      productInfo:"",
+      payPriceTotal:"0",
+      payMoneyTotal:"0",
+      payRemainTotal:"0",
       // 新增排序相关数据
       currentSort: {
         prop: null,
@@ -1178,6 +1207,18 @@ export default {
       listOrder(this.queryParams).then(response => {
         this.orderList = response.rows;
         this.total = response.total;
+        if(this.total>0){
+          this.payPriceTotal = response.payPriceTotal;
+          this.payMoneyTotal = response.payMoneyTotal;
+          this.payRemainTotal = response.payRemainTotal;
+          this.productInfo = response.productInfo;
+        } else {
+          this.payPriceTotal = "0"
+          this.payMoneyTotal = "0"
+          this.payRemainTotal = "0"
+          this.productInfo = response.productInfo;
+        }
+        
         this.loading = false;
         
         if(response.msg == 'jnmy'){
@@ -1798,59 +1839,6 @@ export default {
         this.storeOPtions = response.rows;
       });
     },
-    /** 查询订单列表 */
-    getList() {
-      this.loading = true;
-      if(this.payTypeArr.length>0){
-        this.queryParams.payType=this.payTypeArr.toString();
-      }
-      else{
-        this.queryParams.payType=null
-      }
-      if(this.scheduleIdArr.length>0){
-        this.queryParams.scheduleId=this.scheduleIdArr.toString();
-      }
-      else{
-        this.queryParams.scheduleId=null
-      }
-      if(this.buyTypeArr.length>0){
-        this.queryParams.orderBuyType=this.buyTypeArr.toString();
-      }
-      else{
-        this.queryParams.orderbuyType=null
-      }
-      if(this.channelArr.length>0){
-        this.queryParams.orderChannel=this.channelArr.toString();
-      }
-      else{
-        this.queryParams.orderChannel=null
-      }
-      if(this.qwSubjectArr.length>0){
-        this.queryParams.qwSubject=this.qwSubjectArr.toString();
-      }
-      else{
-        this.queryParams.qwSubject=null
-      }
-      if(this.companyIds && this.companyIds.length>1){
-        this.queryParams.companyIds = this.companyIds
-        this.queryParams.companyId = null;
-        this.queryParams.deptId = null;
-      } else {
-        this.queryParams.companyId = this.companyId
-        this.queryParams.companyIds = null;
-      }
-      listOrder(this.queryParams).then(response => {
-        this.orderList = response.rows;
-        this.total = response.total;
-        this.loading = false;
-        if(response.msg == 'jnmy'){
-          this.SFDFopen = true;
-        } else{
-          this.SFDFopen = false;
-        }
-      });
-
-    },
     // 取消按钮
     cancel() {
       this.open = false;

+ 3 - 3
src/views/his/storeProduct/index.vue

@@ -836,9 +836,9 @@ export default {
         specType: [
          { required: true, message: "规格不能为空", trigger: "blur" }
        ],
-        storeId: [
-         { required: true, message: "所属店铺不能为空", trigger: "blur" }
-       ],
+       //  storeId: [
+       //   { required: true, message: "所属店铺不能为空", trigger: "blur" }
+       // ],
         productType: [
          { required: true, message: "商品类型不能为空", trigger: "blur" }
        ],

+ 6 - 6
src/views/his/user/indexProject.vue

@@ -351,7 +351,7 @@
     <el-dialog title="更换会员归属" :visible.sync="changeCompanyUserOpen" width="500px" append-to-body>
       <el-form ref="changeCompanyUserForm" :model="changeCompanyUserForm" :rules="changeCompanyUserRules" label-width="100px">
         <el-form-item label="选择公司" prop="companyId">
-          <el-select v-model="changeCompanyUserForm.companyId" placeholder="请选择公司" style="width: 100%" @change="handleCompanyChange">
+          <el-select v-model="changeCompanyUserForm.companyId" placeholder="请选择公司" filterable style="width: 100%" @change="handleCompanyChange">
             <el-option
               v-for="item in companyOptions"
               :key="item.companyId"
@@ -361,7 +361,7 @@
           </el-select>
         </el-form-item>
         <el-form-item label="选择销售" prop="companyUserId">
-          <el-select v-model="changeCompanyUserForm.companyUserId" placeholder="请选择销售" style="width: 100%" @change="handleCompanyUserChange">
+          <el-select v-model="changeCompanyUserForm.companyUserId" placeholder="请选择销售" filterable style="width: 100%" @change="handleCompanyUserChange">
             <el-option
               v-for="item in companyUserOptions"
               :key="item.userId"
@@ -380,7 +380,7 @@
 </template>
 
 <script>
-import {listUserByProject, getUser, addUser, updateUser, exportUser, delUserCompanyUser} from "@/api/his/user";
+import {listUserByProject, getUser, addUser, updateUser, exportUser, delUserCompanyUser,exportListProject} from "@/api/his/user";
 import { getCompanyUserList, changeCompanyUser, getCompanyList } from '@/api/company/companyUser';
 import userDetailsByNew from '@/views/his/user/userDetails.vue'
 export default {
@@ -703,13 +703,13 @@ export default {
         cancelButtonText: "取消",
         type: "warning"
       }).then(function() {
-        return exportUser(queryParams);
+        return exportListProject(queryParams);
       }).then(response => {
         console.log(response)
         this.download(response.msg);
       }).catch(function() {});
-    }
-    ,handleShow(row){
+    },
+    handleShow(row){
       var that=this;
       that.show.open=true;
       setTimeout(() => {

+ 199 - 0
src/views/hisStore/components/OrderSummaryTable.vue

@@ -0,0 +1,199 @@
+<!-- src/components/OrderSummaryTable.vue -->
+<template>
+  <div class="table-container">
+    <h3 class="table-title">{{ title }}</h3>
+    <el-table
+      :data="tableData"
+      border
+      stripe
+      style="width: 100%; margin-top: 20px;"
+      :row-class-name="tableRowClassName"
+      :span-method="objectSpanMethod"
+      show-summary
+      :summary-method="getSummaries"
+      >
+      <el-table-column prop="name" :label="nameLable" width="150" class-name="sticky-column" align="center">
+        <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="completeOrders" label="成交数" width="120" align="center"></el-table-column>
+      <el-table-column prop="completeAmount" label="成交金额" width="130" align="center">
+        <template slot-scope="scope">
+          {{ scope.row.completeAmount ? scope.row.completeAmount.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>
+</template>
+
+<script>
+export default {
+  name: 'OrderSummaryTable',
+  props: {
+    title: {
+      type: String,
+      required: true
+    },
+    tableData: {
+      type: Array,
+      default: () => []
+    },
+    nameLable: {  // 新增 prop
+      type: String,
+      default: '姓名/工号'
+    }
+  },
+  watch: {
+    tableData: {
+      handler(newVal) {
+        console.log('接收到的tableData:', newVal);
+        console.log('tableData长度:', newVal ? newVal.length : 0);
+      },
+      immediate: true
+    }
+  },
+  mounted() {
+    console.log('组件挂载时的tableData:', this.tableData);
+    console.log('tableData长度:', this.tableData ? this.tableData.length : 0);
+  },
+  methods: {
+    // 表格行样式
+    tableRowClassName({ row, rowIndex }) {
+      if (row.isGroup) {
+        return 'group-row';
+      }
+      return '';
+    },
+    // 表格合并方法
+    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+      return {
+        rowspan: 1,
+        colspan: 1
+      };
+    },
+    // 合计方法
+    getSummaries(param) {
+      const { columns, data } = param;
+      const sums = [];
+      const sumFields = ['totalCalls', 'totalAmount', 'validAmount', 'waitingOrders', 'waitingAmount',
+        'unPassedOrders', 'unPassedAmount', 'cancelOrders', 'cancelAmount', 'completeOrders',
+        'completeAmount', 'unshippedOrders', 'unshippedAmount', 'shippedOrders', 'shippedAmount',
+        'transitOrders', 'transitAmount', 'receivedOrders', 'receivedAmount', 'returnOrders',
+        'returnAmount', 'paybackOrders', 'paybackAmount'];
+      
+      columns.forEach((column, index) => {
+        if (index === 0) {
+          sums[index] = '合计';
+          return;
+        }
+        
+        if (sumFields.includes(column.property)) {
+          const values = data.map(item => Number(item[column.property]));
+          if (!values.every(value => Number.isNaN(value))) {
+            const sum = values.reduce((prev, curr) => {
+              const value = Number(curr);
+              if (!Number.isNaN(value)) {
+                return prev + value;
+              } else {
+                return prev;
+              }
+            }, 0);
+            
+            // 对于金额字段保留两位小数
+            if (column.property && column.property.includes('Amount')) {
+              sums[index] = sum.toFixed(2);
+            } else {
+              sums[index] = sum;
+            }
+          } else {
+            sums[index] = '0';
+          }
+        } else {
+          sums[index] = '';
+        }
+      });
+
+      return sums;
+    }
+  } 
+}
+</script>
+
+<style scoped>
+.table-container {
+  margin-top: 30px;
+}
+
+.table-title {
+  font-size: 16px;
+  font-weight: bold;
+  color: #333;
+  margin-bottom: 10px;
+}
+</style>

+ 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>

+ 561 - 0
src/views/hisStore/statistics/storeOrderStatistics.vue

@@ -0,0 +1,561 @@
+<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="true"  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-row :gutter="20">
+          <el-col :span="6">
+            <!-- 查询方式 下单时间 发货时间 -->
+            <el-form-item label="下单时间:">
+              <el-select v-model="queryType" placeholder="查询方式" size="small">
+                <el-option
+                  v-for="item in queryTypes"
+                  :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="筛选日期" prop="createTime">
+              <el-date-picker clearable size="small" style="width: 220px"
+                v-model="dateRange"
+                type="daterange"
+                value-format="yyyy-MM-dd"
+                        start-placeholder="开始日期" end-placeholder="结束日期"
+                        >
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <!-- 实收金额 金额等于0 金额大于0 -->
+            <el-form-item label="实收金额:">
+              <el-select v-model="amountType" placeholder="请选择金额" clearable size="small">
+                <el-option
+                  v-for="item in amountTypes"
+                  :key="item.dictLabel"
+                  :label="item.dictLabel"
+                  :value="item.dictValue">
+                </el-option>
+              </el-select>
+            </el-form-item>
+
+          </el-col>
+          <el-col :span="6">
+
+          </el-col>
+        </el-row>
+
+
+        
+        <el-form-item>
+                    <el-button type="primary" icon="el-icon-search" plain   @click="storeOrderStatistics">搜索</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">
+          <!-- 使用组件替换原有表格 -->
+          <order-summary-table 
+            title="员工下单汇总" 
+            :table-data="tableData" 
+            nameLable="员工姓名" />
+            
+          <order-summary-table 
+            title="公司下单汇总" 
+            :table-data="companyTableData" 
+            nameLable="公司" />
+            
+          <order-summary-table 
+            title="部门下单汇总" 
+            :table-data="deptTableData" 
+            nameLable="部门"/>
+        </div>
+      </div>
+    </div>
+
+  </div>
+</template>
+
+<script>
+import OrderSummaryTable from '../components/OrderSummaryTable';
+import { storeOrderStatistics } 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: 'storeOrderStatatic',
+  mixins: [resize],
+  components: { Treeselect,OrderSummaryTable },
+  watch: {
+    // 监听deptId
+    'deptId': 'currDeptChange'
+  },
+  data() {
+    return {
+      queryTypes:[
+        { dictLabel: '下单时间', dictValue: 1 },
+        { dictLabel: '发货时间', dictValue: 2 }
+      ],
+      amountTypes:[
+        { dictLabel: '金额等于0', dictValue: 1 },
+        { dictLabel: '金额大于0', dictValue: 2 }
+      ],
+      queryType: 1,
+      amountType: null,
+      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: [],        // 员工下单汇总
+      companyTableData: [], // 公司下单汇总
+      deptTableData: []     // 部门下单汇总
+    }
+  },
+  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.storeOrderStatistics()
+        }
+      });
+    },
+    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;
+      });
+    },
+    storeOrderStatistics() {
+      var data={};
+      if(this.value){
+        data.type = this.value
+      }
+      if(this.userIds){
+        data.companyUserId = this.userIds
+      }
+
+      if(this.queryType){
+        data.queryType = this.queryType
+      }
+      if(this.amountType){
+        data.amountType = this.amountType
+      }
+
+      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
+      }
+      if(this.companyId){
+        data.companyId = this.companyId
+      }
+      if(this.deptId){
+        data.deptId = this.deptId
+      }
+      storeOrderStatistics(data).then((response) => {
+        this.dates = response.dates;
+        this.orderCount = response.orderCount;
+        this.payPrice = response.payPrice;
+        //表格数据
+        this.tableData = response.userTableData || [];
+        this.companyTableData = response.companyTableData || [];
+        this.deptTableData = response.deptTableData || [];
+
+        // 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;
+  height: calc(100vh - 24px); // 设置容器高度
+  display: flex;
+  flex-direction: column;
+  
+  .app-content {
+    background-color: white;
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+    
+    .title {
+      padding: 20px 30px 0px 30px;
+      font-size: 18px;
+      font-weight: bold;
+      color: black;
+    }
+    
+    .search-form {
+      margin: 20px 30px 0px 30px;
+      position: sticky;
+      top: 0;
+      background-color: white;
+      z-index: 100;
+      padding: 20px 30px 0px 30px;
+      margin: 0 30px;
+      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+      flex-shrink: 0; // 防止收缩
+    }
+    
+    .data-box {
+      padding: 30px;
+      background-color: rgb(255, 255, 255);
+      flex: 1;
+      overflow-y: auto; // 添加垂直滚动条
+      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>

+ 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>

+ 9 - 8
src/views/hisStore/storeProduct/index.vue

@@ -47,7 +47,7 @@
           />
         </el-select>
       </el-form-item>
-      <el-form-item label="所属店铺">
+      <el-form-item label="所属店铺" v-if="this.isStores">
         <el-select style="width: 240px" v-model="queryParams.storeIds" placeholder="请选择店铺" clearable size="small" >
           <el-option
             v-for="item in storeOptions"
@@ -296,7 +296,7 @@
       <el-table-column label="商品名称" show-overflow-tooltip align="center" prop="productName" />
       <el-table-column label="分类" align="center" prop="cateName" />
       <el-table-column label="所属公司" align="center" prop="companyName" />
-      <el-table-column label="所属店铺" align="center" prop="storeName" />
+      <el-table-column label="所属店铺" align="center" prop="storeName" v-if="this.isStores"/>
       <el-table-column label="售价" align="center" prop="price" >
         <template slot-scope="scope" >
           <span v-if="scope.row.price!=null">{{scope.row.price.toFixed(2)}}</span>
@@ -837,7 +837,7 @@
             />
           </el-select>
         </el-form-item>
-        <el-form-item label="所属店铺" prop="storeId">
+        <el-form-item label="所属店铺" prop="storeId" v-if="this.isStores">
           <el-select style="width: 240px" v-model="form.storeId" placeholder="请选择店铺" clearable size="small" >
             <el-option
               v-for="item in storeOptions"
@@ -941,6 +941,7 @@ export default {
   data() {
     return {
       isMedicalMall: this.$store.state.user.medicalMallConfig.medicalMall,
+      isStores: this.$store.state.user.medicalMallConfig.stores,
       companyId: null,
       storeId: null,
       isAudit: null,
@@ -1149,9 +1150,9 @@ export default {
         precautions: [
           { required: true, message: "注意事项不能为空", trigger: "blur" }
         ],
-        storeId :[
-          { required: true, message: "所属店铺不能为空", trigger: "blur"}
-        ],
+        // storeId :[
+        //   { required: true, message: "所属店铺不能为空", trigger: "blur"}
+        // ],
       }
     };
   },
@@ -1555,8 +1556,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(",");
         }

+ 265 - 0
src/views/hisStore/userBill/index.vue

@@ -0,0 +1,265 @@
+<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="创建时间">
+        <el-date-picker v-model="dateRange" size="small" style="width: 205.4px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
+      </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:userBill: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="userBillList" @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="title" />
+      <el-table-column label="明细分类 " align="center" prop="category" />
+      <el-table-column label="明细类型" align="center" prop="type" />
+      <el-table-column label="明细数字" align="center" prop="number" />
+      <el-table-column label="余额" align="center" prop="balance" />
+      <el-table-column label="备注" align="center" prop="remark" />
+      <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 { listUserBill, getUserBill, delUserBill, addUserBill, updateUserBill, exportUserBill } from "@/api/his/userBill";
+
+export default {
+  name: "UserBill",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      dateRange:[],
+      // 总条数
+      total: 0,
+      // 用户账单表格数据
+      userBillList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        userId: null,
+        businessId: null,
+        category: null,
+        billType: null,
+        type: null,
+        title: null,
+        number: null,
+        balance: null,
+        status: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        userId: [
+          { required: true, message: "用户uid不能为空", trigger: "blur" }
+        ],
+        businessId: [
+          { required: true, message: "关联id不能为空", trigger: "blur" }
+        ],
+        billType: [
+          { required: true, message: "类型 0 = 支出 1 = 获得不能为空", trigger: "change" }
+        ],
+        title: [
+          { required: true, message: "账单标题不能为空", trigger: "blur" }
+        ],
+        number: [
+          { required: true, message: "明细数字不能为空", trigger: "blur" }
+        ],
+        balance: [
+          { required: true, message: "剩余不能为空", trigger: "blur" }
+        ],
+        remark: [
+          { required: true, message: "备注不能为空", trigger: "blur" }
+        ],
+        createTime: [
+          { required: true, message: "添加时间不能为空", trigger: "blur" }
+        ],
+        status: [
+          { required: true, message: "0 = 带确定 1 = 有效 -1 = 无效不能为空", trigger: "blur" }
+        ]
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询用户账单列表 */
+    getList() {
+      this.loading = true;
+      listUserBill(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
+        this.userBillList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        userId: null,
+        businessId: null,
+        category: null,
+        billType: null,
+        type: null,
+        title: null,
+        number: null,
+        balance: null,
+        remark: null,
+        createTime: null,
+        updateTime: 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.id)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加用户账单";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getUserBill(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改用户账单";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateUserBill(this.form).then(response => {
+              if (response.code === 200) {
+                this.msgSuccess("修改成功");
+                this.open = false;
+                this.getList();
+              }
+            });
+          } else {
+            addUserBill(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 delUserBill(ids);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(function() {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有用户账单数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return exportUserBill(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+        }).catch(function() {});
+    }
+  }
+};
+</script>

+ 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>

+ 55 - 3
src/views/system/config/config.vue

@@ -348,7 +348,7 @@
               <el-input-number v-model="form7.followRate" :min="0" :max="1000"></el-input-number>
             </el-tooltip>
           </el-form-item>
-          <el-form-item label="是否需要根据物流信息更新订单完成状态" prop="followRate">
+          <el-form-item  label="是否需要根据物流信息更新订单完成状态" prop="isUpdateOrder">
             <el-switch
               v-model="form7.isUpdateOrder"
               active-color="#13ce66"
@@ -358,6 +358,24 @@
             >
             </el-switch>
           </el-form-item>
+          <el-form-item  label="是否开启就诊人身份验证" prop="isIdVerification">
+            <el-switch
+              v-model="form7.isIdVerification"
+              active-color="#13ce66"
+              inactive-color="#ff4949"
+              :active-value=1
+              :inactive-value=0>
+            </el-switch>
+          </el-form-item>
+          <el-form-item label="API_URL" v-if="form7.isIdVerification == 1" prop="API_URL">
+              <el-input   v-model="form7.API_URL"  label="请输入API_URL"></el-input>
+          </el-form-item>
+          <el-form-item label="HASHCODE" v-if="form7.isIdVerification == 1" prop="HASHCODE">
+              <el-input   v-model="form7.HASHCODE"  label="请输入HASHCODE"></el-input>
+          </el-form-item>
+          <el-form-item label="SECRET_KEY" v-if="form7.isIdVerification == 1" prop="SECRET_KEY">
+              <el-input   v-model="form7.SECRET_KEY"  label="请输入SECRET_KEY"></el-input>
+          </el-form-item>
           <div class="footer">
             <el-button type="primary" @click="submitForm7">提 交</el-button>
           </div>
@@ -781,6 +799,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"
@@ -1415,6 +1441,14 @@
             </el-switch>
           </el-form-item>
 
+           <el-form-item label="是否开启IM" prop="isOpenIM">
+             <el-switch
+               v-model="form18.isOpenIM"
+               active-color="#13ce66"
+               inactive-color="#ff4949">
+             </el-switch>
+           </el-form-item>
+
           <div class="line"></div>
           <div style="float:right;margin-right:20px">
             <el-button type="primary" @click="submitForm18">提交</el-button>
@@ -1582,10 +1616,10 @@
           <el-form-item label="apiV3密钥" prop="apiV3Key">
             <el-input v-model="form19.apiV3Key" label="请输入apiV3Key"></el-input>
           </el-form-item>
-          <el-form-item label="公钥ID" prop="publicKeyId" v-if="form19.isNew==1">
+           <el-form-item   label="公钥ID" prop="publicKeyId" v-if="form19.isNew==1">
             <el-input v-model="form19.publicKeyId" label="请输入公钥ID"></el-input>
           </el-form-item>
-          <el-form-item label="公钥证书" prop="publicKeyPath" v-if="form19.isNew==1">
+           <el-form-item   label="公钥证书" prop="publicKeyPath" v-if="form19.isNew==1">
             <el-input v-model="form19.publicKeyPath" label="请输入publicKeyPath"></el-input>
           </el-form-item>
           <el-form-item label="key路径" prop="privateKeyPath">
@@ -2726,6 +2760,24 @@ export default {
       })
     },
     submitForm7() {
+      if (this.form7.isIdVerification  == null){
+        this.form7.isIdVerification = 0;
+      }
+    if(this.form7.isIdVerification != 1){
+      this.form7.API_URL = null;
+      this.form7.HASHCODE = null;
+      this.form7.SECRET_KEY = null;
+    } else{
+      // 校验这三个参数是否为空
+      if (
+        !this.form7.API_URL ||
+        !this.form7.HASHCODE ||
+        !this.form7.SECRET_KEY
+      ) {
+        this.msgError("API_URL、HASHCODE 和 SECRET_KEY 为必填项");
+        return; // 阻止提交
+      }
+    }
       var param = { configId: this.configId, configValue: JSON.stringify(this.form7) }
       updateConfigByKey(param).then(response => {
         if (response.code === 200) {