@@ -34,7 +34,7 @@ ENV = 'development'
VUE_APP_BASE_API = '/prod-api'
#默认 1、会员 2、企微
-VUE_APP_COURSE_DEFAULT = 2
+VUE_APP_COURSE_DEFAULT = 1
# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true
@@ -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/hyt.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_CLI_BABEL_TRANSPILE_MODULES = true
+VUE_APP_TITLE =济南联志健康互联网医院管理系统
+VUE_APP_TITLE_INDEX =济南联志健康互联网医院
+VUE_APP_COMPANY_NAME =济南联志健康
+VUE_APP_ICP_RECORD =渝ICP备2024031984号-2
+VUE_APP_LOG_URL =@/assets/logo/jnlzjk.png
+VUE_APP_OBS_BUCKET = jnlzjk-hw079058881
+VUE_APP_COS_BUCKET = jnlzjk-1323137866
+VUE_APP_VIDEO_LINE_1 = https://jnlzjktcpv.ylrzcloud.com
+VUE_APP_VIDEO_LINE_2 = https://jnlzjkobs.ylrztop.com
-VUE_APP_COURSE_DEFAULT = 1
+VUE_APP_COURSE_DEFAULT = 2
@@ -1,7 +1,7 @@
# 页面标题
VUE_APP_TITLE =木易华康互联网医院管理系统
# 首页菜单标题
-VUE_APP_TITLE_INDEX =木易华康互联网医院
+VUE_APP_TITLE_INDEX =康复e站
# 公司名称
VUE_APP_COMPANY_NAME =福州市木易华康医药有限公司
# ICP备案号
+VUE_APP_TITLE =内蒙古一贴医药
+VUE_APP_TITLE_INDEX =内蒙古一贴医药
+VUE_APP_COMPANY_NAME =内蒙古好药师蒙一堂大药房有限公司
+VUE_APP_ICP_RECORD =蒙ICP备2023002294号
+VUE_APP_LOG_URL =@/assets/logo/nmgyt.jpg
+VUE_APP_OBS_BUCKET = nmgyt-hw079058881
+VUE_APP_COS_BUCKET = nmgyt-1323137866
+VUE_APP_VIDEO_LINE_1 = https://nmgyttcpv.ylrzcloud.com
+VUE_APP_VIDEO_LINE_2 = https://nmgytobs.ylrztop.com
VUE_APP_TITLE =互联网医院管理系统
-VUE_APP_TITLE_INDEX =陕西今正
+VUE_APP_TITLE_INDEX =挑宝网
VUE_APP_COMPANY_NAME =银川鑫泰互联网医院有限公司
@@ -19,7 +19,7 @@ VUE_APP_OBS_SERVER = https://obs.cn-north-4.myhuaweicloud.com
# 存储桶配置
VUE_APP_OBS_BUCKET = syysy-hw079058881
-VUE_APP_COS_BUCKET = syysy -1323137866
+VUE_APP_COS_BUCKET = syysy-1323137866
VUE_APP_COS_REGION = ap-chongqing
# 线路一地址
@@ -13,6 +13,7 @@
"build:prod-jzzx": "vue-cli-service build --mode prod-jzzx",
"build:prod-hcl": "vue-cli-service build --mode prod-hcl",
"build:prod-myhk": "vue-cli-service build --mode prod-myhk",
+ "build:prod-nmgyt": "vue-cli-service build --mode prod-nmgyt",
"build:prod-sxjz": "vue-cli-service build --mode prod-sxjz",
"build:prod-xfk": "vue-cli-service build --mode prod-xfk",
"build:prod-jnmy": "vue-cli-service build --mode prod-jnmy",
@@ -32,9 +33,11 @@
"build:prod-cqxzt": "vue-cli-service build --mode prod-cqxzt",
"build:prod-bjyjb": "vue-cli-service build --mode prod-bjyjb",
"build:prod-bjczwh": "vue-cli-service build --mode prod-bjczwh",
+ "build:prod-jnlzjk": "vue-cli-service build --mode prod-jnlzjk",
"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"
},
@@ -100,7 +100,7 @@ export function exportCustomer(query) {
})
}
-
export function customerVisit(query) {
return request({
url: '/company/statistics/customerVisit',
@@ -116,6 +116,28 @@ export function exportCustomerVisit(query) {
+export function ipadStaticTotal(dateTime) {
+ return request({
+ url: '/company/statistics/ipadStaticTotal/' + dateTime,
+ method: 'get'
+ })
+}
+export function exportIpadStaticByTime(dateTime) {
+ url: '/company/statistics/exportIpadStaticByTime/' + dateTime,
+export function tokenStaticTotal(dateTime) {
+ url: '/company/statistics/tokenStaticTotal/' + dateTime,
+export function exportTokenStaticByTime(dateTime) {
+ url: '/company/statistics/exportTokenStaticByTime/' + dateTime,
@@ -0,0 +1,18 @@
+import request from '@/utils/request'
+export function rechargeTraffic(data) {
+ url: '/company/traffic/rechargeTraffic',
+ method: 'post',
+ data: data
+export function listTrafficRecords(query) {
+ url: '/company/traffic/list',
+ method: 'get',
+ params: query
@@ -0,0 +1,19 @@
+export function listTrafficLogExport(query) {
+ url: '/company/trafficLog/export',
+export function listTrafficLog(query) {
+ url: '/company/trafficLog/list',
@@ -0,0 +1,53 @@
+// 查询投诉分类列表
+export function listCategory(query) {
+ url: '/complaint/category/list',
+// 查询投诉分类详细
+export function getCategory(id) {
+ url: '/complaint/category/' + id,
+// 新增投诉分类
+export function addCategory(data) {
+ url: '/complaint/category',
+// 修改投诉分类
+export function updateCategory(data) {
+ method: 'put',
+// 删除投诉分类
+export function delCategory(ids) {
+ url: '/complaint/category/' + ids,
+ method: 'delete'
+// 修改投诉分类状态
+export function changeStatus(data) {
+ url: '/complaint/category/status',
@@ -0,0 +1,75 @@
+// 提交投诉
+export function submitComplaint(data) {
+ url: '/complaint',
+// 根据ID查询投诉详情
+export function getComplaintById(id) {
+ url: `/complaint/${id}`,
+// 根据投诉单号查询投诉详情
+export function getComplaintByNo(complaintNo) {
+ url: `/complaint/no/${complaintNo}`,
+// 分页查询投诉列表
+export function getComplaintPage(data) {
+ url: '/complaint/list',
+// 更新投诉信息
+export function updateComplaint(id, data) {
+ data: {
+ ...data,
+ type: data.categoryId
+ }
+// 删除投诉
+export function deleteComplaint(id) {
+// 处理投诉(快捷更新状态为已处理)
+export function handleComplaint(id) {
+ status: '1' // 假设1表示已处理状态
+// 新增:获取所有投诉分类
+export function getAllCategory() {
+ url: '/complaint/queryAllCategory',
+ method: 'post'
@@ -0,0 +1,46 @@
+export function list(query) {
+ url: '/course/playSourceConfig/list',
+export function get(id) {
+ url: '/course/playSourceConfig/' + id,
+export function add(data) {
+ url: '/course/playSourceConfig',
+export function update(data) {
+export function del(id) {
+export function listAll() {
+ url: '/course/playSourceConfig/listAll',
@@ -35,6 +35,15 @@ export function listCourseWatchComment(query) {
// })
// }
//
+// 修改弹幕状态
+export function updateBarrageStatus(data) {
+ url: '/course/courseWatchComment/updateBarrageStatus',
// 删除看课评论
export function delCourseWatchComment(commentId) {
@@ -60,3 +69,12 @@ export function addBlack(query) {
params: query
+// 解除拉黑外部联系人
+export function clearBlack(query) {
+ url: '/course/courseWatchComment/clearBlack',
@@ -51,6 +51,15 @@ export function exportFsCourseProductOrder(query) {
+// 导出拍单商品订单(解密手机号)
+export function exportFsCourseProductOrderDecodePhone(query) {
+ url: '/course/fsCourseProductOrder/decodeExport',
// 退款拍商品订单
export function refund(data) {
@@ -67,4 +76,4 @@ export function getOrderUserPhone(courseOrderId) {
url: '/course/fsCourseProductOrder/queryPhone/' + courseOrderId,
method: 'get'
-}
@@ -52,3 +52,11 @@ export function batchAddVideoResource(data) {
+// 批量修改视频资源
+export function batchUpdateVideoResource(data) {
+ url: '/course/videoResource/batchUpdateClass',
+ params: data
@@ -0,0 +1,70 @@
+// 查询处理新客标签列表
+export function listFastGptExtUserTag(query) {
+ url: '/fastGpt/FastGptExtUserTag/list',
+// 查询处理新客标签详细
+export function getFastGptExtUserTag(id) {
+ url: '/fastGpt/FastGptExtUserTag/' + id,
+// 新增处理新客标签
+export function addFastGptExtUserTag(data) {
+ url: '/fastGpt/FastGptExtUserTag',
+// 修改处理新客标签
+export function updateFastGptExtUserTag(data) {
+// 删除处理新客标签
+export function delFastGptExtUserTag(id) {
+// 导出处理新客标签
+export function exportFastGptExtUserTag(query) {
+ url: '/fastGpt/FastGptExtUserTag/export',
+export function addFastGptTagByCorpId(data) {
+ url: '/fastGpt/FastGptExtUserTag/addFastGptTagByCorpId',
+export function getMyQwUserList(query) {
+ url: '/fastGpt/FastGptExtUserTag/getMyQwUserList',
+// 查询违规词语列表
+export function listFastGptChatReplaceText(query) {
+ url: '/fastGpt/fastGptChatReplaceText/list',
+// 查询违规词语详细
+export function getFastGptChatReplaceText(id) {
+ url: '/fastGpt/fastGptChatReplaceText/' + id,
+// 新增违规词语
+export function addFastGptChatReplaceText(data) {
+ url: '/fastGpt/fastGptChatReplaceText',
+// 修改违规词语
+export function updateFastGptChatReplaceText(data) {
+// 删除违规词语
+export function delFastGptChatReplaceText(id) {
+// 导出违规词语
+export function exportFastGptChatReplaceText(query) {
+ url: '/fastGpt/fastGptChatReplaceText/export',
@@ -0,0 +1,62 @@
+// 查询Ai指令关键字列表
+export function keywordList(query) {
+ url: '/fastGpt/fastGptKeywordSend/keywordList',
+// 查询Ai指令列表
+export function listFastGptKeywordSend(query) {
+ url: '/fastGpt/fastGptKeywordSend/list',
+// 查询Ai指令详细
+export function getFastGptKeywordSend(id) {
+ url: '/fastGpt/fastGptKeywordSend/' + id,
+// 新增Ai指令
+export function addFastGptKeywordSend(data) {
+ url: '/fastGpt/fastGptKeywordSend',
+// 修改Ai指令
+export function updateFastGptKeywordSend(data) {
+// 删除Ai指令
+export function delFastGptKeywordSend(id) {
+// 导出Ai指令
+export function exportFastGptKeywordSend(query) {
+ url: '/fastGpt/fastGptKeywordSend/export',
+// 查询转人工提示词列表
+export function listFastgptChatArtificialWords(query) {
+ url: '/fastGpt/fastgptChatArtificialWords/list',
+// 查询转人工提示词详细
+export function getFastgptChatArtificialWords(id) {
+ url: '/fastGpt/fastgptChatArtificialWords/' + id,
+// 新增转人工提示词
+export function addFastgptChatArtificialWords(data) {
+ url: '/fastGpt/fastgptChatArtificialWords',
+// 修改转人工提示词
+export function updateFastgptChatArtificialWords(data) {
+// 删除转人工提示词
+export function delFastgptChatArtificialWords(id) {
+// 导出转人工提示词
+export function exportFastgptChatArtificialWords(query) {
+ url: '/fastGpt/fastgptChatArtificialWords/export',
+// 查询ai事件埋点统计列表
+/*export function listFastgptEventLogTotal(query) {
+ url: '/fastGpt/fastgptEventLogTotal/list',
+}*/
+export function listFastgptEventLogTotal(data) {
+// 查询ai事件埋点统计详细
+export function getFastgptEventLogTotal(id) {
+ url: '/fastGpt/fastgptEventLogTotal/' + id,
+// 新增ai事件埋点统计
+export function addFastgptEventLogTotal(data) {
+ url: '/fastGpt/fastgptEventLogTotal',
+// 修改ai事件埋点统计
+export function updateFastgptEventLogTotal(data) {
+// 删除ai事件埋点统计
+export function delFastgptEventLogTotal(id) {
+// 导出ai事件埋点统计
+export function exportFastgptEventLogTotal(query) {
+ url: '/fastGpt/fastgptEventLogTotal/export',
+export function getFastGptRoleAppKeyList() {
+ url: '/fastGpt/fastgptEventLogTotal/getFastGptRoleAppKeyList',
@@ -0,0 +1,44 @@
+// 查询饮食记录列表
+export function listFoodRecord(query) {
+ url: '/food-record/admin/list',
+// 查询饮食记录详细
+export function getFoodRecord(id) {
+ url: '/food-record/getRecordInfo/' + id,
+// 新增饮食记录
+export function addFoodRecord(data) {
+ url: '/food-record/addRecord',
+// 修改饮食记录
+export function updateFoodRecord(data) {
+ url: '/food-record/editRecord',
+// 删除饮食记录
+export function delFoodRecord(id) {
+ url: '/food-record/deleteRecord/' + id,
@@ -0,0 +1,106 @@
+// 查询用户投诉列表
+export function listComplaint(data) {
+ url: '/user/complaint/list',
+// 查询用户投诉详细
+export function getComplaint(id) {
+ url: '/user/complaint/' + id,
+// 新增用户投诉
+export function addComplaint(data) {
+ url: '/user/complaint',
+// 修改用户投诉
+export function updateComplaint(data) {
+// 删除用户投诉
+export function delComplaint(id) {
+// 导出用户投诉
+export function exportComplaint(query) {
+ url: '/user/complaint/export',
+// 查询投诉消息记录列表
+export function listMsg(query) {
+ url: '/user/msg/list',
+// 查询投诉消息记录详细
+export function getMsg(id) {
+ url: '/user/msg/' + id,
+// 新增投诉消息记录
+export function addMsg(data) {
+ url: '/user/msg',
+// 修改投诉消息记录
+export function updateMsg(data) {
+// 删除投诉消息记录
+export function delMsg(id) {
+// 导出投诉消息记录
+export function exportMsg(query) {
+ url: '/user/msg/export',
+// 查询初诊单列表
+export function listFsFirstDiagnosis(query) {
+ url: '/his/fsFirstDiagnosis/list',
+// 查询初诊单详细
+export function getFsFirstDiagnosis(id) {
+ url: '/his/fsFirstDiagnosis/' + id,
+// 新增初诊单
+export function addFsFirstDiagnosis(data) {
+ url: '/his/fsFirstDiagnosis',
+// 修改初诊单
+export function updateFsFirstDiagnosis(data) {
+// 删除初诊单
+export function delFsFirstDiagnosis(id) {
+// 导出初诊单
+export function exportFsFirstDiagnosis(query) {
+ url: '/his/fsFirstDiagnosis/export',
+// 查询汇付多支付配置列表
+export function listHfpayConfig(query) {
+ url: '/his/hfpayConfig/list',
+// 查询汇付多支付配置详细
+export function getHfpayConfig(id) {
+ url: '/his/hfpayConfig/' + id,
+// 新增汇付多支付配置
+export function addHfpayConfig(data) {
+ url: '/his/hfpayConfig',
+// 修改汇付多支付配置
+export function updateHfpayConfig(data) {
+// 删除汇付多支付配置
+export function delHfpayConfig(id) {
+// 导出汇付多支付配置
+export function exportHfpayConfig(query) {
+ url: '/his/hfpayConfig/export',
@@ -0,0 +1,27 @@
+// 新增患者问诊信息
+export function addinquiryPatient(data) {
+ url: '/his/inquiryPatientInfo',
+// 修改患者问诊信息
+export function updateinquiryPatient(data) {
+//获取患者问诊信息详情
+export function detail(inquiryOrderId) {
+ url: '/his/inquiryPatientInfo/detail/'+ inquiryOrderId,
@@ -9,6 +9,14 @@ export function listPatient(query) {
+export function listPatientList(query) {
+ url: '/his/patient/userList',
// 查询病人详细
export function getPatient(patientId) {
@@ -57,4 +65,4 @@ export function exportPatient(query) {
method: 'get',
+// 查询广告列表
+export function listAdv(query) {
+ url: '/his/adv/list',
+// 查询广告详细
+export function getAdv(advId) {
+ url: '/his/adv/' + advId,
+// 新增广告
+export function addAdv(data) {
+ url: '/his/adv',
+// 修改广告
+export function updateAdv(data) {
+// 删除广告
+export function delAdv(advId) {
+// 导出广告
+export function exportAdv(query) {
+ url: '/his/adv/export',
@@ -0,0 +1,76 @@
+// 查询快递公司列表
+export function listExpress(query) {
+ url: '/his/express/list',
+// 查询快递公司详细
+export function getExpress(id) {
+ url: '/his/express/' + id,
+export function getExpressList() {
+ url: '/his/express/getExpressList',
+// 新增快递公司
+export function addExpress(data) {
+ url: '/his/express',
+// 修改快递公司
+export function updateExpress(data) {
+// 删除快递公司
+export function delExpress(id) {
+// 导出快递公司
+export function exportExpress(query) {
+ url: '/his/express/export',
+//分配快递公司
+export function allotExpress(data,omsCode) {
+ url: '/his/express/allotExpress/'+omsCode,
+export function getCompanyByOmsCode(omsCode) {
+ url: '/his/express/omsCode/' + omsCode,
+// 查询免邮费列表
+export function listShippingTemplatesFree(query) {
+ url: '/store/shippingTemplatesFree/list',
+// 查询免邮费详细
+export function getShippingTemplatesFree(id) {
+ url: '/store/shippingTemplatesFree/' + id,
+// 新增免邮费
+export function addShippingTemplatesFree(data) {
+ url: '/store/shippingTemplatesFree',
+// 修改免邮费
+export function updateShippingTemplatesFree(data) {
+// 删除免邮费
+export function delShippingTemplatesFree(id) {
+// 导出免邮费
+export function exportShippingTemplatesFree(query) {
+ url: '/store/shippingTemplatesFree/export',
+// 查询邮费区域列表
+export function listShippingTemplatesRegion(query) {
+ url: '/store/shippingTemplatesRegion/list',
+// 查询邮费区域详细
+export function getShippingTemplatesRegion(id) {
+ url: '/store/shippingTemplatesRegion/' + id,
+// 新增邮费区域
+export function addShippingTemplatesRegion(data) {
+ url: '/store/shippingTemplatesRegion',
+// 修改邮费区域
+export function updateShippingTemplatesRegion(data) {
+// 删除邮费区域
+export function delShippingTemplatesRegion(id) {
+// 导出邮费区域
+export function exportShippingTemplatesRegion(query) {
+ url: '/store/shippingTemplatesRegion/export',
@@ -0,0 +1,61 @@
+// 查询医疗指标分页列表
+export function listIndicator(query) {
+ url: '/admin/medical/indicator/page',
+// 查询所有启用的指标
+export function listAllEnabled() {
+ url: '/admin/medical/indicator/listEnabled',
+// 根据分类查询指标
+export function listByCategory(category) {
+ url: '/admin/medical/indicator/listByCategory',
+ params: { category }
+// 查询医疗指标详细
+export function getIndicator(indicatorId) {
+ url: '/admin/medical/indicator/' + indicatorId,
+// 新增医疗指标
+export function addIndicator(data) {
+ url: '/admin/medical/indicator/add',
+// 修改医疗指标
+export function updateIndicator(data) {
+ url: '/admin/medical/indicator/update',
+// 删除医疗指标
+export function delIndicator(indicatorId) {
@@ -0,0 +1,64 @@
+// 查询体检报告分页列表
+export function listReport(query) {
+ url: '/admin/medical/report/page',
+// 查询体检报告详细
+export function getReport(reportId) {
+ url: '/admin/medical/report/' + reportId,
+// 根据用户ID查询体检报告列表
+export function listReportByUser(userId) {
+ url: '/admin/medical/report/listByUser/' + userId,
+// 根据用户ID和体检日期查询体检报告
+export function getReportByUserAndDate(userId, examDate) {
+ url: '/admin/medical/report/getByUserAndDate',
+ params: {
+ userId: userId,
+ examDate: examDate
+// 新增体检报告
+export function addReport(data) {
+ url: '/admin/medical/report/add',
+// 修改体检报告
+export function updateReport(data) {
+ url: '/admin/medical/report/update',
+// 删除体检报告
+export function delReport(reportId) {
@@ -0,0 +1,69 @@
+// 查询报告指标检查结果列表
+export function listResult(query) {
+ url: '/admin/medical/result/page',
+// 查询报告指标检查结果详细
+export function getResult(resultId) {
+ url: '/admin/medical/result/' + resultId,
+// 根据报告ID查询所有指标结果
+export function listByReportId(reportId) {
+ url: '/admin/medical/result/listByReport/' + reportId,
+// 根据指标ID查询所有结果
+export function listByIndicatorId(indicatorId) {
+ url: '/admin/medical/result/listByIndicator/' + indicatorId,
+// 新增报告指标检查结果
+export function addResult(data) {
+ url: '/admin/medical/result/add',
+// 批量新增报告指标检查结果
+export function batchAddResult(data) {
+ url: '/admin/medical/result/batchAdd',
+// 修改报告指标检查结果
+export function updateResult(data) {
+ url: '/admin/medical/result/update',
+// 删除报告指标检查结果
+export function delResult(resultId) {
+// 查询所有计量单位
+export function listAllUnit() {
+ url: '/admin/medical/unit/listAll',
+// 分页查询计量单位列表
+export function listUnit(query) {
+ url: '/admin/medical/unit/page',
+// 根据单位类型查询计量单位
+export function listUnitByType(unitType) {
+ url: '/admin/medical/unit/listByType',
+ params: { unitType }
+// 查询计量单位详细
+export function getUnit(unitId) {
+ url: '/admin/medical/unit/' + unitId,
+// 新增计量单位
+export function addUnit(data) {
+ url: '/admin/medical/unit/add',
+// 修改计量单位
+export function updateUnit(data) {
+ url: '/admin/medical/unit/update',
+// 删除计量单位
+export function delUnit(unitId) {
@@ -51,3 +51,12 @@ export function exportExternalContact(query) {
+// 导出企业微信客户unionId
+export function exportUnionId(query) {
+ url: '/qw/externalContact/exportUnionId',
@@ -16,6 +16,14 @@ export function allListTagGroup(query) {
+export function getAllListTagGroup(query) {
+ url: '/qw/tagGroup/getAllList',
// 查询企微客户标签组详细
export function getTagGroup(id) {
+// 查询充值模板列表
+export function listRechargeTemplate(query) {
+ url: '/recharge-templates/list',
+ data: query
+// 查询充值模板详细
+export function getRechargeTemplate(id) {
+ url: '/recharge-templates/' + id,
+// 新增充值模板
+export function addRechargeTemplate(data) {
+ url: '/recharge-templates',
+// 修改充值模板
+export function updateRechargeTemplate(data) {
+ url: '/recharge-templates/' + data.id,
+// 删除充值模板
+export function delRechargeTemplate(id) {
+// 修改充值模板状态
+export function updateRechargeTemplateStatus(id, status) {
+ url: '/recharge-templates/' + id + '/status',
+ status: status
+/**
+ * 获取优惠券列表
+ * @param {Object} query 查询参数
+ * @returns {Promise} 请求结果
+ */
+export function getCouponList(query) {
+ url: '/recharge-templates/getCouponList',
@@ -0,0 +1,49 @@
+// 竞品信息模块请求前缀
+const prefix = '/saler/competitorInfo'
+// 查询竞品信息列表
+export function listCompetitorInfo(query) {
+ url: prefix + '/listPage',
+// 查询竞品信息详细
+export function getCompetitorInfo(id) {
+ url: prefix + '/findById',
+ data: { id }
+// 新增竞品信息
+export function addCompetitorInfo(data) {
+ url: prefix + '/save',
+// 修改竞品信息
+export function updateCompetitorInfo(data) {
+ url: prefix + '/updateById',
+// 删除竞品信息
+export function delCompetitorInfo(id) {
+ url: prefix + '/deleteById',
+// 查询商品列表
+export function listProductInfo(query) {
+ url: '/saler/serviceGoods/listPage',
+// 查询商品详细
+export function getProductInfo(id) {
+ url: '/saler/serviceGoods/findById',
+// 新增商品
+export function addProductInfo(data) {
+ url: '/saler/serviceGoods/save',
+// 修改商品
+export function updateProductInfo(data) {
+ url: '/saler/serviceGoods/updateById',
+// 删除商品
+export function delProductInfo(id) {
+ url: '/saler/serviceGoods/deleteById',
@@ -81,4 +81,11 @@ export function updateConfigByKey(data) {
method: 'post',
data: data
+export function updateIsTownOn(query) {
+ url: '/system/config/updateIsTownOn',
@@ -0,0 +1,81 @@
+// 查询待办事项列表
+export function listTodoItems(query) {
+ url: '/todoItems/listPage',
+// 查询待办事项详细
+export function getTodoItems(id) {
+ url: '/todoItems/findById',
+ data: { id: id }
+// 新增待办事项
+export function addTodoItems(data) {
+ url: '/todoItems/add',
+// 修改待办事项
+export function updateTodoItems(data) {
+ url: '/todoItems/updateById',
+// 更新待办事项状态
+export function updateTodoItemsStatus(id, status) {
+ url: '/todoItems/updateStatusById',
+ data: { id: id, status: status }
+// 删除待办事项
+export function delTodoItems(id) {
+ url: '/todoItems/removeById',
+// 分配执行者
+export function assignExecutor(data) {
+ url: '/todoItems/assignExecutor',
+// 获取可分配的执行者列表
+export function getExecutorList() {
+ url: '/todoItems/getExecutorList',
+// 获取执行人员列表(支持分页和公司名称搜索)
+export function getUserList(param) {
+ url: '/todoItems/getUserList',
+ data: param
+export function listComplaint(query) {
@@ -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 slot="footer">
+ <el-button @click="close">取消</el-button>
+ <el-button type="primary" @click="confirm">确定</el-button>
+ </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.$set(that.cityList[key], 'checked', false);
+ that.$set(that.cityList[key].children[k], 'checked', false);
+ this.iSselect = false;
+ * 点击省
+ * @param index
+ checkedClick: function (index) {
+ 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);
+ that.$set(that.cityList[index], 'count', 0);
+ that.$set(that.cityList[index], 'checked', false);
+ that.$set(that.cityList[index].children[key], 'checked', false);
+ that.iSselect = false;
+ * 点击市区
+ * @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 selectList = [];
+ let data = {};
+ 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'
+ this.$emit('selectCity', selectList, this.type);
+ that.addressView = false;
+ this.cityList = []
+ close () {
+ this.addressView = false;
+ 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 {
+ top: 3px;
+ width: 0;
+ height: 0;
+ border: 8px solid transparent;
+ border-bottom-color: #ddd;
+ .modal .item .city .checkBox .arrow:before {
+ bottom: -8px;
+ right: -7px;
+ content: "";
+ 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>
@@ -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)
@@ -1,97 +1,102 @@
-import COS from 'cos-js-sdk-v5';
-import { Message } from 'element-ui';
-import { getTmpSecretKey } from '@/api/common';
+import COS from "cos-js-sdk-v5"
+import { getTmpSecretKey } from "@/api/common"
-console.log('环境变量:', process.env);
-console.log('NODE_ENV:', process.env.NODE_ENV);
-console.log('VUE_APP_COS_BUCKET:', process.env.VUE_APP_COS_BUCKET);
-console.log('VUE_APP_COS_REGION:', process.env.VUE_APP_COS_REGION);
+console.log("环境变量:", process.env)
+console.log("NODE_ENV:", process.env.NODE_ENV)
+console.log("VUE_APP_COS_BUCKET:", process.env.VUE_APP_COS_BUCKET)
+console.log("VUE_APP_COS_REGION:", process.env.VUE_APP_COS_REGION)
const config = {
Bucket: process.env.VUE_APP_COS_BUCKET,
Region: process.env.VUE_APP_COS_REGION,
-};
-console.log('COS配置:', config);
+console.log("COS配置:", config)
-// 上传到腾讯云cos
-export const uploadObject = async (file,onProgress,type,callBackUp) => {
- try {
- console.log(type);
- const response = await getTmpSecretKey(); // 后台接口返回 密钥相关信息
- console.log("Key ",response);
- const data = response.data;
- const credentials = data && data.credentials;
+export const uploadObject = async (file, onProgress, type, callBackUp) => {
+ try {
+ console.log(type)
+ const response = await getTmpSecretKey()
+ console.log("Key ", response)
+ const data = response.data
+ const credentials = data && data.credentials
- if (!data || !credentials) {
- console.error('未获取到参数');
- return;
- }
+ if (!data || !credentials) {
+ console.error("未获取到参数")
+ return
+ const cos = new COS({
+ Timeout: 1200 * 1000,
+ getAuthorization: (options, callback) => {
+ callback({
+ TmpSecretId: credentials.tmpSecretId,
+ TmpSecretKey: credentials.tmpSecretKey,
+ XCosSecurityToken: credentials.sessionToken,
+ StartTime: data.startTime,
+ ExpiredTime: data.expiredTime,
- // 初始化
- const cos = new COS({
- Timeout: 1200 * 1000,
- getAuthorization: (options, callback) => {
- callback({
- TmpSecretId: credentials.tmpSecretId,
- TmpSecretKey: credentials.tmpSecretKey,
- XCosSecurityToken: credentials.sessionToken,
- StartTime: data.startTime,
- ExpiredTime: data.expiredTime,
- });
- },
+ console.log("初始化成功")
+ const fileName = file.name || ""
+ const upload_file_name = new Date().getTime() + "." + fileName.split(".")[fileName.split(".").length - 1]
+ const date = new Date()
+ const year = date.getFullYear()
+ const month = date.getMonth() + 1
+ const strDate = date.getDate()
+ const uploadDay = `${year}${month}${strDate}`
+ const videoKey = `/userVideo/${uploadDay}/${upload_file_name}`
+ const courseKey = `/course/${uploadDay}/${upload_file_name}`
+ const key = type === 1 ? courseKey : videoKey
+ console.log("开始上传")
- console.log("初始化成功")
- let fileName = file.name || ""
- const upload_file_name = new Date().getTime() + '.' + fileName.split(".")[fileName.split(".").length - 1];
- let date = new Date()
- let year = date.getFullYear()
- let month = date.getMonth() + 1
- let strDate = date.getDate()
- let uploadDay = `${year}${month}${strDate}`
- let videoKey = `/userVideo/${uploadDay}/${upload_file_name}`
- let courseKey = `/course/${uploadDay}/${upload_file_name}`
- let key = type ===1 ? courseKey : videoKey;
- console.log("开始上传")
- return new Promise((resolve, reject) => {
- console.log("uploadFile")
- cos.uploadFile(
- {
- Bucket: config.Bucket, /* 必须 */
- Region: config.Region, /* 存储桶所在地域,必须字段 */
- Key: key, // 文件名
- StorageClass: 'STANDARD', // 上传类型,可选
- Body: file, // 上传文件对象
- // onTaskReady: function (taskId) {
- // // 用于中断分片上传回调
- // console.log('Task ready:', taskId);
- // callBackUp && callBackUp({cos,taskId})
- // },
- onProgress: function (progressData) {
- console.log('COS上传进度=======>:', JSON.stringify(progressData));
- onProgress(progressData);
- // onFileFinish: function (err, data, options) {
- // console.log(options.Key + '上传' + (err ? '失败' : '完成'));
+ return new Promise((resolve, reject) => {
+ console.log("uploadFile")
+ let taskId = null
+ const uploadTask = cos.uploadFile(
+ {
+ Bucket: config.Bucket,
+ Region: config.Region,
+ Key: key,
+ StorageClass: "STANDARD",
+ Body: file,
+ onTaskReady: (id) => {
+ taskId = id
+ console.log("Task ready:", taskId)
+ if (callBackUp) {
+ callBackUp({
+ cos,
+ taskId,
+ cancel: () => {
+ console.log("Cancelling COS upload:", taskId)
+ cos.cancelTask(taskId)
+ reject(new Error("Upload cancelled by user"))
- (err, data) => {
- if (err) {
- reject(err);
- } else {
- // 将上传的key包含在返回的数据中
- const result = {
- ...data,
- urlPath: key
- };
- console.log('上传成功', result);
- resolve(result);
- );
- } catch (error) {
- console.error('Error during upload:', error);
- throw error;
+ onProgress: (progressData) => {
+ onProgress(progressData)
+ (err, data) => {
+ if (err) {
+ reject(err)
+ const result = {
+ urlPath: key,
+ console.log("上传成功", result)
+ resolve(result)
+ )
+ } catch (error) {
+ console.error("Error during upload:", error)
+ throw error
@@ -1,56 +1,73 @@
-import ObsClient from "esdk-obs-browserjs/src/obs";
+import ObsClient from "esdk-obs-browserjs/src/obs"
+export const uploadToOBS = async (file, progressCallback, type, cancelCallback) => {
+ const obsClient = new ObsClient({
+ access_key_id: process.env.VUE_APP_OBS_ACCESS_KEY_ID,
+ secret_access_key: process.env.VUE_APP_OBS_SECRET_ACCESS_KEY,
+ server: process.env.VUE_APP_OBS_SERVER,
+ timeout: 1200,
-export const uploadToOBS = async(file,progressCallback,type) => {
- const obsClient = new ObsClient({
- access_key_id: process.env.VUE_APP_OBS_ACCESS_KEY_ID,
- secret_access_key: process.env.VUE_APP_OBS_SECRET_ACCESS_KEY,
- server: process.env.VUE_APP_OBS_SERVER,
- timeout: 1200,
- let videoKey = `userVideo/${uploadDay}/${upload_file_name}`
- let courseKey = `course/${uploadDay}/${upload_file_name}`
- var callback = function (transferredAmount, totalAmount, totalSeconds) {
- // 获取上传进度百分比
- const progress = parseInt(transferredAmount * 100.0 / totalAmount);
- console.log("OBS上传进度=========>",progress);
- if (progressCallback) {
- progressCallback(progress);
- //上传对象
- obsClient.putObject({
- Bucket: process.env.VUE_APP_OBS_BUCKET,//桶名称
- Key: key,//文件名
- Body: file,
- ProgressCallback: callback,//进度回调
- }, (err, result) => {
- if(err){
- console.error('Error-->' + err);
- }else{
- const a = {
- ...result,
- console.log('上传成功', a);
- resolve(a);
+ const videoKey = `userVideo/${uploadDay}/${upload_file_name}`
+ const courseKey = `course/${uploadDay}/${upload_file_name}`
+ var callback = (transferredAmount, totalAmount, totalSeconds) => {
+ const progress = Number.parseInt((transferredAmount * 100.0) / totalAmount)
+ if (progressCallback) {
+ progressCallback(progress)
+ let isCancelled = false
+ if (cancelCallback) {
+ cancelCallback({
+ console.log("Cancelling OBS upload")
+ isCancelled = true
+ obsClient.putObject(
+ Bucket: process.env.VUE_APP_OBS_BUCKET,
+ ProgressCallback: callback,
+ (err, result) => {
+ if (isCancelled) {
+ return // Don't process result if cancelled
+ console.error("Error-->" + err)
+ const a = {
+ ...result,
+ console.log("上传成功", a)
+ resolve(a)
@@ -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.companyId != null) {
updateCompany(this.form).then(response => {
if (response.code === 200) {
@@ -0,0 +1,350 @@
+ <div class="app-container">
+ <!-- 查询条件 -->
+ <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px">
+ <el-form-item label="公司名称">
+ <!-- 修改为多选搜索框 -->
+ <el-select
+ v-model="queryParams.companyIds"
+ multiple
+ filterable
+ remote
+ reserve-keyword
+ placeholder="请输入公司名称搜索"
+ :remote-method="searchCompanies"
+ :loading="companySearchLoading"
+ style="width: 220px"
+ clearable
+ size="small"
+ >
+ <el-option
+ v-for="item in companyOptions"
+ :key="item.dictValue"
+ :label="item.dictLabel"
+ :value="item.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>
+ <!-- 操作按钮区域 -->
+ <el-row :gutter="10" class="mb8">
+ <el-col :span="1.5">
+ <el-button
+ type="primary"
+ plain
+ icon="el-icon-plus"
+ size="mini"
+ @click="handleRecharge"
+ v-hasPermi="['company:traffic:charge']"
+ >流量充值</el-button>
+ <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+ <!-- 数据表格 -->
+ <el-table v-loading="loading" :data="trafficRecordList" @selection-change="handleSelectionChange">
+ <el-table-column label="公司名称" align="center" prop="companyName" :show-overflow-tooltip="true" />
+ <el-table-column label="流量余额" align="center" prop="balance" :formatter="formatBalance"/>
+<!-- <el-table-column label="操作人员" align="center" prop="createBy" />
+ <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">
+ type="text"
+ icon="el-icon-money"
+ @click="handleRechargeCompany(scope.row)"
+ >充值</el-button>
+ </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="rechargeTitle" :visible.sync="rechargeOpen" width="500px" append-to-body :before-close="resetOption">
+ <el-form ref="rechargeForm" :model="rechargeForm" :rules="rechargeRules" label-width="100px">
+ <el-form-item label="公司ID" prop="companyId" v-show="!isCompanyRecharge">
+ v-model="rechargeForm.companyId"
+ @change="syncCompanyName"
+ :label="item.dictValue"
+ <span style="float: left">{{ item.dictValue }}</span>
+ <span style="margin-left: 30px">{{ item.dictLabel }}</span>
+ </el-option>
+ <el-form-item label="公司名称" prop="companyName">
+ <el-input v-model="rechargeForm.companyName" placeholder="请输入公司名称" size="small" disabled/>
+ <el-form-item label="充值金额" prop="chargeAmount">
+ <el-input-number
+ v-model="rechargeForm.chargeAmount"
+ :min="1"
+ :max="999999999"
+ placeholder="请输入充值金额(元)"
+ controls-position="right"
+ style="width: 100%"
+ <el-form-item label="备注" prop="remark">
+ <el-input
+ v-model="rechargeForm.remark"
+ type="textarea"
+ placeholder="请输入备注"
+ :rows="3"
+ <div slot="footer" class="dialog-footer">
+ <el-button type="primary" @click="submitRechargeForm">确 定</el-button>
+ <el-button @click="cancelRecharge">取 消</el-button>
+import { listTrafficRecords, rechargeTraffic } from "@/api/company/traffic";
+import { allList } from '@/api/company/company'
+import { resetForm } from '@/utils/common'
+import { delAdIqiyiAccount } from '@/api/ad/AdIqiyiAccount'
+export default {
+ name: "CompanyTraffic",
+ data() {
+ // 遮罩层
+ loading: true,
+ // 选中数组
+ ids: [],
+ // 非单个禁用
+ single: true,
+ // 非多个禁用
+ multiple: true,
+ // 显示搜索条件
+ showSearch: true,
+ // 总条数
+ total: 0,
+ // 流量记录表格数据
+ trafficRecordList: [],
+ // 弹出层标题
+ rechargeTitle: "",
+ // 是否显示充值弹出层
+ rechargeOpen: false,
+ // 公司搜索相关
+ companySearchLoading: false,
+ companyOptions: [],
+ isCompanyRecharge: false,
+ // 查询参数
+ queryParams: {
+ pageNum: 1,
+ pageSize: 10,
+ companyName: null,
+ companyIds: [], // 修改为数组
+ createTimeStart: null,
+ createTimeEnd: null
+ // 流量充值表单参数(保持不变)
+ rechargeForm: {
+ companyId: null,
+ chargeAmount: null,
+ remark: null
+ // 流量详情数据
+ detailData: {},
+ // 表单校验(保持不变)
+ rechargeRules: {
+ companyId: [
+ { required: true, message: "公司ID不能为空", trigger: "blur" }
+ ],
+ chargeAmount: [
+ { required: true, message: "充值金额不能为空", trigger: "blur" },
+ { type: "number", min: 1, message: "充值金额必须大于0", trigger: "blur" }
+ ]
+ created() {
+ this.getList();
+ resetForm,
+ resetOption(){
+ this.rechargeOpen = false;
+ this.companyOptions = [];
+ this.rechargeForm = {};
+ /** 查询流量记录列表 */
+ getList() {
+ listTrafficRecords(this.queryParams).then(response => {
+ this.trafficRecordList = response.rows;
+ console.log(this.trafficRecordList)
+ this.total = response.total;
+ /** 搜索公司 */
+ searchCompanies( query) {
+ allList().then(response => {
+ this.companyOptions = response.rows.filter(item => item.dictLabel.includes(query));
+ this.companySearchLoading = false;
+ }).catch(()=>{
+ syncCompanyName(){
+ if(!this.rechargeForm.companyId){
+ this.rechargeForm.companyName = null;
+ this.rechargeForm.companyName = this.companyOptions.filter(item => item.dictValue === this.rechargeForm.companyId)[0].dictLabel;
+ /** 搜索按钮操作 */
+ handleQuery() {
+ this.queryParams.pageNum = 1;
+ /** 重置按钮操作 */
+ resetQuery() {
+ this.resetForm("queryForm");
+ this.handleQuery();
+ formatBalance(row){
+ //对流量值进行判断,换算成GB或TB
+ if(!row.balance){
+ return "0KB";
+ if(row.balance < 1024){
+ return row.balance + "KB";
+ else if(row.balance < 1024 * 1024){
+ return (row.balance / 1024).toFixed(2) + "MB";
+ else if(row.balance < 1024 * 1024 * 1024){
+ return (row.balance / (1024 * 1024)).toFixed(2) + "GB";
+ else{
+ return (row.balance / (1024 * 1024 * 1024)).toFixed(2) + "TB";
+ /** 多选框选中数据 */
+ handleSelectionChange(selection) {
+ this.ids = selection.map(item => item.id)
+ this.single = selection.length !== 1
+ this.multiple = !selection.length
+ /** 流量充值按钮操作 */
+ handleRecharge() {
+ this.rechargeTitle = "流量充值";
+ this.resetForm("rechargeForm");
+ this.isCompanyRecharge = false;
+ this.rechargeForm.operationType = 1; // 默认充值
+ this.rechargeOpen = true;
+ },/** 流量充值按钮操作 */
+ handleRechargeCompany(row) {
+ this.isCompanyRecharge = true;
+ this.rechargeForm.companyId = row.companyId;
+ this.rechargeForm.companyName = row.companyName;
+ /** 提交流量充值 */
+ submitRechargeForm() {
+ this.$refs["rechargeForm"].validate(valid => {
+ if (valid) {
+ //添加confirm提示
+ this.$confirm('确定要为 '+this.rechargeForm.companyName+' 充值 '+this.rechargeForm.chargeAmount+' 元吗?', '提示', {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning'
+ }).then(() => {
+ return rechargeTraffic(this.rechargeForm);
+ }).then(response => {
+ if(response.code === 200){
+ this.msgSuccess("充值成功");
+ }else{
+ this.msgError(response.msg);
+ }).catch(() => {});
+ /** 取消充值 */
+ cancelRecharge() {
+};
+.mb8 {
+ margin-bottom: 8px;
@@ -0,0 +1,276 @@
+ <el-form-item label="操作类型">
+ <el-select v-model="queryParams.operationType" placeholder="请选择操作类型" clearable size="small">
+ <el-option label="充值" :value="1"></el-option>
+ <el-option label="扣费" :value="2"></el-option>
+ <el-form-item label="操作人员">
+ v-model="queryParams.userName"
+ placeholder="请输入操作人员"
+ @keyup.enter.native="handleQuery"
+ <el-form-item label="操作时间">
+ <el-date-picker
+ v-model="dateRange"
+ style="width: 240px"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ type="datetimerange"
+ range-separator="-"
+ start-placeholder="开始日期"
+ end-placeholder="结束日期"
+ ></el-date-picker>
+ type="warning"
+ icon="el-icon-download"
+ @click="handleExport"
+ v-hasPermi="['company:trafficLog:export']"
+ >导出</el-button>
+ <el-table-column type="selection" width="55" align="center" />
+ <el-table-column label="公司名称" align="center" prop="companyName" :show-overflow-tooltip="true" :formatter="companyNameFormatter"/>
+ <el-table-column label="操作类型" align="center" prop="operationType">
+ <el-tag :type="scope.row.operationType === 1 ? 'success' : 'danger'">
+ {{ scope.row.operationType === 1 ? '充值' : '扣费' }}
+ </el-tag>
+ <el-table-column label="流量数量(KB)" align="center" prop="trafficAmount">
+ <span :class="scope.row.operationType === 1 ? 'recharge' : 'deduction'">
+ {{ scope.row.operationType === 1 ? '+' : '-' }}{{ scope.row.trafficAmount }}
+ </span>
+ <el-table-column label="操作后余额(KB)" align="center" prop="balance" />
+ <el-table-column label="操作人员" align="center" prop="userName" />
+ <el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
+import { listTrafficLog, listTrafficLogExport } from "@/api/company/trafficLog";
+ name: "CompanyTrafficLog",
+ // 日期范围
+ dateRange: [],
+ formatterCompanyOptions: [],
+ companyIds: [], // 多选公司ID
+ operationType: null,
+ userName: null,
+ createTime: null,
+ //初始化formatterCompanyOptions
+ allList().then(e => {
+ this.formatterCompanyOptions = e.rows;
+ // 处理日期范围
+ if (this.dateRange && this.dateRange.length === 2) {
+ this.queryParams.createTimeStart = this.dateRange[0];
+ this.queryParams.createTimeEnd = this.dateRange[1];
+ this.queryParams.createTimeStart = null;
+ this.queryParams.createTimeEnd = null;
+ listTrafficLog(this.queryParams).then(response => {
+ searchCompanies(query) {
+ this.companySearchLoading = true;
+ this.companyOptions = response.rows;
+ if (query) {
+ this.companyOptions = this.companyOptions.filter(item =>
+ item.dictLabel.includes(query)
+ );
+ this.dateRange = [];
+ companyNameFormatter(row){
+ return this.formatterCompanyOptions.filter(item => item.dictValue === row.companyId)[0].dictLabel
+ /** 导出按钮操作 */
+ handleExport() {
+ const queryParams = {...this.queryParams};
+ queryParams.createTimeStart = this.dateRange[0];
+ queryParams.createTimeEnd = this.dateRange[1];
+ this.$confirm('是否确认导出所有流量充值记录数据项?', "警告", {
+ confirmButtonText: "确定",
+ cancelButtonText: "取消",
+ type: "warning"
+ this.exportLoading = true;
+ return listTrafficLogExport(queryParams);
+ this.download(response.msg);
+ this.exportLoading = false;
+.recharge {
+ color: #67C23A;
+ font-weight: bold;
+.deduction {
+ color: #F56C6C;
@@ -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>
@@ -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 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-form-item label="患者年龄" prop="age">
+ <el-input disabled v-model="JSON.parse(item.patientJson).age"></el-input>
+ <el-form-item label="患者电话" prop="mobile">
+ <el-input disabled v-model="JSON.parse(item.patientJson).mobile"></el-input>
+ <el-form-item label="患者会员电话" prop="userPhone">
+ <el-input disabled v-model="patientForm.userPhone"></el-input>
+ <el-form-item label="客户标签" prop="tag">
+ <el-input v-model="patientForm.tag"></el-input>
+ <el-form-item label="客服姓名" prop="companyUserName">
+ <el-input disabled v-model="patientForm.companyUserName"></el-input>
+ <el-form-item label="课程档期" prop="courseName">
+ <el-input v-model="patientForm.courseName"></el-input>
+ <el-form-item label="预约医生" prop="doctorName">
+ <el-input disabled v-model="item.doctorName"></el-input>
+ <el-form-item label="会诊时间" prop="subTime">
+ v-model="patientForm.subTime"
+ type="date"
+ value-format="yyyy-MM-dd"
+ placeholder="选择日期">
+ </el-date-picker>
+ <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-form-item label="部门负责人" prop="deptManager">
+ <el-input v-model="patientForm.deptManager"></el-input>
+ <el-form-item label="患者病情主诉">
+ placeholder="请输入内容"
+ v-model="patientForm.patientCondition">
+ </el-input>
+ <div class="contentx">
+ <div class="desct">
+ 医生建议及处置
+ <el-form-item label="诊断">
+ v-model="patientForm.doctorAdviceJson.diagnosis">
+ <el-form-item label="饮食方面">
+ v-model="patientForm.doctorAdviceJson.foodAdvice">
+ <el-form-item label="运动方面">
+ v-model="patientForm.doctorAdviceJson.sportAdvice">
+ <el-form-item label="保健方面">
+ v-model="patientForm.doctorAdviceJson.healthAdvice">
+ <el-form-item label="注意禁忌">
+ v-model="patientForm.taboo">
+ <el-form-item label="客户需求">
+ <el-input v-model="patientForm.customerRequire"></el-input>
+ <el-form-item label="职业医师" prop="age">
+ <el-input v-model="patientForm.professionalDoctor"></el-input>
+ <el-form-item label="医生助理" prop="mobile">
+ <el-input v-model="patientForm.assistantDoctor"></el-input>
+ 治疗方面
+ <div v-for="(i,index) in patientForm.doctorAdviceJson.treatmentAdvice" :key="index">
+ <el-col :span="8">
+ <el-form-item label="诊断内容" prop="content">
+ <el-input v-model="i.content"></el-input>
+ <el-form-item label="建议治疗" prop="advice">
+ <el-input v-model="i.advice"></el-input>
+ <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>
+ <span slot="footer" class="dialog-footer">
+ <el-button @click="patientOpen = false">取 消</el-button>
+ <el-button type="primary" @click="patientInquirySubmit">确 定</el-button>
<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,36 @@ import { js } from "js-beautify";
methods: {
+ addItem(length){
+ this.patientForm.doctorAdviceJson.treatmentAdvice.push({
+ content:'',
+ advice:'',
+ 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 = {
cancelorder(){
var that=this;
this.$confirm('是否确认取消订单?', "警告", {
@@ -369,6 +610,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;
+ addinquiryPatient(this.patientForm).then(res => {
+ this.msgSuccess("添加成功");
msgServiceDetailsClose(){
this.msgServiceDetails.open = false;
@@ -299,11 +299,10 @@
<el-option key="SF" label="顺丰" value="SF" />
<el-option key="EMS" label="邮政" value="EMS" />
<el-option key="ZTO" label="中通" value="ZTO" />
- <el-option key="STO" label="申通" value="ZTO" />
+ <el-option key="STO" label="申通" value="STO" />
<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:{
@@ -170,7 +170,15 @@
</template>
-import { listPatient, getPatient, delPatient, addPatient, updatePatient, exportPatient } from "@/api/his/patient";
+import {
+ listPatient,
+ getPatient,
+ delPatient,
+ addPatient,
+ updatePatient,
+ exportPatient,
+ listPatientList
+} from '@/api/his/patient'
import {getUserList} from "@/api/his/doctor";
export default {
name: "Patient",
@@ -0,0 +1,508 @@
+ <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+ <el-form-item label="名称" prop="name">
+ v-model="queryParams.name"
+ placeholder="请输入名称"
+ <el-form-item label="所属公司" prop="companyId">
+ v-model="queryParams.companyId"
+ <el-form-item label="appid" prop="appid">
+ v-model="queryParams.appid"
+ placeholder="请输入appid"
+ @click="handleAdd"
+ v-hasPermi="['course:playSourceConfig:add']"
+ >新增</el-button>
+ type="success"
+ icon="el-icon-edit"
+ :disabled="single"
+ @click="handleUpdate"
+ v-hasPermi="['course:playSourceConfig:edit']"
+ >修改</el-button>
+ type="danger"
+ icon="el-icon-delete"
+ :disabled="multiple"
+ @click="handleDelete"
+ v-hasPermi="['course:playSourceConfig:remove']"
+ >删除</el-button>
+ <!-- 开关配置对话框 -->
+ <el-dialog title="开关配置" :visible.sync="switchDialogVisible" width="500px" class="switch-dialog">
+ <el-form :model="switchForm" label-width="100px">
+ <el-form-item label="AppId">
+ <el-input v-model="switchForm.appId" :disabled="true"></el-input>
+ <el-form-item label="开关状态">
+ <el-switch
+ v-model="switchForm.switchStatus"
+ active-text="开启"
+ inactive-text="关闭"
+ active-value="001"
+ inactive-value="002">
+ </el-switch>
+ <el-form-item label="配置信息" v-if="switchForm.configInfo">
+ :rows="4"
+ v-model="switchForm.configInfo"
+ :disabled="true">
+ <el-button @click="switchDialogVisible = false">取 消</el-button>
+ <el-button type="primary" @click="submitSwitchConfig">确 定</el-button>
+ <el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange" border>
+ <el-table-column label="ID" align="center" prop="id" />
+ <el-table-column label="名称" align="center" prop="name" />
+ <el-table-column label="所属公司" align="center" prop="companyId" :formatter="companyNameFormatter"/>
+ <el-table-column label="图标" align="center" prop="img">
+ <el-image
+ style="width: 80px; height: 80px"
+ :src="scope.row.img"
+ :preview-src-list="[scope.row.img]">
+ </el-image>
+ <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">
+ <dict-tag :options="typesOptions" :value="scope.row.type"/>
+ <el-table-column label="创建时间" align="center" prop="createTime" />
+ <el-table-column label="修改时间" align="center" prop="updateTime" />
+ @click="handleUpdate(scope.row)"
+ @click="handleDelete(scope.row)"
+ icon="el-icon-setting"
+ @click="handleSwitchConfig(scope.row)"
+ >是否展示销售</el-button>
+ <!-- 添加或修改点播配置对话框 -->
+ <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body :before-close="resetOption">
+ <el-form ref="form" :model="form" :rules="rules" label-width="130px">
+ <el-input v-model="form.name" placeholder="请输入名称" />
+ v-model="form.companyId"
+ <el-form-item label="图标" prop="img">
+ <image-upload v-model="form.img" :file-type='["png", "jpg", "jpeg"]' :limit="1"/>
+ <el-form-item label="类型" prop="type">
+ v-model="form.type"
+ placeholder="请选择类型">
+ v-for="item in typesOptions"
+ :value="item.dictValue"/>
+ <el-form-item label="原始id" prop="originalId">
+ <el-input v-model="form.originalId" placeholder="请输入原始id" />
+ <el-input v-model="form.appid" placeholder="请输入appid" />
+ <el-form-item label="secret" prop="secret">
+ <el-input v-model="form.secret" placeholder="请输入secret" />
+ <el-form-item label="token" prop="token">
+ <el-input v-model="form.token" placeholder="请输入token" />
+ <el-form-item label="aesKey" prop="aesKey">
+ <el-input v-model="form.aesKey" placeholder="请输入aesKey" />
+ <el-form-item label="msgDataFormat" prop="msgDataFormat">
+ <el-input v-model="form.msgDataFormat" placeholder="请输入msgDataFormat" />
+ <el-button type="primary" @click="submitForm">确 定</el-button>
+ <el-button @click="cancel">取 消</el-button>
+import {list, get, update, add, del} from '@/api/course/coursePlaySourceConfig'
+import {updateIsTownOn} from "@/api/system/config";
+ name: 'CoursePlaySourceConfig',
+ switchDialogVisible: false,
+ switchForm: {
+ appId: '',
+ switchStatus: '001',
+ name: null,
+ appid: null
+ loading: false,
+ list: [],
+ typesOptions: [],
+ title: null,
+ open: false,
+ form: {},
+ rules: {
+ name: [
+ { required: true, message: "名称不能为空", trigger: "blur" }
+ // companyId: [
+ // { required: true, message: "所属公司不能为空", trigger: "blur" }
+ // ],
+ appid: [
+ { required: true, message: "appid不能为空", trigger: "blur" }
+ img: [
+ { required: true, message: "图标不能为空", trigger: "blur" }
+ type: [
+ { required: true, message: "类型不能为空", trigger: "blur" }
+ originalId: [
+ { required: true, message: "原始id不能为空", 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" }
+ this.getDicts("play_source_type").then(response => {
+ this.typesOptions = response.data.map(item => {
+ ...item,
+ listClass: 'primary'}
+ console.log(1)
+ this.open = false;
+ // 处理开关配置
+ handleSwitchConfig(row) {
+ this.switchForm.appId = row.appid;
+ this.switchForm.switchStatus = "001"; // 默认关闭状态
+ // 调用接口获取开关状态
+ this.getSwitchConfig(row.appid);
+ this.switchDialogVisible = true;
+ let company = this.formatterCompanyOptions.filter(item => item.dictValue === row.companyId)[0];
+ return company ? company.dictLabel : '';
+ // 获取开关配置
+ getSwitchConfig(appId) {
+ const params = {
+ appId: this.switchForm.appId
+ updateIsTownOn(params).then(response=>{
+ if (response.code === 200) {
+ if ( response.date){
+ this.switchForm.switchStatus = response.date;
+ this.$message.error('获取配置失败: ' + response.msg);
+ }).catch(error => {
+ this.$message.error('请求失败: ' + error.message);
+ // 提交开关配置
+ submitSwitchConfig() {
+ appId: this.switchForm.appId,
+ bock: this.switchForm.switchStatus
+ this.$message.success('配置更新成功');
+ this.switchDialogVisible = false;
+ this.$message.error('更新失败: ' + response.msg);
+ list(this.queryParams).then(response => {
+ this.list = response.rows;
+ handleAdd() {
+ this.reset()
+ this.open = true
+ this.title = "添加小程序配置"
+ handleUpdate(row) {
+ const id = row.id || this.ids
+ get(id).then(response => {
+ this.form = {
+ ...response.data,
+ type: response.data.type.toString()
+ this.title = "修改小程序配置"
+ handleDelete(row) {
+ this.$confirm('是否确认删除小程序配置编号为"' + id + '"的数据项?', "警告", {
+ }).then(function() {
+ return del(id);
+ this.msgSuccess("删除成功");
+ this.single = selection.length!==1
+ submitForm() {
+ this.$refs["form"].validate(valid => {
+ if (this.form.id != null) {
+ update(this.form).then(response => {
+ const {code, msg} = response
+ if (code !== 200) {
+ this.msgError(msg)
+ this.msgSuccess("修改成功");
+ add(this.form).then(response => {
+ this.msgSuccess("新增成功");
+ cancel() {
+ this.reset();
+ reset() {
+ id: null,
+ appid: null,
+ secret: null,
+ img: null,
+ originalId: null,
+ token: 'cbnd7lJvkripVOpyTFAna6NAWCxCrvC',
+ aesKey: 'HlEiBB55eaWUaeBVAQO3cWKWPYv1vOVQSq7nFNICw4E',
+ msgDataFormat: 'JSON',
+ type: '1'
+ this.resetForm("form");
@@ -1,261 +1,233 @@
<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-tab-pane label="公开课" name="common"></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-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-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-form-item label="公开课" v-if="activeTab === 'all' || activeTab === 'common'">
+ <!-- 时间选择 -->
+ <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-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>
- <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'||activeTab === 'common'" />
+ <el-table-column label="日期" align="center" prop="month" />
<el-table-column label="使用流量" align="center">
<template slot-scope="scope">
<span>{{ formatTrafficData(scope.row.totalInternetTraffic) }}</span>
</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"
/>
-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";
- name: "CourseTrafficLog",
- 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: '昨日',
+ start.setDate(start.getDate() - 1);
+ const end = new Date(start);
+ text: '本周',
+ const now = new Date();
+ const day = now.getDay() || 7;
+ const start = new Date(now);
+ start.setDate(now.getDate() - day + 1);
+ text: '本月',
+ const start = new Date(new Date().setDate(1));
- // 遮罩层
- loading: true,
- // 导出遮罩层
+ courseLists: [],
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
};
- this.getList();
+ courseList().then(res => this.courseLists = res.list);
+ this.getDicts("sys_course_project").then(res => this.projectOptions = res.data);
this.getAllCompany();
- getAllCompany() {
- allList().then(response => {
- this.companyList = response.rows;
- formatTrafficData(traffic) {
+ handleTabClick(tab) {
+ this.queryParams.tabType = tab.name;
- 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) + ' 元'
- 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];
+ 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,
- createTime: 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.open = true;
- this.title = "添加短链课程流量记录";
- /** 修改按钮操作 */
- handleUpdate(row) {
- const logId = row.logId || this.ids
- getCourseTrafficLog(logId).then(response => {
- this.form = response.data;
- this.title = "修改短链课程流量记录";
+ this.timeRange = null;
+ this.queryParams = {
+ ...this.queryParams,
+ courseId: null,
- /** 提交按钮 */
- submitForm() {
- this.$refs["form"].validate(valid => {
- if (valid) {
- if (this.form.logId != null) {
- updateCourseTrafficLog(this.form).then(response => {
- this.msgSuccess("修改成功");
- addCourseTrafficLog(this.form).then(response => {
- this.msgSuccess("新增成功");
+ 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.msgSuccess("删除成功");
- }).catch(() => {});
+ this.ids = selection.map(item => item.logId);
- /** 导出按钮操作 */
handleExport() {
- const queryParams = this.queryParams;
- this.$confirm('是否确认导出所有短链课程流量记录数据项?', "警告", {
- this.exportLoading = true;
- return exportCourseTrafficLog(queryParams);
- }).then(response => {
- this.download(response.msg);
- this.exportLoading = false;
+ this.$confirm("确认导出数据?", "提示").then(() => {
+ return exportCourseTrafficLog(this.queryParams);
+ }).then(res => {
+ this.download(res.msg);
@@ -11,6 +11,22 @@
style="width: 280px"
+ <el-form-item label="状态" prop="status">
+ v-model="queryParams.status"
+ placeholder="操作状态"
+ v-for="dict in statusOptions"
+ :key="dict.dictValue"
+ :label="dict.dictLabel"
+ :value="dict.dictValue"
@@ -18,27 +34,27 @@
<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:courseWatchComment:add']"-->
-<!-- >新增</el-button>-->
-<!-- </el-col>-->
-<!-- type="success"-->
-<!-- icon="el-icon-edit"-->
-<!-- :disabled="single"-->
-<!-- @click="handleUpdate"-->
-<!-- v-hasPermi="['course:courseWatchComment:edit']"-->
-<!-- >修改</el-button>-->
+ <!-- <el-col :span="1.5">-->
+ <!-- <el-button-->
+ <!-- type="primary"-->
+ <!-- plain-->
+ <!-- icon="el-icon-plus"-->
+ <!-- size="mini"-->
+ <!-- @click="handleAdd"-->
+ <!-- v-hasPermi="['course:courseWatchComment:add']"-->
+ <!-- >新增</el-button>-->
+ <!-- </el-col>-->
+ <!-- type="success"-->
+ <!-- icon="el-icon-edit"-->
+ <!-- :disabled="single"-->
+ <!-- @click="handleUpdate"-->
+ <!-- v-hasPermi="['course:courseWatchComment:edit']"-->
+ <!-- >修改</el-button>-->
<el-col :span="1.5">
<el-button
type="danger"
@@ -66,26 +82,39 @@
<el-table border v-loading="loading" :data="courseWatchCommentList" @selection-change="handleSelectionChange">
-<!-- <el-table-column label="评论id" align="center" prop="commentId" />-->
-<!-- <el-table-column label="用户id" align="center" prop="userId" />-->
+ <!-- <el-table-column label="评论id" align="center" prop="commentId" />-->
+ <!-- <el-table-column label="用户id" align="center" prop="userId" />-->
<el-table-column label="用户昵称" align="center" prop="nickName" width="130px" />
-<!-- <el-table-column label="用户类型,1-管理员,2-用户" align="center" prop="userType" />-->
-<!-- <el-table-column label="评论类型 1:评论,2:回复" align="center" prop="type" />-->
-<!-- <el-table-column label="父评论id" align="center" prop="parentId" />-->
+ <!-- <el-table-column label="用户类型,1-管理员,2-用户" align="center" prop="userType" />-->
+ <!-- <el-table-column label="评论类型 1:评论,2:回复" align="center" prop="type" />-->
+ <!-- <el-table-column label="父评论id" align="center" prop="parentId" />-->
<el-table-column label="评论内容" align="center" prop="content" />
<el-table-column label="所属课程" align="center" prop="courseName" />
<el-table-column label="所属小节" align="center" prop="title" />
+ <el-table-column label="弹幕状态" align="center" prop="status">
+ <el-tag :type="getStatusTagType(scope.row.status)">
+ {{ formatBarrageStatus(scope.row.status) }}
<el-table-column label="评论时间" align="center" prop="createTime" width="160px"/>
-<!-- <el-table-column label="是否是撤回的消息,1-是,0-否" align="center" prop="isRevoke" />-->
+ <!-- <el-table-column label="是否是撤回的消息,1-是,0-否" align="center" prop="isRevoke" />-->
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
-<!-- type="text"-->
-<!-- @click="handleUpdate(scope.row)"-->
+ <!-- type="text"-->
+ <!-- @click="handleUpdate(scope.row)"-->
+ @click="handleUpdateStatus(scope.row)"
+ >修改弹幕状态</el-button>
size="mini"
type="text"
@@ -93,11 +122,19 @@
@click="handleAddKeyWords(scope.row)"
>添加关键字</el-button>
+ v-if="scope.row.userStatus === 1 "
icon="el-icon-edit"
@click="handleAddBlack(scope.row)"
>拉黑</el-button>
+ v-if="scope.row.userStatus === 0 "
+ @click="handleClearBlack(scope.row)"
+ >解除拉黑</el-button>
@@ -126,57 +163,86 @@
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
- </el-dialog>
-<!-- <!– 添加或修改看课评论对话框 –>-->
-<!-- <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="用户类型,1-管理员,2-用户" prop="userType">-->
-<!-- <el-select v-model="form.userType" placeholder="请选择用户类型,1-管理员,2-用户">-->
-<!-- <el-option label="请选择字典生成" value="" />-->
-<!-- </el-select>-->
-<!-- <el-form-item label="课程id" prop="courseId">-->
-<!-- <el-input v-model="form.courseId" placeholder="请输入课程id" />-->
-<!-- <el-form-item label="视频id" prop="videoId">-->
-<!-- <el-input v-model="form.videoId" placeholder="请输入视频id" />-->
-<!-- <el-form-item label="评论类型 1:评论,2:回复" prop="type">-->
-<!-- <el-select v-model="form.type" placeholder="请选择评论类型 1:评论,2:回复">-->
-<!-- <el-form-item label="父评论id" prop="parentId">-->
-<!-- <el-input v-model="form.parentId" placeholder="请输入父评论id" />-->
-<!-- <el-form-item label="评论内容" prop="content">-->
-<!-- <el-input v-model="form.content" type="textarea" placeholder="请输入内容" />-->
-<!-- <el-form-item label="是否是撤回的消息,1-是,0-否" prop="isRevoke">-->
-<!-- <el-select v-model="form.isRevoke" placeholder="请选择是否是撤回的消息,1-是,0-否">-->
-<!-- </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="title" :visible.sync="updateStatus" width="500px" append-to-body>
+ <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+ <el-form-item label="弹幕状态" prop="barrageStatus">
+ <el-radio-group v-model="form.status">
+ <el-radio
+ v-for="dict in barrageStatusOptions"
+ :label="dict.dictValue"
+ v-if="dict.dictValue !== 2"
+ <el-tag :type="getStatusTagType(dict.dictValue)" size="small">
+ {{dict.dictLabel}}
+ </el-radio>
+ </el-radio-group>
+ <el-button type="primary" @click="updateForm">确 定</el-button>
+ <!-- <!– 添加或修改看课评论对话框 –>-->
+ <!-- <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="用户类型,1-管理员,2-用户" prop="userType">-->
+ <!-- <el-select v-model="form.userType" placeholder="请选择用户类型,1-管理员,2-用户">-->
+ <!-- <el-option label="请选择字典生成" value="" />-->
+ <!-- </el-select>-->
+ <!-- <el-form-item label="课程id" prop="courseId">-->
+ <!-- <el-input v-model="form.courseId" placeholder="请输入课程id" />-->
+ <!-- <el-form-item label="视频id" prop="videoId">-->
+ <!-- <el-input v-model="form.videoId" placeholder="请输入视频id" />-->
+ <!-- <el-form-item label="评论类型 1:评论,2:回复" prop="type">-->
+ <!-- <el-select v-model="form.type" placeholder="请选择评论类型 1:评论,2:回复">-->
+ <!-- <el-form-item label="父评论id" prop="parentId">-->
+ <!-- <el-input v-model="form.parentId" placeholder="请输入父评论id" />-->
+ <!-- <el-form-item label="评论内容" prop="content">-->
+ <!-- <el-input v-model="form.content" type="textarea" placeholder="请输入内容" />-->
+ <!-- <el-form-item label="是否是撤回的消息,1-是,0-否" prop="isRevoke">-->
+ <!-- <el-select v-model="form.isRevoke" placeholder="请选择是否是撤回的消息,1-是,0-否">-->
+ <!-- </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>-->
-import { listCourseWatchComment, delCourseWatchComment, exportCourseWatchComment, addBlack } from "@/api/course/courseWatchComment";
+import { listCourseWatchComment, delCourseWatchComment, exportCourseWatchComment, addBlack,clearBlack,updateBarrageStatus } from "@/api/course/courseWatchComment";
import { addKeyword } from "@/api/system/keyword";
name: "CourseWatchComment",
+ // 弹幕状态选项
+ barrageStatusOptions: [
+ { dictValue: 0, dictLabel: "正常" },
+ { dictValue: 1, dictLabel: "屏蔽" },
+ { dictValue: 2, dictLabel: "人工" }
// 遮罩层
loading: true,
// 导出遮罩层
@@ -193,16 +259,21 @@ export default {
// 看课评论表格数据
courseWatchCommentList: [],
+ //下拉状态
+ statusOptions:[],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
+ updateStatus: false,
// 查询参数
keywords: null,
isAll: true, //判断是否属于全局查询
+ status: '',
+ userStatus: '',
// userId: null,
// userType: null,
// courseId: null,
@@ -223,6 +294,9 @@ export default {
+ this.getDicts("sys_barrage_clean_type").then((response) => {
+ this.statusOptions = response.data;
@@ -235,9 +309,24 @@ export default {
+ // 获取状态标签类型
+ getStatusTagType(status) {
+ switch(status) {
+ case 0: return 'success';
+ case 1: return 'danger';
+ case 2: return 'primary';
+ default: return 'info';
+ // 格式化状态显示
+ formatBarrageStatus(status) {
+ const dict = this.barrageStatusOptions.find(item => item.dictValue === status);
+ return dict ? dict.dictLabel : status;
// 取消按钮
cancel() {
this.open = false;
+ this.updateStatus = false;
this.reset();
// 表单重置
@@ -254,7 +343,9 @@ export default {
createTime: null,
updateTime: null,
isRevoke: null,
- keyword: null
+ keyword: null,
+ userStatus: ''
this.resetForm("form");
@@ -281,6 +372,34 @@ export default {
this.open = true;
this.title = "添加到关键字";
+ handleUpdateStatus(row) {
+ this.form.status = row.status;
+ this.form.commentId = row.commentId;
+ this.updateStatus = true;
+ this.title = "修改弹幕状态";
+ /** 解除拉黑用户按钮操作 */
+ handleClearBlack(row) {
+ this.$confirm(`谨慎操作,确定要解除"${row.nickName}"用户拉黑吗`, "警告", {
+ const data = {
+ fsUserId: row.userId,
+ commentStatus: 0
+ clearBlack(data).then(response => {
+ this.msgSuccess("操作成功");
+ this.getList(); // 重新加载列表
+ }).catch(() => {
+ this.msgError("操作失败");
+ // 用户取消操作
/** 拉黑用户按钮操作 */
handleAddBlack(row) {
this.$confirm(`谨慎操作,确定要拉黑用户"${row.nickName}"吗`, "警告", {
@@ -302,6 +421,20 @@ export default {
// 用户取消操作
+ updateForm() {
+ console.log(this.form)
+ updateBarrageStatus(this.form).then(response => {
+ this.msgError("修改失败");
/** 提交按钮 */
@@ -339,30 +472,30 @@ export default {
handleDelete(row) {
const commentIds = row.commentId || this.ids;
this.$confirm('是否确认删除此看课评论?删除后不可恢复', "警告", {
- return delCourseWatchComment(commentIds);
+ return delCourseWatchComment(commentIds);
/** 导出按钮操作 */
const queryParams = this.queryParams;
this.$confirm('是否确认导出当前看课评论数据项?', "警告", {
- return exportCourseWatchComment(queryParams);
+ return exportCourseWatchComment(queryParams);
@@ -10,7 +10,7 @@
@keyup.enter.native="handleQuery"
<el-form-item label="用户名称" prop="userName">
<el-input
v-model="queryParams.userName"
@@ -29,9 +29,9 @@
<el-form-item label="支付状态" prop="isPay">
<!-- <el-input
v-model="queryParams.isPay"
@@ -76,10 +76,10 @@
style="width: 240px"
@@ -130,6 +130,17 @@
v-hasPermi="['course:fsCourseProductOrder:export']"
>导出</el-button>
</el-col>
+ :loading="exportLoading"
+ @click="handleDecodeExport"
+ v-hasPermi="['course:fsCourseProductOrder:decodeExport']"
+ >解密手机号导出</el-button>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
@@ -146,8 +157,8 @@
<el-table-column label="课程" align="center" :show-overflow-tooltip="true" prop="courseName" />
<el-table-column label="视频" align="center" :show-overflow-tooltip="true" prop="title" />
<el-table-column label="公司名称" align="center" prop="companyName" />
- <el-table-column label="销售" align="center" prop="companyUserName" />
- <el-table-column label="企微外部联系人" align="center" prop="extName" />
+ <el-table-column label="销售" align="center" prop="companyUserName" />
+ <el-table-column label="企微外部联系人" align="center" prop="extName" />
<el-table-column label="支付状态" align="center" prop="isPay">
<el-tag v-if="scope.row.isPay == 0">待支付</el-tag>
@@ -175,7 +186,7 @@
<el-table-column label="申请退款理由" :show-overflow-tooltip="true" align="center" prop="refundExplain" />
<el-table-column label="核销码" align="center" prop="verifyCode" />
@@ -278,7 +289,17 @@
-import { listFsCourseProductOrder, getFsCourseProductOrder, delFsCourseProductOrder, addFsCourseProductOrder, updateFsCourseProductOrder, exportFsCourseProductOrder, refund, getOrderUserPhone } from "@/api/course/fsCourseProductOrder";
+ listFsCourseProductOrder,
+ getFsCourseProductOrder,
+ delFsCourseProductOrder,
+ addFsCourseProductOrder,
+ updateFsCourseProductOrder,
+ exportFsCourseProductOrder,
+ refund,
+ getOrderUserPhone,
+ exportFsCourseProductOrderDecodePhone
+} from "@/api/course/fsCourseProductOrder";
name: "FsCourseProductOrder",
@@ -466,6 +487,35 @@ export default {
}).catch(() => {});
+ handleDecodeExport() {
+ if (this.payDateRange && this.payDateRange.length === 2) {
+ this.queryParams.payStartTime = this.payDateRange[0];
+ this.queryParams.payEndTime = this.payDateRange[1];
+ this.queryParams.payStartTime = null;
+ this.queryParams.payEndTime = null;
+ if (this.refundDateRange && this.refundDateRange.length === 2) {
+ this.queryParams.refundStartTime = this.refundDateRange[0];
+ this.queryParams.refundEndTime = this.refundDateRange[1];
+ this.queryParams.refundStartTime = null;
+ this.queryParams.refundEndTime = null;
+ const queryParams = this.queryParams;
+ this.$confirm('是否确认导出所有拍单商品订单数据项?', "警告", {
+ return exportFsCourseProductOrderDecodePhone(queryParams);
if (this.payDateRange && this.payDateRange.length === 2) {
this.queryParams.payStartTime = this.payDateRange[0];
@@ -516,7 +566,7 @@ export default {
handlePhone(scope) {
getOrderUserPhone(scope.row.courseOrderId).then(res=>{
scope.row.userPhone = res.userPhone
- })
@@ -176,7 +176,7 @@
@click="handleUpdate(scope.row)"
- v-hasPermi="['course:period:query']"
+ v-hasPermi="['course:period:edit']"
>修改</el-button>
<!-- <el-button-->
<!-- size="mini"-->
@@ -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"
placeholder="选择日期"
@@ -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 &&
@@ -18,6 +18,22 @@
+ <el-form-item label="公司">
+ placeholder="请选择公司"
+ style="width: 400px"
+ :key="item.companyId"
+ :label="item.companyName"
+ :value="item.companyId"
<el-button type="primary" @click="handleQuery">查询</el-button>
@@ -112,7 +128,7 @@
-import {getDays, periodCountSelect} from "@/api/course/userCoursePeriod";
+import {getDays, periodCountSelect, getPeriodCompanyList} from "@/api/course/userCoursePeriod";
name: "CourseStatistics",
@@ -134,6 +150,7 @@ export default {
// 课程选项
courseOptions: [],
// 统计数据
statistics: {
courseCompleteNum: 0,
@@ -182,8 +199,16 @@ export default {
initializeData() {
this.getCourseOptions();
this.getCountList();
+ this.getCompanyOptions()
this.initialized = true;
+ getCompanyOptions() {
+ getPeriodCompanyList({
+ periodId: this.periodId
+ this.companyOptions = response.data || [];
/** 获取课程选项 */
getCourseOptions() {
@@ -0,0 +1,340 @@
+ <el-select v-model="queryParams.type" placeholder="请选择类型" clearable size="small">
+ v-for="dict in typeOptions"
+ <el-form-item label="易错词" prop="content">
+ v-model="queryParams.content"
+ placeholder="请输入原来的文本"
+ <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
+ v-hasPermi="['fastGpt:fastGptChatReplaceText:add']"
+ v-hasPermi="['fastGpt:fastGptChatReplaceText:edit']"
+ v-hasPermi="['fastGpt:fastGptChatReplaceText:remove']"
+ v-hasPermi="['fastGpt:fastGptChatReplaceText:export']"
+ <el-table border v-loading="loading" :data="fastGptChatReplaceTextList" @selection-change="handleSelectionChange">
+ <el-table-column label="id" align="center" prop="id" />
+ <dict-tag :options="typeOptions" :value="scope.row.type"/>
+ <el-table-column label="易错词" align="center" prop="content" />
+ <el-table-column label="替换文本" align="center" prop="changeCount" />
+ <el-table-column label="状态" align="center" prop="status">
+ <dict-tag :options="statusOptions" :value="scope.row.status"/>
+ <el-table-column label="排序" align="center" prop="sort" />
+ <!-- 添加或修改易错词语对话框 -->
+ <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+ <el-select v-model="form.type" placeholder="请选择类型">
+ :value="parseInt(dict.dictValue)"
+ ></el-option>
+ <el-input v-model="form.content" placeholder="请输入易错词" />
+ <el-form-item label="替换文本" prop="changeCount">
+ <el-input v-model="form.changeCount" placeholder="替换文本" />
+ <el-form-item label="状态">
+ :label="parseInt(dict.dictValue)"
+ >{{dict.dictLabel}}</el-radio>
+ <el-form-item label="排序" prop="sort">
+ <el-input-number v-model="form.sort" :min="0" label="请输入排序"></el-input-number>
+import { listFastGptChatReplaceText, getFastGptChatReplaceText, delFastGptChatReplaceText, addFastGptChatReplaceText, updateFastGptChatReplaceText, exportFastGptChatReplaceText } from "@/api/fastGpt/fastGptChatReplaceText";
+ name: "FastGptChatReplaceText",
+ // 导出遮罩层
+ exportLoading: false,
+ // 易错词语表格数据
+ fastGptChatReplaceTextList: [],
+ title: "",
+ // 是否显示弹出层
+ // 类型字典
+ typeOptions: [],
+ // 状态字典
+ statusOptions: [],
+ type: null,
+ content: null,
+ changeCount: null,
+ status: null,
+ sort: null,
+ // 表单参数
+ // 表单校验
+ this.getDicts("sys_fastgpt_chat_replace_words_type").then(response => {
+ this.typeOptions = response.data;
+ this.getDicts("sys_company_status").then(response => {
+ /** 查询易错词语列表 */
+ listFastGptChatReplaceText(this.queryParams).then(response => {
+ this.fastGptChatReplaceTextList = response.rows;
+ // 取消按钮
+ // 表单重置
+ status: 0,
+ createTime: null
+ // 多选框选中数据
+ /** 新增按钮操作 */
+ this.open = true;
+ this.title = "添加易错词语";
+ /** 修改按钮操作 */
+ getFastGptChatReplaceText(id).then(response => {
+ this.form = response.data;
+ this.title = "修改易错词语";
+ /** 提交按钮 */
+ updateFastGptChatReplaceText(this.form).then(response => {
+ addFastGptChatReplaceText(this.form).then(response => {
+ /** 删除按钮操作 */
+ const ids = row.id || this.ids;
+ this.$confirm('是否确认删除易错词语编号为"' + ids + '"的数据项?', "警告", {
+ return delFastGptChatReplaceText(ids);
+ this.$confirm('是否确认导出所有易错词语数据项?', "警告", {
+ return exportFastGptChatReplaceText(queryParams);
@@ -0,0 +1,567 @@
+ <el-form-item label="企微账号" prop="corpId">
+ <el-select v-model="queryParams.corpId" placeholder="企微账号" clearable size="small"
+ @change="updateQwuser()">
+ v-for="dict in myQwUserList"
+ :key="dict.corpId"
+ :label="dict.corpName"
+ :value="dict.corpId"
+ <el-form-item label="标签id" prop="tagId">
+ v-model="queryParams.tagId"
+ placeholder="请输入标签id"
+ v-hasPermi="['FastGptExtUserTag:FastGptExtUserTag:add']"
+<!-- <el-col :span="1.5">
+ v-hasPermi="['FastGptExtUserTag:FastGptExtUserTag:edit']"
+ </el-col>-->
+ v-hasPermi="['FastGptExtUserTag:FastGptExtUserTag:remove']"
+ v-hasPermi="['FastGptExtUserTag:FastGptExtUserTag:export']"
+ <el-table border v-loading="loading" :data="FastGptExtUserTagList" @selection-change="handleSelectionChange">
+ <el-table-column label="企业名称" align="center" prop="corpId">
+ {{ getCorpNameById(scope.row.corpId) }}
+ <el-table-column label="标签名称" align="center" prop="tagName">
+ {{ getTagNameById(scope.row.tagId) }}
+ <el-table-column label="标签id" align="center" prop="tagId" />
+<!-- <el-button
+ >修改</el-button>-->
+ <!-- 添加或修改处理新客标签对话框 -->
+ <el-input v-model="form.tagId" placeholder="请输入标签id" />
+ <el-dialog title="批量添加标签" :visible.sync="tagOpen" width="800px" append-to-body>
+ <div>搜索标签:
+ <el-input v-model="tagChange.tagName" placeholder="请输入标签名称" clearable size="small" style="width: 200px;margin-right: 10px" />
+ <el-button type="primary" icon="el-icon-search" size="mini" @click="handleSearchTags(tagChange.tagName)">搜索</el-button>
+ <el-button type="primary" icon="el-icon-plus" size="mini" @click="cancelSearchTags">重置</el-button>
+ <el-form ref="form" :model="addTagFormByWatch" label-width="80px">
+ <div v-for="item in tagGroupList" :key="item.id" >
+ <div style="font-size: 20px;margin-top: 20px;margin-bottom: 20px;">
+ <span class="name-background">{{ item.name }}</span>
+ <!-- 添加外层滚动容器 -->
+ <div class="scroll-wrapper">
+ <div class="tag-container">
+ <a
+ v-for="tagItem in item.tag"
+ class="tag-box"
+ @click="tagSelection(tagItem)"
+ :class="{ 'tag-selected': tagItem.isSelected }"
+ {{ tagItem.name }}
+ </a>
+ v-show="tagTotal>0"
+ :total="tagTotal"
+ :page.sync="queryTagParams.pageNum"
+ :limit.sync="queryTagParams.pageSize"
+ @pagination="updateQwuser"
+ <el-button type="primary" @click="addTagSubmitForm()">确 定</el-button>
+ <el-button @click="addTagCancel">取 消</el-button>
+import { listFastGptExtUserTag,addFastGptTagByCorpId,getMyQwUserList, getFastGptExtUserTag, delFastGptExtUserTag, addFastGptExtUserTag, updateFastGptExtUserTag, exportFastGptExtUserTag } from "@/api/fastGpt/FastGptExtUserTag";
+import {allListTagGroup, getAllListTagGroup} from "@/api/qw/tagGroup";
+import {searchTags} from "@/api/qw/tag";
+ name: "FastGptExtUserTag",
+ // 处理新客标签表格数据
+ FastGptExtUserTagList: [],
+ myQwUserList: [],
+ tagOpen: false,
+ queryTagParams: {
+ pageSize: 5,
+ tagName: null,
+ corpId: null,
+ //标签弹窗选择
+ tagChange: {
+ index: null,
+ addTagFormByWatch: {
+ tagIds: [],
+ tagGroupList: [],
+ showTagGroupList: [],
+ tagTotal: 0,
+ tagId: null,
+ rules: {}
+ getMyQwUserList().then(response => {
+ this.myQwUserList = response.data;
+ // 如果myQwUserList不为空,默认选中第一个
+ if (this.myQwUserList && this.myQwUserList.length > 0) {
+ this.queryParams.corpId = this.myQwUserList[0].corpId;
+ // 重新加载列表以显示选中企业的数据
+ /** 查询处理新客标签列表 */
+ listFastGptExtUserTag(this.queryParams).then(response => {
+ this.FastGptExtUserTagList = response.rows;
+ addTagCancel() {
+ this.addTagFormByWatch = {
+ this.tagOpen = false;
+ // 清除标签选择状态
+ this.clearTagSelections();
+ handleSearchTags(name) {
+ if (!name) {
+ return this.$message.error("请输入要搜索的标签")
+ this.queryTagParams.name = name;
+ this.queryTagParams.corpId = this.queryParams.corpId;
+ searchTags(this.queryTagParams).then(response => {
+ this.tagGroupList = response.rows;
+ tagSelection(row) {
+ row.isSelected = !row.isSelected;
+ this.$forceUpdate();
+ cancelSearchTags() {
+ this.resetSearchQueryTag()
+ resetSearchQueryTag() {
+ this.queryTagParams = {
+ updateQwuser() {
+ this.queryTagParams.corpId = this.queryParams.corpId
+ allListTagGroup(this.queryTagParams).then(response => {
+ this.tagTotal = response.total;
+ getAllListTagGroup(this.queryTagParams).then(response => {
+ this.showTagGroupList = response.rows;
+ addTagSubmitForm() {
+ for (let i = 0; i < this.tagGroupList.length; i++) {
+ for (let x = 0; x < this.tagGroupList[i].tag.length; x++) {
+ if (this.tagGroupList[i].tag[x].isSelected == true) {
+ this.addTagFormByWatch.tagIds.push(this.tagGroupList[i].tag[x].tagId)
+ if (this.addTagFormByWatch.tagIds == [] || this.addTagFormByWatch.tagIds == null || this.addTagFormByWatch.tagIds == "") {
+ return this.$message('请选择标签');
+ if (this.queryParams.corpId == [] || this.queryParams.corpId == null || this.queryParams.corpId == "") {
+ return this.$message('请选择企微账号');
+ let loadingRock = this.$loading({
+ lock: true,
+ text: '正在执行中请稍后~~请不要刷新页面!!',
+ spinner: 'el-icon-loading',
+ background: 'rgba(0, 0, 0, 0.7)'
+ this.addTagFormByWatch.corpId = this.queryParams.corpId;
+ addFastGptTagByCorpId(this.addTagFormByWatch).then(response => {
+ loadingRock.close();
+ this.getList()
+ }).finally(res => {
+ // 清除所有标签的选中状态
+ clearTagSelections() {
+ this.tagGroupList[i].tag[x].isSelected = false;
+ /** 根据tagId获取tagName */
+ getTagNameById(tagId) {
+ // 在tagList中查找匹配的标签
+ for (let i = 0; i < this.showTagGroupList.length; i++) {
+ for (let x = 0; x < this.showTagGroupList[i].tag.length; x++) {
+ if (this.showTagGroupList[i].tag[x].tagId === tagId) {
+ return this.showTagGroupList[i].tag[x].name;
+ // 如果找不到匹配的标签,返回空字符串
+ return '';
+ //this.open = false;
+ this.tagOpen = true;
+ this.title = "添加新客标签";
+ getFastGptExtUserTag(id).then(response => {
+ this.title = "修改处理新客标签";
+ getCorpNameById(corpId) {
+ if (!corpId) return '';
+ const corp = this.myQwUserList.find(item => item.corpId === corpId);
+ return corp ? corp.corpName : corpId;
+ updateFastGptExtUserTag(this.form).then(response => {
+ addFastGptExtUserTag(this.form).then(response => {
+ this.$confirm('是否确认删除处理新客标签编号为"' + ids + '"的数据项?', "警告", {
+ }).then(function () {
+ return delFastGptExtUserTag(ids);
+ this.$confirm('是否确认导出所有处理新客标签数据项?', "警告", {
+ return exportFastGptExtUserTag(queryParams);
+/* CSS 样式 */
+.tag-container {
+ flex-wrap: wrap; /* 超出宽度时自动换行 */
+ gap: 8px; /* 设置标签之间的间距 */
+.name-background {
+ display: inline-block;
+ background-color: #abece6; /* 背景颜色 */
+ padding: 4px 8px; /* 调整内边距,让背景包裹文字 */
+ border-radius: 4px; /* 可选:设置圆角 */
+.tag-box {
+ padding: 8px 12px;
+ border: 1px solid #989797;
+ border-radius: 4px;
+.tag-selected {
+ background-color: #00bc98;
+ color: #fff;
+ border-color: #00bc98;
+.el-tag + .el-tag {
+ margin-left: 10px;
+.button-new-tag {
+ height: 32px;
+ line-height: 30px;
+ padding-top: 0;
+ padding-bottom: 0;
+.input-new-tag {
+ width: 90px;
+ vertical-align: bottom;
+/* 新增的滚动容器样式(不影响原有样式) */
+.scroll-wrapper {
+ max-height: 130px; /* 大约三行的高度 */
+ overflow-y: auto; /* 垂直滚动 */
+ padding-right: 5px; /* 为滚动条留出空间 */
+/* 美化滚动条(可选) */
+.scroll-wrapper::-webkit-scrollbar {
+ width: 6px;
+.scroll-wrapper::-webkit-scrollbar-thumb {
+ background: rgba(0, 0, 0, 0.2);
+ border-radius: 3px;
@@ -0,0 +1,113 @@
+ <div style="background-color: #f0f2f5; padding-bottom: 20px; min-height: 100%; " >
+ <div style="padding: 20px; background-color: #fff;">
+ 营销指令内容
+ <!-- 使用 el-form 包裹表单项 -->
+ <el-form label-width="120px" style="padding: 20px;">
+ <!-- 发送文字内容 -->
+ <el-form-item label="发送文字内容" >
+ <div class="el-form-item__content readonly-field" style="line-height: 28px;">
+ {{ form.content || '-' }}
+ <!-- 图片访问地址 -->
+ <el-form-item label="图片访问地址">
+ <div class="el-form-item__content readonly-field">
+ <div v-if="form.contentType !== 0 && form.imgUrl && form.imgUrl.trim()">
+ v-for="(url, index) in form.imgUrl.split(',')"
+ :key="index"
+ :src="url" style="width: 100px; height: 100px; margin-right: 10px;"
+ fit="cover"
+ <div slot="error" class="image-slot">
+ <i class="el-icon-picture-outline"></i>
+ <div v-else class="el-form-item__content" style="line-height: 28px;">-</div>
+import {getFastGptKeywordSend} from "@/api/fastGpt/fastGptKeywordSend";
+ name: "fastGptChatMsgDetails",
+ open:false,
+ logsOpen:false,
+ roles:[],
+ msgList:[],
+ item:null,
+ form: {
+ imgUrl: ''
+ contentType: null,
+ imgUrl: null,
+ roleId: null,
+ getDetails(id) {
+ getFastGptKeywordSend(id).then(response => {
+ console.log(response);
+ cancel(){
+<style>
+ .readonly-field {
+ background-color: #fafafa;
+ .contentx{
+ height: 100%;
+ padding: 0px 20px 20px;
+ margin: 20px;
+ .el-descriptions-item__label.is-bordered-label{
+ font-weight: normal;
+ .el-descriptions-item__content {
+ max-width: 150px;
+ min-width: 100px;
+ .desct{
+ padding-top: 20px;
+ padding-bottom: 20px;
+ color: #524b4a;
+ .padding-a{
+ padding-right: 10px;
@@ -0,0 +1,529 @@
+ <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="88px">
+<!-- <el-form-item label="营销关键字" prop="keyword" style="white-space: nowrap;">
+ v-model="queryParams.keyword"
+ placeholder="请输入营销关键字"
+ </el-form-item>-->
+ <el-form-item label="营销关键字" prop="keyword" style="white-space: nowrap;">
+ <el-select v-model="queryParams.keyword" clearable placeholder="请选择营销关键字">
+ v-for="dict in keywordOptions"
+ :key="dict.keyword"
+ :label="dict.keyword"
+ :value="dict.keyword"
+ <el-form-item label="发送文字内容" prop="content" style="white-space: nowrap;">
+ placeholder="请输入发送文字内容"
+ <el-form-item label="内容类型" prop="contentType">
+ <el-select v-model="queryParams.contentType" placeholder="请选择内容类型" clearable size="small">
+ v-for="dict in contentTypeOptions"
+<!-- <el-form-item label="客服角色" prop="roleIds">
+ <el-select v-model="queryParams.roleIds" placeholder="请选择客服角色" clearable size="small">
+ v-for="item in roles"
+ :key="item.roleId"
+ :label="item.roleName"
+ :value="item.roleId"
+ v-hasPermi="['fastGpt:fastGptKeywordSend:add']"
+ v-hasPermi="['fastGpt:fastGptKeywordSend:edit']"
+ v-hasPermi="['fastGpt:fastGptKeywordSend:remove']"
+ v-hasPermi="['fastGpt:fastGptKeywordSend:export']"
+ <el-table border v-loading="loading" :data="fastGptKeywordSendList" @selection-change="handleSelectionChange">
+ <el-table-column label="营销关键字" align="center" prop="keyword"/>
+ <el-table-column label="内容类型" align="center" prop="contentType">
+ <dict-tag :options="contentTypeOptions" :value="scope.row.contentType"/>
+<!-- <el-table-column label="图片访问地址" align="center" prop="imgUrl" />-->
+<!-- <el-table-column label="客服角色" align="center" prop="roleIds">
+ {{ getRoleNameById(scope.row.roleIds) }}
+ @click="handleDetails(scope.row)"
+ >查看</el-button>
+ <!-- 添加或修改Ai指令对话框 -->
+ <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+ <el-form-item label="营销关键字" prop="keyword">
+ <el-select v-model="form.keyword" placeholder="请选择营销关键字">
+ <el-form-item label="发送内容" prop="content">
+ :autosize="{ minRows: 2, maxRows: 4}"
+ placeholder="请输入发送内容"
+ v-model="form.content">
+ <el-select v-model="form.contentType" placeholder="请选择内容类型">
+ <el-form-item label="图片" prop="imgUrl" v-if="this.form.contentType !== 0">
+ <ImageUpload v-model="form.imgUrl" type="image" :limit="1" :width="100" :height="100" />
+ v-model="form.roleIds"
+ placeholder="请选择客服角色"
+ :filter-method="filterRoles"
+ v-for="item in filteredRoles"
+ :value="item.roleId"/>
+ <el-drawer
+ :with-header="false"
+ size="75%" @close="handleDrawerClose"
+ :title="show.title" :visible.sync="show.open">
+ <fastGptKeyWordDetails ref="Details" />
+ </el-drawer>
+ listFastGptKeywordSend,
+ getFastGptKeywordSend,
+ delFastGptKeywordSend,
+ addFastGptKeywordSend,
+ updateFastGptKeywordSend,
+ exportFastGptKeywordSend,
+ keywordList
+} from "@/api/fastGpt/fastGptKeywordSend";
+import ImageUpload from "@/components/ImageUpload/index.vue";
+import fastGptKeyWordDetails from "@/views/fastGpt/fastGptKeywordSend/fastGptKeyWordDetails.vue";
+import { getAllRoleList } from "@/api/fastGpt/fastGptRole";
+ name: "FastGptKeywordSend",
+ components: {fastGptKeyWordDetails, ImageUpload},
+ show:{
+ title:"指令内容",
+ roleMap:{},
+ filteredRoles: [], // 过滤后的角色数据
+ // Ai指令表格数据
+ fastGptKeywordSendList: [],
+ // 关键字内容字典
+ keywordOptions: [],
+ // 内容类型字典
+ contentTypeOptions: [],
+ roleIds: [],
+ form: {roleIds: [],},
+ keyword: [
+ { required: true, message: "营销关键字不能为空", trigger: "change" }
+ content: [
+ // 如果 contentType 不是纯文本类型(比如图文混合),可以动态设置校验规则
+ // 这里假设纯文本内容不需要上传图片
+ { validator: (rule, value, callback) => {
+ const { contentType } = this.form;
+ if (contentType === 0 && !value) {
+ callback(new Error("发送文字内容不能为空"));
+ callback();
+ trigger: "blur"
+ imgUrl: [
+ if (contentType !== 0 && !value) {
+ callback(new Error("图片不能为空"));
+ trigger: "change"
+ Promise.all([
+ keywordList().then(response => {
+ this.keywordOptions = response.data;
+ }),
+ this.getDicts("sys_fastgpt_keyword_file_type").then(response => {
+ this.contentTypeOptions = response.data;
+ this.getDicts("sys_fastgpt_keyword_send_status").then(response => {
+ getAllRoleList().then(response => {
+ this.roles = response.data;
+ this.filteredRoles = response.data;
+ // 生成角色映射表
+ this.roleMap = response.data.reduce((map, role) => {
+ map[role.roleId] = role.roleName;
+ return map;
+ }, {});
+ ])
+ /** 查询Ai指令列表 */
+ listFastGptKeywordSend(this.queryParams).then(response => {
+ this.fastGptKeywordSendList = response.rows;
+ // 添加过滤方法
+ filterRoles(query) {
+ this.filteredRoles = this.roles.filter(item =>
+ item.roleName.toLowerCase().includes(query.toLowerCase())
+ // 获取角色名
+ getRoleNameById(roleIds) {
+ if (!roleIds) return '-';
+ // 确保 roleIds 是数组
+ const idArray = Array.isArray(roleIds) ? roleIds : roleIds.split(',').map(id => id.trim());
+ return idArray
+ .map(id => this.roleMap[id])
+ .filter(name => name)
+ .join('、');
+ //查看按钮
+ handleDetails(row){
+ this.show.open=true;
+ setTimeout(() => {
+ this.$refs.Details.getDetails(row.id);
+ }, 500);
+ //关闭
+ handleDrawerClose(){
+ this.title = "添加Ai指令";
+ const id = row.id || this.ids;
+ const data = response.data;
+ roleIds: data.roleIds ? data.roleIds.split(',').map(Number) : [] // 确保转为 number[]
+ this.title = "修改Ai指令";
+ this.$nextTick(() => {
+ this.$forceUpdate(); // 强制更新 el-select 的绑定
+ // 提取 roleIds 数组中的 roleId 字段组成字符串
+ this.form.roleIds = this.form.roleIds.join(',');
+ updateFastGptKeywordSend(this.form).then(response => {
+ addFastGptKeywordSend(this.form).then(response => {
+ this.$confirm('是否确认删除Ai指令编号为"' + ids + '"的数据项?', "警告", {
+ return delFastGptKeywordSend(ids);
+ this.$confirm('是否确认导出所有Ai指令数据项?', "警告", {
+ return exportFastGptKeywordSend(queryParams);
+<style scoped>.el-form-item__content {
+ white-space: nowrap;
@@ -0,0 +1,341 @@
+ <!-- <el-form-item label="排序" prop="sort">
+ v-model="queryParams.sort"
+ placeholder="请输入排序"
+ v-hasPermi="['fastGpt:fastgptChatArtificialWords:add']"
+ v-hasPermi="['fastGpt:fastgptChatArtificialWords:edit']"
+ v-hasPermi="['fastGpt:fastgptChatArtificialWords:remove']"
+ <!-- <el-col :span="1.5">
+ v-hasPermi="['fastGpt:fastgptChatArtificialWords:export']"
+ <el-table border v-loading="loading" :data="fastgptChatArtificialWordsList" @selection-change="handleSelectionChange">
+ <el-table-column label="文本" align="center" prop="content" />
+ <!-- 添加或修改转人工提示词对话框 -->
+ <el-form-item label="文本" prop="content">
+ <el-input v-model="form.content" placeholder="请输入文本内容"/>
+ <el-input v-model="form.sort" placeholder="请输入排序" />
+import { listFastgptChatArtificialWords, getFastgptChatArtificialWords, delFastgptChatArtificialWords, addFastgptChatArtificialWords, updateFastgptChatArtificialWords, exportFastgptChatArtificialWords } from "@/api/fastGpt/fastgptChatArtificialWords";
+ name: "FastgptChatArtificialWords",
+ // 转人工提示词表格数据
+ fastgptChatArtificialWordsList: [],
+ // 类型 1报错 2关键词字典
+ { required: true, message: "文本不能为空", trigger: "blur" }
+ sort: [
+ { required: true, message: "排序不能为空", trigger: "blur" }
+ this.getDicts("sys_artificial_words_type").then(response => {
+ /** 查询转人工提示词列表 */
+ listFastgptChatArtificialWords(this.queryParams).then(response => {
+ this.fastgptChatArtificialWordsList = response.rows;
+ this.title = "添加转人工提示词";
+ getFastgptChatArtificialWords(id).then(response => {
+ this.title = "修改转人工提示词";
+ updateFastgptChatArtificialWords(this.form).then(response => {
+ addFastgptChatArtificialWords(this.form).then(response => {
+ this.$confirm('是否确认删除转人工提示词编号为"' + ids + '"的数据项?', "警告", {
+ return delFastgptChatArtificialWords(ids);
+ this.$confirm('是否确认导出所有转人工提示词数据项?', "警告", {
+ return exportFastgptChatArtificialWords(queryParams);
@@ -0,0 +1,333 @@
+ <el-form-item label="公司名" prop="companyId">
+ <select-tree
+ v-model="selectedCompanyList"
+ :raw-data="deptList"
+ placeholder="请选择销售"
+ :parentSelectable="true"
+ :multiple="true"
+ component-width="300px"
+ :max-display-tags="3"
+ :check-strictly="false"
+ :return-leaf-only="false"
+ @change="handleMultiChange"
+ ></select-tree>
+ <el-form-item label="销售" prop="nickName" v-if="queryParams.companyId">
+ <el-select v-model="queryParams.companyUserId" remote
+ placeholder="请选择"
+ filterable clearable
+ style="width: 100%;"
+ @change="handleCompanyUserId"
+ v-for="dict in companyUserList"
+ :key="`${dict.nickName} - ${dict.userName}`"
+ :label="`${dict.nickName} - ${dict.userName}`"
+ :value="dict.userId">
+ <el-form-item label="AppKey" prop="appKey">
+ <div style="display: flex; align-items: center;">
+ <tree-select
+ v-model="selectedAppKey"
+ :options="appKeyOptions"
+ :normalizer="normalizer"
+ :disable-branch-nodes="false"
+ placeholder="请选择 AppKey" style="width: 300px;"
+ @input="handleAppKeyChange"
+ <el-form-item label="创建时间" prop="createTime">
+ <el-date-picker v-model="createTime" size="small" style="width: 220px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" @change="changeTime"></el-date-picker>
+ <el-table border v-loading="loading" :data="fastgptEventLogTotalList" :row-class-name="() => 'fixed-bottom-row'"
+ @selection-change="handleSelectionChange" :max-height="600">
+ <el-table-column label="角色名称" align="center" prop="roleName" />
+ <el-table-column label="时间" align="center" prop="statTime" />
+ <el-table-column
+ align="center">
+ <span>{{ scope.row.typeCountMap ? scope.row.typeCountMap[dict.dictValue] : '' }}</span>
+ <span v-if="dict.dictValue !== '11'"
+ :style="{ fontSize: '12px', marginLeft: '5px',
+ color: getPercentageColor((scope.row.typeCountMap[dict.dictValue] / scope.row.typeCountMap[2]) * 100) }">
+ ({{ ((scope.row.typeCountMap[dict.dictValue] / scope.row.typeCountMap[2]) * 100).toFixed(2) }}%)
+import { listFastgptEventLogTotal, getFastgptEventLogTotal, delFastgptEventLogTotal, addFastgptEventLogTotal, updateFastgptEventLogTotal, exportFastgptEventLogTotal, getFastGptRoleAppKeyList} from "@/api/fastGpt/fastgptEventLogTotal";
+import SelectTree from "@/components/TreeSelect/index.vue";
+import {getDeptData} from "@/api/system/employeeStats";
+import TreeSelect from '@riophae/vue-treeselect'
+import '@riophae/vue-treeselect/dist/vue-treeselect.css'
+ name: "FastgptEventLogTotal",
+ components: {SelectTree,TreeSelect},
+ createTime:null,
+ selectedCompanyList: [],
+ deptList: [],
+ companyUserList: [],
+ selectedAppKey: null,
+ selectedAppKeyLabel: '',
+ appKeyOptions: [],
+ // ai事件埋点统计表格数据
+ fastgptEventLogTotalList: [],
+ typeCountMap: null,
+ // 日志类型字典
+ count: null,
+ companyUserId: null,
+ qwUserId: null,
+ beginTime:null,
+ endTime:null,
+ appKey:null,
+ this.getDicts("sys_fastgpt_event_log_type").then(response => {
+ getDeptData().then(response => {
+ this.deptList = response.data;
+ getFastGptRoleAppKeyList().then(res => {
+ this.appKeyOptions = res.data.map(item => ({
+ id: `p_${item.roleId}`,
+ label: item.roleName,
+ children: (item.roleList || []).map(child => ({
+ id: `c_${child.roleId}`,
+ label: child.roleName,
+ parentId: `p_${item.roleId}`, // 记录父节点 ID
+ parentLabel: item.roleName, // 记录父节点 label
+ disabled: true
+ }))
+ }));
+ /** 查询ai事件埋点统计列表 */
+ if(this.selectedCompanyList != null && this.selectedCompanyList.length > 0) {
+ this.queryParams.userIds = this.selectedCompanyList;
+ }else {
+ this.queryParams.userIds = [];
+ listFastgptEventLogTotal(this.queryParams).then(response => {
+ console.log(response)
+ this.fastgptEventLogTotalList = response.data.list;
+ this.total = response.data.total;
+ normalizer(node) {
+ id: node.id,
+ label: node.label,
+ children: node.children,
+ disabled: node.disabled
+ handleAppKeyChange(value) {
+ const node = this.findNodeById(this.appKeyOptions, value);
+ if (!node) {
+ this.selectedAppKeyLabel = '';
+ return;
+ // 如果是子节点,则找父节点 label
+ if (node.parentLabel) {
+ this.queryParams.appKey = node.parentLabel;
+ this.selectedAppKeyLabel = node.parentLabel;
+ this.selectedAppKey = this.selectedAppKeyLabel;
+ this.queryParams.appKey = node.label;
+ this.selectedAppKeyLabel = node.label;
+ findNodeById(nodes, id) {
+ for (const node of nodes) {
+ if (node.id === id) return node;
+ if (node.children) {
+ const found = this.findNodeById(node.children, id);
+ if (found) return found;
+ return null;
+ changeTime(){
+ console.log(this.createTime);
+ if(this.createTime!=null){
+ this.queryParams.beginTime=this.createTime[0];
+ this.queryParams.endTime=this.createTime[1];
+ this.queryParams.beginTime=null;
+ this.queryParams.endTime=null;
+ console.log(this.queryParams.beginTime);
+ console.log(this.queryParams.endTime);
+ handleMultiChange(e){
+ handleCompanyUserId(val){
+ if(val == null || val === '') {
+ this.queryParams.companyUserId = null;
+ console.log(val);
+ statTime: null
+ getPercentageColor(percentage) {
+ // HSL模式从黄色(60度)渐变到红色(0度)
+ const percent = Math.min(100, Math.max(0, parseFloat(percentage)));
+ // 调整色相范围:从深黄色(40°)渐变到红色(0°)
+ const hue = 40 - 40 * (percent / 100); // 初始 hue=40(深黄),终点 hue=0(红)
+ // 提高饱和度(100%),亮度保持 50%(鲜艳但不刺眼)
+ return `hsl(${hue}, 100%, 50%)`;
+ console.log(this.selectedAppKey)
+ if(this.selectedAppKey === null || typeof this.selectedAppKey === 'undefined'){
+ this.queryParams.appKey = null;
+ this.selectedAppKey = null;
+ this.selectedCompanyList = [];
+ this.$confirm('是否确认导出所有ai事件埋点统计数据项?', "警告", {
+ return exportFastgptEventLogTotal(queryParams);
@@ -0,0 +1,302 @@
+ <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+ <el-form-item label="用户ID" prop="userId">
+ v-model="queryParams.userId"
+ placeholder="请输入用户ID"
+ <el-form-item label="用餐日期" prop="recordDate">
+ <el-date-picker clearable
+ v-model="queryParams.recordDate"
+ placeholder="请选择用餐日期">
+ <el-form-item label="用餐描述" prop="mealDescription">
+ v-model="queryParams.mealDescription"
+ placeholder="请输入用餐描述"
+ v-hasPermi="['food:record:add']"
+ v-hasPermi="['food:record:edit']"
+ v-hasPermi="['food:record:remove']"
+ <el-table v-loading="loading" :data="foodRecordList" @selection-change="handleSelectionChange">
+ <el-table-column label="记录ID" align="center" prop="id" />
+ <el-table-column label="用户" align="center" prop="username" >
+ <span>{{scope.row.username}}</span>
+ <el-table-column label="用餐日期" align="center" prop="recordDate" width="180">
+ <span>{{ parseTime(scope.row.recordDate, '{y}-{m}-{d}') }}</span>
+ <el-table-column label="记录时间" align="center" prop="recordTime" width="180">
+ <span>{{ scope.row.recordTime }}</span>
+ <el-table-column label="用餐描述" align="center" prop="mealDescription" :show-overflow-tooltip="true" />
+ <el-table-column label="创建时间" align="center" prop="createdAt" width="180">
+ <span>{{ parseTime(scope.row.createdAt, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+ <!-- 添加或修改饮食记录对话框 -->
+ <el-input v-model="form.userId" placeholder="请输入用户ID" />
+ v-model="form.recordDate"
+ <el-form-item label="记录时间" prop="recordTime">
+ <el-time-picker
+ v-model="form.recordTime"
+ value-format="HH:mm:ss"
+ placeholder="请选择记录时间">
+ </el-time-picker>
+ <el-input v-model="form.mealDescription" type="textarea" placeholder="请输入用餐情况描述" />
+import { listFoodRecord, getFoodRecord, delFoodRecord, addFoodRecord, updateFoodRecord } from "@/api/food/record";
+import {parseTime} from "../../../utils/common";
+ name: "FoodRecord",
+ // 饮食记录表格数据
+ foodRecordList: [],
+ userId: null,
+ recordDate: null,
+ mealDescription: null
+ userId: [
+ { required: true, message: "用户ID不能为空", trigger: "blur" }
+ recordDate: [
+ { required: true, message: "用餐日期不能为空", trigger: "blur" }
+ mealDescription: [
+ { required: true, message: "用餐描述不能为空", trigger: "blur" }
+ parseTime,
+ /** 查询饮食记录列表 */
+ listFoodRecord(this.queryParams).then(response => {
+ this.foodRecordList = response.rows;
+ recordTime: null,
+ mealDescription: null,
+ createdAt: null,
+ updatedAt: null
+ this.title = "添加饮食记录";
+ getFoodRecord(id).then(response => {
+ this.title = "修改饮食记录";
+ updateFoodRecord(this.form).then(response => {
+ this.$message.success("修改成功");
+ addFoodRecord(this.form).then(response => {
+ this.$message.success("新增成功");
+ this.$confirm('是否确认删除饮食记录编号为"' + ids + '"的数据项?').then(function() {
+ return delFoodRecord(ids);
+ this.$message.success("删除成功");
@@ -0,0 +1,838 @@
+ <el-form-item label="用户" prop="userId">
+ placeholder="请输入用户id"
+ <el-form-item label="联系方式" prop="phone">
+ v-model="queryParams.phone"
+ placeholder="请输入联系方式"
+ <el-form-item label="处理状态" prop="isHandle">
+ v-model="queryParams.isHandle"
+ placeholder="请选择处理状态"
+ <el-option label="未处理" value="0"></el-option>
+ <el-option label="已处理" value="1"></el-option>
+ <el-form-item label="投诉时间" prop="complaintTime">
+ <el-date-picker v-model="complaintTime" size="small" style="width: 220px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" @change="changeTime"></el-date-picker>
+ v-hasPermi="['his:complaint:export']"
+ <el-table border v-loading="loading" :data="complaintList" @selection-change="handleSelectionChange">
+ <el-table-column label="用户" align="center" prop="nickName" />
+ <el-table-column label="投诉方式" align="center" prop="complaintType" >
+ <template v-for="item in complaintTypeOptions">
+ <el-tag v-if="item.dictValue === scope.row.complaintType" :key="item.dictValue">
+ {{ item.dictLabel }}
+ <el-table-column label="投诉类型" align="center" prop="type" >
+ <el-table-column label="投诉时间" align="center" prop="createTime" />
+ label="是否处理"
+ align="center"
+ prop="isHandlePlatform"
+ :render-header="renderHandleHeader"
+ <el-tag
+ :type="scope.row.isHandlePlatform == 1 ? 'success' : 'warning'"
+ disable-transitions
+ {{ formatHandleStatus(scope.row.isHandle) }}
+ label="店铺是否处理"
+ :type="(scope.row.isHandleStore == 1)? 'success' : 'warning'"
+ <el-table-column label="备注" align="center" prop="remarks" />
+ v-hasPermi="['his:complaint:edit']"
+ >投诉详情</el-button>
+ v-hasPermi="['his:complaint:remove']"
+ <!-- 修改用户投诉对话框 -->
+ <el-dialog :title="title" :visible.sync="open" width="900px" append-to-body>
+ <!-- 修改tab-click事件处理器名称 -->
+ <el-tabs v-model="activeTab" type="card" @tab-click="handleClick">
+ <!-- 投诉详情标签页 -->
+ <el-tab-pane label="投诉详情" name="complaint">
+ <el-form-item label="投诉内容" prop="name">
+ <el-input v-model="form.name" :disabled="true" />
+ <el-form-item label="详细内容" v-if="form.content && form.content!=''">
+ <el-input type="textarea" v-model="form.content" :disabled="true"/>
+ <el-form-item label="联系方式" prop="phone" v-if="form.phone && form.phone!=''">
+ <el-input v-model="form.phone" :disabled="true"/>
+ <el-form-item label="图片" v-if="form.images && form.images!=''">
+ <div v-for="(url, index) in imageUrls(form.images)" :key="index" class="image-container">
+ <el-image :src="url" :preview-src-list="[url]" style="width: 100px; height: 100px;"></el-image>
+ <!-- <el-form-item label="交易截图" v-if="form.tradeImage && form.tradeImage!=''">
+ <div v-for="(url, index) in imageUrls(form.tradeImage)" :key="index" class="image-container">
+ </el-form-item> -->
+ <el-form-item label="用户" prop="nickName">
+ <el-input v-model="form.nickName" :disabled="true"/>
+ <el-form-item label="是否处理" prop="isHandle">
+ <el-select v-model="form.isHandlePlatform" placeholder="请选择处理状态" :disabled="true">
+ <el-option label="未处理" :value="0"></el-option>
+ <el-option label="已处理" :value="1"></el-option>
+ <el-form-item label="备注" prop="remarks" >
+ <el-input type="textarea" v-model="form.remarks" :maxlength="250" :disabled="true"/>
+ </el-tab-pane>
+ <!-- 回复详情标签页 -->
+ <el-tab-pane label="回复详情" name="replies">
+ <div class="reply-section">
+ <!-- 添加回复表单 -->
+ <el-card class="add-reply-card" shadow="never">
+ <div slot="header">
+ <span>添加回复</span>
+ <el-form :model="replyForm" ref="replyForm" label-width="80px">
+ <el-form-item label="回复内容" prop="content" :rules="[{ required: true, message: '请输入回复内容', trigger: 'blur' }]">
+ v-model="replyForm.content"
+ placeholder="请输入回复内容"
+ maxlength="500"
+ show-word-limit
+ <!-- 添加图片上传功能 -->
+ <el-form-item label="上传图片" prop="images">
+ <!-- <div class="image-upload-container">
+ <el-upload
+ ref="imageUpload"
+ :action="uploadUrl"
+ :show-file-list="false"
+ :file-list="replyImageList"
+ :on-success="handleSuccess"
+ :before-upload="beforeUpload"
+ :limit="4"
+ list-type="picture-card"
+ accept="image/*"
+ <i class="el-icon-plus"></i>
+ <div slot="tip" class="el-upload__tip">
+ 最多上传4张图片,单张图片不超过2MB
+ </el-upload>
+ </div> -->
+ <ImageUpload v-model="replyForm.images" type="image" :num="4" :width="150" :height="150"/>
+ <el-button type="primary" size="small" @click="submitReply" :loading="replyLoading">
+ <i class="el-icon-s-promotion"></i> 发送回复
+ </el-button>
+ </el-card>
+ <!-- 回复列表 -->
+ <el-card class="reply-list-card" shadow="never">
+ <span>回复记录 ({{ replyTotal }}条)</span>
+ <div v-loading="replyLoading" class="reply-list">
+ <div v-if="replyList.length === 0" class="empty-replies">
+ <el-empty description="暂无回复记录" :image-size="100"></el-empty>
+ <div v-else>
+ <div v-for="reply in replyList" :key="reply.id" class="reply-item">
+ <div class="reply-header">
+ <div class="reply-user">
+ <el-avatar :size="32" :src="reply.avatar || '/default-avatar.png'">
+ {{ reply.userName ? reply.userName.charAt(0) : 'U' }}
+ </el-avatar>
+ <!-- <span class="user-name">{{ reply.userName || '系统管理员' }}</span> -->
+ <el-tag size="mini" :type="reply.sendType != 1 ? 'success' : 'info'">
+ {{ reply.sendType === 1 ? '用户' : reply.sendType === 2 ? '系统平台':'店铺平台' }}
+ <div class="reply-time">
+ {{ reply.createTime }}
+ <div class="reply-content">
+ {{ reply.content }}
+ <!-- 显示回复中的图片 -->
+ <div class="reply-images" v-if="reply.images && reply.images !== ''">
+ <div v-for="(url, index) in imageUrls(reply.images)" :key="index" class="reply-image-container">
+ :src="url"
+ :preview-src-list="imageUrls(reply.images)"
+ style="width: 80px; height: 80px;"
+ ></el-image>
+ <div class="reply-actions" v-if="reply.userType === 'admin'">
+ <el-button type="text" size="mini" @click="editReply(reply)">
+ <i class="el-icon-edit"></i> 编辑
+ <el-button type="text" size="mini" @click="deleteReply(reply)" style="color: #f56c6c;">
+ <i class="el-icon-delete"></i> 删除
+ <!-- 回复分页 -->
+ <div class="reply-pagination" v-if="replyTotal > 0">
+ <el-pagination
+ @size-change="handleReplySizeChange"
+ @current-change="handleReplyCurrentChange"
+ :current-page="replyQueryParams.pageNum"
+ :page-sizes="[5, 10, 20]"
+ :page-size="replyQueryParams.pageSize"
+ layout="total, sizes, prev, pager, next, jumper"
+ :total="replyTotal"
+ small
+ <el-button type="primary" @click="submitForm" v-if="activeTab === 'complaint' && form.id==null">确 定</el-button>
+ <!-- 编辑回复对话框 -->
+ <el-dialog title="编辑回复" :visible.sync="editReplyVisible" width="500px" append-to-body>
+ <el-form :model="editReplyForm" ref="editReplyForm" label-width="80px">
+ v-model="editReplyForm.content"
+ <el-button type="primary" @click="updateReply" :loading="replyLoading">确 定</el-button>
+ <el-button @click="editReplyVisible = false">取 消</el-button>
+import { listComplaint, getComplaint, delComplaint, addComplaint, updateComplaint, exportComplaint,listMsg,addMsg } from "@/api/his/complaint";
+import ImageUpload from '@/components/ImageUpload/index';
+ name: "Complaint",
+ components: {
+ ImageUpload
+ replyImageList: [],
+ uploadUrl:process.env.VUE_APP_BASE_API+"/common/uploadOSS",
+ complaintId:null,
+ activeName:"0",
+ typeOptions:[
+ dictValue:'0',
+ dictLabel:'默认'
+ dictValue:'1',
+ dictLabel:'店铺'
+ dictValue:'2',
+ dictLabel:'商品'
+ complaintTypeOptions:[
+ dictValue:1,
+ dictLabel:'咨询'
+ dictValue:2,
+ dictLabel:'投诉/举报'
+ complaintTime:null,
+ // 用户投诉表格数据
+ complaintList: [],
+ // 当前激活的标签页
+ activeTab: 'complaint',
+ templateId: null,
+ phone: null,
+ urls: null,
+ account: null,
+ isHandle: null
+ { required: true, message: "用户id不能为空", trigger: "blur" }
+ templateId: [
+ { required: true, message: "投诉模板id不能为空", trigger: "blur" }
+ // 回复相关数据
+ replyList: [],
+ replyTotal: 0,
+ replyLoading: false,
+ replyQueryParams: {
+ complaintId: null
+ replyForm: {
+ // 编辑回复
+ editReplyVisible: false,
+ editReplyForm: {
+ content: ''
+ handleClick(tab) {
+ if (tab.name === 'replies') {
+ this.getReplyList();
+ renderHandleHeader(h, { column }) {
+ if (column.label === '是否处理') {
+ return h('div', [
+ '是否处理',
+ h('el-tooltip', {
+ content: '仅需要处理投诉/举报类',
+ placement: 'top'
+ }, [
+ h('i', {
+ class: 'el-icon-question',
+ style: 'margin-left: 5px; cursor: pointer; color: #909399;'
+ ]);
+ } else if (column.label === '店铺是否处理') {
+ '店铺是否处理',
+ content: '仅需要处理咨询类',
+ return column.label;
+ imageUrls(urls) {
+ return String(urls).split(",");
+ formatHandleStatus(status) {
+ return status == 1 ? '已处理' : '未处理';
+ /** 查询用户投诉列表 */
+ listComplaint(this.queryParams).then(response => {
+ this.complaintList = response.rows;
+ this.resetReplyData();
+ isHandle: 0,
+ remarks:null
+ // 重置回复数据
+ resetReplyData() {
+ this.activeTab = 'complaint';
+ this.replyList = [];
+ this.replyTotal = 0;
+ this.replyQueryParams = {
+ this.replyForm = {
+ complaintId: null,
+ images: '' // 重置图片字段
+ this.replyImageList = [];
+ this.editReplyImageList = [];
+ this.complaintTime = null;
+ this.queryParams.complaintsTime=null;
+ this.queryParams.complainteTime=null;
+ this.title = "添加用户投诉";
+ // const id = row.id || this.ids
+ const complaintId = row.id || this.complaintId
+ this.complaintId = complaintId;
+ getComplaint(complaintId).then(response => {
+ this.replyForm.complaintId = complaintId;
+ this.replyQueryParams.complaintId = complaintId;
+ this.title = "投诉详情";
+ // 加载回复列表
+ updateComplaint(this.form).then(response => {
+ addComplaint(this.form).then(response => {
+ this.$confirm('是否确认删除用户投诉编号为"' + ids + '"的数据项?', "警告", {
+ return delComplaint(ids);
+ this.$confirm('是否确认导出所有用户投诉数据项?', "警告", {
+ return exportComplaint(queryParams);
+ if(this.complaintTime!=null){
+ this.queryParams.complaintsTime=this.complaintTime[0];
+ this.queryParams.complainteTime=this.complaintTime[1];
+ // 获取回复列表
+ getReplyList() {
+ this.replyLoading = true;
+ // 模拟API调用 - 你需要替换为实际的API
+ // 模拟数据
+ listMsg(this.replyQueryParams).then(response => {
+ this.replyList = response.rows;
+ this.replyTotal = response.total;
+ this.replyLoading = false;
+ // 提交回复
+ submitReply() {
+ this.$refs.replyForm.validate(valid => {
+ // const imageUrls = this.replyImageList.map(file => file.url || file.response?.url).filter(url => url);
+ // this.replyForm.images = imageUrls.join(',');
+ // 模拟API调用
+ const newReply = {
+ content: this.replyForm.content,
+ complaintId:this.replyForm.complaintId,
+ images: this.replyForm.images, // 包含图片数据
+ sendType: 2
+ addMsg(newReply).then(response => {
+ this.$message.success('回复发送成功');
+ this.replyForm.content = '';
+ this.replyForm.images = ''; // 重置图片字段
+ this.replyImageList = []; // 重置图片列表
+ this.getReplyList()
+ editReply(reply) {
+ this.editReplyForm = {
+ id: reply.id,
+ content: reply.content,
+ images: reply.images || '' // 包含图片数据
+ this.editReplyImageList = reply.images ?
+ reply.images.split(',').map((url, index) => ({
+ uid: index,
+ name: `image-${index}`,
+ url: url
+ })) : [];
+ this.editReplyVisible = true;
+ // 更新回复
+ updateReply() {
+ this.$refs.editReplyForm.validate(valid => {
+ // const imageUrls = this.editReplyImageList.map(file => file.url || file.response?.url).filter(url => url);
+ // this.editReplyForm.images = imageUrls.join(',');
+ const index = this.replyList.findIndex(item => item.id === this.editReplyForm.id);
+ if (index !== -1) {
+ this.replyList[index].content = this.editReplyForm.content;
+ this.replyList[index].images = this.editReplyForm.images; // 更新图片
+ this.editReplyVisible = false;
+ this.$message.success('回复更新成功');
+ // 删除回复
+ deleteReply(reply) {
+ this.$confirm('确定要删除这条回复吗?', '提示', {
+ const index = this.replyList.findIndex(item => item.id === reply.id);
+ this.replyList.splice(index, 1);
+ this.replyTotal--;
+ this.$message.success('删除成功');
+ // 回复分页大小改变
+ handleReplySizeChange(val) {
+ this.replyQueryParams.pageSize = val;
+ // 回复当前页改变
+ handleReplyCurrentChange(val) {
+ this.replyQueryParams.pageNum = val;
+ handleSuccess(res, file) {
+ if(res.code==200){
+ this.form.licenseImages=res.url;
+ this.$forceUpdate()
+ this.msgError(res.msg);
+ beforeUpload(file) {
+ const isLt1M = file.size / 1024 / 1024 < 1;
+ if (!isLt1M) {
+ this.$message.error('上传图片大小不能超过 1MB!');
+ return isLt1M;
+.reply-section {
+ margin-top: 10px;
+.add-reply-card {
+.reply-list-card {
+ min-height: 400px;
+.reply-list {
+ min-height: 300px;
+.empty-replies {
+ justify-content: center;
+ height: 200px;
+.reply-item {
+ border-bottom: 1px solid #f0f0f0;
+ padding: 15px 0;
+.reply-item:last-child {
+ border-bottom: none;
+.reply-header {
+ justify-content: space-between;
+.reply-user {
+ gap: 8px;
+.user-name {
+ font-weight: 500;
+ color: #303133;
+.reply-time {
+ color: #909399;
+ font-size: 12px;
+.reply-content {
+ background-color: #f8f9fa;
+ padding: 12px;
+ border-radius: 6px;
+ line-height: 1.5;
+ color: #606266;
+.reply-actions {
+ text-align: right;
+.reply-pagination {
+ margin-top: 20px;
+ text-align: center;
+.image-container {
+ margin-right: 10px;
@@ -0,0 +1,369 @@
+ <el-input v-model="queryParams.patientName" placeholder="请输入患者姓名" clearable size="small"
+ @keyup.enter.native="handleQuery" />
+ <el-form-item label="电话" prop="phone">
+ <el-input v-model="queryParams.phone" placeholder="请输入电话" clearable size="small"
+ <el-form-item label="医生名称" prop="doctorName">
+ <el-input v-model="queryParams.doctorName" placeholder="请输入医生名称" clearable size="small"
+ <el-form-item label="用户姓名" prop="userName">
+ <el-input v-model="queryParams.userName" placeholder="请输入用户姓名" clearable size="small"
+ <el-form-item label="销售名称" prop="qwUserName">
+ <el-input v-model="queryParams.qwUserName" placeholder="请输入销售名称" clearable size="small"
+ <el-form-item label="医生证号" prop="doctorCertificate">
+ <el-input v-model="queryParams.doctorCertificate" placeholder="请输入医生证号" clearable size="small"
+ <el-form-item label="医生填写" prop="doctorStatus">
+ <el-select clearable v-model="queryParams.doctorStatus">
+ <el-option label="未填写" value="0"></el-option>
+ <el-option label="已填写" value="1"></el-option>
+ <el-form-item label="用户答复" prop="userStatus">
+ <el-select clearable v-model="queryParams.userStatus">
+ <el-option label="未答复" value="0"></el-option>
+ <el-option label="已答复" value="1"></el-option>
+ v-hasPermi="['his:fsFirstDiagnosis:add']"
+ v-hasPermi="['his:fsFirstDiagnosis:edit']"
+ v-hasPermi="['his:fsFirstDiagnosis:remove']"
+ </el-col> -->
+ <el-button type="warning" plain icon="el-icon-download" size="mini" :loading="exportLoading"
+ @click="handleExport" v-hasPermi="['his:fsFirstDiagnosis:export']">导出</el-button>
+ <el-table border v-loading="loading" :data="fsFirstDiagnosisList" @selection-change="handleSelectionChange">
+ <!-- <el-table-column label="医生证号" align="center" prop="id" /> -->
+ <el-table-column label="患者姓名" align="center" prop="patientName" />
+ <el-table-column label="年龄" align="center" prop="age" />
+ <el-table-column label="性别" align="center" prop="gender">
+ <el-tag v-if="scope.row.gender == 0">未知</el-tag>
+ <el-tag v-if="scope.row.gender == 1">男</el-tag>
+ <el-tag v-if="scope.row.gender == 2">女</el-tag>
+ <el-table-column label="电话" align="center" prop="phone" />
+ <el-table-column label="身体状况" align="center" prop="physicalCondition" :show-overflow-tooltip="true" />
+ <el-table-column label="日期" align="center" prop="dateTime" width="180">
+ <span>{{ parseTime(scope.row.dateTime, '{y}-{m}-{d}') }}</span>
+ <el-table-column label="初步诊断" align="center" prop="firstDiagnosis" :show-overflow-tooltip="true" />
+ <el-table-column label="医生名称" align="center" prop="doctorName" />
+ <el-table-column label="医生职称" align="center" prop="doctorDep" />
+ <el-table-column label="医生证号" align="center" prop="doctorCertificate" />
+ <el-table-column label="用户姓名" align="center" prop="userName" />
+ <el-table-column label="销售名称" align="center" prop="qwUserName" />
+ <el-table-column label="用户答复" align="center" prop="userStatus" width="120px">
+ <el-tag v-if="scope.row.userStatus == 0">未答复</el-tag>
+ <el-tag type="success" v-if="scope.row.userStatus == 1">已答复</el-tag>
+ <el-table-column label="医生填写" align="center" prop="doctorStatus" width="120px">
+ <el-tag v-if="scope.row.doctorStatus == 0">未填写</el-tag>
+ <el-tag type="success" v-if="scope.row.doctorStatus == 1">已填写</el-tag>
+ <!-- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+ </el-table-column> -->
+ <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
+ @pagination="getList" />
+ <!-- 添加或修改初诊单对话框 -->
+ <el-input v-model="form.patientName" placeholder="请输入患者姓名" />
+ <el-form-item label="年龄" prop="age">
+ <el-input v-model="form.age" placeholder="请输入年龄" />
+ <el-form-item label="0-未知 1-男性 2-女性" prop="gender">
+ <el-input v-model="form.gender" placeholder="请输入0-未知 1-男性 2-女性" />
+ <el-input v-model="form.phone" placeholder="请输入电话" />
+ <el-form-item label="身体状况" prop="physicalCondition">
+ <el-input v-model="form.physicalCondition" type="textarea" placeholder="请输入内容" />
+ <el-form-item label="日期" prop="dateTime">
+ <el-date-picker clearable size="small" v-model="form.dateTime" type="date" value-format="yyyy-MM-dd"
+ <el-form-item label="出版诊断" prop="firstDiagnosis">
+ <el-input v-model="form.firstDiagnosis" type="textarea" placeholder="请输入内容" />
+ <el-form-item label="医生id" prop="doctoId">
+ <el-input v-model="form.doctoId" placeholder="请输入医生id" />
+ <el-input v-model="form.doctorName" placeholder="请输入医生名称" />
+ <el-form-item label="职称" prop="doctorDep">
+ <el-input v-model="form.doctorDep" placeholder="请输入职称" />
+ <el-form-item label="用户id" prop="userId">
+ <el-input v-model="form.userId" placeholder="请输入用户id" />
+ <el-input v-model="form.doctorCertificate" placeholder="请输入医生证号" />
+import { listFsFirstDiagnosis, getFsFirstDiagnosis, delFsFirstDiagnosis, addFsFirstDiagnosis, updateFsFirstDiagnosis, exportFsFirstDiagnosis } from "@/api/his/fsFirstDiagnosis";
+ name: "FsFirstDiagnosis",
+ // 初诊单表格数据
+ fsFirstDiagnosisList: [],
+ patientName: null,
+ age: null,
+ gender: null,
+ physicalCondition: null,
+ dateTime: null,
+ firstDiagnosis: null,
+ doctoId: null,
+ doctorName: null,
+ doctorDep: null,
+ doctorCertificate: null
+ /** 查询初诊单列表 */
+ listFsFirstDiagnosis(this.queryParams).then(response => {
+ this.fsFirstDiagnosisList = response.rows;
+ updateTime: null,
+ this.title = "添加初诊单";
+ getFsFirstDiagnosis(id).then(response => {
+ this.title = "修改初诊单";
+ updateFsFirstDiagnosis(this.form).then(response => {
+ addFsFirstDiagnosis(this.form).then(response => {
+ this.$confirm('是否确认删除初诊单编号为"' + ids + '"的数据项?', "警告", {
+ return delFsFirstDiagnosis(ids);
+ }).catch(() => { });
+ this.$confirm('是否确认导出所有初诊单数据项?', "警告", {
+ return exportFsFirstDiagnosis(queryParams);
@@ -0,0 +1,326 @@
+ <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="85px">
+ <el-form-item label="appId" prop="appId">
+ v-model="queryParams.appId"
+ placeholder="请输入appId"
+ <el-form-item label="汇付产品号" prop="hfProductId">
+ v-model="queryParams.hfProductId"
+ placeholder="请输入汇付产品号"
+ v-hasPermi="['his:hfpayConfig:add']"
+ v-hasPermi="['his:hfpayConfig:edit']"
+ v-hasPermi="['his:hfpayConfig:remove']"
+ v-hasPermi="['his:hfpayConfig:export']"
+ <el-table border v-loading="loading" :data="hfpayConfigList" @selection-change="handleSelectionChange">
+ <el-table-column label="appId" align="center" prop="appId" />
+ <el-table-column label="汇付产品号" align="center" prop="hfProductId" />
+ <el-table-column label="系统号" align="center" prop="hfSysId" />
+ <el-table-column label="商户号" align="center" prop="huifuId" />
+ <el-table-column label="支付回调地址" align="center" :show-overflow-tooltip="true" prop="hfPayNotifyUrl" />
+ <el-table-column label="大额支付回调地址" align="center" :show-overflow-tooltip="true" prop="hfPayOnlineNotifyUrl" />
+ <el-table-column label="退款回调地址" align="center" :show-overflow-tooltip="true" prop="hfRefundNotifyUrl" />
+ <el-table-column label="大额退款回调地址" align="center" :show-overflow-tooltip="true" prop="hfOnlineRefundNotifyUrl" />
+ <el-table-column label="商户私钥" align="center" :show-overflow-tooltip="true" prop="hfRsaPrivateKey" />
+ <el-table-column label="汇付公钥" align="center" :show-overflow-tooltip="true" prop="hfRsaPublicKey" />
+ <!-- 添加或修改汇付多支付配置对话框 -->
+ <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
+ <el-form ref="form" :model="form" :rules="rules" label-width="125px">
+ <el-input v-model="form.appId" placeholder="请输入appId" />
+ <el-input v-model="form.hfProductId" placeholder="请输入汇付产品号" />
+ <el-form-item label="系统号" prop="hfSysId">
+ <el-input v-model="form.hfSysId" placeholder="请输入系统号" />
+ <el-form-item label="商户号" prop="huifuId">
+ <el-input v-model="form.huifuId" placeholder="请输入商户号" />
+ <el-form-item label="支付回调地址" prop="hfPayNotifyUrl">
+ <el-input v-model="form.hfPayNotifyUrl" placeholder="请输入支付回调地址" />
+ <el-form-item label="大额支付回调地址" prop="hfPayOnlineNotifyUrl">
+ <el-input v-model="form.hfPayOnlineNotifyUrl" placeholder="请输入大额支付回调地址" />
+ <el-form-item label="退款回调地址" prop="hfRefundNotifyUrl">
+ <el-input v-model="form.hfRefundNotifyUrl" placeholder="请输入退款回调地址" />
+ <el-form-item label="大额退款回调地址" prop="hfOnlineRefundNotifyUrl">
+ <el-input v-model="form.hfOnlineRefundNotifyUrl" placeholder="请输入大额退款回调地址" />
+ <el-form-item label="商户私钥" prop="hfRsaPrivateKey">
+ <el-input v-model="form.hfRsaPrivateKey" type="textarea" placeholder="请输入商户私钥" />
+ <el-form-item label="汇付公钥" prop="hfRsaPublicKey">
+ <el-input v-model="form.hfRsaPublicKey" type="textarea" placeholder="请输入汇付公钥" />
+import { listHfpayConfig, getHfpayConfig, delHfpayConfig, addHfpayConfig, updateHfpayConfig, exportHfpayConfig } from "@/api/his/hfpayConfig";
+ name: "HfpayConfig",
+ // 汇付多支付配置表格数据
+ hfpayConfigList: [],
+ appId: null,
+ hfProductId: null,
+ hfSysId: null,
+ huifuId: null,
+ hfPayNotifyUrl: null,
+ hfPayOnlineNotifyUrl: null,
+ hfRefundNotifyUrl: null,
+ hfOnlineRefundNotifyUrl: null,
+ hfRsaPrivateKey: null,
+ hfRsaPublicKey: null,
+ /** 查询汇付多支付配置列表 */
+ listHfpayConfig(this.queryParams).then(response => {
+ this.hfpayConfigList = response.rows;
+ updateTime: null
+ this.title = "添加汇付多支付配置";
+ getHfpayConfig(id).then(response => {
+ this.title = "修改汇付多支付配置";
+ updateHfpayConfig(this.form).then(response => {
+ addHfpayConfig(this.form).then(response => {
+ this.$confirm('是否确认删除汇付多支付配置编号为"' + ids + '"的数据项?', "警告", {
+ return delHfpayConfig(ids);
+ this.$confirm('是否确认导出所有汇付多支付配置数据项?', "警告", {
+ return exportHfpayConfig(queryParams);
@@ -0,0 +1,252 @@
+ <el-card>
+ <div slot="header" class="clearfix">
+ <span>设备绑定统计</span>
+ <el-tab-pane label="按天统计" name="daily">
+ <el-form :inline="true" class="demo-form-inline">
+ <el-form-item label="日期">
+ v-model="dailyDate"
+ placeholder="选择日期"
+ @change="handleDailyDateChange"
+ <el-button type="primary" @click="searchDaily">查询</el-button>
+ <el-button @click="resetDaily">重置</el-button>
+ <el-button type="success" @click="exportDaily">导出</el-button>
+ <el-table
+ v-loading="dailyLoading"
+ border
+ :data="companyList"
+ <el-table-column prop="date" label="日期" width="180" />
+ <el-table-column prop="companyName" label="公司名称" />
+ <el-table-column prop="bindCount" label="绑定台数" />
+ <div class="chart-container" style="margin-top: 20px; height: 400px">
+ <div ref="dailyChart" style="height: 100%; width: 100%"></div>
+ <el-tab-pane label="按月统计" name="monthly">
+ <el-form-item label="月份">
+ v-model="monthlyDate"
+ type="month"
+ placeholder="选择月份"
+ value-format="yyyy-MM"
+ @change="handleMonthlyDateChange"
+ <el-button type="primary" @click="searchMonthly">查询</el-button>
+ <el-button @click="resetMonthly">重置</el-button>
+ <el-button type="success" @click="exportMonthly">导出</el-button>
+ v-loading="monthlyLoading"
+ <el-table-column prop="date" label="月份" width="180" />
+ <div ref="monthlyChart" style="height: 100%; width: 100%"></div>
+ <script>
+ import { ipadStaticTotal,exportIpadStaticByTime} from "@/api/company/statistics";
+ name: 'ipadStatic',
+ 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}')
+ // 激活的标签页
+ activeTab: 'daily',
+ // 按天统计数据
+ dailyLoading: false,
+ dailyDate: yesterday, // 默认当天
+ // 按月统计数据
+ monthlyLoading: false,
+ monthlyDate: this.parseTime(new Date(), '{y}-{m}'), // 默认当月
+ // 获取当天数据
+ // 标签页切换
+ if (tab.name === 'daily') {
+ } else if (tab.name === 'monthly') {
+ this.getMonthlyList()
+ // 按天统计相关方法
+ handleDailyDateChange(val) {
+ if (val) {
+ this.dailyDate = val
+ searchDaily() {
+ resetDaily() {
+ this.dailyDate = yesterday
+ // 导出
+ exportDaily() {
+ this.$confirm("是否确认导出数据项?", "警告", {
+ type: "warning",
+ .then(() => {
+ return exportIpadStaticByTime(this.dailyDate);
+ .then((response) => {
+ .catch(() => { });
+ this.dailyLoading = true
+ ipadStaticTotal(this.dailyDate).then(response => {
+ // 处理返回数据,添加日期字段用于表格和图表显示
+ this.companyList = response.list;
+ this.dailyLoading = false;
+ // 按月统计相关方法
+ handleMonthlyDateChange(val) {
+ this.monthlyDate = val
+ searchMonthly() {
+ resetMonthly() {
+ this.monthlyDate = this.parseTime(new Date(), '{y}-{m}')
+ exportMonthly() {
+ return exportIpadStaticByTime(this.monthlyDate);
+ getMonthlyList() {
+ this.monthlyLoading = true
+ ipadStaticTotal(this.monthlyDate).then(response => {
+ // 处理返回数据,添加月份字段用于表格和图表显示
+ 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
+ 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 {
+ padding: 20px 0;
+ </style>
+ <span>token消耗统计</span>
+ <el-table-column prop="statTime" label="日期" width="180" />
+ <el-table-column prop="count" label="消耗token数" />
+ import { tokenStaticTotal,exportTokenStaticByTime} from "@/api/company/statistics";
+ name: 'tokenStatic',
+ return exportTokenStaticByTime(this.dailyDate);
+ tokenStaticTotal(this.dailyDate).then(response => {
+ return exportTokenStaticByTime(this.monthlyDate);
+ tokenStaticTotal(this.monthlyDate).then(response => {
@@ -433,6 +433,16 @@
>创建erp</el-button>
</el-tooltip>
+ <el-tooltip content="批量推送erp" placement="top">
+ effect="plain"
+ v-hasPermi="['his:storeOrder:createErpOrder']"
+ >创建erp</el-tag>
+ </el-tooltip>
<el-tabs type="card" v-model="actName" @tab-click="handleClickX">
@@ -1386,7 +1396,7 @@ export default {
this.executeCreateErpOrder();
async executSetErpOrder() {
@@ -1685,6 +1695,7 @@ export default {
} else {
this.$message.error(response.msg || '保存失败');
}).catch(() => {
this.$message.error('保存失败');
@@ -1,40 +1,6 @@
- <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">
- v-model="queryCompanyUserId"
- placeholder="请选择所属销售"
- v-for="item in companyQueryUserOptions"
- :key="item.userId"
- :label="item.nickName"
- :value="item.userId">
<el-form-item label="会员ID" prop="userId">
v-model="queryParams.userId"
@@ -149,8 +115,7 @@
<dict-tag :options="userOptions" :value="scope.row.status"/>
- <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},
- companyQueryOptions:[],
- companyQueryUserOptions:[],
- queryCompanyId:null,
- queryCompanyUserId:null,
companyName: null,
companyUserNickName: null,
companyOptions: [],
@@ -321,6 +282,7 @@ export default {
isBuy:null,
source: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;
- }});
/** 销售选择变化 */
@@ -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 => {
- this.companyQueryUserOptions = response.data;
- this.$message.error(response.msg || '获取销售列表失败');
- this.companyQueryUserOptions = [];
- }).catch(() => {
- this.$message.error('获取销售列表失败');
/** 查询用户列表 */
@@ -459,8 +397,6 @@ export default {
/** 搜索按钮操作 */
- this.queryParams.companyId = this.queryCompanyId;
- this.queryParams.companyUserId = this.queryCompanyUserId;
/** 重置按钮操作 */
@@ -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;
@@ -30,7 +30,7 @@
- <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"
@@ -64,7 +64,7 @@
<el-form-item label="所属销售" prop="companyUserNickName">
<el-select
- v-model="queryParams.companyUserNickName"
+ v-model="queryParams.companyUserId"
placeholder="请选择所属销售"
clearable
filterable
@@ -74,7 +74,7 @@
v-for="item in companyQueryUserOptions"
:key="item.userId"
:label="item.nickName"
- :value="item.nickName">
+ :value="item.userId">
</el-option>
@@ -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 label="操作" align="center" width="150px" class-name="small-padding fixed-width">
- 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>-->
@@ -450,7 +450,8 @@ export default {
startCreateTime: null,
endCreateTime: null,
- companyUserNickName: null
+ companyUserNickName: null,
@@ -489,7 +490,7 @@ export default {
- 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
/** 处理日期范围变化 */
@@ -629,10 +632,27 @@ export default {
const userId = row.userId || this.ids
getUser(userId).then(response => {
- 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();
+ this.form.status = null;
+ if(response.data.isShow){
+ this.form.isShow = response.data.isShow.toString();
+ this.form.isShow = null;
+ if(response.data.level){
+ this.form.level = response.data.level.toString();
+ this.form.level = null;
+ if(response.data.isPromoter){
+ this.form.isPromoter = response.data.isPromoter.toString();
this.title = "修改用户";
@@ -1,9 +1,9 @@
<div>
<div style="background-color: #f0f2f5; padding-bottom: 20px; min-height: 100%; " >
- <div style="padding: 20px; background-color: #fff;">
+ <!-- <div style="padding: 20px; background-color: #fff;">
会员详情
- </div>
<el-tabs v-model="activeName" :tab-position="tabPosition" style="height: 200px;margin: 40px">
@@ -0,0 +1,492 @@
+ <el-form-item label="广告位置" prop="advType">
+ <el-select v-model="queryParams.advType" placeholder="请选择广告位置" clearable size="small">
+ v-for="item in advTypeOptions"
+ <el-form-item label="显示类型" prop="showType">
+ <el-select v-model="queryParams.showType" placeholder="请选择显示类型" clearable size="small">
+ v-for="item in showTypeOptions"
+ v-hasPermi="['store:adv:add']"
+ v-hasPermi="['store:adv:edit']"
+ v-hasPermi="['store:adv:remove']"
+ <el-table height="500" border v-loading="loading" :data="advList" @selection-change="handleSelectionChange">
+ <el-table-column label="ID" align="center" prop="advId" />
+ <el-table-column label="广告标题" align="center" prop="advTitle" />
+ <el-table-column label="广告图片" align="center" width="120">
+ <el-popover
+ placement="right"
+ title=""
+ trigger="hover"
+ <img slot="reference" :src="scope.row.imageUrl" width="100">
+ <img :src="scope.row.imageUrl" style="max-width: 150px;">
+ </el-popover>
+ <el-table-column label="URL地址" show-overflow-tooltip align="center" prop="advUrl" />
+ <el-table-column label="广告位置" align="center" prop="advType">
+ <el-tag prop="advType" v-for="(item, index) in advTypeOptions" v-if="scope.row.advType==item.dictValue">{{item.dictLabel}}</el-tag>
+ <el-table-column label="显示方式" align="center" prop="showType">
+ <el-tag prop="showType" v-for="(item, index) in showTypeOptions" v-if="scope.row.showType==item.dictValue">{{item.dictLabel}}</el-tag>
+ <el-tag prop="status" v-for="(item, index) in statusOptions" v-if="scope.row.status==item.dictValue">{{item.dictLabel}}</el-tag>
+ <!-- 添加或修改广告对话框 -->
+ <el-dialog :title="title" :visible.sync="open" width="680px" append-to-body>
+ <el-form-item label="广告标题" prop="advTitle">
+ <el-input v-model="form.advTitle" placeholder="请输入广告标题" />
+ <el-form-item label="展示类型" prop="urlType">
+ <el-radio-group v-model="form.urlType">
+ <el-radio :label="1">图片</el-radio>
+ <el-radio :label="2">视频</el-radio>
+ <el-form-item label="广告图片" prop="imageUrl" v-if="form.urlType==1">
+ v-model="form.icon"
+ class="avatar-uploader"
+ :on-success="handleAvatarSuccess"
+ :before-upload="beforeAvatarUpload">
+ <img v-if="form.imageUrl" :src="form.imageUrl" class="avatar">
+ <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+ <el-form-item label="广告视频" prop="video" v-if="form.urlType==2">
+ ref="upload"
+ class="upload-demo"
+ :limit="1"
+ :accept="videoAccept"
+ <el-button size="small" type="primary">点击上传视频</el-button>
+ <video v-if="form.imageUrl" :src="form.imageUrl" controls style="max-width: 300px; max-height: 300px; margin-top: 10px"></video>
+ <el-radio-group v-model="form.advType">
+ <el-radio :label="item.dictValue" v-for="item in advTypeOptions" >{{item.dictLabel}}</el-radio>
+ <el-form-item label="显示方式" prop="showType" v-if="form.urlType==1">
+ <el-radio-group @change="showTypeChange" v-model="form.showType">
+ <el-radio :label="item.dictValue" v-for="item in showTypeOptions" >{{item.dictLabel}}</el-radio>
+ <el-form-item label="公众号链接" prop="advUrl" v-if="form.showType==1 && form.urlType==1 " >
+ <el-input v-model="form.advUrl" placeholder="请输入公众号链接" />
+ <el-form-item label="小程序地址" prop="advUrl" v-if="form.showType==2 && form.urlType==1 ">
+ <el-input v-model="form.advUrl" placeholder="请输入小程序地址" />
+ <el-form-item label="文章内容" v-if="form.showType==3 && form.urlType==1 ">
+ <editor ref="myeditor" @on-text-change="updateText" />
+ <el-radio :label="item.dictValue" v-for="item in statusOptions" >{{item.dictLabel}}</el-radio>
+ <el-input-number v-model="form.sort" :min="1" :max="99" ></el-input-number>
+import { listAdv, getAdv, delAdv, addAdv, updateAdv, exportAdv } from "@/api/hisStore/adv";
+import Editor from '@/components/Editor/wang';
+ name: "Adv",
+ Editor
+ baseUrl: process.env.VUE_APP_BASE_API,
+ videoAccept:"video/*",
+ advTypeOptions:[],
+ showTypeOptions:[],
+ // 广告表格数据
+ advList: [],
+ advTitle: null,
+ imageUrl: null,
+ advUrl: null,
+ advType: null,
+ showType: null
+ advTitle: [
+ { required: true, message: "广告标题不能为空", trigger: "blur" }
+ imageUrl: [
+ { required: true, message: "广告图不能为空", trigger: "blur" }
+ this.getDicts("common_status").then((response) => {
+ this.getDicts("adv_adv_type").then((response) => {
+ this.advTypeOptions = response.data;
+ this.getDicts("adv_show_type").then((response) => {
+ this.showTypeOptions = response.data;
+ handleSuccess(response, file) {
+ // 上传成功后的回调函数
+ this.myloading.close();
+ this.form.imageUrl = response.url;
+ this.$refs.upload.clearFiles();
+ // 上传前的钩子函数,可以在这里对文件进行处理
+ // 返回 false 则取消上传
+ // 例如限制文件大小
+ const isLt2M = file.size / 1024 / 1024 < 200;
+ if (!isLt2M) {
+ this.$message.error('上传视频文件大小不能超过 200MB!');
+ return false;
+ this.myloading = this.$loading({
+ text: '上传中',
+ showTypeChange(e){
+ console.log(e)
+ if(e==3){
+ this.$refs.myeditor.setText("");
+ }, 200);
+ updateText(text){
+ this.form.content=text
+ handleAvatarSuccess(res, file) {
+ this.form.imageUrl=res.url;
+ beforeAvatarUpload(file) {
+ const isLt1M = file.size / 1024 / 1024 < 200;
+ this.$message.error('上传图片大小不能超过 200MB!');
+ /** 查询广告列表 */
+ listAdv(this.queryParams).then(response => {
+ this.advList = response.rows;
+ advId: null,
+ urlType:1,
+ status: "1",
+ this.ids = selection.map(item => item.advId)
+ this.title = "添加广告";
+ const advId = row.advId || this.ids
+ var that=this;
+ getAdv(advId).then(response => {
+ this.form.advType = response.data.advType.toString();
+ this.form.showType = response.data.showType ? response.data.showType.toString() : "";
+ this.title = "修改广告";
+ if(this.form.showType=="3"){
+ console.log(that.form.content)
+ if(this.form.content==null){
+ that.$refs.myeditor.setText("");
+ that.$refs.myeditor.setText(that.form.content);
+ if (this.form.advId != null) {
+ updateAdv(this.form).then(response => {
+ addAdv(this.form).then(response => {
+ const advIds = row.advId || this.ids;
+ this.$confirm('是否确认删除广告编号为"' + advIds + '"的数据项?', "警告", {
+ return delAdv(advIds);
+ this.$confirm('是否确认导出所有广告数据项?', "警告", {
+ return exportAdv(queryParams);
+<style >
+ .avatar-uploader .el-upload {
+ border: 1px dashed #d9d9d9;
+ overflow: hidden;
+ .avatar-uploader .el-upload:hover {
+ border-color: #409EFF;
+ .avatar-uploader-icon {
+ font-size: 28px;
+ color: #8c939d;
+ width: 300px;
+ height: 150px;
+ line-height: 150px;
+ .avatar {
+ display: block;
@@ -0,0 +1,394 @@
+ <el-form-item label="公司名称" prop="name">
+ placeholder="请输入快递公司名称"
+ <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+ v-hasPermi="['store:express:add']"
+ v-hasPermi="['store:express:edit']"
+ v-hasPermi="['store:express:remove']"
+ <el-table height="500" border v-loading="loading" :data="expressList" @selection-change="handleSelectionChange">
+ <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" />
+ @click="handleAllot(scope.row)"
+ v-hasPermi="['store:express:allot']"
+ >分配公司</el-button>
+ <!-- 添加或修改快递公司对话框 -->
+ <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 label="快递公司全称" prop="name">
+ <el-input v-model="form.name" placeholder="请输入快递公司全称" />
+ <el-form-item label="OMS编号" prop="omsCode">
+ <el-input v-model="form.omsCode" placeholder="请输入快递公司简称" />
+ <el-input-number :min="0" v-model="form.sort" placeholder="请输入排序" />
+ <el-dialog :title="allot.title" :visible.sync="allot.open" width="1100px" append-to-body>
+ <el-transfer
+ width="960px"
+ :filter-method="filterMethod"
+ filter-placeholder="请输入公司名称"
+ v-model="value"
+ :titles="['所有公司', '已选公司']"
+ :right-default-checked="value"
+ :data="allCompanies">
+ </el-transfer>
+ <el-button type="primary" @click="handleAllotCompany">分 配</el-button>
+ <el-button @click="cancel1">取 消</el-button>
+import { listExpress, getExpress, delExpress, addExpress, updateExpress, exportExpress ,allotExpress ,getExpressList,getCompanyByOmsCode} from "@/api/hisStore/express";
+import { getCompanyList} from "@/api/company/company";
+ name: "Express",
+ formId:null,
+ value: [],
+ value2:[],
+ filterMethod(query, item) {
+ return item.label.indexOf(query) > -1;
+ allCompanies:undefined,
+ allot:{
+ title:"分配公司",
+ // 快递公司表格数据
+ expressList: [],
+ code: null,
+ isShow: null,
+ isDel: null
+ code: [
+ { required: true, message: "快递公司简称不能为空", trigger: "blur" }
+ omsCode: [
+ { required: true, message: "OMS编号不能为空", trigger: "blur" }
+ { required: true, message: "快递公司全称不能为空", trigger: "blur" }
+ isShow: [
+ { required: true, message: "是否显示不能为空", trigger: "blur" }
+ handleAllotCompany(){
+ console.log(this.value);
+ allotExpress(this.value,this.formId).then(response => {
+ this.allot.open = false;
+ /** 查询快递公司列表 */
+ listExpress(this.queryParams).then(response => {
+ this.expressList = response.rows;
+ cancel1() {
+ omsCode: null,
+ 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
+ getExpress(id).then(response => {
+ this.title = "修改快递公司";
+ updateExpress(this.form).then(response => {
+ addExpress(this.form).then(response => {
+ this.$confirm('是否确认删除快递公司编号为"' + ids + '"的数据项?', "警告", {
+ return delExpress(ids);
+ }).catch(function() {});
+ this.$confirm('是否确认导出所有快递公司数据项?', "警告", {
+ return exportExpress(queryParams);
+<style scoped lang="scss">
+.container {
+.box {
+.el-scrollbar {
+ max-height: 300px;
+ overflow-y: auto; /* 添加滚动条 */
+/* 新增样式 */
+ align-items: flex-start;
+ 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%;
@@ -0,0 +1,443 @@
+ v-hasPermi="['store:shippingTemplates:add']"
+ v-hasPermi="['store:shippingTemplates:edit']"
+ v-hasPermi="['store:shippingTemplates:remove']"
+ <el-table height="500" border v-loading="loading" :data="shippingTemplatesList" @selection-change="handleSelectionChange">
+ <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" >
+ <el-tag prop="type" v-for="(item, index) in typeOptions" v-if="scope.row.type==item.dictValue">{{item.dictLabel}}</el-tag>
+ <el-table-column label="指定包邮开关" align="center" prop="appoint" >
+ <el-tag prop="type" v-for="(item, index) in appointOptions" v-if="scope.row.appoint==item.dictValue">{{item.dictLabel}}</el-tag>
+ <el-table-column label="添加时间" align="center" prop="createTime" />
+ <!-- 添加或修改运费模板对话框 -->
+ <el-form-item label="模板名称" prop="name">
+ <el-input v-model="form.name" placeholder="请输入模板名称" />
+ <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-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24">
+ <el-form-item class="label" label="配送区域及运费:" props="state">
+ ref="table"
+ :data="templateList"
+ empty-text="暂无数据"
+ <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>
+ <span><el-input type="text" v-model="scope.row.first" /></span>
+ <el-table-column prop="price" label="运费(元)" width="110">
+ <span><el-input type="text" v-model="scope.row.price"/></span>
+ <el-table-column prop="_continue" label="续件" width="120">
+ <span v-if="form.type == 1">续件</span>
+ <span v-else-if="form.type == 2">续件重量(KG)</span>
+ <span v-else>续件体积(m³)</span>
+ <span><el-input type="text" v-model="scope.row.continues"/></span>
+ <el-table-column prop="continuePrice" label="续费(元)" width="110">
+ <span><el-input type="text" v-model="scope.row.continuePrice"/></span>
+ <el-table-column label="操作">
+ <a v-if="scope.row.regionName!=='默认全国'" @click="delCity(scope.row.index,1)">删除</a>
+ <el-row type="flex" class="addTop">
+ <el-col>
+ <el-button size="small" type="primary" icon="md-add" @click="addCity(1)">单独添加配送区域</el-button>
+ <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>
+ :data="appointList"
+ v-if="form.appoint === '1'"
+ <el-table-column prop="placeName" label="选择地区" />
+ <el-table-column prop="a_num" label="包邮件数" width="120" >
+ <span v-if="form.type == 1">包邮件数</span>
+ <span v-else-if="form.type == 2">包邮重量(KG)</span>
+ <span v-else>包邮体积(m³)</span>
+ <span><el-input type="text" v-model="scope.row.number"/></span>
+ <el-table-column prop="price" label="包邮金额(元)" width="120">
+ <a v-if="scope.row.regionName!=='默认全国'" @click="delCity(scope.row.index,2)">删除</a>
+ <el-row type="flex" v-if="form.appoint === '1'">
+ <el-button size="small" type="primary" icon="md-add" @click="addCity(2)">单独指定包邮</el-button>
+ <city ref="city" @selectCity="selectCity" :type="type"></city>
+import { listShippingTemplates, getShippingTemplates, delShippingTemplates, addShippingTemplates, updateShippingTemplates, exportShippingTemplates } from "@/api/hisStore/shippingTemplates";
+import City from '@/components/City'
+ name: "ShippingTemplates",
+ City
+ type:0,
+ appointList:[],
+ templateList:[],
+ appointOptions:[],
+ typeOptions:[],
+ // 运费模板表格数据
+ shippingTemplatesList: [],
+ regionInfo: null,
+ appoint: null,
+ appointInfo: null,
+ isDel: null,
+ sort: null
+ this.getDicts("store_shipping_type").then((response) => {
+ this.getDicts("store_shipping_appoint").then((response) => {
+ this.appointOptions = response.data;
+ delCity (index,type) {
+ console.log(index)
+ if (type === 1) {
+ this.templateList.splice(index, 1);
+ 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
+ // 单独添加配送区域
+ addCity (type) {
+ this.$refs.city.addressView = true;
+ this.type = type;
+ this.$refs.city.getCityList()
+ /** 查询运费模板列表 */
+ listShippingTemplates(this.queryParams).then(response => {
+ this.shippingTemplatesList = response.rows;
+ type: "1",
+ appoint: "0",
+ this.templateList = [
+ region: [
+ name: '默认全国',
+ cityId: 0
+ regionName: '默认全国',
+ ];
+ this.appointList=[],
+ this.title = "添加运费模板";
+ getShippingTemplates(id).then(response => {
+ 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.title = "修改运费模板";
+ this.form.regionInfo=this.templateList;
+ this.form.appointInfo=this.appointList;
+ updateShippingTemplates(this.form).then(response => {
+ addShippingTemplates(this.form).then(response => {
+ this.$confirm('是否确认删除运费模板编号为"' + ids + '"的数据项?', "警告", {
+ return delShippingTemplates(ids);
+ this.$confirm('是否确认导出所有运费模板数据项?', "警告", {
+ return exportShippingTemplates(queryParams);
@@ -0,0 +1,366 @@
+ <el-form-item label="模板ID" prop="tempId">
+ v-model="queryParams.tempId"
+ placeholder="请输入模板ID"
+ <el-form-item label="省ID" prop="provinceId">
+ v-model="queryParams.provinceId"
+ placeholder="请输入省ID"
+ <el-form-item label="城市ID" prop="cityId">
+ v-model="queryParams.cityId"
+ placeholder="请输入城市ID"
+ <el-form-item label="包邮件数" prop="number">
+ v-model="queryParams.number"
+ placeholder="请输入包邮件数"
+ <el-form-item label="包邮金额" prop="price">
+ v-model="queryParams.price"
+ placeholder="请输入包邮金额"
+ <el-select v-model="queryParams.type" placeholder="请选择计费方式" clearable size="small">
+ <el-option label="请选择字典生成" value="" />
+ <el-form-item label="产品ID" prop="productId">
+ v-model="queryParams.productId"
+ placeholder="请输入产品ID"
+ v-hasPermi="['store:shippingTemplatesFree:add']"
+ v-hasPermi="['store:shippingTemplatesFree:edit']"
+ v-hasPermi="['store:shippingTemplatesFree:remove']"
+ v-hasPermi="['store:shippingTemplatesFree:export']"
+ <el-table v-loading="loading" :data="shippingTemplatesFreeList" @selection-change="handleSelectionChange" border>
+ <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-input v-model="form.tempId" placeholder="请输入模板ID" />
+ <el-input v-model="form.provinceId" placeholder="请输入省ID" />
+ <el-input v-model="form.cityId" placeholder="请输入城市ID" />
+ <el-input v-model="form.number" placeholder="请输入包邮件数" />
+ <el-input v-model="form.price" placeholder="请输入包邮金额" />
+ <el-select v-model="form.type" placeholder="请选择计费方式">
+ <el-input v-model="form.productId" placeholder="请输入产品ID" />
+import { listShippingTemplatesFree, getShippingTemplatesFree, delShippingTemplatesFree, addShippingTemplatesFree, updateShippingTemplatesFree, exportShippingTemplatesFree } from "@/api/hisStore/shippingTemplatesFree";
+ name: "ShippingTemplatesFree",
+ // 免邮费表格数据
+ shippingTemplatesFreeList: [],
+ tempId: null,
+ provinceId: null,
+ cityId: null,
+ number: null,
+ price: null,
+ productId: null
+ 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" }
+ { required: true, message: "计费方式不能为空", trigger: "change" }
+ productId: [
+ { required: true, message: "产品ID不能为空", trigger: "blur" }
+ /** 查询免邮费列表 */
+ listShippingTemplatesFree(this.queryParams).then(response => {
+ this.shippingTemplatesFreeList = response.rows;
+ this.title = "添加免邮费";
+ getShippingTemplatesFree(id).then(response => {
+ this.title = "修改免邮费";
+ updateShippingTemplatesFree(this.form).then(response => {
+ addShippingTemplatesFree(this.form).then(response => {
+ this.$confirm('是否确认删除免邮费编号为"' + ids + '"的数据项?', "警告", {
+ return delShippingTemplatesFree(ids);
+ this.$confirm('是否确认导出所有免邮费数据项?', "警告", {
+ return exportShippingTemplatesFree(queryParams);
@@ -0,0 +1,402 @@
+ <el-form-item label="首件" prop="first">
+ v-model="queryParams.first"
+ placeholder="请输入首件"
+ <el-form-item label="首件运费" prop="firstPrice">
+ v-model="queryParams.firstPrice"
+ placeholder="请输入首件运费"
+ <el-form-item label="续件" prop="continues">
+ v-model="queryParams.continues"
+ placeholder="请输入续件"
+ <el-form-item label="续件运费" prop="continuePrice">
+ v-model="queryParams.continuePrice"
+ placeholder="请输入续件运费"
+ <el-form-item label="分组唯一值" prop="productId">
+ placeholder="请输入分组唯一值"
+ v-hasPermi="['store:shippingTemplatesRegion:add']"
+ v-hasPermi="['store:shippingTemplatesRegion:edit']"
+ v-hasPermi="['store:shippingTemplatesRegion:remove']"
+ v-hasPermi="['store:shippingTemplatesRegion:export']"
+ <el-table v-loading="loading" :data="shippingTemplatesRegionList" @selection-change="handleSelectionChange" border>
+ <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="productId" />
+ <!-- 添加或修改邮费区域对话框 -->
+ <el-input v-model="form.first" placeholder="请输入首件" />
+ <el-input v-model="form.firstPrice" placeholder="请输入首件运费" />
+ <el-input v-model="form.continues" placeholder="请输入续件" />
+ <el-input v-model="form.continuePrice" placeholder="请输入续件运费" />
+ <el-input v-model="form.productId" placeholder="请输入分组唯一值" />
+import { listShippingTemplatesRegion, getShippingTemplatesRegion, delShippingTemplatesRegion, addShippingTemplatesRegion, updateShippingTemplatesRegion, exportShippingTemplatesRegion } from "@/api/hisStore/shippingTemplatesRegion";
+ name: "ShippingTemplatesRegion",
+ // 邮费区域表格数据
+ shippingTemplatesRegionList: [],
+ first: null,
+ firstPrice: null,
+ continues: null,
+ continuePrice: null,
+ first: [
+ { required: true, message: "首件不能为空", trigger: "blur" }
+ firstPrice: [
+ { required: true, message: "首件运费不能为空", trigger: "blur" }
+ continues: [
+ { required: true, message: "续件不能为空", trigger: "blur" }
+ continuePrice: [
+ { required: true, message: "续件运费不能为空", trigger: "blur" }
+ { required: true, message: "分组唯一值不能为空", trigger: "blur" }
+ /** 查询邮费区域列表 */
+ listShippingTemplatesRegion(this.queryParams).then(response => {
+ this.shippingTemplatesRegionList = response.rows;
+ this.title = "添加邮费区域";
+ getShippingTemplatesRegion(id).then(response => {
+ this.title = "修改邮费区域";
+ updateShippingTemplatesRegion(this.form).then(response => {
+ addShippingTemplatesRegion(this.form).then(response => {
+ this.$confirm('是否确认删除邮费区域编号为"' + ids + '"的数据项?', "警告", {
+ return delShippingTemplatesRegion(ids);
+ this.$confirm('是否确认导出所有邮费区域数据项?', "警告", {
+ return exportShippingTemplatesRegion(queryParams);
@@ -88,7 +88,7 @@
<el-table-column label="地址" align="center" prop="address" width="200px"/>
<el-table-column label="店铺电话" align="center" prop="phone" width="120px"/>
- <el-table-column label="资质证书" align="center" prop="licenseImages" width="100px">
+<!-- <el-table-column label="资质证书" align="center" prop="licenseImages" width="100px">
<el-popover
placement="right"
@@ -98,7 +98,7 @@
<img :src="scope.row.licenseImages" style="max-width: 150px;">
</el-popover>
<el-table-column label="审核状态" align="center" prop="isAudit">
<dict-tag :options="isAuditOptions" :value="scope.row.isAudit"/>
@@ -121,6 +121,7 @@
+ icon="el-icon-s-promotion"
@click="handledetails(scope.row)"
<span v-if="scope.row.isAudit===0">审核</span>
@@ -121,8 +121,8 @@
title=""
trigger="hover">
- <img slot="reference" :src="scope.row.logoUrl" width="80px">
- <img :src="scope.row.logoUrl" style="max-width: 150px;">
+ <img slot="reference" :src="scope.row.logoUrl" width="80px" height="80px">
+ <img :src="scope.row.logoUrl" style="max-width: 160px;">
@@ -178,6 +178,7 @@
>详情
</el-button>
@@ -42,7 +42,7 @@
- <div class="botttombg companycard">
+ <div class="cardafter companycard">
<div class="card-title1">
<img src="../assets/images/tab_enterprise.png" alt="" class="icon-img">
企微数量
@@ -51,6 +51,17 @@
<count-to :start-val="0" :end-val="qwMemberNum" :duration="3600" class="card-panel-num companynumber" />
+ <div class="botttombg companycard">
+ <div class="card-title1">
+ <svg-icon icon-class="phone" />
+ pad使用情况
+ <div class="card-value highlight1">
+ <count-to :start-val="0" :end-val="padUsedNum" :duration="3600" class="card-panel-num companynumber" />
+ /
+ <count-to :start-val="0" :end-val="padTotalNum" :duration="1800" class="card-panel-num companynumber" />
@@ -218,6 +229,24 @@
<div class="action-group">
+ <!-- 选择部门 -->
+ <el-select v-model="deptId" placeholder="请选择部门" size="small" @change="handleDeptChange" style="width: 100px">
+ v-for="company in deptOptions"
+ :key="company.deptId"
+ :label="company.deptName"
+ :value="company.deptId"
+ <!-- 选择销售公司 -->
+ <el-select v-model="companyId" placeholder="请选择销售公司" size="small" clearable @change="handleCompanyChange" style="width: 180px" >
+ v-for="company in companyOptions"
+ :key="company.companyId"
+ :label="company.companyName"
+ :value="company.companyId"
<el-radio-group v-model="userTypeText" @change="handleUserType">
<el-radio-button label="会员"></el-radio-button>
<el-radio-button label="企微"></el-radio-button>
@@ -512,6 +541,8 @@ import {
watchCourseTopTen, watchEndPlayTrend
} from "@/api/statistics/statistics";
import dayjs from 'dayjs';
+import { listDept } from '@/api/system/dept'
+import { listCompany } from '@/api/his/company'
const viewCharOption = {
@@ -846,6 +877,11 @@ export default {
components: {CountTo},
+ deptOptions:[],
+ deptId:this.$store.state.user.deptId,
+ companyInitOptions:[],
+ companyOptions:[],
+ companyId:null,
percentage: 0,
// 预测message
remainMessage: '',
@@ -870,6 +906,10 @@ export default {
memberCount: 0,
// 企微数量
qwMemberNum: 0,
+ // pad使用情况
+ padTotalNum: 0,
+ padUsedNum: 0,
// 正常会员数量
normalNum: 0,
// 黑名单会员数量
@@ -942,8 +982,29 @@ export default {
this.refresh();
+ listDept().then(res => {
+ this.deptOptions = res.data;
+ listCompany().then(res => {
+ this.companyIntiOptions = res.rows;
+ this.companyOptions = this.companyIntiOptions.filter(item => item.deptId === this.deptId);
+ //首页统计选择部门、销售公司
+ handleDeptChange(){
+ this.companyId = null;
+ this.refresh();
+ handleCompanyChange(){
+ if(this.companyId){
+ this.deptId = this.companyOptions.filter(item => item.companyId === this.companyId)[0].deptId;
handleUserType(){
if(this.userTypeText === '会员'){
this.userType = 1
@@ -1082,6 +1143,9 @@ export default {
this.groupMgrCount = res.data.groupMgrCount??0;
this.memberCount = res.data.memberCount??0;
this.qwMemberNum = res.data.qwMemberNum??0;
+ this.padTotalNum = res.data.padTotalNum??0;
+ this.padUsedNum = res.data.padUsedNum??0;
+ this.padInfo = res.data.padInfo;
this.normalNum = res.data.normalNum??0;
this.blackNum = res.data.blackNum??0;
this.todayIncreaseUserNum = res.data.todayIncreaseUserNum??0;
@@ -0,0 +1,328 @@
+ <el-form-item label="指标名称" prop="indicatorName">
+ v-model="queryParams.indicatorName"
+ placeholder="请输入指标名称"
+ <el-form-item label="分类" prop="category">
+ <el-select v-model="queryParams.category" placeholder="请选择分类" clearable>
+ v-for="dict in categoryOptions"
+ :key="dict.value"
+ :label="dict.label"
+ :value="dict.value"
+ <el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
+ v-hasPermi="['medical:indicator:add']"
+ v-hasPermi="['medical:indicator:edit']"
+ v-hasPermi="['medical:indicator:remove']"
+ <el-table v-loading="loading" :data="indicatorList" @selection-change="handleSelectionChange">
+ <el-table-column label="指标ID" align="center" prop="indicatorId" />
+ <el-table-column label="指标名称" align="center" prop="indicatorName" />
+ <el-table-column label="指标代码" align="center" prop="indicatorCode" />
+ <el-table-column label="分类" align="center" prop="category">
+ <dict-tag :options="categoryOptions" :value="scope.row.category"/>
+ <el-table-column label="单位" align="center" prop="unit" />
+ <el-table-column label="正常范围" align="center" prop="normalRange" />
+ <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+ <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+ <!-- 添加或修改医疗指标对话框 -->
+ <el-input v-model="form.indicatorName" placeholder="请输入指标名称" />
+ <el-form-item label="指标代码" prop="indicatorCode">
+ <el-input v-model="form.indicatorCode" placeholder="请输入指标代码" />
+ <el-select v-model="form.category" placeholder="请选择分类">
+ <el-form-item label="单位" prop="unit">
+ <el-input v-model="form.unit" placeholder="请输入单位" />
+ <el-form-item label="正常范围" prop="normalRange">
+ <el-input v-model="form.normalRange" placeholder="请输入正常范围" />
+ <el-form-item label="描述" prop="description">
+ <el-input v-model="form.description" type="textarea" placeholder="请输入描述" />
+ :label="dict.value"
+ >{{dict.label}}</el-radio>
+import { listIndicator, getIndicator, delIndicator, addIndicator, updateIndicator } from "@/api/medical/indicator";
+ name: "Indicator",
+ // 医疗指标表格数据
+ indicatorList: [],
+ // 分类字典
+ categoryOptions: [],
+ indicatorName: null,
+ category: null,
+ status: null
+ indicatorName: [
+ { required: true, message: "指标名称不能为空", trigger: "blur" }
+ indicatorCode: [
+ { required: true, message: "指标代码不能为空", trigger: "blur" }
+ category: [
+ { required: true, message: "分类不能为空", trigger: "change" }
+ status: [
+ { required: true, message: "状态不能为空", trigger: "change" }
+ this.getDicts("indicator_category").then(response => {
+ this.categoryOptions = response.data;
+ this.getDicts("indicator_status").then(response => {
+ /** 查询医疗指标列表 */
+ listIndicator(this.queryParams).then(response => {
+ this.indicatorList = response.data.list;
+ indicatorId: null,
+ indicatorCode: null,
+ unit: null,
+ normalRange: null,
+ description: null,
+ status: "1"
+ this.ids = selection.map(item => item.indicatorId)
+ this.title = "添加医疗指标";
+ const indicatorId = row.indicatorId || this.ids
+ getIndicator(indicatorId).then(response => {
+ this.title = "修改医疗指标";
+ if (this.form.indicatorId != null) {
+ updateIndicator(this.form).then(response => {
+ addIndicator(this.form).then(response => {
+ const indicatorIds = row.indicatorId || this.ids;
+ this.$confirm('是否确认删除医疗指标编号为"' + indicatorIds + '"的数据项?').then(function() {
+ return delIndicator(indicatorIds);
@@ -0,0 +1,910 @@
+ <el-form-item label="体检日期" prop="examDate">
+ v-model="queryParams.examDate"
+ placeholder="请选择体检日期">
+ v-hasPermi="['medical:report:add']"
+ v-hasPermi="['medical:report:edit']"
+ v-hasPermi="['medical:report:remove']"
+ <el-table v-loading="loading" :data="reportList" @selection-change="handleSelectionChange">
+ <el-table-column label="报告ID" align="center" prop="reportId" />
+ <el-table-column label="用户" align="center" prop="userName" />
+ <el-table-column label="体检日期" align="center" prop="examDate" width="180">
+ <span>{{ parseTime(scope.row.examDate, '{y}-{m}-{d}') }}</span>
+ <el-table-column label="身高(cm)" align="center" prop="height" />
+ <el-table-column label="体重(kg)" align="center" prop="weight" />
+ <el-table-column label="BMI" align="center" prop="bmi" />
+ <el-table-column label="血压" align="center" prop="bloodPressure" />
+ <el-table-column label="心率" align="center" prop="heartRate" />
+ <!-- 添加或修改体检报告对话框 -->
+ <el-dialog :title="title" :visible.sync="open" width="1000px" append-to-body>
+ <el-tabs v-model="activeTab">
+ <el-tab-pane label="身体信息" name="bodyInfo">
+ <el-row :gutter="20">
+ <el-form-item label="用户名" prop="userName">
+ <el-input v-model="form.userName" placeholder="请输入用户名" />
+ <el-form-item label="销售ID" prop="companyUserId">
+ <el-input v-model="form.companyUserId" placeholder="请输入销售ID" />
+ <el-form-item label="销售名称" prop="companyUserName">
+ <el-input v-model="form.companyUserName" placeholder="请输入销售名称" />
+ v-model="form.examDate"
+ <el-form-item label="身高(cm)" prop="height">
+ <el-input v-model="form.height" placeholder="请输入身高" @input="calculateBMI" />
+ <el-form-item label="体重(kg)" prop="weight">
+ <el-input v-model="form.weight" placeholder="请输入体重" @input="calculateBMI" />
+ <el-form-item label="BMI指数" prop="bmi">
+ <el-input v-model="form.bmi" placeholder="BMI自动计算" disabled />
+ <el-form-item label="腰围(cm)" prop="waistCircumference">
+ <el-input v-model="form.waistCircumference" placeholder="请输入腰围" />
+ <el-form-item label="胸围(cm)" prop="chestCircumference">
+ <el-input v-model="form.chestCircumference" placeholder="请输入胸围" />
+ <el-form-item label="血压" prop="bloodPressure">
+ <el-input v-model="form.bloodPressure" placeholder="请输入血压" />
+ <el-form-item label="心率" prop="heartRate">
+ <el-input v-model="form.heartRate" placeholder="请输入心率" />
+ <el-tab-pane label="指标检查" name="indicators">
+ <div class="indicator-toolbar" style="margin-bottom: 15px;">
+ placeholder="搜索指标"
+ v-model="indicatorSearch"
+ style="width: 200px; margin-right: 10px;"
+ class="filter-item"
+ @keyup.enter.native="searchIndicators"
+ <el-button slot="append" icon="el-icon-search" @click="searchIndicators"></el-button>
+ v-model="indicatorCateId"
+ placeholder="选择指标分类"
+ style="width: 180px; margin-right: 10px;"
+ @change="handleIndicatorCateChange"
+ v-for="item in indicatorCateOptions"
+ :value="item.dictValue">
+ <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAddIndicator">添加指标</el-button>
+ <el-table :data="indicatorList" style="width: 100%" v-loading="indicatorLoading">
+ <el-table-column prop="indicatorName" label="指标名称" />
+ <el-table-column prop="testValue" label="检测值" />
+ <el-table-column prop="refRange" label="参考范围" />
+ <el-table-column label="结果评价" align="center">
+ <el-tag v-if="scope.row.isAbnormal === 0" type="success">正常</el-tag>
+ <el-tag v-else-if="scope.row.abnormalType === '偏高'" type="danger">偏高</el-tag>
+ <el-tag v-else-if="scope.row.abnormalType === '偏低'" type="warning">偏低</el-tag>
+ <el-tag v-else-if="scope.row.isAbnormal === 1" type="danger">异常</el-tag>
+ <span v-else>-</span>
+ <el-table-column label="操作" width="150">
+ <el-button type="text" size="small" @click="viewIndicatorDetail(scope.row)">查看详情</el-button>
+ <el-button type="text" size="small" @click="editIndicator(scope.row)">编辑</el-button>
+ <!-- 指标检查分页 -->
+ v-show="indicatorTotal > 0"
+ :total="indicatorTotal"
+ :page.sync="indicatorQueryParams.pageNum"
+ :limit.sync="indicatorQueryParams.pageSize"
+ @pagination="loadIndicators"
+ style="margin-top: 15px;"
+ <!-- 指标详情对话框 -->
+ <el-dialog title="指标详情" :visible.sync="indicatorDetailVisible" width="600px" append-to-body>
+ <el-descriptions :column="1" border>
+ <el-descriptions-item label="指标名称">{{ currentIndicator.indicatorName }}</el-descriptions-item>
+ <el-descriptions-item label="检测值">{{ currentIndicator.testValue || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="参考范围">{{ currentIndicator.refRange }}</el-descriptions-item>
+ <el-descriptions-item label="结果评价">
+ <el-tag v-if="currentIndicator.isAbnormal === 0" type="success">正常</el-tag>
+ <el-tag v-else-if="currentIndicator.abnormalType === '偏高'" type="danger">偏高</el-tag>
+ <el-tag v-else-if="currentIndicator.abnormalType === '偏低'" type="warning">偏低</el-tag>
+ <el-tag v-else-if="currentIndicator.isAbnormal === 1" type="danger">异常</el-tag>
+ </el-descriptions-item>
+ <el-descriptions-item label="备注说明">{{ currentIndicator.remarks || '-' }}</el-descriptions-item>
+ </el-descriptions>
+ <!-- 添加指标对话框 -->
+ <el-dialog title="添加指标" :visible.sync="indicatorSelectVisible" width="600px" append-to-body>
+ <div class="search-container" style="margin-bottom: 15px;">
+ placeholder="搜索指标库"
+ v-model="indicatorLibrarySearch"
+ style="width: 250px; margin-right: 10px;"
+ @keyup.enter.native="searchIndicatorLibrary"
+ <el-button slot="append" icon="el-icon-search" @click="searchIndicatorLibrary"></el-button>
+ <el-select v-model="indicatorCategory" placeholder="选择分类" style="width: 150px;">
+ v-for="item in indicatorCategoryOptions"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value">
+ :data="indicatorLibrary"
+ height="350px"
+ @selection-change="handleIndicatorSelectionChange">
+ <el-table-column type="selection" width="55" />
+ <el-table-column prop="indicatorCategory" label="分类" />
+ <el-table-column label="参考范围" align="center">
+ {{ formatReferenceRange(scope.row) }}
+ <el-table-column prop="description" label="描述" />
+ <div style="margin-top: 15px;">
+ @size-change="handleSizeChange"
+ @current-change="handleCurrentChange"
+ :current-page="currentPage"
+ :page-sizes="[10, 20, 50, 100]"
+ :page-size="pageSize"
+ :total="totalIndicators">
+ </el-pagination>
+ <el-button type="primary" @click="addSelectedIndicators">添加所选指标</el-button>
+ <el-button @click="indicatorSelectVisible = false">取 消</el-button>
+ <!-- 编辑指标结果对话框 -->
+ <el-dialog title="编辑指标结果" :visible.sync="indicatorResultDialogVisible" width="500px" append-to-body>
+ <el-form ref="indicatorResultForm" :model="indicatorResultForm" :rules="indicatorResultRules" label-width="100px">
+ <el-form-item label="指标名称">
+ <span>{{ indicatorResultForm.indicatorName }}</span>
+ <el-form-item label="参考范围">
+ <span>{{ indicatorResultForm.referenceRange }}</span>
+ <el-form-item label="检查数值" prop="testValue">
+ <el-input v-model="indicatorResultForm.testValue" placeholder="请输入检查数值" />
+ <el-form-item label="检查结果" prop="testResult">
+ <el-input v-model="indicatorResultForm.testResult" placeholder="请输入检查结果(文本)" />
+ <el-form-item label="是否异常">
+ <el-radio-group v-model="indicatorResultForm.isAbnormal">
+ <el-radio :label="0">正常</el-radio>
+ <el-radio :label="1">异常</el-radio>
+ <el-form-item label="异常类型" v-if="indicatorResultForm.isAbnormal === 1" prop="abnormalType">
+ <el-select v-model="indicatorResultForm.abnormalType" placeholder="请选择异常类型">
+ <el-option label="偏高" value="偏高" />
+ <el-option label="偏低" value="偏低" />
+ <el-option label="其他" value="其他" />
+ <el-form-item label="备注说明" prop="remarks">
+ <el-input v-model="indicatorResultForm.remarks" type="textarea" rows="3" placeholder="请输入备注说明" />
+ <el-button type="primary" @click="submitIndicatorResult">确 定</el-button>
+ <el-button @click="indicatorResultDialogVisible = false">取 消</el-button>
+import { listReport, getReport, delReport, addReport, updateReport } from "@/api/medical/report";
+import { parseTime } from "@/utils/common";
+import { getDicts } from "@/api/system/dict/data";
+ name: "Report",
+ // 体检报告表格数据
+ reportList: [],
+ indicatorCateId: '', // 选中的指标分类ID
+ indicatorCateOptions: [], // 指标分类选项列表
+ // 当前激活的tab页
+ activeTab: 'bodyInfo',
+ examDate: null
+ examDate: [
+ { required: true, message: "体检日期不能为空", trigger: "blur" }
+ // 指标搜索
+ indicatorSearch: '',
+ // 指标列表
+ // 肝功能列表
+ liverFunctionList: [],
+ // 指标详情对话框可见性
+ indicatorDetailVisible: false,
+ // 当前查看的指标
+ currentIndicator: {},
+ // 指标选择对话框可见性
+ indicatorSelectVisible: false,
+ // 指标库搜索
+ indicatorLibrarySearch: '',
+ // 指标分类
+ indicatorCategory: '',
+ // 指标分类选项
+ indicatorCategoryOptions: [
+ { value: '', label: '全部' },
+ { value: '肝脏', label: '肝脏' },
+ { value: '血常规', label: '血常规' },
+ { value: '尿常规', label: '尿常规' },
+ { value: '心脏', label: '心脏' },
+ { value: '肾功能', label: '肾功能' },
+ { value: '血脂', label: '血脂' },
+ { value: '其他', label: '其他' }
+ // 指标库数据
+ indicatorLibrary: [],
+ // 选中的指标
+ selectedIndicators: [],
+ // 分页
+ currentPage: 1,
+ totalIndicators: 0,
+ // 指标结果对话框可见性
+ indicatorResultDialogVisible: false,
+ // 指标结果表单
+ indicatorResultForm: {
+ resultId: null,
+ indicatorName: '',
+ referenceRange: '',
+ testValue: '',
+ testResult: '',
+ isAbnormal: 0,
+ abnormalType: '',
+ remarks: ''
+ // 指标结果表单校验规则
+ indicatorResultRules: {
+ testValue: [
+ { required: true, message: "检查数值不能为空", trigger: "blur" }
+ testResult: [
+ { required: true, message: "检查结果不能为空", trigger: "blur" }
+ abnormalType: [
+ { required: true, message: "异常类型不能为空", trigger: "blur" }
+ // 指标检查分页参数
+ indicatorQueryParams: {
+ reportId: null, // 报告ID
+ indicatorName: '', // 指标名称
+ indicatorCateId: '', // 指标分类ID
+ isAbnormal: null // 是否异常
+ // 指标检查加载状态
+ indicatorLoading: false,
+ // 指标检查总条数
+ indicatorTotal: 0
+ this.loadIndicatorCateDict(); // 加载指标分类字典
+ * 加载指标分类字典数据
+ loadIndicatorCateDict() {
+ getDicts('user_custom_type').then(response => {
+ this.indicatorCateOptions = response.data || [];
+ console.log('指标分类字典加载成功:', this.indicatorCateOptions);
+ console.error("加载指标分类字典失败", error);
+ this.$message.error("加载指标分类字典失败");
+ /** 查询体检报告列表 */
+ listReport(this.queryParams).then(response => {
+ this.reportList = response.data.list;
+ reportId: null,
+ companyUserName: null,
+ examDate: null,
+ height: null,
+ weight: null,
+ bmi: null,
+ waistCircumference: null,
+ chestCircumference: null,
+ bloodPressure: null,
+ heartRate: null,
+ generalCondition: null,
+ skinAndMucosa: null,
+ lymphNodes: null,
+ head: null,
+ neck: null,
+ chest: null,
+ heart: null,
+ lungs: null,
+ abdomen: null,
+ examResult: null,
+ doctorAdvice: null
+ // 重置指标列表
+ this.indicatorList = [];
+ this.liverFunctionList = [];
+ // 重置当前tab
+ this.activeTab = 'bodyInfo';
+ // 重置指标查询参数
+ this.indicatorQueryParams = {
+ indicatorCateId: '',
+ isAbnormal: null
+ this.indicatorSearch = '';
+ this.indicatorCateId = '';
+ this.indicatorTotal = 0;
+ // 搜索指标
+ searchIndicators() {
+ if (!this.form.reportId) {
+ // 重置到第一页
+ this.indicatorQueryParams.pageNum = 1;
+ this.indicatorQueryParams.reportId = this.form.reportId;
+ this.loadIndicators(this.form.reportId);
+ * 指标分类筛选变化处理
+ handleIndicatorCateChange(value) {
+ this.indicatorCateId = value;
+ this.searchIndicators();
+ this.ids = selection.map(item => item.reportId)
+ this.title = "添加体检报告";
+ const reportId = row.reportId || this.ids
+ getReport(reportId).then(response => {
+ this.title = "修改体检报告";
+ // 设置指标查询参数
+ this.indicatorQueryParams.reportId = reportId;
+ // 获取指标数据
+ this.loadIndicators(reportId);
+ // 获取肝功能数据
+ this.loadLiverFunction(reportId);
+ if (this.form.reportId != null) {
+ updateReport(this.form).then(response => {
+ addReport(this.form).then(response => {
+ const reportIds = row.reportId || this.ids;
+ this.$confirm('是否确认删除体检报告编号为"' + reportIds + '"的数据项?').then(function() {
+ return delReport(reportIds);
+ // 自动计算BMI
+ calculateBMI() {
+ if (this.form.height && this.form.weight) {
+ const height = parseFloat(this.form.height) / 100; // 转换为米
+ const weight = parseFloat(this.form.weight);
+ if (height > 0 && weight > 0) {
+ this.form.bmi = (weight / (height * height)).toFixed(2);
+ // 加载指标数据
+ loadIndicators(reportId) {
+ this.indicatorLoading = true; // 开始加载
+ // 如果有reportId参数,更新查询参数
+ if (reportId) {
+ // 调用API从后端获取报告相关的指标检查结果
+ return import('@/api/medical/reportIndicator').then(module => {
+ const { listResult } = module;
+ const query = {
+ reportId: this.indicatorQueryParams.reportId,
+ pageNum: this.indicatorQueryParams.pageNum,
+ pageSize: this.indicatorQueryParams.pageSize,
+ indicatorName: this.indicatorSearch || undefined,
+ indicatorCateId: this.indicatorCateId || undefined,
+ isAbnormal: this.indicatorQueryParams.isAbnormal || undefined
+ return listResult(query).then(response => {
+ this.indicatorTotal = response.data.total;
+ this.indicatorLoading = false; // 结束加载
+ return this.indicatorList; // 返回过滤后的数据
+ console.error("加载指标数据失败", error);
+ this.$message.error("加载指标数据失败");
+ throw error; // 重新抛出错误
+ // 加载肝功能数据
+ loadLiverFunction(reportId) {
+ // 调用API从后端获取报告相关的肝功能检查结果
+ reportId: reportId,
+ pageSize: 1000 // 获取足够多的数据
+ // 过滤出肝功能相关的指标
+ this.liverFunctionList = response.data.list.filter(item => item.category === '肝脏' || item.indicatorCategory === '肝脏');
+ return this.liverFunctionList; // 返回过滤后的数据
+ console.error("加载肝功能数据失败", error);
+ this.$message.error("加载肝功能数据失败");
+ * 重置指标筛选条件
+ resetIndicatorFilter() {
+ // 查看指标详情
+ viewIndicatorDetail(indicator) {
+ this.currentIndicator = indicator;
+ this.indicatorDetailVisible = true;
+ // 添加指标
+ handleAddIndicator() {
+ this.$message.warning("请先保存体检报告,再添加指标");
+ // 加载指标库数据
+ this.searchIndicatorLibrary();
+ this.indicatorSelectVisible = true;
+ // 搜索指标库
+ searchIndicatorLibrary() {
+ // 构建查询参数
+ pageNum: this.currentPage,
+ pageSize: this.pageSize,
+ indicatorName: this.indicatorLibrarySearch || undefined,
+ indicatorCategory: this.indicatorCategory || undefined
+ // 调用API查询指标库
+ import('@/api/medical/indicator').then(module => {
+ const { listIndicator } = module;
+ listIndicator(query).then(response => {
+ this.indicatorLibrary = response.data.list;
+ this.totalIndicators = response.data.total;
+ console.error("搜索指标库失败", error);
+ this.$message.error("搜索指标库失败");
+ // 分页大小变化
+ handleSizeChange(val) {
+ this.pageSize = val;
+ // 分页页码变化
+ handleCurrentChange(val) {
+ this.currentPage = val;
+ // 指标选择变化
+ handleIndicatorSelectionChange(selection) {
+ this.selectedIndicators = selection;
+ // 添加选中的指标
+ addSelectedIndicators() {
+ if (this.selectedIndicators.length === 0) {
+ this.$message.warning("请至少选择一个指标");
+ // 准备批量添加的数据
+ const batchData = this.selectedIndicators.map(item => ({
+ reportId: this.form.reportId,
+ indicatorId: item.indicatorId,
+ testValue: null,
+ testResult: null,
+ abnormalType: null,
+ remarks: null
+ // 调用API批量添加指标结果
+ import('@/api/medical/reportIndicator').then(module => {
+ const { batchAddResult } = module;
+ batchAddResult(batchData).then(() => {
+ this.$message.success("添加指标成功");
+ this.indicatorSelectVisible = false;
+ // 重新加载指标数据
+ this.loadIndicators();
+ // 重新加载肝功能数据
+ this.loadLiverFunction(this.form.reportId);
+ console.error("添加指标失败", error);
+ this.$message.error("添加指标失败");
+ // 格式化参考范围
+ formatReferenceRange(indicator) {
+ if (indicator.referenceText) {
+ return indicator.referenceText;
+ } else if (indicator.referenceMin !== null && indicator.referenceMax !== null) {
+ return `${indicator.referenceMin}-${indicator.referenceMax}`;
+ } else if (indicator.referenceMin !== null) {
+ return `>${indicator.referenceMin}`;
+ } else if (indicator.referenceMax !== null) {
+ return `<${indicator.referenceMax}`;
+ return '无参考范围';
+ // 编辑指标结果
+ editIndicator(indicator) {
+ this.indicatorResultForm = {
+ resultId: indicator.resultId,
+ indicatorName: indicator.indicatorName || indicator.name,
+ referenceRange: indicator.refRange || '',
+ testValue: indicator.testValue || '',
+ testResult: indicator.testResult || '',
+ isAbnormal: indicator.isAbnormal || 0,
+ abnormalType: indicator.abnormalType || '',
+ remarks: indicator.remarks || ''
+ this.indicatorResultDialogVisible = true;
+ // 提交指标结果
+ submitIndicatorResult() {
+ this.$refs.indicatorResultForm.validate(valid => {
+ // 调用API更新指标结果
+ const { updateResult } = module;
+ resultId: this.indicatorResultForm.resultId,
+ testValue: this.indicatorResultForm.testValue,
+ testResult: this.indicatorResultForm.testResult,
+ isAbnormal: this.indicatorResultForm.isAbnormal,
+ abnormalType: this.indicatorResultForm.abnormalType,
+ remarks: this.indicatorResultForm.remarks
+ updateResult(data).then(() => {
+ this.$message.success("更新指标结果成功");
+ this.indicatorResultDialogVisible = false;
+ console.error("更新指标结果失败", error);
+ this.$message.error("更新指标结果失败");
@@ -0,0 +1,468 @@
+ <el-form-item label="报告ID" prop="reportId">
+ v-model="queryParams.reportId"
+ placeholder="请输入报告ID"
+ <el-form-item label="指标ID" prop="indicatorId">
+ v-model="queryParams.indicatorId"
+ placeholder="请输入指标ID"
+ v-hasPermi="['medical:result:add']"
+ @click="handleBatchAdd"
+ >批量新增</el-button>
+ <el-table v-loading="loading" :data="resultList" @selection-change="handleSelectionChange">
+ <el-table-column label="结果ID" align="center" prop="resultId" />
+ <el-table-column label="检查结果" align="center" prop="resultValue" />
+ <el-table-column label="参考范围" align="center" prop="referenceRange" />
+ <el-table-column label="异常标识" align="center" prop="abnormalFlag">
+ <dict-tag :options="abnormalFlagOptions" :value="scope.row.abnormalFlag"/>
+ icon="el-icon-view"
+ @click="handleDetail(scope.row)"
+ v-hasPermi="['medical:result:query']"
+ >详情</el-button>
+ v-hasPermi="['medical:result:edit']"
+ v-hasPermi="['medical:result:remove']"
+ <!-- 添加或修改报告指标检查结果对话框 -->
+ <el-input v-model="form.reportId" placeholder="请输入报告ID" />
+ <el-input v-model="form.indicatorId" placeholder="请输入指标ID" />
+ <el-form-item label="检查结果" prop="resultValue">
+ <el-input v-model="form.resultValue" placeholder="请输入检查结果" />
+ <el-form-item label="参考范围" prop="referenceRange">
+ <el-input v-model="form.referenceRange" placeholder="请输入参考范围" />
+ <el-form-item label="异常标识" prop="abnormalFlag">
+ <el-select v-model="form.abnormalFlag" placeholder="请选择异常标识">
+ v-for="dict in abnormalFlagOptions"
+ <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
+ <!-- 批量新增对话框 -->
+ <el-dialog title="批量新增检查结果" :visible.sync="batchOpen" width="800px" append-to-body>
+ <el-form ref="batchForm" :model="batchForm" label-width="80px">
+ <el-input v-model="batchForm.reportId" placeholder="请输入报告ID" />
+ <el-button type="primary" size="mini" @click="addBatchRow">添加行</el-button>
+ <el-table :data="batchForm.results" style="margin-top: 10px;">
+ <el-table-column label="指标ID" width="100">
+ <el-input v-model="scope.row.indicatorId" size="mini" />
+ <el-table-column label="指标名称" width="120">
+ <el-input v-model="scope.row.indicatorName" size="mini" />
+ <el-table-column label="检查结果" width="100">
+ <el-input v-model="scope.row.resultValue" size="mini" />
+ <el-table-column label="参考范围" width="120">
+ <el-input v-model="scope.row.referenceRange" size="mini" />
+ <el-table-column label="单位" width="80">
+ <el-input v-model="scope.row.unit" size="mini" />
+ <el-table-column label="异常标识" width="100">
+ <el-select v-model="scope.row.abnormalFlag" size="mini">
+ <el-table-column label="操作" width="80">
+ <el-button type="text" size="mini" @click="removeBatchRow(scope.$index)">删除</el-button>
+ <el-button type="primary" @click="submitBatchForm">确 定</el-button>
+ <el-button @click="cancelBatch">取 消</el-button>
+ <!-- 详情对话框 -->
+ <el-dialog title="检查结果详情" :visible.sync="detailOpen" width="500px" append-to-body>
+ <el-descriptions :column="2" border>
+ <el-descriptions-item label="结果ID">{{ detailData.resultId }}</el-descriptions-item>
+ <el-descriptions-item label="报告ID">{{ detailData.reportId }}</el-descriptions-item>
+ <el-descriptions-item label="指标ID">{{ detailData.indicatorId }}</el-descriptions-item>
+ <el-descriptions-item label="指标名称">{{ detailData.indicatorName }}</el-descriptions-item>
+ <el-descriptions-item label="检查结果">{{ detailData.resultValue }}</el-descriptions-item>
+ <el-descriptions-item label="参考范围">{{ detailData.referenceRange }}</el-descriptions-item>
+ <el-descriptions-item label="单位">{{ detailData.unit }}</el-descriptions-item>
+ <el-descriptions-item label="异常标识">
+ <dict-tag :options="abnormalFlagOptions" :value="detailData.abnormalFlag"/>
+ <el-descriptions-item label="创建时间" :span="2">
+ {{ parseTime(detailData.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
+ <el-descriptions-item label="备注" :span="2">{{ detailData.remark }}</el-descriptions-item>
+ <el-button @click="detailOpen = false">关 闭</el-button>
+import { listResult, getResult, delResult, addResult, updateResult, batchAddResult, listByReportId, listByIndicatorId } from "@/api/medical/reportIndicator";
+ name: "Result",
+ // 报告指标检查结果表格数据
+ resultList: [],
+ // 是否显示批量新增弹出层
+ batchOpen: false,
+ // 是否显示详情弹出层
+ detailOpen: false,
+ // 详情数据
+ // 异常标识字典
+ abnormalFlagOptions: [],
+ // 批量表单参数
+ batchForm: {
+ results: [] },
+ // 表单校验规则
+ reportId: [{ required: true, message: '请输入报告ID', trigger: 'blur' }],
+ indicatorId: [{ required: true, message: '请输入指标ID', trigger: 'blur' }],
+ indicatorName: [{ required: true, message: '请输入指标名称', trigger: 'blur' }],
+ resultValue: [{ required: true, message: '请输入检查结果', trigger: 'blur' }],
+ referenceRange: [{ required: true, message: '请输入参考范围', trigger: 'blur' }],
+ unit: [{ required: true, message: '请输入单位', trigger: 'blur' }],
+ abnormalFlag: [{ required: true, message: '请选择异常标识', trigger: 'change' }],
+ this.loadDictData();
+ // 加载异常标识字典数据
+ loadDictData() {
+ // 这里模拟加载字典数据,实际可以根据项目字典接口替换
+ this.abnormalFlagOptions = [
+ { label: '正常', value: '0' },
+ { label: '异常', value: '1' }
+ // 查询列表
+ listResult(this.queryParams).then((res) => {
+ if (res && res.data) {
+ this.resultList = res.data.list;
+ this.total = res.data.total;
+ // 重置搜索条件
+ // 处理查询按钮点击
+ // 选择项变化
+ this.ids = selection.map(item => item.resultId);
+ this.single = this.ids.length !== 1;
+ this.multiple = this.ids.length === 0;
+ // 打开新增弹窗
+ this.title = "新增检查结果";
+ this.form = {};
+ if (this.$refs.form) {
+ this.$refs.form.resetFields();
+ // 打开批量新增弹窗
+ handleBatchAdd() {
+ this.batchForm = {
+ results: []
+ this.batchOpen = true;
+ // 添加批量新增表格行
+ addBatchRow() {
+ this.batchForm.results.push({
+ indicatorId: '',
+ resultValue: '',
+ unit: '',
+ abnormalFlag: '0'
+ // 删除批量新增表格行
+ removeBatchRow(index) {
+ this.batchForm.results.splice(index, 1);
+ // 取消批量新增
+ cancelBatch() {
+ this.batchOpen = false;
+ // 提交批量新增表单
+ submitBatchForm() {
+ if (!this.batchForm.reportId) {
+ this.$message.error('请输入报告ID');
+ if (this.batchForm.results.length === 0) {
+ this.$message.error('请添加检查结果行');
+ // 给每个结果设置报告ID
+ this.batchForm.results.forEach(item => {
+ item.reportId = this.batchForm.reportId;
+ batchAddResult(this.batchForm.results).then(res => {
+ if (res.code === 200) {
+ this.$message.success(res.msg || '批量新增成功');
+ this.$message.error(res.msg || '批量新增失败');
+ // 提交新增或修改表单
+ this.$refs.form.validate((valid) => {
+ if (this.form.resultId) {
+ updateResult(this.form).then(res => {
+ this.$message.success(res.msg || '更新成功');
+ this.$message.error(res.msg || '更新失败');
+ addResult(this.form).then(res => {
+ this.$message.success(res.msg || '新增成功');
+ this.$message.error(res.msg || '新增失败');
+ // 取消新增或修改
+ // 查看详情
+ handleDetail(row) {
+ getResult(row.resultId).then(res => {
+ this.detailData = res.data;
+ this.detailOpen = true;
+ this.$message.error(res.msg || '获取详情失败');
+ // 修改
+ this.title = "修改检查结果";
+ this.form = Object.assign({}, row);
+ this.$refs.form.clearValidate();
+ // 删除
+ this.$confirm('确定删除该检查结果吗?', '提示', {
+ delResult(row.resultId).then(res => {
+ this.$message.success(res.msg || '删除成功');
+ this.$message.error(res.msg || '删除失败');
@@ -0,0 +1,300 @@
+ <el-form-item label="单位名称" prop="unitName">
+ v-model="queryParams.unitName"
+ placeholder="请输入单位名称"
+ <el-form-item label="单位类型" prop="unitType">
+ <el-select v-model="queryParams.unitType" placeholder="请选择单位类型" clearable>
+ v-for="dict in unitTypeOptions"
+ v-hasPermi="['medical:unit:add']"
+ v-hasPermi="['medical:unit:edit']"
+ v-hasPermi="['medical:unit:remove']"
+ <el-table v-loading="loading" :data="unitList" @selection-change="handleSelectionChange">
+ <el-table-column label="单位ID" align="center" prop="unitId" />
+ <el-table-column label="单位名称" align="center" prop="unitName" />
+ <el-table-column label="单位符号" align="center" prop="unitSymbol" />
+ <el-table-column label="单位类型" align="center" prop="unitType">
+ <dict-tag :options="unitTypeOptions" :value="scope.row.unitType"/>
+ <!-- 添加或修改计量单位对话框 -->
+ <el-input v-model="form.unitName" placeholder="请输入单位名称" />
+ <el-select v-model="form.unitType" placeholder="请选择单位类型">
+ <el-form-item label="单位符号" prop="unitSymbol">
+ <el-input v-model="form.unitSymbol" placeholder="请输入单位符号" />
+ <el-form-item label="备注" prop="description">
+ <el-input v-model="form.description" type="textarea" placeholder="请输入备注" />
+ <el-select v-model="form.status" placeholder="请选择状态">
+ :value="parseInt(dict.value)"
+import { listUnit, getUnit, addUnit, updateUnit, delUnit } from "@/api/medical/unit";
+ name: "Unit",
+ // 计量单位表格数据
+ unitList: [],
+ // 单位类型字典
+ unitTypeOptions: [],
+ unitName: null,
+ unitType: null
+ unitName: [
+ { required: true, message: "单位名称不能为空", trigger: "blur" }
+ unitType: [
+ { required: true, message: "单位类型不能为空", trigger: "change" }
+ this.getDicts("unit_type").then(response => {
+ this.unitTypeOptions = response.data;
+ this.getDicts("sys_normal_disable").then(response => {
+ /** 查询计量单位列表 */
+ listUnit(this.queryParams).then(response => {
+ this.unitList = response.data.list;
+ unitId: null,
+ unitType: null,
+ unitSymbol: null,
+ status: 1
+ this.ids = selection.map(item => item.unitId);
+ this.single = selection.length !== 1;
+ this.multiple = !selection.length;
+ this.title = "添加计量单位";
+ const unitId = row.unitId || this.ids[0];
+ getUnit(unitId).then(response => {
+ this.title = "修改计量单位";
+ if (this.form.unitId != null) {
+ updateUnit(this.form).then(response => {
+ addUnit(this.form).then(response => {
+ const unitIds = row.unitId || this.ids;
+ this.$confirm('是否确认删除计量单位编号为"' + unitIds + '"的数据项?').then(function() {
+ return delUnit(unitIds);
@@ -222,6 +222,17 @@
v-hasPermi="['qw:externalContact:export']"
+ :loading="exportUnionidLoading"
+ @click="handleExportUnionId"
+ v-hasPermi="['qw:externalContact:export']"
+ >导出unionid</el-button>
@@ -402,7 +413,7 @@
-import { listExternalContact, getExternalContact, delExternalContact, addExternalContact, updateExternalContact, exportExternalContact } from "@/api/qw/externalContact";
+import { listExternalContact, getExternalContact, delExternalContact, addExternalContact, updateExternalContact, exportExternalContact, exportUnionId } from "@/api/qw/externalContact";
import {getCompanyList} from "@/api/company/company";
import {getAllUserlist} from "@/api/company/companyUser";
import {getQwUserInfo} from "@/api/qw/qwUser";
@@ -420,6 +431,7 @@ export default {
loading: false,
+ exportUnionidLoading: false,
//等级状态
ratingUpFall: [],
// 性别字典
@@ -908,7 +920,29 @@ export default {
+ /** 导出Unionid按钮操作 */
+ handleExportUnionId() {
+ //验证是否选择企业
+ if(!this.queryParams.companyId){
+ return this.$message.warning({
+ message: "请先选择企业!",
+ duration: 3000
+ this.$confirm('是否确认导出所有企业微信客户unionid数据项?', "警告", {
+ this.exportUnionidLoading = true;
+ return exportUnionId(queryParams);
+ this.exportUnionidLoading = false;
</script>
@@ -174,9 +174,12 @@
<el-form-item label="应用回调地接" prop="notifyUrl" >
<el-input v-model="form.notifyUrl" placeholder="请输入应用回调地接" :readonly="true"/>
- <el-form-item label="应用id" prop="serverAgentId" >
- <el-input v-model="form.serverAgentId" placeholder="请输入serverAgentId" />
+ <el-form-item label="应用id" prop="serverAgentId" >
+ <el-input v-model="form.serverAgentId" placeholder="请输入serverAgentId" />
+ <el-form-item label="小程序id" prop="miniAppId" >
+ <el-input v-model="form.miniAppId" placeholder="请输入小程序id" />
<el-form-item label="企业可信IP" >
<div>42.194.245.189;119.29.195.254;129.204.130.233;43.138.187.210;129.204.76.229;159.75.239.132119.29.249.66;122.152.230.82</div>
@@ -595,6 +595,9 @@ export default {
this.title = "修改";
+ if(response.data.project){
+ this.form.project = String(response.data.project)
@@ -728,7 +728,7 @@ export default {
dayList: [],
ruleList: [],
ids: [],
- courseTypeList: ['3', '4', '9'],
+ courseTypeList: ['1','3', '4', '9'],
sysFsSopWatchStatus: [],
//消息内容类型 企微版
sysQwSopContentType: [],