Parcourir la source

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	src/views/user/complaint/index.vue
吴树波 il y a 2 semaines
Parent
commit
e5f624a022
53 fichiers modifiés avec 7753 ajouts et 1282 suppressions
  1. 40 0
      .env.prod-hyt
  2. 1 1
      .env.prod-kyt
  3. 1 0
      package.json
  4. 13 2
      src/api/company/statistics.js
  5. 53 0
      src/api/complaint/category.js
  6. 75 0
      src/api/complaint/complaint.js
  7. 39 0
      src/api/course/coursePlaySourceConfig.js
  8. 8 0
      src/api/course/videoResource.js
  9. 44 0
      src/api/food/record.js
  10. 27 0
      src/api/his/inquiryPatient.js
  11. 9 9
      src/api/hisStore/city.js
  12. 76 0
      src/api/hisStore/express.js
  13. 53 0
      src/api/hisStore/shippingTemplatesFree.js
  14. 53 0
      src/api/hisStore/shippingTemplatesRegion.js
  15. 7 0
      src/api/hisStore/storeOrder.js
  16. 69 0
      src/api/recharge/template.js
  17. 49 0
      src/api/saler/competitorInfo.js
  18. 46 0
      src/api/saler/productInfo.js
  19. 81 0
      src/api/todo/todoItems.js
  20. BIN
      src/assets/logo/hcl.png
  21. 264 0
      src/components/City/index.vue
  22. 129 134
      src/components/Editor/wang.vue
  23. 4 0
      src/store/modules/user.js
  24. 17 2
      src/views/company/company/index.vue
  25. 33 31
      src/views/components/course/userCourseCatalogDetails.vue
  26. 261 0
      src/views/components/his/inquiryOrderDetails.vue
  27. 1 1
      src/views/components/his/storeOrderDetails.vue
  28. 324 0
      src/views/course/coursePlaySourceConfig/index.vue
  29. 148 182
      src/views/course/courseTrafficLog/index.vue
  30. 5 5
      src/views/course/userCoursePeriod/index.vue
  31. 26 1
      src/views/course/userCoursePeriod/statistics.vue
  32. 92 1
      src/views/course/videoResource/index.vue
  33. 302 0
      src/views/food/record/index.vue
  34. 16 1
      src/views/his/company/index.vue
  35. 252 0
      src/views/his/statistics/ipadStatic.vue
  36. 5 71
      src/views/his/user/index.vue
  37. 35 15
      src/views/his/user/indexProject.vue
  38. 394 0
      src/views/hisStore/express/index.vue
  39. 443 0
      src/views/hisStore/shippingTemplates/index.vue
  40. 366 0
      src/views/hisStore/shippingTemplatesFree/index.vue
  41. 402 0
      src/views/hisStore/shippingTemplatesRegion/index.vue
  42. 747 580
      src/views/hisStore/storeOrder/healthStoreList.vue
  43. 119 0
      src/views/hisStore/storeOrder/index.vue
  44. 1 1
      src/views/qw/sopTemp/updateSopTemp.vue
  45. 272 0
      src/views/saler/competitorInfo/index.vue
  46. 296 0
      src/views/saler/productInfo/index.vue
  47. 108 88
      src/views/system/config/config.vue
  48. 4 4
      src/views/system/config/config2.vue
  49. 8 2
      src/views/system/role/index.vue
  50. 619 0
      src/views/todo/todoItems/index.vue
  51. 308 0
      src/views/user/complaint/category/index.vue
  52. 253 151
      src/views/user/complaint/index.vue
  53. 755 0
      src/views/user/rechargeTemplate/index.vue

+ 40 - 0
.env.prod-hyt

@@ -0,0 +1,40 @@
+# 页面标题
+VUE_APP_TITLE =宏医堂互联网医院管理系统
+# 首页菜单标题
+VUE_APP_TITLE_INDEX =宏医堂互联网医院
+# 公司名称
+VUE_APP_COMPANY_NAME =易行健和泰(湖北)健康咨询有限公司
+# ICP备案号
+VUE_APP_ICP_RECORD =鄂ICP备2025116549号-1
+# ICP网站访问地址
+VUE_APP_ICP_URL =https://beian.miit.gov.cn
+# 网站LOG
+VUE_APP_LOG_URL =@/assets/logo/myhk.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 = hyt-hw079058881
+# 存储桶配置
+VUE_APP_COS_BUCKET = fzhyt-1323137866
+# 存储桶配置
+VUE_APP_COS_REGION = ap-chongqing
+# 线路一地址
+VUE_APP_VIDEO_LINE_1 = https://fzhyttcpv.ylrzcloud.com
+# 线路二地址
+VUE_APP_VIDEO_LINE_2 = https://hytobs.ylrztop.com
+
+# 开发环境配置
+ENV = 'production'
+
+# FS管理系统/开发环境
+VUE_APP_BASE_API = '/prod-api'
+
+#默认 1、会员 2、企微
+VUE_APP_COURSE_DEFAULT = 1
+
+# 路由懒加载
+VUE_CLI_BABEL_TRANSPILE_MODULES = true

+ 1 - 1
.env.prod-kyt

@@ -34,7 +34,7 @@ ENV = 'development'
 VUE_APP_BASE_API = '/prod-api'
 
 #默认 1、会员 2、企微
-VUE_APP_COURSE_DEFAULT = 1
+VUE_APP_COURSE_DEFAULT = 2
 
 # 路由懒加载
 VUE_CLI_BABEL_TRANSPILE_MODULES = true

+ 1 - 0
package.json

@@ -35,6 +35,7 @@
     "build:prod-fby": "vue-cli-service build --mode prod-fby",
     "build:prod-zkzh": "vue-cli-service build --mode prod-zkzh",
     "build:prod-syysy": "vue-cli-service build --mode prod-syysy",
+    "build:prod-hyt": "vue-cli-service build --mode prod-hyt",
     "preview": "node build/index.js --preview",
     "lint": "eslint --ext .js,.vue src"
   },

+ 13 - 2
src/api/company/statistics.js

@@ -100,7 +100,7 @@ export function exportCustomer(query) {
   })
 }
 
- 
+
 export function customerVisit(query) {
   return request({
     url: '/company/statistics/customerVisit',
@@ -116,6 +116,17 @@ export function exportCustomerVisit(query) {
   })
 }
 
-
+export function ipadStaticTotal(dateTime) {
+  return request({
+    url: '/company/statistics/ipadStaticTotal/' + dateTime,
+    method: 'get'
+  })
+}
+export function exportIpadStaticByTime(dateTime) {
+  return request({
+    url: '/company/statistics/exportIpadStaticByTime/' + dateTime,
+    method: 'get'
+  })
+}
 
 

+ 53 - 0
src/api/complaint/category.js

@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询投诉分类列表
+export function listCategory(query) {
+  return request({
+    url: '/complaint/category/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询投诉分类详细
+export function getCategory(id) {
+  return request({
+    url: '/complaint/category/' + id,
+    method: 'get'
+  })
+}
+
+// 新增投诉分类
+export function addCategory(data) {
+  return request({
+    url: '/complaint/category',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改投诉分类
+export function updateCategory(data) {
+  return request({
+    url: '/complaint/category',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除投诉分类
+export function delCategory(ids) {
+  return request({
+    url: '/complaint/category/' + ids,
+    method: 'delete'
+  })
+}
+
+// 修改投诉分类状态
+export function changeStatus(data) {
+  return request({
+    url: '/complaint/category/status',
+    method: 'put',
+    data: data
+  })
+}

+ 75 - 0
src/api/complaint/complaint.js

@@ -0,0 +1,75 @@
+import request from '@/utils/request'
+
+// 提交投诉
+export function submitComplaint(data) {
+  return request({
+    url: '/complaint',
+    method: 'post',
+    data: data
+  })
+}
+
+// 根据ID查询投诉详情
+export function getComplaintById(id) {
+  return request({
+    url: `/complaint/${id}`,
+    method: 'get'
+  })
+}
+
+// 根据投诉单号查询投诉详情
+export function getComplaintByNo(complaintNo) {
+  return request({
+    url: `/complaint/no/${complaintNo}`,
+    method: 'get'
+  })
+}
+
+// 分页查询投诉列表
+export function getComplaintPage(data) {
+  return request({
+    url: '/complaint/list',
+    method: 'post',
+    data: data
+  })
+}
+
+// 更新投诉信息
+export function updateComplaint(id, data) {
+  return request({
+    url: `/complaint/${id}`,
+    method: 'put',
+    data: {
+      ...data,
+      type: data.categoryId
+    }
+  })
+}
+
+// 删除投诉
+export function deleteComplaint(id) {
+  return request({
+    url: `/complaint/${id}`,
+    method: 'delete'
+  })
+}
+
+// 处理投诉(快捷更新状态为已处理)
+export function handleComplaint(id) {
+  return request({
+    url: `/complaint/${id}`,
+    method: 'put',
+    data: {
+      status: '1' // 假设1表示已处理状态
+    }
+  })
+}
+// 新增:获取所有投诉分类
+export function getAllCategory() {
+  return request({
+    url: '/complaint/queryAllCategory',
+    method: 'post'
+  })
+}
+
+

+ 39 - 0
src/api/course/coursePlaySourceConfig.js

@@ -0,0 +1,39 @@
+import request from '@/utils/request'
+
+export function list(query) {
+  return request({
+    url: '/course/playSourceConfig/list',
+    method: 'get',
+    params: query
+  })
+}
+
+export function get(id) {
+  return request({
+    url: '/course/playSourceConfig/' + id,
+    method: 'get'
+  })
+}
+
+export function add(data) {
+  return request({
+    url: '/course/playSourceConfig',
+    method: 'post',
+    data: data
+  })
+}
+
+export function update(data) {
+  return request({
+    url: '/course/playSourceConfig',
+    method: 'put',
+    data: data
+  })
+}
+
+export function del(id) {
+  return request({
+    url: '/course/playSourceConfig/' + id,
+    method: 'delete'
+  })
+}

+ 8 - 0
src/api/course/videoResource.js

@@ -52,3 +52,11 @@ export function batchAddVideoResource(data) {
   })
 }
 
+// 批量修改视频资源
+export function batchUpdateVideoResource(data) {
+  return request({
+    url: '/course/videoResource/batchUpdateClass',
+    method: 'post',
+    params: data
+  })
+}

+ 44 - 0
src/api/food/record.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询饮食记录列表
+export function listFoodRecord(query) {
+  return request({
+    url: '/food-record/admin/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询饮食记录详细
+export function getFoodRecord(id) {
+  return request({
+    url: '/food-record/getRecordInfo/' + id,
+    method: 'get'
+  })
+}
+
+// 新增饮食记录
+export function addFoodRecord(data) {
+  return request({
+    url: '/food-record/addRecord',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改饮食记录
+export function updateFoodRecord(data) {
+  return request({
+    url: '/food-record/editRecord',
+    method: 'post',
+    data: data
+  })
+}
+
+// 删除饮食记录
+export function delFoodRecord(id) {
+  return request({
+    url: '/food-record/deleteRecord/' + id,
+    method: 'post'
+  })
+}

+ 27 - 0
src/api/his/inquiryPatient.js

@@ -0,0 +1,27 @@
+import request from '@/utils/request'
+
+// 新增患者问诊信息
+export function addinquiryPatient(data) {
+  return request({
+    url: '/his/inquiryPatientInfo',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改患者问诊信息
+export function updateinquiryPatient(data) {
+  return request({
+    url: '/his/inquiryPatientInfo',
+    method: 'put',
+    data: data
+  })
+}
+
+//获取患者问诊信息详情
+export function detail(inquiryOrderId) {
+  return request({
+    url: '/his/inquiryPatientInfo/detail/'+ inquiryOrderId,
+    method: 'get'
+  })
+}

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

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

+ 76 - 0
src/api/hisStore/express.js

@@ -0,0 +1,76 @@
+import request from '@/utils/request'
+
+// 查询快递公司列表
+export function listExpress(query) {
+  return request({
+    url: '/his/express/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询快递公司详细
+export function getExpress(id) {
+  return request({
+    url: '/his/express/' + id,
+    method: 'get'
+  })
+}
+
+export function getExpressList() {
+  return request({
+    url: '/his/express/getExpressList',
+    method: 'get'
+  })
+}
+
+// 新增快递公司
+export function addExpress(data) {
+  return request({
+    url: '/his/express',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改快递公司
+export function updateExpress(data) {
+  return request({
+    url: '/his/express',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除快递公司
+export function delExpress(id) {
+  return request({
+    url: '/his/express/' + id,
+    method: 'delete'
+  })
+}
+
+// 导出快递公司
+export function exportExpress(query) {
+  return request({
+    url: '/his/express/export',
+    method: 'get',
+    params: query
+  })
+}
+
+//分配快递公司
+export function allotExpress(data,omsCode) {
+  return request({
+    url: '/his/express/allotExpress/'+omsCode,
+    method: 'post',
+    data: data
+  })
+}
+
+export function getCompanyByOmsCode(omsCode) {
+  return request({
+    url: '/his/express/omsCode/' + omsCode,
+    method: 'get'
+  })
+}

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

@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询免邮费列表
+export function listShippingTemplatesFree(query) {
+  return request({
+    url: '/store/shippingTemplatesFree/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询免邮费详细
+export function getShippingTemplatesFree(id) {
+  return request({
+    url: '/store/shippingTemplatesFree/' + id,
+    method: 'get'
+  })
+}
+
+// 新增免邮费
+export function addShippingTemplatesFree(data) {
+  return request({
+    url: '/store/shippingTemplatesFree',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改免邮费
+export function updateShippingTemplatesFree(data) {
+  return request({
+    url: '/store/shippingTemplatesFree',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除免邮费
+export function delShippingTemplatesFree(id) {
+  return request({
+    url: '/store/shippingTemplatesFree/' + id,
+    method: 'delete'
+  })
+}
+
+// 导出免邮费
+export function exportShippingTemplatesFree(query) {
+  return request({
+    url: '/store/shippingTemplatesFree/export',
+    method: 'get',
+    params: query
+  })
+}

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

@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询邮费区域列表
+export function listShippingTemplatesRegion(query) {
+  return request({
+    url: '/store/shippingTemplatesRegion/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询邮费区域详细
+export function getShippingTemplatesRegion(id) {
+  return request({
+    url: '/store/shippingTemplatesRegion/' + id,
+    method: 'get'
+  })
+}
+
+// 新增邮费区域
+export function addShippingTemplatesRegion(data) {
+  return request({
+    url: '/store/shippingTemplatesRegion',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改邮费区域
+export function updateShippingTemplatesRegion(data) {
+  return request({
+    url: '/store/shippingTemplatesRegion',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除邮费区域
+export function delShippingTemplatesRegion(id) {
+  return request({
+    url: '/store/shippingTemplatesRegion/' + id,
+    method: 'delete'
+  })
+}
+
+// 导出邮费区域
+export function exportShippingTemplatesRegion(query) {
+  return request({
+    url: '/store/shippingTemplatesRegion/export',
+    method: 'get',
+    params: query
+  })
+}

+ 7 - 0
src/api/hisStore/storeOrder.js

@@ -285,3 +285,10 @@ export function orderDimensionStatisticsExport(query) {
     params: query
   })
 }
+
+export function importDeliveryNoteExpressTemplate() {
+  return request({
+    url: '/store/storeOrder/importDeliveryNoteExpressTemplate',
+    method: 'get'
+  })
+}

+ 69 - 0
src/api/recharge/template.js

@@ -0,0 +1,69 @@
+import request from '@/utils/request'
+
+// 查询充值模板列表
+export function listRechargeTemplate(query) {
+  return request({
+    url: '/recharge-templates/list',
+    method: 'post',
+    data: query
+  })
+}
+
+// 查询充值模板详细
+export function getRechargeTemplate(id) {
+  return request({
+    url: '/recharge-templates/' + id,
+    method: 'get'
+  })
+}
+
+// 新增充值模板
+export function addRechargeTemplate(data) {
+  return request({
+    url: '/recharge-templates',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改充值模板
+export function updateRechargeTemplate(data) {
+  return request({
+    url: '/recharge-templates/' + data.id,
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除充值模板
+export function delRechargeTemplate(id) {
+  return request({
+    url: '/recharge-templates/' + id,
+    method: 'delete'
+  })
+}
+
+// 修改充值模板状态
+export function updateRechargeTemplateStatus(id, status) {
+  return request({
+    url: '/recharge-templates/' + id + '/status',
+    method: 'put',
+    params: {
+      status: status
+    }
+  })
+}
+
+
+/**
+ * 获取优惠券列表
+ * @param {Object} query 查询参数
+ * @returns {Promise} 请求结果
+ */
+export function getCouponList(query) {
+  return request({
+    url: '/recharge-templates/getCouponList',
+    method: 'get',
+    params: query
+  })
+}

+ 49 - 0
src/api/saler/competitorInfo.js

@@ -0,0 +1,49 @@
+import request from '@/utils/request'
+
+// 竞品信息模块请求前缀
+const prefix = '/saler/competitorInfo'
+
+// 查询竞品信息列表
+export function listCompetitorInfo(query) {
+  return request({
+    url: prefix + '/listPage',
+    method: 'post',
+    data: query
+  })
+}
+
+// 查询竞品信息详细
+export function getCompetitorInfo(id) {
+  return request({
+    url: prefix + '/findById',
+    method: 'post',
+    data: { id }
+  })
+}
+
+// 新增竞品信息
+export function addCompetitorInfo(data) {
+  return request({
+    url: prefix + '/save',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改竞品信息
+export function updateCompetitorInfo(data) {
+  return request({
+    url: prefix + '/updateById',
+    method: 'post',
+    data: data
+  })
+}
+
+// 删除竞品信息
+export function delCompetitorInfo(id) {
+  return request({
+    url: prefix + '/deleteById',
+    method: 'post',
+    data: { id }
+  })
+}

+ 46 - 0
src/api/saler/productInfo.js

@@ -0,0 +1,46 @@
+import request from '@/utils/request'
+
+// 查询商品列表
+export function listProductInfo(query) {
+  return request({
+    url: '/saler/serviceGoods/listPage',
+    method: 'post',
+    data: query
+  })
+}
+
+// 查询商品详细
+export function getProductInfo(id) {
+  return request({
+    url: '/saler/serviceGoods/findById',
+    method: 'post',
+    data: { id }
+  })
+}
+
+// 新增商品
+export function addProductInfo(data) {
+  return request({
+    url: '/saler/serviceGoods/save',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改商品
+export function updateProductInfo(data) {
+  return request({
+    url: '/saler/serviceGoods/updateById',
+    method: 'post',
+    data: data
+  })
+}
+
+// 删除商品
+export function delProductInfo(id) {
+  return request({
+    url: '/saler/serviceGoods/deleteById',
+    method: 'post',
+    data: { id }
+  })
+}

+ 81 - 0
src/api/todo/todoItems.js

@@ -0,0 +1,81 @@
+import request from '@/utils/request'
+
+// 查询待办事项列表
+export function listTodoItems(query) {
+  return request({
+    url: '/todoItems/listPage',
+    method: 'post',
+    data: query
+  })
+}
+
+// 查询待办事项详细
+export function getTodoItems(id) {
+  return request({
+    url: '/todoItems/findById',
+    method: 'post',
+    data: { id: id }
+  })
+}
+
+// 新增待办事项
+export function addTodoItems(data) {
+  return request({
+    url: '/todoItems/add',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改待办事项
+export function updateTodoItems(data) {
+  return request({
+    url: '/todoItems/updateById',
+    method: 'post',
+    data: data
+  })
+}
+
+// 更新待办事项状态
+export function updateTodoItemsStatus(id, status) {
+  return request({
+    url: '/todoItems/updateStatusById',
+    method: 'post',
+    data: { id: id, status: status }
+  })
+}
+
+// 删除待办事项
+export function delTodoItems(id) {
+  return request({
+    url: '/todoItems/removeById',
+    method: 'post',
+    data: { id: id }
+  })
+}
+
+// 分配执行者
+export function assignExecutor(data) {
+  return request({
+    url: '/todoItems/assignExecutor',
+    method: 'post',
+    data: data
+  })
+}
+
+// 获取可分配的执行者列表
+export function getExecutorList() {
+  return request({
+    url: '/todoItems/getExecutorList',
+    method: 'get'
+  })
+}
+
+// 获取执行人员列表(支持分页和公司名称搜索)
+export function getUserList(param) {
+  return request({
+    url: '/todoItems/getUserList',
+    method: 'post',
+    data: param
+  })
+}

BIN
src/assets/logo/hcl.png


+ 264 - 0
src/components/City/index.vue

@@ -0,0 +1,264 @@
+<template>
+  <el-dialog :close-on-click-modal="false"
+             :visible.sync="addressView"
+             append-to-body
+             class="modal"
+             title="选择城市" width="950px">
+    <el-row :gutter="24" type="flex">
+      <el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24" class="item">
+        <div class="check-btn">
+          <el-checkbox v-model="iSselect" @change="allCheckbox">全选</el-checkbox>
+          <div class="empty" @click="empty">清空</div>
+        </div>
+      </el-col>
+    </el-row>
+    <el-row  :gutter="24"  :loading="loading" >
+      <el-col  :xl="6" :lg="6" :md="6" :sm="8" :xs="6" class="item"  v-for="(item,index) in cityList" :key="index">
+        <div @mouseenter="enter(index)" @mouseleave="leave()" v-if="item.level==1">
+          <el-checkbox v-model="item.checked" :label="item.cityName" @change="checkedClick(index)">{{item.cityName}}</el-checkbox>
+          <div class="city" v-show="activeCity===index">
+            <div class="checkBox">
+              <div class="arrow"></div>
+              <div>
+                <el-checkbox v-model="subitem.checked" :label="subitem.cityName" @change="primary(index,subindex)"
+                class="itemn"  v-for="(subitem,subindex) in item.children" :key="subindex"
+                >{{subitem.cityName}}</el-checkbox>
+              </div>
+            </div>
+          </div>
+        </div>
+      </el-col>
+    </el-row>
+    <div slot="footer">
+      <el-button @click="close">取消</el-button>
+      <el-button type="primary" @click="confirm">确定</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import {getAllList} from "@/api/hisStore/city";
+
+  export default {
+    name: 'city',
+    props: {
+      type: {
+        type: Number,
+        default: 0
+      }
+    },
+    data () {
+      return {
+        iSselect: false,
+        addressView: false,
+        cityList: [],
+        activeCity: -1,
+        loading: false
+      }
+    },
+    methods: {
+      enter (index) {
+        this.activeCity = index;
+      },
+      leave () {
+        this.activeCity = null;
+      },
+      getCityList () {
+        this.loading = true;
+        getAllList().then(res => {
+          this.loading = false;
+          console.log(res.data)
+          var data=res.data;
+          this.cityList=data.filter(item => item.level===1 )
+
+          this.cityList.forEach(function(item,index,arr){
+            var subData=data.filter(subitem => subitem.parentId===item.cityId )
+            console.log(subData)
+            item.children=subData;
+          });
+        })
+      },
+      /**
+       * 全选或者反选
+       * @param checked
+       */
+      allCheckbox: function () {
+        let that = this, checked = this.iSselect;
+        that.cityList.forEach(function (item, key) {
+          that.$set(that.cityList[key], 'checked', checked);
+          if (checked) {
+            that.$set(that.cityList[key], 'count', that.cityList[key].children.length);
+          } else {
+            that.$set(that.cityList[key], 'count', 0);
+          }
+          that.cityList[key].children.forEach(function (val, k) {
+            that.$set(that.cityList[key].children[k], 'checked', checked);
+          })
+        });
+      },
+      // 清空;
+      empty () {
+        let that = this;
+        that.cityList.forEach(function (item, key) {
+          that.$set(that.cityList[key], 'checked', false);
+          that.cityList[key].children.forEach(function (val, k) {
+            that.$set(that.cityList[key].children[k], 'checked', false);
+          });
+          that.$set(that.cityList[key], 'count', 0);
+        });
+        this.iSselect = false;
+      },
+      /**
+       * 点击省
+       * @param index
+       */
+      checkedClick: function (index) {
+        let that = this;
+        if (that.cityList[index].checked) {
+          that.$set(that.cityList[index], 'count', that.cityList[index].children.length);
+          that.cityList[index].children.forEach(function (item, key) {
+            that.$set(that.cityList[index].children[key], 'checked', true);
+          });
+        } else {
+          that.$set(that.cityList[index], 'count', 0);
+          that.$set(that.cityList[index], 'checked', false);
+          that.cityList[index].children.forEach(function (item, key) {
+            that.$set(that.cityList[index].children[key], 'checked', false);
+          });
+          that.iSselect = false;
+        }
+      },
+      /**
+       * 点击市区
+       * @param index
+       * @param ind
+       */
+      primary: function (index, ind) {
+        let checked = false, count = 0;
+        this.cityList[index].children.forEach(function (item, key) {
+          console.log("item:"+item.checked)
+          if (item.checked) {
+            checked = true;
+            count++;
+          }
+        });
+        this.$set(this.cityList[index], 'count', count);
+        this.$set(this.cityList[index], 'checked', checked);
+      },
+      // 确定;
+      confirm () {
+        let that = this;
+        // 被选中的省市;
+        let selectList = [];
+        that.cityList.forEach(function (item, key) {
+          let data = {};
+          if (item.checked) {
+            data = {
+              name: item.cityName,
+              cityId: item.cityId,
+              children: []
+            };
+
+          }
+          that.cityList[key].children.forEach(function (i, k) {
+            if (i.checked) {
+              data.children.push({
+                cityId: i.cityId
+              })
+            }
+          });
+          if (data.cityId !== undefined) {
+            selectList.push(data);
+          }
+        });
+        console.log(selectList);
+        if (selectList.length === 0) {
+          return this.$message({
+            message:'至少选择一个省份或者城市',
+            type: 'error'
+          });
+        } else {
+          this.$emit('selectCity', selectList, this.type);
+          that.addressView = false;
+          this.cityList = []
+        }
+      },
+      close () {
+        this.addressView = false;
+        this.cityList = []
+      }
+    },
+    mounted () {
+    }
+  }
+</script>
+
+<style scoped>
+
+  .modal .item {
+    position: relative;
+    margin-bottom: 20px;
+  }
+
+  .modal .item .city {
+    position: absolute;
+    z-index: 9;
+    top: 17px;
+    width: 100%;
+    padding-top: 18px;
+  }
+
+  .modal .item .city .checkBox {
+    width: 97%;
+    padding: 10px;
+    border: 1px solid #eee;
+    background-color: #fff;
+    max-height: 100px;
+    overflow-x: hidden;
+    overflow-y: auto;
+  }
+
+  .modal .item .city .checkBox .arrow {
+    position: absolute;
+    top: 3px;
+    width: 0;
+    height: 0;
+    border: 8px solid transparent;
+    border-bottom-color: #ddd;
+  }
+
+  .modal .item .city .checkBox .arrow:before {
+    position: absolute;
+    bottom: -8px;
+    right: -7px;
+    content: "";
+    width: 0;
+    height: 0;
+    border: 7px solid transparent;
+    border-bottom-color: #fff;
+  }
+
+  .modal .item .city .checkBox .itemn {
+    margin-bottom: 10px;
+  }
+
+  .radio {
+    padding: 5px 0;
+    font-size: 14px !important;
+  }
+
+  .red {
+    color: #ff0000;
+  }
+
+  .empty {
+    cursor: pointer;
+    margin-left:10px
+  }
+  .check-btn{
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: flex-end;
+  }
+</style>

+ 129 - 134
src/components/Editor/wang.vue

@@ -1,144 +1,139 @@
-<template>  
-    <div>
-      <div  ref='editor1' class="myedit"></div>
-    </div> 
-</template>  
-  
-<script>  
-  import E from 'wangeditor'  
-  export default {  
-    name: 'editoritem',  
-    data() {  
-      return {
-        uploadUrl:process.env.VUE_APP_BASE_API+"/common/uploadWang",
-        editor: null
-      }  
-    },
-    created() {
-       
-      
+<template>
+  <div>
+    <div ref='editor1' class="myedit"></div>
+  </div>
+</template>
+
+<script>
+import E from 'wangeditor'
+export default {
+  name: 'editoritem',
+  data() {
+    return {
+      uploadUrl: process.env.VUE_APP_BASE_API + "/common/uploadWang",
+      editor: null,
+      selectedImageCount: 0, // 记录选择的图片数量
+      uploadedImageCount: 0  // 记录已上传的图片数量
+    }
+  },
+  beforeDestroy() {
+    if (this.editor != null) {
+      this.editor.destroy()
+      this.editor = null
+    }
+  },
+  methods: {
+    initEditor() {
+      const that = this;
+      if (this.editor == null) {
+        this.editor = new E(that.$refs.editor1)
+        this.editor.config.uploadImgServer = this.uploadUrl;
+        this.editor.config.uploadImgMaxSize = 6 * 1024 * 1024 // 2M
+        this.editor.config.uploadImgAccept = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']
+        this.editor.config.uploadFileName = 'fileName'
+        this.editor.config.zIndex = 1
+
+        // 关键配置:允许多选,串行上传
+        this.editor.config.uploadImgMultiple = true;
+        this.editor.config.uploadImgMaxLength = 5;
+        this.editor.config.uploadImgConcurrent = 1;
+
+        this.editor.config.customUploadImg = function (files, insertImgFn) {
+          // 获取选择的图片数量
+          that.selectedImageCount = files.length;
+          that.uploadedImageCount = 0;
+          console.log(`已选择 ${that.selectedImageCount} 张图片,准备开始上传`);
+
+          that.$emit('image-selected', that.selectedImageCount);
+
+          const uploadNext = (index) => {
+            if (index >= files.length) {
+              console.log(`所有 ${files.length} 张图片上传处理完毕`);
+              that.$emit('all-images-uploaded', that.uploadedImageCount);
+              return;
+            }
+
+            const formData = new FormData();
+            formData.append(that.editor.config.uploadFileName, files[index]);
+
+            const xhr = new XMLHttpRequest();
+            xhr.open('POST', that.uploadUrl);
+
+            xhr.onload = function () {
+              if (xhr.status >= 200 && xhr.status < 300) {
+                const result = JSON.parse(xhr.responseText);
+                if (result.errno === 0 && result.data && result.data[0] && result.data[0].url) {
+                  insertImgFn(result.data[0].url);
+                  that.uploadedImageCount++;
+                  that.$emit('image-uploaded', that.uploadedImageCount, that.selectedImageCount);
+                } else {
+                  console.error(`第 ${index+1} 张图片上传失败:`, result);
+                  that.$emit('image-upload-error', index+1);
+                }
+              } else {
+                console.error(`第 ${index+1} 张图片上传请求失败:`, xhr.statusText);
+                that.$emit('image-upload-error', index+1);
+              }
+              uploadNext(index + 1);
+            };
+
+            xhr.onerror = function () {
+              console.error(`第 ${index+1} 张图片上传出错`);
+              that.$emit('image-upload-error', index+1);
+              uploadNext(index + 1);
+            };
+
+            // 发送请求
+            xhr.send(formData);
+          };
+
+          // 开始上传第一张
+          uploadNext(0);
+        };
+
+        this.editor.config.menus = [
+          'head', 'bold', 'fontSize', 'fontName', 'italic', 'underline',
+          'strikeThrough', 'indent', 'lineHeight', 'foreColor', 'backColor',
+          'link', 'list', 'todo', 'justify', 'quote', 'emoticon', 'image',
+          'table', 'code', 'splitLine', 'undo', 'redo'
+        ]
+
+        this.editor.config.onchange = function (newHtml) {
+          that.$emit("on-text-change", newHtml);
+        }
+
+        this.editor.config.pasteFilterStyle = false
+        this.editor.config.onchangeTimeout = 500
+
+        this.editor.create()
+      }
+      this.editor.txt.html("");
     },
-    beforeDestroy() {
-      // 销毁编辑器
-      if(this.editor!=null){
-        this.editor.destroy()
-        this.editor = null
+
+    setText(text) {
+      if (this.editor == null) {
+        this.initEditor()
       }
-      
+      this.editor.txt.html(text || "");
     },
-    methods:{
-      initEditor(){
-        var that=this;
-        if(this.editor==null){
-            //创建编辑器
-            this.editor = new E(that.$refs.editor1 )
-            this.editor.config.uploadImgServer = this.uploadUrl;
-            this.editor.config.uploadImgMaxSize = 2 * 1024 * 1024 // 2M
-            this.editor.config.uploadImgAccept = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']
-            this.editor.config.uploadFileName = 'fileName'
-            this.editor.config.zIndex = 1
-            this.editor.config.menus = [
-              'head',
-              'bold',
-              'fontSize',
-              'fontName',
-              'italic',
-              'underline',
-              'strikeThrough',
-              'indent',
-              'lineHeight',
-              'foreColor',
-              'backColor',
-              'link',
-              'list',
-              'todo',
-              'justify',
-              'quote',
-              'emoticon',
-              'image',
-              // 'video',
-              'table',
-              'code',
-              'splitLine',
-              'undo',
-              'redo',
-          ]
-          this.editor.config.onchange = function (newHtml) {
-            console.log(newHtml)
-            that.$emit("on-text-change", newHtml);
-          }
-          this.editor.config.pasteFilterStyle = false
-          // 配置触发 onchange 的时间频率,默认为 200ms
-          this.editor.config.onchangeTimeout = 500 // 修改为 500ms
-            this.editor.config.uploadImgHooks = {
-                // 上传图片之前
-                before: function(xhr) {
-                    //console.log(xhr)
-                    
-                },
-                // 图片上传并返回了结果,图片插入已成功
-                success: function(xhr) {
-                    //console.log('success', xhr)
-                },
-                // 图片上传并返回了结果,但图片插入时出错了
-                fail: function(xhr, editor, resData) {
-                    console.log('fail', resData)
-                },
-                // 上传图片出错,一般为 http 请求的错误
-                error: function(xhr, editor, resData) {
-                    console.log('error', xhr, resData)
-                },
-                // 上传图片超时
-                timeout: function(xhr) {
-                    //console.log('timeout')
-                },
-                // 图片上传并返回了结果,想要自己把图片插入到编辑器中
-                // 例如服务器端返回的不是 { errno: 0, data: [...] } 这种格式,可使用 customInsert
-                customInsert: function(insertImg, result, editor) {
-                      console.log(result);
-                      // 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!)
-                      // insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果
-                      // 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片:
-                      var url =   result.data[0].url
-                      console.log(url);
-                      insertImg(url)
-                      // result 必须是一个 JSON 格式字符串!!!否则报错
-                }
-            }
-            this.editor.create()
-        }
-        this.editor.txt.html("");
-      },
-      setText(text){
-        if(this.editor==null){
-          this.initEditor()
-        }
-        if(text==undefined||text==null){
-          this.editor.txt.html("");
-        }
-        else{
-          this.editor.txt.html(text);
-        }
-        
-      },
-     }
-   
-  }  
-</script>  
-  
-<style scoped>
-.toolbar {
-  border: 1px solid #ccc;
+
+    getSelectedImageCount() {
+      return this.selectedImageCount;
+    },
+
+    getUploadedImageCount() {
+      return this.uploadedImageCount;
+    }
+  }
 }
+</script>
+
+<style scoped>
 .myedit {
   min-height: 300px;
   z-index: 1 !important;
 }
-.w-e-toolbar{
-  z-index: 1 !important;
-}
-.w-e-text-container{
+.w-e-toolbar, .w-e-text-container {
   z-index: 1 !important;
 }
- 
-</style>
+</style>

+ 4 - 0
src/store/modules/user.js

@@ -29,6 +29,9 @@ const user = {
     },
     SET_PERMISSIONS: (state, permissions) => {
       state.permissions = permissions
+    },
+    SET_ISADMIN: (state, isAdmin) => {
+      state.isAdmin = isAdmin
     }
   },
 
@@ -65,6 +68,7 @@ const user = {
           commit('SET_NAME', user.userName)
           commit('SET_AVATAR', avatar)
           commit('SET_USER', user)
+          commit('SET_ISADMIN', res.isAdmin)
           resolve(res)
         }).catch(error => {
           reject(error)

+ 17 - 2
src/views/company/company/index.vue

@@ -509,9 +509,15 @@ export default {
         this.form = response.data;
         this.form.status = response.data.status.toString();
         this.form.companyType = response.data.companyType.toString();
-        if(this.form.followDoctorIds!=null){
-           this.form.followDoctorIds= JSON.parse(this.form.followDoctorIds)
+
+        if (this.form.followDoctorIds==null || this.form.followDoctorIds.length==0){
+          this.form.followDoctorIds=null;
+        }
+
+        if(this.form.followDoctorIds!=null && this.form.followDoctorIds.length>0){
+          this.form.followDoctorIds= JSON.stringify(this.form.followDoctorIds)
         }
+
         if(this.form.packageIds!=null){
           var packageList=this.form.packageIds.split(",");
           packageList.forEach(element => {
@@ -527,6 +533,15 @@ export default {
     submitForm() {
       this.$refs["form"].validate(valid => {
         if (valid) {
+
+          if (this.form.followDoctorIds==null || this.form.followDoctorIds.length==0){
+            this.form.followDoctorIds=null;
+          }
+
+          if(this.form.followDoctorIds!=null && this.form.followDoctorIds.length>0){
+            this.form.followDoctorIds= JSON.stringify(this.form.followDoctorIds)
+          }
+
           if (this.form.companyId != null) {
             updateCompany(this.form).then(response => {
               if (response.code === 200) {

+ 33 - 31
src/views/components/course/userCourseCatalogDetails.vue

@@ -6,7 +6,7 @@
     <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" />
+                  @keyup.enter.native="handleQuery" />
       </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
@@ -16,23 +16,23 @@
     <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="['course:userCourseVideo:add']">新增目录</el-button>
+                   v-hasPermi="['course:userCourseVideo:add']">新增目录</el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button type="primary" plain :disabled="!ids || ids.length <= 0" size="mini" @click="openUpdates"
-          v-hasPermi="['course:userCourseVideo:updateTime']">修改时间</el-button>
+                   v-hasPermi="['course:userCourseVideo:updateTime']">修改时间</el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button type="primary" plain size="mini" @click="openAdds"
-          v-hasPermi="['course:userCourseVideo:batchAdd']">批量添加</el-button>
+                   v-hasPermi="['course:userCourseVideo:batchAdd']">批量添加</el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button type="primary" plain size="mini" @click="updateRedPageckeOpen"
-          v-hasPermi="['course:userCourseVideo:updateRed']">修改红包</el-button>
+                   v-hasPermi="['course:userCourseVideo:updateRed']">修改红包</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="['course:userCourseVideo:remove']">删除</el-button>
+                   v-hasPermi="['course:userCourseVideo:remove']">删除</el-button>
       </el-col>
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
@@ -72,17 +72,17 @@
       <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="['course:userCourseVideo:edit']">修改</el-button>
+                     v-hasPermi="['course:userCourseVideo:edit']">修改</el-button>
           <el-button size="mini" type="text" icon="el-icon-edit" @click="handleComment(scope.row)"
-            v-hasPermi="['course:courseWatchComment:list']">查看评论</el-button>
+                     v-hasPermi="['course:courseWatchComment:list']">查看评论</el-button>
           <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
-            v-hasPermi="['course:userCourseVideo:remove']">删除</el-button>
+                     v-hasPermi="['course:userCourseVideo: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" />
+                @pagination="getList" />
     <el-dialog :title="title" :visible.sync="open" width="1000px" append-to-body>
       <el-form ref="form" :model="form" :rules="rules" label-width="110px" v-loading="uploadLoading">
         <el-form-item label="视频标题" prop="title">
@@ -120,17 +120,17 @@
 
         <el-form-item label="视频缩略图" prop="thumbnail">
           <el-upload v-model="form.thumbnail" class="avatar-uploader" :action="uploadUrl" :show-file-list="false"
-            :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
+                     :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
             <img v-if="form.thumbnail" :src="form.thumbnail" class="avatar" width="300px">
             <i v-else class="el-icon-plus avatar-uploader-icon"></i>
           </el-upload>
         </el-form-item>
         <video-upload :type="1" :isPrivate="isPrivate" :fileKey.sync="form.fileKey" :fileSize.sync="form.fileSize"
-          :videoUrl.sync="videoUrl" :fileName.sync="form.fileName" :line_1.sync="form.lineOne"
-          :line_2.sync="form.lineTwo" :line_3.sync="form.lineThree" :thumbnail.sync="form.thumbnail"
-          :uploadType.sync="form.uploadType" :isTranscode.sync="form.isTranscode"
-          :transcodeFileKey.sync="form.transcodeFileKey" @video-duration="handleVideoDuration"
-          @change="handleVideoChange" @selectProjects="handleSelectProjects" ref="videoUpload" append-to-body />
+                      :videoUrl.sync="videoUrl" :fileName.sync="form.fileName" :line_1.sync="form.lineOne"
+                      :line_2.sync="form.lineTwo" :line_3.sync="form.lineThree" :thumbnail.sync="form.thumbnail"
+                      :uploadType.sync="form.uploadType" :isTranscode.sync="form.isTranscode"
+                      :transcodeFileKey.sync="form.transcodeFileKey" @video-duration="handleVideoDuration"
+                      @change="handleVideoChange" @selectProjects="handleSelectProjects" ref="videoUpload" append-to-body />
 
         <el-form-item label="课题选择" prop="questionBankId">
           <el-button size="small" type="primary" @click="chooseQuestionBank">选取课题</el-button>
@@ -155,7 +155,7 @@
             <el-table-column label="操作" align="center" width="100px" fixed="right">
               <template slot-scope="scope">
                 <el-button size="mini" type="text" icon="el-icon-delete"
-                  @click="handleQuestionBankDelete(scope.row)">删除</el-button>
+                           @click="handleQuestionBankDelete(scope.row)">删除</el-button>
               </template>
             </el-table-column>
           </el-table>
@@ -177,7 +177,7 @@
             <el-table-column label="操作" align="center" width="100px" fixed="right">
               <template slot-scope="scope">
                 <el-button size="mini" type="text" icon="el-icon-delete"
-                  @click="handleCourseProductDelete(scope.row)">删除</el-button>
+                           @click="handleCourseProductDelete(scope.row)">删除</el-button>
               </template>
             </el-table-column>
           </el-table>
@@ -204,12 +204,12 @@
       <el-form ref="form" :model="updateBatchData.form" label-width="110px">
         <el-form-item label="看课时间" prop="timeRange">
           <el-time-picker is-range v-model="updateBatchData.form.timeRange" range-separator="至" start-placeholder="开始时间"
-            value-format="HH:mm:ss" end-placeholder="结束时间" placeholder="选择时间范围">
+                          value-format="HH:mm:ss" end-placeholder="结束时间" placeholder="选择时间范围">
           </el-time-picker>
         </el-form-item>
         <el-form-item label="领取红包时间" prop="lastJoinTime">
           <el-time-picker v-model="updateBatchData.form.lastJoinTime" :selectableRange="updateBatchData.form.timeRange"
-            value-format="HH:mm:ss" placeholder="选择时间范围">
+                          value-format="HH:mm:ss" placeholder="选择时间范围">
           </el-time-picker>
           <p style="color: red;margin: 0;font-size: 12px">超过领取红包时间,只允许看课,不允许领取红包</p>
         </el-form-item>
@@ -230,19 +230,19 @@
       <el-form :inline="true" :model="addBatchData.queryParams" class="library-search">
         <el-form-item label="素材名称">
           <el-input v-model="addBatchData.queryParams.resourceName" placeholder="请输入素材名称" clearable size="small"
-            @keyup.enter.native="resourceList" />
+                    @keyup.enter.native="resourceList" />
         </el-form-item>
         <el-form-item label="类型">
           <el-select v-model="addBatchData.queryParams.typeId" @change="changeCateType" placeholder="请选择素材类型" clearable
-            size="small">
+                     size="small">
             <el-option v-for="item in addBatchData.typeOptions" :key="item.dictValue" :label="item.dictLabel"
-              :value="item.dictValue" />
+                       :value="item.dictValue" />
           </el-select>
         </el-form-item>
         <el-form-item label="子类型">
           <el-select v-model="addBatchData.queryParams.typeSubId" placeholder="请选择素材子类型" clearable size="small">
             <el-option v-for="item in addBatchData.typeSubOptions" :key="item.dictValue" :label="item.dictLabel"
-              :value="item.dictValue" />
+                       :value="item.dictValue" />
           </el-select>
         </el-form-item>
         <el-form-item>
@@ -252,7 +252,7 @@
 
       <!-- 视频列表 -->
       <el-table v-loading="addBatchData.loading" :data="addBatchData.list"
-        @selection-change="handVideoleSelectionChange" height="400px">
+                @selection-change="handVideoleSelectionChange" height="400px">
         <el-table-column type="selection" width="55" align="center" />
         <el-table-column label="素材名称" align="center" prop="resourceName" />
         <el-table-column label="文件名称" align="center" prop="fileName" />
@@ -274,8 +274,8 @@
 
       <!-- 分页 -->
       <pagination v-show="addBatchData.total > 0" :total="addBatchData.total"
-        :page.sync="addBatchData.queryParams.pageNum" :limit.sync="addBatchData.queryParams.pageSize"
-        @pagination="resourceList" />
+                  :page.sync="addBatchData.queryParams.pageNum" :limit.sync="addBatchData.queryParams.pageSize"
+                  @pagination="resourceList" />
 
       <div slot="footer" class="dialog-footer">
         <el-button type="primary" @click="batchVideoSave">确 定</el-button>
@@ -304,9 +304,9 @@
       </div>
     </el-dialog>
     <el-dialog :title="commentDialog.title" :visible.sync="commentDialog.open" width="1000px" append-to-body
-      :close-on-click-modal="false">
+               :close-on-click-modal="false">
       <course-watch-comment ref="courseWatchComment" :courseId="commentDialog.courseId" :videoId="commentDialog.videoId"
-        v-if="commentDialog.open">
+                            v-if="commentDialog.open">
       </course-watch-comment>
     </el-dialog>
 
@@ -429,7 +429,9 @@ export default {
       // 非多个禁用
       multiple: true,
       // 表单参数
-      form: {},
+      form: {
+        courseProducts:[]
+      },
       updateBatchData: {
         open: false,
         form: {}
@@ -779,7 +781,7 @@ export default {
             return
           }
           if (this.form.isProduct != null && this.form.isProduct == 1 && this.form.courseProducts.length < 1) {
-             this.$message({
+            this.$message({
               message: '请选择关联商品',
               type: 'warning'
             });

+ 261 - 0
src/views/components/his/inquiryOrderDetails.vue

@@ -31,6 +31,9 @@
               <div class="operate-button-container" >
                  <el-button size="mini" @click="handledetails()" v-hasPermi="['his:inquiryOrderReport:query']">咨询报告</el-button>
               </div>
+              <div class="operate-button-container" >
+                 <el-button size="mini" @click="handlePatient()" v-hasPermi="['his:inquiryOrderReport:query']">患者诊断数据</el-button>
+              </div>
 
 
              </div>
@@ -93,6 +96,197 @@
              <el-button type="primary" @click="editStatusOpenOk">确 定</el-button>
            </span>
          </el-dialog>
+
+        <el-dialog
+        title="患者问诊数据"
+        :visible.sync="patientOpen"
+        width="1000px"
+        append-to-body>
+          <el-form ref="patientForm" :model="patientForm" label-width="110px" >
+
+            <el-row>
+              <el-col :span="12">
+                <el-form-item label="患者姓名" prop="patientName">
+                  <el-input disabled v-model="item.patientName"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="患者性别" prop="sex">
+                  <el-select disabled v-model="JSON.parse(item.patientJson).sex">
+                    <el-option label="男" :value = "1"></el-option>
+                    <el-option label="女" :value = "0"></el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+            </el-row>
+
+            <el-row>
+              <el-col :span="12">
+                <el-form-item label="患者年龄" prop="age">
+                  <el-input disabled v-model="JSON.parse(item.patientJson).age"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="患者电话" prop="mobile">
+                  <el-input disabled v-model="JSON.parse(item.patientJson).mobile"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+
+            <el-row>
+              <el-col :span="12">
+                <el-form-item label="患者会员电话" prop="userPhone">
+                  <el-input disabled v-model="patientForm.userPhone"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="客户标签" prop="tag">
+                  <el-input  v-model="patientForm.tag"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+
+            <el-row>
+              <el-col :span="12">
+                <el-form-item label="客服姓名" prop="companyUserName">
+                  <el-input disabled v-model="patientForm.companyUserName"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="课程档期" prop="courseName">
+                  <el-input  v-model="patientForm.courseName"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+
+            <el-row>
+              <el-col :span="12">
+                <el-form-item label="预约医生" prop="doctorName">
+                  <el-input disabled v-model="item.doctorName"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="会诊时间" prop="subTime">
+                  <el-date-picker
+                  v-model="patientForm.subTime"
+                  type="date"
+                  value-format="yyyy-MM-dd"
+                  placeholder="选择日期">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+            </el-row>
+
+            <el-row>
+              <el-col :span="12">
+                <el-form-item label="就诊状态" prop="sex">
+                  <el-select  v-model="patientForm.diagnosisStatus">
+                    <el-option label="初诊" :value = "1"></el-option>
+                    <el-option label="复诊" :value = "2"></el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="部门负责人" prop="deptManager">
+                  <el-input v-model="patientForm.deptManager"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+
+            <el-form-item label="患者病情主诉">
+              <el-input
+              type="textarea"
+              placeholder="请输入内容"
+              v-model="patientForm.patientCondition">
+              </el-input>
+            </el-form-item>
+
+            <div class="contentx">
+              <div class="desct">
+                医生建议及处置
+              </div>
+            </div>
+            <el-form-item label="诊断">
+              <el-input
+              type="textarea"
+              placeholder="请输入内容"
+              v-model="patientForm.doctorAdviceJson.diagnosis">
+              </el-input>
+            </el-form-item>
+            <el-form-item label="饮食方面">
+              <el-input
+              type="textarea"
+              placeholder="请输入内容"
+              v-model="patientForm.doctorAdviceJson.foodAdvice">
+              </el-input>
+            </el-form-item>
+            <el-form-item label="运动方面">
+              <el-input
+              type="textarea"
+              placeholder="请输入内容"
+              v-model="patientForm.doctorAdviceJson.sportAdvice">
+              </el-input>
+            </el-form-item>
+            <el-form-item label="保健方面">
+              <el-input
+              type="textarea"
+              placeholder="请输入内容"
+              v-model="patientForm.doctorAdviceJson.healthAdvice">
+              </el-input>
+            </el-form-item>
+
+            <el-form-item label="注意禁忌">
+              <el-input
+              type="textarea"
+              placeholder="请输入内容"
+              v-model="patientForm.taboo">
+              </el-input>
+            </el-form-item>
+            <el-form-item label="客户需求">
+              <el-input  v-model="patientForm.customerRequire"></el-input>
+            </el-form-item>
+            <el-row>
+              <el-col :span="12">
+                <el-form-item label="职业医师" prop="age">
+                  <el-input  v-model="patientForm.professionalDoctor"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="医生助理" prop="mobile">
+                  <el-input  v-model="patientForm.assistantDoctor"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <div class="contentx">
+              <div class="desct">
+                治疗方面
+              </div>
+              </div>
+            <div v-for="(i,index) in patientForm.doctorAdviceJson.treatmentAdvice" :key="index">
+              <el-row>
+                <el-col :span="8">
+                  <el-form-item label="诊断内容" prop="content">
+                    <el-input  v-model="i.content"></el-input>
+                  </el-form-item>
+                </el-col>
+                <el-col :span="8">
+                  <el-form-item label="建议治疗" prop="advice">
+                    <el-input  v-model="i.advice"></el-input>
+                  </el-form-item>
+                </el-col>
+                <el-col :span="8">
+                  <el-button style="margin: 5px;" v-if="index+1 == patientForm.doctorAdviceJson.treatmentAdvice.length" @click="addItem(patientForm.doctorAdviceJson.treatmentAdvice.length)" type="primary" size="mini">+</el-button>
+                  <el-button style="margin: 5px;"  v-if="index !== 0" type="danger" size="mini" @click="delItem(i,index)">-</el-button>
+                </el-col>
+                
+              </el-row>
+            </div>
+          </el-form>
+          <span slot="footer" class="dialog-footer">
+             <el-button @click="patientOpen = false">取 消</el-button>
+             <el-button type="primary" @click="patientInquirySubmit">确 定</el-button>
+          </span>
+        </el-dialog>
  </div>
 
 <div class="contentx" v-if="item!=null">
@@ -259,6 +453,7 @@
 
 <script>
 import { msglist, sendMsg,listinquiryOrder,editStatus, logList,getinquiryOrder, delinquiryOrder, addinquiryOrder, updateinquiryOrder, exportinquiryOrder ,cancelOrder,refundOrder} from "@/api/his/inquiryOrder";
+import {addinquiryPatient, updateinquiryPatient, detail} from "@/api/his/inquiryPatient";
 import {getReportId} from "@/api/his/inquiryOrderReport";
 import msgDetails from '../../components/his/msgDetails.vue';
 import msgServiceDetails from '../../components/his/msgServiceDetails.vue';
@@ -273,6 +468,7 @@ import { js } from "js-beautify";
     components: { inquiryOrderReportDetails,msgDetails ,msgServiceDetails},
     data() {
       return {
+        patientOpen: false,
         logs:[],
         editStatusOpen:false,
         usageJson:{},
@@ -313,6 +509,21 @@ import { js } from "js-beautify";
         doctor:[],
         user:[],
         sexOptions: [],
+        patientForm: {
+          doctorAdviceJson: {
+            diagnosis: '',
+            foodAdvice: '',
+            sportAdvice: '',
+            healthAdvice: '',
+            treatmentAdvice: [
+              //默认一条
+              {
+                content: '',
+                advice: '',
+              }
+            ]
+          }
+        },
       }
     },
     created() {
@@ -340,6 +551,37 @@ import { js } from "js-beautify";
 
     },
     methods: {
+      addItem(length){
+        this.patientForm.doctorAdviceJson.treatmentAdvice.push({
+          content:'',
+          advice:'',
+        })
+        let ak = this.patientForm.doctorAdviceJson.treatmentAdvice.filter(obj => obj.content != '');
+      },
+      delItem(item,index){
+        this.patientForm.doctorAdviceJson.treatmentAdvice.splice(index,1)
+      },
+      handlePatient(){
+        this.patientOpen = true;
+        detail(this.item.orderId).then(res => {
+          this.patientForm = res.data;
+          if(!this.patientForm.doctorAdviceJson) {
+            this.patientForm.doctorAdviceJson = {
+              diagnosis: '',
+              foodAdvice: '',
+              sportAdvice: '',
+              healthAdvice: '',
+              treatmentAdvice: [
+                //默认一条
+                {
+                  content: '',
+                  advice: '',
+                }
+              ]
+            }
+          }
+        })
+      },
       cancelorder(){
         var that=this;
         this.$confirm('是否确认取消订单?', "警告", {
@@ -369,6 +611,25 @@ import { js } from "js-beautify";
           });
           });
       },
+      patientInquirySubmit(){
+        this.patientForm.patientId = this.item.patientId;
+        this.patientForm.companyUserId = this.item.companyUserId;
+        this.patientForm.userId = this.item.userId;
+        this.patientForm.inquiryOrderId = this.item.orderId;
+        this.patientForm.subDoctorId = this.item.doctorId;
+        console.log(this.patientForm);
+        if(this.patientForm.id != null) {
+          updateinquiryPatient(this.patientForm).then(res => {
+            this.msgSuccess("更新成功");
+            this.patientOpen = false;
+          })
+        } else {
+          addinquiryPatient(this.patientForm).then(res => {
+            this.msgSuccess("添加成功");
+            this.patientOpen = false;
+          })
+        }
+      },
       msgServiceDetailsClose(){
         this.msgServiceDetails.open = false;
       },

+ 1 - 1
src/views/components/his/storeOrderDetails.vue

@@ -303,7 +303,6 @@
                          <el-option key="JD"  label="京东" value="JD" />
                          <el-option key="DBL"  label="德邦" value="DBL" />
 						              <el-option key="YD"  label="韵达" value="YD" />
-						              <el-option key="STO"  label="申通" value="STO" />
                        </el-select>
                      </el-form-item>
                     <el-form-item label="物流单号" prop="deliverySn"  >
@@ -470,6 +469,7 @@ import {getCitys} from "@/api/store/city";
           orderId:null,
           deliveryId:null,
           deliveryCode:null,
+          deliverySn: null
         },
         showList:true,
         edit:{

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

@@ -0,0 +1,324 @@
+<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 label="appid" prop="appid">
+        <el-input
+          v-model="queryParams.appid"
+          placeholder="请输入appid"
+          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="['course:playSourceConfig: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="['course:playSourceConfig: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="['course:playSourceConfig:remove']"
+        >删除</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange" border>
+      <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="name" />
+      <el-table-column label="图标" align="center" prop="img">
+        <template slot-scope="scope">
+          <el-image
+            style="width: 80px; height: 80px"
+            :src="scope.row.img"
+            :preview-src-list="[scope.row.img]">
+          </el-image>
+        </template>
+      </el-table-column>
+      <el-table-column label="原始ID" align="center" prop="originalId" />
+      <el-table-column label="appId" align="center" prop="appid" />
+      <el-table-column label="secret" align="center" prop="secret" />
+      <el-table-column label="token" align="center" prop="token" />
+      <el-table-column label="aesKey" align="center" prop="aesKey" />
+      <el-table-column label="msgDataFormat" align="center" prop="msgDataFormat" />
+      <el-table-column label="类型" align="center" prop="type">
+        <template slot-scope="scope">
+          <dict-tag  :options="typesOptions" :value="scope.row.type"/>
+        </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
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['course:playSourceConfig:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['course:playSourceConfig: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="800px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="130px">
+        <el-form-item label="名称" prop="name">
+          <el-input v-model="form.name" placeholder="请输入名称" />
+        </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>
+        <el-form-item label="类型" prop="type">
+          <el-select
+            v-model="form.type"
+            placeholder="请选择类型">
+            <el-option
+              v-for="item in typesOptions"
+              :key="item.dictValue"
+              :label="item.dictLabel"
+              :value="item.dictValue"/>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="原始id" prop="originalId">
+          <el-input v-model="form.originalId" placeholder="请输入原始id" />
+        </el-form-item>
+        <el-form-item label="appid" prop="appid">
+          <el-input v-model="form.appid" placeholder="请输入appid" />
+        </el-form-item>
+        <el-form-item label="secret" prop="secret">
+          <el-input v-model="form.secret" placeholder="请输入secret" />
+        </el-form-item>
+        <el-form-item label="token" prop="token">
+          <el-input v-model="form.token" placeholder="请输入token" />
+        </el-form-item>
+        <el-form-item label="aesKey" prop="aesKey">
+          <el-input v-model="form.aesKey" placeholder="请输入aesKey" />
+        </el-form-item>
+        <el-form-item label="msgDataFormat" prop="msgDataFormat">
+          <el-input v-model="form.msgDataFormat" placeholder="请输入msgDataFormat" />
+        </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 {list, get, update, add, del} from '@/api/course/coursePlaySourceConfig'
+
+export default {
+  name: 'CoursePlaySourceConfig',
+  data() {
+    return {
+      queryParams: {},
+      showSearch: true,
+      single: true,
+      multiple: true,
+      ids: [],
+      loading: false,
+      list: [],
+      total: 0,
+      typesOptions: [],
+      title: null,
+      open: false,
+      form: {},
+      rules: {
+        name: [
+          { required: true, message: "名称不能为空", trigger: "blur" }
+        ],
+        appid: [
+          { required: true, message: "appid不能为空", trigger: "blur" }
+        ],
+        secret: [
+          { required: true, message: "secret不能为空", trigger: "blur" }
+        ],
+        token: [
+          { required: true, message: "token不能为空", trigger: "blur" }
+        ],
+        aesKey: [
+          { required: true, message: "aesKey不能为空", trigger: "blur" }
+        ],
+        msgDataFormat: [
+          { required: true, message: "msgDataFormat不能为空", trigger: "blur" }
+        ]
+      }
+    }
+  },
+  created() {
+    this.getDicts("play_source_type").then(response => {
+      this.typesOptions = response.data.map(item =>  {
+        return {
+        ...item,
+        listClass: 'primary'}
+      })
+    });
+    this.getList();
+  },
+  methods: {
+    getList() {
+      this.loading = true;
+      list(this.queryParams).then(response => {
+        this.list = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.getList();
+    },
+    handleAdd() {
+      this.reset()
+      this.open = true
+      this.title = "添加点播配置"
+    },
+    handleUpdate(row) {
+      this.reset()
+      const id = row.id || this.ids
+      get(id).then(response => {
+        this.form = {
+          ...response.data,
+          type: response.data.type.toString()
+        }
+        this.open = true
+        this.title = "修改点播配置"
+      })
+    },
+    handleDelete(row) {
+      const id = row.id || this.ids
+      this.$confirm('是否确认删除点播配置编号为"' + id + '"的数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function() {
+        return del(id);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("删除成功");
+      }).catch(() => {});
+    },
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            update(this.form).then(response => {
+              const {code, msg} = response
+              if (code !== 200) {
+                this.msgError(msg)
+                return
+              }
+              this.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            add(this.form).then(response => {
+              const {code, msg} = response
+              if (code !== 200) {
+                this.msgError(msg)
+                return
+              }
+              this.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    reset() {
+      this.form = {
+        id: null,
+        name: null,
+        appid: null,
+        secret: null,
+        img: null,
+        originalId: null,
+        token: null,
+        aesKey: null,
+        msgDataFormat: null,
+        type: '1'
+      }
+      this.resetForm("form");
+    }
+  },
+}
+</script>
+
+<style scoped>
+
+</style>

+ 148 - 182
src/views/course/courseTrafficLog/index.vue

@@ -1,261 +1,227 @@
 <template>
   <div class="app-container">
+    <!-- Tab 切换 -->
+    <el-tabs v-model="activeTab" @tab-click="handleTabClick">
+      <el-tab-pane label="公司" name="company"></el-tab-pane>
+      <el-tab-pane label="项目" name="project"></el-tab-pane>
+      <el-tab-pane label="课程" name="course"></el-tab-pane>
+    </el-tabs>
+
+    <!-- 查询条件 -->
     <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="公司名称" prop="companyId" >
-        <el-select v-model="queryParams.companyId" placeholder="请选择所属公司" filterable clearable size="small">
+      <!-- 公司选择 -->
+      <el-form-item label="公司" v-if="activeTab === 'all' || activeTab === 'company'">
+        <el-select v-model="queryParams.companyId" placeholder="请选择公司" filterable clearable size="small">
           <el-option v-for="(option, index) in companyList" :key="index" :value="option.dictValue" :label="option.dictLabel"></el-option>
         </el-select>
       </el-form-item>
-      <el-form-item label="年月" prop="time">
+
+      <!-- 项目选择 -->
+      <el-form-item label="项目" v-if="activeTab === 'all' || activeTab === 'project'">
+        <el-select v-model="queryParams.project" placeholder="请选择项目" filterable clearable size="small">
+          <el-option v-for="dict in projectOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
+        </el-select>
+      </el-form-item>
+
+      <!-- 课程选择 -->
+      <el-form-item label="课程" v-if="activeTab === 'all' || activeTab === 'course'">
+        <el-select v-model="queryParams.courseId" placeholder="请选择课程" filterable clearable size="small">
+          <el-option v-for="dict in courseLists" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
+        </el-select>
+      </el-form-item>
+
+      <!-- 时间选择 -->
+      <el-form-item label="年月">
         <el-date-picker
-          v-model="queryParams.time"
-          type="month"
+          v-model="timeRange"
+          type="daterange"
           placeholder="选择年月"
+          :value-format="'yyyy-MM-dd'"
           :picker-options="pickerOptions"
-          :value-format="'yyyy-MM'"
+          @change="handleDateData"
         ></el-date-picker>
       </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="warning"
-          plain
-          icon="el-icon-download"
-          size="mini"
-          :loading="exportLoading"
-          @click="handleExport"
-          v-hasPermi="['course:courseTrafficLog:export']"
-        >导出</el-button>
-      </el-col>
-      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
-    </el-row>
-
+    <!-- 表格 -->
     <el-table border v-loading="loading" :data="courseTrafficLogList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="公司名称" align="center" prop="companyName" />
-      <el-table-column label="月份" align="center" prop="month" />
+      <!-- 公司列 -->
+      <el-table-column label="公司" align="center" prop="companyName" v-if="activeTab === 'all' || activeTab === 'company'" />
+      <!-- 项目列 -->
+      <el-table-column label="项目" align="center" prop="projectName" v-if="activeTab === 'all' || activeTab === 'project'" />
+      <!-- 课程列 -->
+      <el-table-column label="课程" align="center" prop="courseName" v-if="activeTab === 'all' || activeTab === 'course'" />
+      <el-table-column label="日期" align="center" prop="month" />
       <el-table-column label="使用流量" align="center">
         <template slot-scope="scope">
           <span>{{ formatTrafficData(scope.row.totalInternetTraffic) }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="费用" align="center">
-        <template slot-scope="scope">
-          <span>{{ formatTrafficMoney(scope.row.totalInternetTraffic) }}</span>
-        </template>
-      </el-table-column>
     </el-table>
 
+    <!-- 分页 -->
     <pagination
-      v-show="total>0"
+      v-show="total > 0"
       :total="total"
       :page.sync="queryParams.pageNum"
       :limit.sync="queryParams.pageSize"
       @pagination="getList"
     />
-
   </div>
 </template>
 
 <script>
-import { listCourseTrafficLog, getCourseTrafficLog, delCourseTrafficLog, addCourseTrafficLog, updateCourseTrafficLog, exportCourseTrafficLog } from "@/api/course/courseTrafficLog";
-import { allList } from '../../../api/company/company'
+import { listCourseTrafficLog, exportCourseTrafficLog } from "@/api/course/courseTrafficLog";
+import { courseList } from "@/api/course/courseRedPacketLog";
+import { allList } from "@/api/company/company";
 
 export default {
-  name: "CourseTrafficLog",
   data() {
     return {
-      companyList:[],
+      activeTab: "company", // 默认 tab
+      timeRange: null, // 时间范围单独绑定
+      companyList: [],
+      projectOptions: [],
       pickerOptions: {
-        shortcuts: [{ text: '本月', onClick: () => this.handleShortcut() }],
+        shortcuts: [
+          {
+            text: '今日',
+            onClick(picker) {
+              const start = new Date();
+              const end = new Date();
+              picker.$emit('pick', [start, end]);
+            }
+          },
+          {
+            text: '昨日',
+            onClick(picker) {
+              const start = new Date();
+              start.setDate(start.getDate() - 1);
+              const end = new Date(start);
+              picker.$emit('pick', [start, end]);
+            }
+          },
+          {
+            text: '本周',
+            onClick(picker) {
+              const now = new Date();
+              const day = now.getDay() || 7;
+              const start = new Date(now);
+              start.setDate(now.getDate() - day + 1);
+              const end = new Date();
+              picker.$emit('pick', [start, end]);
+            }
+          },
+          {
+            text: '本月',
+            onClick(picker) {
+              const start = new Date(new Date().setDate(1));
+              const end = new Date();
+              picker.$emit('pick', [start, end]);
+            }
+          }
+        ]
       },
-      // 遮罩层
-      loading: true,
-      // 导出遮罩层
+      courseLists: [],
+      loading: false,
       exportLoading: false,
-      // 选中数组
-      ids: [],
-      // 非单个禁用
-      single: true,
-      // 非多个禁用
-      multiple: true,
-      // 显示搜索条件
       showSearch: true,
-      // 总条数
       total: 0,
-      // 短链课程流量记录表格数据
       courseTrafficLogList: [],
-      // 弹出层标题
-      title: "",
-      // 是否显示弹出层
-      open: false,
-      // 查询参数
       queryParams: {
+        tabType: "", // 当前 tab 类型
+        startDate: null,
+        endDate: null,
         pageNum: 1,
         pageSize: 10,
-        userId: null,
-        videoId: null,
-        qwExternalContactId: null,
-        internetTraffic: null,
-        qwUserId: null,
-        companyUserId: null,
         companyId: null,
-        courseId: null,
-        time:new Date().toISOString().slice(0, 7)
-      },
-      // 表单参数
-      form: {},
-      // 表单校验
-      rules: {
+        project: null,
+        courseId: null
       }
     };
   },
   created() {
-    this.getList();
+    courseList().then(res => this.courseLists = res.list);
+    this.getDicts("sys_course_project").then(res => this.projectOptions = res.data);
     this.getAllCompany();
+    this.getList();
   },
   methods: {
-    getAllCompany() {
-      allList().then(response => {
-        this.companyList = response.rows;
-      });
-    },
-    formatTrafficData(traffic) {
+    handleTabClick(tab) {
+      this.queryParams.tabType = tab.name;
+      this.queryParams.pageNum = 1;
 
-        if (traffic < 1024) { // Less than 1 KB
-          return traffic + ' B';
-        } else if (traffic < 1024 * 1024) { // Less than 1 MB
-          return (traffic / 1024).toFixed(2) + ' KB';
-        } else if (traffic < 1024 * 1024 * 1024) { // Less than 1 GB
-          return (traffic / (1024 * 1024)).toFixed(2) + ' MB';
-        } else { // More than 1 GB
-          return (traffic / (1024 * 1024 * 1024)).toFixed(2) + ' GB';
-        }
+      // 清理互斥参数
+      if (tab.name !== "project") this.queryParams.project = null;
+      if (tab.name !== "course") this.queryParams.courseId = null;
+      if (tab.name !== "company") this.queryParams.companyId = null;
 
-    },
-    formatTrafficMoney(traffic){
-      return (traffic / (1024 * 1024 * 1024) * 0.095).toFixed(2) + ' 元'
+      this.getList();
     },
 
-    handleShortcut() {
-      this.queryParams.time = new Date().toISOString().slice(0, 7);
+    handleDateData() {
+      if (this.timeRange) {
+        this.queryParams.startDate = this.timeRange[0];
+        this.queryParams.endDate = this.timeRange[1];
+      } else {
+        this.queryParams.startDate = null;
+        this.queryParams.endDate = null;
+      }
+    },
+    getAllCompany() {
+      allList().then(res => this.companyList = res.rows);
     },
-    /** 查询短链课程流量记录列表 */
     getList() {
       this.loading = true;
-      listCourseTrafficLog(this.queryParams).then(response => {
-        this.courseTrafficLogList = response.rows;
-        this.total = response.total;
+      listCourseTrafficLog(this.queryParams).then(res => {
+        this.courseTrafficLogList = res.rows;
+        this.total = res.total;
+      }).finally(() => {
         this.loading = false;
       });
     },
-    // 取消按钮
-    cancel() {
-      this.open = false;
-      this.reset();
-    },
-    // 表单重置
-    reset() {
-      this.form = {
-        logId: null,
-        userId: null,
-        videoId: null,
-        createTime: null,
-        qwExternalContactId: null,
-        internetTraffic: null,
-        qwUserId: null,
-        companyUserId: null,
-        companyId: null,
-        courseId: 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.logId)
-      this.single = selection.length!==1
-      this.multiple = !selection.length
-    },
-    /** 新增按钮操作 */
-    handleAdd() {
-      this.reset();
-      this.open = true;
-      this.title = "添加短链课程流量记录";
-    },
-    /** 修改按钮操作 */
-    handleUpdate(row) {
-      this.reset();
-      const logId = row.logId || this.ids
-      getCourseTrafficLog(logId).then(response => {
-        this.form = response.data;
-        this.open = true;
-        this.title = "修改短链课程流量记录";
-      });
+      this.timeRange = null;
+      this.queryParams = {
+        ...this.queryParams,
+        startDate: null,
+        endDate: null,
+        companyId: null,
+        project: null,
+        courseId: null,
+        pageNum: 1,
+      };
+      this.getList();
     },
-    /** 提交按钮 */
-    submitForm() {
-      this.$refs["form"].validate(valid => {
-        if (valid) {
-          if (this.form.logId != null) {
-            updateCourseTrafficLog(this.form).then(response => {
-              this.msgSuccess("修改成功");
-              this.open = false;
-              this.getList();
-            });
-          } else {
-            addCourseTrafficLog(this.form).then(response => {
-              this.msgSuccess("新增成功");
-              this.open = false;
-              this.getList();
-            });
-          }
-        }
-      });
+    formatTrafficData(traffic) {
+      if (traffic < 1024) return `${traffic} B`;
+      if (traffic < 1024 ** 2) return `${(traffic / 1024).toFixed(2)} KB`;
+      if (traffic < 1024 ** 3) return `${(traffic / 1024 ** 2).toFixed(2)} MB`;
+      return `${(traffic / 1024 ** 3).toFixed(2)} GB`;
     },
-    /** 删除按钮操作 */
-    handleDelete(row) {
-      const logIds = row.logId || this.ids;
-      this.$confirm('是否确认删除短链课程流量记录编号为"' + logIds + '"的数据项?', "警告", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        }).then(function() {
-          return delCourseTrafficLog(logIds);
-        }).then(() => {
-          this.getList();
-          this.msgSuccess("删除成功");
-        }).catch(() => {});
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.logId);
     },
-    /** 导出按钮操作 */
     handleExport() {
-      const queryParams = this.queryParams;
-      this.$confirm('是否确认导出所有短链课程流量记录数据项?', "警告", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        }).then(() => {
-          this.exportLoading = true;
-          return exportCourseTrafficLog(queryParams);
-        }).then(response => {
-          this.download(response.msg);
-          this.exportLoading = false;
-        }).catch(() => {});
+      this.$confirm("确认导出数据?", "提示").then(() => {
+        this.exportLoading = true;
+        return exportCourseTrafficLog(this.queryParams);
+      }).then(res => {
+        this.download(res.msg);
+      }).finally(() => {
+        this.exportLoading = false;
+      });
     }
   }
 };

+ 5 - 5
src/views/course/userCoursePeriod/index.vue

@@ -275,7 +275,7 @@
             start-placeholder="开始日期"
             end-placeholder="结束日期"
             value-format="yyyy-MM-dd"
-            :picker-options="{disabledDate}"
+            :picker-options="{}"
             :clearable="false"
           >
           </el-date-picker>
@@ -287,7 +287,7 @@
             type="date"
             value-format="yyyy-MM-dd"
             placeholder="选择日期"
-            :picker-options="{disabledDate}"
+            :picker-options="{}"
             :clearable="false"
           >
           </el-date-picker>
@@ -1712,9 +1712,9 @@ export default {
       this.updatePeriodDate.form = {id: row.id, dayDate: row.dayDate};
       this.updatePeriodDate.open = true;
     },
-    disabledDate(time) {
-      return time.getTime() < new Date(new Date().setHours(0,0,0,0));
-    },
+    // disabledDate(time) {
+    //   return time.getTime() < new Date(new Date().setHours(0,0,0,0));
+    // },
     getPickerOptions() {
       // 如果已选择看课时间范围,则领取红包时间应在看课时间范围内
       if (this.updateCourse.form.timeRange &&

+ 26 - 1
src/views/course/userCoursePeriod/statistics.vue

@@ -18,6 +18,22 @@
             />
           </el-select>
         </el-form-item>
+
+        <el-form-item label="公司">
+          <el-select
+            v-model="queryParams.companyId"
+            placeholder="请选择公司"
+            clearable
+            style="width: 400px"
+          >
+            <el-option
+              v-for="item in companyOptions"
+              :key="item.companyId"
+              :label="item.companyName"
+              :value="item.companyId"
+            />
+          </el-select>
+        </el-form-item>
         <el-form-item>
           <el-button type="primary" @click="handleQuery">查询</el-button>
         </el-form-item>
@@ -112,7 +128,7 @@
 </template>
 
 <script>
-import {getDays, periodCountSelect} from "@/api/course/userCoursePeriod";
+import {getDays, periodCountSelect, getPeriodCompanyList} from "@/api/course/userCoursePeriod";
 
 export default {
   name: "CourseStatistics",
@@ -134,6 +150,7 @@ export default {
       total: 0,
       // 课程选项
       courseOptions: [],
+      companyOptions: [],
       // 统计数据
       statistics: {
         courseCompleteNum: 0,
@@ -182,8 +199,16 @@ export default {
     initializeData() {
       this.getCourseOptions();
       this.getCountList();
+      this.getCompanyOptions()
       this.initialized = true;
     },
+    getCompanyOptions() {
+      getPeriodCompanyList({
+        periodId: this.periodId
+      }).then(response => {
+        this.companyOptions = response.data || [];
+      });
+    },
     /** 获取课程选项 */
     getCourseOptions() {
       this.loading = true;

+ 92 - 1
src/views/course/videoResource/index.vue

@@ -66,6 +66,16 @@
           v-hasPermi="['course:videoResource:batchAdd']"
         >批量新增</el-button>
       </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          icon="el-icon-plus"
+          size="mini"
+          :disabled="multiple"
+          @click="handleBatchUpdate"
+          v-hasPermi="['course:videoResource:batchUpdateClass']"
+        >批量修改分类</el-button>
+      </el-col>
       <el-col :span="1.5">
         <el-button
           type="danger"
@@ -340,6 +350,37 @@
       <video ref="up-video" id="video" width="100%" height="400px" controls :src="videoPreviewUrl" />
     </el-dialog>
 
+    <!--批量修改弹框-->
+    <minimizable-dialog :title="'批量修改'" :visible.sync="batchUpdateVisible" width="700px" append-to-body :before-close="cancel"
+                        @minimize="hasMinimizableDialog = true" @restore="hasMinimizableDialog = false">
+      <el-form ref="form" :model="batchUpdateForm" :rules="rules" label-width="80px">
+      <el-form-item label="分类" prop="typeId">
+          <el-select v-model="batchUpdateForm.typeId" placeholder="请选择分类" style="width: 100%" @change="val => changeCateType(val, 2)">
+            <el-option
+              v-for="item in rootTypeList"
+              :key="item.dictValue"
+              :label="item.dictLabel"
+              :value="item.dictValue">
+            </el-option>
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="子分类" prop="typeSubId">
+          <el-select v-model="batchUpdateForm.typeSubId" clearable placeholder="请选择子分类" style="width: 100%">
+            <el-option
+              v-for="item in subTypeList"
+              :key="item.dictValue"
+              :label="item.dictLabel"
+              :value="item.dictValue">
+            </el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <div class="dialog-footer">
+        <el-button @click="cancelBatch">取 消</el-button>
+        <el-button type="primary" @click="submitBatchUpdate">保 存</el-button>
+      </div>
+    </minimizable-dialog>
     <!-- 批量选择视频弹窗 -->
     <minimizable-dialog :title="'选择视频'" :visible.sync="batchAddVisible" width="1200px" append-to-body class="batch-dialog" :close-on-click-modal="false" :before-close="cancelBeforeBatch"
                         @minimize="hasMinimizableDialog = true" @restore="hasMinimizableDialog = false">
@@ -720,7 +761,8 @@ import {
   getVideoResource,
   listVideoResource,
   updateVideoResource,
-  batchAddVideoResource
+  batchAddVideoResource,
+  batchUpdateVideoResource
 } from '@/api/course/videoResource'
 import {listUserCourseCategory,getCatePidList,getCateListByPid} from '@/api/course/userCourseCategory'
 import {getByIds, listCourseQuestionBank} from '@/api/course/courseQuestionBank'
@@ -828,6 +870,15 @@ export default {
       batchLoading: false,
       videoList: [],
 
+      // 批量修改相关
+      batchUpdateVisible: false,
+      batchUpdateLoading: false,
+      batchUpdateForm: {
+        typeId: null,
+        typeSubId: null,
+        ids: [],
+      },
+
       // 批量上传相关
       showUpload: false,
       batchUploadForm: {
@@ -1383,6 +1434,17 @@ export default {
       this.batchAddVisible = true;
       this.videoList = []; // 清空之前的视频列表
     },
+    /** 批量修改 */
+    handleBatchUpdate(){
+      if (this.ids.length === 0) {
+        this.$message.warning("请至少选择一条数据");
+        return;
+      }
+      this.batchUpdateForm.typeId = null;
+      this.batchUpdateForm.typeSubId = null;
+      this.batchUpdateForm.ids = this.ids; // 将选中的ID传递给批量修改表单
+      this.batchUpdateVisible = true;
+    },
     cancelBeforeBatch(done, cancel) {
       if (!this.videoList || this.videoList.length === 0) {
         done()
@@ -1414,6 +1476,35 @@ export default {
       }).catch(() => {
       });
     },
+    /** 批量修改 */
+    submitBatchUpdate() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.batchUpdateForm.ids.length === 0) {
+            this.$message.warning("未选择任何数据");
+            return;
+          }
+
+          this.$confirm('是否确认修改视频素材库编号为"' + this.batchUpdateForm.ids.join(',') + '"的数据项?', "警告", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          }).then(() => {
+            // 构造正确的参数格式
+            const params = new URLSearchParams();
+            params.append('typeId', this.batchUpdateForm.typeId || '');
+            params.append('typeSubId', this.batchUpdateForm.typeSubId || '');
+            params.append('ids', this.batchUpdateForm.ids.join(','));
+
+            return batchUpdateVideoResource(params);
+          }).then(() => {
+            this.getList();
+            this.batchUpdateVisible = false;
+            this.msgSuccess("修改成功");
+          }).catch(() => {});
+        }
+      });
+    },
 
     /** 提交批量添加 */
     submitBatchAdd() {

+ 302 - 0
src/views/food/record/index.vue

@@ -0,0 +1,302 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="用户ID" prop="userId">
+        <el-input
+          v-model="queryParams.userId"
+          placeholder="请输入用户ID"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="用餐日期" prop="recordDate">
+        <el-date-picker clearable
+                        v-model="queryParams.recordDate"
+                        type="date"
+                        value-format="yyyy-MM-dd"
+                        placeholder="请选择用餐日期">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="用餐描述" prop="mealDescription">
+        <el-input
+          v-model="queryParams.mealDescription"
+          placeholder="请输入用餐描述"
+          clearable
+          @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="['food:record: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="['food:record: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="['food:record:remove']"
+        >删除</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="foodRecordList" @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="username" >
+        <template slot-scope="scope">
+          <span>{{scope.row.username}}</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="用餐日期" align="center" prop="recordDate" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.recordDate, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="记录时间" align="center" prop="recordTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ scope.row.recordTime }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="用餐描述" align="center" prop="mealDescription" :show-overflow-tooltip="true" />
+      <el-table-column label="创建时间" align="center" prop="createdAt" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createdAt, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+        </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="['food:record:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['food:record: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="用户ID" prop="userId">
+          <el-input v-model="form.userId" placeholder="请输入用户ID" />
+        </el-form-item>
+        <el-form-item label="用餐日期" prop="recordDate">
+          <el-date-picker clearable
+                          v-model="form.recordDate"
+                          type="date"
+                          value-format="yyyy-MM-dd"
+                          placeholder="请选择用餐日期">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="记录时间" prop="recordTime">
+          <el-time-picker
+            v-model="form.recordTime"
+            value-format="HH:mm:ss"
+            placeholder="请选择记录时间">
+          </el-time-picker>
+        </el-form-item>
+        <el-form-item label="用餐描述" prop="mealDescription">
+          <el-input v-model="form.mealDescription" type="textarea" 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 { listFoodRecord, getFoodRecord, delFoodRecord, addFoodRecord, updateFoodRecord } from "@/api/food/record";
+import {parseTime} from "../../../utils/common";
+
+export default {
+  name: "FoodRecord",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 饮食记录表格数据
+      foodRecordList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        userId: null,
+        recordDate: null,
+        mealDescription: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        userId: [
+          { required: true, message: "用户ID不能为空", trigger: "blur" }
+        ],
+        recordDate: [
+          { required: true, message: "用餐日期不能为空", trigger: "blur" }
+        ],
+        mealDescription: [
+          { required: true, message: "用餐描述不能为空", trigger: "blur" }
+        ]
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    parseTime,
+    /** 查询饮食记录列表 */
+    getList() {
+      this.loading = true;
+      listFoodRecord(this.queryParams).then(response => {
+        this.foodRecordList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        userId: null,
+        recordDate: null,
+        recordTime: null,
+        mealDescription: null,
+        createdAt: null,
+        updatedAt: 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
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加饮食记录";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getFoodRecord(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) {
+            updateFoodRecord(this.form).then(response => {
+              this.$message.success("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addFoodRecord(this.form).then(response => {
+              this.$message.success("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm('是否确认删除饮食记录编号为"' + ids + '"的数据项?').then(function() {
+        return delFoodRecord(ids);
+      }).then(() => {
+        this.getList();
+        this.$message.success("删除成功");
+      }).catch(() => {});
+    }
+  }
+};
+</script>

+ 16 - 1
src/views/his/company/index.vue

@@ -472,6 +472,7 @@ export default {
         courseMaAppId: null,
         courseMiniAppId: null,
         miniAppMaster: [],
+        miniAppServer:[],
         miniAppList: [],
       },
       // 表单校验
@@ -753,9 +754,15 @@ export default {
     submitForm() {
       this.$refs["form"].validate(valid => {
         if (valid) {
-          if(this.form.followDoctorIds!=null){
+
+          if (this.form.followDoctorIds==null || this.form.followDoctorIds.length==0){
+            this.form.followDoctorIds=null;
+          }
+
+          if(this.form.followDoctorIds!=null && this.form.followDoctorIds.length>0){
              this.form.followDoctorIds= JSON.stringify(this.form.followDoctorIds)
           }
+
           if(this.form.packageCateIds!=null){
              this.form.packageCateIds= JSON.stringify(this.form.packageCateIds)
           }
@@ -765,6 +772,14 @@ export default {
           if(this.doctorIds!=null){
             this.form.doctorIds= (this.doctorIds).toString()
           }
+          if (this.form.miniAppMaster==null || this.form.miniAppMaster.length ===0 ){
+            return this.$message.error("请选择主小程序")
+          }
+
+          if (this.form.miniAppServer==null || this.form.miniAppServer.length ===0 ){
+            return this.$message.error("请选择备小程序")
+          }
+
           if (this.form.companyId != null) {
             updateCompany(this.form).then(response => {
               this.msgSuccess("修改成功");

+ 252 - 0
src/views/his/statistics/ipadStatic.vue

@@ -0,0 +1,252 @@
+<template>
+    <div class="app-container">
+      <el-card>
+        <div slot="header" class="clearfix">
+          <span>设备绑定统计</span>
+        </div>
+
+        <el-tabs v-model="activeTab" @tab-click="handleTabClick">
+          <el-tab-pane label="按天统计" name="daily">
+            <el-form :inline="true" class="demo-form-inline">
+              <el-form-item label="日期">
+                <el-date-picker
+                  v-model="dailyDate"
+                  type="date"
+                  placeholder="选择日期"
+                  value-format="yyyy-MM-dd"
+                  @change="handleDailyDateChange"
+                ></el-date-picker>
+              </el-form-item>
+
+              <el-form-item>
+                <el-button type="primary" @click="searchDaily">查询</el-button>
+                <el-button @click="resetDaily">重置</el-button>
+                <el-button type="success" @click="exportDaily">导出</el-button>
+              </el-form-item>
+            </el-form>
+
+            <el-table
+              v-loading="dailyLoading"
+              border
+              :data="companyList"
+              style="width: 100%"
+            >
+              <el-table-column prop="date" label="日期" width="180" />
+              <el-table-column prop="companyName" label="公司名称" />
+              <el-table-column prop="bindCount" label="绑定台数" />
+            </el-table>
+
+            <div class="chart-container" style="margin-top: 20px; height: 400px">
+              <div ref="dailyChart" style="height: 100%; width: 100%"></div>
+            </div>
+          </el-tab-pane>
+
+          <el-tab-pane label="按月统计" name="monthly">
+            <el-form :inline="true" class="demo-form-inline">
+              <el-form-item label="月份">
+                <el-date-picker
+                  v-model="monthlyDate"
+                  type="month"
+                  placeholder="选择月份"
+                  value-format="yyyy-MM"
+                  @change="handleMonthlyDateChange"
+                ></el-date-picker>
+              </el-form-item>
+
+              <el-form-item>
+                <el-button type="primary" @click="searchMonthly">查询</el-button>
+                <el-button @click="resetMonthly">重置</el-button>
+                <el-button type="success" @click="exportMonthly">导出</el-button>
+              </el-form-item>
+            </el-form>
+
+            <el-table
+              v-loading="monthlyLoading"
+              border
+              :data="companyList"
+              style="width: 100%"
+            >
+              <el-table-column prop="date" label="月份" width="180" />
+              <el-table-column prop="companyName" label="公司名称" />
+              <el-table-column prop="bindCount" label="绑定台数" />
+            </el-table>
+
+            <div class="chart-container" style="margin-top: 20px; height: 400px">
+              <div ref="monthlyChart" style="height: 100%; width: 100%"></div>
+            </div>
+          </el-tab-pane>
+        </el-tabs>
+      </el-card>
+    </div>
+  </template>
+
+  <script>
+  import { ipadStaticTotal,exportIpadStaticByTime} from "@/api/company/statistics";
+
+  export default {
+    name: 'ipadStatic',
+    data() {
+      const today = this.parseTime(new Date(), '{y}-{m}-{d}')
+      const yesterday = this.parseTime(new Date(new Date().getTime() - 24 * 60 * 60 * 1000), '{y}-{m}-{d}')
+      return {
+        // 激活的标签页
+        activeTab: 'daily',
+        // 按天统计数据
+        dailyLoading: false,
+        dailyDate: yesterday, // 默认当天
+        // 按月统计数据
+        monthlyLoading: false,
+        monthlyDate: this.parseTime(new Date(), '{y}-{m}'), // 默认当月
+        companyList: [],
+      }
+    },
+    created() {
+      // 获取当天数据
+      this.getList()
+    },
+    methods: {
+      // 标签页切换
+      handleTabClick(tab) {
+        if (tab.name === 'daily') {
+          this.getList()
+        } else if (tab.name === 'monthly') {
+          this.getMonthlyList()
+        }
+      },
+
+      // 按天统计相关方法
+      handleDailyDateChange(val) {
+        if (val) {
+          this.dailyDate = val
+        }
+      },
+      searchDaily() {
+        this.getList()
+      },
+      resetDaily() {
+        const today = this.parseTime(new Date(), '{y}-{m}-{d}')
+        const yesterday = this.parseTime(new Date(new Date().getTime() - 24 * 60 * 60 * 1000), '{y}-{m}-{d}')
+        this.dailyDate = yesterday
+        this.getList()
+      },
+
+      // 导出
+      exportDaily() {
+        this.$confirm("是否确认导出数据项?", "警告", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning",
+        })
+            .then(() => {
+            this.exportLoading = true;
+            return exportIpadStaticByTime(this.dailyDate);
+            })
+            .then((response) => {
+            this.download(response.msg);
+            this.exportLoading = false;
+            })
+            .catch(() => { });
+      },
+      getList() {
+        this.dailyLoading = true
+        ipadStaticTotal(this.dailyDate).then(response => {
+          // 处理返回数据,添加日期字段用于表格和图表显示
+          this.companyList = response.list;
+          this.dailyLoading = false;
+        }).catch(() => {
+          this.dailyLoading = false;
+        });
+      },
+
+      // 按月统计相关方法
+      handleMonthlyDateChange(val) {
+        if (val) {
+          this.monthlyDate = val
+        }
+      },
+      searchMonthly() {
+        this.getMonthlyList()
+      },
+      resetMonthly() {
+        this.monthlyDate = this.parseTime(new Date(), '{y}-{m}')
+        this.getMonthlyList()
+      },
+      exportMonthly() {
+        this.$confirm("是否确认导出数据项?", "警告", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning",
+        })
+            .then(() => {
+            this.exportLoading = true;
+            return exportIpadStaticByTime(this.monthlyDate);
+            })
+            .then((response) => {
+            this.download(response.msg);
+            this.exportLoading = false;
+            })
+            .catch(() => { });
+      },
+      getMonthlyList() {
+        this.monthlyLoading = true
+        ipadStaticTotal(this.monthlyDate).then(response => {
+          // 处理返回数据,添加月份字段用于表格和图表显示
+          this.companyList = response.list;
+          this.monthlyLoading = false;
+        }).catch(() => {
+          this.monthlyLoading = false;
+          this.monthlyTotal = 0;
+        });
+      },
+
+      // 日期格式化
+      parseTime(time, pattern) {
+        let date;
+        if (arguments.length === 0 || !time) {
+          return null
+        }
+        const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
+
+        if (typeof time === 'object') {
+          date = time
+        } else {
+          if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
+            time = parseInt(time)
+          } else if (typeof time === 'string') {
+            time = time.replace(new RegExp(/-/gm), '/')
+          }
+          if ((typeof time === 'number') && (time.toString().length === 10)) {
+            time = time * 1000
+          }
+          date = new Date(time)
+        }
+        const formatObj = {
+          y: date.getFullYear(),
+          m: date.getMonth() + 1,
+          d: date.getDate(),
+          h: date.getHours(),
+          i: date.getMinutes(),
+          s: date.getSeconds(),
+          a: date.getDay()
+        }
+        const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+          let value = formatObj[key]
+          // Note: getDay() returns 0 on Sunday
+          if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
+          if (result.length > 0 && value < 10) {
+            value = '0' + value
+          }
+          return value || 0
+        })
+        return time_str
+      }
+    }
+  }
+  </script>
+
+  <style scoped>
+  .chart-container {
+    position: relative;
+    padding: 20px 0;
+  }
+  </style>

+ 5 - 71
src/views/his/user/index.vue

@@ -1,40 +1,6 @@
 <template>
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="所属公司" prop="companyName">
-        <el-select
-          v-model="queryCompanyId"
-          placeholder="请选择所属公司"
-          clearable
-          filterable
-          size="small"
-          @change="handleQueryCompanyChange"
-        >
-          <el-option
-            v-for="item in companyQueryOptions"
-            :key="item.companyId"
-            :label="item.companyName"
-            :value="item.companyId">
-          </el-option>
-        </el-select>
-      </el-form-item>
-      <el-form-item label="所属销售" prop="companyUserId">
-
-        <el-select
-          v-model="queryCompanyUserId"
-          placeholder="请选择所属销售"
-          clearable
-          filterable
-          size="small"
-        >
-          <el-option
-            v-for="item in companyQueryUserOptions"
-            :key="item.userId"
-            :label="item.nickName"
-            :value="item.userId">
-          </el-option>
-        </el-select>
-      </el-form-item>
       <el-form-item label="会员ID" prop="userId">
         <el-input
           v-model="queryParams.userId"
@@ -149,8 +115,7 @@
               <dict-tag :options="userOptions" :value="scope.row.status"/>
          </template>
       </el-table-column>
-      <el-table-column label="所属公司" align="center" prop="companyName" />
-      <el-table-column label="所属销售" align="center" prop="companyUserNickName" />
+      <el-table-column label="用户备注" align="center" prop="remark" />
       <el-table-column label="上级昵称" align="center" prop="tuiName" />
       <el-table-column label="app来源" align="center" prop="source" />
       <el-table-column label="登陆设备" align="center" prop="loginDevice" />
@@ -261,10 +226,6 @@ export default {
   components: {userDetails,userDetailsByNew},
   data() {
     return {
-      companyQueryOptions:[],
-      companyQueryUserOptions:[],
-      queryCompanyId:null,
-      queryCompanyUserId:null,
       companyName: null,
       companyUserNickName: null,
       companyOptions: [],
@@ -321,6 +282,7 @@ export default {
         isBuy:null,
         source:null,
         companyName: null,
+        userId: null
       },
       // 表单参数
       form: {},
@@ -368,10 +330,6 @@ export default {
     this.getDicts("sys_company_or").then(response => {
       this.orOptions = response.data;
     });
-    getCompanyList().then(response => {
-        if (response.code === 200) {
-          this.companyQueryOptions = response.data;
-        }});
   },
   methods: {
     /** 销售选择变化 */
@@ -397,26 +355,6 @@ export default {
                  this.$refs.userDetailsByNew.getDetails(row.userId);
             }, 1);
      },
-     handleQueryCompanyChange(companyId){
-      // 清空已选择的销售
-      this.queryCompanyUserId = null;
-      // 根据公司ID获取对应的销售列表
-      if (companyId) {
-        getCompanyUserList({ companyId: companyId }).then(response => {
-          if (response.code === 200) {
-            this.companyQueryUserOptions = response.data;
-          } else {
-            this.$message.error(response.msg || '获取销售列表失败');
-            this.companyQueryUserOptions = [];
-          }
-        }).catch(() => {
-          this.$message.error('获取销售列表失败');
-          this.companyQueryUserOptions = [];
-        });
-      } else {
-        this.companyQueryUserOptions = [];
-      }
-     },
     /** 查询用户列表 */
     getList() {
       this.loading = true;
@@ -459,8 +397,6 @@ export default {
     /** 搜索按钮操作 */
     handleQuery() {
       this.queryParams.pageNum = 1;
-      this.queryParams.companyId = this.queryCompanyId;
-      this.queryParams.companyUserId = this.queryCompanyUserId;
       this.getList();
     },
     /** 重置按钮操作 */
@@ -469,10 +405,6 @@ export default {
        this.createTime=null;
       this.queryParams.sTime=null;
       this.queryParams.eTime=null;
-      this.queryParams.companyName = null;
-      this.queryParams.companyUserNickName = null;
-      this.queryParams.companyId = null;
-      this.queryParams.companyUserId = null;
       this.handleQuery();
     },
     // 多选框选中数据
@@ -574,7 +506,9 @@ export default {
         }).then(response => {
           this.download(response.msg);
           this.exportLoading = false;
-        }).catch(() => {});
+        }).catch(() => {
+          this.exportLoading = false;
+      });
     },
   }
 };

+ 35 - 15
src/views/his/user/indexProject.vue

@@ -30,7 +30,7 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="注册时间" prop="createTimeRange">
+      <el-form-item label="绑定时间" prop="createTimeRange">
         <el-date-picker clearable size="small" style="width: 340px"
                         v-model="dateRange"
                         type="daterange"
@@ -186,7 +186,7 @@
       <el-table-column label="用户余额" align="center" prop="nowMoney" />
       <!--      <el-table-column label="推广佣金" align="center" prop="brokeragePrice" />-->
       <el-table-column label="积分" align="center" prop="integral" />
-      <el-table-column label="会员注册时间" align="center" prop="createTime" />
+      <el-table-column label="绑定时间" align="center" prop="bindTime" width="100" />
       <!--      <el-table-column label="累计消费金额" align="center" prop="totalAmount" />-->
       <!--      <el-table-column label="上次消费时间" align="center" prop="lastBuyTime" />-->
       <!--      <el-table-column label="上次消费金额(元)" align="center" prop="number" />-->
@@ -226,13 +226,13 @@
       </el-table-column>
       <el-table-column label="操作" align="center"  width="150px"   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:user:edit']"
-          >修改</el-button>
+<!--          <el-button-->
+<!--            size="mini"-->
+<!--            type="text"-->
+<!--            icon="el-icon-edit"-->
+<!--            @click="handleUpdate(scope.row)"-->
+<!--            v-hasPermi="['store:user:edit']"-->
+<!--          >修改</el-button>-->
 
           <el-button
             size="mini"
@@ -450,7 +450,8 @@ export default {
         startCreateTime: null,
         endCreateTime: null,
         companyId: null,
-        companyUserNickName: null
+        companyUserNickName: null,
+        userId: null
       },
       // 表单参数
       form: {},
@@ -489,7 +490,7 @@ export default {
     };
   },
   created() {
-    this.getDicts("user_status").then((response) => {
+    this.getDicts("project_user_status").then((response) => {
       this.statusOptions = response.data;
     });
     this.getDicts("user_level").then((response) => {
@@ -598,6 +599,8 @@ export default {
       this.queryParams.companyId = null;
       this.queryParams.companyUserNickName = null;
       this.companyQueryUserOptions = null;
+      this.queryParams.startCreateTime = null
+      this.queryParams.endCreateTime = null
       this.handleQuery();
     },
     /** 处理日期范围变化 */
@@ -629,10 +632,27 @@ export default {
       const userId = row.userId || this.ids
       getUser(userId).then(response => {
         this.form = response.data;
-        this.form.status = response.data.status.toString();
-        this.form.isShow = response.data.isShow.toString();
-        this.form.level = response.data.level.toString();
-        this.form.isPromoter = response.data.isPromoter.toString();
+        if(response.data.status){
+          this.form.status = response.data.status.toString();
+        } else {
+          this.form.status = null;
+        }
+        if(response.data.isShow){
+          this.form.isShow = response.data.isShow.toString();
+        }else {
+          this.form.isShow = null;
+        }
+        if(response.data.level){
+          this.form.level = response.data.level.toString();
+        }else {
+          this.form.level = null;
+        }
+        if(response.data.isPromoter){
+          this.form.isPromoter = response.data.isPromoter.toString();
+        }else {
+          this.form.status = null;
+        }
+
         this.open = true;
         this.title = "修改用户";
       });

+ 394 - 0
src/views/hisStore/express/index.vue

@@ -0,0 +1,394 @@
+<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="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:express: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:express: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:express:remove']"
+        >删除</el-button>
+      </el-col>
+	  <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table  height="500" border v-loading="loading" :data="expressList" @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="code" />
+      <el-table-column label="快递公司" align="center" prop="name" />
+      <el-table-column label="OMS编号" align="center" prop="omsCode" />
+      <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="handleAllot(scope.row)"
+            v-hasPermi="['store:express:allot']"
+          >分配公司</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['store:express:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['store:express: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="120px">
+        <el-form-item label="快递公司简称" prop="code">
+          <el-input v-model="form.code" placeholder="请输入快递公司简称" />
+        </el-form-item>
+        <el-form-item label="快递公司全称" prop="name">
+          <el-input v-model="form.name" placeholder="请输入快递公司全称" />
+        </el-form-item>
+        <el-form-item label="OMS编号" prop="omsCode">
+          <el-input v-model="form.omsCode" placeholder="请输入快递公司简称" />
+        </el-form-item>
+        <el-form-item label="排序" prop="sort">
+          <el-input-number :min="0"  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="allot.title" :visible.sync="allot.open" width="1100px"   append-to-body>
+      <el-transfer
+        filterable
+        width="960px"
+        :filter-method="filterMethod"
+        filter-placeholder="请输入公司名称"
+        v-model="value"
+        :titles="['所有公司', '已选公司']"
+        :right-default-checked="value"
+        :data="allCompanies">
+      </el-transfer>
+      <div slot="footer" class="dialog-footer">
+          <el-button type="primary" @click="handleAllotCompany">分 配</el-button>
+          <el-button @click="cancel1">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listExpress, getExpress, delExpress, addExpress, updateExpress, exportExpress ,allotExpress ,getExpressList,getCompanyByOmsCode} from "@/api/hisStore/express";
+import { getCompanyList} from "@/api/company/company";
+export default {
+  name: "Express",
+  data() {
+    return {
+
+      formId:null,
+        value: [],
+        value2:[],
+        filterMethod(query, item) {
+          return item.label.indexOf(query) > -1;
+        },
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      allCompanies:undefined,
+      allot:{
+        title:"分配公司",
+        open:false,
+      },
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 快递公司表格数据
+      expressList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        code: null,
+        name: null,
+        sort: null,
+        isShow: null,
+        isDel: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        code: [
+          { required: true, message: "快递公司简称不能为空", trigger: "blur" }
+        ],
+        omsCode: [
+          { required: true, message: "OMS编号不能为空", trigger: "blur" }
+        ],
+        name: [
+          { required: true, message: "快递公司全称不能为空", trigger: "blur" }
+        ],
+        sort: [
+          { required: true, message: "排序不能为空", trigger: "blur" }
+        ],
+        isShow: [
+          { required: true, message: "是否显示不能为空", trigger: "blur" }
+        ],
+      }
+    };
+  },
+  created() {
+    this.getList();
+
+  },
+
+  methods: {
+    handleAllotCompany(){
+      console.log(this.value);
+      allotExpress(this.value,this.formId).then(response => {
+      if (response.code === 200) {
+      this.msgSuccess("修改成功");
+      this.allot.open = false;
+      this.getList();
+      }
+      });
+    },
+
+    /** 查询快递公司列表 */
+    getList() {
+      this.loading = true;
+      listExpress(this.queryParams).then(response => {
+        this.expressList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    cancel1() {
+      this.allot.open = false;
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        code: null,
+        omsCode: null,
+        name: null,
+        sort: null,
+        isShow: null,
+        createTime: null,
+        updateTime: 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
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加快递公司";
+    },
+    /**分配公司按钮 */
+    handleAllot(row){
+      this.allot.open = true;
+      this.formId = row.omsCode;
+      getCompanyList().then(response => {
+      let data = [];
+      response.data.forEach((item,index) => {
+        data.push({
+          key: item.companyId,
+          label:item.companyName,
+        })
+      });
+      this.allCompanies = data;
+    });
+    const omsCode = row.omsCode;
+    getCompanyByOmsCode(omsCode).then(response => {
+      this.value = response.data2
+      console.log(this.value);
+    });
+
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getExpress(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) {
+            updateExpress(this.form).then(response => {
+              if (response.code === 200) {
+                this.msgSuccess("修改成功");
+                this.open = false;
+                this.getList();
+              }
+            });
+          } else {
+            addExpress(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 delExpress(ids);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(function() {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有快递公司数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return exportExpress(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+        }).catch(function() {});
+    }
+  },
+};
+</script>
+<style scoped lang="scss">
+.container {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 20px;
+}
+.box {
+  width: 300px;
+}
+.el-scrollbar {
+  max-height: 300px;
+  overflow-y: auto; /* 添加滚动条 */
+}
+/* 新增样式 */
+.container {
+  display: flex;
+  justify-content: center;
+  align-items: flex-start;
+}
+.box {
+  margin: 0 10px;
+}
+
+/deep/.el-transfer-panel {
+    width:40%;
+}
+/deep/.el-transfer-panel__body{
+  height: 450px;
+}
+/deep/.el-transfer-panel__list.is-filterable {
+   height: 88%;
+}
+
+</style>
+

+ 443 - 0
src/views/hisStore/shippingTemplates/index.vue

@@ -0,0 +1,443 @@
+<template>
+  <div class="app-container">
+
+    <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:shippingTemplates: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:shippingTemplates: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:shippingTemplates:remove']"
+        >删除</el-button>
+      </el-col>
+	  <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table  height="500" border v-loading="loading" :data="shippingTemplatesList" @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="name" />
+      <el-table-column label="计费方式" align="center" prop="type" >
+          <template slot-scope="scope">
+              <el-tag prop="type" v-for="(item, index) in typeOptions"    v-if="scope.row.type==item.dictValue">{{item.dictLabel}}</el-tag>
+          </template>
+      </el-table-column>
+      <el-table-column label="指定包邮开关" align="center" prop="appoint" >
+          <template slot-scope="scope">
+              <el-tag prop="type" v-for="(item, index) in appointOptions"    v-if="scope.row.appoint==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="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:shippingTemplates:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['store:shippingTemplates: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="800px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="130px">
+        <el-form-item label="模板名称" prop="name">
+          <el-input v-model="form.name" placeholder="请输入模板名称" />
+        </el-form-item>
+        <el-form-item label="计费方式" prop="type">
+            <el-radio-group v-model="form.type" >
+               <el-radio :label="item.dictValue" v-for="item in typeOptions" >{{item.dictLabel}}</el-radio>-radio>
+            </el-radio-group>
+        </el-form-item>
+        <el-row :gutter="24" type="flex">
+          <el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24">
+            <el-form-item class="label" label="配送区域及运费:" props="state">
+              <el-table
+                ref="table"
+                :data="templateList"
+                empty-text="暂无数据"
+                border
+              >
+                <el-table-column prop="regionName" label="可配送区域" width="130" />
+                <el-table-column prop="first" label="首件" width="120">
+                  <template slot="header" slot-scope="scope">
+                    <span v-if="form.type == 1">首件</span>
+                    <span v-else-if="form.type == 2">首件重量(KG)</span>
+                    <span v-else>首件体积(m³)</span>
+                  </template>
+                  <template slot-scope="scope">
+                    <span><el-input type="text" v-model="scope.row.first" /></span>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="price" label="运费(元)" width="110">
+                  <template slot-scope="scope">
+                    <span><el-input type="text" v-model="scope.row.price"/></span>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="_continue" label="续件" width="120">
+                  <template slot="header" slot-scope="scope">
+                    <span v-if="form.type == 1">续件</span>
+                    <span v-else-if="form.type == 2">续件重量(KG)</span>
+                    <span v-else>续件体积(m³)</span>
+                  </template>
+                  <template slot-scope="scope">
+                    <span><el-input type="text" v-model="scope.row.continues"/></span>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="continuePrice" label="续费(元)" width="110">
+                  <template slot-scope="scope">
+                    <span><el-input type="text" v-model="scope.row.continuePrice"/></span>
+                  </template>
+                </el-table-column>
+                <el-table-column  label="操作">
+                  <template slot-scope="scope">
+                    <a v-if="scope.row.regionName!=='默认全国'" @click="delCity(scope.row.index,1)">删除</a>
+                  </template>
+                </el-table-column>
+
+              </el-table>
+              <el-row type="flex" class="addTop">
+                <el-col>
+                  <el-button size="small" type="primary" icon="md-add" @click="addCity(1)">单独添加配送区域</el-button>
+                </el-col>
+              </el-row>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="24" type="flex">
+          <el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24">
+            <el-form-item label="指定包邮:" prop="appoint">
+              <el-radio-group v-model="form.appoint" >
+                    <el-radio :label="item.dictValue" v-for="item in appointOptions" >{{item.dictLabel}}</el-radio>-radio>
+                  </el-radio-group>
+              <el-table
+                ref="table"
+                :data="appointList"
+                empty-text="暂无数据"
+                border
+                v-if="form.appoint === '1'"
+              >
+                <el-table-column prop="placeName" label="选择地区" />
+                <el-table-column prop="a_num" label="包邮件数" width="120" >
+                  <template slot="header" slot-scope="scope">
+                    <span v-if="form.type == 1">包邮件数</span>
+                    <span v-else-if="form.type == 2">包邮重量(KG)</span>
+                    <span v-else>包邮体积(m³)</span>
+                  </template>
+                  <template slot-scope="scope">
+                    <span><el-input type="text" v-model="scope.row.number"/></span>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="price" label="包邮金额(元)" width="120">
+                  <template slot-scope="scope">
+                    <span><el-input type="text" v-model="scope.row.price"/></span>
+                  </template>
+                </el-table-column>
+                <el-table-column  label="操作">
+                  <template slot-scope="scope">
+                    <a v-if="scope.row.regionName!=='默认全国'" @click="delCity(scope.row.index,2)">删除</a>
+                  </template>
+                </el-table-column>
+
+              </el-table>
+              <el-row type="flex" v-if="form.appoint === '1'">
+                <el-col>
+                  <el-button size="small" type="primary" icon="md-add" @click="addCity(2)">单独指定包邮</el-button>
+                </el-col>
+              </el-row>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="排序" prop="sort">
+          <el-input-number :min="0"  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>
+    <city ref="city" @selectCity="selectCity" :type="type"></city>
+  </div>
+</template>
+
+<script>
+import { listShippingTemplates, getShippingTemplates, delShippingTemplates, addShippingTemplates, updateShippingTemplates, exportShippingTemplates } from "@/api/hisStore/shippingTemplates";
+import City from '@/components/City'
+export default {
+  name: "ShippingTemplates",
+  components: {
+    City
+  },
+  data() {
+    return {
+      type:0,
+      appointList:[],
+      templateList:[],
+      appointOptions:[],
+      typeOptions:[],
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 运费模板表格数据
+      shippingTemplatesList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        name: null,
+        type: null,
+        regionInfo: null,
+        appoint: null,
+        appointInfo: null,
+        isDel: null,
+        sort: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        name: [
+          { required: true, message: "名称不能为空", trigger: "blur" }
+        ],
+      }
+    };
+  },
+  created() {
+    this.getDicts("store_shipping_type").then((response) => {
+      this.typeOptions = response.data;
+    });
+    this.getDicts("store_shipping_appoint").then((response) => {
+      this.appointOptions = response.data;
+    });
+    this.getList();
+  },
+  methods: {
+    delCity (index,type) {
+      console.log(index)
+      if (type === 1) {
+        this.templateList.splice(index, 1);
+      } else {
+        this.appointList.splice(index, 1);
+      }
+    },
+    selectCity: function (data, type) {
+      let cityName = data.map(function (item) {
+        return item.name;
+      }).join(';');
+      switch (type) {
+        case 1:
+          this.templateList.push({
+            region: data,
+            regionName: cityName,
+            first: 1,
+            price: 0,
+            continues: 1,
+            continuePrice: 0
+          });
+          break;
+        case 2:
+          this.appointList.push({
+            place: data,
+            placeName: cityName,
+            number: 0,
+            price: 0
+          });
+          break;
+      }
+    },
+    // 单独添加配送区域
+    addCity (type) {
+      this.$refs.city.addressView = true;
+      this.type = type;
+      this.$refs.city.getCityList()
+    },
+    /** 查询运费模板列表 */
+    getList() {
+      this.loading = true;
+      listShippingTemplates(this.queryParams).then(response => {
+        this.shippingTemplatesList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        name: null,
+        type: "1",
+        appoint: "0",
+        createTime: null,
+        updateTime: null,
+        isDel: null,
+        sort: null
+      };
+      this.templateList = [
+        {
+          region: [
+            {
+              name: '默认全国',
+              cityId: 0
+            }
+          ],
+          regionName: '默认全国',
+          first: 1,
+          price: 0,
+          continues: 1,
+          continuePrice: 0
+        }
+      ];
+      this.appointList=[],
+      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
+      getShippingTemplates(id).then(response => {
+        this.form = response.data;
+        this.form.type = response.data.type.toString();
+        this.form.appoint = response.data.appoint.toString();
+        this.appointList=JSON.parse(this.form.appointInfo)
+        this.templateList=JSON.parse(this.form.regionInfo)
+        this.open = true;
+        this.title = "修改运费模板";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          this.form.regionInfo=this.templateList;
+          this.form.appointInfo=this.appointList;
+          if (this.form.id != null) {
+            updateShippingTemplates(this.form).then(response => {
+              if (response.code === 200) {
+                this.msgSuccess("修改成功");
+                this.open = false;
+                this.getList();
+              }
+            });
+          } else {
+            addShippingTemplates(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 delShippingTemplates(ids);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(function() {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有运费模板数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return exportShippingTemplates(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+        }).catch(function() {});
+    }
+  }
+};
+</script>

+ 366 - 0
src/views/hisStore/shippingTemplatesFree/index.vue

@@ -0,0 +1,366 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="模板ID" prop="tempId">
+        <el-input
+          v-model="queryParams.tempId"
+          placeholder="请输入模板ID"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="省ID" prop="provinceId">
+        <el-input
+          v-model="queryParams.provinceId"
+          placeholder="请输入省ID"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="城市ID" prop="cityId">
+        <el-input
+          v-model="queryParams.cityId"
+          placeholder="请输入城市ID"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="包邮件数" prop="number">
+        <el-input
+          v-model="queryParams.number"
+          placeholder="请输入包邮件数"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="包邮金额" prop="price">
+        <el-input
+          v-model="queryParams.price"
+          placeholder="请输入包邮金额"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="计费方式" prop="type">
+        <el-select v-model="queryParams.type" placeholder="请选择计费方式" clearable size="small">
+          <el-option label="请选择字典生成" value="" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="产品ID" prop="productId">
+        <el-input
+          v-model="queryParams.productId"
+          placeholder="请输入产品ID"
+          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:shippingTemplatesFree: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:shippingTemplatesFree: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:shippingTemplatesFree: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:shippingTemplatesFree:export']"
+        >导出</el-button>
+      </el-col>
+	  <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="shippingTemplatesFreeList" @selection-change="handleSelectionChange" border>
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="编号" align="center" prop="id" />
+      <el-table-column label="模板ID" align="center" prop="tempId" />
+      <el-table-column label="省ID" align="center" prop="provinceId" />
+      <el-table-column label="城市ID" align="center" prop="cityId" />
+      <el-table-column label="包邮件数" align="center" prop="number" />
+      <el-table-column label="包邮金额" align="center" prop="price" />
+      <el-table-column label="计费方式" align="center" prop="type" />
+      <el-table-column label="产品ID" align="center" prop="productId" />
+      <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:shippingTemplatesFree:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['store:shippingTemplatesFree: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="模板ID" prop="tempId">
+          <el-input v-model="form.tempId" placeholder="请输入模板ID" />
+        </el-form-item>
+        <el-form-item label="省ID" prop="provinceId">
+          <el-input v-model="form.provinceId" placeholder="请输入省ID" />
+        </el-form-item>
+        <el-form-item label="城市ID" prop="cityId">
+          <el-input v-model="form.cityId" placeholder="请输入城市ID" />
+        </el-form-item>
+        <el-form-item label="包邮件数" prop="number">
+          <el-input v-model="form.number" placeholder="请输入包邮件数" />
+        </el-form-item>
+        <el-form-item label="包邮金额" prop="price">
+          <el-input v-model="form.price" placeholder="请输入包邮金额" />
+        </el-form-item>
+        <el-form-item label="计费方式" prop="type">
+          <el-select v-model="form.type" placeholder="请选择计费方式">
+            <el-option label="请选择字典生成" value="" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="产品ID" prop="productId">
+          <el-input v-model="form.productId" placeholder="请输入产品ID" />
+        </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 { listShippingTemplatesFree, getShippingTemplatesFree, delShippingTemplatesFree, addShippingTemplatesFree, updateShippingTemplatesFree, exportShippingTemplatesFree } from "@/api/hisStore/shippingTemplatesFree";
+
+export default {
+  name: "ShippingTemplatesFree",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 免邮费表格数据
+      shippingTemplatesFreeList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        tempId: null,
+        provinceId: null,
+        cityId: null,
+        number: null,
+        price: null,
+        type: null,
+        productId: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        tempId: [
+          { required: true, message: "模板ID不能为空", trigger: "blur" }
+        ],
+        provinceId: [
+          { required: true, message: "省ID不能为空", trigger: "blur" }
+        ],
+        cityId: [
+          { required: true, message: "城市ID不能为空", trigger: "blur" }
+        ],
+        number: [
+          { required: true, message: "包邮件数不能为空", trigger: "blur" }
+        ],
+        price: [
+          { required: true, message: "包邮金额不能为空", trigger: "blur" }
+        ],
+        type: [
+          { required: true, message: "计费方式不能为空", trigger: "change" }
+        ],
+        productId: [
+          { required: true, message: "产品ID不能为空", trigger: "blur" }
+        ]
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询免邮费列表 */
+    getList() {
+      this.loading = true;
+      listShippingTemplatesFree(this.queryParams).then(response => {
+        this.shippingTemplatesFreeList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        tempId: null,
+        provinceId: null,
+        cityId: null,
+        number: null,
+        price: null,
+        type: null,
+        productId: 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
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加免邮费";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getShippingTemplatesFree(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) {
+            updateShippingTemplatesFree(this.form).then(response => {
+              if (response.code === 200) {
+                this.msgSuccess("修改成功");
+                this.open = false;
+                this.getList();
+              }
+            });
+          } else {
+            addShippingTemplatesFree(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 delShippingTemplatesFree(ids);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(function() {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有免邮费数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return exportShippingTemplatesFree(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+        }).catch(function() {});
+    }
+  }
+};
+</script>

+ 402 - 0
src/views/hisStore/shippingTemplatesRegion/index.vue

@@ -0,0 +1,402 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="省ID" prop="provinceId">
+        <el-input
+          v-model="queryParams.provinceId"
+          placeholder="请输入省ID"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="模板ID" prop="tempId">
+        <el-input
+          v-model="queryParams.tempId"
+          placeholder="请输入模板ID"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="城市ID" prop="cityId">
+        <el-input
+          v-model="queryParams.cityId"
+          placeholder="请输入城市ID"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="首件" prop="first">
+        <el-input
+          v-model="queryParams.first"
+          placeholder="请输入首件"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="首件运费" prop="firstPrice">
+        <el-input
+          v-model="queryParams.firstPrice"
+          placeholder="请输入首件运费"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="续件" prop="continues">
+        <el-input
+          v-model="queryParams.continues"
+          placeholder="请输入续件"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="续件运费" prop="continuePrice">
+        <el-input
+          v-model="queryParams.continuePrice"
+          placeholder="请输入续件运费"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="计费方式" prop="type">
+        <el-select v-model="queryParams.type" placeholder="请选择计费方式" clearable size="small">
+          <el-option label="请选择字典生成" value="" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="分组唯一值" prop="productId">
+        <el-input
+          v-model="queryParams.productId"
+          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:shippingTemplatesRegion: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:shippingTemplatesRegion: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:shippingTemplatesRegion: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:shippingTemplatesRegion:export']"
+        >导出</el-button>
+      </el-col>
+	  <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="shippingTemplatesRegionList" @selection-change="handleSelectionChange" border>
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="编号" align="center" prop="id" />
+      <el-table-column label="省ID" align="center" prop="provinceId" />
+      <el-table-column label="模板ID" align="center" prop="tempId" />
+      <el-table-column label="城市ID" align="center" prop="cityId" />
+      <el-table-column label="首件" align="center" prop="first" />
+      <el-table-column label="首件运费" align="center" prop="firstPrice" />
+      <el-table-column label="续件" align="center" prop="continues" />
+      <el-table-column label="续件运费" align="center" prop="continuePrice" />
+      <el-table-column label="计费方式" align="center" prop="type" />
+      <el-table-column label="分组唯一值" align="center" prop="productId" />
+      <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:shippingTemplatesRegion:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['store:shippingTemplatesRegion: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="省ID" prop="provinceId">
+          <el-input v-model="form.provinceId" placeholder="请输入省ID" />
+        </el-form-item>
+        <el-form-item label="模板ID" prop="tempId">
+          <el-input v-model="form.tempId" placeholder="请输入模板ID" />
+        </el-form-item>
+        <el-form-item label="城市ID" prop="cityId">
+          <el-input v-model="form.cityId" placeholder="请输入城市ID" />
+        </el-form-item>
+        <el-form-item label="首件" prop="first">
+          <el-input v-model="form.first" placeholder="请输入首件" />
+        </el-form-item>
+        <el-form-item label="首件运费" prop="firstPrice">
+          <el-input v-model="form.firstPrice" placeholder="请输入首件运费" />
+        </el-form-item>
+        <el-form-item label="续件" prop="continues">
+          <el-input v-model="form.continues" placeholder="请输入续件" />
+        </el-form-item>
+        <el-form-item label="续件运费" prop="continuePrice">
+          <el-input v-model="form.continuePrice" placeholder="请输入续件运费" />
+        </el-form-item>
+        <el-form-item label="计费方式" prop="type">
+          <el-select v-model="form.type" placeholder="请选择计费方式">
+            <el-option label="请选择字典生成" value="" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="分组唯一值" prop="productId">
+          <el-input v-model="form.productId" 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 { listShippingTemplatesRegion, getShippingTemplatesRegion, delShippingTemplatesRegion, addShippingTemplatesRegion, updateShippingTemplatesRegion, exportShippingTemplatesRegion } from "@/api/hisStore/shippingTemplatesRegion";
+
+export default {
+  name: "ShippingTemplatesRegion",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 邮费区域表格数据
+      shippingTemplatesRegionList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        provinceId: null,
+        tempId: null,
+        cityId: null,
+        first: null,
+        firstPrice: null,
+        continues: null,
+        continuePrice: null,
+        type: null,
+        productId: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        provinceId: [
+          { required: true, message: "省ID不能为空", trigger: "blur" }
+        ],
+        tempId: [
+          { required: true, message: "模板ID不能为空", trigger: "blur" }
+        ],
+        cityId: [
+          { required: true, message: "城市ID不能为空", trigger: "blur" }
+        ],
+        first: [
+          { required: true, message: "首件不能为空", trigger: "blur" }
+        ],
+        firstPrice: [
+          { required: true, message: "首件运费不能为空", trigger: "blur" }
+        ],
+        continues: [
+          { required: true, message: "续件不能为空", trigger: "blur" }
+        ],
+        continuePrice: [
+          { required: true, message: "续件运费不能为空", trigger: "blur" }
+        ],
+        type: [
+          { required: true, message: "计费方式不能为空", trigger: "change" }
+        ],
+        productId: [
+          { required: true, message: "分组唯一值不能为空", trigger: "blur" }
+        ]
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询邮费区域列表 */
+    getList() {
+      this.loading = true;
+      listShippingTemplatesRegion(this.queryParams).then(response => {
+        this.shippingTemplatesRegionList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        provinceId: null,
+        tempId: null,
+        cityId: null,
+        first: null,
+        firstPrice: null,
+        continues: null,
+        continuePrice: null,
+        type: null,
+        productId: 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
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加邮费区域";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getShippingTemplatesRegion(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) {
+            updateShippingTemplatesRegion(this.form).then(response => {
+              if (response.code === 200) {
+                this.msgSuccess("修改成功");
+                this.open = false;
+                this.getList();
+              }
+            });
+          } else {
+            addShippingTemplatesRegion(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 delShippingTemplatesRegion(ids);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(function() {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有邮费区域数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return exportShippingTemplatesRegion(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+        }).catch(function() {});
+    }
+  }
+};
+</script>

+ 747 - 580
src/views/hisStore/storeOrder/healthStoreList.vue

@@ -1,22 +1,22 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form v-show="showSearch" ref="queryForm" :inline="true" :model="queryParams" label-width="68px">
 
       <el-form-item label="订单号" prop="orderCode">
         <el-input
           v-model="queryParams.orderCode"
-          placeholder="请输入订单号"
           clearable
+          placeholder="请输入订单号"
           size="small"
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
 
-       <el-form-item label="运单号" prop="deliveryId">
+      <el-form-item label="运单号" prop="deliveryId">
         <el-input
           v-model="queryParams.deliveryId"
-          placeholder="请输入运单号"
           clearable
+          placeholder="请输入运单号"
           size="small"
           @keyup.enter.native="handleQuery"
         />
@@ -25,8 +25,8 @@
       <el-form-item label="手机号" prop="userPhone">
         <el-input
           v-model="queryParams.userPhone"
-          placeholder="请输入手机号"
           clearable
+          placeholder="请输入手机号"
           size="small"
           @keyup.enter.native="handleQuery"
         />
@@ -35,8 +35,8 @@
         <el-input
 
           v-model="queryParams.realName"
-          placeholder="请输入收件人姓名"
           clearable
+          placeholder="请输入收件人姓名"
           size="small"
           @keyup.enter.native="handleQuery"
         />
@@ -46,104 +46,112 @@
         <el-input
 
           v-model="queryParams.productName"
-          placeholder="请输入产品名"
           clearable
+          placeholder="请输入产品名"
           size="small"
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-<!--      <el-form-item label="订单类型" prop="orderType">
-         <el-select   v-model="queryParams.orderType" placeholder="请选择订单类型" clearable size="small" >
-         <el-option
-                v-for="item in orderTypeOptions"
-                :key="item.dictValue"
-                :label="item.dictLabel"
-                :value="item.dictValue"
-              />
-        </el-select>
-      </el-form-item>-->
-<!--      <el-form-item label="上传凭证" prop="isUpload">
-         <el-select   v-model="queryParams.isUpload" placeholder="请选择" clearable size="small" >
-          <el-option key="0"  label="未上传" value="0" />
-             <el-option key="1"  label="已上传" value="1" />
-        </el-select>
-      </el-form-item>-->
+      <!--      <el-form-item label="订单类型" prop="orderType">
+               <el-select   v-model="queryParams.orderType" placeholder="请选择订单类型" clearable size="small" >
+               <el-option
+                      v-for="item in orderTypeOptions"
+                      :key="item.dictValue"
+                      :label="item.dictLabel"
+                      :value="item.dictValue"
+                    />
+              </el-select>
+            </el-form-item>-->
+      <!--      <el-form-item label="上传凭证" prop="isUpload">
+               <el-select   v-model="queryParams.isUpload" placeholder="请选择" clearable size="small" >
+                <el-option key="0"  label="未上传" value="0" />
+                   <el-option key="1"  label="已上传" value="1" />
+              </el-select>
+            </el-form-item>-->
       <el-form-item label="物流状态" prop="deliveryStatus">
-         <el-select   v-model="queryParams.deliveryStatus" placeholder="请选择物流状态" clearable size="small" >
-         <el-option
-                v-for="item in deliveryStatusOptions"
-                :key="item.dictValue"
-                :label="item.dictLabel"
-                :value="item.dictValue"
-              />
+        <el-select v-model="queryParams.deliveryStatus" clearable placeholder="请选择物流状态" size="small">
+          <el-option
+            v-for="item in deliveryStatusOptions"
+            :key="item.dictValue"
+            :label="item.dictLabel"
+            :value="item.dictValue"
+          />
         </el-select>
       </el-form-item>
       <el-form-item label="结算状态" prop="deliveryPayStatus">
-         <el-select style="width: 200px" v-model="queryParams.deliveryPayStatus" placeholder="请选择物流结算状态" clearable size="small" >
-         <el-option
-                v-for="item in deliveryPayStatusOptions"
-                :key="item.dictValue"
-                :label="item.dictLabel"
-                :value="item.dictValue"
-              />
+        <el-select v-model="queryParams.deliveryPayStatus" clearable placeholder="请选择物流结算状态"
+                   size="small" style="width: 200px"
+        >
+          <el-option
+            v-for="item in deliveryPayStatusOptions"
+            :key="item.dictValue"
+            :label="item.dictLabel"
+            :value="item.dictValue"
+          />
         </el-select>
       </el-form-item>
-        <el-form-item label="支付方式" prop="payType">
-         <el-select style="width: 200px" v-model="queryParams.payType" placeholder="请选择支付方式" clearable size="small" >
-         <el-option
-                v-for="item in payTypeOptions"
-                :key="item.dictValue"
-                :label="item.dictLabel"
-                :value="item.dictValue"
-              />
+      <el-form-item label="支付方式" prop="payType">
+        <el-select v-model="queryParams.payType" clearable placeholder="请选择支付方式" size="small"
+                   style="width: 200px"
+        >
+          <el-option
+            v-for="item in payTypeOptions"
+            :key="item.dictValue"
+            :label="item.dictLabel"
+            :value="item.dictValue"
+          />
         </el-select>
       </el-form-item>
       <el-form-item label="下单时间" prop="createTimeRange">
         <el-date-picker
-          style="width:205.4px"
-          clearable size="small"
           v-model="createTimeRange"
+          clearable end-placeholder="结束日期"
+          size="small"
+          start-placeholder="开始日期"
+          style="width:205.4px"
           type="daterange"
           value-format="yyyy-MM-dd"
-          start-placeholder="开始日期"
-          end-placeholder="结束日期">
+        >
         </el-date-picker>
       </el-form-item>
       <el-form-item label="支付时间" prop="payTimeRange">
         <el-date-picker
-          style="width:205.4px"
-          clearable size="small"
           v-model="payTimeRange"
+          clearable end-placeholder="结束日期"
+          size="small"
+          start-placeholder="开始日期"
+          style="width:205.4px"
           type="daterange"
           value-format="yyyy-MM-dd"
-          start-placeholder="开始日期"
-          end-placeholder="结束日期">
+        >
         </el-date-picker>
       </el-form-item>
       <el-form-item label="发货时间" prop="deliverySendTimeRange">
         <el-date-picker
-          style="width:205.4px"
-          clearable size="small"
           v-model="deliverySendTimeRange"
+          clearable end-placeholder="结束日期"
+          size="small"
+          start-placeholder="开始日期"
+          style="width:205.4px"
           type="daterange"
           value-format="yyyy-MM-dd"
-          start-placeholder="开始日期"
-          end-placeholder="结束日期">
+        >
         </el-date-picker>
       </el-form-item>
       <el-form-item label="回单时间" prop="deliveryImportTimeRange">
         <el-date-picker
-          style="width:205.4px"
-          clearable size="small"
           v-model="deliveryImportTimeRange"
+          clearable end-placeholder="结束日期"
+          size="small"
+          start-placeholder="开始日期"
+          style="width:205.4px"
           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" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-search" size="mini" type="cyan" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
       </el-form-item>
     </el-form>
@@ -158,30 +166,43 @@
         >创建订单</el-button>
       </el-col> -->
       <el-col :span="1.5">
-            <el-button  plain type="info" icon="el-icon-upload2" size="mini" @click="handleImport" v-hasPermi="['store:storeOrder:importExpress']">导入银行回单</el-button>
+        <el-button v-hasPermi="['store:storeOrder:importExpress']" icon="el-icon-upload2" plain size="mini" type="info"
+                   @click="handleImport"
+        >导入银行回单
+        </el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button
-            type="warning"
+          v-hasPermi="['store:healthStoreOrder:export']"
           icon="el-icon-download"
           size="mini"
-            @click="handleExport"
-          v-hasPermi="['store:healthStoreOrder:export']"
-        >导出订单</el-button>
+          type="warning"
+          @click="handleExport"
+        >导出订单
+        </el-button>
       </el-col>
-        <el-col :span="1.5">
+      <el-col :span="1.5">
         <el-button
-            type="warning"
+          v-hasPermi="['store:healthStoreOrder:exportItems']"
           icon="el-icon-download"
           size="mini"
-            @click="handleExportItems"
-          v-hasPermi="['store:healthStoreOrder:exportItems']"
-        >导出订单明细</el-button>
+          type="warning"
+          @click="handleExportItems"
+        >导出订单明细
+        </el-button>
       </el-col>
-
-	  <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+      <el-col :span="1.5">
+        <el-button
+          icon="el-icon-s-order"
+          size="mini"
+          type="warning"
+          @click="openDeliveryNote"
+        >批量更新订单状态
+        </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-tabs v-model="activeName" type="card" @tab-click="handleClick">
       <el-tab-pane label="全部订单" name="00"></el-tab-pane>
       <el-tab-pane label="待支付" name="0"></el-tab-pane>
       <el-tab-pane label="待发货" name="1"></el-tab-pane>
@@ -191,18 +212,18 @@
       <el-tab-pane label="已退款" name="-2"></el-tab-pane>
       <el-tab-pane label="已取消" name="-3"></el-tab-pane>
     </el-tabs>
-    <el-table  height="500" border v-loading="loading" :data="storeOrderList" @selection-change="handleSelectionChange">
-      <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="订单号" align="center" prop="orderCode" width="200px" />
-      <el-table-column label="用户昵称" align="center" prop="nickname" width="150px" >
-          <template slot-scope="scope">
-              <span>{{scope.row.nickname}} </span>
-          </template>
+    <el-table v-loading="loading" :data="storeOrderList" border height="500" @selection-change="handleSelectionChange">
+      <el-table-column align="center" type="selection" width="55"/>
+      <el-table-column align="center" label="订单号" prop="orderCode" width="200px"/>
+      <el-table-column align="center" label="用户昵称" prop="nickname" width="150px">
+        <template slot-scope="scope">
+          <span>{{ scope.row.nickname }} </span>
+        </template>
       </el-table-column>
-      <el-table-column label="收件人" align="center" prop="realName" width="150px" >
-          <template slot-scope="scope">
-              <span>{{scope.row.realName}} </span>
-          </template>
+      <el-table-column align="center" label="收件人" prop="realName" width="150px">
+        <template slot-scope="scope">
+          <span>{{ scope.row.realName }} </span>
+        </template>
       </el-table-column>
       <!-- <el-table-column label="商品" align="center" width="300px" >
           <template slot-scope="scope">
@@ -217,54 +238,65 @@
               </div>
           </template>
       </el-table-column> -->
-      <el-table-column label="订单金额" align="center" prop="totalPrice" >
-          <template slot-scope="scope">
-              <span v-if="scope.row.totalPrice!=null">{{scope.row.totalPrice.toFixed(2)}}</span>
-          </template>
+      <el-table-column align="center" label="订单金额" prop="totalPrice">
+        <template slot-scope="scope">
+          <span v-if="scope.row.totalPrice!=null">{{ scope.row.totalPrice.toFixed(2) }}</span>
+        </template>
       </el-table-column>
-       <el-table-column label="应付金额" align="center" prop="payPrice" >
-          <template slot-scope="scope">
-              <span v-if="scope.row.payPrice!=null">{{scope.row.payPrice.toFixed(2)}}</span>
-          </template>
+      <el-table-column align="center" label="应付金额" prop="payPrice">
+        <template slot-scope="scope">
+          <span v-if="scope.row.payPrice!=null">{{ scope.row.payPrice.toFixed(2) }}</span>
+        </template>
       </el-table-column>
-      <el-table-column label="下单时间" align="center" prop="createTime" />
+      <el-table-column align="center" label="下单时间" prop="createTime"/>
       <!-- <el-table-column label="支付状态" align="center" prop="paid" /> -->
-      <el-table-column label="支付时间" align="center" prop="payTime" width="180">
+      <el-table-column align="center" label="支付时间" prop="payTime" width="180">
       </el-table-column>
-      <el-table-column label="支付方式" align="center" prop="payType" >
-          <template slot-scope="scope">
-              <el-tag prop="payType" v-for="(item, index) in payTypeOptions"    v-if="scope.row.payType==item.dictValue">{{item.dictLabel}}</el-tag>
-          </template>
+      <el-table-column align="center" label="支付方式" prop="payType">
+        <template slot-scope="scope">
+          <el-tag v-for="(item, index) in payTypeOptions" v-if="scope.row.payType==item.dictValue" prop="payType">
+            {{ item.dictLabel }}
+          </el-tag>
+        </template>
       </el-table-column>
-<!--      <el-table-column label="订单类型" align="center" prop="orderType" >
-          <template slot-scope="scope">
-              <el-tag prop="status" v-for="(item, index) in orderTypeOptions"    v-if="scope.row.orderType==item.dictValue">{{item.dictLabel}}</el-tag>
-          </template>
-      </el-table-column>-->
-      <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 label="订单类型" align="center" prop="orderType" >
+                <template slot-scope="scope">
+                    <el-tag prop="status" v-for="(item, index) in orderTypeOptions"    v-if="scope.row.orderType==item.dictValue">{{item.dictLabel}}</el-tag>
+                </template>
+            </el-table-column>-->
+      <el-table-column align="center" label="状态" prop="status">
+        <template slot-scope="scope">
+          <el-tag v-for="(item, index) in statusOptions" v-if="scope.row.status==item.dictValue" prop="status">
+            {{ item.dictLabel }}
+          </el-tag>
+        </template>
       </el-table-column>
-      <el-table-column label="物流状态" align="center" prop="deliveryStatus" >
-          <template slot-scope="scope">
-              <el-tag prop="status" v-for="(item, index) in deliveryStatusOptions"    v-if="scope.row.deliveryStatus==item.dictValue">{{item.dictLabel}}</el-tag>
-          </template>
+      <el-table-column align="center" label="物流状态" prop="deliveryStatus">
+        <template slot-scope="scope">
+          <el-tag v-for="(item, index) in deliveryStatusOptions" v-if="scope.row.deliveryStatus==item.dictValue"
+                  prop="status"
+          >{{ item.dictLabel }}
+          </el-tag>
+        </template>
       </el-table-column>
-      <el-table-column label="物流结算状态" align="center" prop="deliveryPayStatus" >
-          <template slot-scope="scope">
-              <el-tag prop="status" v-for="(item, index) in deliveryPayStatusOptions"    v-if="scope.row.deliveryPayStatus==item.dictValue">{{item.dictLabel}}</el-tag>
-          </template>
+      <el-table-column align="center" label="物流结算状态" prop="deliveryPayStatus">
+        <template slot-scope="scope">
+          <el-tag v-for="(item, index) in deliveryPayStatusOptions" v-if="scope.row.deliveryPayStatus==item.dictValue"
+                  prop="status"
+          >{{ item.dictLabel }}
+          </el-tag>
+        </template>
       </el-table-column>
 
-      <el-table-column label="操作" fixed="right" width="80px" align="center">
+      <el-table-column align="center" fixed="right" label="操作" width="80px">
         <template slot-scope="scope">
           <el-button
+            v-hasPermi="['store:storeOrder:query']"
             size="mini"
             type="text"
             @click="handleDetails(scope.row)"
-            v-hasPermi="['store:storeOrder:query']"
-          >查看</el-button>
+          >查看
+          </el-button>
           <!-- <el-button
             size="mini"
             type="text"
@@ -277,242 +309,316 @@
 
     <pagination
       v-show="total>0"
-      :total="total"
-      :page.sync="queryParams.pageNum"
       :limit.sync="queryParams.pageSize"
+      :page.sync="queryParams.pageNum"
+      :total="total"
       @pagination="getList"
     />
     <el-drawer
-     size="75%"
-      :title="show.title" :visible.sync="show.open"
-      >
-      <product-order  ref="order" />
+      :title="show.title"
+      :visible.sync="show.open" size="75%"
+    >
+      <product-order ref="order"/>
     </el-drawer>
 
 
-     <el-dialog :title="title" v-if="open" :visible.sync="open" width="1000px" append-to-body>
-        <el-form ref="form" :model="form" :rules="rules" label-width="120px">
-           <el-form-item label="会员信息" prop="userId">
-                <el-row  >
-                  <el-col >
-                      <el-input placeholder="请输入会员手机号" style="width:240px;cursor:pointer" v-model="phone">
-                      </el-input>
-                      <el-button plain style="margin-left:10px;"    @click="searchUser()">查询</el-button>
-                      <el-button plain style="margin-left:10px;" icon="el-icon-plus"  type="primary" @click="handleAddUser()">添加会员</el-button>
-                  </el-col>
-                </el-row>
-                <el-table border style="margin-top:5px;"  v-loading="userloading" :data="users">
-                  <el-table-column label="ID" align="center" prop="userId" />
-                  <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="nickname" />
-                  <el-table-column label="手机号" align="center" prop="phone" />
-                  <el-table-column label="状态" align="center" prop="status" >
-                      <template slot-scope="scope">
-                          <el-tag prop="status" v-for="(item, index) in userStatusOptions"    v-if="scope.row.status==item.dictValue">{{item.dictLabel}}</el-tag>
-                      </template>
-                  </el-table-column>
-                </el-table>
-            </el-form-item>
-            <el-form-item label="收货信息" prop="addressId">
-              <el-row  >
-                <el-col >
-                      <el-button plain  type="primary" icon="el-icon-plus"  @click="handleAddUserAddress()">添加收货地址</el-button>
-                </el-col>
-              </el-row>
-              <el-radio-group v-model="form.addressId" style="width:100%">
-              <el-table border  style="margin-top:5px;"  v-loading="addressloading" :data="address">
-                <el-table-column label="ID" align="center"  >
-                    <template slot-scope="scope">
-                       <el-radio :label="scope.row.id"></el-radio>
-                    </template>
-                </el-table-column>
-                <el-table-column label="收货人姓名" align="center" prop="realName" />
-                <el-table-column label="收货人电话" align="center" prop="phone" />
-                <el-table-column label="地址" align="center" prop="detail" >
-                    <template slot-scope="scope">
-                       {{scope.row.province}} {{scope.row.city}} {{scope.row.district}} {{scope.row.detail}}
-                    </template>
-                </el-table-column>
-              </el-table>
-              </el-radio-group>
-            </el-form-item>
-            <el-form-item label="商品列表" >
-              <el-row  >
-                <el-col >
-                      <el-button plain  type="primary" icon="el-icon-plus" @click="handleAddProduct">添加商品</el-button>
-                </el-col>
-              </el-row>
-              <el-table border :key = "tablekey" width="100%" style="margin-top:5px;"  :data="products">
-                <el-table-column label="商品编号" align="center" prop="barCode" />
-                <el-table-column label="商品图片" align="center" width="100">
-                  <template slot-scope="scope">
-                    <el-popover
-                      placement="right"
-                      title=""
-                      trigger="hover"
-                    >
-                      <img slot="reference" :src="scope.row.image" width="50">
-                      <img :src="scope.row.image" style="max-width: 50px;">
-                    </el-popover>
-                  </template>
-                </el-table-column>
-                <el-table-column label="商品名称" show-overflow-tooltip align="center" prop="productName" />
-                <el-table-column label="商品规格" align="center" prop="sku" />
-                <el-table-column label="库存" align="center" prop="stock" />
-                <el-table-column label="单价" align="center" prop="price" />
-                <el-table-column label="数量" align="center"  prop="count" width="200px" :key="tablekey">
-                   <template slot-scope="scope">
-                    <div>
-                        <el-input-number v-model="scope.row.count"  @change="handleProductCountChange(scope.row)"  size="mini" :min="1" :max="scope.row.stock"  ></el-input-number>
-                    </div>
-                  </template>
-                </el-table-column>
-                <el-table-column label="小计" align="center" prop="money"   />
-                <el-table-column label="操作" align="center" width="100px" >
-                  <template slot-scope="scope">
-                    <el-button
-                      size="mini"
-                      type="text"
-                      icon="el-icon-delete"
-                      @click="handleDelete(scope.row)"
-                    >删除</el-button>
-                  </template>
-                </el-table-column>
-              </el-table>
-              <el-row>
-                <el-col>
-                      <span>商品合计:{{products.length}}</span><span style="margin-left:10px;">商品总价:{{totalMoney.toFixed(2)}}</span>
-                </el-col>
-              </el-row>
-            </el-form-item>
-            <el-form-item label="订单备注" prop="mark">
-              <el-input  type="textarea" rows="2" v-model="form.mark" placeholder="" />
-            </el-form-item>
-        </el-form>
+    <el-dialog v-if="open" :title="title" :visible.sync="open" append-to-body width="1000px">
+      <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+        <el-form-item label="会员信息" prop="userId">
+          <el-row>
+            <el-col>
+              <el-input v-model="phone" placeholder="请输入会员手机号" style="width:240px;cursor:pointer">
+              </el-input>
+              <el-button plain style="margin-left:10px;" @click="searchUser()">查询</el-button>
+              <el-button icon="el-icon-plus" plain style="margin-left:10px;" type="primary" @click="handleAddUser()">
+                添加会员
+              </el-button>
+            </el-col>
+          </el-row>
+          <el-table v-loading="userloading" :data="users" border style="margin-top:5px;">
+            <el-table-column align="center" label="ID" prop="userId"/>
+            <el-table-column align="center" label="会员头像" 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 align="center" label="昵称" prop="nickname"/>
+            <el-table-column align="center" label="手机号" prop="phone"/>
+            <el-table-column align="center" label="状态" prop="status">
+              <template slot-scope="scope">
+                <el-tag v-for="(item, index) in userStatusOptions" v-if="scope.row.status==item.dictValue"
+                        prop="status"
+                >{{ item.dictLabel }}
+                </el-tag>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-form-item>
+        <el-form-item label="收货信息" prop="addressId">
+          <el-row>
+            <el-col>
+              <el-button icon="el-icon-plus" plain type="primary" @click="handleAddUserAddress()">添加收货地址
+              </el-button>
+            </el-col>
+          </el-row>
+          <el-radio-group v-model="form.addressId" style="width:100%">
+            <el-table v-loading="addressloading" :data="address" border style="margin-top:5px;">
+              <el-table-column align="center" label="ID">
+                <template slot-scope="scope">
+                  <el-radio :label="scope.row.id"></el-radio>
+                </template>
+              </el-table-column>
+              <el-table-column align="center" label="收货人姓名" prop="realName"/>
+              <el-table-column align="center" label="收货人电话" prop="phone"/>
+              <el-table-column align="center" label="地址" prop="detail">
+                <template slot-scope="scope">
+                  {{ scope.row.province }} {{ scope.row.city }} {{ scope.row.district }} {{ scope.row.detail }}
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="商品列表">
+          <el-row>
+            <el-col>
+              <el-button icon="el-icon-plus" plain type="primary" @click="handleAddProduct">添加商品</el-button>
+            </el-col>
+          </el-row>
+          <el-table :key="tablekey" :data="products" border style="margin-top:5px;" width="100%">
+            <el-table-column align="center" label="商品编号" prop="barCode"/>
+            <el-table-column align="center" label="商品图片" width="100">
+              <template slot-scope="scope">
+                <el-popover
+                  placement="right"
+                  title=""
+                  trigger="hover"
+                >
+                  <img slot="reference" :src="scope.row.image" width="50">
+                  <img :src="scope.row.image" style="max-width: 50px;">
+                </el-popover>
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="商品名称" prop="productName" show-overflow-tooltip/>
+            <el-table-column align="center" label="商品规格" prop="sku"/>
+            <el-table-column align="center" label="库存" prop="stock"/>
+            <el-table-column align="center" label="单价" prop="price"/>
+            <el-table-column :key="tablekey" align="center" label="数量" prop="count" width="200px">
+              <template slot-scope="scope">
+                <div>
+                  <el-input-number v-model="scope.row.count" :max="scope.row.stock" :min="1"
+                                   size="mini" @change="handleProductCountChange(scope.row)"
+                  ></el-input-number>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="小计" prop="money"/>
+            <el-table-column align="center" label="操作" width="100px">
+              <template slot-scope="scope">
+                <el-button
+                  icon="el-icon-delete"
+                  size="mini"
+                  type="text"
+                  @click="handleDelete(scope.row)"
+                >删除
+                </el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+          <el-row>
+            <el-col>
+              <span>商品合计:{{ products.length }}</span><span style="margin-left:10px;"
+            >商品总价:{{ totalMoney.toFixed(2) }}</span>
+            </el-col>
+          </el-row>
+        </el-form-item>
+        <el-form-item label="订单备注" prop="mark">
+          <el-input v-model="form.mark" placeholder="" rows="2" type="textarea"/>
+        </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="product.title" v-if="product.open"  :visible.sync="product.open" width="1000px" append-to-body>
-        <product-select  @selectProduct="selectProduct" />
+    <el-dialog v-if="product.open" :title="product.title" :visible.sync="product.open" append-to-body width="1000px">
+      <product-select @selectProduct="selectProduct"/>
     </el-dialog>
-    <el-dialog :title="user.title" v-if="user.open"  :visible.sync="user.open" width="500px" append-to-body>
-        <add-user @addUser="addUser" />
+    <el-dialog v-if="user.open" :title="user.title" :visible.sync="user.open" append-to-body width="500px">
+      <add-user @addUser="addUser"/>
     </el-dialog>
-    <el-dialog :title="userAddress.title" v-if="userAddress.open"  :visible.sync="userAddress.open" width="800px" append-to-body>
-        <add-user-address ref="addUserAddress"   @addUserAddress="addUserAddress" />
+    <el-dialog v-if="userAddress.open" :title="userAddress.title" :visible.sync="userAddress.open" append-to-body
+               width="800px"
+    >
+      <add-user-address ref="addUserAddress" @addUserAddress="addUserAddress"/>
     </el-dialog>
-    <el-dialog :title="payQr.title" v-if="payQr.open"  :visible.sync="payQr.open" width="240px" append-to-body>
-        <div style="padding-bottom:15px;" >
-            <div  class="qrcode" ref="qrCodeUrl"></div>
-        </div>
+    <el-dialog v-if="payQr.open" :title="payQr.title" :visible.sync="payQr.open" append-to-body width="240px">
+      <div style="padding-bottom:15px;">
+        <div ref="qrCodeUrl" class="qrcode"></div>
+      </div>
     </el-dialog>
 
-    <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
-      <el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
+    <el-dialog :title="upload.title" :visible.sync="upload.open" append-to-body width="400px">
+      <el-upload ref="upload" :action="upload.url + '?updateSupport=' + upload.updateSupport" :auto-upload="false" :disabled="upload.isUploading"
+                 :headers="upload.headers" :limit="1"
+                 :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" accept=".xlsx, .xls" drag
+      >
         <i class="el-icon-upload"></i>
         <div class="el-upload__text">
           将文件拖到此处,或
           <em>点击上传</em>
         </div>
-        <div class="el-upload__tip" slot="tip">
+        <div slot="tip" class="el-upload__tip">
           <!-- <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的数据 -->
-          <el-link type="info" style="font-size:12px" @click="importTemplate">下载模板</el-link>
+          <el-link style="font-size:12px" type="info" @click="importTemplate">下载模板</el-link>
         </div>
-        <div class="el-upload__tip" style="color:red" slot="tip">提示:仅允许导入“xls”或“xlsx”格式文件!</div>
+        <div slot="tip" class="el-upload__tip" style="color:red">提示:仅允许导入“xls”或“xlsx”格式文件!</div>
       </el-upload>
       <div slot="footer" class="dialog-footer">
         <el-button type="primary" @click="submitFileForm">确 定</el-button>
         <el-button @click="upload.open = false">取 消</el-button>
       </div>
     </el-dialog>
-    <el-dialog title="导入结果" :close-on-press-escape="false" :close-on-click-modal="false" :visible.sync="importMsgOpen" width="500px" append-to-body>
-       <div class="import-msg" v-html="importMsg">
-       </div>
+    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :visible.sync="importMsgOpen"
+               append-to-body title="导入结果" width="500px"
+    >
+      <h1>操作成功!</h1>
     </el-dialog>
 
+    <!-- 批量发货 -->
+    <el-dialog
+      :before-close="handleClose"
+      :visible.sync="deliveryNoteOpen"
+      center
+      title="批量发货"
+      width="35%"
+    >
+      <span slot="footer" class="dialog-footer">
+        <!-- 小程序Appid选择 -->
+<!--        <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">-->
+<!--          <el-form-item label="小程序:" prop="miniAppId">-->
+<!--        <el-select-->
+<!--          v-model="ruleForm.miniAppId"-->
+<!--          clearable-->
+<!--          placeholder="请选择发货小程序"-->
+<!--          style="width: 100%"-->
+<!--        >-->
+<!--          <el-option-->
+<!--            v-for="item in miniAppList"-->
+<!--            :key="item.appId"-->
+<!--            :label="item.appName"-->
+<!--            :value="item.appId"-->
+<!--          />-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+<!--        </el-form>-->
+
+        <el-upload ref="upload" :action="orderUpload.url" :auto-upload="false" :disabled="orderUpload.isUploading" :headers="orderUpload.headers"
+                   :limit="1" :on-progress="handleFileUploadProgress"
+                   :on-success="handleFileSuccess" accept=".xlsx, .xls" drag
+        >
+        <i class="el-icon-upload"></i>
+        <div class="el-upload__text">
+          将文件拖到此处,或
+          <em>点击上传</em>
+        </div>
+        <div slot="tip" class="el-upload__tip">
+          <el-link style="font-size:12px" type="info" @click="importDeliveryNoteTemplate">下载模板</el-link>
+        </div>
+        <div slot="tip" class="el-upload__tip" style="color:red">提示:仅允许导入“xls”或“xlsx”格式文件!</div>
+      </el-upload>
+        <el-divider></el-divider>
+        <el-button @click="deliveryNoteOpen = false">取 消</el-button>
+        <el-button type="primary" @click="submitDeliveryNote">确 定</el-button>
+      </span>
+    </el-dialog>
   </div>
 </template>
 
 <script>
-import { importTemplate,exportHealthStoreOrderItems,createUserOrder,listHealthStoreOrder, getStoreOrder, delStoreOrder, addStoreOrder, updateStoreOrder, exportHealthStoreOrder } from "@/api/hisStore/storeOrder";
-import { getUserList } from "@/api/hisStore/user";
-import { getAddressList } from "@/api/hisStore/userAddress";
-import productOrder from "../components/productOrder";
-import productSelect from "../components/productSelect";
-import addUser from "../components/addUser";
-import addUserAddress from "../components/addUserAddress";
-import { getToken } from "@/utils/auth";
+import {
+  importDeliveryNoteExpressTemplate,
+  importTemplate,
+  exportHealthStoreOrderItems,
+  createUserOrder,
+  listHealthStoreOrder,
+  getStoreOrder,
+  delStoreOrder,
+  addStoreOrder,
+  updateStoreOrder,
+  exportHealthStoreOrder
+} from '@/api/hisStore/storeOrder'
+import { getUserList } from '@/api/hisStore/user'
+import { getAddressList } from '@/api/hisStore/userAddress'
+import productOrder from '../components/productOrder'
+import productSelect from '../components/productSelect'
+import addUser from '../components/addUser'
+import addUserAddress from '../components/addUserAddress'
+import { getToken } from '@/utils/auth'
 import QRCode from 'qrcodejs2'
-import { getCompanyList } from "@/api/company/company";
+import { getCompanyList } from '@/api/company/company'
 
-import { treeselect } from "@/api/company/companyDept";
-import Treeselect from "@riophae/vue-treeselect";
-import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import { treeselect } from '@/api/company/companyDept'
+import Treeselect from '@riophae/vue-treeselect'
+import '@riophae/vue-treeselect/dist/vue-treeselect.css'
+import { getConfigByKey } from '@/api/system/config'
 
 export default {
-  components: { productOrder,productSelect,addUser,addUserAddress,Treeselect },
-  name: "HisHealthStoreOrderList",
+  components: { productOrder, productSelect, addUser, addUserAddress, Treeselect },
+  name: 'HisHealthStoreOrderList',
   watch: {
     // 监听deptId
     'deptId': 'currDeptChange'
   },
   data() {
     return {
-      importMsgOpen:false,
-      importMsg:"",
-      deliveryPayStatusOptions:[],
-      deliveryStatusOptions:[],
-      companys:[],
-      deptOptions:[],
-      companyId:undefined,
-      deptId:undefined,
-      orderTypeOptions:[],
-      payTypeOptions:[],
-      payQr:{
-        open:false,
-        title:"付款二维码"
+      importMsgOpen: false,
+      importMsg: '',
+      deliveryPayStatusOptions: [],
+      deliveryStatusOptions: [],
+      companys: [],
+      deptOptions: [],
+      companyId: undefined,
+      deptId: undefined,
+      orderTypeOptions: [],
+      payTypeOptions: [],
+      payQr: {
+        open: false,
+        title: '付款二维码'
       },
-      user:{
-        open:false,
-        title:"创建会员"
+      user: {
+        open: false,
+        title: '创建会员'
       },
-      userAddress:{
-        open:false,
-        title:"创建收货地址"
+      userAddress: {
+        open: false,
+        title: '创建收货地址'
       },
-      tablekey:false,
-      totalMoney:0.00,
-      products:[],
-      product:{
-        open:false,
-        title:"商品选择"
+      tablekey: false,
+      totalMoney: 0.00,
+      products: [],
+      product: {
+        open: false,
+        title: '商品选择'
       },
-      userStatusOptions:[],
-      phone:null,
-      address:[],
+      userStatusOptions: [],
+      phone: null,
+      address: [],
       addressloading: false,
       userloading: false,
-      users:[],
-      userStatusOptions:[],
-      show:{
-        open:false,
-        title:"订单详情"
+      users: [],
+      show: {
+        open: false,
+        title: '订单详情'
       },
-      activeName:"00",
-      statusOptions:[],
+      activeName: '00',
+      statusOptions: [],
       // 遮罩层
       loading: true,
       // 选中数组
@@ -528,13 +634,13 @@ export default {
       // 订单表格数据
       storeOrderList: [],
       // 弹出层标题
-      title: "",
+      title: '',
       // 是否显示弹出层
       open: false,
-      createTimeRange:[],
-      payTimeRange:[],
-      deliveryImportTimeRange:[],
-      deliverySendTimeRange:[],
+      createTimeRange: [],
+      payTimeRange: [],
+      deliveryImportTimeRange: [],
+      deliverySendTimeRange: [],
       // 查询参数
       queryParams: {
         pageNum: 1,
@@ -583,451 +689,512 @@ export default {
         isChannel: null,
         isRemind: null,
         isSysDel: null,
-        deptId:null,
+        deptId: null
 
       },
       // 表单参数
       form: {
-        addressId:null,
-        userId:null,
+        addressId: null,
+        userId: null
       },
       // 表单校验
       rules: {
         userId: [
-          { required: true, message: "会员信息不能为空" }
+          { required: true, message: '会员信息不能为空' }
         ],
         addressId: [
-          { required: true, message: "收货信息不能为空" }
+          { required: true, message: '收货信息不能为空' }
+        ],
+        miniAppId: [
+          { required: true, message: '发货小程序不能为空' }
         ],
-
       },
       upload: {
         // 是否显示弹出层(用户导入)
         open: false,
         // 弹出层标题(用户导入)
-        title: "",
+        title: '',
         // 是否禁用上传
         isUploading: false,
         // 是否更新已经存在的用户数据
         updateSupport: 0,
         // 设置上传的请求头部
-        headers: { Authorization: "Bearer " + getToken() },
+        headers: { Authorization: 'Bearer ' + getToken() },
         // 上传的地址
-        url: process.env.VUE_APP_BASE_API + "/store/storeOrder/importExpress",
+        url: process.env.VUE_APP_BASE_API + '/store/storeOrder/importExpress'
       },
-    };
+      orderUpload: {
+        // 是否显示弹出层(用户导入)
+        open: false,
+        // 弹出层标题(用户导入)
+        title: '',
+        // 是否禁用上传
+        isUploading: false,
+        // 是否更新已经存在的用户数据
+        updateSupport: 0,
+        // 设置上传的请求头部
+        headers: { Authorization: 'Bearer ' + getToken() },
+        // 上传的地址
+        url: process.env.VUE_APP_BASE_API + '/store/store/storeOrder/importDeliveryNoteExpress',
+      },
+      deliveryNoteOpen: false,
+      miniAppList: [],
+      ruleForm:{
+        miniAppId: null,
+      },
+    }
   },
   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("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;
-    });
+      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('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
+    })
 
-    this.getList();
+    this.getList()
   },
   methods: {
-    handleGenPayUrl(row){
-      this.payQr.open=true;
+    handleGenPayUrl(row) {
+      this.payQr.open = true
       setTimeout(() => {
         var qrcode = new QRCode(this.$refs.qrCodeUrl, {
-            text: config.payQRUrl+row.id, // 需要转换为二维码的内容
-            width: 200,
-            height: 200,
-            colorDark: '#000000',
-            colorLight: '#ffffff',
-            correctLevel: QRCode.CorrectLevel.H
+          text: config.payQRUrl + row.id, // 需要转换为二维码的内容
+          width: 200,
+          height: 200,
+          colorDark: '#000000',
+          colorLight: '#ffffff',
+          correctLevel: QRCode.CorrectLevel.H
         })
-      }, 200);
+      }, 200)
     },
-    handleAddUser(){
-      this.user.open=true;
+    handleAddUser() {
+      this.user.open = true
     },
-    handleAddUserAddress(){
-      if(this.form.userId==null){
-        this.msgError("请选择会员");
-        return;
+    handleAddUserAddress() {
+      if (this.form.userId == null) {
+        this.msgError('请选择会员')
+        return
       }
-      this.userAddress.open=true;
+      this.userAddress.open = true
       setTimeout(() => {
-        this.$refs.addUserAddress.init(this.form.userId);
-      }, 500);
+        this.$refs.addUserAddress.init(this.form.userId)
+      }, 500)
     },
-    addUser(){
-      this.user.open=false;
+    addUser() {
+      this.user.open = false
     },
-    addUserAddress(){
-      this.userAddress.open=false;
+    addUserAddress() {
+      this.userAddress.open = false
       //获取地址
-      this.getAddressList(this.form.userId);
+      this.getAddressList(this.form.userId)
     },
-    compute(){
-      this.totalMoney=0;
-      var that=this;
-      this.products.forEach (function (value) {
-          that.totalMoney += value.money;
-      });
+    compute() {
+      this.totalMoney = 0
+      var that = this
+      this.products.forEach(function(value) {
+        that.totalMoney += value.money
+      })
       console.log(that.totalMoney)
     },
-    handleProductCountChange(row){
+    handleProductCountChange(row) {
       this.tablekey = !this.tablekey
       console.log(row)
-      row.money=row.count*row.price;
-      this.$forceUpdate();
-      this.compute();
+      row.money = row.count * row.price
+      this.$forceUpdate()
+      this.compute()
     },
-    selectProduct(row){
-      console.log(row);
-      for(var i=0;i<this.products.length;i++){
-        if(this.products[i].id==row.id){
-          return;
+    selectProduct(row) {
+      console.log(row)
+      for (var i = 0; i < this.products.length; i++) {
+        if (this.products[i].id == row.id) {
+          return
         }
       }
-      row.count=1;
-      row.money=row.count*row.price;
-      this.products.push(row);
-      this.compute();
+      row.count = 1
+      row.money = row.count * row.price
+      this.products.push(row)
+      this.compute()
     },
-    handleAddProduct(){
-      this.product.open=true;
+    handleAddProduct() {
+      this.product.open = true
     },
-    searchUser(){
-      if(this.phone==null||this.phone==""){
-        return;
+    searchUser() {
+      if (this.phone == null || this.phone == '') {
+        return
       }
-      var data={phone:this.phone}
-      this.userloading = true;
-      this.users=[];
-      this.address=[];
+      var data = { phone: this.phone }
+      this.userloading = true
+      this.users = []
+      this.address = []
       getUserList(data).then(response => {
-        this.users = response.data;
-        this.userloading = false;
-        if(this.users!=null&&this.users.length==1){
-          this.form.userId=this.users[0].userId;
+        this.users = response.data
+        this.userloading = false
+        if (this.users != null && this.users.length == 1) {
+          this.form.userId = this.users[0].userId
           this.getAddressList(this.form.userId)
         }
-      });
+      })
     },
-    getAddressList(userId){
-      var data={userId:userId}
-      this.addressloading = true;
-      this.address=[];
+    getAddressList(userId) {
+      var data = { userId: userId }
+      this.addressloading = true
+      this.address = []
       getAddressList(data).then(response => {
-        this.address = response.data;
-        this.addressloading = false;
-      });
+        this.address = response.data
+        this.addressloading = false
+      })
     },
-    handleDetails(row){
-      this.show.open=true;
-      const orderId = row.id ;
+    handleDetails(row) {
+      this.show.open = true
+      const orderId = row.id
       setTimeout(() => {
-        this.$refs.order.getOrder(orderId);
-      }, 500);
+        this.$refs.order.getOrder(orderId)
+      }, 500)
     },
     handleClick(tab, event) {
-      this.activeName=tab.name;
-      this.queryParams.status=tab.name
+      this.activeName = tab.name
+      this.queryParams.status = tab.name
       console.log(this.queryParams.status)
-      this.getList();
+      this.getList()
     },
     /** 查询订单列表 */
     getList() {
-      this.loading = true;
-      if(this.queryParams.status=='00'){
-        this.queryParams.status=null;
+      this.loading = true
+      if (this.queryParams.status == '00') {
+        this.queryParams.status = null
       }
 
-      if(this.createTimeRange!=null&&this.createTimeRange.length==2){
-        this.queryParams.createTimeRange=this.createTimeRange[0]+"--"+this.createTimeRange[1]
-      }
-      else{
-        this.queryParams.createTimeRange=null;
+      if (this.createTimeRange != null && this.createTimeRange.length == 2) {
+        this.queryParams.createTimeRange = this.createTimeRange[0] + '--' + this.createTimeRange[1]
+      } else {
+        this.queryParams.createTimeRange = null
       }
 
-      if(this.payTimeRange!=null&&this.payTimeRange.length==2){
-        this.queryParams.payTimeRange=this.payTimeRange[0]+"--"+this.payTimeRange[1]
-      }
-      else{
-        this.queryParams.payTimeRange=null;
-      }
-      if(this.deliveryImportTimeRange!=null&&this.deliveryImportTimeRange.length==2){
-        this.queryParams.deliveryImportTimeRange=this.deliveryImportTimeRange[0]+"--"+this.deliveryImportTimeRange[1]
+      if (this.payTimeRange != null && this.payTimeRange.length == 2) {
+        this.queryParams.payTimeRange = this.payTimeRange[0] + '--' + this.payTimeRange[1]
+      } else {
+        this.queryParams.payTimeRange = null
       }
-      else{
-        this.queryParams.deliveryImportTimeRange=null;
+      if (this.deliveryImportTimeRange != null && this.deliveryImportTimeRange.length == 2) {
+        this.queryParams.deliveryImportTimeRange = this.deliveryImportTimeRange[0] + '--' + this.deliveryImportTimeRange[1]
+      } else {
+        this.queryParams.deliveryImportTimeRange = null
       }
-      if(this.deliverySendTimeRange!=null&&this.deliverySendTimeRange.length==2){
-        this.queryParams.deliverySendTimeRange=this.deliverySendTimeRange[0]+"--"+this.deliverySendTimeRange[1]
-      }
-      else{
-        this.queryParams.deliverySendTimeRange=null;
+      if (this.deliverySendTimeRange != null && this.deliverySendTimeRange.length == 2) {
+        this.queryParams.deliverySendTimeRange = this.deliverySendTimeRange[0] + '--' + this.deliverySendTimeRange[1]
+      } else {
+        this.queryParams.deliverySendTimeRange = null
       }
 
       listHealthStoreOrder(this.queryParams).then(response => {
-        this.storeOrderList = response.rows;
-        this.total = response.total;
-        this.loading = false;
-      });
+        this.storeOrderList = response.rows
+        this.total = response.total
+        this.loading = false
+      })
     },
     // 取消按钮
     cancel() {
-      this.open = false;
-      this.reset();
+      this.open = false
+      this.reset()
     },
     // 表单重置
     reset() {
       this.form = {
-        addressId:null,
-        userId:null,
+        addressId: null,
+        userId: null
 
-      };
-      this.resetForm("form");
+      }
+      this.resetForm('form')
     },
     /** 搜索按钮操作 */
     handleQuery() {
-      this.queryParams.pageNum = 1;
-      this.getList();
+      this.queryParams.pageNum = 1
+      this.getList()
     },
     /** 重置按钮操作 */
     resetQuery() {
-      this.resetForm("queryForm");
-      this.handleQuery();
+      this.resetForm('queryForm')
+      this.handleQuery()
     },
     // 多选框选中数据
     handleSelectionChange(selection) {
       this.ids = selection.map(item => item.id)
-      this.single = selection.length!==1
+      this.single = selection.length !== 1
       this.multiple = !selection.length
     },
     /** 新增按钮操作 */
     handleAdd() {
-      this.reset();
-      this.open = true;
-      this.title = "创建订单";
+      this.reset()
+      this.open = true
+      this.title = '创建订单'
     },
     /** 修改按钮操作 */
     handleUpdate(row) {
-      this.reset();
+      this.reset()
       const id = row.id || this.ids
       getStoreOrder(id).then(response => {
-        this.form = response.data;
-        this.open = true;
-        this.title = "修改订单";
-      });
+        this.form = response.data
+        this.open = true
+        this.title = '修改订单'
+      })
     },
     /** 提交按钮 */
     submitForm() {
-      this.$refs["form"].validate(valid => {
-        this.form.products=this.products;
+      this.$refs['form'].validate(valid => {
+        this.form.products = this.products
         if (valid) {
-          console.log(this.form);
+          console.log(this.form)
           createUserOrder(this.form).then(response => {
             if (response.code === 200) {
-              this.msgSuccess("创建成功");
-              this.open = false;
-              this.getList();
+              this.msgSuccess('创建成功')
+              this.open = false
+              this.getList()
             }
-          });
+          })
 
         }
-      });
+      })
     },
     /** 删除按钮操作 */
     handleDelete(row) {
-       this.products.splice(this.products.findIndex(item => item.id === row.id), 1)
-       this.compute();
+      this.products.splice(this.products.findIndex(item => item.id === row.id), 1)
+      this.compute()
 
     },
     /** 导出按钮操作 */
     handleExport() {
-      if(this.queryParams.status=='00'){
-        this.queryParams.status=null;
-      }
-      if(this.createTimeRange!=null&&this.createTimeRange.length==2){
-        this.queryParams.createTimeRange=this.createTimeRange[0]+"--"+this.createTimeRange[1]
-      }
-      else{
-        this.queryParams.createTimeRange=null;
-      }
-      if(this.payTimeRange!=null&&this.payTimeRange.length==2){
-        this.queryParams.payTimeRange=this.payTimeRange[0]+"--"+this.payTimeRange[1]
+      if (this.queryParams.status == '00') {
+        this.queryParams.status = null
       }
-      else{
-        this.queryParams.payTimeRange=null;
+      if (this.createTimeRange != null && this.createTimeRange.length == 2) {
+        this.queryParams.createTimeRange = this.createTimeRange[0] + '--' + this.createTimeRange[1]
+      } else {
+        this.queryParams.createTimeRange = null
       }
-      if(this.deliveryImportTimeRange!=null&&this.deliveryImportTimeRange.length==2){
-        this.queryParams.deliveryImportTimeRange=this.deliveryImportTimeRange[0]+"--"+this.deliveryImportTimeRange[1]
+      if (this.payTimeRange != null && this.payTimeRange.length == 2) {
+        this.queryParams.payTimeRange = this.payTimeRange[0] + '--' + this.payTimeRange[1]
+      } else {
+        this.queryParams.payTimeRange = null
       }
-      else{
-        this.queryParams.deliveryImportTimeRange=null;
+      if (this.deliveryImportTimeRange != null && this.deliveryImportTimeRange.length == 2) {
+        this.queryParams.deliveryImportTimeRange = this.deliveryImportTimeRange[0] + '--' + this.deliveryImportTimeRange[1]
+      } else {
+        this.queryParams.deliveryImportTimeRange = null
       }
-      if(this.deliverySendTimeRange!=null&&this.deliverySendTimeRange.length==2){
-        this.queryParams.deliverySendTimeRange=this.deliverySendTimeRange[0]+"--"+this.deliverySendTimeRange[1]
+      if (this.deliverySendTimeRange != null && this.deliverySendTimeRange.length == 2) {
+        this.queryParams.deliverySendTimeRange = this.deliverySendTimeRange[0] + '--' + this.deliverySendTimeRange[1]
+      } else {
+        this.queryParams.deliverySendTimeRange = null
       }
-      else{
-        this.queryParams.deliverySendTimeRange=null;
-      }
-      const queryParams = this.addDateRange(this.queryParams, this.dateRange);
-      this.$confirm('是否确认导出所有订单数据项?', "警告", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        }).then(function() {
-          return exportHealthStoreOrder(queryParams);
-        }).then(response => {
-          this.download(response.msg);
-        }).catch(function() {});
+      const queryParams = this.addDateRange(this.queryParams, this.dateRange)
+      this.$confirm('是否确认导出所有订单数据项?', '警告', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(function() {
+        return exportHealthStoreOrder(queryParams)
+      }).then(response => {
+        this.download(response.msg)
+      }).catch(function() {
+      })
     },
     handleExportItems() {
-      if(this.queryParams.status=='00'){
-        this.queryParams.status=null;
-      }
-      if(this.createTimeRange!=null&&this.createTimeRange.length==2){
-        this.queryParams.createTimeRange=this.createTimeRange[0]+"--"+this.createTimeRange[1]
-      }
-      else{
-        this.queryParams.createTimeRange=null;
-      }
-      if(this.payTimeRange!=null&&this.payTimeRange.length==2){
-        this.queryParams.payTimeRange=this.payTimeRange[0]+"--"+this.payTimeRange[1]
-      }
-      else{
-        this.queryParams.payTimeRange=null;
+      if (this.queryParams.status == '00') {
+        this.queryParams.status = null
       }
-      if(this.deliveryImportTimeRange!=null&&this.deliveryImportTimeRange.length==2){
-        this.queryParams.deliveryImportTimeRange=this.deliveryImportTimeRange[0]+"--"+this.deliveryImportTimeRange[1]
+      if (this.createTimeRange != null && this.createTimeRange.length == 2) {
+        this.queryParams.createTimeRange = this.createTimeRange[0] + '--' + this.createTimeRange[1]
+      } else {
+        this.queryParams.createTimeRange = null
       }
-      else{
-        this.queryParams.deliveryImportTimeRange=null;
+      if (this.payTimeRange != null && this.payTimeRange.length == 2) {
+        this.queryParams.payTimeRange = this.payTimeRange[0] + '--' + this.payTimeRange[1]
+      } else {
+        this.queryParams.payTimeRange = null
       }
-      if(this.deliverySendTimeRange!=null&&this.deliverySendTimeRange.length==2){
-        this.queryParams.deliverySendTimeRange=this.deliverySendTimeRange[0]+"--"+this.deliverySendTimeRange[1]
+      if (this.deliveryImportTimeRange != null && this.deliveryImportTimeRange.length == 2) {
+        this.queryParams.deliveryImportTimeRange = this.deliveryImportTimeRange[0] + '--' + this.deliveryImportTimeRange[1]
+      } else {
+        this.queryParams.deliveryImportTimeRange = null
       }
-      else{
-        this.queryParams.deliverySendTimeRange=null;
+      if (this.deliverySendTimeRange != null && this.deliverySendTimeRange.length == 2) {
+        this.queryParams.deliverySendTimeRange = this.deliverySendTimeRange[0] + '--' + this.deliverySendTimeRange[1]
+      } else {
+        this.queryParams.deliverySendTimeRange = null
       }
-      const queryParams = this.addDateRange(this.queryParams, this.dateRange);
-      this.$confirm('是否确认导出所有订单明细数据项?', "警告", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        }).then(function() {
-          return exportHealthStoreOrderItems(queryParams);
-        }).then(response => {
-          this.download(response.msg);
-        }).catch(function() {});
+      const queryParams = this.addDateRange(this.queryParams, this.dateRange)
+      this.$confirm('是否确认导出所有订单明细数据项?', '警告', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(function() {
+        return exportHealthStoreOrderItems(queryParams)
+      }).then(response => {
+        this.download(response.msg)
+      }).catch(function() {
+      })
     },
     handleImport() {
-      this.upload.title = "导入银行回单";
-      this.upload.open = true;
+      this.upload.title = '导入银行回单'
+      this.upload.open = true
     },
     submitFileForm() {
-      this.$refs.upload.submit();
+      this.$refs.upload.submit()
     },
     importTemplate() {
       importTemplate().then((response) => {
-        this.download(response.msg);
-      });
+        this.download(response.msg)
+      })
     },
     // 文件上传中处理
     handleFileUploadProgress(event, file, fileList) {
-      this.upload.isUploading = true;
+      this.upload.isUploading = true
     },
     // 文件上传成功处理
     handleFileSuccess(response, file, fileList) {
-      this.upload.open = false;
-      this.upload.isUploading = false;
-      this.$refs.upload.clearFiles();
-      this.importMsgOpen=true;
-      this.importMsg=response.msg
+      this.upload.open = false
+      this.upload.isUploading = false
+      this.$refs.upload.clearFiles()
+      this.importMsgOpen = true
+      this.importMsg = response.msg
       // this.$alert(response.msg, '导入结果', {
       //     dangerouslyUseHTMLString: true
       //   });
-      this.getList();
+      this.getList()
     },
 
-        /** 查询部门下拉树结构 */
+    /** 查询部门下拉树结构 */
     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.queryParams.deptId=response.data[0].id;
-          }
-        });
+      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.queryParams.deptId=response.data[0].id;
+        }
+      })
     },
-     companyChange(val){
-      console.log(val);
-      this.companyId=val;
-      this.getTreeselect();
+    companyChange(val) {
+      console.log(val)
+      this.companyId = val
+      this.getTreeselect()
     },
-     currDeptChange(val){
-          console.log(val)
-          this.queryParams.deptId=val;
-          this.getList();
+    currDeptChange(val) {
+      console.log(val)
+      this.queryParams.deptId = val
+      this.getList()
     },
+    //打开发货单
+    openDeliveryNote() {
+      this.deliveryNoteOpen = true
+      // this.getAppList();
+    },
+    handleClose(done) {
+      this.$confirm('确认关闭?')
+        .then(_ => {
+          done()
+        })
+        .catch(_ => {
+        })
+    },
+    //发货单模板下载
+    importDeliveryNoteTemplate() {
+      importDeliveryNoteExpressTemplate().then((response) => {
+        this.download(response.msg)
+      })
+    },
+    getAppList() {
+      this.miniAppList = []
+      const key = 'courseMa.config'
+      getConfigByKey(key).then(response => {
+        const { code, data } = response
+        if (code === 200) {
+          let value = data?.configValue
+          if (value) {
+            const appList = JSON.parse(value)
+            this.miniAppList = appList.filter(v => v.type === '1').map(v => {
+              return { appId: v.appid, appName: v.name }
+            })
+          }
+        }
+      })
+    },
+    // 提交发货单
+    submitDeliveryNote() {
+      const uploadFiles = this.$refs.upload.uploadFiles;
+      if (uploadFiles.length === 0) {
+        this.$message.error('请选择要上传的文件');
+        return;
+      }
+      this.$refs.upload.submit();
+    }
+
   }
-};
+}
 </script>
-<style scoped lang="scss">
-.items{
+<style lang="scss" scoped>
+.items {
   margin: 5px 0px;
   display: flex;
   flex-direction: row;
   align-items: center;
   justify-content: flex-start;
-  .pic{
-    width:60px;
-    height:60px;
+
+  .pic {
+    width: 60px;
+    height: 60px;
   }
-  .goods-content{
+
+  .goods-content {
     margin-left: 10px;
     max-width: 200px;
     text-align: left;
-    .goods-title{
 
-      overflow:hidden;
+    .goods-title {
+
+      overflow: hidden;
       white-space: nowrap;
       text-overflow: ellipsis;
-      -o-text-overflow:ellipsis;
+      -o-text-overflow: ellipsis;
     }
   }
 }
-.el-message-box__message p{
+
+.el-message-box__message p {
   max-height: 400px;
-  overflow:scroll;
+  overflow: scroll;
 }
-.import-msg{
+
+.import-msg {
   height: 500px;
   overflow: auto;
 }
 </style>
 <style>
-  .el-descriptions-item__label.is-bordered-label{
-    font-weight: normal;
-  }
+.el-descriptions-item__label.is-bordered-label {
+  font-weight: normal;
+}
 
 </style>
 

+ 119 - 0
src/views/hisStore/storeOrder/index.vue

@@ -203,6 +203,14 @@
         >导出订单明细</el-button>
       </el-col>
       <el-col :span="1.5">
+<!--        <el-button-->
+<!--          type="warning"-->
+<!--          icon="el-icon-s-order"-->
+<!--          size="mini"-->
+<!--          @click="openDeliveryNote"-->
+<!--        >批量更新订单状态</el-button>-->
+<!--      </el-col>-->
+<!--      <el-col :span="1.5">-->
         <el-input
           v-model="orderItemNum"
           disabled
@@ -492,6 +500,54 @@
        </div>
     </el-dialog>
 
+    <!-- 批量发货 -->
+    <el-dialog
+      :before-close="handleClose"
+      :visible.sync="deliveryNoteOpen"
+      center
+      title="批量发货"
+      width="35%"
+    >
+      <span slot="footer" class="dialog-footer">
+        <!-- 小程序Appid选择 -->
+<!--        <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">-->
+<!--          <el-form-item label="小程序:" prop="miniAppId">-->
+<!--        <el-select-->
+<!--          v-model="ruleForm.miniAppId"-->
+<!--          clearable-->
+<!--          placeholder="请选择发货小程序"-->
+<!--          style="width: 100%"-->
+<!--        >-->
+<!--          <el-option-->
+<!--            v-for="item in miniAppList"-->
+<!--            :key="item.appId"-->
+<!--            :label="item.appName"-->
+<!--            :value="item.appId"-->
+<!--          />-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+<!--        </el-form>-->
+
+        <el-upload ref="upload" :action="orderUpload.url" :auto-upload="false" :disabled="orderUpload.isUploading" :headers="orderUpload.headers"
+                   :limit="1" :on-progress="handleFileUploadProgress"
+                   :on-success="handleFileSuccess" accept=".xlsx, .xls" drag
+        >
+        <i class="el-icon-upload"></i>
+        <div class="el-upload__text">
+          将文件拖到此处,或
+          <em>点击上传</em>
+        </div>
+        <div slot="tip" class="el-upload__tip">
+          <el-link style="font-size:12px" type="info" @click="importDeliveryNoteTemplate">下载模板</el-link>
+        </div>
+        <div slot="tip" class="el-upload__tip" style="color:red">提示:仅允许导入“xls”或“xlsx”格式文件!</div>
+      </el-upload>
+        <el-divider></el-divider>
+        <el-button @click="deliveryNoteOpen = false">取 消</el-button>
+        <el-button type="primary" @click="submitDeliveryNote">确 定</el-button>
+      </span>
+    </el-dialog>
+
   </div>
 </template>
 
@@ -510,6 +566,7 @@ import { getTcmScheduleList } from "@/api/company/schedule";
 import { treeselect } from "@/api/company/companyDept";
 import Treeselect from "@riophae/vue-treeselect";
 import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import { getConfigByKey } from '@/api/system/config'
 
 export default {
   components: { productOrder,productSelect,addUser,addUserAddress,Treeselect },
@@ -668,6 +725,25 @@ export default {
         // 上传的地址
         url: process.env.VUE_APP_BASE_API + "/store/storeOrder/importExpress",
       },
+      orderUpload: {
+        // 是否显示弹出层(用户导入)
+        open: false,
+        // 弹出层标题(用户导入)
+        title: "",
+        // 是否禁用上传
+        isUploading: false,
+        // 是否更新已经存在的用户数据
+        updateSupport: 0,
+        // 设置上传的请求头部
+        headers: { Authorization: "Bearer " + getToken() },
+        // 上传的地址
+        url: '',
+      },
+      deliveryNoteOpen:false,
+      miniAppList: [],
+      ruleForm:{
+        miniAppId: null,
+      },
     };
   },
   created() {
@@ -1085,6 +1161,49 @@ export default {
           this.queryParams.deptId=val;
           this.getList();
     },
+    //打开发货单
+    openDeliveryNote(){
+      this.deliveryNoteOpen=true;
+      // this.getAppList();
+    },
+    handleClose(done) {
+      this.$confirm('确认关闭?')
+        .then(_ => {
+          done();
+        })
+        .catch(_ => {});
+    },
+    //发货单模板下载
+    importDeliveryNoteTemplate(){
+
+    },
+    getAppList() {
+      this.miniAppList = []
+      const key = "courseMa.config"
+      getConfigByKey(key).then(response => {
+        const {code,data} = response
+        if (code === 200) {
+          let value = data?.configValue
+          if (value) {
+            console.log("打印-----------------》",value)
+            const appList = JSON.parse(value);
+            this.miniAppList = appList.filter(v => v.type === '1').map(v => {
+              return { appId: v.appid, appName: v.name }
+            })
+          }
+        }
+      })
+    },
+    // 提交发货单
+    submitDeliveryNote() {
+      const uploadFiles = this.$refs.upload.uploadFiles;
+      if (uploadFiles.length === 0) {
+        this.$message.error('请选择要上传的文件');
+        return;
+      }
+      this.orderUpload.url = `${process.env.VUE_APP_BASE_API}/store/store/storeOrder/importDeliveryNoteExpress`;
+      this.$refs.upload.submit();
+    },
   }
 };
 </script>

+ 1 - 1
src/views/qw/sopTemp/updateSopTemp.vue

@@ -728,7 +728,7 @@ export default {
       dayList: [],
       ruleList: [],
       ids: [],
-      courseTypeList: ['3', '4', '9'],
+      courseTypeList: ['1','3', '4', '9'],
       sysFsSopWatchStatus: [],
       //消息内容类型 企微版
       sysQwSopContentType: [],

+ 272 - 0
src/views/saler/competitorInfo/index.vue

@@ -0,0 +1,272 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="竞品公司" prop="competitorCompany">
+        <el-input
+          v-model="queryParams.competitorCompany"
+          placeholder="请输入竞品公司"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="产品" prop="product">
+        <el-input
+          v-model="queryParams.product"
+          placeholder="请输入产品名称"
+          clearable
+          @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="['saler:competitorInfo: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="['saler:competitorInfo: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="['saler:competitorInfo:remove']"
+        >删除</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="competitorInfoList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="ID" align="center" prop="id" v-if="false" />
+      <el-table-column label="竞品公司" align="center" prop="competitorCompany" :show-overflow-tooltip="true" />
+      <el-table-column label="产品" align="center" prop="product" :show-overflow-tooltip="true" />
+      <el-table-column label="价格" align="center" prop="price" />
+      <el-table-column label="服务" align="center" prop="service" :show-overflow-tooltip="true" />
+      <el-table-column label="免费服务次数" align="center" prop="freeServiceTimes" />
+      <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="['saler:competitorInfo:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['saler:competitorInfo: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="120px">
+        <el-form-item label="竞品公司" prop="competitorCompany">
+          <el-input v-model="form.competitorCompany" placeholder="请输入竞品公司" />
+        </el-form-item>
+        <el-form-item label="产品" prop="product">
+          <el-input v-model="form.product" placeholder="请输入产品" />
+        </el-form-item>
+        <el-form-item label="价格" prop="price">
+          <el-input-number v-model="form.price" :precision="2" :step="0.1" :min="0" placeholder="请输入价格" />
+        </el-form-item>
+        <el-form-item label="服务" prop="service">
+          <el-input v-model="form.service" type="textarea" placeholder="请输入服务内容" />
+        </el-form-item>
+        <el-form-item label="免费服务次数" prop="freeServiceTimes">
+          <el-input-number v-model="form.freeServiceTimes" :min="0" placeholder="请输入免费服务次数" />
+        </el-form-item>
+        <el-form-item label="备注" prop="remark">
+          <el-input v-model="form.remark" type="textarea" 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 { listCompetitorInfo, getCompetitorInfo, addCompetitorInfo, updateCompetitorInfo, delCompetitorInfo } from "@/api/saler/competitorInfo";
+
+export default {
+  name: "CompetitorInfo",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 竞品信息表格数据
+      competitorInfoList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        competitorCompany: null,
+        product: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        competitorCompany: [
+          { required: true, message: "竞品公司不能为空", trigger: "blur" }
+        ],
+        product: [
+          { required: true, message: "产品不能为空", trigger: "blur" }
+        ],
+        price: [
+          { required: true, message: "价格不能为空", trigger: "blur" }
+        ]
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询竞品信息列表 */
+    getList() {
+      this.loading = true;
+      listCompetitorInfo(this.queryParams).then(response => {
+        this.competitorInfoList = response.data.list;
+        this.total = response.data.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        competitorCompany: null,
+        product: null,
+        price: 0,
+        service: null,
+        freeServiceTimes: 0,
+        remark: 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
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加竞品信息";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getCompetitorInfo(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) {
+            updateCompetitorInfo(this.form).then(response => {
+              this.$message.success("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addCompetitorInfo(this.form).then(response => {
+              this.$message.success("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm('是否确认删除竞品信息编号为"' + ids + '"的数据项?').then(function() {
+        return delCompetitorInfo(ids);
+      }).then(() => {
+        this.getList();
+        this.$message.success("删除成功");
+      }).catch(() => {});
+    }
+  }
+};
+</script>

+ 296 - 0
src/views/saler/productInfo/index.vue

@@ -0,0 +1,296 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="商品名称" prop="productName">
+        <el-input
+          v-model="queryParams.productName"
+          placeholder="请输入商品名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="会员情况" prop="memberStatus">
+        <el-input
+          v-model="queryParams.memberStatus"
+          placeholder="请输入会员情况"
+          clearable
+          @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="['saler:productInfo: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="['saler:productInfo: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="['saler:productInfo:remove']"
+        >删除</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="productInfoList" @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="productName" />
+      <el-table-column label="购买数量" align="center" prop="purchaseQuantity" />
+      <el-table-column label="金额" align="center" prop="amount" />
+      <el-table-column label="预计完成时间" align="center" prop="plannedCompletionDate" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.plannedCompletionDate, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="购买次数" align="center" prop="purchaseTimes" />
+      <el-table-column label="剩余次数" align="center" prop="surplusTimes" />
+      <el-table-column label="会员情况" align="center" prop="memberStatus" />
+      <el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime) }}</span>
+        </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="['saler:productInfo:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['saler:productInfo: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="120px">
+        <el-form-item label="商品名称" prop="productName">
+          <el-input v-model="form.productName" placeholder="请输入商品名称" />
+        </el-form-item>
+        <el-form-item label="购买数量" prop="purchaseQuantity">
+          <el-input-number v-model="form.purchaseQuantity" :min="0" :max="9999" />
+        </el-form-item>
+        <el-form-item label="金额" prop="amount">
+          <el-input-number v-model="form.amount" :precision="2" :min="0" :step="0.01" />
+        </el-form-item>
+        <el-form-item label="预计完成时间" prop="plannedCompletionDate">
+          <el-date-picker clearable
+                          v-model="form.plannedCompletionDate"
+                          type="date"
+                          value-format="yyyy-MM-dd"
+                          placeholder="请选择预计完成时间">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="购买次数" prop="purchaseTimes">
+          <el-input-number v-model="form.purchaseTimes" :min="0" :max="9999" />
+        </el-form-item>
+        <el-form-item label="剩余次数" prop="surplusTimes">
+          <el-input-number v-model="form.surplusTimes" :min="0" :max="9999" />
+        </el-form-item>
+        <el-form-item label="会员情况" prop="memberStatus">
+          <el-input v-model="form.memberStatus" placeholder="请输入会员情况" />
+        </el-form-item>
+        <el-form-item label="备注" prop="remark">
+          <el-input v-model="form.remark" type="textarea" 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 { listProductInfo, getProductInfo, addProductInfo, updateProductInfo, delProductInfo } from "@/api/saler/productInfo";
+
+export default {
+  name: "ProductInfo",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 商品表格数据
+      productInfoList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        productName: null,
+        memberStatus: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        productName: [
+          { required: true, message: "商品名称不能为空", trigger: "blur" }
+        ],
+        purchaseQuantity: [
+          { required: true, message: "购买数量不能为空", trigger: "blur" }
+        ],
+        amount: [
+          { required: true, message: "金额不能为空", trigger: "blur" }
+        ]
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询商品列表 */
+    getList() {
+      this.loading = true;
+      listProductInfo(this.queryParams).then(response => {
+        this.productInfoList = response.data.list;
+        this.total = response.data.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        productName: null,
+        purchaseQuantity: 0,
+        amount: 0,
+        plannedCompletionDate: null,
+        purchaseTimes: 0,
+        surplusTimes: 0,
+        memberStatus: null,
+        remark: 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
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加商品";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids[0]
+      getProductInfo(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) {
+            updateProductInfo(this.form).then(response => {
+              this.$message.success("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addProductInfo(this.form).then(response => {
+              this.$message.success("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm('是否确认删除商品编号为"' + ids + '"的数据项?').then(function() {
+        return delProductInfo(ids);
+      }).then(() => {
+        this.getList();
+        this.$message.success("删除成功");
+      }).catch(() => {});
+    }
+  }
+};
+</script>

+ 108 - 88
src/views/system/config/config.vue

@@ -513,89 +513,89 @@
           </div>
         </el-form>
     </el-tab-pane>
-      <el-tab-pane label="APP支付配置" name="store.pay">
-        <el-form ref="form23" :model="form23"  label-width="160px">
-          <el-form-item label="支付类型" prop="type">
-            <el-radio-group v-model="form23.type">
-              <el-radio label="yb">易宝</el-radio>
-              <el-radio label="wx">微信</el-radio>
-              <el-radio label="hf">汇付</el-radio>
-            </el-radio-group>
-          </el-form-item>
-          <el-form-item   label="appId" prop="appId">
-            <el-input   v-model="form23.appId"  label="请输入appId"></el-input>
-          </el-form-item>
-          <el-form-item  v-if="form23.type=='yb'" label="易宝商户号" prop="ybAccount">
-            <el-input   v-model="form23.ybAccount"  label="请输入易宝商户号"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='yb'" label="易宝Key" prop="ybKey">
-            <el-input  v-model="form23.ybKey" label="请输入易宝Key"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='yb'" label="易宝回调地址" prop="ybNotifyUrl">
-            <el-input  v-model="form23.ybNotifyUrl" label="易宝回调地址"></el-input>
-          </el-form-item>
-
-          <el-form-item  v-if="form23.type=='wx'" label="微信商户号" prop="wxMchId">
-            <el-input   v-model="form23.wxMchId"  label="请输入微信商户号"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='wx'" label="微信Key" prop="wxMchKey">
-            <el-input  v-model="form23.wxMchKey" label="请输入微信Key"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='wx'" label="微信商户V3密钥" prop="wxMchKey">
-            <el-input  v-model="form23.wxApiV3Key" label="请输入商户V3密钥"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='wx'" label="keyPath" prop="wxMchKey">
-            <el-input  v-model="form23.keyPath" label="请输入商户V3密钥"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='wx'" label="privateKeyPath" prop="wxMchKey">
-            <el-input  v-model="form23.privateKeyPath" label="请输入商户V3密钥"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='wx'" label="privateCertPath" prop="wxMchKey">
-            <el-input  v-model="form23.privateCertPath" label="请输入商户V3密钥"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='wx'" label="notifyUrlScrm" prop="wxMchKey">
-            <el-input  v-model="form23.notifyUrlScrm" label="请输入商户V3密钥"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='wx'" label="publicKeyId" prop="wxMchKey">
-            <el-input  v-model="form23.publicKeyId" label="请输入商户V3密钥"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='wx'" label="publicKeyPath" prop="wxMchKey">
-            <el-input  v-model="form23.publicKeyPath" label="请输入商户V3密钥"></el-input>
-          </el-form-item>
-
-
-          <el-form-item  v-if="form23.type=='hf'" label="汇付产品号" prop="hfProductId">
-            <el-input   v-model="form23.hfProductId"  label="汇付产品号"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='hf'" label="系统号" prop="hfSysId">
-            <el-input  v-model="form23.hfSysId" label="系统号Key"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='hf'" label="商户号" prop="huifuId">
-            <el-input  v-model="form23.huifuId" label="商户号"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='hf'" label="商户私钥" prop="hfRsaPrivateKey">
-            <el-input  v-model="form23.hfRsaPrivateKey" label="商户私钥"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='hf'" label="汇付公钥" prop="hfRsaPublicKey">
-            <el-input  v-model="form23.hfRsaPublicKey" label="汇付公钥"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='hf'" label="汇付支付回调地址" prop="hfPayNotifyUrl">
-            <el-input  v-model="form23.hfPayNotifyUrl" label="汇付支付回调地址"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='hf'" label="大额支付回调地址" prop="hfPayOnlineNotifyUrl">
-            <el-input  v-model="form23.hfPayOnlineNotifyUrl" label="汇付支付回调地址"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='hf'" label="汇付退款回调地址" prop="hfRefundNotifyUrl">
-            <el-input  v-model="form23.hfRefundNotifyUrl" label="汇付退款回调地址"></el-input>
-          </el-form-item>
-          <el-form-item v-if="form23.type=='hf'" label="汇付大额退款回调地址" prop="hfOnlineRefundNotifyUrl">
-            <el-input  v-model="form23.hfOnlineRefundNotifyUrl" label="汇付分账回调地址"></el-input>
-          </el-form-item>
-          <div   class="footer">
-            <el-button type="primary" @click="submitForm23">提  交</el-button>
-          </div>
-        </el-form>
-      </el-tab-pane>
+<!--      <el-tab-pane label="APP支付配置" name="store.pay">-->
+<!--        <el-form ref="form23" :model="form23"  label-width="160px">-->
+<!--          <el-form-item label="支付类型" prop="type">-->
+<!--            <el-radio-group v-model="form23.type">-->
+<!--              <el-radio label="yb">易宝</el-radio>-->
+<!--              <el-radio label="wx">微信</el-radio>-->
+<!--              <el-radio label="hf">汇付</el-radio>-->
+<!--            </el-radio-group>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item   label="appId" prop="appId">-->
+<!--            <el-input   v-model="form23.appId"  label="请输入appId"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item  v-if="form23.type=='yb'" label="易宝商户号" prop="ybAccount">-->
+<!--            <el-input   v-model="form23.ybAccount"  label="请输入易宝商户号"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='yb'" label="易宝Key" prop="ybKey">-->
+<!--            <el-input  v-model="form23.ybKey" label="请输入易宝Key"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='yb'" label="易宝回调地址" prop="ybNotifyUrl">-->
+<!--            <el-input  v-model="form23.ybNotifyUrl" label="易宝回调地址"></el-input>-->
+<!--          </el-form-item>-->
+
+<!--          <el-form-item  v-if="form23.type=='wx'" label="微信商户号" prop="wxMchId">-->
+<!--            <el-input   v-model="form23.wxMchId"  label="请输入微信商户号"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='wx'" label="微信Key" prop="wxMchKey">-->
+<!--            <el-input  v-model="form23.wxMchKey" label="请输入微信Key"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='wx'" label="微信商户V3密钥" prop="wxMchKey">-->
+<!--            <el-input  v-model="form23.wxApiV3Key" label="请输入商户V3密钥"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='wx'" label="keyPath" prop="wxMchKey">-->
+<!--            <el-input  v-model="form23.keyPath" label="请输入商户V3密钥"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='wx'" label="privateKeyPath" prop="wxMchKey">-->
+<!--            <el-input  v-model="form23.privateKeyPath" label="请输入商户V3密钥"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='wx'" label="privateCertPath" prop="wxMchKey">-->
+<!--            <el-input  v-model="form23.privateCertPath" label="请输入商户V3密钥"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='wx'" label="notifyUrlScrm" prop="wxMchKey">-->
+<!--            <el-input  v-model="form23.notifyUrlScrm" label="请输入商户V3密钥"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='wx'" label="publicKeyId" prop="wxMchKey">-->
+<!--            <el-input  v-model="form23.publicKeyId" label="请输入商户V3密钥"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='wx'" label="publicKeyPath" prop="wxMchKey">-->
+<!--            <el-input  v-model="form23.publicKeyPath" label="请输入商户V3密钥"></el-input>-->
+<!--          </el-form-item>-->
+
+
+<!--          <el-form-item  v-if="form23.type=='hf'" label="汇付产品号" prop="hfProductId">-->
+<!--            <el-input   v-model="form23.hfProductId"  label="汇付产品号"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='hf'" label="系统号" prop="hfSysId">-->
+<!--            <el-input  v-model="form23.hfSysId" label="系统号Key"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='hf'" label="商户号" prop="huifuId">-->
+<!--            <el-input  v-model="form23.huifuId" label="商户号"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='hf'" label="商户私钥" prop="hfRsaPrivateKey">-->
+<!--            <el-input  v-model="form23.hfRsaPrivateKey" label="商户私钥"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='hf'" label="汇付公钥" prop="hfRsaPublicKey">-->
+<!--            <el-input  v-model="form23.hfRsaPublicKey" label="汇付公钥"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='hf'" label="汇付支付回调地址" prop="hfPayNotifyUrl">-->
+<!--            <el-input  v-model="form23.hfPayNotifyUrl" label="汇付支付回调地址"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='hf'" label="大额支付回调地址" prop="hfPayOnlineNotifyUrl">-->
+<!--            <el-input  v-model="form23.hfPayOnlineNotifyUrl" label="汇付支付回调地址"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='hf'" label="汇付退款回调地址" prop="hfRefundNotifyUrl">-->
+<!--            <el-input  v-model="form23.hfRefundNotifyUrl" label="汇付退款回调地址"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <el-form-item v-if="form23.type=='hf'" label="汇付大额退款回调地址" prop="hfOnlineRefundNotifyUrl">-->
+<!--            <el-input  v-model="form23.hfOnlineRefundNotifyUrl" label="汇付分账回调地址"></el-input>-->
+<!--          </el-form-item>-->
+<!--          <div   class="footer">-->
+<!--            <el-button type="primary" @click="submitForm23">提  交</el-button>-->
+<!--          </div>-->
+<!--        </el-form>-->
+<!--      </el-tab-pane>-->
     <el-tab-pane label="布局配置" name="his.appShow" >
         <div >
           <el-table border :data="form10">
@@ -735,6 +735,7 @@
         <el-radio v-model="form13.erpType" label=3>瀚智OMS</el-radio>
         <el-radio v-model="form13.erpType" label=4>代服管家</el-radio>
         <el-radio v-model="form13.erpType" label=5>聚水潭</el-radio>
+        <el-radio v-model="form13.erpType" label=6>金博</el-radio>
       </el-form-item>
      <el-form-item   label="不推送erp的公司" v-if="form13.erpOpen == 1">
        <el-select filterable v-model="form13.noErpCompany" placeholder="请选公司" multiple clearable size="small"
@@ -910,6 +911,25 @@
          <el-input   v-model="form13.erpJstrehouseCode"  label="请输入erpJstrehouseCode"></el-input>
        </el-form-item>
 
+       <el-form-item   label="kingbosan" v-if="form13.erpOpen == 1 && form13.erpType == 6 " prop="kingbosan">
+         <el-input   v-model="form13.kingbosan"  label="请输入账套名称(kingbosan)"></el-input>
+       </el-form-item>
+       <el-form-item   label="kingbosSecret" v-if="form13.erpOpen == 1 && form13.erpType == 6 " prop="kingbosSecret">
+         <el-input   v-model="form13.kingbosSecret"  label="请输入密钥(kingbosSecret)"></el-input>
+       </el-form-item>
+       <el-form-item   label="kingbosUrl" v-if="form13.erpOpen == 1 && form13.erpType == 6 " prop="kingbosUrl">
+         <el-input   v-model="form13.kingbosUrl"  label="请输入金博地址(kingbosUrl)"></el-input>
+       </el-form-item>
+       <el-form-item   label="corgid" v-if="form13.erpOpen == 1 && form13.erpType == 6 " prop="corgid">
+         <el-input   v-model="form13.corgid"  label="请输入机构编码(corgid)"></el-input>
+       </el-form-item>
+       <el-form-item   label="cwarehouseCode" v-if="form13.erpOpen == 1 && form13.erpType == 6 " prop="cwarehouseCode">
+         <el-input   v-model="form13.cwarehouseCode"  label="请输入仓库编码(cwarehouseCode)"></el-input>
+       </el-form-item>
+       <el-form-item   label="cwarehouseName" v-if="form13.erpOpen == 1 && form13.erpType == 6 " prop="cwarehouseName">
+         <el-input   v-model="form13.cwarehouseName"  label="请输入仓库名称(cwarehouseName)"></el-input>
+       </el-form-item>
+
 
       <el-form-item   label="appid" prop="appid">
           <el-input   v-model="form13.appid"  label="请输入appid"></el-input>
@@ -1397,13 +1417,13 @@
          <el-form ref="form20" :model="form20" :rules="rules20" label-width="120px">
            <el-form-item label="评级天数(天)" prop="levelDay">
              <el-tooltip class="item" effect="dark" content="最小评级天数(天)" placement="top-end">
-               <el-input-number v-model="form20.levelDay" :min="7" :max="365"></el-input-number>
+               <el-input-number v-model="form20.levelDay" :min="4" :max="365"></el-input-number>
              </el-tooltip>
            </el-form-item>
 
            <el-form-item label="超过多少天的客户没看课评E级" prop="levelDay">
              <el-tooltip class="item" effect="dark" content="超过多少天的客户没看课评E级,且不生成sop执行记录了,不发了" placement="top-end">
-               <el-input-number v-model="form20.notStudyDays" :min="7" :max="365"></el-input-number>
+               <el-input-number v-model="form20.notStudyDays" :min="4" :max="365"></el-input-number>
              </el-tooltip>
            </el-form-item>
 
@@ -1613,8 +1633,8 @@ export default {
       form19:{
       },
       form20:{
-        levelDay: 7,
-        notStudyDays:7,
+        levelDay: 4,
+        notStudyDays:4,
         aLevelMin: 80,
         aLevelMax: 100,
         bLevelMin: 40,
@@ -1712,7 +1732,7 @@ export default {
   methods: {
     handleCityChange(value) {
       // console.log(this.$refs.citySelect,this.$refs.citySelect[0])
-      var nodes=this.$refs.citySelect[0].getCheckedNodes();
+      var nodes=this.$refs.citySelect[value].getCheckedNodes();
       // console.log(nodes[0])
       // this.account[value].cityIds=value.toString();
       this.form13.dfAccounts[value].senderProvince=nodes[0].pathLabels[0];

+ 4 - 4
src/views/system/config/config2.vue

@@ -1172,13 +1172,13 @@
          <el-form ref="form20" :model="form20" :rules="rules20" label-width="120px">
            <el-form-item label="评级天数(天)" prop="levelDay">
              <el-tooltip class="item" effect="dark" content="最小评级天数(天)" placement="top-end">
-               <el-input-number v-model="form20.levelDay" :min="7" :max="365"></el-input-number>
+               <el-input-number v-model="form20.levelDay" :min="4" :max="365"></el-input-number>
              </el-tooltip>
            </el-form-item>
 
            <el-form-item label="超过多少天的客户没看课评E级" prop="levelDay">
              <el-tooltip class="item" effect="dark" content="超过多少天的客户没看课评E级,且不生成sop执行记录了,不发了" placement="top-end">
-               <el-input-number v-model="form20.notStudyDays" :min="7" :max="365"></el-input-number>
+               <el-input-number v-model="form20.notStudyDays" :min="4" :max="365"></el-input-number>
              </el-tooltip>
            </el-form-item>
 
@@ -1366,8 +1366,8 @@ export default {
       form19:{
       },
       form20:{
-        levelDay: 7,
-        notStudyDays:7,
+        levelDay: 4,
+        notStudyDays:4,
         aLevelMin: 80,
         aLevelMax: 100,
         bLevelMin: 40,

+ 8 - 2
src/views/system/role/index.vue

@@ -189,7 +189,7 @@
             >{{dict.dictLabel}}</el-radio>
           </el-radio-group>
         </el-form-item>
-        <el-form-item label="是否可以查看手机全号" >
+        <el-form-item label="是否可以查看手机全号" v-if="isAdmin == 1">
           <span slot="label">
             <el-tooltip content="是否可以查看手机全号" placement="top">
               <i class="el-icon-question"></i>
@@ -361,7 +361,7 @@ export default {
         roleSort: [
           { required: true, message: "角色顺序不能为空", trigger: "blur" }
         ]
-      }
+      },
     };
   },
   created() {
@@ -370,6 +370,12 @@ export default {
       this.statusOptions = response.data;
     });
   },
+  computed: {
+    isAdmin() {
+      console.log(this.$store.state.user.isAdmin)
+      return this.$store.state.user.isAdmin
+    }
+  },
   methods: {
     /** 查询角色列表 */
     getList() {

+ 619 - 0
src/views/todo/todoItems/index.vue

@@ -0,0 +1,619 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px" >
+      <el-form-item label="标题" prop="title">
+        <el-input
+          v-model="queryParams.title"
+          placeholder="请输入待办事项标题"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="公司名称" prop="companyName">
+        <el-input
+          v-model="queryParams.companyName"
+          placeholder="请输入公司名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+
+      <el-form-item label="状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
+          <el-option
+            v-for="dict in statusOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </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"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['todo:todoItems: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="['todo:todoItems: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="['todo:todoItems:remove']"
+        >删除</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table
+      v-loading="loading"
+      :data="todoItemsList"
+      @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="title" />
+      <el-table-column label="分配者" align="center" prop="creatorName" />
+      <el-table-column label="执行人" align="center" prop="assigneeName" />
+      <el-table-column label="描述" align="center" prop="description" show-overflow-tooltip />
+      <el-table-column label="状态" align="center" prop="status">
+        <template slot-scope="scope">
+          <el-tag :type="getStatusType(scope.row.status)" size="small">
+            {{ getStatusLabel(scope.row.status) }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="优先级" align="center" prop="priority">
+        <template slot-scope="scope">
+          <el-tag :type="getPriorityType(scope.row.priority)" size="small">
+            {{ getPriorityLabel(scope.row.priority) }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="截止时间" align="center" prop="dueDate" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.dueDate, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="220">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['todo:todoItems:edit']"
+          >修改</el-button>
+<!--          <el-button-->
+<!--            size="mini"-->
+<!--            type="text"-->
+<!--            icon="el-icon-check"-->
+<!--            @click="handleUpdateStatus(scope.row)"-->
+<!--            v-hasPermi="['todo:todoItems:edit']"-->
+<!--          >更新状态</el-button>-->
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-user"
+            @click="handleAssignExecutor(scope.row)"
+            v-hasPermi="['todo:todoItems:edit']"
+            class="assign-executor-btn"
+          >分配执行者</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['todo:todoItems:remove']"
+          >删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <div class="pagination-wrapper">
+      <pagination
+        v-show="total>0"
+        :total="total"
+        :page.sync="queryParams.pageNum"
+        :limit.sync="queryParams.pageSize"
+        @pagination="getList"
+      />
+    </div>
+
+    <!-- 添加或修改待办事项对话框 -->
+    <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="标题" prop="title">
+          <el-input v-model="form.title" placeholder="请输入待办事项标题" />
+        </el-form-item>
+        <el-form-item label="描述" prop="description">
+          <el-input v-model="form.description" type="textarea" placeholder="请输入描述" />
+        </el-form-item>
+        <el-form-item label="状态" prop="status">
+          <el-select v-model="form.status" placeholder="请选择状态" default-first-option>
+            <el-option
+              v-for="dict in statusOptions"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              :value="dict.dictValue"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="优先级" prop="priority">
+          <el-select v-model="form.priority" placeholder="请选择优先级">
+            <el-option
+              v-for="dict in priorityOptions"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              :value="dict.dictValue"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="截止时间" prop="dueDate">
+          <el-date-picker clearable
+                          v-model="form.dueDate"
+                          type="date"
+                          value-format="yyyy-MM-dd"
+                          placeholder="请选择截止时间">
+          </el-date-picker>
+        </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="statusOpen" width="300px" append-to-body>
+      <el-form ref="statusForm" :model="statusForm" label-width="80px">
+        <el-form-item label="状态" prop="status">
+          <el-select v-model="statusForm.status" placeholder="请选择状态">
+            <el-option
+              v-for="dict in statusOptions"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              :value="dict.dictValue"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitStatusForm">确 定</el-button>
+        <el-button @click="cancelStatus">取 消</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 分配执行者对话框 -->
+    <el-dialog title="分配执行者" :visible.sync="assignOpen" width="700px" append-to-body>
+      <el-form ref="assignForm" :model="assignForm" :rules="assignRules" label-width="80px">
+        <el-form-item label="待办事项" prop="title">
+          <el-input v-model="assignForm.title" disabled />
+        </el-form-item>
+        <el-form-item label="执行者" prop="executorId">
+          <el-select v-model="assignForm.executorId" placeholder="请选择执行者" filterable class="executor-select">
+            <el-option
+              v-for="executor in executorList"
+              :key="executor.userId"
+              :label="executor.userName"
+              :value="executor.userId"
+            ></el-option>
+          </el-select>
+          <div class="el-form-item__tip">
+            <small>执行者列表会根据搜索条件中的公司名称进行过滤</small>
+          </div>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitAssignForm">确 定</el-button>
+        <el-button @click="cancelAssign">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listTodoItems, getTodoItems, delTodoItems, addTodoItems, updateTodoItems, updateTodoItemsStatus, assignExecutor, getExecutorList, getUserList } from "@/api/todo/todoItems";
+import {parseTime} from "../../../utils/common";
+
+export default {
+  name: "TodoItems",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 待办事项表格数据
+      todoItemsList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 是否显示状态更新弹出层
+      statusOpen: false,
+      // 是否显示分配执行者弹出层
+      assignOpen: false,
+      // 状态选项
+      statusOptions: [],
+      // 优先级选项
+      priorityOptions: [],
+      todoItemTypeOptions: [],
+      // 执行者列表
+      executorList: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        title: null,
+        companyName: null,
+        status: null
+      },
+      // 表单参数
+      form: {
+        status: 0
+      },
+      // 状态表单参数
+      statusForm: {},
+      // 分配执行者表单参数
+      assignForm: {
+        id: null,
+        title: '',
+        executorId: null,
+        remark: ''
+      },
+      // 表单校验
+      rules: {
+        title: [
+          { required: true, message: "标题不能为空", trigger: "blur" }
+        ],
+        status: [
+          { required: true, message: "状态不能为空", trigger: "change" }
+        ]
+      },
+      // 分配执行者表单校验
+      assignRules: {
+        executorId: [
+          { required: true, message: "请选择执行者", trigger: "change" }
+        ]
+      }
+    };
+  },
+  created() {
+    this.getList();
+    this.getDicts("todo_status").then(response => {
+      this.statusOptions = response.data;
+    });
+    this.getDicts("todo_priority").then(response => {
+      this.priorityOptions = response.data;
+    });
+    this.getDicts("todo_item_type").then(response => {
+      this.todoItemTypeOptions = response.data;
+    });
+    // 获取执行者列表
+    this.getExecutorList();
+  },
+  methods: {
+    parseTime,
+    /** 查询待办事项列表 */
+    getList() {
+      this.loading = true;
+      listTodoItems(this.queryParams).then(response => {
+        this.todoItemsList = response.data.list;
+        this.total = response.data.total;
+        this.loading = false;
+      });
+    },
+    /** 获取执行者列表 */
+    getExecutorList() {
+      const params = {
+        companyName: this.queryParams.companyName || '',
+        companyId: null,
+        pageNum: 1,
+        pageSize: 10 // 获取足够多的执行者供选择
+      };
+      getUserList(params).then(response => {
+        if (response.code === 200) {
+          this.executorList = response.data || [];
+        }
+      });
+    },
+    /** 获取状态标签 */
+    getStatusLabel(status) {
+      const statusOption = this.statusOptions.find(option => option.dictValue === String(status));
+      return statusOption ? statusOption.dictLabel : '未知';
+    },
+    /** 获取状态标签类型(颜色) */
+    getStatusType(status) {
+      const statusMap = {
+        '0': 'info',      // 待处理 - 蓝色
+        '1': 'warning',   // 进行中 - 橙色
+        '2': 'success',   // 已完成 - 绿色
+        '3': 'danger'     // 已取消 - 红色
+      };
+      return statusMap[String(status)] || 'info';
+    },
+    /** 获取优先级标签 */
+    getPriorityLabel(priority) {
+      const priorityOption = this.priorityOptions.find(option => option.dictValue === String(priority));
+      return priorityOption ? priorityOption.dictLabel : '未知';
+    },
+    /** 获取优先级标签类型(颜色) */
+    getPriorityType(priority) {
+      const priorityMap = {
+        '0': 'info',      // 低 - 蓝色
+        '1': 'success',   // 中 - 绿色
+        '2': 'warning',   // 高 - 橙色
+        '3': 'danger'     // 紧急 - 红色
+      };
+      return priorityMap[String(priority)] || 'info';
+    },
+
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 取消状态更新
+    cancelStatus() {
+      this.statusOpen = false;
+      this.statusForm = {};
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        title: null,
+        description: null,
+        status: null,
+        priority: null,
+        dueDate: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+      // 更新执行者列表
+      this.getExecutorList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+      // 重置后更新执行者列表
+      this.getExecutorList();
+    },
+    // 多选框选中数据
+    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
+      // 确保id是单个值,如果是数组则取第一个
+      const todoId = Array.isArray(id) ? id[0] : id;
+      getTodoItems(todoId).then(response => {
+        this.form = response.data;
+        // 确保数据类型匹配
+        if (this.form.status !== null && this.form.status !== undefined) {
+          this.form.status = String(this.form.status);
+        }
+        if (this.form.priority !== null && this.form.priority !== undefined) {
+          this.form.priority = String(this.form.priority);
+        }
+        this.open = true;
+        this.title = "修改待办事项";
+      });
+    },
+    /** 更新状态按钮操作 */
+    handleUpdateStatus(row) {
+      this.statusForm = {
+        id: row.id,
+        status: String(row.status)
+      };
+      this.statusOpen = true;
+    },
+    /** 分配执行者按钮操作 */
+    handleAssignExecutor(row) {
+      this.assignForm = {
+        id: row.id,
+        title: row.title,
+        executorId: row.executorId || null,
+        remark: ''
+      };
+      this.assignOpen = true;
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateTodoItems(this.form).then(response => {
+              this.$message.success("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addTodoItems(this.form).then(response => {
+              this.$message.success("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 提交状态更新 */
+    submitStatusForm() {
+      updateTodoItemsStatus(this.statusForm.id, this.statusForm.status).then(response => {
+        this.$message.success("状态更新成功");
+        this.statusOpen = false;
+        this.getList();
+      });
+    },
+    /** 提交分配执行者 */
+    submitAssignForm() {
+      this.$refs["assignForm"].validate(valid => {
+        if (valid) {
+          assignExecutor(this.assignForm).then(response => {
+            this.$message.success("执行者分配成功");
+            this.assignOpen = false;
+            this.getList();
+          });
+        }
+      });
+    },
+    /** 取消分配执行者 */
+    cancelAssign() {
+      this.assignOpen = false;
+      this.assignForm = {
+        id: null,
+        title: '',
+        executorId: null,
+        remark: ''
+      };
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm('是否确认删除待办事项编号为"' + ids + '"的数据项?').then(function() {
+        return delTodoItems(ids);
+      }).then(() => {
+        this.getList();
+        this.$message.success("删除成功");
+      }).catch(() => {});
+    }
+  }
+}
+</script>
+
+<style scoped>
+.mb8 {
+  margin-bottom: 8px;
+}
+
+.fixed-width {
+  width: 100px;
+}
+
+
+
+
+
+.assign-executor-btn {
+  margin-left: 5px;
+}
+
+.executor-select {
+  width: 100%;
+}
+
+.el-form-item__tip {
+  margin-top: 5px;
+  color: #909399;
+  font-size: 12px;
+}
+
+
+
+
+/* 标签样式优化 */
+.el-tag {
+  border-radius: 12px;
+  font-weight: 500;
+  padding: 4px 12px;
+  border: none;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+/* 分页样式 */
+.pagination-wrapper {
+  margin-top: 20px;
+}
+
+.el-pagination {
+  text-align: center;
+  padding: 20px;
+  background: #fff;
+  border-radius: 8px;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+/* 对话框样式 */
+.el-dialog {
+  border-radius: 12px;
+  overflow: hidden;
+}
+
+.el-dialog__header {
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  color: white;
+  padding: 20px;
+}
+
+.el-dialog__title {
+  color: white;
+  font-weight: 600;
+}
+
+.el-dialog__body {
+  padding: 30px;
+}
+
+.el-dialog__footer {
+  padding: 20px;
+  border-top: 1px solid #ebeef5;
+  background: #f8f9fa;
+}
+
+
+</style>

+ 308 - 0
src/views/user/complaint/category/index.vue

@@ -0,0 +1,308 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="分类名称" prop="categoryName">
+        <el-input
+          v-model="queryParams.categoryName"
+          placeholder="请输入分类名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="分类状态" clearable>
+          <el-option
+            v-for="dict in categoryStatusOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+           :value="dict.dictValue"/>
+        </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"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['complaint:category: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="['complaint:category: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="['complaint:category:remove']"
+        >删除</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="categoryList" @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="categoryName" />
+      <el-table-column label="分类编码" align="center" prop="categoryCode" />
+      <el-table-column label="排序" align="center" prop="sortOrder" />
+      <el-table-column label="状态" align="center" prop="status">
+        <template slot-scope="scope">
+          <el-switch
+            v-model="scope.row.status"
+            :active-value="1"
+            :inactive-value="0"
+            @change="handleStatusChange(scope.row)"
+          ></el-switch>
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime) }}</span>
+        </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="['complaint:category:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['complaint:category: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="categoryName">
+          <el-input v-model="form.categoryName" placeholder="请输入分类名称" />
+        </el-form-item>
+        <el-form-item label="分类编码" prop="categoryCode">
+          <el-input v-model="form.categoryCode" placeholder="请输入分类编码" />
+        </el-form-item>
+        <el-form-item label="显示顺序" prop="sortOrder">
+          <el-input-number v-model="form.sortOrder" :min="0" />
+        </el-form-item>
+        <el-form-item label="状态">
+          <el-radio-group v-model="form.status">
+            <el-radio
+              v-for="dict in categoryStatusOptions"
+              :key="dict.dictValue"
+              :label="dict.dictValue"
+            >{{dict.dictLabel}}</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 { listCategory, getCategory, delCategory, addCategory, updateCategory, changeStatus } from "@/api/complaint/category";
+import {parseTime} from "../../../../utils/common";
+
+export default {
+  name: "Category",
+  data() {
+    return {
+      dicts: ['sys_normal_disable'],
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 投诉分类表格数据
+      categoryList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        categoryName: undefined,
+        categoryCode: undefined,
+        status: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        categoryName: [
+          { required: true, message: "分类名称不能为空", trigger: "blur" }
+        ],
+        categoryCode: [
+          { required: true, message: "分类编码不能为空", trigger: "blur" }
+        ],
+        orderNum: [
+          { required: true, message: "显示顺序不能为空", trigger: "blur" }
+        ]
+      },
+      categoryStatusOptions: []
+    };
+  },
+  created() {
+    this.getList();
+    this.getDicts('category_status').then(response => {
+      this.categoryStatusOptions = response.data;
+    })
+  },
+  methods: {
+    parseTime,
+    /** 查询投诉分类列表 */
+    getList() {
+      this.loading = true;
+      listCategory(this.queryParams).then(response => {
+        this.categoryList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: undefined,
+        categoryName: undefined,
+        categoryCode: undefined,
+        orderNum: 0,
+        status: "0",
+        remark: undefined
+      };
+      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[0];
+      getCategory(id).then(response => {
+        this.form = response.data;
+        console.log(this.form)
+        this.form.status = response.data.status+"";
+        this.open = true;
+        this.title = "修改投诉分类";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != undefined) {
+            updateCategory(this.form).then(response => {
+              this.$message.success("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addCategory(this.form).then(response => {
+              this.$message.success("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm('是否确认删除投诉分类编号为"' + ids + '"的数据项?').then(function() {
+        return delCategory(ids);
+      }).then(() => {
+        this.getList();
+        this.$message.success("删除成功");
+      }).catch(() => {});
+    },
+    /** 修改状态 */
+    handleStatusChange(row) {
+      let text = row.status === "1" ? "启用" : "停用";
+      this.$confirm('确认要"' + text + '""' + row.categoryName + '"分类吗?').then(function() {
+        return changeStatus({
+          id: row.id,
+          status: row.status
+        });
+      }).then(() => {
+        this.$message.success(text + "成功");
+      }).catch(function() {
+        row.status = row.status === "0" ? "1" : "0";
+      });
+    }
+  }
+};
+</script>

+ 253 - 151
src/views/user/complaint/index.vue

@@ -1,46 +1,41 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="投诉用户" prop="fsUserId">
+    <!-- 查询条件 -->
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="投诉单号" prop="complaintNo">
         <el-input
-          v-model="queryParams.fsUserId"
-          placeholder="请输入投诉用户"
+          v-model="queryParams.complaintNo"
+          placeholder="请输入投诉单号"
           clearable
-          size="small"
           @keyup.enter.native="handleQuery"
         />
       </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="images">
-        <el-input
-          v-model="queryParams.images"
-          placeholder="请输入投诉图片"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
-        />
+      <el-form-item label="投诉分类" prop="categoryId">
+        <el-select v-model="queryParams.categoryId" placeholder="请选择投诉分类" clearable>
+          <el-option
+            v-for="category in categoryList"
+            :key="category.id"
+            :label="category.categoryName"
+            :value="category.id"
+          />
+        </el-select>
       </el-form-item>
-      <el-form-item label="投诉类型0默认1店铺2商品" prop="type">
-        <el-select v-model="queryParams.type" placeholder="请选择投诉类型0默认1店铺2商品" clearable size="small">
-          <el-option label="请选择字典生成" value="" />
+      <el-form-item label="投诉状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择投诉状态" clearable>
+          <el-option label="待处理" value="0" />
+          <el-option label="已处理" value="1" />
         </el-select>
       </el-form-item>
-      <el-form-item label="关联ID" prop="linkId">
-        <el-input
-          v-model="queryParams.linkId"
-          placeholder="请输入关联ID"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
-        />
+      <el-form-item label="投诉时间">
+        <el-date-picker
+          v-model="dateRange"
+          style="width: 240px"
+          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="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
@@ -48,6 +43,7 @@
       </el-form-item>
     </el-form>
 
+    <!-- 操作按钮 -->
     <el-row :gutter="10" class="mb8">
       <el-col :span="1.5">
         <el-button
@@ -56,19 +52,8 @@
           icon="el-icon-plus"
           size="mini"
           @click="handleAdd"
-          v-hasPermi="['user: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="['user:complaint:edit']"
-        >修改</el-button>
+          v-hasPermi="['complaint:add']"
+        >新增投诉</el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button
@@ -78,53 +63,67 @@
           size="mini"
           :disabled="multiple"
           @click="handleDelete"
-          v-hasPermi="['user:complaint:remove']"
-        >删除</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="['user:complaint:export']"
-        >导出</el-button>
+          v-hasPermi="['complaint:delete']"
+        >批量删除</el-button>
       </el-col>
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
 
-    <el-table border v-loading="loading" :data="complaintList" @selection-change="handleSelectionChange">
+    <!-- 投诉列表 -->
+    <el-table 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="fsUserId" />
-      <el-table-column label="投诉标题" align="center" prop="title" />
-      <el-table-column label="投诉内容" align="center" prop="content" />
-      <el-table-column label="投诉图片" align="center" prop="images" />
-      <el-table-column label="投诉类型0默认1店铺2商品" align="center" prop="type" />
-      <el-table-column label="关联ID" align="center" prop="linkId" />
-      <el-table-column label="备注" align="center" prop="remark" />
+      <el-table-column label="投诉单号" align="center" prop="complaintNo" />
+      <el-table-column label="投诉人" align="center" prop="complainantName" />
+      <el-table-column label="投诉分类" align="center" prop="categoryName" />
+      <el-table-column label="投诉内容" align="center" prop="content" show-overflow-tooltip />
+      <el-table-column label="投诉状态" align="center" prop="status">
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.status === '0'" type="warning">待处理</el-tag>
+          <el-tag v-else-if="scope.row.status === '1'" type="success">已处理</el-tag>
+          <el-tag v-else type="info">未知</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="投诉时间" align="center" prop="createTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+        </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-view"
+            @click="handleDetail(scope.row)"
+            v-hasPermi="['complaint:query']"
+          >详情</el-button>
           <el-button
             size="mini"
             type="text"
             icon="el-icon-edit"
             @click="handleUpdate(scope.row)"
-            v-hasPermi="['user:complaint:edit']"
-          >修改</el-button>
+            v-hasPermi="['complaint:edit']"
+          >编辑</el-button>
+          <el-button
+            v-if="scope.row.status === '0'"
+            size="mini"
+            type="text"
+            icon="el-icon-check"
+            @click="handleProcess(scope.row)"
+            v-hasPermi="['complaint:edit']"
+          >处理</el-button>
           <el-button
             size="mini"
             type="text"
             icon="el-icon-delete"
             @click="handleDelete(scope.row)"
-            v-hasPermi="['user:complaint:remove']"
+            v-hasPermi="['complaint:delete']"
           >删除</el-button>
         </template>
       </el-table-column>
     </el-table>
 
+    <!-- 分页 -->
     <pagination
       v-show="total>0"
       :total="total"
@@ -133,31 +132,48 @@
       @pagination="getList"
     />
 
-    <!-- 添加或修改用户投诉对话框 -->
-    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+    <!-- 添加或修改投诉对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
       <el-form ref="form" :model="form" :rules="rules" label-width="80px">
-        <el-form-item label="投诉用户" prop="fsUserId">
-          <el-input v-model="form.fsUserId" placeholder="请输入投诉用户" />
+        <el-form-item label="投诉人" prop="complainantName">
+          <el-input v-model="form.complainantName" placeholder="请输入投诉人姓名" />
         </el-form-item>
-        <el-form-item label="投诉标题" prop="title">
-          <el-input v-model="form.title" placeholder="请输入投诉标题" />
+        <el-form-item label="联系电话" prop="phone">
+          <el-input v-model="form.phone" placeholder="请输入联系电话" />
         </el-form-item>
-        <el-form-item label="投诉内容">
-          <editor v-model="form.content" :min-height="192"/>
+
+        <el-form-item label="投诉分类" prop="type">
+          <el-select v-model="form.type" placeholder="请选择投诉分类" style="width: 100%">
+            <el-option
+              v-for="category in categoryList"
+              :key="category.id"
+              :label="category.categoryName"
+              :value="category.id"
+            />
+          </el-select>
         </el-form-item>
-        <el-form-item label="投诉图片" prop="images">
-          <el-input v-model="form.images" placeholder="请输入投诉图片" />
+
+        <el-form-item label="投诉内容" prop="content">
+          <el-input v-model="form.content" type="textarea" placeholder="请输入投诉内容" :rows="4" />
         </el-form-item>
-        <el-form-item label="投诉类型0默认1店铺2商品" prop="type">
-          <el-select v-model="form.type" placeholder="请选择投诉类型0默认1店铺2商品">
-            <el-option label="请选择字典生成" value="" />
-          </el-select>
+        <!-- 图片上传 -->
+        <el-form-item label="投诉凭证" prop="url">
+          <image-upload
+            v-model="form.url"
+            :limit="0"
+            :file-size="5"
+            @change="handleImageChange"
+          />
+          <el-button type="primary" @click="submitForm">提交</el-button>
         </el-form-item>
-        <el-form-item label="关联ID" prop="linkId">
-          <el-input v-model="form.linkId" placeholder="请输入关联ID" />
+        <el-form-item label="投诉状态" prop="status" v-if="form.id">
+          <el-select v-model="form.status" placeholder="请选择投诉状态">
+            <el-option label="待处理" value="0" />
+            <el-option label="已处理" value="1" />
+          </el-select>
         </el-form-item>
-        <el-form-item label="备注" prop="remark">
-          <el-input v-model="form.remark" placeholder="请输入备注" />
+        <el-form-item label="处理备注" prop="remark" v-if="form.id">
+          <el-input v-model="form.remark" type="textarea" placeholder="请输入处理备注" :rows="3" />
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
@@ -165,20 +181,54 @@
         <el-button @click="cancel">取 消</el-button>
       </div>
     </el-dialog>
+
+    <!-- 投诉详情对话框 -->
+    <el-dialog title="投诉详情" :visible.sync="detailOpen" width="600px" append-to-body>
+      <el-descriptions :column="2" border>
+        <el-descriptions-item label="投诉单号">{{ detailData.complaintNo }}</el-descriptions-item>
+        <el-descriptions-item label="投诉状态">
+          <el-tag v-if="detailData.status === '0'" type="warning">待处理</el-tag>
+          <el-tag v-else-if="detailData.status === '1'" type="success">已处理</el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="投诉人">{{ detailData.complainantName }}</el-descriptions-item>
+        <el-descriptions-item label="联系电话">{{ detailData.phone }}</el-descriptions-item>
+        <el-descriptions-item label="投诉分类">{{ detailData.categoryName }}</el-descriptions-item>
+        <el-descriptions-item label="投诉时间" :span="2">
+          {{ parseTime(detailData.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
+        </el-descriptions-item>
+        <el-descriptions-item label="投诉内容" :span="2">{{ detailData.content }}</el-descriptions-item>
+        <el-descriptions-item label="处理备注" :span="2" v-if="detailData.remark">
+          {{ detailData.remark }}
+        </el-descriptions-item>
+      </el-descriptions>
+      <div slot="footer" class="dialog--footer">
+        <el-button @click="detailOpen = false">关 闭</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script>
-import { listComplaint, getComplaint, delComplaint, addComplaint, updateComplaint, exportComplaint } from "@/api/user/complaint";
+import {
+  getComplaintPage,
+  getComplaintById,
+  submitComplaint,
+  updateComplaint,
+  deleteComplaint,
+  handleComplaint,
+  getAllCategory
+} from "@/api/complaint/complaint";
+import {parseTime} from "../../../utils/common";
+import ImageUpload from "@/components/ImageUpload/index.vue";
 
 export default {
   name: "Complaint",
+  components: {ImageUpload},
   data() {
     return {
+      categoryList: [],
       // 遮罩层
       loading: true,
-      // 导出遮罩层
-      exportLoading: false,
       // 选中数组
       ids: [],
       // 非单个禁用
@@ -189,38 +239,76 @@ export default {
       showSearch: true,
       // 总条数
       total: 0,
-      // 用户投诉表格数据
+      // 投诉表格数据
       complaintList: [],
       // 弹出层标题
       title: "",
       // 是否显示弹出层
       open: false,
+      // 是否显示详情弹出层
+      detailOpen: false,
+      // 详情数据
+      detailData: {},
+      // 日期范围
+      dateRange: [],
       // 查询参数
       queryParams: {
         pageNum: 1,
         pageSize: 10,
-        fsUserId: null,
-        title: null,
-        content: null,
-        images: null,
-        type: null,
-        linkId: null,
+        complaintNo: null,
+        status: null,
+        startTime: null,
+        endTime: null
       },
       // 表单参数
       form: {},
       // 表单校验
       rules: {
+        complainantName: [
+          { required: true, message: "投诉人姓名不能为空", trigger: "blur" }
+        ],
+        phone: [
+          { required: true, message: "联系电话不能为空", trigger: "blur" },
+          { pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请输入正确的手机号码", trigger: "blur" }
+        ],
+        type: [
+          { required: true, message: "投诉分类不能为空", trigger: "change" }
+        ],
+        content: [
+          { required: true, message: "投诉内容不能为空", trigger: "blur" }
+        ]
       }
     };
   },
   created() {
+    this.getCategoryList();
     this.getList();
   },
   methods: {
-    /** 查询用户投诉列表 */
+    handleImageChange(newImages) {
+      this.form.url = newImages;
+    },
+    /** 获取投诉分类列表 */
+    getCategoryList() {
+      getAllCategory().then(response => {
+        this.categoryList = response.data || [];
+      }).catch(() => {
+        this.$message.error('获取投诉分类失败');
+        this.categoryList = [];
+      });
+    },
+    parseTime,
+    /** 查询投诉列表 */
     getList() {
       this.loading = true;
-      listComplaint(this.queryParams).then(response => {
+      if (this.dateRange != null && this.dateRange.length === 2) {
+        this.queryParams.startTime = this.dateRange[0];
+        this.queryParams.endTime = this.dateRange[1];
+      } else {
+        this.queryParams.startTime = null;
+        this.queryParams.endTime = null;
+      }
+      getComplaintPage(this.queryParams).then(response => {
         this.complaintList = response.rows;
         this.total = response.total;
         this.loading = false;
@@ -235,16 +323,10 @@ export default {
     reset() {
       this.form = {
         id: null,
-        fsUserId: null,
-        title: null,
+        complainantName: null,
+        phone: null,
         content: null,
-        images: null,
-        type: null,
-        linkId: null,
-        createTime: null,
-        createBy: null,
-        updateTime: null,
-        updateBy: null,
+        status: "0",
         remark: null
       };
       this.resetForm("form");
@@ -256,6 +338,7 @@ export default {
     },
     /** 重置按钮操作 */
     resetQuery() {
+      this.dateRange = [];
       this.resetForm("queryForm");
       this.handleQuery();
     },
@@ -269,67 +352,86 @@ export default {
     handleAdd() {
       this.reset();
       this.open = true;
-      this.title = "添加用户投诉";
+      this.title = "添加投诉";
     },
     /** 修改按钮操作 */
     handleUpdate(row) {
       this.reset();
       const id = row.id || this.ids
-      getComplaint(id).then(response => {
+      getComplaintById(id).then(response => {
         this.form = response.data;
         this.open = true;
-        this.title = "修改用户投诉";
+        this.title = "修改投诉";
+      });
+    },
+    /** 查看详情 */
+    handleDetail(row) {
+      getComplaintById(row.id).then(response => {
+        this.detailData = response.data;
+        this.detailOpen = true;
+      });
+    },
+    /** 处理投诉 */
+    handleProcess(row) {
+      this.$confirm('是否确认将投诉单号为"' + row.complaintNo + '"的投诉标记为已处理?').then(() => {
+        handleComplaint(row.id).then(() => {
+          this.$message.success('处理成功');
+          this.getList();
+        }).catch(() => {
+          this.$message.error('处理失败');
+        });
       });
     },
-    /** 提交按钮 */
+    /** 删除投诉 */
+    handleDelete(row) {
+      const ids = row ? [row.id] : this.ids;
+      this.$confirm('确认删除选中的投诉吗?').then(() => {
+        deleteComplaint(ids).then(() => {
+          this.$message.success('删除成功');
+          this.getList();
+        }).catch(() => {
+          this.$message.error('删除失败');
+        });
+      });
+    },
+    /** 提交表单 */
     submitForm() {
-      this.$refs["form"].validate(valid => {
+      this.$refs['form'].validate((valid) => {
         if (valid) {
-          if (this.form.id != null) {
-            updateComplaint(this.form).then(response => {
-              this.msgSuccess("修改成功");
-              this.open = false;
+          if (this.form.id) {
+            updateComplaint(this.form.id, this.form).then(() => {
+              this.$message.success('修改成功');
               this.getList();
+              this.cancel();
+            }).catch(() => {
+              this.$message.error('修改失败');
             });
           } else {
-            addComplaint(this.form).then(response => {
-              this.msgSuccess("新增成功");
-              this.open = false;
+            submitComplaint(this.form).then(() => {
+              this.$message.success('添加成功');
               this.getList();
+              this.cancel();
+            }).catch(() => {
+              this.$message.error('添加失败');
             });
           }
+        } else {
+          return false;
         }
       });
-    },
-    /** 删除按钮操作 */
-    handleDelete(row) {
-      const ids = row.id || this.ids;
-      this.$confirm('是否确认删除用户投诉编号为"' + ids + '"的数据项?', "警告", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        }).then(function() {
-          return delComplaint(ids);
-        }).then(() => {
-          this.getList();
-          this.msgSuccess("删除成功");
-        }).catch(() => {});
-    },
-    /** 导出按钮操作 */
-    handleExport() {
-      const queryParams = this.queryParams;
-      this.$confirm('是否确认导出所有用户投诉数据项?', "警告", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        }).then(() => {
-          this.exportLoading = true;
-          return exportComplaint(queryParams);
-        }).then(response => {
-          this.download(response.msg);
-          this.exportLoading = false;
-        }).catch(() => {});
     }
   }
 };
 </script>
+
+<style scoped>
+.app-container {
+  padding: 20px;
+}
+.mb8 {
+  margin-bottom: 8px;
+}
+.fixed-width {
+  width: 120px;
+}
+</style>

+ 755 - 0
src/views/user/rechargeTemplate/index.vue

@@ -0,0 +1,755 @@
+<template>
+  <div class="app-container">
+    <!-- 查询条件 -->
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="模板名称" prop="templateName">
+        <el-input
+          v-model="queryParams.templateName"
+          placeholder="请输入模板名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
+          <el-option label="启用" value="1" />
+          <el-option label="禁用" value="0" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="标签" prop="tag">
+        <el-input
+          v-model="queryParams.tag"
+          placeholder="请输入标签"
+          clearable
+          @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="['recharge:template:add']"
+        >新增</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="['recharge:template:remove']"
+        >删除</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <!-- 表格数据 -->
+    <el-table v-loading="loading" :data="templateList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="模板ID" align="center" prop="id" width="80" />
+      <el-table-column label="模板名称" align="center" prop="templateName" :show-overflow-tooltip="true" />
+      <el-table-column label="储值金额" align="center" prop="rechargeAmount" width="100">
+        <template slot-scope="scope">
+          <span>¥{{ scope.row.rechargeAmount }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="赠送金额" align="center" prop="bonusAmount" width="100">
+        <template slot-scope="scope">
+          <span>¥{{ scope.row.bonusAmount || 0 }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="标签" align="center" prop="tag" width="100">
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.tag" size="mini">{{ scope.row.tag }}</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="限购次数" align="center" prop="purchaseLimit" width="100" />
+      <el-table-column label="排序" align="center" prop="sortOrder" width="80" />
+      <el-table-column label="状态" align="center" prop="status" width="100">
+        <template slot-scope="scope">
+          <el-switch
+            v-model="scope.row.status"
+            :active-value="1"
+            :inactive-value="0"
+            @change="handleStatusChange(scope.row)"
+          ></el-switch>
+        </template>
+      </el-table-column>
+      <el-table-column label="默认选中" align="center" prop="isDefault" width="100">
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.isDefault === 1" type="success" size="mini">是</el-tag>
+          <el-tag v-else type="info" size="mini">否</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="绑定优惠券" align="center" width="100">
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.couponCount" type="primary" size="mini">{{ scope.row.couponCount }}张</el-tag>
+          <el-tag v-else type="info" size="mini">无</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="有效期" align="center" width="180">
+        <template slot-scope="scope">
+          <span v-if="scope.row.startTime && scope.row.endTime">
+            {{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }} 至 {{ parseTime(scope.row.endTime, '{y}-{m}-{d}') }}
+          </span>
+          <span v-else>永久有效</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-view"
+            @click="handleDetail(scope.row)"
+          >详情</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['recharge:template:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['recharge:template: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="800px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="模板名称" prop="templateName">
+              <el-input v-model="form.templateName" placeholder="请输入模板名称" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="储值金额" prop="rechargeAmount">
+              <el-input-number v-model="form.rechargeAmount" :precision="2" :min="0" placeholder="请输入储值金额" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="赠送金额" prop="bonusAmount">
+              <el-input-number v-model="form.bonusAmount" :precision="2" :min="0" placeholder="请输入赠送金额" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="限购次数" prop="purchaseLimit">
+              <el-input-number v-model="form.purchaseLimit" :min="0" placeholder="请输入限购次数,0为不限制" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="排序序号" prop="sortOrder">
+              <el-input-number v-model="form.sortOrder" :min="0" placeholder="请输入排序序号" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="标签" prop="tag">
+              <el-input v-model="form.tag" placeholder="请输入标签" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <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-col>
+          <el-col :span="12">
+            <el-form-item label="默认选中" prop="isDefault">
+              <el-radio-group v-model="form.isDefault">
+                <el-radio :label="1">是</el-radio>
+                <el-radio :label="0">否</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="有效期" prop="validTime">
+              <el-date-picker
+                v-model="validTime"
+                type="datetimerange"
+                range-separator="至"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                format="yyyy-MM-dd HH:mm:ss"
+              ></el-date-picker>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="图标" prop="iconUrl">
+              <el-upload
+                class="avatar-uploader"
+                :action="uploadFileUrl"
+                :headers="headers"
+                :show-file-list="false"
+                :on-success="handleIconSuccess"
+                :before-upload="beforeIconUpload"
+                :on-error="handleIconError"
+              >
+                <img v-if="form.iconUrl" :src="form.iconUrl" class="avatar" />
+                <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+              </el-upload>
+              <div class="el-upload__tip">
+                <div v-if="form.iconUrl" style="margin-top: 10px;">
+                  <el-button size="mini" type="danger" icon="el-icon-delete" @click="handleIconRemove">移除</el-button>
+                </div>
+                <div style="color: #999; font-size: 12px; margin-top: 5px;">
+                  只能上传jpg/png文件,且不超过2MB
+                </div>
+              </div>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="详情链接" prop="detailUrl">
+              <el-input v-model="form.detailUrl" placeholder="请输入详情链接" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="描述文案" prop="shortDesc">
+              <el-input v-model="form.shortDesc" type="textarea" placeholder="请输入描述文案" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="权益详情" prop="benefitDetails">
+              <el-input v-model="form.benefitDetails" type="textarea" placeholder="请输入权益详情" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="绑定优惠券" prop="couponIdList">
+              <el-select
+                v-model="form.couponIdList"
+                multiple
+                filterable
+                remote
+                reserve-keyword
+                placeholder="请输入优惠券名称搜索"
+                :remote-method="remoteCouponSearch"
+                :loading="couponLoading"
+                style="width: 100%"
+                @focus="handleCouponFocus"
+                @clear="handleCouponClear"
+                clearable
+              >
+                <el-option
+                  v-for="item in couponOptions"
+                  :key="item.couponId"
+                  :label="`${item.title}(¥${item.limitTime})`"
+                  :value="item.couponId"
+                >
+                  <span>{{ item.title }}</span>
+                  <span style="float: right; color: #8492a6; font-size: 13px">
+                    ¥{{ item.price }}
+                  </span>
+                </el-option>
+              </el-select>
+              <div class="el-form-item__tip" style="margin-top: 5px; color: #999; font-size: 12px;">
+                已选择 {{ form.couponIdList ? form.couponIdList.length : 0 }} 张优惠券
+              </div>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </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="detailOpen" width="800px" append-to-body>
+      <el-descriptions :column="2" border>
+        <el-descriptions-item label="模板名称">{{ detailData.templateName }}</el-descriptions-item>
+        <el-descriptions-item label="储值金额">¥{{ detailData.rechargeAmount }}</el-descriptions-item>
+        ```vue
+        <el-descriptions-item label="赠送金额">¥{{ detailData.bonusAmount || 0 }}</el-descriptions-item>
+        <el-descriptions-item label="限购次数">{{ detailData.purchaseLimit || '不限制' }}</el-descriptions-item>
+        <el-descriptions-item label="排序序号">{{ detailData.sortOrder }}</el-descriptions-item>
+        <el-descriptions-item label="标签">{{ detailData.tag || '无' }}</el-descriptions-item>
+        <el-descriptions-item label="状态">
+          <el-tag :type="detailData.status === 1 ? 'success' : 'danger'">
+            {{ detailData.status === 1 ? '启用' : '禁用' }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="默认选中">
+          <el-tag :type="detailData.isDefault === 1 ? 'success' : 'info'">
+            {{ detailData.isDefault === 1 ? '是' : '否' }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="有效期" :span="2">
+          <span v-if="detailData.startTime && detailData.endTime">
+            {{ parseTime(detailData.startTime, '{y}-{m}-{d} {h}:{i}:{s}') }} 至 {{ parseTime(detailData.endTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
+          </span>
+          <span v-else>永久有效</span>
+        </el-descriptions-item>
+        <el-descriptions-item label="图标" :span="2">
+          <img v-if="detailData.iconUrl" :src="getImageUrl(detailData.iconUrl)" style="max-height: 100px;" />
+          <span v-else>无</span>
+        </el-descriptions-item>
+        <el-descriptions-item label="详情链接" :span="2">{{ detailData.detailUrl || '无' }}</el-descriptions-item>
+        <el-descriptions-item label="描述文案" :span="2">{{ detailData.shortDesc || '无' }}</el-descriptions-item>
+        <el-descriptions-item label="权益详情" :span="2">{{ detailData.benefitDetails || '无' }}</el-descriptions-item>
+        <el-descriptions-item label="绑定优惠券" :span="2">
+          <div v-if="detailData.coupons && detailData.coupons.length > 0">
+            <el-tag v-for="(coupon, index) in detailData.coupons" :key="index" type="success" style="margin-right: 5px; margin-bottom: 5px;">
+              {{ coupon.title }} (¥{{ coupon.price }})
+            </el-tag>
+          </div>
+          <span v-else>无</span>
+        </el-descriptions-item>
+      </el-descriptions>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="detailOpen = false">关 闭</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  listRechargeTemplate,
+  getRechargeTemplate,
+  delRechargeTemplate,
+  addRechargeTemplate,
+  updateRechargeTemplate,
+  updateRechargeTemplateStatus,
+  getCouponList
+} from "@/api/recharge/template";
+import { getToken } from "@/utils/auth";
+import { parseTime } from "@/utils/common";
+
+export default {
+  name: "RechargeTemplate",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 充值模板表格数据
+      templateList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 是否显示详情弹出层
+      detailOpen: false,
+      // 详情数据
+      detailData: {},
+      // 有效期时间范围
+      validTime: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        templateName: null,
+        status: null,
+        tag: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        templateName: [
+          { required: true, message: "模板名称不能为空", trigger: "blur" }
+        ],
+        rechargeAmount: [
+          { required: true, message: "储值金额不能为空", trigger: "blur" }
+        ],
+        status: [
+          { required: true, message: "状态不能为空", trigger: "change" }
+        ],
+        sortOrder: [
+          { required: true, message: "排序序号不能为空", trigger: "blur" }
+        ]
+      },
+      // 上传参数
+      uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
+      headers: {
+        Authorization: "Bearer " + getToken()
+      },
+      // 优惠券相关
+      couponOptions: [],
+      couponLoading: false,
+      couponSearchTimer: null // 搜索防抖定时器
+    };
+  },
+  created() {
+    this.getList();
+  },
+  beforeDestroy() {
+    // 组件销毁时清理定时器
+    if (this.couponSearchTimer) {
+      clearTimeout(this.couponSearchTimer);
+    }
+  },
+  methods: {
+    parseTime,
+    handleIconRemove(){
+      this.form.iconUrl = null;
+    },
+    /** 查询充值模板列表 */
+    getList() {
+      this.loading = true;
+      listRechargeTemplate(this.queryParams).then(response => {
+        this.templateList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+
+    /** 搜索按钮操作 */
+    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.loadDefaultCoupons(); // 新增时加载默认选项
+      this.open = true;
+      this.title = "添加充值模板";
+    },
+
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids;
+      getRechargeTemplate(id).then(response => {
+        this.form = response.data;
+
+        // 设置有效期时间范围
+        if (this.form.startTime && this.form.endTime) {
+          this.validTime = [this.form.startTime, this.form.endTime];
+        }
+
+        // 如果已有绑定的优惠券,加载到选项中
+        if (this.form.couponIdList && this.form.couponIdList.length > 0) {
+          this.loadSelectedCoupons(this.form.couponIdList);
+        } else {
+          // 没有已选择的优惠券时,加载默认选项
+          this.loadDefaultCoupons();
+        }
+
+        this.open = true;
+        this.title = "修改充值模板";
+      });
+    },
+
+    /** 详情按钮操作 */
+    handleDetail(row) {
+      const id = row.id;
+      getRechargeTemplate(id).then(response => {
+        this.detailData = response.data;
+        this.detailOpen = true;
+      });
+    },
+
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          // 处理有效期时间
+          if (this.validTime && this.validTime.length === 2) {
+            this.form.startTime = this.validTime[0];
+            this.form.endTime = this.validTime[1];
+          } else {
+            this.form.startTime = null;
+            this.form.endTime = null;
+          }
+
+          if (this.form.id != null) {
+            updateRechargeTemplate(this.form).then(response => {
+              this.$message.success("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addRechargeTemplate(this.form).then(response => {
+              this.$message.success("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm('是否确认删除充值模板编号为"' + ids + '"的数据项?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        return delRechargeTemplate(ids);
+      }).then(() => {
+        this.getList();
+        this.$message.success("删除成功");
+      }).catch(() => {});
+    },
+
+    /** 状态修改 */
+    handleStatusChange(row) {
+      let text = row.status === 1 ? "启用" : "停用";
+      this.$confirm('确认要"' + text + '""' + row.templateName + '"模板吗?').then(() => {
+        return updateRechargeTemplateStatus(row.id, row.status);
+      }).then(() => {
+        this.$message.success(text + "成功");
+      }).catch(() => {
+        row.status = row.status === 0 ? 1 : 0;
+      });
+    },
+
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+
+    // 表单重置
+    reset() {
+      // 清理搜索定时器
+      if (this.couponSearchTimer) {
+        clearTimeout(this.couponSearchTimer);
+        this.couponSearchTimer = null;
+      }
+
+      this.form = {
+        id: null,
+        templateName: null,
+        rechargeAmount: null,
+        bonusAmount: null,
+        benefitDetails: null,
+        status: 1,
+        sortOrder: 0,
+        startTime: null,
+        endTime: null,
+        userType: null,
+        purchaseLimit: null,
+        tag: null,
+        shortDesc: null,
+        detailUrl: null,
+        iconUrl: null,
+        isDefault: 0,
+        couponIdList: []
+      };
+      this.validTime = [];
+      this.resetForm("form");
+      this.couponOptions = [];
+    },
+
+    // 优惠券下拉框获得焦点时
+    handleCouponFocus() {
+      // 如果没有选项且没有已选择的优惠券,加载默认选项
+      if (this.couponOptions.length === 0 && (!this.form.couponIdList || this.form.couponIdList.length === 0)) {
+        this.loadDefaultCoupons();
+      }
+    },
+
+    // 清空优惠券选择
+    handleCouponClear() {
+      this.form.couponIdList = [];
+    },
+
+    // 加载默认优惠券列表
+    loadDefaultCoupons() {
+      this.couponLoading = true;
+      getCouponList({
+        pageSize: 20,
+        pageNum: 1,
+        status: 1 // 只查询有效的优惠券
+      }).then(response => {
+        this.couponOptions = response.data.list || [];
+        this.couponLoading = false;
+      }).catch(() => {
+        this.couponLoading = false;
+        this.couponOptions = [];
+      });
+    },
+
+    // 远程搜索优惠券(添加防抖)
+    remoteCouponSearch(query) {
+      // 清除之前的定时器
+      if (this.couponSearchTimer) {
+        clearTimeout(this.couponSearchTimer);
+      }
+
+      // 设置新的定时器,300ms后执行搜索
+      this.couponSearchTimer = setTimeout(() => {
+        if (query && query.trim() !== '') {
+          this.couponLoading = true;
+          getCouponList({
+            couponName: query.trim(),
+            pageSize: 50, // 增加搜索结果数量
+            pageNum: 1,
+            status: 1 // 只查询有效的优惠券
+          }).then(response => {
+            this.couponOptions = response.data.list || [];
+            this.couponLoading = false;
+          }).catch(() => {
+            this.couponLoading = false;
+            this.couponOptions = [];
+            this.$message.error('搜索优惠券失败');
+          });
+        } else {
+          // 如果搜索为空,加载默认选项
+          this.loadDefaultCoupons();
+        }
+      }, 300);
+    },
+
+    // 加载已选择的优惠券
+    loadSelectedCoupons(couponIds) {
+      if (couponIds && couponIds.length > 0) {
+        this.couponLoading = true;
+        getCouponList({
+          couponIds: couponIds.join(',')
+        }).then(response => {
+          // 合并已选择的优惠券到选项中,避免重复
+          const selectedCoupons = response.data.list || [];
+          const existingIds = this.couponOptions.map(item => item.couponId);
+
+          selectedCoupons.forEach(coupon => {
+            if (!existingIds.includes(coupon.couponId)) {
+              this.couponOptions.push(coupon);
+            }
+          });
+
+          this.couponLoading = false;
+        }).catch(() => {
+          this.couponLoading = false;
+        });
+      }
+    },
+
+    // 获取完整的图片URL
+    getImageUrl(url) {
+      if (!url) return '';
+      // 如果已经是完整URL,直接返回
+      if (url.startsWith('http://') || url.startsWith('https://')) {
+        return url;
+      }
+      // 如果是相对路径,拼接基础URL
+      return process.env.VUE_APP_BASE_API + url;
+    },
+
+    // 图标上传前校验
+    beforeIconUpload(file) {
+      const isJPG = file.type === 'image/jpeg';
+      const isPNG = file.type === 'image/png';
+      const isGIF = file.type === 'image/gif';
+      const isWebP = file.type === 'image/webp';
+      const isLt2M = file.size / 1024 /1024 < 2; // 限制大小为2MB
+      if (!isJPG && !isPNG && !isGIF && !isWebP) {
+        this.$message.error('上传头像图片只能是 JPG、PNG、GIF 或 WebP 格式!');
+      }
+      if (!isLt2M) {
+        this.$message.error('上传头像图片大小不能超过 2MB!');
+      }
+      return (isJPG || isPNG || isGIF || isWebP) && isLt2M;
+    },
+
+    // 图标上传成功后处理
+    handleIconUploadSuccess(response, file) {
+      if (response && response.url) {
+        this.form.iconUrl = response.url; // 赋值上传后的图片URL
+      } else {
+        this.$message.error('图标上传失败,请重试');
+      }
+    },
+
+    // 图标上传失败处理
+    handleIconUploadError() {
+      this.$message.error('图标上传失败,请重试');
+    },
+    handleIconSuccess(response, file) {
+      // 处理图标上传成功的逻辑
+      this.form.iconUrl = response.url; // 假设返回的数据结构有URL
+      this.$message.success('图标上传成功!');
+    },
+    handleIconError(err, file) {
+      // 处理图标上传失败的逻辑
+      this.$message.error('图标上传失败,请重试.');
+    },
+  }
+};
+</script>
+
+<style scoped>
+.dialog-footer {
+  text-align: right;
+}
+</style>
+