1、迁移商城订单权限等代码

2、vuex升级兼容pinia
3、增加stylus支持
This commit is contained in:
cuiyouliang 2025-06-03 11:53:46 +08:00
parent d5e618489e
commit e895946567
84 changed files with 12975 additions and 2 deletions

View File

@ -20,6 +20,7 @@
"url": "https://gitee.com/JavaLionLi/plus-ui.git"
},
"dependencies": {
"@riophae/vue-treeselect": "0.4.0",
"@element-plus/icons-vue": "2.3.1",
"@highlightjs/vue-plugin": "2.1.0",
"@tencentcloud/chat": "^3.5.5",
@ -80,7 +81,9 @@
"vite-plugin-svg-icons-ng": "^1.4.0",
"vite-plugin-vue-devtools": "7.7.5",
"vitest": "3.1.2",
"vue-tsc": "^2.2.8"
"vue-tsc": "^2.2.8",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.2"
},
"overrides": {
"quill": "2.0.2"

View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
// 查询优惠券活动表列表
export function listCouponActivity(query, pageReq) {
return request({
url: '/act/couponActivity/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询优惠券活动表详细
export function getCouponActivity(id) {
return request({
url: '/act/couponActivity/' + id,
method: 'get'
})
}
// 新增优惠券活动表
export function addCouponActivity(data) {
return request({
url: '/act/couponActivity',
method: 'post',
data: data
})
}
// 修改优惠券活动表
export function updateCouponActivity(data) {
return request({
url: '/act/couponActivity',
method: 'put',
data: data
})
}
// 删除优惠券活动表
export function delCouponActivity(id) {
return request({
url: '/act/couponActivity/' + id,
method: 'delete'
})
}
// 导出优惠券活动表
export function exportCouponActivity(query) {
return request({
url: '/act/couponActivity/export',
method: 'get',
params: query
})
}

View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
// 查询用户领券记录列表
export function listMemberCoupon(query, pageReq) {
return request({
url: '/act/memberCoupon/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询用户领券记录详细
export function getMemberCoupon(id) {
return request({
url: '/act/memberCoupon/' + id,
method: 'get'
})
}
// 新增用户领券记录
export function addMemberCoupon(data) {
return request({
url: '/act/memberCoupon',
method: 'post',
data: data
})
}
// 修改用户领券记录
export function updateMemberCoupon(data) {
return request({
url: '/act/memberCoupon',
method: 'put',
data: data
})
}
// 删除用户领券记录
export function delMemberCoupon(id) {
return request({
url: '/act/memberCoupon/' + id,
method: 'delete'
})
}
// 导出用户领券记录
export function exportMemberCoupon(query) {
return request({
url: '/act/memberCoupon/export',
method: 'get',
params: query
})
}

View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
// 查询系统数据统计列表
export function listAwsSystemStatistics(query, pageReq) {
return request({
url: '/aws/systemStatistics/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询系统数据统计详细
export function getAwsSystemStatistics(id) {
return request({
url: '/aws/systemStatistics/' + id,
method: 'get'
})
}
// 新增系统数据统计
export function addAwsSystemStatistics(data) {
return request({
url: '/aws/systemStatistics',
method: 'post',
data: data
})
}
// 修改系统数据统计
export function updateAwsSystemStatistics(data) {
return request({
url: '/aws/systemStatistics',
method: 'put',
data: data
})
}
// 删除系统数据统计
export function delAwsSystemStatistics(id) {
return request({
url: '/aws/systemStatistics/' + id,
method: 'delete'
})
}
// 导出系统数据统计
export function exportAwsSystemStatistics(query) {
return request({
url: '/aws/systemStatistics/export',
method: 'get',
params: query
})
}

57
src/api/monitor/cache.js Normal file
View File

@ -0,0 +1,57 @@
import request from '@/utils/request'
// 查询缓存详细
export function getCache() {
return request({
url: '/monitor/cache',
method: 'get'
})
}
// 查询缓存名称列表
export function listCacheName() {
return request({
url: '/monitor/cache/getNames',
method: 'get'
})
}
// 查询缓存键名列表
export function listCacheKey(cacheName) {
return request({
url: '/monitor/cache/getKeys/' + cacheName,
method: 'get'
})
}
// 查询缓存内容
export function getCacheValue(cacheName, cacheKey) {
return request({
url: '/monitor/cache/getValue/' + cacheName + '/' + cacheKey,
method: 'get'
})
}
// 清理指定名称缓存
export function clearCacheName(cacheName) {
return request({
url: '/monitor/cache/clearCacheName/' + cacheName,
method: 'delete'
})
}
// 清理指定键名缓存
export function clearCacheKey(cacheKey) {
return request({
url: '/monitor/cache/clearCacheKey/' + cacheKey,
method: 'delete'
})
}
// 清理全部缓存
export function clearCacheAll() {
return request({
url: '/monitor/cache/clearCacheAll',
method: 'delete'
})
}

71
src/api/monitor/job.js Normal file
View File

@ -0,0 +1,71 @@
import request from '@/utils/request'
// 查询定时任务调度列表
export function listJob(query) {
return request({
url: '/monitor/job/list',
method: 'get',
params: query
})
}
// 查询定时任务调度详细
export function getJob(jobId) {
return request({
url: '/monitor/job/' + jobId,
method: 'get'
})
}
// 新增定时任务调度
export function addJob(data) {
return request({
url: '/monitor/job',
method: 'post',
data: data
})
}
// 修改定时任务调度
export function updateJob(data) {
return request({
url: '/monitor/job',
method: 'put',
data: data
})
}
// 删除定时任务调度
export function delJob(jobId) {
return request({
url: '/monitor/job/' + jobId,
method: 'delete'
})
}
// 任务状态修改
export function changeJobStatus(jobId, status) {
const data = {
jobId,
status
}
return request({
url: '/monitor/job/changeStatus',
method: 'put',
data: data
})
}
// 定时任务立即执行一次
export function runJob(jobId, jobGroup) {
const data = {
jobId,
jobGroup
}
return request({
url: '/monitor/job/run',
method: 'put',
data: data
})
}

26
src/api/monitor/jobLog.js Normal file
View File

@ -0,0 +1,26 @@
import request from '@/utils/request'
// 查询调度日志列表
export function listJobLog(query) {
return request({
url: '/monitor/jobLog/list',
method: 'get',
params: query
})
}
// 删除调度日志
export function delJobLog(jobLogId) {
return request({
url: '/monitor/jobLog/' + jobLogId,
method: 'delete'
})
}
// 清空调度日志
export function cleanJobLog() {
return request({
url: '/monitor/jobLog/clean',
method: 'delete'
})
}

View File

@ -0,0 +1,26 @@
import request from '@/utils/request'
// 查询登录日志列表
export function list(query) {
return request({
url: '/monitor/logininfor/list',
method: 'get',
params: query
})
}
// 删除登录日志
export function delLogininfor(infoId) {
return request({
url: '/monitor/logininfor/' + infoId,
method: 'delete'
})
}
// 清空登录日志
export function cleanLogininfor() {
return request({
url: '/monitor/logininfor/clean',
method: 'delete'
})
}

18
src/api/monitor/online.js Normal file
View File

@ -0,0 +1,18 @@
import request from '@/utils/request'
// 查询在线用户列表
export function list(query) {
return request({
url: '/monitor/online/list',
method: 'get',
params: query
})
}
// 强退用户
export function forceLogout(tokenId) {
return request({
url: '/monitor/online/' + tokenId,
method: 'delete'
})
}

View File

@ -0,0 +1,26 @@
import request from '@/utils/request'
// 查询操作日志列表
export function list(query) {
return request({
url: '/monitor/operlog/list',
method: 'get',
params: query
})
}
// 删除操作日志
export function delOperlog(operId) {
return request({
url: '/monitor/operlog/' + operId,
method: 'delete'
})
}
// 清空操作日志
export function cleanOperlog() {
return request({
url: '/monitor/operlog/clean',
method: 'delete'
})
}

View File

@ -0,0 +1,9 @@
import request from '@/utils/request'
// 获取服务信息
export function getServer() {
return request({
url: '/monitor/server',
method: 'get'
})
}

70
src/api/oms/aftersale.js Normal file
View File

@ -0,0 +1,70 @@
import request from '@/utils/request'
// 查询订单售后列表
export function listOmsAftersale(query, pageReq) {
return request({
url: '/oms/aftersale/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询订单售后详细
export function getOmsAftersale(id) {
return request({
url: '/oms/aftersale/' + id,
method: 'get'
})
}
// 新增订单售后
export function addOmsAftersale(data) {
return request({
url: '/oms/aftersale',
method: 'post',
data: data
})
}
// 修改订单售后
export function updateOmsAftersale(data) {
return request({
url: '/oms/aftersale',
method: 'put',
data: data
})
}
// 删除订单售后
export function delOmsAftersale(id) {
return request({
url: '/oms/aftersale/' + id,
method: 'delete'
})
}
// 导出订单售后
export function exportOmsAftersale(query) {
return request({
url: '/oms/aftersale/export',
method: 'get',
params: query
})
}
// 售后订单操作
export function dealWithAftersale(data){
return request({
url: '/oms/aftersale/dealWith',
method: 'post',
data: data
})
}
export function viewLog(orderId){
return request({
url: `/oms/aftersale/log/` + orderId,
method: 'get'
})
}

View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
// 查询订单售后列表
export function listOmsAftersaleItem(query, pageReq) {
return request({
url: '/oms/aftersaleItem/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询订单售后详细
export function getOmsAftersaleItem(id) {
return request({
url: '/oms/aftersaleItem/' + id,
method: 'get'
})
}
// 新增订单售后
export function addOmsAftersaleItem(data) {
return request({
url: '/oms/aftersaleItem',
method: 'post',
data: data
})
}
// 修改订单售后
export function updateOmsAftersaleItem(data) {
return request({
url: '/oms/aftersaleItem',
method: 'put',
data: data
})
}
// 删除订单售后
export function delOmsAftersaleItem(id) {
return request({
url: '/oms/aftersaleItem/' + id,
method: 'delete'
})
}
// 导出订单售后
export function exportOmsAftersaleItem(query) {
return request({
url: '/oms/aftersaleItem/export',
method: 'get',
params: query
})
}

94
src/api/oms/order.js Normal file
View File

@ -0,0 +1,94 @@
import request from '@/utils/request'
// 查询订单表列表
export function listOmsOrder(query, pageReq) {
return request({
url: '/oms/order/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询订单表详细
export function getOmsOrder(id) {
return request({
url: '/oms/order/' + id,
method: 'get'
})
}
// 查询订单手机号密文
export function getDecryptPhone(id) {
return request({
url: '/oms/order/decryptPhone/' + id,
method: 'get'
})
}
// 新增订单表
export function addOmsOrder(data) {
return request({
url: '/oms/order',
method: 'post',
data: data
})
}
// 修改订单表
export function updateOmsOrder(data) {
return request({
url: '/oms/order',
method: 'put',
data: data
})
}
// 删除订单表
export function delOmsOrder(id) {
return request({
url: '/oms/order/' + id,
method: 'delete'
})
}
// 导出订单表
export function exportOmsOrder(query) {
return request({
url: '/oms/order/export',
method: 'get',
params: query
})
}
// 保存商家备注
export function saveMerchantNote(data){
return request({
url: '/oms/order/merchantNote/add',
method: 'post',
data: data
})
}
// 发货
export function deliverProduct(data){
return request({
url: '/oms/order/deliverProduct',
method: 'post',
data: data
})
}
export function updateReceiverAddress(data){
return request({
url: '/oms/order/receiver/update',
method: 'post',
data: data
})
}
// 查看订单操作日志
export function viewLog(orderId){
return request({
url:`/oms/order/log/` + orderId,
method: 'get'
})
}

View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
// 查询订单发货记录列表
export function listOmsOrderDeliveryHistory(query, pageReq) {
return request({
url: '/oms/orderDeliveryHistory/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询订单发货记录详细
export function getOmsOrderDeliveryHistory(id) {
return request({
url: '/oms/orderDeliveryHistory/' + id,
method: 'get'
})
}
// 新增订单发货记录
export function addOmsOrderDeliveryHistory(data) {
return request({
url: '/oms/orderDeliveryHistory',
method: 'post',
data: data
})
}
// 修改订单发货记录
export function updateOmsOrderDeliveryHistory(data) {
return request({
url: '/oms/orderDeliveryHistory',
method: 'put',
data: data
})
}
// 删除订单发货记录
export function delOmsOrderDeliveryHistory(id) {
return request({
url: '/oms/orderDeliveryHistory/' + id,
method: 'delete'
})
}
// 导出订单发货记录
export function exportOmsOrderDeliveryHistory(query) {
return request({
url: '/oms/orderDeliveryHistory/export',
method: 'get',
params: query
})
}

54
src/api/oms/orderItem.js Normal file
View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
// 查询订单中所包含的商品列表
export function listOmsOrderItem(query, pageReq) {
return request({
url: '/oms/orderItem/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询订单中所包含的商品详细
export function getOmsOrderItem(id) {
return request({
url: '/oms/orderItem/' + id,
method: 'get'
})
}
// 新增订单中所包含的商品
export function addOmsOrderItem(data) {
return request({
url: '/oms/orderItem',
method: 'post',
data: data
})
}
// 修改订单中所包含的商品
export function updateOmsOrderItem(data) {
return request({
url: '/oms/orderItem',
method: 'put',
data: data
})
}
// 删除订单中所包含的商品
export function delOmsOrderItem(id) {
return request({
url: '/oms/orderItem/' + id,
method: 'delete'
})
}
// 导出订单中所包含的商品
export function exportOmsOrderItem(query) {
return request({
url: '/oms/orderItem/export',
method: 'get',
params: query
})
}

View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
// 查询订单操作历史记录列表
export function listOmsOrderOperateHistory(query, pageReq) {
return request({
url: '/oms/orderOperateHistory/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询订单操作历史记录详细
export function getOmsOrderOperateHistory(id) {
return request({
url: '/oms/orderOperateHistory/' + id,
method: 'get'
})
}
// 新增订单操作历史记录
export function addOmsOrderOperateHistory(data) {
return request({
url: '/oms/orderOperateHistory',
method: 'post',
data: data
})
}
// 修改订单操作历史记录
export function updateOmsOrderOperateHistory(data) {
return request({
url: '/oms/orderOperateHistory',
method: 'put',
data: data
})
}
// 删除订单操作历史记录
export function delOmsOrderOperateHistory(id) {
return request({
url: '/oms/orderOperateHistory/' + id,
method: 'delete'
})
}
// 导出订单操作历史记录
export function exportOmsOrderOperateHistory(query) {
return request({
url: '/oms/orderOperateHistory/export',
method: 'get',
params: query
})
}

View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
// 查询微信订单表列表
export function listOmsWechatPaymentHistory(query, pageReq) {
return request({
url: '/pms/omsWechatPaymentHistory/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询微信订单表详细
export function getOmsWechatPaymentHistory(id) {
return request({
url: '/pms/omsWechatPaymentHistory/' + id,
method: 'get'
})
}
// 新增微信订单表
export function addOmsWechatPaymentHistory(data) {
return request({
url: '/pms/omsWechatPaymentHistory',
method: 'post',
data: data
})
}
// 修改微信订单表
export function updateOmsWechatPaymentHistory(data) {
return request({
url: '/pms/omsWechatPaymentHistory',
method: 'put',
data: data
})
}
// 删除微信订单表
export function delOmsWechatPaymentHistory(id) {
return request({
url: '/pms/omsWechatPaymentHistory/' + id,
method: 'delete'
})
}
// 导出微信订单表
export function exportOmsWechatPaymentHistory(query) {
return request({
url: '/pms/omsWechatPaymentHistory/export',
method: 'get',
params: query
})
}

62
src/api/pms/brand.js Normal file
View File

@ -0,0 +1,62 @@
import request from '@/utils/request'
// 查询品牌管理列表
export function listPmsBrand(query, pageReq) {
return request({
url: '/pms/brand/list',
method: 'post',
data: query,
params: pageReq
})
}
export function allBrand(query, pageReq) {
return request({
url: '/pms/brand/all',
method: 'post',
data: query,
params: pageReq
})
}
// 查询品牌管理详细
export function getPmsBrand(id) {
return request({
url: '/pms/brand/' + id,
method: 'get'
})
}
// 新增品牌管理
export function addPmsBrand(data) {
return request({
url: '/pms/brand',
method: 'post',
data: data
})
}
// 修改品牌管理
export function updatePmsBrand(data) {
return request({
url: '/pms/brand',
method: 'put',
data: data
})
}
// 删除品牌管理
export function delPmsBrand(id) {
return request({
url: '/pms/brand/' + id,
method: 'delete'
})
}
// 导出品牌管理
export function exportPmsBrand(query) {
return request({
url: '/pms/brand/export',
method: 'get',
params: query
})
}

54
src/api/pms/product.js Normal file
View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
// 查询商品信息列表
export function listPmsProduct(query, pageReq) {
return request({
url: '/pms/product/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询商品信息详细
export function getPmsProduct(id) {
return request({
url: '/pms/product/' + id,
method: 'get'
})
}
// 新增商品信息
export function addPmsProduct(data) {
return request({
url: '/pms/product',
method: 'post',
data: data
})
}
// 修改商品信息
export function updatePmsProduct(data) {
return request({
url: '/pms/product',
method: 'put',
data: data
})
}
// 删除商品信息
export function delPmsProduct(id) {
return request({
url: '/pms/product/' + id,
method: 'delete'
})
}
// 导出商品信息
export function exportPmsProduct(query) {
return request({
url: '/pms/product/export',
method: 'get',
params: query
})
}

View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
// 查询商品分类列表
export function listPmsProductCategory(query, pageReq) {
return request({
url: '/pms/productCategory/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询商品分类详细
export function getPmsProductCategory(id) {
return request({
url: '/pms/productCategory/' + id,
method: 'get'
})
}
// 新增商品分类
export function addPmsProductCategory(data) {
return request({
url: '/pms/productCategory',
method: 'post',
data: data
})
}
// 修改商品分类
export function updatePmsProductCategory(data) {
return request({
url: '/pms/productCategory',
method: 'put',
data: data
})
}
// 删除商品分类
export function delPmsProductCategory(id) {
return request({
url: '/pms/productCategory/' + id,
method: 'delete'
})
}
// 导出商品分类
export function exportPmsProductCategory(query) {
return request({
url: '/pms/productCategory/export',
method: 'get',
params: query
})
}

54
src/api/pms/sku.js Normal file
View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
// 查询sku信息列表
export function listPmsSku(query, pageReq) {
return request({
url: '/pms/sku/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询sku信息详细
export function getPmsSku(id) {
return request({
url: '/pms/sku/' + id,
method: 'get'
})
}
// 新增sku信息
export function addPmsSku(data) {
return request({
url: '/pms/sku',
method: 'post',
data: data
})
}
// 修改sku信息
export function updatePmsSku(data) {
return request({
url: '/pms/sku',
method: 'put',
data: data
})
}
// 删除sku信息
export function delPmsSku(id) {
return request({
url: '/pms/sku/' + id,
method: 'delete'
})
}
// 导出sku信息
export function exportPmsSku(query) {
return request({
url: '/pms/sku/export',
method: 'get',
params: query
})
}

View File

@ -0,0 +1,32 @@
import request from '@/utils/request'
// 获取首页查询热卖商品TOP
export function goodsStatistics(query) {
return request({
url: '/dev/statistics/index/goodsStatistics',
method: 'get',
params: query
})
}
export function memberAndCartStatistics() {
return request({
url: '/dev/statistics/index/memberAndCart/statistics',
method: 'get'
})
}
export function orderAndAftersaleStatistics() {
return request({
url: '/dev/statistics/index/order/aftersale/statistics',
method: 'get'
})
}
// 获取订单信息
export function orderStatistics(query) {
return request({
url: '/dev/statistics/index/orderStatistics',
method: 'post',
data: query
})
}

10
src/api/system/common.js Normal file
View File

@ -0,0 +1,10 @@
import request from '@/utils/request';
// 查询省市区列表
export function areaSelect(query) {
return request({
url: '/common/area',
method: 'get',
params: query
});
}

26
src/api/ums/feedback.js Normal file
View File

@ -0,0 +1,26 @@
import request from "@/utils/request";
export function updateMark(data) {
return request({
url: '/ums/feedback/mark/update',
method: 'post',
data: data
})
}
export function changeHandleStatus(data) {
return request({
url: '/ums/feedback/handle/status/change',
method: 'post',
data: data
})
}
export function listFeedbacks(query, pageReq) {
return request({
url: '/ums/feedback/list',
method: 'post',
data: query,
params: pageReq
})
}

104
src/api/ums/member.js Normal file
View File

@ -0,0 +1,104 @@
import request from '@/utils/request'
// 查询会员信息列表
export function listUmsMember(query, pageReq) {
return request({
url: '/ums/member/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询会员信息详细
export function getUmsMember(id) {
return request({
url: '/ums/member/' + id,
method: 'get'
})
}
// 新增会员信息
export function addUmsMember(data) {
return request({
url: '/ums/member',
method: 'post',
data: data
})
}
// 修改会员信息
export function updateUmsMember(data) {
return request({
url: '/ums/member',
method: 'put',
data: data
})
}
export function updateUmsMemberMark(data) {
return request({
url: '/ums/member/mark/update',
method: 'post',
data: data
})
}
// 删除会员信息
export function delUmsMember(id) {
return request({
url: '/ums/member/' + id,
method: 'delete'
})
}
// 导出会员信息
export function exportUmsMember(query) {
return request({
url: '/ums/member/export',
method: 'get',
params: query
})
}
// 更改会员账号状态
export function changeAccountStatus(data) {
return request({
url: '/ums/member/status/change',
method: 'post',
data: data
})
}
// 获取解密手机号
export function decryptedPhone(data) {
return request({
url: `/ums/member/phone/decrypt/` + data,
method: 'get'
})
}
// 查询会员统计数据
export function viewStatistics(memberId){
return request({
url: `/ums/member/view/statistics/` + memberId,
method: 'get'
})
}
export function getMiniWechatImg(params){
return request({
url: `/ums/member/wechat/code`,
method: 'get',
params
})
}
export function judgeQrCode(params){
return request({
url: `/no-auth/verified/code`,
method: 'get',
params
})
}

View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
// 查询会员收货地址列表
export function listUmsMemberAddress(query, pageReq) {
return request({
url: '/ums/memberAddress/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询会员收货地址详细
export function getUmsMemberAddress(id) {
return request({
url: '/ums/memberAddress/' + id,
method: 'get'
})
}
// 新增会员收货地址
export function addUmsMemberAddress(data) {
return request({
url: '/ums/memberAddress',
method: 'post',
data: data
})
}
// 修改会员收货地址
export function updateUmsMemberAddress(data) {
return request({
url: '/ums/memberAddress',
method: 'put',
data: data
})
}
// 删除会员收货地址
export function delUmsMemberAddress(id) {
return request({
url: '/ums/memberAddress/' + id,
method: 'delete'
})
}
// 导出会员收货地址
export function exportUmsMemberAddress(query) {
return request({
url: '/ums/memberAddress/export',
method: 'get',
params: query
})
}

54
src/api/ums/memberCart.js Normal file
View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
// 查询购物车列表
export function listUmsMemberCart(query, pageReq) {
return request({
url: '/ums/memberCart/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询购物车详细
export function getUmsMemberCart(id) {
return request({
url: '/ums/memberCart/' + id,
method: 'get'
})
}
// 新增购物车
export function addUmsMemberCart(data) {
return request({
url: '/ums/memberCart',
method: 'post',
data: data
})
}
// 修改购物车
export function updateUmsMemberCart(data) {
return request({
url: '/ums/memberCart',
method: 'put',
data: data
})
}
// 删除购物车
export function delUmsMemberCart(id) {
return request({
url: '/ums/memberCart/' + id,
method: 'delete'
})
}
// 导出购物车
export function exportUmsMemberCart(query) {
return request({
url: '/ums/memberCart/export',
method: 'get',
params: query
})
}

View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
// 查询会员登录记录列表
export function listUmsMemberLogininfor(query, pageReq) {
return request({
url: '/ums/memberLogininfor/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询会员登录记录详细
export function getUmsMemberLogininfor(id) {
return request({
url: '/ums/memberLogininfor/' + id,
method: 'get'
})
}
// 新增会员登录记录
export function addUmsMemberLogininfor(data) {
return request({
url: '/ums/memberLogininfor',
method: 'post',
data: data
})
}
// 修改会员登录记录
export function updateUmsMemberLogininfor(data) {
return request({
url: '/ums/memberLogininfor',
method: 'put',
data: data
})
}
// 删除会员登录记录
export function delUmsMemberLogininfor(id) {
return request({
url: '/ums/memberLogininfor/' + id,
method: 'delete'
})
}
// 导出会员登录记录
export function exportUmsMemberLogininfor(query) {
return request({
url: '/ums/memberLogininfor/export',
method: 'get',
params: query
})
}

View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
// 查询用户微信信息列表
export function listUmsMemberWechat(query, pageReq) {
return request({
url: '/ums/memberWechat/list',
method: 'post',
data: query,
params: pageReq
})
}
// 查询用户微信信息详细
export function getUmsMemberWechat(id) {
return request({
url: '/ums/memberWechat/' + id,
method: 'get'
})
}
// 新增用户微信信息
export function addUmsMemberWechat(data) {
return request({
url: '/ums/memberWechat',
method: 'post',
data: data
})
}
// 修改用户微信信息
export function updateUmsMemberWechat(data) {
return request({
url: '/ums/memberWechat',
method: 'put',
data: data
})
}
// 删除用户微信信息
export function delUmsMemberWechat(id) {
return request({
url: '/ums/memberWechat/' + id,
method: 'delete'
})
}
// 导出用户微信信息
export function exportUmsMemberWechat(query) {
return request({
url: '/ums/memberWechat/export',
method: 'get',
params: query
})
}

View File

@ -0,0 +1,71 @@
<template>
<el-dialog title="扫描解锁" v-model:visible="open" width="500px" append-to-body :close-on-click-modal="false">
<p>使用微信扫描下方二维码观看完广告获取验证码</p>
<p class="red f13">如果第一次扫码未弹出广告请重新扫码进入</p>
<div class="flex-center">
<el-image class="qr-code" :src="'data:image/png;base64,' + miniImg" fit="fill"></el-image>
<el-input v-model="qrCode" class="left-input" />
<el-button @click="asyncOk" class="right-btn" type="primary" :disabled="!qrCode">提交</el-button>
</div>
</el-dialog>
</template>
<script>
import { getMiniWechatImg, judgeQrCode } from '@/api/ums/member';
import { useUserStore } from '@/store/modules/user';
export default {
computed: {
roles: {
get() {
return useUserStore().roles;
}
}
},
data() {
return {
open: false,
miniImg: null,
qrCode: null
};
},
methods: {
initMiniWechatImg() {
getMiniWechatImg({ scene: 2 }).then((res) => {
this.miniImg = res.data;
});
},
show() {
//
if (this.roles.includes('admin')) {
this.$emit('confirmOk', true);
return;
}
this.initMiniWechatImg();
this.open = true;
},
async asyncOk() {
const res = await judgeQrCode({ code: this.qrCode }).then((res) => {
return res.data;
});
if (res) {
this.open = false;
} else {
this.$message.error('验证码错误');
}
this.$emit('confirmOk', res);
}
}
};
</script>
<style lang="stylus">
.qr-code
min-width 150px
height 150px
margin 20px 20px 20px 0
.left-input
.el-input__inner
border-radius 4px 0 0 4px !important
.right-btn
border-radius 0 4px 4px 0 !important
</style>

View File

@ -19,6 +19,9 @@ const isWhiteList = (path: string) => {
router.beforeEach(async (to, from, next) => {
NProgress.start();
// 仅仅限本地无token调试时候不做token校验
/* next();
return;*/
if (getToken()) {
to.meta.title && useSettingsStore().setTitle(to.meta.title as string);
/* has token*/

View File

@ -94,6 +94,121 @@ export const constantRoutes: RouteRecordRaw[] = [
}
]
},
// 新迁移的菜单,开发阶段暂时放在固定菜单内,后续迁移到权限菜单里
{
path: '/system/user-auth',
component: Layout,
hidden: true,
permissions: ['system:user:edit'],
children: [
{
path: 'role/:userId(\\d+)',
component: () => import('@/views/system/user/authRole.vue'),
name: 'AuthRole',
meta: { title: '分配角色', activeMenu: '/system/user' }
}
]
},
{
path: '/system/role-auth',
component: Layout,
hidden: true,
permissions: ['system:role:edit'],
children: [
{
path: 'user/:roleId(\\d+)',
component: () => import('@/views/system/role/authUser.vue'),
name: 'AuthUser',
meta: { title: '分配用户', activeMenu: '/system/role' }
}
]
},
{
path: '/system/dict-data',
component: Layout,
hidden: true,
permissions: ['system:dict:list'],
children: [
{
path: 'index/:dictId(\\d+)',
component: () => import('@/views/system/dict/data.vue'),
name: 'Data',
meta: { title: '字典数据', activeMenu: '/system/dict' }
}
]
},
{
path: '/monitor/job-log',
component: Layout,
hidden: true,
permissions: ['monitor:job:list'],
children: [
{
path: 'index',
component: () => import('@/views/monitor/job/log.vue'),
name: 'JobLog',
meta: { title: '调度日志', activeMenu: '/monitor/job' }
}
]
},
{
path: '/tool/gen-edit',
component: Layout,
hidden: true,
permissions: ['tool:gen:edit'],
children: [
{
path: 'index/:tableId(\\d+)',
component: () => import('@/views/tool/gen/editTable.vue'),
name: 'GenEdit',
meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
}
]
},
{
path: '/product',
component: Layout,
hidden: true,
permissions: ['pms:product:list'],
children: [
{
path: 'edit',
component: () => import('@/views/pms/product/AddProduct.vue'),
name: 'addProduct',
meta: { title: '编辑商品' }
}
]
},
{
path: '/order',
component: Layout,
hidden: true,
permissions: ['oms:order:query'],
children: [
{
path: 'detail',
component: () => import('@/views/oms/order/detail.vue'),
name: 'orderDetail',
meta: { title: '订单详情' }
}
]
},
{
path: '/aftersale',
component: Layout,
hidden: true,
// permissions: ['oms:aftersale:query'],
children: [
{
path: 'detail',
component: () => import('@/views/oms/aftersale/detail.vue'),
name: 'aftersaleOrderDetail',
meta: { title: '售后订单详情' }
}
]
},
// 内容中心
{
path: '/content-center',

27
src/store/getters.js Normal file
View File

@ -0,0 +1,27 @@
const getters = {
sidebar: (state) => state.app.sidebar,
size: (state) => state.app.size,
device: (state) => state.app.device,
visitedViews: (state) => state.tagsView.visitedViews,
cachedViews: (state) => state.tagsView.cachedViews,
token: (state) => state.user.token,
avatar: (state) => state.user.avatar,
name: (state) => state.user.name,
userId: (state) => state.user.userId,
introduction: (state) => state.user.introduction,
roles: (state) => state.user.roles,
permissions: (state) => state.user.permissions,
permission_routes: (state) => state.permission.routes,
topbarRouters: (state) => state.permission.topbarRouters,
defaultRoutes: (state) => state.permission.defaultRoutes,
sidebarRouters: (state) => state.permission.sidebarRouters,
dictMap: (state) => state.dict.dictMap,
productCategories: (state) => state.mall.productCategories,
areaSelect: (state) => state.mall.areaSelect,
brandList: (state) => state.mall.brandList
};
export default getters;

50
src/store/modules/mall.ts Normal file
View File

@ -0,0 +1,50 @@
import { defineStore } from 'pinia';
import { reactive } from 'vue';
import { listPmsProductCategory } from '@/api/pms/productCategory';
import { allBrand } from '@/api/pms/brand';
import { areaSelect } from '@/api/system/common.js';
export const useMallStore = defineStore('mall', () => {
const state = reactive({
productCategories: [],
brandList: [],
areaSelect: [],
aaaaaaa: 'store开发测试'
});
const aaaaaaa = ref('store开发测试');
const changeAAA = (info: any) => {
aaaaaaa.value = info;
};
const loadProductCategories = async (force: any = false) => {
if (!force && state.productCategories.length > 0) {
return Promise.resolve();
}
return listPmsProductCategory({}).then((res: any) => {
state.productCategories = res;
});
};
const loadAreaSelect = async (force: any = false) => {
if (!force && state.areaSelect.length > 0) {
return Promise.resolve();
}
return areaSelect({}).then((res) => {
state.areaSelect = res.data;
});
};
const loadBrandList = async (force: any = false) => {
if (!force && state.brandList.length > 0) {
return Promise.resolve();
}
return allBrand({}).then((res: any) => {
state.brandList = res;
});
};
return {
changeAAA,
aaaaaaa,
state,
loadProductCategories,
loadAreaSelect,
loadBrandList
};
});

222
src/utils/DateUtil.js Normal file
View File

@ -0,0 +1,222 @@
/**
* Created by lcx47996 on 2017/12/25.
*/
export function dateFormat(date, format) {
if (!date || date === 0) {
return '';
}
if (!(date instanceof Date)) {
date = new Date(date);
if (date.toString() === 'Invalid Date') {
return '无效时间戳';
}
}
format = format || 'yyyy-MM-dd hh:mm:ss';
const o = {
'M+': date.getMonth() + 1, // 月份
'd+': date.getDate(), // 日
'h+': date.getHours(), // 小时
'm+': date.getMinutes(), // 分
's+': date.getSeconds(), // 秒
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
'S': date.getMilliseconds() // 毫秒
};
if (/(y+)/.test(format)) {
format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
}
for (const k in o) {
if (new RegExp('(' + k + ')').test(format)) {
format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length));
}
}
return format;
}
function getAfterDate(after) {
var dd = new Date();
dd.setDate(dd.getDate() + after); // 获取AddDayCount天后的日期
var y = dd.getFullYear();
var m = dd.getMonth() + 1; // 获取当前月份的日期
var d = dd.getDate();
return y + '-' + m + '-' + d;
}
function getAfterDateReturnDate(datetime, after) {
if (!(datetime.type instanceof Date)) {
return datetime;
}
var r = new Date(datetime.getTime());
r.setDate(datetime.getDate() + after); // 获取AddDayCount天后的日期
return r;
}
function getAfterHourReturnDate(datetime, after) {
if (!(datetime.type instanceof Date)) {
return datetime;
}
var r = new Date(datetime.getTime() + after * 60 * 60 * 1000);
return r;
}
function getAfterMounth(date, after) {
var dd = new Date();
dd.setMonth(dd.getMonth() + after); // 获取AddDayCount天后的日期
var y = dd.getFullYear();
var m = dd.getMonth() + 1; // 获取当前月份的日期
var d = dd.getDate();
return y + '-' + m + '-' + d;
}
/**
* 计算2个日期相差的天数不包含今天2016-12-13到2016-12-15相差2天
*/
function dateDiff(startDate, endDate) {
return parseInt((endDate - startDate) / 1000 / 60 / 60 / 24); // 把相差的毫秒数转换为天数
}
/**
* 计算2个日期相差的天数包含今天2016-12-13到2016-12-15相差3天
*/
function dateDiffIncludeToday(startDate, endDate) {
return parseInt((endDate - startDate) / 1000 / 60 / 60 / 24) + 1; // 把相差的毫秒数转换为天数
}
/**
* 获取凌晨时间
* @param day
*/
export function getMorningTime(day = 0) {
if (day == null) {
return null;
}
const timeStamp = new Date(new Date().setHours(0, 0, 0, 0)).getTime();
return new Date(timeStamp + day * 86400000);
}
export function getStartEnd(length) {
const end = getMorningTime(0);
const start = getMorningTime(0);
start.setTime(start.getTime() - 3600 * 1000 * 24 * length);
return { end, start };
}
function getTimeShort() {
const timeShort = [
{
text: '今天',
onClick(picker) {
const { end, start } = getStartEnd(0);
picker.$emit('pick', [start, end]);
}
},
{
text: '昨天',
onClick(picker) {
const time = getMorningTime(0);
time.setTime(time.getTime() - 3600 * 1000 * 24);
picker.$emit('pick', [time, time]);
}
},
{
text: '最近一周',
onClick(picker) {
const { end, start } = getStartEnd(7);
picker.$emit('pick', [start, end]);
}
},
{
text: '最近一个月',
onClick(picker) {
const { end, start } = getStartEnd(30);
picker.$emit('pick', [start, end]);
}
},
{
text: '最近三个月',
onClick(picker) {
const { end, start } = getStartEnd(90);
picker.$emit('pick', [start, end]);
}
}
];
return timeShort;
}
function getTimeShort2() {
const timeShort = [
{
text: '今天',
onClick(picker) {
const temp = new Date();
picker.$emit('pick', [new Date(temp.setHours(0, 0, 0, 0)), new Date(temp.setHours(23, 59, 59, 0))]);
}
},
{
text: '昨天',
onClick(picker) {
const temp = new Date();
temp.setTime(temp.getTime() - 3600 * 1000 * 24);
picker.$emit('pick', [new Date(temp.setHours(0, 0, 0, 0)), new Date(temp.setHours(23, 59, 59, 0))]);
}
},
{
text: '前一周',
onClick(picker) {
const start = new Date();
const end = new Date();
start.setTime(end.getTime() - 3600 * 1000 * 24 * 6);
picker.$emit('pick', [new Date(start.setHours(0, 0, 0, 0)), new Date(end.setHours(23, 59, 59, 0))]);
}
},
{
text: '这个月',
onClick(picker) {
const end = getCurrentMonthLast();
const start = getCurrentMonthFirst();
picker.$emit('pick', [new Date(start.setHours(0, 0, 0, 0)), new Date(end.setHours(23, 59, 59, 0))]);
function getCurrentMonthFirst() {
let date = new Date();
date.setDate(1);
return date;
}
// 获取当前月的最后一天
function getCurrentMonthLast() {
let date = new Date();
let currentMonth = date.getMonth();
let nextMonth = ++currentMonth;
let nextMonthFirstDay = new Date(date.getFullYear(), nextMonth, 1);
let oneDay = 1000 * 60 * 60 * 24;
return new Date(nextMonthFirstDay - oneDay);
}
}
},
{
text: '前一个月',
onClick(picker) {
const start = new Date();
const end = new Date();
start.setTime(end.getTime() - 3600 * 1000 * 24 * 29);
picker.$emit('pick', [new Date(start.setHours(0, 0, 0, 0)), new Date(end.setHours(23, 59, 59, 0))]);
}
}
];
return timeShort;
}
export default {
'getAfterDate': getAfterDate,
'getAfterMounth': getAfterMounth,
'dateDiff': dateDiff,
'dateDiffIncludeToday': dateDiffIncludeToday,
'getAfterDateReturnDate': getAfterDateReturnDate,
'getAfterHourReturnDate': getAfterHourReturnDate,
getTimeShort,
getTimeShort2,
dateFormat,
getStartEnd,
getMorningTime
};

218
src/utils/is-star-plugin.js Normal file
View File

@ -0,0 +1,218 @@
// 用于检测用户是否 star 了仓库,如果没有 star将弹窗提示用户 star 。
import { Message, MessageBox } from 'element-ui'
// 使用axios代替$.ajax
import axios from 'axios'
// 应用参数
const client_id = '9addfce3712d04898b5a3dbb223db38b8d6495d2e66d07e3c0af71a708ee3b54'
const client_secret = '1f73096ce60406eba8fb297a16245eadf2777540abdf531266b406b2479e25fe'
// 检查成功后,多少天不再检查
const allowDisparity = 1000 * 60 * 60 * 24 * 7
/**
* 判断当前是否已 star
* @param owner 仓库所属空间地址(企业组织或个人的地址path)
* @param repo 仓库路径(path)
* @param userId
* @param redirectUrl
* @param productName 开源项目名
* @param productLink 开源链接
*/
export function isStarRepo(owner, repo, userId, redirectUrl,productName,productLink) {
const judge = process.env.VUE_APP_JUDGE_STAR
if (!judge || judge == 0) {
return true;
}
const key = userId + '_' + owner + '_' + repo
console.log(key)
// 判断是否近期已经判断过了
try {
if (typeof window !== 'undefined') {
const isStarRepo = localStorage.getItem(key)
if (isStarRepo) {
// 记录 star 的时间,和当前时间的差距
const disparity = new Date().getTime() - parseInt(isStarRepo)
// 差距小于一月,不再检测,大于一月,再检测一下
if (disparity < allowDisparity) {
console.log('checked ...')
return true;
}
}
}
} catch (e) {
console.error(e)
}
return getCode(owner, repo, key, redirectUrl,productName,productLink)
}
// 去请求授权
function getCode(owner, repo, key, redirectUrl,productName,productLink) {
// 检查url中是否有code
const code = getParam('code')
if (code) {
// 有 code进一步去请求 access_token
getAccessToken(code, redirectUrl, owner, repo, key,productName,productLink)
} else {
// 不存在code弹窗提示询问
confirmStar(redirectUrl,productName,productLink)
return false;
}
}
// 弹窗提示点 star
function confirmStar(redirectUrl,productName,productLink) {
// 弹窗提示文字
const tipStr = `
<div>
<p><b>同学来支持一下 ${productName} 为项目点个 star </b></p>
<div>仅需两步即可完成<br>
<div>1打开 ${productName} <a href=${productLink} target="_blank" style="color: red">${productName}</a> star </div>
<div>2点击下方 [ 同意授权检测 ] 按钮同意 ${productName} 获取 API 权限进行检测</div>
</div>
<p><b>本页面将在 star 后正常开放展示</b></p>
</div>
`
// 弹窗提示
MessageBox.alert(tipStr, '温馨提示', {
// if you want to disable its autofocus
// autofocus: false,
confirmButtonText: '同意授权检测',
showClose: false,
dangerouslyUseHTMLString: true,
callback: (action) => {
if (action === 'confirm') {
// 用户点了确认,去 gitee 官方请求授权获取
goAuth(redirectUrl)
}
}
})
}
function toStar(redirectUrl,productName,productLink,accessToken,owner,repo,key,code) {
// 弹窗提示文字
const tipStr = `
<div>
<p><b>同学来支持一下 ${productName} 为项目点个 star </b></p>
<div>点击去Star按钮进入${productName} 开源项目主页在右上角点个 star </div>
<p><b>本页面将在 star 后正常开放展示</b></p>
</div>
`
MessageBox.confirm(tipStr, '温馨提示', {
// if you want to disable its autofocus
// autofocus: false,
closeOnClickModal: false,
confirmButtonText: '去Star',
cancelButtonText: '我已Star',
showClose: false,
dangerouslyUseHTMLString: true,
callback: (action) => {
if (action === 'confirm') {
// 用户点了确认,去 gitee 官方请求授权获取
window.open(productLink)
toStar(redirectUrl,productName,productLink,accessToken,owner,repo,key,code)
}
if (action === 'cancel') {
//检测
judgeStar(accessToken,owner,repo,key,productName,productLink,redirectUrl,code)
}
}
})
}
// 跳转到 gitee 授权界面
function goAuth(redirectUrl) {
location.href = 'https://gitee.com/oauth/authorize' +
'?client_id=' + client_id +
'&redirect_uri=' + redirectUrl +
'&response_type=code' +
'&scope=user_info'
}
// 获取 access_token
function getAccessToken(code, redirectUrl, owner, repo, key,productName,productLink) {
// 根据 code 获取 access_token
axios.post('https://gitee.com/oauth/token', {
grant_type: 'authorization_code',
code: code,
client_id: client_id,
redirect_uri: redirectUrl,
client_secret: client_secret
})
.then(res => {
// 拿到 access_token
const accessToken = res.data.access_token
judgeStar(accessToken,owner, repo, key,productName,productLink,redirectUrl,code)
})
.catch(e => {
console.log('请求错误 ', e)
// 如果请求地址有错,可能是服务器宕机了,暂停一天检测
if (e.response && (e.response.status === 0 || e.response.status === 502)) {
// 一天内不再检查
const ygTime = allowDisparity - (1000 * 60 * 60 * 24)
if (typeof window !== 'undefined') {
localStorage.setItem(key, new Date().getTime() - ygTime)
}
// 刷新 url去掉 code 参数
location.href = location.href.replace('?code=' + code, '')
}
// 无效授权,可能是 code 无效
const errorMsg = (e.response && e.response.data.error) || JSON.stringify(e)
if (errorMsg === 'invalid_grant') {
console.log('无效code', code)
let url = location.href.replace('?code=' + code, '')
url = url.replace('&code=' + code, '')
location.href = url
}
})
}
function judgeStar(accessToken,owner, repo, key,productName,productLink,redirectUrl,code){
// 根据 access_token 判断是否 star 了仓库
axios.get(`https://gitee.com/api/v5/user/starred/${owner}/${repo}`, {
params: { access_token: accessToken }
})
.then(res => {
// success 回调即代表已经 stargitee API 请求体不返回任何数据
console.log('-> stared ...')
// 记录本次检查时间
if (typeof window !== 'undefined') {
localStorage.setItem(key, new Date().getTime())
}
Message.success('感谢你的支持 ❤️ ❤️ ❤️ ,我们将努力变得更加完善!')
setTimeout(()=>{
location.href = location.href.replace('?code=' + code, '')
},1000)
})
.catch(e => {
// console.log('ff请求错误 ', e);
// 如下返回,代表没有 star
if (e.response && e.response.status === 404) {
console.log('not star ...')
toStar(redirectUrl,productName,productLink,accessToken,owner,repo,key,code);
}
})
}
// 获取 url 携带的参数
function getParam(name) {
const urls = window.location.href.split('?')
if (urls.length < 2) {
return null
}
let url = urls[1]
let obj = {} // 声明参数对象
let arr = url.split('&') // 以&符号分割为数组
for (let i = 0; i < arr.length; i++) {
let arrNew = arr[i].split('=') // 以"="分割为数组
obj[arrNew[0]] = arrNew[1]
}
return obj[name]
}

View File

@ -0,0 +1,387 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="100px" size="medium" class="ry_form">
<el-form-item label="活动名称" prop="title">
<el-input
v-model="queryParams.title"
placeholder="请输入活动名称"
clearable
size="small"
/>
</el-form-item>
<el-form-item label="使用范围" prop="useScope">
<DictRadio v-model="queryParams.useScope" @change="handleQuery" size="small"
:radioData="dict?.type.coupon_use_scope" :showAll="'all'"/>
</el-form-item>
<el-form-item label="兑换类型" prop="couponType">
<DictRadio v-model="queryParams.couponType" @change="handleQuery" size="small"
:radioData="dict?.type.coupon_exchange_type" :showAll="'all'"/>
</el-form-item>
<el-form-item class="flex_one tr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['act:couponActivity:opt']"
>新增
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="CouponActivityList" border>
<el-table-column label="活动名称" prop="title"/>
<el-table-column label="使用范围" prop="useScope">
<template slot-scope="scope">
<dict-tag :value="scope.row.useScope" prop-name="coupon_use_scope"/>
</template>
</el-table-column>
<el-table-column label="优惠内容">
<template slot-scope="scope">
<span v-if="scope.row.minAmount">{{ scope.row.minAmount }}优惠{{ scope.row.couponAmount }}</span>
<span v-else>无门槛优惠{{ scope.row.couponAmount }}</span>
</template>
</el-table-column>
<el-table-column label="发行总数" prop="totalCount"/>
<el-table-column label="剩余总数" prop="leftCount"/>
<el-table-column label="已使用" prop="useCount"/>
<el-table-column label="每人限领" prop="userLimit"/>
<el-table-column label="兑换类型" prop="couponType">
<template slot-scope="scope">
<dict-tag :value="scope.row.couponType" prop-name="coupon_exchange_type"/>
</template>
</el-table-column>
<el-table-column label="要兑换的积分" prop="useIntegral"/>
<el-table-column label="活动时间" prop="beginTime" width="180">
<template slot-scope="scope">
<p>{{ scope.row.beginTime }}</p>
<p> ~ </p>
<p>{{ scope.row.endTime }}</p>
</template>
</el-table-column>
<el-table-column label="操作" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
@click="seeCouponList(scope.row)"
>领取记录
</el-button>
<el-button
size="mini"
type="text"
@click="handleUpdate(scope.row)"
v-hasPermi="['act:couponActivity:opt']"
>修改
</el-button>
<el-button
size="mini"
type="text"
@click="handleDelete(scope.row)"
v-if="scope.row.leftCount === scope.row.totalCount"
v-hasPermi="['act:couponActivity:opt']"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<InBody v-show="total>0">
<pagination
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</InBody>
<!-- 添加或修改优惠券活动表对话框 -->
<el-dialog :title="title" :visible.sync="open" width="50%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="108px">
<el-form-item label="活动名称" prop="title">
<el-input v-model="form.title" placeholder="请输入活动名称"/>
</el-form-item>
<el-form-item label="发放数量" prop="totalCount">
<el-input-number v-model="form.totalCount" placeholder="请输入发放数量" style="width:220px" :min="1"
:disabled="form.id"/>
</el-form-item>
<el-form-item label="每人限领" prop="userLimit">
<el-input v-model="form.userLimit" style="width:220px">
<template slot="append"></template>
</el-input>
</el-form-item>
<el-form-item label="最低消费金额" prop="minAmount">
<el-input v-model="form.minAmount" style="width:220px">
<template slot="append"></template>
</el-input>
</el-form-item>
<el-form-item label="优惠券金额" prop="couponAmount">
<el-input v-model="form.couponAmount" style="width:220px">
<template slot="append"></template>
</el-input>
</el-form-item>
<el-form-item label="兑换类型" prop="couponType">
<el-radio-group v-model="form.couponType" :disabled="form.id">
<el-radio :label="1">免费兑换</el-radio>
<el-radio :label="2">积分兑换</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="要兑换的积分" prop="useIntegral" v-if="form.couponType === 2">
<el-input-number v-model="form.useIntegral" placeholder="请输入要兑换的积分" style="width:220px"
:disabled="form.id"/>
</el-form-item>
<el-form-item label="活动开始时间" prop="beginTime">
<el-date-picker clearable size="small"
v-model="form.beginTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择活动开始时间">
</el-date-picker>
</el-form-item>
<el-form-item label="活动结束时间" prop="endTime">
<el-date-picker clearable size="small"
v-model="form.endTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择活动结束时间">
</el-date-picker>
</el-form-item>
<el-form-item label="使用范围" prop="useScope">
<el-radio-group v-model="form.useScope" :disabled="form.id">
<el-radio :label="1">全场通用</el-radio>
<el-radio :label="2">指定商品可用</el-radio>
<el-radio :label="3">指定商品不可用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="商品列表" prop="productIds" v-if="[2,3].includes(form.useScope)">
<el-button @click="chooseSku" size="small">选择商品</el-button>
<el-table :data="productList" class="mt10" max-height="300px" border>
<el-table-column label="菜品信息">
<template v-slot="{row}">
<div class="flex-center">
<el-image v-if="row.pic" :src="row.pic" :preview-src-list="[row.pic]" class="small-img circle-img"/>
<span class="ml5">{{ row.name }}</span>
</div>
</template>
</el-table-column>
<el-table-column label="操作">
<template v-slot="{row}">
<span class="red ml5 pointer" @click="delProduct(row)">删除</span>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<product-select ref="productSelect" @onComplete="completeProductIds"/>
<receive-list ref="receiveListRef"/>
</div>
</template>
<script>
import {
addCouponActivity,
delCouponActivity,
exportCouponActivity,
listCouponActivity,
updateCouponActivity
} from "@/api/act/couponActivity";
import ProductSelect from "@/views/pms/product/productSelect.vue";
import receiveList from "@/views/act/couponActivity/receiveList.vue";
export default {
name: "CouponActivity",
components: {ProductSelect, receiveList},
dicts: ['coupon_use_scope', 'coupon_exchange_type'],
data() {
return {
//
loading: true,
productList: [],
//
exportLoading: false,
//
ids: [],
//
total: 0,
//
CouponActivityList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
title: null,
useScope: null,
couponType: null,
},
//
form: {},
//
rules: {
title: [
{required: true, message: "活动名称不能为空", trigger: "blur"}
],
useScope: [
{required: true, message: "使用范围不能为空", trigger: "change"}
],
totalCount: [
{required: true, message: "发行总数不能为空", trigger: "blur"}
],
userLimit: [
{required: true, message: "每人限领不能为空", trigger: "blur"}
],
couponAmount: [
{required: true, message: "优惠券金额不能为空", trigger: "blur"}
],
couponType: [
{required: true, message: "兑换类型不能为空", trigger: "change"}
],
beginTime: [
{required: true, message: "活动开始时间不能为空", trigger: "change"}
],
endTime: [
{required: true, message: "活动结束时间不能为空", trigger: "change"}
],
},
showMoreCondition: false
};
},
created() {
this.getList();
},
methods: {
delProduct(item) {
this.productList = this.productList.filter(it => it.id !== item.id)
this.completeProductIds([])
},
completeProductIds(products) {
this.productList = this.productList.concat(products)
if (!this.productList.length) {
this.form.productIds = null
return
}
this.form.productIds = this.productList.map(it => it.id).join()
},
chooseSku() {
this.$refs.productSelect.init(this.productList.map(it => it.id))
},
/** 查询优惠券活动表列表 */
getList() {
this.loading = true;
const {pageNum, pageSize} = this.queryParams;
const query = {...this.queryParams, pageNum: undefined, pageSize: undefined};
const pageReq = {page: pageNum - 1, size: pageSize};
listCouponActivity(query, pageReq).then(response => {
const {content, totalElements} = response
this.CouponActivityList = content;
this.total = totalElements;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
title: null,
useScope: 1,
productIds: null,
totalCount: null,
userLimit: 1,
couponAmount: null,
minAmount: null,
useIntegral: null,
couponType: 1,
beginTime: null,
endTime: null,
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 新增按钮操作 */
handleAdd() {
this.productList = []
this.reset();
this.open = true;
this.title = "添加优惠券活动";
},
seeCouponList(row) {
this.$refs.receiveListRef.init(row.id)
},
/** 修改按钮操作 */
handleUpdate(row) {
this.productList = row.productList
this.form = row;
this.open = true;
this.title = "修改优惠券活动";
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
delete this.form.createTime
updateCouponActivity(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addCouponActivity(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除优惠券活动【' + row.title + '】?').then(function () {
return delCouponActivity(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal.confirm('是否确认导出所有优惠券活动表数据项?').then(() => {
this.exportLoading = true;
return exportCouponActivity(queryParams);
}).then(response => {
this.$download.download(response);
this.exportLoading = false;
}).catch(() => {
});
}
}
};
</script>

View File

@ -0,0 +1,95 @@
<template>
<el-dialog title="领取记录" :visible.sync="open" width="80%" append-to-body>
<el-form :model="queryParams" :inline="true" label-width="100px" size="medium" class="ry_form">
<el-form-item label="使用状态" prop="useStatus">
<DictRadio v-model="queryParams.useStatus" @change="handleQuery" size="small"
:radioData="dict?.type.activity_coupon_status" :showAll="'all'"/>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="tableList" border>
<el-table-column label="券ID" prop="id" />
<el-table-column label="用户信息 " >
<template slot-scope="scope">
<div class="flex-center">
<el-avatar :src="scope.row.avatar"></el-avatar>
<div class="tl ml5">
<p>{{scope.row.nickname}}</p>
<p>{{scope.row.phone}}</p>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="领取时间" prop="createTime" width="180" />
<el-table-column label="使用状态" >
<template slot-scope="scope">
<dict-tag :value="scope.row.useStatus" prop-name="activity_coupon_status"/>
</template>
</el-table-column>
<el-table-column label="有效期" width="180" >
<template slot-scope="scope">
<p>{{ scope.row.beginTime}}</p>
<p> ~ </p>
<p>{{ scope.row.endTime}}</p>
</template>
</el-table-column>
<el-table-column label="订单号" prop="orderId" />
<el-table-column label="使用时间" prop="useTime" width="180" />
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</el-dialog>
</template>
<script>
import {listMemberCoupon} from "@/api/act/memberCoupon";
export default {
dicts: ['activity_coupon_status'],
data(){
return{
open:false,
loading: false,
tableList: [],
queryParams: {
pageNum: 1,
pageSize: 10,
useStatus: null,
couponActivityId: null,
},
total: 0,
}
},
methods:{
async init(activityId){
if (!activityId) {
return
}
this.queryParams.couponActivityId = activityId
await this.handleQuery()
this.open = true
},
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
getList() {
this.loading = true;
const {pageNum, pageSize} = this.queryParams;
const query = {...this.queryParams, pageNum: undefined, pageSize: undefined};
const pageReq = {page: pageNum - 1, size: pageSize};
return listMemberCoupon(query, pageReq).then(response => {
const { content, totalElements } = response
this.tableList = content;
this.total = totalElements;
this.loading = false;
});
},
}
}
</script>

View File

@ -0,0 +1,484 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="活动id" prop="couponActivityId">
<el-input
v-model="queryParams.couponActivityId"
placeholder="请输入活动id"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="用户id" prop="memberId">
<el-input
v-model="queryParams.memberId"
placeholder="请输入用户id"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="活动名称" prop="title">
<el-input
v-model="queryParams.title"
placeholder="请输入活动名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="使用范围 1全场通用 2指定商品可用 3指定商品不可用" prop="useScope">
<el-input
v-model="queryParams.useScope"
placeholder="请输入使用范围 1全场通用 2指定商品可用 3指定商品不可用"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="商品id集合逗号分隔" prop="productIds">
<el-input
v-model="queryParams.productIds"
placeholder="请输入商品id集合逗号分隔"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="优惠券金额" prop="couponAmount">
<el-input
v-model="queryParams.couponAmount"
placeholder="请输入优惠券金额"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="最低消费金额" prop="minAmount">
<el-input
v-model="queryParams.minAmount"
placeholder="请输入最低消费金额"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<template v-if="showMoreCondition">
<el-form-item label="要兑换的积分" prop="useIntegral">
<el-input
v-model="queryParams.useIntegral"
placeholder="请输入要兑换的积分"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="1免费兑换 2积分兑换" prop="couponType">
<el-select v-model="queryParams.couponType" placeholder="请选择1免费兑换 2积分兑换" clearable size="small">
<el-option label="请选择字典生成" value="" />
</el-select>
</el-form-item>
<el-form-item label="券开始时间" prop="beginTime">
<el-date-picker
clearable
size="small"
v-model="queryParams.beginTime"
type="datetime"
value-format="yyyy-MM-ddTHH:mm:ss"
placeholder="选择券开始时间">
</el-date-picker>
</el-form-item>
<el-form-item label="券结束时间" prop="endTime">
<el-date-picker
clearable
size="small"
v-model="queryParams.endTime"
type="datetime"
value-format="yyyy-MM-ddTHH:mm:ss"
placeholder="选择券结束时间">
</el-date-picker>
</el-form-item>
<el-form-item label="0未使用 1已使用" prop="useStatus">
<el-select v-model="queryParams.useStatus" placeholder="请选择0未使用 1已使用" clearable size="small">
<el-option label="请选择字典生成" value="" />
</el-select>
</el-form-item>
<el-form-item label="订单id" prop="orderId">
<el-input
v-model="queryParams.orderId"
placeholder="请输入订单id"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="使用时间" prop="useTime">
<el-date-picker
clearable
size="small"
v-model="queryParams.useTime"
type="datetime"
value-format="yyyy-MM-ddTHH:mm:ss"
placeholder="选择使用时间">
</el-date-picker>
</el-form-item>
</template>
<el-form-item class="flex_one tr">
<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-button :icon="showMoreCondition ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" size="mini" @click="showMoreCondition = !showMoreCondition">{{showMoreCondition ? '收起条件' : '展开条件'}}</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['act:memberCoupon:add']"
>新增</el-button>
</el-col>
</el-col>
</el-row>
<el-table v-loading="loading" :data="MemberCouponList" @selection-change="handleSelectionChange" border>
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="活动id" prop="couponActivityId"/>
<el-table-column label="用户id" prop="memberId"/>
<el-table-column label="活动名称" prop="title"/>
<el-table-column label="使用范围 1全场通用 2指定商品可用 3指定商品不可用" prop="useScope"/>
<el-table-column label="商品id集合逗号分隔" prop="productIds"/>
<el-table-column label="优惠券金额" prop="couponAmount"/>
<el-table-column label="最低消费金额" prop="minAmount"/>
<el-table-column label="要兑换的积分" prop="useIntegral"/>
<el-table-column label="1免费兑换 2积分兑换" prop="couponType"/>
<el-table-column label="券开始时间" prop="beginTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.beginTime, '') }}</span>
</template>
</el-table-column>
<el-table-column label="券结束时间" prop="endTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.endTime, '') }}</span>
</template>
</el-table-column>
<el-table-column label="0未使用 1已使用" prop="useStatus"/>
<el-table-column label="订单id" prop="orderId"/>
<el-table-column label="使用时间" prop="useTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.useTime, '') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['act:memberCoupon:edit']"
>修改
</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['act:memberCoupon:remove']"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<InBody v-show="total>0">
<pagination
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</InBody>
<!-- 添加或修改用户领券记录对话框 -->
<el-dialog :title="title" :visible.sync="open" width="50%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="108px" inline class="dialog-form-two">
<el-form-item label="活动id" prop="couponActivityId">
<el-input v-model="form.couponActivityId" placeholder="请输入活动id" />
</el-form-item>
<el-form-item label="用户id" prop="memberId">
<el-input v-model="form.memberId" placeholder="请输入用户id" />
</el-form-item>
<el-form-item label="活动名称" prop="title">
<el-input v-model="form.title" placeholder="请输入活动名称" />
</el-form-item>
<el-form-item label="使用范围 1全场通用 2指定商品可用 3指定商品不可用" prop="useScope">
<el-input v-model="form.useScope" placeholder="请输入使用范围 1全场通用 2指定商品可用 3指定商品不可用" />
</el-form-item>
<el-form-item label="商品id集合逗号分隔" prop="productIds">
<el-input v-model="form.productIds" placeholder="请输入商品id集合逗号分隔" />
</el-form-item>
<el-form-item label="优惠券金额" prop="couponAmount">
<el-input v-model="form.couponAmount" placeholder="请输入优惠券金额" />
</el-form-item>
<el-form-item label="最低消费金额" prop="minAmount">
<el-input v-model="form.minAmount" placeholder="请输入最低消费金额" />
</el-form-item>
<el-form-item label="要兑换的积分" prop="useIntegral">
<el-input v-model="form.useIntegral" placeholder="请输入要兑换的积分" />
</el-form-item>
<el-form-item label="1免费兑换 2积分兑换" prop="couponType">
<el-select v-model="form.couponType" placeholder="请选择1免费兑换 2积分兑换">
<el-option label="请选择字典生成" value="" />
</el-select>
</el-form-item>
<el-form-item label="券开始时间" prop="beginTime">
<el-date-picker clearable size="small"
v-model="form.beginTime"
type="datetime"
value-format="yyyy-MM-ddTHH:mm:ss"
placeholder="选择券开始时间">
</el-date-picker>
</el-form-item>
<el-form-item label="券结束时间" prop="endTime">
<el-date-picker clearable size="small"
v-model="form.endTime"
type="datetime"
value-format="yyyy-MM-ddTHH:mm:ss"
placeholder="选择券结束时间">
</el-date-picker>
</el-form-item>
<el-form-item label="0未使用 1已使用">
<el-radio-group v-model="form.useStatus">
<el-radio label="1">请选择字典生成</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="订单id" prop="orderId">
<el-input v-model="form.orderId" placeholder="请输入订单id" />
</el-form-item>
<el-form-item label="使用时间" prop="useTime">
<el-date-picker clearable size="small"
v-model="form.useTime"
type="datetime"
value-format="yyyy-MM-ddTHH:mm:ss"
placeholder="选择使用时间">
</el-date-picker>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
addMemberCoupon,
delMemberCoupon,
exportMemberCoupon,
getMemberCoupon,
listMemberCoupon,
updateMemberCoupon
} from "@/api/act/memberCoupon";
export default {
name: "MemberCoupon",
data() {
return {
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
MemberCouponList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
couponActivityId: null,
memberId: null,
title: null,
useScope: null,
productIds: null,
couponAmount: null,
minAmount: null,
useIntegral: null,
couponType: null,
beginTime: null,
endTime: null,
useStatus: null,
orderId: null,
useTime: null,
},
//
form: {},
//
rules: {
couponActivityId: [
{ required: true, message: "活动id不能为空", trigger: "blur" }
],
title: [
{ required: true, message: "活动名称不能为空", trigger: "blur" }
],
useScope: [
{ required: true, message: "使用范围 1全场通用 2指定商品可用 3指定商品不可用不能为空", trigger: "blur" }
],
couponAmount: [
{ required: true, message: "优惠券金额不能为空", trigger: "blur" }
],
couponType: [
{ required: true, message: "1免费兑换 2积分兑换不能为空", trigger: "change" }
],
beginTime: [
{ required: true, message: "券开始时间不能为空", trigger: "blur" }
],
endTime: [
{ required: true, message: "券结束时间不能为空", trigger: "blur" }
],
useStatus: [
{ required: true, message: "0未使用 1已使用不能为空", trigger: "blur" }
],
},
showMoreCondition: false
};
},
created() {
this.getList();
},
methods: {
/** 查询用户领券记录列表 */
getList() {
this.loading = true;
const {pageNum, pageSize} = this.queryParams;
const query = {...this.queryParams, pageNum: undefined, pageSize: undefined};
const pageReq = {page: pageNum - 1, size: pageSize};
listMemberCoupon(query, pageReq).then(response => {
const { content, totalElements } = response
this.MemberCouponList = content;
this.total = totalElements;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
couponActivityId: null,
memberId: null,
title: null,
useScope: null,
productIds: null,
couponAmount: null,
minAmount: null,
useIntegral: null,
couponType: null,
beginTime: null,
endTime: null,
useStatus: 0,
orderId: null,
useTime: null,
createTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加用户领券记录";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getMemberCoupon(id).then(response => {
this.form = response;
this.open = true;
this.title = "修改用户领券记录";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateMemberCoupon(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addMemberCoupon(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除用户领券记录编号为"' + ids + '"的数据项?').then(function() {
return delMemberCoupon(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal.confirm('是否确认导出所有用户领券记录数据项?').then(() => {
this.exportLoading = true;
return exportMemberCoupon(queryParams);
}).then(response => {
this.$download.download(response);
this.exportLoading = false;
}).catch(() => {});
}
}
};
</script>

View File

@ -0,0 +1,257 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="统计日期" prop="date">
<el-date-picker v-model="dateRange" style="width: 240px" value-format="yyyy-MM-dd" type="daterange"
:clearable="true" :picker-options='pickerOptions' range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"></el-date-picker>
</el-form-item>
<el-form-item class="flex_one tr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="awsSystemStatisticsList" @selection-change="handleSelectionChange" border>
<el-table-column label="统计日期" prop="date" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.date, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="登录用户数" prop="loginMemberCount"/>
<el-table-column label="注册用户数" prop="registerMemberCount"/>
<el-table-column label="加购用户数" prop="addCartMemberCount"/>
<el-table-column label="下单用户数" prop="createOrderMemberCount"/>
<el-table-column label="成交用户数" prop="dealMemberCount"/>
<el-table-column label="下单数" prop="orderCount"/>
<el-table-column label="成交数" prop="dealCount"/>
<el-table-column label="成交金额" prop="dealAmount">
<template v-slot="scope">
{{ scope.row.dealAmount.toFixed(2) }}
</template>
</el-table-column>
<el-table-column label="售后数" prop="aftersaleCount"/>
<el-table-column label="售后金额" prop="aftersaleAmount">
<template v-slot="scope">
{{ scope.row.aftersaleAmount.toFixed(2) }}
</template>
</el-table-column>
</el-table>
<InBody v-show="total>0">
<pagination
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</InBody>
</div>
</template>
<script>
import {
addAwsSystemStatistics,
delAwsSystemStatistics,
exportAwsSystemStatistics,
getAwsSystemStatistics,
listAwsSystemStatistics,
updateAwsSystemStatistics
} from "@/api/aws/systemStatistics";
import dateUtil from "@/utils/DateUtil";
export default {
name: "AwsSystemStatistics",
data() {
return {
//
loading: true,
pickerOptions: {
shortcuts: dateUtil.getTimeShort()
},
dateRange: [],
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
awsSystemStatisticsList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10
},
//
form: {},
//
rules: {
date: [
{ required: true, message: "统计日期不能为空", trigger: "blur" }
],
loginMemberCount: [
{ required: true, message: "登录用户数不能为空", trigger: "blur" }
],
registerMemberCount: [
{ required: true, message: "注册用户数不能为空", trigger: "blur" }
],
addCartMemberCount: [
{ required: true, message: "加购用户数不能为空", trigger: "blur" }
],
createOrderMemberCount: [
{ required: true, message: "下单用户数不能为空", trigger: "blur" }
],
dealMemberCount: [
{ required: true, message: "成交用户数不能为空", trigger: "blur" }
],
orderCount: [
{ required: true, message: "下单数不能为空", trigger: "blur" }
],
dealCount: [
{ required: true, message: "成交数不能为空", trigger: "blur" }
],
dealAmount: [
{ required: true, message: "成交金额不能为空", trigger: "blur" }
],
aftersaleCount: [
{ required: true, message: "售后数不能为空", trigger: "blur" }
],
aftersaleAmount: [
{ required: true, message: "售后金额不能为空", trigger: "blur" }
]
},
showMoreCondition: false
};
},
created() {
this.getList();
},
methods: {
/** 查询系统数据统计列表 */
getList() {
this.loading = true;
const {pageNum, pageSize} = this.queryParams;
let query = {...this.queryParams, pageNum: undefined, pageSize: undefined};
const pageReq = {page: pageNum - 1, size: pageSize};
if (this.dateRange && this.dateRange.length > 0){
query = {...this.addDateRange3(query, this.dateRange)}
}
listAwsSystemStatistics(query, pageReq).then(response => {
const { content, totalElements } = response
this.awsSystemStatisticsList = content;
this.total = totalElements;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
date: null,
loginMemberCount: null,
registerMemberCount: null,
addCartMemberCount: null,
createOrderMemberCount: null,
dealMemberCount: null,
orderCount: null,
dealCount: null,
dealAmount: null,
aftersaleCount: null,
aftersaleAmount: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加系统数据统计";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getAwsSystemStatistics(id).then(response => {
this.form = response;
this.open = true;
this.title = "修改系统数据统计";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateAwsSystemStatistics(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addAwsSystemStatistics(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除系统数据统计编号为"' + ids + '"的数据项?').then(function() {
return delAwsSystemStatistics(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal.confirm('是否确认导出所有系统数据统计数据项?').then(() => {
this.exportLoading = true;
return exportAwsSystemStatistics(queryParams);
}).then(response => {
this.$download.download(response);
this.exportLoading = false;
}).catch(() => {});
}
}
};
</script>

View File

@ -0,0 +1,59 @@
<template>
<div class="w200">
<el-cascader
:props="{ checkStrictly: true }"
ref="AddressSelector"
v-model="tempValue"
:options="menuOptions"
v-bind="$props"
clearable
placeholder="请选择..."
:size="size"
/>
</div>
</template>
<script>
import { useMallStore } from '@/store/modules/mall';
export default {
name: 'AddressSelector',
props: ['value', 'props', 'size'],
computed: {
areaSelect: {
get() {
return useMallStore().state.areaSelect;
}
},
tempValue: {
get() {
return this.value;
},
set(v) {
this.$emit('input', v);
}
},
menuOptions() {
if (!this.areaSelect || this.areaSelect.length === 0) {
return [];
}
this.recurs(this.areaSelect);
return this.areaSelect;
}
},
created() {
useMallStore().loadAreaSelect();
},
methods: {
recurs(list) {
list.forEach((it) => {
it.label = it.name;
it.value = it.name;
if (it.children) {
this.recurs(it.children);
}
});
}
}
};
</script>
<style></style>

View File

@ -0,0 +1,49 @@
<template>
<el-select v-model="value1" placeholder="选择品牌" ref="brandSelect" @change="handleBrandChange" clearable>
<el-option v-for="it in options" :key="it.id" :value="it.id" :label="it.name">{{ it.name }}</el-option>
</el-select>
</template>
<script>
import { useMallStore } from '@/store/modules/mall';
export default {
name: 'BrandSelect',
props: ['value'],
computed: {
brandList: {
get() {
return useMallStore().state.brandList;
}
},
value1: {
get() {
return this.value;
},
set(v) {
this.$emit('input', v);
}
},
options() {
return this.brandList;
}
},
methods: {
handleBrandChange(id) {
if (id) {
const brand = this.brandList.find((item) => {
return item.id == id;
});
this.$emit('change', brand.name);
} else {
this.$emit('change', null);
}
}
},
created() {
useMallStore().loadBrandList();
}
};
</script>
<style scoped></style>

View File

@ -0,0 +1,95 @@
<template>
<div class="sales-top">
<el-card>
<div slot="header" class="clearfix">
<el-row>
<el-col :span="6">
<div style="font-size: large">
<el-radio-group v-model="params.statType" size="small" @change="getData">
<el-radio-button label="2">商品销量榜</el-radio-button>
<el-radio-button label="1">规格销量榜</el-radio-button>
</el-radio-group>
</div>
</el-col>
<el-col :span="18">
<div style="text-align: right">
<el-radio-group v-model="params.type" size="small" @change="getData">
<el-radio-button label="0">今日</el-radio-button>
<el-radio-button label="7">近七日</el-radio-button>
<el-radio-button label="30">近三十日</el-radio-button>
</el-radio-group>
</div>
</el-col>
</el-row>
</div>
<el-table v-loading="loading" :data="salesTopData" :border="false">
<el-table-column type="index" width="80"></el-table-column>
<el-table-column prop="productName" label="商品名称"></el-table-column>
<el-table-column prop="spData" label="规格" v-if="params.statType == 1">
<template v-slot="scope">
<div v-for="(value, key) in JSON.parse(scope.row.spData)">{{ key }}{{ value }}&nbsp;</div>
</template>
</el-table-column>
<el-table-column label="主图" align="center" prop="pic">
<template slot-scope="{ row }">
<el-image v-if="row.pic" :src="row.pic" :preview-src-list="[row.pic]" class="small-img circle-img"/>
</template>
</el-table-column>
<el-table-column prop="totalSales" label="销量" width="120">
<template #default="{ row }">
{{ row.totalSales }}
</template>
</el-table-column>
</el-table>
</el-card>
</div>
</template>
<script>
import {goodsStatistics} from "@/api/statistics";
import dateUtil from '@/utils/DateUtil';
export default {
name: 'TopProduct',
data() {
return {
salesTopData: [],
params: {
statType: 1,
type:0,
size: 10,
startDate: '2023-02-01',
endDate: '2023-06-01'
},
loading: false
};
},
created() {
this.getData()
},
methods: {
getData(){
this.loading = true
let range= Number(this.params.type)
this.params.startDate = dateUtil.getAfterDate(-range)
this.params.endDate = dateUtil.getAfterDate(0)
goodsStatistics(this.params).then(res => {
this.salesTopData = res
this.loading = false
})
},
},
};
</script>
<style>
.sales-top {
margin: 20px;
}
.export-btn {
float: right;
margin-right: 20px;
}
</style>

View File

@ -0,0 +1,181 @@
<template>
<el-row :gutter="40" class="panel-group">
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('newVisitis')">
<div class="card-panel-icon-wrapper icon-people">
<svg-icon icon-class="peoples" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
New Visits
</div>
<count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('messages')">
<div class="card-panel-icon-wrapper icon-message">
<svg-icon icon-class="message" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
Messages
</div>
<count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('purchases')">
<div class="card-panel-icon-wrapper icon-money">
<svg-icon icon-class="money" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
Purchases
</div>
<count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('shoppings')">
<div class="card-panel-icon-wrapper icon-shopping">
<svg-icon icon-class="shopping" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
Shoppings
</div>
<count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num" />
</div>
</div>
</el-col>
</el-row>
</template>
<script>
import CountTo from 'vue-count-to'
export default {
components: {
CountTo
},
methods: {
handleSetLineChartData(type) {
this.$emit('handleSetLineChartData', type)
}
}
}
</script>
<style lang="scss" scoped>
.panel-group {
margin-top: 18px;
.card-panel-col {
margin-bottom: 32px;
}
.card-panel {
height: 108px;
cursor: pointer;
font-size: 12px;
position: relative;
overflow: hidden;
color: #666;
background: #fff;
box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
border-color: rgba(0, 0, 0, .05);
&:hover {
.card-panel-icon-wrapper {
color: #fff;
}
.icon-people {
background: #40c9c6;
}
.icon-message {
background: #36a3f7;
}
.icon-money {
background: #f4516c;
}
.icon-shopping {
background: #34bfa3
}
}
.icon-people {
color: #40c9c6;
}
.icon-message {
color: #36a3f7;
}
.icon-money {
color: #f4516c;
}
.icon-shopping {
color: #34bfa3
}
.card-panel-icon-wrapper {
float: left;
margin: 14px 0 0 14px;
padding: 16px;
transition: all 0.38s ease-out;
border-radius: 6px;
}
.card-panel-icon {
float: left;
font-size: 48px;
}
.card-panel-description {
float: right;
font-weight: bold;
margin: 26px;
margin-left: 0px;
.card-panel-text {
line-height: 18px;
color: rgba(0, 0, 0, 0.45);
font-size: 16px;
margin-bottom: 12px;
}
.card-panel-num {
font-size: 20px;
}
}
}
}
@media (max-width:550px) {
.card-panel-description {
display: none;
}
.card-panel-icon-wrapper {
float: none !important;
width: 100%;
height: 100%;
margin: 0 !important;
.svg-icon {
display: block;
margin: 14px auto !important;
float: none !important;
}
}
}
</style>

View File

@ -0,0 +1,67 @@
<template>
<el-cascader
ref="cascaderMallCatergory"
@change="handleMallCatergoryChange"
v-model="value1"
:options="menuOptions"
v-bind="$props"
clearable
placeholder="选择类目"
/>
</template>
<script>
import '@riophae/vue-treeselect/dist/vue-treeselect.css';
import { useMallStore } from '@/store/modules/mall';
export default {
name: 'ProductCategorySelect',
props: ['value', 'props'],
computed: {
productCategories: {
get() {
return useMallStore().state.productCategories;
}
},
value1: {
get() {
return this.value;
},
set(v) {
this.$emit('input', v);
}
},
menuOptions() {
if (!this.productCategories || this.productCategories.length === 0) {
return [];
}
this.recurs(this.productCategories);
return this.productCategories;
}
},
methods: {
handleMallCatergoryChange(e) {
if (e.length > 0) {
const arr = this.$refs['cascaderMallCatergory'].getCheckedNodes()[0].pathLabels;
this.$emit('change', arr);
} else {
this.$emit('change', '');
}
},
recurs(list) {
list.forEach((it) => {
it.label = it.name;
it.value = it.id;
if (it.children) {
this.recurs(it.children);
}
});
}
},
created() {
useMallStore().loadProductCategories();
}
};
</script>
<style scoped></style>

View File

@ -0,0 +1,3 @@
const elementIcons = ['platform-eleme', 'eleme', 'delete-solid', 'delete', 's-tools', 'setting', 'user-solid', 'user', 'phone', 'phone-outline', 'more', 'more-outline', 'star-on', 'star-off', 's-goods', 'goods', 'warning', 'warning-outline', 'question', 'info', 'remove', 'circle-plus', 'success', 'error', 'zoom-in', 'zoom-out', 'remove-outline', 'circle-plus-outline', 'circle-check', 'circle-close', 's-help', 'help', 'minus', 'plus', 'check', 'close', 'picture', 'picture-outline', 'picture-outline-round', 'upload', 'upload2', 'download', 'camera-solid', 'camera', 'video-camera-solid', 'video-camera', 'message-solid', 'bell', 's-cooperation', 's-order', 's-platform', 's-fold', 's-unfold', 's-operation', 's-promotion', 's-home', 's-release', 's-ticket', 's-management', 's-open', 's-shop', 's-marketing', 's-flag', 's-comment', 's-finance', 's-claim', 's-custom', 's-opportunity', 's-data', 's-check', 's-grid', 'menu', 'share', 'd-caret', 'caret-left', 'caret-right', 'caret-bottom', 'caret-top', 'bottom-left', 'bottom-right', 'back', 'right', 'bottom', 'top', 'top-left', 'top-right', 'arrow-left', 'arrow-right', 'arrow-down', 'arrow-up', 'd-arrow-left', 'd-arrow-right', 'video-pause', 'video-play', 'refresh', 'refresh-right', 'refresh-left', 'finished', 'sort', 'sort-up', 'sort-down', 'rank', 'loading', 'view', 'c-scale-to-original', 'date', 'edit', 'edit-outline', 'folder', 'folder-opened', 'folder-add', 'folder-remove', 'folder-delete', 'folder-checked', 'tickets', 'document-remove', 'document-delete', 'document-copy', 'document-checked', 'document', 'document-add', 'printer', 'paperclip', 'takeaway-box', 'search', 'monitor', 'attract', 'mobile', 'scissors', 'umbrella', 'headset', 'brush', 'mouse', 'coordinate', 'magic-stick', 'reading', 'data-line', 'data-board', 'pie-chart', 'data-analysis', 'collection-tag', 'film', 'suitcase', 'suitcase-1', 'receiving', 'collection', 'files', 'notebook-1', 'notebook-2', 'toilet-paper', 'office-building', 'school', 'table-lamp', 'house', 'no-smoking', 'smoking', 'shopping-cart-full', 'shopping-cart-1', 'shopping-cart-2', 'shopping-bag-1', 'shopping-bag-2', 'sold-out', 'sell', 'present', 'box', 'bank-card', 'money', 'coin', 'wallet', 'discount', 'price-tag', 'news', 'guide', 'male', 'female', 'thumb', 'cpu', 'link', 'connection', 'open', 'turn-off', 'set-up', 'chat-round', 'chat-line-round', 'chat-square', 'chat-dot-round', 'chat-dot-square', 'chat-line-square', 'message', 'postcard', 'position', 'turn-off-microphone', 'microphone', 'close-notification', 'bangzhu', 'time', 'odometer', 'crop', 'aim', 'switch-button', 'full-screen', 'copy-document', 'mic', 'stopwatch', 'medal-1', 'medal', 'trophy', 'trophy-1', 'first-aid-kit', 'discover', 'place', 'location', 'location-outline', 'location-information', 'add-location', 'delete-location', 'map-location', 'alarm-clock', 'timer', 'watch-1', 'watch', 'lock', 'unlock', 'key', 'service', 'mobile-phone', 'bicycle', 'truck', 'ship', 'basketball', 'football', 'soccer', 'baseball', 'wind-power', 'light-rain', 'lightning', 'heavy-rain', 'sunrise', 'sunrise-1', 'sunset', 'sunny', 'cloudy', 'partly-cloudy', 'cloudy-and-sunny', 'moon', 'moon-night', 'dish', 'dish-1', 'food', 'chicken', 'fork-spoon', 'knife-fork', 'burger', 'tableware', 'sugar', 'dessert', 'ice-cream', 'hot-water', 'water-cup', 'coffee-cup', 'cold-drink', 'goblet', 'goblet-full', 'goblet-square', 'goblet-square-full', 'refrigerator', 'grape', 'watermelon', 'cherry', 'apple', 'pear', 'orange', 'coffee', 'ice-tea', 'ice-drink', 'milk-tea', 'potato-strips', 'lollipop', 'ice-cream-square', 'ice-cream-round']
export default elementIcons

View File

@ -0,0 +1,87 @@
<template>
<div class="icons-container">
<aside>
<a href="#" target="_blank">Add and use
</a>
</aside>
<el-tabs type="border-card">
<el-tab-pane label="Icons">
<div v-for="item of svgIcons" :key="item">
<el-tooltip placement="top">
<div slot="content">
{{ generateIconCode(item) }}
</div>
<div class="icon-item">
<svg-icon :icon-class="item" class-name="disabled" />
<span>{{ item }}</span>
</div>
</el-tooltip>
</div>
</el-tab-pane>
<el-tab-pane label="Element-UI Icons">
<div v-for="item of elementIcons" :key="item">
<el-tooltip placement="top">
<div slot="content">
{{ generateElementIconCode(item) }}
</div>
<div class="icon-item">
<i :class="'el-icon-' + item" />
<span>{{ item }}</span>
</div>
</el-tooltip>
</div>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import svgIcons from './svg-icons'
import elementIcons from './element-icons'
export default {
name: 'Icons',
data() {
return {
svgIcons,
elementIcons
}
},
methods: {
generateIconCode(symbol) {
return `<svg-icon icon-class="${symbol}" />`
},
generateElementIconCode(symbol) {
return `<i class="el-icon-${symbol}" />`
}
}
}
</script>
<style lang="scss" scoped>
.icons-container {
margin: 10px 20px 0;
overflow: hidden;
.icon-item {
margin: 20px;
height: 85px;
text-align: center;
width: 100px;
float: left;
font-size: 30px;
color: #24292e;
cursor: pointer;
}
span {
display: block;
font-size: 16px;
margin-top: 10px;
}
.disabled {
pointer-events: none;
}
}
</style>

View File

@ -0,0 +1,10 @@
const req = require.context('../../../assets/icons/svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys()
const re = /\.\/(.*)\.svg/
const svgIcons = requireAll(req).map(i => {
return i.match(re)[1]
})
export default svgIcons

View File

@ -0,0 +1,102 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
const animationDuration = 6000
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: { //
type: 'shadow' // 线'line' | 'shadow'
}
},
grid: {
top: 10,
left: '2%',
right: '2%',
bottom: '3%',
containLabel: true
},
xAxis: [{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisTick: {
alignWithLabel: true
}
}],
yAxis: [{
type: 'value',
axisTick: {
show: false
}
}],
series: [{
name: 'pageA',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [79, 52, 200, 334, 390, 330, 220],
animationDuration
}, {
name: 'pageB',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [80, 52, 200, 334, 390, 330, 220],
animationDuration
}, {
name: 'pageC',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [30, 52, 200, 334, 390, 330, 220],
animationDuration
}]
})
}
}
}
</script>

View File

@ -0,0 +1,135 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '350px'
},
autoResize: {
type: Boolean,
default: true
},
chartData: {
type: Object,
required: true
}
},
data() {
return {
chart: null
}
},
watch: {
chartData: {
deep: true,
handler(val) {
this.setOptions(val)
}
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.setOptions(this.chartData)
},
setOptions({ expectedData, actualData } = {}) {
this.chart.setOption({
xAxis: {
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
boundaryGap: false,
axisTick: {
show: false
}
},
grid: {
left: 10,
right: 10,
bottom: 20,
top: 30,
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
},
padding: [5, 10]
},
yAxis: {
axisTick: {
show: false
}
},
legend: {
data: ['expected', 'actual']
},
series: [{
name: 'expected', itemStyle: {
normal: {
color: '#FF005A',
lineStyle: {
color: '#FF005A',
width: 2
}
}
},
smooth: true,
type: 'line',
data: expectedData,
animationDuration: 2800,
animationEasing: 'cubicInOut'
},
{
name: 'actual',
smooth: true,
type: 'line',
itemStyle: {
normal: {
color: '#3888fa',
lineStyle: {
color: '#3888fa',
width: 2
},
areaStyle: {
color: '#f3f8ff'
}
}
},
data: actualData,
animationDuration: 2800,
animationEasing: 'quadraticOut'
}]
})
}
}
}
</script>

View File

@ -0,0 +1,234 @@
<template>
<el-card style="margin: 20px 20px; font-size: 14px;">
<div slot="header" class="clearfix">
<el-row>
<el-col :span="6">
<div style="font-weight: bold;font-size: 16px">订单统计</div>
</el-col>
<el-col :span="18">
<div style="text-align: right">
<el-radio-group v-model="params.type" size="small" @change="orderStat">
<el-radio-button label="1">近七日</el-radio-button>
<el-radio-button label="2">近三十日</el-radio-button>
</el-radio-group>
</div>
</el-col>
</el-row>
</div>
<div :style="{minHeight:height,minWidth:width}">
<div ref="chart" class="chart" :style="{height:height,width:width}"/>
</div>
</el-card>
</template>
<script>
import {orderStatistics} from "@/api/statistics";
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
export default {
mixins: [resize],
name: "OrderLineChart",
props: {
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '440px'
},
autoResize: {
type: Boolean,
default: true
},
},
data() {
return {
pickerOptions: {
shortcuts: [{
text: '最近一周',
onClick(picker) {
const end = new Date();
let start = new Date();
start.setFullYear(2018);
start.setMonth(10);
start.setDate(1);
end.setTime(start.getTime() + 3600 * 1000 * 24 * 7);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一月',
onClick(picker) {
const end = new Date();
let start = new Date();
start.setFullYear(2018);
start.setMonth(10);
start.setDate(1);
end.setTime(start.getTime() + 3600 * 1000 * 24 * 30);
picker.$emit('pick', [start, end]);
}
}]
},
orderCountDate: '',
params: {
type: 2
},
chartData: {},
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
created() {
this.orderStat()
},
methods: {
initChart() {
this.chart = echarts.init(this.$refs.chart, 'macarons')
this.setOptions(this.chartData)
},
setOptions({dateList, orderAmount, orderCount} = {}) {
this.chart.setOption({
title: {
text: '订单量趋势',
textStyle: {
fontSize: 14,
fontWeight: 'bolder',
color: '#000000' //
},
},
xAxis: {
data: dateList,
type: 'category',
boundaryGap: false,
axisLabel: {
rotate: 40
},
textStyle: {
fontSize: 12,
},
axisTick: {
show: false
},
axisLine: {
lineStyle: {
color: "#000000"
}
},
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
},
padding: [5, 10]
},
yAxis: [
{
type: 'value',
name: '金额',
position: 'left',
alignTicks: true,
splitLine:{
show: false
},
axisTick:{
show: false
},
axisLine: {
show: false,
lineStyle: {
color: "#000000"
}
},
},
{
type: 'value',
name: '数量',
minInterval:1,
position: 'right',
splitLine:{
show: false
},
axisTick:{
show: false
},
axisLine: {
show: false,
lineStyle: {
color: "#000000"
}
},
}
],
legend: {
data: ['订单金额', '订单数']
},
series: [
{
name: '订单金额',
itemStyle: {
normal: {
color: '#5b8ff9',
}
},
type: 'bar',
barMaxWidth: 20,
data: orderAmount,
animationDuration: 2800,
animationEasing: 'cubicInOut'
},
{
name: '订单数',
smooth: true,
type: 'line',
itemStyle: {
normal: {
color: '#5ccfd9',
}
},
yAxisIndex: 1,
data: orderCount,
animationDuration: 2800,
animationEasing: 'quadraticOut'
}
]
})
},
handleDateChange() {
this.getData();
},
orderStat(){
orderStatistics(this.params).then(res => {
const orderAmount = res.map(it => {
return it.orderAmount
})
const orderCount = res.map(it => {
return it.orderCount
})
const dateList = res.map(it => {
return it.date.substr(5)
})
this.chartData = {dateList, orderAmount, orderCount}
this.initChart()
})
}
}
}
</script>
<style scoped lang="scss">
</style>

View File

@ -0,0 +1,181 @@
<template>
<el-row :gutter="40" class="panel-group">
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('newVisitis')">
<div class="card-panel-icon-wrapper icon-people">
<svg-icon icon-class="peoples" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
访客
</div>
<count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('messages')">
<div class="card-panel-icon-wrapper icon-message">
<svg-icon icon-class="message" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
消息
</div>
<count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('purchases')">
<div class="card-panel-icon-wrapper icon-money">
<svg-icon icon-class="money" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
金额
</div>
<count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('shoppings')">
<div class="card-panel-icon-wrapper icon-shopping">
<svg-icon icon-class="shopping" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
订单
</div>
<count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num" />
</div>
</div>
</el-col>
</el-row>
</template>
<script>
import CountTo from 'vue-count-to'
export default {
components: {
CountTo
},
methods: {
handleSetLineChartData(type) {
this.$emit('handleSetLineChartData', type)
}
}
}
</script>
<style lang="scss" scoped>
.panel-group {
margin-top: 18px;
.card-panel-col {
margin-bottom: 32px;
}
.card-panel {
height: 108px;
cursor: pointer;
font-size: 12px;
position: relative;
overflow: hidden;
color: #666;
background: #fff;
box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
border-color: rgba(0, 0, 0, .05);
&:hover {
.card-panel-icon-wrapper {
color: #fff;
}
.icon-people {
background: #40c9c6;
}
.icon-message {
background: #36a3f7;
}
.icon-money {
background: #f4516c;
}
.icon-shopping {
background: #34bfa3
}
}
.icon-people {
color: #40c9c6;
}
.icon-message {
color: #36a3f7;
}
.icon-money {
color: #f4516c;
}
.icon-shopping {
color: #34bfa3
}
.card-panel-icon-wrapper {
float: left;
margin: 14px 0 0 14px;
padding: 16px;
transition: all 0.38s ease-out;
border-radius: 6px;
}
.card-panel-icon {
float: left;
font-size: 48px;
}
.card-panel-description {
float: right;
font-weight: bold;
margin: 26px;
margin-left: 0px;
.card-panel-text {
line-height: 18px;
color: rgba(0, 0, 0, 0.45);
font-size: 16px;
margin-bottom: 12px;
}
.card-panel-num {
font-size: 20px;
}
}
}
}
@media (max-width:550px) {
.card-panel-description {
display: none;
}
.card-panel-icon-wrapper {
float: none !important;
width: 100%;
height: 100%;
margin: 0 !important;
.svg-icon {
display: block;
margin: 14px auto !important;
float: none !important;
}
}
}
</style>

View File

@ -0,0 +1,79 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
left: 'center',
bottom: '10',
data: ['Industries', 'Technology', 'Forex', 'Gold', 'Forecasts']
},
series: [
{
name: 'WEEKLY WRITE ARTICLES',
type: 'pie',
roseType: 'radius',
radius: [15, 95],
center: ['50%', '38%'],
data: [
{ value: 320, name: 'Industries' },
{ value: 240, name: 'Technology' },
{ value: 149, name: 'Forex' },
{ value: 100, name: 'Gold' },
{ value: 59, name: 'Forecasts' }
],
animationEasing: 'cubicInOut',
animationDuration: 2600
}
]
})
}
}
}
</script>

View File

@ -0,0 +1,116 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
const animationDuration = 3000
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: { //
type: 'shadow' // 线'line' | 'shadow'
}
},
radar: {
radius: '66%',
center: ['50%', '42%'],
splitNumber: 8,
splitArea: {
areaStyle: {
color: 'rgba(127,95,132,.3)',
opacity: 1,
shadowBlur: 45,
shadowColor: 'rgba(0,0,0,.5)',
shadowOffsetX: 0,
shadowOffsetY: 15
}
},
indicator: [
{ name: 'Sales', max: 10000 },
{ name: 'Administration', max: 20000 },
{ name: 'Information Techology', max: 20000 },
{ name: 'Customer Support', max: 20000 },
{ name: 'Development', max: 20000 },
{ name: 'Marketing', max: 20000 }
]
},
legend: {
left: 'center',
bottom: '10',
data: ['Allocated Budget', 'Expected Spending', 'Actual Spending']
},
series: [{
type: 'radar',
symbolSize: 0,
areaStyle: {
normal: {
shadowBlur: 13,
shadowColor: 'rgba(0,0,0,.2)',
shadowOffsetX: 0,
shadowOffsetY: 10,
opacity: 1
}
},
data: [
{
value: [5000, 7000, 12000, 11000, 15000, 14000],
name: 'Allocated Budget'
},
{
value: [4000, 9000, 15000, 15000, 13000, 11000],
name: 'Expected Spending'
},
{
value: [5500, 11000, 12000, 15000, 12000, 12000],
name: 'Actual Spending'
}
],
animationDuration: animationDuration
}]
})
}
}
}
</script>

View File

@ -0,0 +1,56 @@
import { debounce } from '@/utils'
export default {
data() {
return {
$_sidebarElm: null,
$_resizeHandler: null
}
},
mounted() {
this.initListener()
},
activated() {
if (!this.$_resizeHandler) {
// avoid duplication init
this.initListener()
}
// when keep-alive chart activated, auto resize
this.resize()
},
beforeDestroy() {
this.destroyListener()
},
deactivated() {
this.destroyListener()
},
methods: {
// use $_ for mixins properties
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
$_sidebarResizeHandler(e) {
if (e.propertyName === 'width') {
this.$_resizeHandler()
}
},
initListener() {
this.$_resizeHandler = debounce(() => {
this.resize()
}, 100)
window.addEventListener('resize', this.$_resizeHandler)
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
},
destroyListener() {
window.removeEventListener('resize', this.$_resizeHandler)
this.$_resizeHandler = null
this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
},
resize() {
const { chart } = this
chart && chart.resize()
}
}
}

View File

@ -0,0 +1,15 @@
<template>
<i-frame :src="url" />
</template>
<script>
import iFrame from "@/components/iFrame/index";
export default {
name: "Druid",
components: { iFrame },
data() {
return {
url: process.env.VUE_APP_BASE_API + "/druid/login.html"
};
},
};
</script>

View File

@ -0,0 +1,515 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="任务名称" prop="jobName">
<el-input
v-model="queryParams.jobName"
placeholder="请输入任务名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="任务组名" prop="jobGroup">
<el-select v-model="queryParams.jobGroup" placeholder="请选择任务组名" clearable>
<el-option
v-for="dict in dict?.type.sys_job_group"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="任务状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择任务状态" clearable>
<el-option
v-for="dict in dict.type.sys_job_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['monitor:job:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['monitor:job:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['monitor:job:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['monitor:job:export']"
>导出</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="el-icon-s-operation"
size="mini"
@click="handleJobLog"
v-hasPermi="['monitor:job:query']"
>日志</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="jobList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="任务编号" width="100" align="center" prop="jobId" />
<el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
<el-table-column label="任务组名" align="center" prop="jobGroup">
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_job_group" :value="scope.row.jobGroup"/>
</template>
</el-table-column>
<el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" />
<el-table-column label="cron执行表达式" align="center" prop="cronExpression" :show-overflow-tooltip="true" />
<el-table-column label="状态" align="center">
<template slot-scope="scope">
<el-switch
v-model="scope.row.status"
active-value="0"
inactive-value="1"
@change="handleStatusChange(scope.row)"
></el-switch>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['monitor:job:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['monitor:job:remove']"
>删除</el-button>
<el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['monitor:job:changeStatus', 'monitor:job:query']">
<span class="el-dropdown-link">
<i class="el-icon-d-arrow-right el-icon--right"></i>更多
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="handleRun" icon="el-icon-caret-right"
v-hasPermi="['monitor:job:changeStatus']">执行一次</el-dropdown-item>
<el-dropdown-item command="handleView" icon="el-icon-view"
v-hasPermi="['monitor:job:query']">任务详细</el-dropdown-item>
<el-dropdown-item command="handleJobLog" icon="el-icon-s-operation"
v-hasPermi="['monitor:job:query']">调度日志</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改定时任务对话框 -->
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-row>
<el-col :span="12">
<el-form-item label="任务名称" prop="jobName">
<el-input v-model="form.jobName" placeholder="请输入任务名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="任务分组" prop="jobGroup">
<el-select v-model="form.jobGroup" placeholder="请选择任务分组">
<el-option
v-for="dict in dict.type.sys_job_group"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item prop="invokeTarget">
<span slot="label">
调用方法
<el-tooltip placement="top">
<div slot="content">
Bean调用示例ryTask.ryParams('ry')
<br />Class类调用示例com.ruoyi.quartz.task.RyTask.ryParams('ry')
<br />参数说明支持字符串布尔类型长整型浮点型整型
</div>
<i class="el-icon-question"></i>
</el-tooltip>
</span>
<el-input v-model="form.invokeTarget" placeholder="请输入调用目标字符串" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="cron表达式" prop="cronExpression">
<el-input v-model="form.cronExpression" placeholder="请输入cron执行表达式">
<template slot="append">
<el-button type="primary" @click="handleShowCron">
生成表达式
<i class="el-icon-time el-icon--right"></i>
</el-button>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="执行策略" prop="misfirePolicy">
<el-radio-group v-model="form.misfirePolicy" size="small">
<el-radio-button label="1">立即执行</el-radio-button>
<el-radio-button label="2">执行一次</el-radio-button>
<el-radio-button label="3">放弃执行</el-radio-button>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否并发" prop="concurrent">
<el-radio-group v-model="form.concurrent" size="small">
<el-radio-button label="0">允许</el-radio-button>
<el-radio-button label="1">禁止</el-radio-button>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in dict.type.sys_job_status"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<el-dialog title="Cron表达式生成器" :visible.sync="openCron" append-to-body destroy-on-close class="scrollbar">
<crontab @hide="openCron=false" @fill="crontabFill" :expression="expression"></crontab>
</el-dialog>
<!-- 任务日志详细 -->
<el-dialog title="任务详细" :visible.sync="openView" width="700px" append-to-body>
<el-form ref="form" :model="form" label-width="120px" size="mini">
<el-row>
<el-col :span="12">
<el-form-item label="任务编号:">{{ form.jobId }}</el-form-item>
<el-form-item label="任务名称:">{{ form.jobName }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="任务分组:">{{ jobGroupFormat(form) }}</el-form-item>
<el-form-item label="创建时间:">{{ form.createTime }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="cron表达式">{{ form.cronExpression }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="下次执行时间:">{{ parseTime(form.nextValidTime) }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="调用目标方法:">{{ form.invokeTarget }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="任务状态:">
<div v-if="form.status == 0">正常</div>
<div v-else-if="form.status == 1">失败</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否并发:">
<div v-if="form.concurrent == 0">允许</div>
<div v-else-if="form.concurrent == 1">禁止</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="执行策略:">
<div v-if="form.misfirePolicy == 0">默认策略</div>
<div v-else-if="form.misfirePolicy == 1">立即执行</div>
<div v-else-if="form.misfirePolicy == 2">执行一次</div>
<div v-else-if="form.misfirePolicy == 3">放弃执行</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="openView = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listJob, getJob, delJob, addJob, updateJob, runJob, changeJobStatus } from "@/api/monitor/job";
import Crontab from '@/components/Crontab'
export default {
components: { Crontab },
name: "Job",
dicts: ['sys_job_group', 'sys_job_status'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
jobList: [],
//
title: "",
//
open: false,
//
openView: false,
// Cron
openCron: false,
//
expression: "",
//
queryParams: {
pageNum: 1,
pageSize: 10,
jobName: undefined,
jobGroup: undefined,
status: undefined
},
//
form: {},
//
rules: {
jobName: [
{ required: true, message: "任务名称不能为空", trigger: "blur" }
],
invokeTarget: [
{ required: true, message: "调用目标字符串不能为空", trigger: "blur" }
],
cronExpression: [
{ required: true, message: "cron执行表达式不能为空", trigger: "blur" }
]
}
};
},
created() {
this.getList();
},
methods: {
/** 查询定时任务列表 */
getList() {
this.loading = true;
listJob(this.queryParams).then(response => {
this.jobList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
jobGroupFormat(row, column) {
return this.selectDictLabel(this.dict.type.sys_job_group, row.jobGroup);
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
jobId: undefined,
jobName: undefined,
jobGroup: undefined,
invokeTarget: undefined,
cronExpression: undefined,
misfirePolicy: 1,
concurrent: 1,
status: "0"
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.jobId);
this.single = selection.length != 1;
this.multiple = !selection.length;
},
//
handleCommand(command, row) {
switch (command) {
case "handleRun":
this.handleRun(row);
break;
case "handleView":
this.handleView(row);
break;
case "handleJobLog":
this.handleJobLog(row);
break;
default:
break;
}
},
//
handleStatusChange(row) {
let text = row.status === "0" ? "启用" : "停用";
this.$modal.confirm('确认要"' + text + '""' + row.jobName + '"任务吗?').then(function() {
return changeJobStatus(row.jobId, row.status);
}).then(() => {
this.$modal.msgSuccess(text + "成功");
}).catch(function() {
row.status = row.status === "0" ? "1" : "0";
});
},
/* 立即执行一次 */
handleRun(row) {
this.$modal.confirm('确认要立即执行一次"' + row.jobName + '"任务吗?').then(function() {
return runJob(row.jobId, row.jobGroup);
}).then(() => {
this.$modal.msgSuccess("执行成功");
}).catch(() => {});
},
/** 任务详细信息 */
handleView(row) {
getJob(row.jobId).then(response => {
this.form = response.data;
this.openView = true;
});
},
/** cron表达式按钮操作 */
handleShowCron() {
this.expression = this.form.cronExpression;
this.openCron = true;
},
/** 确定后回传值 */
crontabFill(value) {
this.form.cronExpression = value;
},
/** 任务日志列表查询 */
handleJobLog(row) {
const jobId = row.jobId || 0;
this.$router.push({ path: '/monitor/job-log/index', query: { jobId: jobId } })
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加任务";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const jobId = row.jobId || this.ids;
getJob(jobId).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改任务";
});
},
/** 提交按钮 */
submitForm: function() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.jobId != undefined) {
updateJob(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addJob(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const jobIds = row.jobId || this.ids;
this.$modal.confirm('是否确认删除定时任务编号为"' + jobIds + '"的数据项?').then(function() {
return delJob(jobIds);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('monitor/job/export', {
...this.queryParams
}, `job_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@ -0,0 +1,295 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="任务名称" prop="jobName">
<el-input
v-model="queryParams.jobName"
placeholder="请输入任务名称"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="任务组名" prop="jobGroup">
<el-select
v-model="queryParams.jobGroup"
placeholder="请选择任务组名"
clearable
style="width: 240px"
>
<el-option
v-for="dict in dict?.type.sys_job_group"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="执行状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择执行状态"
clearable
style="width: 240px"
>
<el-option
v-for="dict in dict?.type.sys_common_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="执行时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['monitor:job:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
@click="handleClean"
v-hasPermi="['monitor:job:remove']"
>清空</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['monitor:job:export']"
>导出</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-close"
size="mini"
@click="handleClose"
>关闭</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="jobLogList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="日志编号" width="80" align="center" prop="jobLogId" />
<el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
<el-table-column label="任务组名" align="center" prop="jobGroup" :show-overflow-tooltip="true">
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_job_group" :value="scope.row.jobGroup"/>
</template>
</el-table-column>
<el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" />
<el-table-column label="日志信息" align="center" prop="jobMessage" :show-overflow-tooltip="true" />
<el-table-column label="执行状态" align="center" prop="status">
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_common_status" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="执行时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="handleView(scope.row)"
v-hasPermi="['monitor:job:query']"
>详细</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 调度日志详细 -->
<el-dialog title="调度日志详细" :visible.sync="open" width="700px" append-to-body>
<el-form ref="form" :model="form" label-width="100px" size="mini">
<el-row>
<el-col :span="12">
<el-form-item label="日志序号:">{{ form.jobLogId }}</el-form-item>
<el-form-item label="任务名称:">{{ form.jobName }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="任务分组:">{{ form.jobGroup }}</el-form-item>
<el-form-item label="执行时间:">{{ form.createTime }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="调用方法:">{{ form.invokeTarget }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="日志信息:">{{ form.jobMessage }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="执行状态:">
<div v-if="form.status == 0">正常</div>
<div v-else-if="form.status == 1">失败</div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="异常信息:" v-if="form.status == 1">{{ form.exceptionInfo }}</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="open = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getJob} from "@/api/monitor/job";
import { listJobLog, delJobLog, cleanJobLog } from "@/api/monitor/jobLog";
export default {
name: "JobLog",
dicts: ['sys_common_status', 'sys_job_group'],
data() {
return {
//
loading: true,
//
ids: [],
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
jobLogList: [],
//
open: false,
//
dateRange: [],
//
form: {},
//
queryParams: {
pageNum: 1,
pageSize: 10,
jobName: undefined,
jobGroup: undefined,
status: undefined
}
};
},
created() {
const jobId = this.$route.query.jobId;
if (jobId !== undefined && jobId != 0) {
getJob(jobId).then(response => {
this.queryParams.jobName = response.data.jobName;
this.queryParams.jobGroup = response.data.jobGroup;
this.getList();
});
} else {
this.getList();
}
},
methods: {
/** 查询调度日志列表 */
getList() {
this.loading = true;
listJobLog(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.jobLogList = response.rows;
this.total = response.total;
this.loading = false;
}
);
},
//
handleClose() {
const obj = { path: "/monitor/job" };
this.$tab.closeOpenPage(obj);
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.jobLogId);
this.multiple = !selection.length;
},
/** 详细按钮操作 */
handleView(row) {
this.open = true;
this.form = row;
},
/** 删除按钮操作 */
handleDelete(row) {
const jobLogIds = this.ids;
this.$modal.confirm('是否确认删除调度日志编号为"' + jobLogIds + '"的数据项?').then(function() {
return delJobLog(jobLogIds);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 清空按钮操作 */
handleClean() {
this.$modal.confirm('是否确认清空所有调度日志数据项?').then(function() {
return cleanJobLog();
}).then(() => {
this.getList();
this.$modal.msgSuccess("清空成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('/monitor/jobLog/export', {
...this.queryParams
}, `log_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@ -0,0 +1,207 @@
<template>
<div class="app-container">
<el-row>
<el-col :span="12" class="card-box">
<el-card>
<div slot="header"><span>CPU</span></div>
<div class="el-table el-table--enable-row-hover el-table--medium">
<table cellspacing="0" style="width: 100%;">
<thead>
<tr>
<th class="el-table__cell is-leaf"><div class="cell">属性</div></th>
<th class="el-table__cell is-leaf"><div class="cell"></div></th>
</tr>
</thead>
<tbody>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">核心数</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.cpu">{{ server.cpu.cpuNum }}</div></td>
</tr>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">用户使用率</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.cpu">{{ server.cpu.used }}%</div></td>
</tr>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">系统使用率</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.cpu">{{ server.cpu.sys }}%</div></td>
</tr>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">当前空闲率</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.cpu">{{ server.cpu.free }}%</div></td>
</tr>
</tbody>
</table>
</div>
</el-card>
</el-col>
<el-col :span="12" class="card-box">
<el-card>
<div slot="header"><span>内存</span></div>
<div class="el-table el-table--enable-row-hover el-table--medium">
<table cellspacing="0" style="width: 100%;">
<thead>
<tr>
<th class="el-table__cell is-leaf"><div class="cell">属性</div></th>
<th class="el-table__cell is-leaf"><div class="cell">内存</div></th>
<th class="el-table__cell is-leaf"><div class="cell">JVM</div></th>
</tr>
</thead>
<tbody>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">总内存</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.mem">{{ server.mem.total }}G</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.total }}M</div></td>
</tr>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">已用内存</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.mem">{{ server.mem.used}}G</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.used}}M</div></td>
</tr>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">剩余内存</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.mem">{{ server.mem.free }}G</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.free }}M</div></td>
</tr>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">使用率</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.mem" :class="{'text-danger': server.mem.usage > 80}">{{ server.mem.usage }}%</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm" :class="{'text-danger': server.jvm.usage > 80}">{{ server.jvm.usage }}%</div></td>
</tr>
</tbody>
</table>
</div>
</el-card>
</el-col>
<el-col :span="24" class="card-box">
<el-card>
<div slot="header">
<span>服务器信息</span>
</div>
<div class="el-table el-table--enable-row-hover el-table--medium">
<table cellspacing="0" style="width: 100%;">
<tbody>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">服务器名称</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.computerName }}</div></td>
<td class="el-table__cell is-leaf"><div class="cell">操作系统</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.osName }}</div></td>
</tr>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">服务器IP</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.computerIp }}</div></td>
<td class="el-table__cell is-leaf"><div class="cell">系统架构</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.osArch }}</div></td>
</tr>
</tbody>
</table>
</div>
</el-card>
</el-col>
<el-col :span="24" class="card-box">
<el-card>
<div slot="header">
<span>Java虚拟机信息</span>
</div>
<div class="el-table el-table--enable-row-hover el-table--medium">
<table cellspacing="0" style="width: 100%;table-layout:fixed;">
<tbody>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">Java名称</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.name }}</div></td>
<td class="el-table__cell is-leaf"><div class="cell">Java版本</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.version }}</div></td>
</tr>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">启动时间</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.startTime }}</div></td>
<td class="el-table__cell is-leaf"><div class="cell">运行时长</div></td>
<td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.runTime }}</div></td>
</tr>
<tr>
<td colspan="1" class="el-table__cell is-leaf"><div class="cell">安装路径</div></td>
<td colspan="3" class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.home }}</div></td>
</tr>
<tr>
<td colspan="1" class="el-table__cell is-leaf"><div class="cell">项目路径</div></td>
<td colspan="3" class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.userDir }}</div></td>
</tr>
<tr>
<td colspan="1" class="el-table__cell is-leaf"><div class="cell">运行参数</div></td>
<td colspan="3" class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.inputArgs }}</div></td>
</tr>
</tbody>
</table>
</div>
</el-card>
</el-col>
<el-col :span="24" class="card-box">
<el-card>
<div slot="header">
<span>磁盘状态</span>
</div>
<div class="el-table el-table--enable-row-hover el-table--medium">
<table cellspacing="0" style="width: 100%;">
<thead>
<tr>
<th class="el-table__cell el-table__cell is-leaf"><div class="cell">盘符路径</div></th>
<th class="el-table__cell is-leaf"><div class="cell">文件系统</div></th>
<th class="el-table__cell is-leaf"><div class="cell">盘符类型</div></th>
<th class="el-table__cell is-leaf"><div class="cell">总大小</div></th>
<th class="el-table__cell is-leaf"><div class="cell">可用大小</div></th>
<th class="el-table__cell is-leaf"><div class="cell">已用大小</div></th>
<th class="el-table__cell is-leaf"><div class="cell">已用百分比</div></th>
</tr>
</thead>
<tbody v-if="server.sysFiles">
<tr v-for="(sysFile, index) in server.sysFiles" :key="index">
<td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.dirName }}</div></td>
<td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.sysTypeName }}</div></td>
<td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.typeName }}</div></td>
<td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.total }}</div></td>
<td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.free }}</div></td>
<td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.used }}</div></td>
<td class="el-table__cell is-leaf"><div class="cell" :class="{'text-danger': sysFile.usage > 80}">{{ sysFile.usage }}%</div></td>
</tr>
</tbody>
</table>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import { getServer } from "@/api/monitor/server";
export default {
name: "Server",
data() {
return {
//
server: []
};
},
created() {
this.getList();
this.openLoading();
},
methods: {
/** 查询服务器信息 */
getList() {
getServer().then(response => {
this.server = response.data;
this.$modal.closeLoading();
});
},
//
openLoading() {
this.$modal.loading("正在加载服务监控数据,请稍候!");
}
}
};
</script>

View File

@ -0,0 +1,275 @@
<template>
<div class="order_detail_wrapper">
<el-main v-loading="loading">
<el-card>
<el-descriptions title="订单信息" :column="2" border label-class-name="my-label" contentClassName="my-content">
<template slot="extra">
<el-button size="small" @click="$router.back()">返回</el-button>
</template>
<el-descriptions-item label="订单号">{{ orderDetail.orderSn }}</el-descriptions-item>
<el-descriptions-item label="用户昵称">{{ orderDetail.nickName }}</el-descriptions-item>
<el-descriptions-item label="用户手机号">{{ orderDetail.phone }}</el-descriptions-item>
<el-descriptions-item label="下单时间">{{ parseTime(orderDetail.createTime, '')
}}</el-descriptions-item>
<el-descriptions-item label="支付方式">{{ getPayType(orderDetail) }}</el-descriptions-item>
<el-descriptions-item label="支付时间">{{ parseTime(orderDetail.payTime, '')
}}</el-descriptions-item>
<el-descriptions-item label="订单状态">{{ getOrderStatus(orderDetail) }}</el-descriptions-item>
</el-descriptions>
</el-card>
<el-card>
<div slot="header" style="font-size: 16px;font-weight: bold;">售后信息</div>
<el-table :data="refundInfoList">
<el-table-column label="售后单号" prop="id" width="150"></el-table-column>
<el-table-column label="售后类型" prop="applyRefundType" width="80">
<template slot-scope="{row}">
<span>{{ getAftersaleType(row) }}</span>
</template>
</el-table-column>
<el-table-column label="申请售后时间" prop="applyRefundTime" width="180">
<template slot-scope="{row}">
<span>
{{ parseTime(row.applyRefundTime, '') }}
</span>
</template>
</el-table-column>
<el-table-column label="退款金额" prop="refundAmount">
<template v-slot="scope">
<span>{{ scope.row.refundAmount }}</span>
</template>
</el-table-column>
<el-table-column label="申请原因" prop="reason"></el-table-column>
<el-table-column label="凭证" prop="proofPics">
<template slot-scope="{row}">
<el-image class="small-img circle-img" :src="row.proofPics"
:preview-src-list="[row.proofPics]" />
</template>
</el-table-column>
<el-table-column label="申请状态" prop="refundStatus" width="110">
<template slot-scope="{row}">
<span>{{ getAftersaleStatus(row) }}</span>
</template>
</el-table-column>
<el-table-column label="平台拒绝理由" prop="remark"></el-table-column>
<el-table-column label="退货快递号" prop="refundWaybillCode"></el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-edit"
@click="handleWatch(scope.row)">查看</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<el-card>
<el-descriptions title="收货信息" :column="2" border label-class-name="my-label" contentClassName="my-content">
<el-descriptions-item label="收货人姓名">{{ addressInfo.name }}</el-descriptions-item>
<el-descriptions-item label="收货人手机号">{{ addressInfo.userPhone }}</el-descriptions-item>
<el-descriptions-item label="收货区域">{{ addressInfo.area }}</el-descriptions-item>
<el-descriptions-item label="详细地址">{{ getHiddenDetailAddress(addressInfo.address) }}</el-descriptions-item>
</el-descriptions>
</el-card>
<el-card>
<div slot="header" style="font-size: 16px;font-weight: bold;">商品信息</div>
<el-table :data="products">
<el-table-column label="商品图片" prop="pic">
<template slot-scope="{row}"><el-image class="small-img circle-img" :src="row.pic"
:preview-src-list="[row.pic]" /></template>
</el-table-column>
<el-table-column label="商品ID" prop="productId"></el-table-column>
<el-table-column label="商品名称" prop="productName"></el-table-column>
<el-table-column label="商品规格" align="center" prop="spData" width="180">
<template slot-scope="scope">
<div v-for="(item,key) in JSON.parse(scope.row.spData)">{{ key }}{{ item }}</div>
</template>
</el-table-column>
<el-table-column label="价格" prop="salePrice"></el-table-column>
<el-table-column label="购买数量" prop="buyNum"></el-table-column>
</el-table>
</el-card>
<el-card>
<el-descriptions title="物流信息" :column="3" border label-class-name="my-label" contentClassName="my-content">
<el-descriptions-item label="发货时间">{{ parseTime(orderDetail.deliveryTime, '')
}}</el-descriptions-item>
<el-descriptions-item label="快递单号">{{ orderDetail.expressNo }}</el-descriptions-item>
<el-descriptions-item label="物流公司">{{ orderDetail.expressNo ? '顺丰速运' : '' }}</el-descriptions-item>
<!-- <el-descriptions-item label="物流公司">{{ orderDetail.expressName }}</el-descriptions-item>-->
</el-descriptions>
</el-card>
<!-- 售后详细信息 -->
<el-dialog title="售后详细信息" :visible.sync="open" width="1100px" append-to-body>
<el-descriptions :column="2" border label-class-name="my-label" contentClassName="my-content">
<el-descriptions-item label="售后单号">{{ refundInfoDetail.id }}</el-descriptions-item>
<el-descriptions-item label="售后类型">{{ getAftersaleType(refundInfoDetail) }}</el-descriptions-item>
<el-descriptions-item label="申请售后时间">{{ parseTime(refundInfoDetail.applyRefundTime,'') }}</el-descriptions-item>
<el-descriptions-item label="退款金额">{{ refundInfoDetail.refundAmount }}</el-descriptions-item>
<el-descriptions-item label="申请原因">{{ refundInfoDetail.reason }}</el-descriptions-item>
<el-descriptions-item label="具体描述">{{ refundInfoDetail.description }}</el-descriptions-item>
<el-descriptions-item label="凭证">
<el-image class="small-img circle-img" :src="refundInfoDetail.proofPics"
:preview-src-list="[refundInfoDetail.proofPics]" />
</el-descriptions-item>
<el-descriptions-item label="申请状态">{{ getAftersaleStatus(refundInfoDetail) }}</el-descriptions-item>
<el-descriptions-item label="平台拒绝理由">{{ refundInfoDetail.remark }}</el-descriptions-item>
<el-descriptions-item label="退货快递号">{{ refundInfoDetail.refundWaybillCode }}</el-descriptions-item>
<el-descriptions-item label="物流公司">{{ getExpressName(refundInfoDetail.refundWpCode) }}</el-descriptions-item>
<el-descriptions-item label="物流进度">
<el-popover placement="left" width="300" trigger="hover" popper-class="popperOptions">
<el-timeline-item v-for="(activity, index) in aliLogisticsInfoList" :key="index"
:timestamp="activity.time">
{{ activity.context }}
</el-timeline-item>
<span slot="reference">{{ refundInfoDetail.logistics }}</span>
</el-popover>
</el-descriptions-item>
</el-descriptions>
</el-dialog>
</el-main>
</div>
</template>
<script>
import { getOmsAftersale } from "@/api/oms/aftersale";
import {getConfigKey2} from "@/api/system/config";
export default {
name: "OmsAftersaleDetail",
dicts: ['oms_order_status', 'oms_pay_type', "oms_aftersale_type", "oms_aftersale_status"],
data() {
return {
products: [],
orderDetail: {},
addressInfo: {},
// aliLogisticsInfoList: [],
refundInfoList: [],
loading: false,
experssList: [],
open: false,
refundInfoDetail: {},
aliLogisticsInfoList: []
}
},
created() {
this.getExpressData()
const { id } = this.$route.query
this.queryDetail(id).then((expressNo) => {
// this.getLogistic(expressNo)
})
},
computed: {
orderStatusMap() {
let obj = this.dict.type.oms_order_status.map(item => [item.value, item.label])
let map = new Map(obj)
return map;
},
payTypeMap() {
let obj = this.dict.type.oms_pay_type.map(item => [item.value, item.label])
let map = new Map(obj)
return map
},
aftersaleTypeMap() {
let obj = this.dict.type.oms_aftersale_type.map(item => [item.value, item.label])
let map = new Map(obj)
return map;
},
aftersaleStatusMap() {
let obj = this.dict.type.oms_aftersale_status.map(item => [item.value, item.label])
let map = new Map(obj)
return map;
},
expressMap() {
let obj = this.experssList.map(item => [item.expressCode, item.expressName])
return new Map(obj)
}
},
methods: {
getExpressData() {
getConfigKey2('express-set-key').then(res => {
if (res.data && res.data.configValue) {
this.experssList = JSON.parse(res.data.configValue)
} else {
this.experssList = []
}
})
},
queryDetail(id) {
this.loading = true
return new Promise(resolve =>
getOmsAftersale(id).then(res => {
const { productList, addressInfo, refundInfoList } = res;
this.orderDetail = res;
this.products = productList
this.refundInfoList = refundInfoList
this.addressInfo = addressInfo || {}
this.loading = false
})
)
},
getOrderStatus(row) {
return this.orderStatusMap.get(row.status + '')
},
getPayType(row) {
return this.payTypeMap.get(row.payType + '')
},
getAftersaleType(row) {
return this.aftersaleTypeMap.get(row.applyRefundType + '')
},
getAftersaleStatus(row) {
return this.aftersaleStatusMap.get(row.refundStatus + '')
},
getExpressName(name) {
return this.expressMap.get(name)
},
handleWatch(row) {
this.refundInfoDetail = row
if(this.refundInfoDetail.allLogistics){
this.aliLogisticsInfoList = JSON.parse(refundInfoDetail.allLogistics)
}
this.open = true
},
cancel() {
this.open = false;
this.refundInfoDetail = {};
}
}
}
</script>
<style lang="stylus">
.order_detail_wrapper
> .el-card + .el-card
margin-top 1rem
.el-form-item
margin-bottom 0
.el-form-item__content, .el-form-item__label
line-height 2
.my-label
width 100px
.my-content
width 400px
.popperOptions[x-placement^=left] .popper__arrow::after{
border-left-color: #565D6B;
}
.popperOptions[x-placement^=right] .popper__arrow::after{
border-right-color: #565D6B;
}
.popperOptions[x-placement^=bottom] .popper__arrow::after{
border-bottom-color: #565D6B;
}
.popperOptions[x-placement^=top] .popper__arrow::after{
border-top-color: #565D6B;
}
.popperOptions{
background-color: #565D6B;
color: #FFFFFF;
border: #565D6B;
}
.el-timeline-item__content {
color: #fff;
}
.el-timeline-item__timestamp {
color: #fff;
}
</style>

View File

@ -0,0 +1,492 @@
<template>
<div class="app-container">
<div v-show="show">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="申请状态" prop="status">
<DictRadio v-model="queryParams.status" :radioData="dict?.type.oms_aftersale_status" size="small" :show-all="'all'" @change="handleQuery"></DictRadio>
</el-form-item>
<el-form-item label="售后类型" prop="type">
<DictRadio v-model="queryParams.type" :radioData="dict?.type.oms_aftersale_type" size="small" :show-all="'all'" @change="handleQuery"></DictRadio>
</el-form-item>
<el-form-item label="订单号" prop="orderSn">
<el-input v-model.trim="queryParams.orderSn" placeholder="请输入订单号" clearable size="small"
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="售后单号" prop="id">
<el-input v-model.trim="queryParams.id" placeholder="请输入售后单号" clearable size="small"
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="会员手机号" prop="userPhone">
<el-input v-model.trim="queryParams.userPhone" placeholder="请输入会员手机号" clearable size="small"
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="创建时间" prop="Time">
<el-date-picker v-model="queryParams.Time" type="datetimerange" :picker-options="pickerOptions"
range-separator="至" size="small" format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']"
align="right"
@change="handleChange">
</el-date-picker>
</el-form-item>
<el-form-item class="flex_one tr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="omsAftersaleList" @selection-change="handleSelectionChange" border>
<!-- <el-table-column type="selection" width="55" align="center" />-->
<el-table-column label="售后单号" prop="id" width="160"/>
<el-table-column label="申请状态" prop="aftersaleStatus" width="80">
<template v-slot="scope">
<el-tag effect="plain" size="medium" :type="getAftersaleStatusTag(scope.row)">{{
getAftersaleStatusText(scope.row)
}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="用户信息" prop="nickName" width="120">
<template v-slot="scope">
<div>{{ scope.row.nickName }}</div>
<div>{{ scope.row.phone }}</div>
<div>{{ scope.row.mark }}</div>
</template>
</el-table-column>
<el-table-column label="退款金额" prop="applyReturnAmount" width="120"/>
<el-table-column label="售后类型" prop="applyRefundType" width="80">
<template v-slot="scope">
<el-tag effect="plain" size="medium" :type="getAftersaleTypeTag(scope.row)">{{
getAftersaleTypeText(scope.row)
}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="申请时间" prop="applyRefundTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.applyRefundTime, '') }}</span>
</template>
</el-table-column>
<el-table-column label="处理时间" prop="handleTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.handleTime, '') }}</span>
</template>
</el-table-column>
<el-table-column label="原因" prop="reason" width="220"/>
<el-table-column label="处理备注" prop="note" width="150"/>
<el-table-column label="处理人员" prop="handleMan" width="100"/>
<el-table-column label="订单编号/操作" class-name="small-padding fixed-width" width="220" fixed="right">
<template slot-scope="scope">
<div>
{{ scope.row.orderSn }}
<el-link @click="copy(scope.row.orderSn)" :underline="false"><i
class="el-icon-document-copy el-icon--right"></i></el-link>
</div>
<el-button size="mini" type="text" @click="handleDetail(scope.row.orderId)"
v-hasPermi="['oms:aftersale:query']">详情
</el-button>
<el-button size="mini" type="text" @click="showLog(scope.row.orderId)"
v-hasPermi="['oms:aftersale:log']">日志
</el-button>
<el-button size="mini" type="text" @click="approve(scope.row, 1)"
v-if="scope.row.aftersaleStatus == 0" v-hasPermi="['manager:oms:aftersale:update']">同意
</el-button>
<el-button size="mini" type="text" @click="handleOpen(scope.row, 2)" class="red"
v-if="scope.row.aftersaleStatus == 0" v-hasPermi="['manager:oms:aftersale:update']">拒绝
</el-button>
<el-button size="mini" type="text" @click="confirmReceive(scope.row, 3)"
v-if="scope.row.aftersaleStatus == 1 && scope.row.applyRefundType == 2"
v-hasPermi="['manager:oms:aftersale:update']">确认收货
</el-button>
</template>
</el-table-column>
</el-table>
<InBody v-show="total>0">
<pagination
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</InBody>
</div>
<!-- <SeeAdsComponent ref="seeAdsComponentRef" v-if="!show" @confirmOk="confirmOk"/>-->
<!-- 拒绝对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="updateForm" :model="updateOrderForm" label-width="100px" :rules="rules">
<el-form-item label="拒绝理由" prop="remark">
<el-input v-model="updateOrderForm.remark" placeholder="请输入拒绝理由" controls-position="right" :min="0" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitUpdate('updateForm')">确定</el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 日志 -->
<el-dialog :title="logObj.title" :visible.sync="logObj.open" width="500px" append-to-body>
<el-timeline>
<el-timeline-item v-for="item in logObj.logList" placement="top" :timestamp="parseTime(item.createTime, '')">
<el-card>
<h4>{{ getLogEvent(item.orderStatus) }}</h4>
<br>
<h4>操作人{{ item.operateMan }}</h4>
<br v-if="item.note">
<h4 v-if="item.note">备注{{ item.note }}</h4>
</el-card>
</el-timeline-item>
</el-timeline>
</el-dialog>
</div>
</template>
<script>
import {
addOmsAftersale,
dealWithAftersale,
delOmsAftersale,
exportOmsAftersale,
getOmsAftersale,
listOmsAftersale,
updateOmsAftersale,
viewLog
} from "@/api/oms/aftersale";
import dateUtil from '@/utils/DateUtil';
import SeeAdsComponent from "@/components/SeeAdsComponent.vue";
export default {
name: "OmsAftersale",
components: {SeeAdsComponent},
dicts: ["oms_aftersale_type", "oms_aftersale_status"],
data() {
return {
show: true,
pickerOptions: {
shortcuts: dateUtil.getTimeShort2()
},
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
omsAftersaleList: [],
//
title: "拒绝售后",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
orderSn: null,
type: null,
status: null,
userPhone: null,
Time: [],
startTime: null,
endTime: null
},
//
form: {},
showMoreCondition: false,
updateOrderForm: {
orderId: null,
optType: null,
remark: null,
id: null,
},
rules: {
remark: [
{required: true, message: '请输入拒绝理由', trigger: 'blur'}
]
},
logObj: {
title: '日志',
logList: null,
open: false,
loading: false
}
};
},
created() {
const { status } = this.$route.query
if (status){
this.queryParams.status = status
}
this.getList();
},
methods: {
confirmOk(success) {
if (success) {
this.show = true
this.getList();
}
},
copy(data) {
let url = data;
let oInput = document.createElement('input');
oInput.value = url;
document.body.appendChild(oInput);
oInput.select(); // ;
console.log(oInput.value)
document.execCommand("Copy"); //
this.$modal.msgSuccess('复制成功');
oInput.remove()
},
/** 查询订单售后列表 */
getList() {
if (this.queryParams.Time) {
this.queryParams.startTime = this.queryParams.Time[0]
this.queryParams.endTime = this.queryParams.Time[1]
}
this.loading = true;
const {pageNum, pageSize} = this.queryParams;
const query = {...this.queryParams, pageNum: undefined, pageSize: undefined};
const pageReq = {page: pageNum - 1, size: pageSize};
listOmsAftersale(query, pageReq).then(response => {
const { content, totalElements } = response
this.omsAftersaleList = content;
this.total = totalElements;
this.loading = false;
});
},
//
reset() {
this.form = {
id: null,
memberId: null,
orderId: null,
returnAmount: null,
type: null,
status: 0,
handleTime: null,
quantity: null,
reason: null,
description: null,
proofPics: null,
handleNote: null,
handleMan: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加订单售后";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getOmsAftersale(id).then(response => {
this.form = response;
this.open = true;
this.title = "修改订单售后";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateOmsAftersale(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addOmsAftersale(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除订单售后编号为"' + ids + '"的数据项?').then(function() {
return delOmsAftersale(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal.confirm('是否确认导出所有订单售后数据项?').then(() => {
this.exportLoading = true;
return exportOmsAftersale(queryParams);
}).then(response => {
this.$download.download(response);
this.exportLoading = false;
}).catch(() => {});
},
/** 售后详情 */
handleDetail(orderId){
const id = orderId
this.$router.push({ path: '/aftersale/detail', query: { id } })
},
/** 同意售后 */
approve(order, type) {
this.$confirm(`您确定要同意售后单号为【${order.id}】的售后申请吗?`, '温馨提示', {type: 'warning'}).then(
() => {
this.updateOrderForm.orderId = order.orderId
this.updateOrderForm.optType = type
dealWithAftersale(this.updateOrderForm).then((response) => {
this.cancel()
this.$message.success('操作成功')
this.getList()
})
}
)
},
/** 拒绝 */
handleOpen(order, type) {
this.updateOrderForm.orderId = order.orderId
this.updateOrderForm.optType = type
this.updateOrderForm.id = order.id
this.open = true
},
confirmReceive(orderId, type) {
this.$confirm(`您确认收到售后单号为【${order.id}】的货物了吗?`, '温馨提示', {type: 'warning'}).then(
() => {
this.updateOrderForm.orderId = orderId
this.updateOrderForm.optType = type
dealWithAftersale(this.updateOrderForm).then((response) => {
this.cancel()
this.$message.success('操作成功')
this.getList()
})
})
},
getAftersaleStatusTag(row) {
switch (row.aftersaleStatus) {
case 0:
return 'info'
case 1:
return 'primary'
case 2:
return 'success'
case 3:
return 'danger'
case 4:
return 'warning'
}
},
getAftersaleStatusText(row) {
switch (row.aftersaleStatus) {
case 0:
return '待处理'
case 1:
return '退货中'
case 2:
return '已完成'
case 3:
return '已拒绝'
case 4:
return '已关闭'
}
},
getAftersaleTypeTag(row) {
switch (row.applyRefundType) {
case 1:
return 'primary'
case 2:
return 'warning'
}
},
getAftersaleTypeText(row) {
switch (row.applyRefundType) {
case 1:
return '退款'
case 2:
return '退货退款'
}
},
cancel() {
this.open = false;
this.updateOrderForm = {
orderId: null,
optType: null,
remark: null,
id: null,
}
},
submitUpdate(formName){
this.$refs[formName].validate(valid => {
if (valid) {
this.$confirm(`您确定要拒绝售后单号为【${this.updateOrderForm.id}】的售后申请了吗?`, '温馨提示', {type: 'warning'}).then(
() => {
dealWithAftersale(this.updateOrderForm).then((response) => {
this.cancel()
this.$message.success('操作成功')
this.getList()
})
})
}
})
},
handleChange(value) {
if (!value) {
this.queryParams.startTime = null;
this.queryParams.endTime = null;
}
},
showLog(orderId){
this.logObj.loading = true
viewLog(orderId).then((response) => {
this.logObj.logList = response
this.logObj.open = true
this.logObj.loading = false
})
},
getLogEvent(status){
switch (status){
case 11:
return '用户申请售后';
case 12:
return '平台同意售后申请';
case 13:
return '售后完成';
case 14:
return '平台拒绝售后';
}
},
}
};
</script>

View File

@ -0,0 +1,291 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="MEMBER_ID" prop="memberId">
<el-input
v-model="queryParams.memberId"
placeholder="请输入MEMBER_ID"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="订单id" prop="orderId">
<el-input
v-model="queryParams.orderId"
placeholder="请输入订单id"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="子订单id" prop="orderItemId">
<el-input
v-model="queryParams.orderItemId"
placeholder="请输入子订单id"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="退款金额" prop="returnAmount">
<el-input
v-model="queryParams.returnAmount"
placeholder="请输入退款金额"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="退货数量" prop="quantity">
<el-input
v-model="queryParams.quantity"
placeholder="请输入退货数量"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item class="flex_one tr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['oms:aftersaleItem:add']"
>新增</el-button>
</el-col>
</el-col>
</el-row>
<el-table v-loading="loading" :data="omsAftersaleItemList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="MEMBER_ID" align="center" prop="memberId" />
<el-table-column label="订单id" align="center" prop="orderId" />
<el-table-column label="子订单id" align="center" prop="orderItemId" />
<el-table-column label="退款金额" align="center" prop="returnAmount" />
<el-table-column label="退货数量" align="center" prop="quantity" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['oms:aftersaleItem:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['oms:aftersaleItem:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改订单售后对话框 -->
<el-dialog :title="title" :visible.sync="open" width="50%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="108px" inline class="dialog-form-two">
<el-form-item label="MEMBER_ID" prop="memberId">
<el-input v-model="form.memberId" placeholder="请输入MEMBER_ID" />
</el-form-item>
<el-form-item label="订单id" prop="orderId">
<el-input v-model="form.orderId" placeholder="请输入订单id" />
</el-form-item>
<el-form-item label="子订单id" prop="orderItemId">
<el-input v-model="form.orderItemId" placeholder="请输入子订单id" />
</el-form-item>
<el-form-item label="退款金额" prop="returnAmount">
<el-input v-model="form.returnAmount" placeholder="请输入退款金额" />
</el-form-item>
<el-form-item label="退货数量" prop="quantity">
<el-input v-model="form.quantity" placeholder="请输入退货数量" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listOmsAftersaleItem, getOmsAftersaleItem, delOmsAftersaleItem, addOmsAftersaleItem, updateOmsAftersaleItem, exportOmsAftersaleItem } from "@/api/oms/aftersaleItem";
export default {
name: "OmsAftersaleItem",
data() {
return {
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
omsAftersaleItemList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
memberId: null,
orderId: null,
orderItemId: null,
returnAmount: null,
quantity: null,
},
//
form: {},
//
rules: {
memberId: [
{ required: true, message: "MEMBER_ID不能为空", trigger: "blur" }
],
},
};
},
created() {
this.getList();
},
methods: {
/** 查询订单售后列表 */
getList() {
this.loading = true;
const {pageNum, pageSize} = this.queryParams;
const query = {...this.queryParams, pageNum: undefined, pageSize: undefined};
const pageReq = {page: pageNum - 1, size: pageSize};
listOmsAftersaleItem(query, pageReq).then(response => {
const { content, totalElements } = response
this.omsAftersaleItemList = content;
this.total = totalElements;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
memberId: null,
orderId: null,
orderItemId: null,
returnAmount: null,
quantity: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加订单售后";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getOmsAftersaleItem(id).then(response => {
this.form = response;
this.open = true;
this.title = "修改订单售后";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateOmsAftersaleItem(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addOmsAftersaleItem(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除订单售后编号为"' + ids + '"的数据项?').then(function() {
return delOmsAftersaleItem(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal.confirm('是否确认导出所有订单售后数据项?').then(() => {
this.exportLoading = true;
return exportOmsAftersaleItem(queryParams);
}).then(response => {
this.$download.download(response);
this.exportLoading = false;
}).catch(() => {});
}
}
};
</script>

View File

@ -0,0 +1,206 @@
<template>
<div class="order_detail_wrapper">
<el-main v-loading="loading">
<el-card class="mt10">
<div slot="header" class="clearfix">
<span style="font-size: 16px;font-weight: bold">订单进程</span>
<el-button style="float: right;" size="small" @click="$router.back()">返回</el-button>
</div>
<el-steps :active="active" align-center>
<el-step title="买家下单" :description="parseTime(orderDetail.createTime, '')"></el-step>
<el-step title="买家付款" :description="parseTime(orderDetail.payTime, '')"></el-step>
<el-step title="商家发货" :description="parseTime(orderDetail.deliveryTime, '')"></el-step>
<el-step title="买家收货" :description="parseTime(orderDetail.receiveTime, '')"></el-step>
</el-steps>
</el-card>
<el-card class="mt10">
<el-descriptions title="订单信息" :column="2" border label-class-name="my-label" contentClassName="my-content">
<!-- <template slot="extra">-->
<!-- <el-button size="small" @click="$router.back()">返回</el-button>-->
<!-- </template>-->
<el-descriptions-item label="订单编号">{{ orderDetail.orderSn }}</el-descriptions-item>
<el-descriptions-item label="用户名称">{{ orderDetail.userName }}</el-descriptions-item>
<el-descriptions-item label="用户手机号">{{ orderDetail.userPhone }}</el-descriptions-item>
<el-descriptions-item label="下单时间">{{ parseTime(orderDetail.createTime, '') }}</el-descriptions-item>
<el-descriptions-item label="支付方式">{{ getPayType(orderDetail) }}</el-descriptions-item>
<el-descriptions-item label="支付时间">{{ parseTime(orderDetail.payTime, '')
}}</el-descriptions-item>
<el-descriptions-item label="订单状态">{{ getOrderStatus(orderDetail) }}</el-descriptions-item>
</el-descriptions>
</el-card>
<el-card class="mt10">
<el-descriptions title="收货信息" :column="2" border label-class-name="my-label" contentClassName="my-content">
<el-descriptions-item label="收货人姓名">{{ getHiddenName(addressInfo.name) }}</el-descriptions-item>
<el-descriptions-item label="收货人手机号">{{ addressInfo.userPhone }}</el-descriptions-item>
<el-descriptions-item label="收货区域">{{ addressInfo.area }}</el-descriptions-item>
<el-descriptions-item label="详细地址">{{ getHiddenDetailAddress(addressInfo.address) }}</el-descriptions-item>
</el-descriptions>
</el-card>
<el-card class="mt10">
<div slot="header" style="font-size: 16px;font-weight: bold;">商品信息</div>
<el-table :data="products">
<el-table-column label="商品图片" prop="pic">
<template slot-scope="{row}"><el-image class="small-img circle-img" :src="row.pic"
:preview-src-list="[row.pic]" /></template>
</el-table-column>
<el-table-column label="商品ID" prop="productId"></el-table-column>
<el-table-column label="商品名称" prop="productName"></el-table-column>
<el-table-column label="商品规格" align="center" prop="spData" width="180">
<template slot-scope="scope">
<div v-for="(item,key) in JSON.parse(scope.row.spData)">{{ key }}{{ item }}</div>
</template>
</el-table-column>
<el-table-column label="购买数量" prop="buyNum"></el-table-column>
<el-table-column label="实付金额" prop="payAmount">
<template slot-scope="scope">
<span>{{ orderDetail.payAmount }}</span>
</template>
</el-table-column>
</el-table>
</el-card>
<el-card class="mt10">
<el-descriptions title="物流信息" :column="3" border label-class-name="my-label" contentClassName="my-content">
<el-descriptions-item label="发货时间">{{ parseTime(orderDetail.deliveryTime, '')
}}</el-descriptions-item>
<el-descriptions-item label="快递单号">{{ orderDetail.expressNo }}</el-descriptions-item>
<el-descriptions-item label="物流公司">{{ orderDetail.expressName }}</el-descriptions-item>
<!-- <el-descriptions-item label="物流进度">-->
<!-- <el-popover placement="top" width="300" trigger="hover" popper-class="popperOptions">-->
<!-- <el-timeline-item v-for="(activity, index) in aliLogisticsInfoList" :key="index"-->
<!-- :timestamp="activity.time">-->
<!-- {{ activity.context }}-->
<!-- </el-timeline-item>-->
<!-- <span slot="reference">{{ orderDetail.logistics }}</span>-->
<!-- </el-popover>-->
<!-- </el-descriptions-item>-->
</el-descriptions>
</el-card>
</el-main>
</div>
</template>
<script>
import { getOmsOrder } from "@/api/oms/order";
import { getConfigKey } from "@/api/system/config";
const key = "express-set-key"
export default {
name: "OrderDetail",
dicts: ['oms_order_status', 'oms_pay_type'],
data() {
return {
products: [],
orderDetail: {},
addressInfo: {},
aliLogisticsInfoList: [],
loading: false,
experssList: [],
active: 1
}
},
created() {
// this.getExpressData()
const { id } = this.$route.query
this.queryDetail(id).then((expressNo) => {
})
},
computed: {
orderStatusMap() {
let obj = this.dict.type.oms_order_status.map(item => [item.value, item.label])
let map = new Map(obj)
return map;
},
payTypeMap() {
let obj = this.dict.type.oms_pay_type.map(item => [item.value, item.label])
let map = new Map(obj)
return map
},
// expressMap() {
// let obj = this.experssList.map(item => [item.expressCode, item.expressName])
// let map = new Map(obj)
// return map
// }
},
methods: {
queryDetail(id) {
this.loading = true
return new Promise(resolve =>
getOmsOrder(id).then(res => {
const { productInfo, addressInfo } = res;
this.orderDetail = res;
// if (allLogistics) {
// this.aliLogisticsInfoList = JSON.parse(allLogistics)
// }
this.products = productInfo
this.addressInfo = addressInfo
if (this.orderDetail.orderStatus <= 3){
this.active = this.orderDetail.orderStatus + 1
}else {
this.active = 1
}
this.loading = false
})
)
},
getOrderStatus(row) {
return this.orderStatusMap.get(row.orderStatus + '')
},
getPayType(row) {
return this.payTypeMap.get(row.payType + '')
},
// getExpressName(row) {
// return this.expressMap.get(row.expressName + '')
// },
// getExpressData() {
// getConfigKey(key).then(res => {
// if (res.msg) {
// this.experssList = JSON.parse(res.msg)
// } else {
// // this.list = [...defaultList]
// }
// })
// }
}
}
</script>
<style lang="stylus">
.order_detail_wrapper
> .el-card + .el-card
margin-top 1rem
.el-form-item
margin-bottom 0
.el-form-item__content, .el-form-item__label
line-height 2
.my-label
width 100px
.my-content
width 400px
.popperOptions[x-placement^=left] .popper__arrow::after{
border-left-color: #565D6B;
}
.popperOptions[x-placement^=right] .popper__arrow::after{
border-right-color: #565D6B;
}
.popperOptions[x-placement^=bottom] .popper__arrow::after{
border-bottom-color: #565D6B;
}
.popperOptions[x-placement^=top] .popper__arrow::after{
border-top-color: #565D6B;
}
.popperOptions{
background-color: #565D6B;
color: #FFFFFF;
border: #565D6B;
}
.el-timeline-item__content {
color: #fff;
}
.el-timeline-item__timestamp {
color: #fff;
}
</style>

View File

@ -0,0 +1,759 @@
<template>
<div class="app-container" v-if="show">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="订单状态" prop="status">
<DictRadio
v-model="queryParams.status"
:radioData="dict?.type.oms_order_status"
size="small"
:show-all="'all'"
:filter="['11', '12', '13', '14']"
@change="handleQuery"
></DictRadio>
</el-form-item>
<el-form-item label="订单编号" prop="orderSn">
<el-input v-model.trim="queryParams.orderSn" placeholder="请输入订单编号" clearable size="small" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="会员手机号" prop="userPhone">
<el-input v-model.trim="queryParams.userPhone" placeholder="请输入会员手机号" clearable size="small" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="省市区" prop="provinces">
<address-selector v-model="queryParams.provinces" size="small"></address-selector>
</el-form-item>
<el-form-item label="下单时间" prop="Time">
<el-date-picker
v-model="queryParams.Time"
type="datetimerange"
:picker-options="pickerOptions"
range-separator="至"
size="small"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"
align="right"
@change="handleChange"
>
</el-date-picker>
</el-form-item>
<el-form-item class="flex_one tr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="omsOrderList" border @selection-change="handleSelectionChange" cell-class-name="my-cell">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="收件信息" prop="receiverName" width="280">
<template v-slot="scope">
<div>
<span>{{ scope.row.decrypt ? scope.row.receiverName : getHiddenName(scope.row.receiverName) }} {{ scope.row.receiverPhone }}</span>
<el-button size="mini" type="text" @click="handleWatch(scope.row)" style="margin-left: 10px">查看 </el-button>
<el-button size="mini" type="text" @click="handleUpdate(scope.row)">修改 </el-button>
</div>
<div>
<span>{{ scope.row.receiverProvince }}{{ scope.row.receiverCity }}{{ scope.row.receiverDistrict }}</span>
<span>{{ scope.row.decrypt ? scope.row.receiverDetailAddress : getHiddenDetailAddress(scope.row.receiverDetailAddress) }}</span>
</div>
</template>
</el-table-column>
<el-table-column label="客户信息" prop="receiverName" width="160">
<template v-slot="scope">
<p>{{ scope.row.nickName }}</p>
<p>{{ scope.row.mark }}</p>
</template>
</el-table-column>
<el-table-column label="备注留言" prop="note" width="160">
<template v-slot="scope">
<div>
<span v-if="scope.row.merchantNote" class="note-title" style="margin-right: 10px">平台备注</span>
<el-button size="mini" type="text" @click="handleSaveNote(scope.row)">{{ scope.row.merchantNote ? '修改' : '添加平台备注' }} </el-button>
</div>
<div v-if="scope.row.merchantNote">{{ scope.row.merchantNote }}</div>
<div v-if="scope.row.note" class="note-title">买家备注</div>
<div v-if="scope.row.note">{{ scope.row.note }}</div>
</template>
</el-table-column>
<el-table-column label="下单时间/支付时间" prop="payTime" width="140">
<template v-slot="scope">
<div v-if="scope.row.createTime">{{ parseTime(scope.row.createTime, '{mm}-{dd} {hh}:{ii}') }} 下单</div>
<div v-if="scope.row.payTime">{{ parseTime(scope.row.payTime, '{mm}-{dd} {hh}:{ii}') }} 支付</div>
</template>
</el-table-column>
<el-table-column label="优惠券" prop="couponAmount" width="80">
<template v-slot="scope">
<div v-if="scope.row.couponAmount">{{ scope.row.couponAmount }}</div>
<div v-else></div>
</template>
</el-table-column>
<el-table-column label="合计" prop="totalAmount" width="140">
<template v-slot="scope">
<div>
<span>总数 </span>
<span style="color: red">{{ scope.row.buyNum }}</span>
</div>
<div>实付 {{ scope.row.payAmount }}</div>
</template>
</el-table-column>
<el-table-column label="商品规格" prop="productList" width="280">
<template v-slot="scope">
<div v-for="item in scope.row.productList" class="product-container">
<el-popover placement="right" trigger="hover">
<el-image :src="item.pic" style="width: 350px; height: 350px" />
<template v-slot:reference>
<el-image class="small-img product-item" :src="item.pic" style="width: 40px; height: 40px" />
</template>
</el-popover>
<div class="product-item" style="margin-left: 5px">
<div class="sp-data">
<span v-for="(value, key) in JSON.parse(item.spData)">{{ key }}{{ value }}&nbsp;</span>
</div>
<div class="product-item quantity">
<span style="margin-right: 10px">{{ item.salePrice }}</span>
<span>x{{ item.buyNum }}</span>
</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="订单状态" prop="status" width="160">
<template v-slot="scope">
<div>
<el-tag :type="getOrderStatusTag(scope.row.status)" style="margin-right: 10px">
{{ getOrderStatusText(scope.row.status) }}
</el-tag>
</div>
<div v-if="scope.row.deliverySn">
物流单号{{ scope.row.deliverySn }}
<el-link @click="copy(scope.row.deliverySn)" :underline="false"><i class="el-icon-document-copy el-icon--right"></i></el-link>
</div>
<div v-if="scope.row.deliveryTime">发货时间{{ parseTime(scope.row.deliveryTime, '') }}</div>
</template>
</el-table-column>
<el-table-column label="订单编号/操作" class-name="small-padding fixed-width" width="220" fixed="right">
<template v-slot="scope">
<div style="float: right">
{{ scope.row.orderSn }}
<!-- <el-link-->
<!-- size="mini"-->
<!-- icon="el-icon-document-copy"-->
<!-- @click="copyOrderSn(scope.row.orderSn)"-->
<!-- ></el-link>-->
<el-link @click="copy(scope.row.orderSn)" :underline="false"><i class="el-icon-document-copy el-icon--right"></i></el-link>
</div>
<div style="float: right">
<el-button size="mini" type="text" @click="goDetail(scope.row)" v-hasPermi="['oms:order:query']">详情 </el-button>
<el-button size="mini" type="text" @click="showLog(scope.row.id)" v-hasPermi="['oms:order:log']">日志 </el-button>
<el-button
size="mini"
type="text"
@click="handleDelivery(scope.row)"
:disabled="scope.row.status !== 1 && scope.row.status !== 2 && scope.row.status !== 3"
>发货
</el-button>
</div>
</template>
</el-table-column>
</el-table>
<InBody v-show="total > 0">
<pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</InBody>
<!-- 发货对话框 -->
<el-dialog :title="deliveryObj.title" v-model:visible="deliveryObj.open" width="500px" append-to-body>
<el-form ref="deliveryForm" :model="deliveryObj.form" :rules="deliveryObj.rules" label-width="100px">
<el-form-item label="快递公司" prop="expressName">
<el-select v-model="deliveryObj.form.expressName" placeholder="请选择快递公司" clearable size="small" filterable>
<!-- <el-option v-for="(item, index) in experssList" :label="item.expressName" :value="item.expressCode"/>-->
<el-option label="顺丰速运" value="1" />
<el-option label="申通快递" value="2" />
<el-option label="圆通快递" value="2" />
</el-select>
</el-form-item>
<el-form-item label="快递单号" prop="expressSn">
<el-input v-model="deliveryObj.form.expressSn" placeholder="请输入快递单号" controls-position="right" :min="0" />
</el-form-item>
</el-form>
<template v-slot:footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitDelivery('deliveryForm')"> </el-button>
<el-button @click="cancelDelivery"> </el-button>
</div>
</template>
</el-dialog>
<!-- 保存商家备注对话框 -->
<el-dialog :title="noteObj.title" v-model:visible="noteObj.open" width="500px" append-to-body>
<el-form ref="noteForm" :model="noteObj.form" label-width="100px">
<el-form-item label="备注" prop="merchantNote">
<el-input type="textarea" v-model="noteObj.form.merchantNote" controls-position="right" :min="0" :rows="3" />
</el-form-item>
</el-form>
<template v-slot:footer>
<div class="dialog-footer">
<el-button type="primary" size="small" @click="submitNoteForm()"> 确认修改 </el-button>
<el-button size="small" @click="cancelNote"> </el-button>
</div>
</template>
</el-dialog>
<!-- 日志 -->
<el-dialog :title="logObj.title" v-model:visible="logObj.open" width="500px" append-to-body>
<el-timeline>
<el-timeline-item v-for="item in logObj.logList" placement="top" :timestamp="parseTime(item.createTime, '')">
<el-card>
<h4>{{ getLogEvent(item.orderStatus) }}</h4>
<br />
<h4>操作人{{ item.operateMan }}</h4>
<br v-if="item.note" />
<h4 v-if="item.note">备注{{ item.note }}</h4>
</el-card>
</el-timeline-item>
</el-timeline>
</el-dialog>
<el-dialog title="修改收件信息" v-model:visible="modifyReceiverInfo.open" width="500px" append-to-body :close-on-click-modal="false">
<el-form ref="modifyReceiverInfoForm" :model="modifyReceiverInfo.form" label-width="100px" :rules="modifyReceiverInfo.rules">
<el-form-item label="收件人姓名" prop="receiverName">
<el-input v-model="modifyReceiverInfo.form.receiverName" />
</el-form-item>
<el-form-item label="收件人电话" prop="receiverPhone">
<el-input v-model="modifyReceiverInfo.form.receiverPhone" />
</el-form-item>
<el-form-item label="省市区" prop="fullArea">
<AddressSelector v-model="modifyReceiverInfo.form.fullArea" style="width: 100%" />
</el-form-item>
<el-form-item label="详细地址" prop="receiverDetailAddress">
<el-input v-model="modifyReceiverInfo.form.receiverDetailAddress" />
</el-form-item>
</el-form>
<template v-slot:footer>
<div class="dialog-footer">
<el-button type="primary" size="small" @click="asyncOk"> 确认修改 </el-button>
<el-button size="small" @click="modifyReceiverInfo.open = false"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script>
import {
addOmsOrder,
deliverProduct,
delOmsOrder,
exportOmsOrder,
getDecryptPhone,
listOmsOrder,
saveMerchantNote,
updateOmsOrder,
updateReceiverAddress,
viewLog
} from '@/api/oms/order';
import AddressSelector from '@/views/components/AddressSelector/index.vue';
import dateUtil, { dateFormat } from '@/utils/DateUtil';
import { isStarRepo } from '@/utils/is-star-plugin';
import { useUserStore } from '@/store/modules/user';
export default {
name: 'OmsOrder',
dicts: ['oms_order_status', 'oms_pay_type'],
components: {
AddressSelector
},
data() {
const validArea = (rule, value, callback) => {
const fullArea = this.modifyReceiverInfo.form.fullArea;
if (fullArea.length < 3) {
callback(new Error('请选择省市区'));
} else {
callback();
}
};
return {
show: false,
//
loading: true,
pickerOptions: {
shortcuts: dateUtil.getTimeShort2()
},
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
omsOrderList: [],
//
title: '',
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
payType: null,
status: null,
Time: [],
provinces: [],
receiverProvince: null,
receiverCity: null,
receiverDistrict: null,
orderSn: null,
productName: null,
userPhone: null,
startTime: null,
endTime: null
},
//
form: {},
//
rules: {
memberId: [{ required: true, message: 'MEMBER_ID不能为空', trigger: 'blur' }],
receiverName: [{ required: true, message: '收货人姓名不能为空', trigger: 'blur' }],
receiverPhone: [{ required: true, message: '收货人电话不能为空', trigger: 'blur' }]
},
showMoreCondition: false,
deliveryObj: {
title: '订单发货',
form: {
orderId: null,
expressName: null,
expressSn: null
},
open: false,
rules: {
expressName: [{ required: true, message: '快递公司不能为空', trigger: 'change' }],
expressSn: [{ required: true, message: '快递单号不能为空', trigger: 'blur' }]
}
},
noteObj: {
title: null,
form: {
id: null,
merchantNote: null
},
open: false
},
logObj: {
title: '日志',
logList: null,
open: false,
loading: false
},
modifyReceiverInfo: {
open: false,
form: {},
rules: {
receiverName: [{ required: true, message: '收件人姓名不能为空', trigger: 'blur' }],
receiverPhone: [{ required: true, message: '收件人电话不能为空', trigger: 'blur' }],
fullArea: [{ required: true, validator: validArea, trigger: 'change' }],
receiverDetailAddress: [{ required: true, message: '详细地址不能为空', trigger: 'blur' }]
}
}
};
},
computed: {
userId: {
get() {
return useUserStore().userId;
}
}
},
async created() {
const res = await isStarRepo(
'zccbbg',
'RuoYi-Mall',
this.userId,
'https://mall.ichengle.top/order/order',
'ruoyi-mall-商城',
'https://gitee.com/zccbbg/RuoYi-Mall'
);
this.show = res;
if (res) {
const { phone, status, today } = this.$route.query;
if (phone) {
this.queryParams.userPhone = phone;
}
if (status) {
this.queryParams.status = status;
}
if (today) {
this.setToday();
}
this.getList();
}
},
methods: {
/** 日期组件设置为今天 */
setToday() {
const temp = new Date();
this.queryParams.Time[0] = dateFormat(new Date(temp.setHours(0, 0, 0, 0)), 'yyyy-MM-dd hh:mm:ss');
this.queryParams.Time[1] = dateFormat(new Date(temp.setHours(23, 59, 59, 0)), 'yyyy-MM-dd hh:mm:ss');
},
/** 查询订单表列表 */
getList() {
if (this.queryParams.Time) {
this.queryParams.startTime = this.queryParams.Time[0];
this.queryParams.endTime = this.queryParams.Time[1];
}
this.loading = true;
const { pageNum, pageSize } = this.queryParams;
const query = { ...this.queryParams, pageNum: undefined, pageSize: undefined };
if (query.provinces) {
const [receiverProvince, receiverCity, receiverDistrict] = query.provinces;
query.receiverProvince = receiverProvince;
query.receiverCity = receiverCity;
query.receiverDistrict = receiverDistrict;
} else {
query.receiverProvince = null;
query.receiverCity = null;
query.receiverDistrict = null;
}
const pageReq = { page: pageNum - 1, size: pageSize };
listOmsOrder(query, pageReq).then((response) => {
const { content, totalElements } = response;
this.omsOrderList = content;
this.total = totalElements;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
memberId: null,
memberUsername: null,
totalAmount: null,
purchasePrice: null,
payAmount: null,
freightAmount: null,
payType: null,
status: 0,
aftersaleStatus: 0,
deliveryCompany: null,
deliverySn: null,
autoConfirmDay: null,
receiverName: null,
receiverPhone: null,
receiverPostCode: null,
receiverProvince: null,
receiverCity: null,
receiverDistrict: null,
receiverDetailAddress: null,
note: null,
confirmStatus: 0,
deleteStatus: 0,
paymentTime: null,
deliveryTime: null,
receiveTime: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.resetForm('form');
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = '添加订单表';
},
/** 修改按钮操作 */
async handleUpdate(row) {
await this.handleWatch(row);
const { receiverCity, receiverDistrict, receiverProvince } = row;
row.fullArea = [receiverProvince, receiverCity, receiverDistrict];
this.modifyReceiverInfo.form = row;
this.modifyReceiverInfo.open = true;
},
handleWatch(row) {
getDecryptPhone(row.id).then((response) => {
row.receiverPhone = response;
row.decrypt = true;
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (valid) {
if (this.form.id != null) {
updateOmsOrder(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
} else {
addOmsOrder(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal
.confirm('是否确认删除订单表编号为"' + ids + '"的数据项?')
.then(function () {
return delOmsOrder(ids);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal
.confirm('是否确认导出所有订单表数据项?')
.then(() => {
this.exportLoading = true;
return exportOmsOrder(queryParams);
})
.then((response) => {
this.$download.download(response);
this.exportLoading = false;
})
.catch(() => {});
},
//change
handleChange(value) {
if (!value) {
this.queryParams.startTime = null;
this.queryParams.endTime = null;
}
},
getOrderStatusTag(status) {
switch (status) {
case 0:
case 1:
return 'info';
case 2:
return 'primary';
case 3:
return 'success';
case 4:
return 'warning';
case 5:
return 'danger';
}
},
getOrderStatusText(status) {
switch (status) {
case 0:
return '待付款';
case 1:
return '待发货';
case 2:
return '已发货';
case 3:
return '已完成';
case 4:
return '已关闭';
case 5:
return '无效订单';
}
},
getLogEvent(status) {
switch (status) {
case 0:
return '用户下单';
case 1:
return '用户支付成功';
case 2:
return '平台发货';
case 3:
return '用户确认收货';
case 4:
return '取消订单';
case 5:
return '无效订单';
}
},
getPayTypeTag(type) {
switch (type) {
case 0:
return 'info';
case 1:
return 'primary';
case 2:
return 'success';
}
},
getPayTypeText(type) {
switch (type) {
case 0:
return '未支付';
case 1:
return '支付宝';
case 2:
return '微信';
}
},
goDetail(row) {
const id = row.id;
this.$router.push({ path: '/order/detail', query: { id } });
},
copy(data) {
const url = data;
const oInput = document.createElement('input');
oInput.value = url;
document.body.appendChild(oInput);
oInput.select(); // ;
console.log(oInput.value);
document.execCommand('Copy'); //
this.$modal.msgSuccess('复制成功');
oInput.remove();
},
handleDelivery(row) {
this.deliveryObj.form.orderId = row.id;
this.deliveryObj.open = true;
},
submitDelivery() {
this.$refs['deliveryForm'].validate((valid) => {
if (valid) {
deliverProduct(this.deliveryObj.form).then((resp) => {
this.$modal.msgSuccess('发货成功');
this.cancelDelivery();
this.getList();
});
}
});
},
cancelDelivery() {
this.deliveryObj.open = false;
this.deliveryObj.form.orderId = null;
this.deliveryObj.form.expressName = null;
this.deliveryObj.form.expressSn = null;
},
handleSaveNote(row) {
const merchantNote = row.merchantNote;
if (merchantNote) {
this.noteObj.title = '修改平台备注';
} else {
this.noteObj.title = '添加平台备注';
}
this.noteObj.form.id = row.id;
this.noteObj.form.merchantNote = row.merchantNote;
this.noteObj.open = true;
},
//
submitNoteForm() {
saveMerchantNote(this.noteObj.form).then((resp) => {
if (resp > 0) {
this.$modal.msgSuccess('修改成功');
this.cancelNote();
this.getList();
}
});
},
cancelNote() {
this.noteObj.open = false;
this.noteObj.form.id = null;
this.noteObj.form.merchantNote = null;
},
showLog(orderId) {
this.logObj.loading = true;
viewLog(orderId).then((response) => {
this.logObj.logList = response;
this.logObj.open = true;
this.logObj.loading = false;
});
},
asyncOk() {
this.$refs['modifyReceiverInfoForm'].validate((valid) => {
if (valid) {
const { id, receiverName, fullArea, receiverPhone, receiverDetailAddress } = this.modifyReceiverInfo.form;
const [receiverProvince, receiverCity, receiverDistrict] = fullArea;
updateReceiverAddress({
id,
receiverCity,
receiverDetailAddress,
receiverDistrict,
receiverName,
receiverPhone,
receiverProvince
}).then((resp) => {
this.$modal.msgSuccess('修改成功');
this.getList();
this.modifyReceiverInfo.open = false;
});
}
});
}
}
};
</script>
<style lang="scss">
.product-container {
display: flex;
flex-direction: row;
align-items: center;
width: 340px;
.product-item {
margin: auto;
width: 290px;
.sp-data {
font-size: 13px;
}
.quantity {
font-weight: bold;
font-size: 13px;
}
}
}
.note-title {
font-weight: bold;
}
.el-table .my-cell {
vertical-align: top;
}
.el-link.el-link--default {
color: #409eff;
}
.el-select {
width: 100%;
}
</style>

View File

@ -0,0 +1,258 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="订单id" prop="orderId">
<el-input
v-model="queryParams.orderId"
placeholder="请输入订单id"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="物流公司(配送方式)" prop="deliveryCompany">
<el-input
v-model="queryParams.deliveryCompany"
placeholder="请输入物流公司(配送方式)"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="物流单号" prop="deliverySn">
<el-input
v-model="queryParams.deliverySn"
placeholder="请输入物流单号"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item class="flex_one tr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['oms:orderDeliveryHistory:add']"
>新增</el-button>
</el-col>
</el-col>
</el-row>
<el-table v-loading="loading" :data="omsOrderDeliveryHistoryList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="订单id" align="center" prop="orderId" />
<el-table-column label="物流公司(配送方式)" align="center" prop="deliveryCompany" />
<el-table-column label="物流单号" align="center" prop="deliverySn" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['oms:orderDeliveryHistory:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['oms:orderDeliveryHistory:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改订单发货记录对话框 -->
<el-dialog :title="title" :visible.sync="open" width="50%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="108px" inline class="dialog-form-two">
<el-form-item label="订单id" prop="orderId">
<el-input v-model="form.orderId" placeholder="请输入订单id" />
</el-form-item>
<el-form-item label="物流公司(配送方式)" prop="deliveryCompany">
<el-input v-model="form.deliveryCompany" placeholder="请输入物流公司(配送方式)" />
</el-form-item>
<el-form-item label="物流单号" prop="deliverySn">
<el-input v-model="form.deliverySn" placeholder="请输入物流单号" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listOmsOrderDeliveryHistory, getOmsOrderDeliveryHistory, delOmsOrderDeliveryHistory, addOmsOrderDeliveryHistory, updateOmsOrderDeliveryHistory, exportOmsOrderDeliveryHistory } from "@/api/oms/orderDeliveryHistory";
export default {
name: "OmsOrderDeliveryHistory",
data() {
return {
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
omsOrderDeliveryHistoryList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
orderId: null,
deliveryCompany: null,
deliverySn: null,
},
//
form: {},
//
rules: {
},
};
},
created() {
this.getList();
},
methods: {
/** 查询订单发货记录列表 */
getList() {
this.loading = true;
const {pageNum, pageSize} = this.queryParams;
const query = {...this.queryParams, pageNum: undefined, pageSize: undefined};
const pageReq = {page: pageNum - 1, size: pageSize};
listOmsOrderDeliveryHistory(query, pageReq).then(response => {
const { content, totalElements } = response
this.omsOrderDeliveryHistoryList = content;
this.total = totalElements;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
orderId: null,
deliveryCompany: null,
deliverySn: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加订单发货记录";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getOmsOrderDeliveryHistory(id).then(response => {
this.form = response;
this.open = true;
this.title = "修改订单发货记录";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateOmsOrderDeliveryHistory(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addOmsOrderDeliveryHistory(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除订单发货记录编号为"' + ids + '"的数据项?').then(function() {
return delOmsOrderDeliveryHistory(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal.confirm('是否确认导出所有订单发货记录数据项?').then(() => {
this.exportLoading = true;
return exportOmsOrderDeliveryHistory(queryParams);
}).then(response => {
this.$download.download(response);
this.exportLoading = false;
}).catch(() => {});
}
}
};
</script>

View File

@ -0,0 +1,424 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="订单id" prop="orderId">
<el-input
v-model="queryParams.orderId"
placeholder="请输入订单id"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="PRODUCT_ID" prop="productId">
<el-input
v-model="queryParams.productId"
placeholder="请输入PRODUCT_ID"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="商品编码" prop="outProductId">
<el-input
v-model="queryParams.outProductId"
placeholder="请输入商品编码"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="商品sku id" prop="skuId">
<el-input
v-model="queryParams.skuId"
placeholder="请输入商品sku id"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="sku编码" prop="outSkuId">
<el-input
v-model="queryParams.outSkuId"
placeholder="请输入sku编码"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="商品快照id" prop="productSnapshotId">
<el-input
v-model="queryParams.productSnapshotId"
placeholder="请输入商品快照id"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="sku快照id" prop="skuSnapshotId">
<el-input
v-model="queryParams.skuSnapshotId"
placeholder="请输入sku快照id"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<template v-if="showMoreCondition">
<el-form-item label="展示图片" prop="pic">
<el-input
v-model="queryParams.pic"
placeholder="请输入展示图片"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="PRODUCT_NAME" prop="productName">
<el-input
v-model="queryParams.productName"
placeholder="请输入PRODUCT_NAME"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="销售价格" prop="salePrice">
<el-input
v-model="queryParams.salePrice"
placeholder="请输入销售价格"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="采购价" prop="purchasePrice">
<el-input
v-model="queryParams.purchasePrice"
placeholder="请输入采购价"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="购买数量" prop="quantity">
<el-input
v-model="queryParams.quantity"
placeholder="请输入购买数量"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="商品分类id" prop="productCategoryId">
<el-input
v-model="queryParams.productCategoryId"
placeholder="请输入商品分类id"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</template>
<el-form-item class="flex_one tr">
<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-button :icon="showMoreCondition ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" size="mini" @click="showMoreCondition = !showMoreCondition">{{showMoreCondition ? '收起条件' : '展开条件'}}</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['oms:orderItem:add']"
>新增</el-button>
</el-col>
</el-col>
</el-row>
<el-table v-loading="loading" :data="omsOrderItemList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="订单id" align="center" prop="orderId" />
<el-table-column label="PRODUCT_ID" align="center" prop="productId" />
<el-table-column label="商品编码" align="center" prop="outProductId" />
<el-table-column label="商品sku id" align="center" prop="skuId" />
<el-table-column label="sku编码" align="center" prop="outSkuId" />
<el-table-column label="商品快照id" align="center" prop="productSnapshotId" />
<el-table-column label="sku快照id" align="center" prop="skuSnapshotId" />
<el-table-column label="展示图片" align="center" prop="pic" />
<el-table-column label="PRODUCT_NAME" align="center" prop="productName" />
<el-table-column label="销售价格" align="center" prop="salePrice" />
<el-table-column label="采购价" align="center" prop="purchasePrice" />
<el-table-column label="购买数量" align="center" prop="quantity" />
<el-table-column label="商品分类id" align="center" prop="productCategoryId" />
<el-table-column label="商品sku属性:[{"key":"颜色","value":"颜色"},{"key":"容量","value":"4G"}]" align="center" prop="spData" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['oms:orderItem:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['oms:orderItem:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改订单中所包含的商品对话框 -->
<el-dialog :title="title" :visible.sync="open" width="50%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="108px" inline class="dialog-form-two">
<el-form-item label="订单id" prop="orderId">
<el-input v-model="form.orderId" placeholder="请输入订单id" />
</el-form-item>
<el-form-item label="PRODUCT_ID" prop="productId">
<el-input v-model="form.productId" placeholder="请输入PRODUCT_ID" />
</el-form-item>
<el-form-item label="商品编码" prop="outProductId">
<el-input v-model="form.outProductId" placeholder="请输入商品编码" />
</el-form-item>
<el-form-item label="商品sku id" prop="skuId">
<el-input v-model="form.skuId" placeholder="请输入商品sku id" />
</el-form-item>
<el-form-item label="sku编码" prop="outSkuId">
<el-input v-model="form.outSkuId" placeholder="请输入sku编码" />
</el-form-item>
<el-form-item label="商品快照id" prop="productSnapshotId">
<el-input v-model="form.productSnapshotId" placeholder="请输入商品快照id" />
</el-form-item>
<el-form-item label="sku快照id" prop="skuSnapshotId">
<el-input v-model="form.skuSnapshotId" placeholder="请输入sku快照id" />
</el-form-item>
<el-form-item label="展示图片" prop="pic">
<el-input v-model="form.pic" placeholder="请输入展示图片" />
</el-form-item>
<el-form-item label="PRODUCT_NAME" prop="productName">
<el-input v-model="form.productName" placeholder="请输入PRODUCT_NAME" />
</el-form-item>
<el-form-item label="销售价格" prop="salePrice">
<el-input v-model="form.salePrice" placeholder="请输入销售价格" />
</el-form-item>
<el-form-item label="采购价" prop="purchasePrice">
<el-input v-model="form.purchasePrice" placeholder="请输入采购价" />
</el-form-item>
<el-form-item label="购买数量" prop="quantity">
<el-input v-model="form.quantity" placeholder="请输入购买数量" />
</el-form-item>
<el-form-item label="商品分类id" prop="productCategoryId">
<el-input v-model="form.productCategoryId" placeholder="请输入商品分类id" />
</el-form-item>
<el-form-item label="商品sku属性:[{"key":"颜色","value":"颜色"},{"key":"容量","value":"4G"}]" prop="spData">
<el-input v-model="form.spData" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listOmsOrderItem, getOmsOrderItem, delOmsOrderItem, addOmsOrderItem, updateOmsOrderItem, exportOmsOrderItem } from "@/api/oms/orderItem";
export default {
name: "OmsOrderItem",
data() {
return {
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
omsOrderItemList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
orderId: null,
productId: null,
outProductId: null,
skuId: null,
outSkuId: null,
productSnapshotId: null,
skuSnapshotId: null,
pic: null,
productName: null,
salePrice: null,
purchasePrice: null,
quantity: null,
productCategoryId: null,
spData: null,
},
//
form: {},
//
rules: {
outProductId: [
{ required: true, message: "商品编码不能为空", trigger: "blur" }
],
outSkuId: [
{ required: true, message: "sku编码不能为空", trigger: "blur" }
],
},
showMoreCondition: false
};
},
created() {
this.getList();
},
methods: {
/** 查询订单中所包含的商品列表 */
getList() {
this.loading = true;
const {pageNum, pageSize} = this.queryParams;
const query = {...this.queryParams, pageNum: undefined, pageSize: undefined};
const pageReq = {page: pageNum - 1, size: pageSize};
listOmsOrderItem(query, pageReq).then(response => {
const { content, totalElements } = response
this.omsOrderItemList = content;
this.total = totalElements;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
orderId: null,
productId: null,
outProductId: null,
skuId: null,
outSkuId: null,
productSnapshotId: null,
skuSnapshotId: null,
pic: null,
productName: null,
salePrice: null,
purchasePrice: null,
quantity: null,
productCategoryId: null,
spData: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加订单中所包含的商品";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getOmsOrderItem(id).then(response => {
this.form = response;
this.open = true;
this.title = "修改订单中所包含的商品";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateOmsOrderItem(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addOmsOrderItem(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除订单中所包含的商品编号为"' + ids + '"的数据项?').then(function() {
return delOmsOrderItem(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal.confirm('是否确认导出所有订单中所包含的商品数据项?').then(() => {
this.exportLoading = true;
return exportOmsOrderItem(queryParams);
}).then(response => {
this.$download.download(response);
this.exportLoading = false;
}).catch(() => {});
}
}
};
</script>

View File

@ -0,0 +1,287 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="订单号" prop="orderId">
<el-input
v-model="queryParams.orderSn"
placeholder="请输入订单号"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="订单状态" prop="status">
<DictRadio v-model="queryParams.status" :radioData="dict?.type.oms_order_status" size="small" :show-all="'all'"></DictRadio>
</el-form-item>
<el-form-item class="flex_one tr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="omsOrderOperateHistoryList" @selection-change="handleSelectionChange">
<!-- <el-table-column type="selection" width="55" align="center" />-->
<el-table-column label="订单号" align="center" prop="orderSn" />
<el-table-column label="订单状态" align="center" prop="orderStatus">
<template v-slot="scope">
<el-tag :type="getOrderTypeTag(scope.row.orderStatus)" style="margin-right: 10px">
{{ getOrderTypeText(scope.row.orderStatus) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="note" />
<el-table-column label="操作时间" align="center" prop="createTime">
<template v-slot="scope">
<div>{{ parseTime(scope.row.createTime, '')}}</div>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<!-- <el-button-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-edit"-->
<!-- @click="handleUpdate(scope.row)"-->
<!-- v-hasPermi="['oms:orderOperateHistory:edit']"-->
<!-- >修改</el-button>-->
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['oms:orderOperateHistory:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改订单操作历史记录对话框 -->
<el-dialog :title="title" :visible.sync="open" width="50%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="108px" inline class="dialog-form-two">
<el-form-item label="订单id" prop="orderId">
<el-input v-model="form.orderId" placeholder="请输入订单id" />
</el-form-item>
<el-form-item label="操作人:用户;系统;后台管理员" prop="operateMan">
<el-input v-model="form.operateMan" placeholder="请输入操作人:用户;系统;后台管理员" />
</el-form-item>
<el-form-item label="订单状态0->待付款1->待发货2->已发货3->已完成4->已关闭5->无效订单">
<el-radio-group v-model="form.orderStatus">
<el-radio label="1">请选择字典生成</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="note">
<el-input v-model="form.note" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listOmsOrderOperateHistory, getOmsOrderOperateHistory, delOmsOrderOperateHistory, addOmsOrderOperateHistory, updateOmsOrderOperateHistory, exportOmsOrderOperateHistory } from "@/api/oms/orderOperateHistory";
export default {
name: "OmsOrderOperateHistory",
dicts: ["oms_order_status"],
data() {
return {
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
omsOrderOperateHistoryList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
orderSn: null,
operateMan: null,
orderStatus: null,
note: null,
},
//
form: {},
//
rules: {
},
};
},
created() {
this.getList();
},
methods: {
/** 查询订单操作历史记录列表 */
getList() {
this.loading = true;
const {pageNum, pageSize} = this.queryParams;
const query = {...this.queryParams, pageNum: undefined, pageSize: undefined};
const pageReq = {page: pageNum - 1, size: pageSize};
listOmsOrderOperateHistory(query, pageReq).then(response => {
const { content, totalElements } = response
this.omsOrderOperateHistoryList = content;
this.total = totalElements;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
orderId: null,
operateMan: null,
orderStatus: 0,
note: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加订单操作历史记录";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getOmsOrderOperateHistory(id).then(response => {
this.form = response;
this.open = true;
this.title = "修改订单操作历史记录";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateOmsOrderOperateHistory(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addOmsOrderOperateHistory(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除订单操作历史记录编号为"' + ids + '"的数据项?').then(function() {
return delOmsOrderOperateHistory(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal.confirm('是否确认导出所有订单操作历史记录数据项?').then(() => {
this.exportLoading = true;
return exportOmsOrderOperateHistory(queryParams);
}).then(response => {
this.$download.download(response);
this.exportLoading = false;
}).catch(() => {});
},
getOrderTypeTag(status){
switch (status){
case 0:
case 1:
return 'info';
case 2:
return 'primary';
case 3:
return 'success';
case 4:
return 'warning';
case 5:
return 'danger';
}
},
getOrderTypeText(status){
switch (status){
case 0:
return '待付款';
case 1:
return '待发货';
case 2:
return '已发货';
case 3:
return '已完成';
case 4:
return '已关闭';
case 5:
return '无效订单';
case 11:
return '售后待处理';
case 12:
return '退货中';
case 13:
return '售后已完成';
case 14:
return '售后已拒绝';
}
}
}
};
</script>

View File

@ -0,0 +1,395 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="payment_id" prop="paymentId">
<el-input
v-model="queryParams.paymentId"
placeholder="请输入payment_id"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="用户 ID" prop="memberId">
<el-input
v-model="queryParams.memberId"
placeholder="请输入用户 ID"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="OPENID" prop="openid">
<el-input
v-model="queryParams.openid"
placeholder="请输入OPENID"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="真实姓名,提现需要" prop="realName">
<el-input
v-model="queryParams.realName"
placeholder="请输入真实姓名,提现需要"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="标题|商品名称" prop="title">
<el-input
v-model="queryParams.title"
placeholder="请输入标题|商品名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="订单号 支付时是payId 其他为orderId" prop="orderId">
<el-input
v-model="queryParams.orderId"
placeholder="请输入订单号 支付时是payId 其他为orderId"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="金额,单位分" prop="money">
<el-input
v-model="queryParams.money"
placeholder="请输入金额,单位分"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<template v-if="showMoreCondition">
<el-form-item label="交易类型" prop="opType">
<el-select v-model="queryParams.opType" placeholder="请选择交易类型" clearable size="small">
<el-option label="请选择字典生成" value="" />
</el-select>
</el-form-item>
<el-form-item label="状态" prop="paymentStatus">
<el-select v-model="queryParams.paymentStatus" placeholder="请选择状态" clearable size="small">
<el-option label="请选择字典生成" value="" />
</el-select>
</el-form-item>
<el-form-item label="附加数据" prop="attach">
<el-input
v-model="queryParams.attach"
placeholder="请输入附加数据"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</template>
<el-form-item class="flex_one tr">
<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-button :icon="showMoreCondition ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" size="mini" @click="showMoreCondition = !showMoreCondition">{{showMoreCondition ? '收起条件' : '展开条件'}}</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['pms:wechatPaymentHistory:add']"
>新增</el-button>
</el-col>
</el-col>
</el-row>
<el-table v-loading="loading" :data="omsWechatPaymentHistoryList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="payment_id" align="center" prop="paymentId" />
<el-table-column label="用户 ID" align="center" prop="memberId" />
<el-table-column label="OPENID" align="center" prop="openid" />
<el-table-column label="真实姓名,提现需要" align="center" prop="realName" />
<el-table-column label="标题|商品名称" align="center" prop="title" />
<el-table-column label="订单号 支付时是payId 其他为orderId" align="center" prop="orderId" />
<el-table-column label="金额,单位分" align="center" prop="money" />
<el-table-column label="交易类型" align="center" prop="opType" />
<el-table-column label="状态" align="center" prop="paymentStatus" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="附加数据" align="center" prop="attach" />
<el-table-column label="响应内容" align="center" prop="responseBody" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['pms:wechatPaymentHistory:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['pms:wechatPaymentHistory:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改微信订单表对话框 -->
<el-dialog :title="title" :visible.sync="open" width="50%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="108px" inline class="dialog-form-two">
<el-form-item label="payment_id" prop="paymentId">
<el-input v-model="form.paymentId" placeholder="请输入payment_id" />
</el-form-item>
<el-form-item label="用户 ID" prop="memberId">
<el-input v-model="form.memberId" placeholder="请输入用户 ID" />
</el-form-item>
<el-form-item label="OPENID" prop="openid">
<el-input v-model="form.openid" placeholder="请输入OPENID" />
</el-form-item>
<el-form-item label="真实姓名,提现需要" prop="realName">
<el-input v-model="form.realName" placeholder="请输入真实姓名,提现需要" />
</el-form-item>
<el-form-item label="标题|商品名称" prop="title">
<el-input v-model="form.title" placeholder="请输入标题|商品名称" />
</el-form-item>
<el-form-item label="订单号 支付时是payId 其他为orderId" prop="orderId">
<el-input v-model="form.orderId" placeholder="请输入订单号 支付时是payId 其他为orderId" />
</el-form-item>
<el-form-item label="金额,单位分" prop="money">
<el-input v-model="form.money" placeholder="请输入金额,单位分" />
</el-form-item>
<el-form-item label="交易类型" prop="opType">
<el-select v-model="form.opType" placeholder="请选择交易类型">
<el-option label="请选择字典生成" value="" />
</el-select>
</el-form-item>
<el-form-item label="状态">
<el-radio-group v-model="form.paymentStatus">
<el-radio label="1">请选择字典生成</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
<el-form-item label="附加数据" prop="attach">
<el-input v-model="form.attach" placeholder="请输入附加数据" />
</el-form-item>
<el-form-item label="响应内容" prop="responseBody">
<el-input v-model="form.responseBody" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listOmsWechatPaymentHistory, getOmsWechatPaymentHistory, delOmsWechatPaymentHistory, addOmsWechatPaymentHistory, updateOmsWechatPaymentHistory, exportOmsWechatPaymentHistory } from "@/api/oms/wechatPaymentHistory";
export default {
name: "OmsWechatPaymentHistory",
data() {
return {
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
omsWechatPaymentHistoryList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
paymentId: null,
memberId: null,
openid: null,
realName: null,
title: null,
orderId: null,
money: null,
opType: null,
paymentStatus: null,
attach: null,
responseBody: null,
},
//
form: {},
//
rules: {
memberId: [
{ required: true, message: "用户 ID不能为空", trigger: "blur" }
],
openid: [
{ required: true, message: "OPENID不能为空", trigger: "blur" }
],
title: [
{ required: true, message: "标题|商品名称不能为空", trigger: "blur" }
],
orderId: [
{ required: true, message: "订单号 支付时是payId 其他为orderId不能为空", trigger: "blur" }
],
money: [
{ required: true, message: "金额,单位分不能为空", trigger: "blur" }
],
opType: [
{ required: true, message: "交易类型不能为空", trigger: "change" }
],
paymentStatus: [
{ required: true, message: "状态不能为空", trigger: "blur" }
],
},
showMoreCondition: false
};
},
created() {
this.getList();
},
methods: {
/** 查询微信订单表列表 */
getList() {
this.loading = true;
const {pageNum, pageSize} = this.queryParams;
const query = {...this.queryParams, pageNum: undefined, pageSize: undefined};
const pageReq = {page: pageNum - 1, size: pageSize};
listOmsWechatPaymentHistory(query, pageReq).then(response => {
const { content, totalElements } = response
this.omsWechatPaymentHistoryList = content;
this.total = totalElements;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
paymentId: null,
memberId: null,
openid: null,
realName: null,
title: null,
orderId: null,
money: null,
opType: null,
paymentStatus: 0,
remark: null,
attach: null,
responseBody: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加微信订单表";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getOmsWechatPaymentHistory(id).then(response => {
this.form = response;
this.open = true;
this.title = "修改微信订单表";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateOmsWechatPaymentHistory(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addOmsWechatPaymentHistory(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除微信订单表编号为"' + ids + '"的数据项?').then(function() {
return delOmsWechatPaymentHistory(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal.confirm('是否确认导出所有微信订单表数据项?').then(() => {
this.exportLoading = true;
return exportOmsWechatPaymentHistory(queryParams);
}).then(response => {
this.$download.download(response);
this.exportLoading = false;
}).catch(() => {});
}
}
};
</script>

View File

@ -0,0 +1,257 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="状态" prop="showStatus">
<DictRadio v-model="queryParams.showStatus" @change="handleQuery" size="small"
:radioData="dict?.type.sys_normal_disable" :showAll="'all'"/>
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input
v-model="queryParams.nameLike"
placeholder="名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item class="flex_one tr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="pmsBrandList" @selection-change="handleSelectionChange" border>
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="品牌logo" prop="logo">
<template slot-scope="{ row }">
<el-image v-if="row.logo" :src="row.logo" :preview-src-list="[row.logo]" class="small-img circle-img"/>
</template>
</el-table-column>
<el-table-column label="名称" prop="name"/>
<el-table-column label="排序" prop="sort"/>
<el-table-column label="状态" prop="showStatus">
<template slot-scope="{ row }">
<dict-tag :value="row.showStatus" prop-name="sys_normal_disable"/>
</template>
</el-table-column>
<el-table-column label="操作" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改
</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<InBody v-show="total>0">
<pagination
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</InBody>
<!-- 添加或修改品牌管理对话框 -->
<el-dialog :title="title" :visible.sync="open" width="50%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="108px" inline class="dialog-form-one">
<el-form-item label="状态">
<DictRadio v-model="form.showStatus" size="small"
:radioData="dict?.type.sys_normal_disable"/>
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input v-model="form.name" placeholder="名称" />
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input v-model="form.sort" placeholder="请输入排序" />
</el-form-item>
<el-form-item label="logo" prop="logo">
<oss-image-upload v-model="form.logo" :limit="1" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {addPmsBrand, delPmsBrand, exportPmsBrand, getPmsBrand, listPmsBrand, updatePmsBrand} from "@/api/pms/brand";
export default {
name: "PmsBrand",
dicts: ['sys_normal_disable'],
data() {
return {
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
pmsBrandList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
nameLike: null,
sort: null,
showStatus: null,
},
//
form: {},
//
rules: {
},
};
},
created() {
this.getList();
},
methods: {
/** 查询品牌管理列表 */
getList() {
this.loading = true;
const {pageNum, pageSize} = this.queryParams;
const query = {...this.queryParams, pageNum: undefined, pageSize: undefined};
const pageReq = {page: pageNum - 1, size: pageSize};
listPmsBrand(query, pageReq).then(response => {
const { content, totalElements } = response
this.pmsBrandList = content;
this.total = totalElements;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
name: null,
sort: null,
showStatus: 0,
logo: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加品牌管理";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getPmsBrand(id).then(response => {
this.form = response;
this.open = true;
this.title = "修改品牌管理";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updatePmsBrand(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addPmsBrand(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除品牌管理编号为"' + ids + '"的数据项?').then(function() {
return delPmsBrand(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal.confirm('是否确认导出所有品牌管理数据项?').then(() => {
this.exportLoading = true;
return exportPmsBrand(queryParams);
}).then(response => {
this.$download.download(response);
this.exportLoading = false;
}).catch(() => {});
}
}
};
</script>

View File

@ -0,0 +1,371 @@
<template>
<div class="add-product-wrapper">
<el-form label-width="108px" :model="form" ref="form" :rules="rules">
<el-card style="margin: 20px 20px; font-size: 14px">
<template v-slot:header>
<div>
<span>基本信息</span>
</div>
</template>
<el-row>
<el-col :span="12">
<el-form-item label="商品名称" prop="name">
<el-input v-model="form.name" placeholder="请输入商品名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="商品编码" prop="outProductId">
<el-input v-model="form.outProductId" placeholder="请输入商品编码"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="品牌" prop="brandId">
<brand-select v-model="form.brandId" @change="onBrandChange"></brand-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="分类" prop="categoryId">
<product-category-select v-model="form.categoryId" @change="categoryChange"></product-category-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="排序" prop="sort">
<el-input v-model="form.sort" placeholder="请输入排序"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="价格" prop="price">
<el-input v-model="form.price" placeholder="请输入PRICE"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="单位" prop="unit">
<el-input v-model="form.unit" placeholder="请输入单位"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="商品重量" prop="weight">
<el-input v-model="form.weight" placeholder="商品重量,默认为克"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="上架状态">
<DictRadio v-model="form.publishStatus" size="small" :radioData="dict?.type.pms_publish_status" />
</el-form-item>
</el-col>
</el-row>
</el-card>
<el-card style="margin: 20px 20px; font-size: 14px">
<template v-slot:header>
<div>
<span>产品图片</span>
</div>
</template>
<el-form-item label="主图" prop="pic">
<oss-image-upload v-model="form.pic" :limit="1"></oss-image-upload>
</el-form-item>
<el-form-item label="轮播图" prop="albumPics">
<oss-image-upload v-model="albumPics" :limit="5"></oss-image-upload>
</el-form-item>
</el-card>
<el-card style="margin: 20px 20px; font-size: 14px">
<template v-slot:header>
<div>
<span>产品规格</span>
</div>
</template>
<el-form-item label="规格类型">
<div class="sku-wrapper">
<div class="sku_sorts">
<div class="sku_sort" v-for="(s, idx0) in productAttr" :key="s.name">
<div class="label flex-center">
<div class="flex-one">
<dict-select v-model="s.name" prop-name="sku_sort_list" value-prop="label"></dict-select>
</div>
<a class="red" @click="deleteSkuSort(idx0)">删除规格类型</a>
</div>
<div class="values" v-if="s.name">
<div class="value" v-for="(it2, idx1) in s.options" :key="idx1">
<el-input :value="it2.name" @input="changeName(s, idx1, $event)" placeholder="请输入规格名称"></el-input
><a
class="red no-break ml8"
v-if="idx1 < s.options.length - 1 || (s.options.length === maxOptionNum &amp;&amp; idx1 === 3)"
@click="deleteOption(s, idx1)"
>删除</a
>
</div>
</div>
</div>
</div>
<el-button v-if="productAttr.length < 2" @click="addSkuSort">+添加规格类型</el-button>
</div>
</el-form-item>
<el-form-item label="规格信息">
<el-button @click="refreshSku()" class="mb20">刷新列表</el-button>
<el-table :data="form.skuList" :max-height="400">
<el-table-column v-for="s in skuAttr" :label="s.name" :key="s.name" :prop="s.name"></el-table-column>
<el-table-column label="展示图片">
<template v-slot="{ row }">
<oss-image-upload class="img-upload-mini" v-model="row.pic" :limit="1" :is-show-tip="false"></oss-image-upload>
</template>
</el-table-column>
<el-table-column label="销售价格">
<template v-slot="{ row, $index }">
<el-form-item :rules="{ required: true, message: '请填写价格', trigger: 'blur' }" :prop="'skuList[' + $index + '].price'">
<el-input v-model="row.price"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="库存">
<template v-slot="{ row, $index }">
<el-input v-model="row.stock" type="number"></el-input>
</template>
</el-table-column>
<el-table-column label="编码">
<template v-slot="{ row }">
<el-form-item>
<el-input v-model="row.outSkuId"></el-input>
<el-input v-model="row.spData" v-show="false"></el-input>
</el-form-item>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-card>
<el-card style="margin: 20px 20px; font-size: 14px">
<template v-slot:header>
<div>
<span>详情页</span>
</div>
</template>
<el-form-item label="移动端" prop="detailMobileHtml">
<Editor v-model="form.detailMobileHtml" placeholder="请输入内容" type="url"></Editor>
</el-form-item>
<el-form-item label="PC端" prop="detailHtml">
<Editor v-model="form.detailHtml" placeholder="请输入内容" type="url"></Editor>
</el-form-item>
</el-card>
<div class="tc">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-form>
</div>
</template>
<script>
import { addPmsProduct, getPmsProduct, updatePmsProduct } from '@/api/pms/product';
import ProductCategorySelect from '@/views/components/ProductCategorySelect';
import BrandSelect from '@/views/components/BrandSelect';
import { useMallStore } from '@/store/modules/mall';
export default {
name: 'AddProduct',
dicts: ['pms_publish_status'],
components: { BrandSelect, ProductCategorySelect },
data() {
return {
rules: {
name: [{ required: true, message: '请输入商品名称', trigger: 'blur' }]
},
form: {
publishStatus: 0,
sort: 1000
},
skuAttr: [],
albumPics: null,
productAttr: [
{
name: '颜色',
options: [{ name: '红' }, { name: null }]
}
],
maxOptionNum: 44
};
},
created() {
const { id } = this.$route.query;
if (id) {
this.getInfo(id);
}
},
methods: {
refreshSku() {
let skus = [];
const skuMap = new Map();
this.skuAttr = [...this.productAttr];
if (this.form.skuList) {
this.form.skuList.forEach((sku) => {
skuMap.set(sku.spData, sku);
});
}
this.productAttr.forEach((attr, index) => {
const attrSku = [];
attr.options.forEach((option) => {
if (!option.name) {
return;
}
if (index === 0) {
attrSku.push({ [attr.name]: option.name });
} else {
skus.forEach((it3) => {
attrSku.push({ ...it3, [attr.name]: option.name });
});
}
});
skus = attrSku;
});
skus.forEach((it) => {
if (it) {
it.spData = JSON.stringify(it);
}
});
skus.forEach((it) => {
const sku = skuMap.get(it.spData);
if (sku) {
it.outSkuId = sku.outSkuId;
it.price = sku.price;
it.pic = sku.pic;
it.stock = sku.stock;
it.id = sku.id;
} else {
it.outSkuId = null;
it.price = null;
it.pic = null;
it.stock = null;
it.id = null;
}
});
this.form.productAttr = JSON.stringify(this.productAttr);
this.form.skuList = skus;
},
categoryChange(value) {
if (Array.isArray(value)) {
console.log(value.toString());
this.form.productCategoryName = value.toString();
} else {
this.form.productCategoryName = null;
}
},
onBrandChange(value) {
this.form.brandName = value;
},
getInfo(id) {
getPmsProduct(id).then((response) => {
const { albumPics } = response;
if (albumPics) {
this.albumPics = albumPics.split(',');
}
this.form = response;
if (this.form.productAttr) {
this.productAttr = JSON.parse(this.form.productAttr);
}
this.refreshSku();
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (valid) {
if (this.albumPics) {
this.form.albumPics = this.albumPics.toString();
}
if (this.form.categoryId && Array.isArray(this.form.categoryId)) {
this.form.categoryId = this.form.categoryId.pop();
}
//sku
if (!this.form.price) {
this.form.price = Math.min.apply(
Math,
this.form.skuList.map((it) => it.price)
);
}
if (this.form.id != null) {
updatePmsProduct(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
});
} else {
addPmsProduct(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
});
}
this.cancel();
} else {
if (this.form.name) {
this.$alert('请填写规格价格', '提示', {
confirmButtonText: '确定'
});
} else {
this.$alert('请填写商品名称', '提示', {
confirmButtonText: '确定'
});
}
}
});
},
cancel() {
this.$tab.closeOpenPage({ path: '/pms/product' });
},
changeName(s, idx, val) {
s.options[idx].name = val;
if (s.options.length - 1 !== idx || s.options.length >= this.maxOptionNum) {
return;
}
s.options.push({ name: null });
},
addSkuSort() {
this.productAttr.push({
name: null,
options: [{ name: null }]
});
},
deleteSkuSort(idx) {
this.productAttr.splice(idx);
},
deleteOption(s, idx) {
s.options.splice(idx, 1);
}
}
};
</script>
<style lang="stylus">
.add-product-wrapper
padding 12px
.content
margin 0 auto
width 75%
min-width 800px
.sku-wrapper
background-color #f7f8fa
padding 12px
.sku_sorts
.sku_sort
background-color white
margin-bottom 12px
.label
padding 8px
.values
padding 8px 0 0 8px
border-top 1px solid $border-color
display flex
flex-wrap wrap
.value
padding 0 32px 8px 0
width 200px!important
display flex
align-items center
.img-upload-mini .el-upload--picture-card
width: 48px;
height: 48px;
line-height: 57px;
</style>

View File

@ -0,0 +1,220 @@
<template>
<div class="app-container">
<div v-show="show">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="上架状态" prop="publishStatus">
<DictRadio
v-model="queryParams.publishStatus"
@change="handleQuery"
size="small"
:radioData="dict?.type.pms_publish_status"
:showAll="'all'"
/>
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input v-model="queryParams.nameLike" placeholder="请输入商品名称" clearable size="small" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="品牌" prop="brandName">
<el-input v-model="queryParams.brandNameLike" placeholder="请输入品牌名称" clearable size="small" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="分类" prop="productCategoryName">
<el-input
v-model="queryParams.productCategoryNameLike"
placeholder="请输入分类名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="编码" prop="outProductId">
<el-input v-model="queryParams.outProductId" placeholder="请输入商品编码" clearable size="small" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item class="flex_one tr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="pmsProductList" @selection-change="handleSelectionChange" border>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="主图" prop="pic">
<template v-slot="{ row }">
<el-image v-if="row.pic" :src="row.pic" :preview-src-list="[row.pic]" class="small-img" />
</template>
</el-table-column>
<el-table-column label="名称/编码" min-width="200" prop="outProductId">
<template v-slot="{ row }">
<div>名称{{ row.name }}</div>
<div v-if="row.outProductId">编码{{ row.outProductId }}</div>
</template>
</el-table-column>
<el-table-column label="品牌/分类" prop="brandName">
<template v-slot="{ row }">
<div v-if="row.brandName">品牌{{ row.brandName }}</div>
<div v-if="row.productCategoryName">分类{{ row.productCategoryName }}</div>
</template>
</el-table-column>
<el-table-column label="价格/排序" prop="price">
<template v-slot="{ row }">
<div v-if="row.price">价格{{ row.price }}</div>
<div v-if="row.sort">排序{{ row.sort }}</div>
</template>
</el-table-column>
<el-table-column label="上架状态" prop="publishStatus">
<template v-slot="{ row }">
<dict-tag :value="row.publishStatus" prop-name="pms_publish_status" />
</template>
</el-table-column>
<el-table-column label="操作" class-name="small-padding fixed-width">
<template v-slot="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改 </el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<InBody v-show="total > 0">
<pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</InBody>
</div>
<!-- <SeeAdsComponent ref="seeAdsComponentRef" v-if="!show" @confirmOk="confirmOk"/>-->
</div>
</template>
<script>
import { delPmsProduct, listPmsProduct } from '@/api/pms/product';
import { isStarRepo } from '@/utils/is-star-plugin';
import { useUserStore } from '@/store/modules/user';
export default {
name: 'PmsProduct',
components: {},
dicts: ['pms_publish_status'],
data() {
return {
show: true,
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
pmsProductList: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
brandId: null,
categoryId: null,
outProductId: null,
name: null,
pic: null,
albumPics: null,
publishStatus: null,
sort: null,
price: null,
unit: null,
weight: null,
detailHtml: null,
detailMobileHtml: null,
brandName: null,
productCategoryName: null
}
};
},
created() {
this.getList();
},
computed: {
userId: {
get() {
return useUserStore().userId;
}
}
},
methods: {
async confirmOk(success) {
if (success) {
const res = await isStarRepo(
'zccbbg',
'RuoYi-Mall',
this.userId,
'https://mall.ichengle.top/pms/product',
'ruoyi-mall-商城',
'https://gitee.com/zccbbg/RuoYi-Mall'
);
this.show = res;
if (res) {
this.getList();
}
}
},
/** 查询商品信息列表 */
getList() {
this.loading = true;
const { pageNum, pageSize } = this.queryParams;
const query = { ...this.queryParams, pageNum: undefined, pageSize: undefined };
const pageReq = { page: pageNum - 1, size: pageSize };
listPmsProduct(query, pageReq).then((response) => {
const { content, totalElements } = response;
this.pmsProductList = content;
this.total = totalElements;
this.loading = false;
});
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.$router.push({ path: '/product/edit' });
},
/** 修改按钮操作 */
handleUpdate(row) {
this.$router.push({ path: '/product/edit', query: { id: row.id } });
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal
.confirm('是否确认删除商品信息编号为"' + ids + '"的数据项?')
.then(function () {
return delPmsProduct(ids);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
}
}
};
</script>

View File

@ -0,0 +1,131 @@
<template>
<el-dialog :title="chooseSkuObj.title" :visible.sync="chooseSkuObj.open" :width="chooseSkuObj.width" append-to-body>
<el-form ref="auditForm" inline :model="chooseSkuObj.queryParams" label-width="80px">
<el-form-item label="菜品名称" prop="nameLike">
<el-input
size="small"
placeholder="请输入菜品名称"
v-model="chooseSkuObj.queryParams.nameLike"
clearable
/>
</el-form-item>
<el-form-item label="菜品分类" prop="productCategoryName">
<product-category-select v-model="chooseSkuObj.queryParams.categoryId"></product-category-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="getSkuList">搜索</el-button>
</el-form-item>
</el-form>
<el-table class="mt20" :data="chooseSkuObj.list" ref="table" v-loading="chooseSkuObj.loading" max-height="500" border
row-key="id" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"/>
<el-table-column label="菜品名称" prop="name">
<template v-slot="{row}">
<div class="flex-center">
<el-image v-if="row.pic" :src="row.pic" :preview-src-list="[row.pic]" class="small-img circle-img"/>
<span class="ml5">{{ row.name }}</span>
</div>
</template>
</el-table-column>
<el-table-column label="销量" prop="sales"/>
<el-table-column label="创建时间" prop="createTime"/>
</el-table>
<pagination
v-show="chooseSkuObj.total>0"
:total="chooseSkuObj.total"
:page.sync="chooseSkuObj.queryParams.pageNum"
:limit.sync="chooseSkuObj.queryParams.pageSize"
@pagination="getSkuList"
/>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="chooseSkuObj.open=false"> </el-button>
</div>
</el-dialog>
</template>
<script>
import {listPmsProduct} from "@/api/pms/product";
import ProductCategorySelect from "@/views/components/ProductCategorySelect.vue";
export default {
components: {ProductCategorySelect},
data() {
return {
selectSkuIds: [],
selectProducts: [],
chooseSkuObj: {
loading: false,
open: false,
title: "选择菜品",
list: [],
width: '60%',
queryParams: {
pageNum: 1,
categoryId: null,
pageSize: 10,
nameLike: null,
publishStatus: 1,
excludeProductIds: []
},
total: 0
}
}
},
methods: {
submitForm() {
this.$emit('onComplete', this.selectProducts)
this.chooseSkuObj.open = false
},
async init(chooseProductId) {
this.chooseSkuObj.queryParams.excludeProductIds = chooseProductId;
this.chooseSkuObj.queryParams.pageNum = 1;
await this.getSkuList();
this.chooseSkuObj.open = true
this.$nextTick(()=>{
this.$refs.table.clearSelection()
})
},
judge() {
this.$nextTick(()=>{
this.chooseSkuObj.list.forEach(ele => {
if (this.selectProducts.some(item => item.id === ele.id)) {
this.$refs.table.toggleRowSelection(ele, true)
} else {
this.$refs.table.toggleRowSelection(ele, false)
}
});
})
},
handleSelectionChange(selection) {
this.selectProducts = selection
},
async getSkuList() {
this.chooseSkuObj.loading = true;
const query = {...this.chooseSkuObj.queryParams, pageNum: undefined, pageSize: undefined};
if (query.categoryId && Array.isArray(query.categoryId)) {
query.categoryId = query.categoryId.pop()
}
const {pageNum, pageSize} = this.chooseSkuObj.queryParams;
const pageReq = {page: pageNum - 1, size: pageSize};
await listPmsProduct(query, pageReq).then(response => {
const {content, totalElements} = response
this.chooseSkuObj.list = [...content];
this.chooseSkuObj.total = totalElements;
this.chooseSkuObj.loading = false;
});
},
}
}
</script>
<style lang="stylus">
.line
display flex
align-items center
margin-bottom: 5px;
border-bottom 1px dashed #ccc
.line:last-child
border-bottom 0 !important
margin-bottom 0 !important
</style>

View File

@ -0,0 +1,320 @@
<template>
<div class="app-container">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="100px"
size="medium"
class="ry_form"
>
<el-form-item label="状态" prop="showStatus">
<DictRadio
v-model="queryParams.showStatus"
@change="handleQuery"
size="small"
:radioData="dict?.type.sys_show_status"
:showAll="'all'"
/>
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input
v-model="queryParams.nameLike"
placeholder="名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item class="flex_one tr">
<el-button
type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>搜索</el-button
>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
>重置</el-button
>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
</el-row>
<el-table
v-loading="loading"
:data="pmsProductCategoryList"
border
:tree-props="{ hasChildren: 'hasChildren', children: 'children' }"
@selection-change="handleSelectionChange"
row-key="id"
>
<el-table-column label="名称" prop="name" />
<el-table-column label="图片" prop="icon">
<template slot-scope="{ row }">
<el-image
v-if="row.icon"
:src="row.icon"
:preview-src-list="[row.icon]"
class="small-img circle-img"
/>
</template>
</el-table-column>
<el-table-column label="排序" prop="sort" />
<el-table-column label="状态" prop="showStatus">
<template v-slot="{ row }">
<dict-tag
:value="row.showStatus"
prop-name="sys_show_status"
></dict-tag>
</template>
</el-table-column>
<el-table-column
label="操作"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改
</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 添加或修改商品分类对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="108px">
<el-form-item label="名称" prop="name">
<el-input v-model="form.name" placeholder="名称" />
</el-form-item>
<el-form-item label="图片" prop="icon">
<oss-image-upload v-model="form.icon" :limit="1" />
</el-form-item>
<el-form-item label="状态">
<DictRadio
v-model="form.showStatus"
size="small"
:radioData="dict?.type.sys_show_status"
/>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input v-model="form.sort" placeholder="排序" />
</el-form-item>
<!-- <el-form-item label="层级" prop="level">
<el-input v-model="form.level" placeholder="层级" />
</el-form-item> -->
<!-- <el-form-item label="上级分类" prop="parentId">
<product-category-select class="w200" v-model="form.parentId" :props="{ checkStrictly: true }"/>
</el-form-item> -->
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listPmsProductCategory,
getPmsProductCategory,
delPmsProductCategory,
addPmsProductCategory,
updatePmsProductCategory,
exportPmsProductCategory,
} from "@/api/pms/productCategory";
import ProductCategorySelect from "@/views/components/ProductCategorySelect";
export default {
name: "PmsProductCategory",
dicts: ["sys_show_status"],
components: { ProductCategorySelect },
data() {
return {
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
pmsProductCategoryList: [],
//
title: "",
//
open: false,
//
queryParams: {
parentId: null,
nameLike: null,
level: null,
showStatus: null,
sort: null,
},
//
form: {},
//
rules: {},
};
},
created() {
this.getList();
},
methods: {
/** 查询商品分类列表 */
getList() {
this.loading = true;
const query = { ...this.queryParams };
listPmsProductCategory(query).then((rows) => {
this.pmsProductCategoryList = rows;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
parentId: null,
name: null,
level: null,
showStatus: 0,
sort: null,
icon: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加商品分类";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids;
getPmsProductCategory(id).then((response) => {
this.form = response;
this.open = true;
this.title = "修改商品分类";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate((valid) => {
if (valid) {
let p;
if (this.form.parentId) {
this.form.parentId = this.form.parentId.pop();
}
if (this.form.id != null) {
p = updatePmsProductCategory(this.form).then((response) => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
p = addPmsProductCategory(this.form).then((response) => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
p.then(() => {
this.$store.dispatch("mall/loadProductCategories", true);
});
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
if (row.children && row.children.length > 0) {
this.$message.error("请先删除子目录");
return;
}
const ids = row.id;
this.$modal
.confirm('是否确认删除商品分类编号为"' + ids + '"的数据项?')
.then(function () {
return delPmsProductCategory(ids);
})
.then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
})
.catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal
.confirm("是否确认导出所有商品分类数据项?")
.then(() => {
this.exportLoading = true;
return exportPmsProductCategory(queryParams);
})
.then((response) => {
this.$download.download(response);
this.exportLoading = false;
})
.catch(() => {});
},
},
};
</script>

282
src/views/pms/sku/index.vue Normal file
View File

@ -0,0 +1,282 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="PRODUCT_ID" prop="productId">
<el-input
v-model="queryParams.productId"
placeholder="请输入PRODUCT_ID"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="sku编码" prop="outSkuId">
<el-input
v-model="queryParams.outSkuId"
placeholder="请输入sku编码"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="PRICE" prop="price">
<el-input
v-model="queryParams.price"
placeholder="请输入PRICE"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="展示图片" prop="pic">
<el-input
v-model="queryParams.pic"
placeholder="请输入展示图片"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item class="flex_one tr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['pms:sku:add']"
>新增</el-button>
</el-col>
</el-col>
</el-row>
<el-table v-loading="loading" :data="pmsSkuList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="PRODUCT_ID" align="center" prop="productId" />
<el-table-column label="sku编码" align="center" prop="outSkuId" />
<el-table-column label="PRICE" align="center" prop="price" />
<el-table-column label="展示图片" align="center" prop="pic" />
<el-table-column label="商品销售属性json格式" align="center" prop="spData" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['pms:sku:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['pms:sku:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改sku信息对话框 -->
<el-dialog :title="title" :visible.sync="open" width="50%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="108px" inline class="dialog-form-two">
<el-form-item label="PRODUCT_ID" prop="productId">
<el-input v-model="form.productId" placeholder="请输入PRODUCT_ID" />
</el-form-item>
<el-form-item label="sku编码" prop="outSkuId">
<el-input v-model="form.outSkuId" placeholder="请输入sku编码" />
</el-form-item>
<el-form-item label="PRICE" prop="price">
<el-input v-model="form.price" placeholder="请输入PRICE" />
</el-form-item>
<el-form-item label="展示图片" prop="pic">
<el-input v-model="form.pic" placeholder="请输入展示图片" />
</el-form-item>
<el-form-item label="商品销售属性json格式" prop="spData">
<el-input v-model="form.spData" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listPmsSku, getPmsSku, delPmsSku, addPmsSku, updatePmsSku, exportPmsSku } from "@/api/pms/sku";
export default {
name: "PmsSku",
data() {
return {
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
// sku
pmsSkuList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
productId: null,
outSkuId: null,
price: null,
pic: null,
spData: null,
},
//
form: {},
//
rules: {
outSkuId: [
{ required: true, message: "sku编码不能为空", trigger: "blur" }
],
},
};
},
created() {
this.getList();
},
methods: {
/** 查询sku信息列表 */
getList() {
this.loading = true;
const {pageNum, pageSize} = this.queryParams;
const query = {...this.queryParams, pageNum: undefined, pageSize: undefined};
const pageReq = {page: pageNum - 1, size: pageSize};
listPmsSku(query, pageReq).then(response => {
const { content, totalElements } = response
this.pmsSkuList = content;
this.total = totalElements;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
productId: null,
outSkuId: null,
price: null,
pic: null,
spData: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加sku信息";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getPmsSku(id).then(response => {
this.form = response;
this.open = true;
this.title = "修改sku信息";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updatePmsSku(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addPmsSku(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除sku信息编号为"' + ids + '"的数据项?').then(function() {
return delPmsSku(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal.confirm('是否确认导出所有sku信息数据项').then(() => {
this.exportLoading = true;
return exportPmsSku(queryParams);
}).then(response => {
this.$download.download(response);
this.exportLoading = false;
}).catch(() => {});
}
}
};
</script>

View File

@ -0,0 +1,121 @@
<template>
<div class="app-container">
<el-card>
<div slot="header" class="clearfix">
<div class="flex-center">
<h2>积分获取规则</h2>
<el-button class="ml-auto" type="primary" @click="saveData">保存
</el-button>
</div>
</div>
<el-form :model="incomeVal" label-width="180px">
<el-form-item label="签到活动状态">
<el-switch v-model="incomeVal.signStatus" :active-value="1" :inactive-value="0"/>
</el-form-item>
<el-form-item label="每日签到固定积分">
<el-input
type="number"
v-model="incomeVal.signCount"
style="width:200px"
placeholder="每天签到获取的积分"
>
<template slot="append">
<span>积分</span>
</template>
</el-input>
</el-form-item>
<el-form-item label="消费获得积分">
<div class="flex-center">
<span class="mr5">每消费</span>
<el-input
type="number"
v-model="incomeVal.orderAmount"
style="width:200px"
placeholder="每天签到获取的积分"
>
<template slot="append">
<span></span>
</template>
</el-input>
<span class="ml5 mr5">获得</span>
<el-input
type="number"
v-model="incomeVal.orderCount"
style="width:200px"
placeholder="每天签到获取的积分"
>
<template slot="append">
<span>积分</span>
</template>
</el-input>
</div>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script>
import {addOrUpdate, getConfigKey2} from "@/api/system/config";
const key = "activity-integral-income-set-key"
const defaultIncomeVal = {
signStatus: 1,
signCount: 1,
orderAmount: 1,
orderCount: 1
}
export default {
data() {
return {
incomeObj: {},
incomeVal: {},
}
},
methods: {
initData() {
getConfigKey2(key).then(res => {
if (res.data) {
this.incomeObj = res.data
this.incomeVal = JSON.parse(res.data.configValue)
} else {
this.incomeVal = {...defaultIncomeVal}
this.incomeObj = {
configValue: JSON.stringify(this.incomeVal),
configKey: key,
configType: 'N',
configName: '积分获取规则',
configId: null
}
}
})
},
saveData() {
let self = this;
this.$modal.confirm('是否确认要保存积分获取规则?').then(function () {
self.incomeObj.configValue = JSON.stringify(self.incomeVal)
return addOrUpdate(self.incomeObj);
}).then(() => {
this.initData();
this.$modal.msgSuccess("保存成功");
}).catch(() => {
});
},
},
created() {
this.initData()
},
}
</script>
<style lang="scss" scoped>
.number-input {
width: 120px;
}
.jc {
justify-content: center;
}
</style>

68
src/views/set/setting.vue Normal file
View File

@ -0,0 +1,68 @@
<template>
<div class="app-container">
<el-tabs v-model="activeKey" @tab-click="changeType">
<el-tab-pane v-for="it in tabList" :key="it.value" :label="it.label" :name="it.value"/>
</el-tabs>
<Editor v-model="currentConfig.configValue" placeholder="请输入内容" type="url"></Editor>
<el-button type="primary" class="mt20" @click="asyncOk">保存</el-button>
<el-button class="mt20 ml20" @click="getData">重置</el-button>
</div>
</template>
<script>
import {getConfigKey2, addOrUpdate} from '@/api/system/config'
export default {
data() {
return {
//
activeKey: 'mall.contact',
tabList: [
{label: '客服配置', value: 'mall.contact'},
{label: '隐私协议', value: 'mall.privacyAgreement'},
{label: '常见问题', value: 'mall.question'},
{label: '关于我们', value: 'mall.aboutUs'},
],
configList: [],
currentConfig: {
configValue: '',
}
}
},
methods: {
changeType() {
this.currentConfig = this.configList.filter(it => it.configKey === this.activeKey)[0]
console.log(this.currentConfig)
},
getData() {
const funcArr = this.tabList.map(it => {
return getConfigKey2(it.value)
})
const list = []
Promise.all(funcArr).then(res => {
res.forEach((it, idx) => {
list.push(it.data ? it.data : {
configValue: '',
configType: 'N',
configKey: this.tabList[idx].value,
configName: this.tabList[idx].label,
configId: null
})
})
this.configList = list
this.changeType()
})
},
asyncOk() {
addOrUpdate(this.currentConfig).then(res=>{
this.$message.success('保存成功')
this.getData()
})
}
},
created() {
this.getData()
},
}
</script>

View File

@ -0,0 +1,219 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="创建时间">
<el-date-picker
size="small"
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
:clearable="true"
:picker-options="pickerOptions"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item label="处理状态">
<el-select v-model="queryParams.status" clearable size="small">
<el-option value="0" label="未处理" />
<el-option value="1" label="已处理" />
</el-select>
</el-form-item>
<el-form-item class="flex_one tr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="feedbackList" border>
<el-table-column label="反馈人" align="left" prop="nickname" width="150">
<template v-slot="scope">
<p>用户ID{{ scope.row.createBy }}</p>
<p>{{ scope.row.phone }}</p>
</template>
</el-table-column>
<el-table-column label="反馈时间" prop="createTime" width="180">
<template v-slot="scope">
<div>{{ parseTime(scope.row.createTime) }}</div>
</template>
</el-table-column>
<el-table-column label="反馈类型" prop="type" />
<el-table-column label="具体内容" prop="content" show-overflow-tooltip />
<el-table-column label="图片">
<template v-slot="scope">
<el-image
v-if="scope.row.imageList.length"
style="width: 60px; height: 60px"
v-for="it in scope.row.imageList"
:key="it"
:src="it"
:preview-src-list="[it]"
>
</el-image>
</template>
</el-table-column>
<el-table-column label="处理状态/时间">
<template v-slot="scope">
<div v-if="scope.row.handleStatus === 1">已处理</div>
<el-switch v-else v-model="scope.row.handleStatus" active-value="1" inactive-value="0" @change="changeStatus(scope.row)" />
<div>{{ scope.row.handleTime ? parseTime(scope.row.handleTime) : '' }}</div>
</template>
</el-table-column>
<el-table-column label="备注">
<template v-slot="scope">
<span class="mr10">{{ scope.row.remark }}</span>
<i class="el-icon-edit pointer" @click="showUpdateMark(scope.row)"></i>
</template>
</el-table-column>
</el-table>
<InBody v-show="total > 0">
<pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</InBody>
<el-dialog title="修改备注" v-model:visible="remarkModal.visible" width="30%" append-to-body>
<el-input type="textarea" :rows="3" placeholder="请输入内容" v-model="remarkModal.remark" />
<template v-slot:footer>
<span class="dialog-footer">
<el-button @click="remarkModal.visible = false"> </el-button>
<el-button type="primary" @click="updateRemark"> </el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script>
import { changeHandleStatus, listFeedbacks, updateMark } from '@/api/ums/feedback';
import dateUtil from '@/utils/DateUtil';
import { useUserStore } from '@/store/modules/user';
export default {
name: 'UmsMember',
data() {
return {
show: false,
pickerOptions: {
shortcuts: dateUtil.getTimeShort()
},
remarkModal: {
visible: false,
mark: null,
memberId: null
},
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
feedbackList: [],
//
title: '',
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
status: null
},
dateRange: [],
//
form: {}
};
},
async created() {
this.getList();
},
computed: {
userId: {
get() {
return useUserStore().userId;
}
}
},
methods: {
showUpdateMark(record) {
this.remarkModal = {
visible: true,
remark: record.remark,
id: record.id
};
},
updateRemark() {
updateMark({ id: this.remarkModal.id, remark: this.remarkModal.remark }).then((res) => {
if (res > 0) {
this.$message.success('修改成功');
this.remarkModal.visible = false;
const obj = this.feedbackList.filter((it) => it.id === this.remarkModal.id)[0];
console.log(111, obj, this.remarkModal.remark);
obj.remark = this.remarkModal.remark;
} else {
this.$message.error('修改失败');
}
});
},
/** 查询会员信息列表 */
getList() {
this.loading = true;
const { pageNum, pageSize } = this.queryParams;
let query = { ...this.queryParams, pageNum: undefined, pageSize: undefined };
const pageReq = { page: pageNum - 1, size: pageSize };
if (!this.dateRange || this.dateRange.length > 0) {
query = { ...this.addDateRange2(query, this.dateRange) };
}
listFeedbacks(query, pageReq).then((response) => {
const { content, totalElements } = response;
content.forEach((it) => {
if (it.images) {
it.imageList = it.images.split(',');
} else {
it.imageList = [];
}
});
this.feedbackList = content;
this.total = totalElements;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
//
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
//
changeStatus(row) {
const data = {
id: row.id,
handleStatus: row.handleStatus
};
changeHandleStatus(data).then((response) => {
if (response) {
this.$message.success('操作成功');
this.getList();
}
});
}
}
};
</script>

View File

@ -0,0 +1,414 @@
<template>
<div class="app-container">
<div v-show="show">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="创建时间">
<el-date-picker
size="small"
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
:clearable="true"
:picker-options="pickerOptions"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<!-- <el-form-item label="账号启用状态">-->
<!-- <el-select v-model="queryParams.status" placeholder="请选择" :clearable="true" size="small">-->
<!-- <el-option label="禁用" value="0">-->
<!-- </el-option>-->
<!-- <el-option label="启用" value="1">-->
<!-- </el-option>-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item label="昵称" prop="nickname">
<el-input v-model.trim="queryParams.nickname" placeholder="请输入昵称" clearable size="small" />
</el-form-item>
<el-form-item label="手机号码" prop="phone">
<el-input v-model.trim="queryParams.phone" placeholder="请输入手机号码" clearable size="small" />
</el-form-item>
<el-form-item label="备注" prop="mark">
<el-select v-model="queryParams.hasMark" clearable size="small">
<el-option value="1" label="有备注" />
<el-option value="0" label="无备注" />
</el-select>
</el-form-item>
<el-form-item class="flex_one tr">
<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-button :icon="showMoreCondition ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" size="mini" @click="showMoreCondition = !showMoreCondition">{{showMoreCondition ? '收起条件' : '展开条件'}}</el-button>-->
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="umsMemberList" border>
<el-table-column label="昵称" prop="nickname" width="150" />
<el-table-column label="手机号码" prop="phoneHidden" width="150" />
<el-table-column label="佣金" width="120">
<template v-slot="scope">
<div>0.00</div>
</template>
</el-table-column>
<el-table-column label="积分" width="120">
<template v-slot="scope">
<div>0.00</div>
</template>
</el-table-column>
<el-table-column label="余额" width="120">
<template v-slot="scope">
<div>0.00</div>
</template>
</el-table-column>
<el-table-column label="注册时间" prop="createTime" width="180">
<template v-slot="scope">
<div>{{ parseTime(scope.row.createTime) }}</div>
</template>
</el-table-column>
<el-table-column label="上次登录" prop="createTime">
<template v-slot="scope">
<div>{{ parseTime(scope.row.createTime) }}</div>
</template>
</el-table-column>
<el-table-column label="备注">
<template v-slot="scope">
<span class="mr10">{{ scope.row.mark }}</span>
<i class="el-icon-edit pointer" @click="showUpdateMark(scope.row)"></i>
</template>
</el-table-column>
<el-table-column label="操作" class-name="small-padding fixed-width" fix="right" width="200">
<template v-slot="scope">
<el-button size="mini" type="text" @click="showStatistics(scope.row.id)" v-hasPermi="['ums:member:statistics']">查看数据 </el-button>
<el-button size="mini" type="text" @click="goOrder(scope.row.phoneEncrypted)">查看下单</el-button>
<el-button size="mini" type="text" @click="goCart(scope.row.phoneEncrypted)">查看购物车</el-button>
</template>
</el-table-column>
</el-table>
<InBody v-show="total > 0">
<pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</InBody>
</div>
<SeeAdsComponent ref="seeAdsComponentRef" v-if="!show" @confirmOk="confirmOk" />
<!-- 统计 -->
<el-dialog :title="statisticsObj.title" v-model:visible="statisticsObj.open" width="500px" append-to-body>
<el-descriptions direction="vertical" :column="2" border>
<el-descriptions-item label="购物车数">{{ statisticsObj.data.cartCount }}</el-descriptions-item>
<el-descriptions-item label="订单数">{{ statisticsObj.data.orderCount }}</el-descriptions-item>
<el-descriptions-item label="下单金额">{{ statisticsObj.data.orderAmount.toFixed(2) }}</el-descriptions-item>
<el-descriptions-item label="售后数">{{ statisticsObj.data.aftersaleCount }}</el-descriptions-item>
</el-descriptions>
</el-dialog>
<el-dialog title="修改备注" v-model:visible="remarkModal.visible" width="30%" append-to-body>
<el-input type="textarea" :rows="3" placeholder="请输入内容" v-model="remarkModal.mark" />
<template v-slot:footer>
<span class="dialog-footer">
<el-button @click="remarkModal.visible = false"> </el-button>
<el-button type="primary" @click="updateRemark"> </el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script>
import {
addUmsMember,
changeAccountStatus,
decryptedPhone,
delUmsMember,
exportUmsMember,
getUmsMember,
listUmsMember,
updateUmsMember,
updateUmsMemberMark,
viewStatistics
} from '@/api/ums/member';
import dateUtil from '@/utils/DateUtil';
import { isStarRepo } from '@/utils/is-star-plugin';
import { useUserStore } from '@/store/modules/user';
import SeeAdsComponent from '@/components/SeeAdsComponent.vue';
export default {
name: 'UmsMember',
components: { SeeAdsComponent },
data() {
return {
show: false,
pickerOptions: {
shortcuts: dateUtil.getTimeShort()
},
remarkModal: {
visible: false,
mark: null,
memberId: null
},
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
umsMemberList: [],
//
title: '',
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
nickname: null,
phone: null,
status: undefined,
hasMark: undefined
},
dateRange: [],
//
form: {},
//
rules: {
level: [{ required: true, message: '等级不能为空', trigger: 'blur' }],
integral: [{ required: true, message: '用户剩余积分不能为空', trigger: 'blur' }]
},
showMoreCondition: false,
statisticsObj: {
open: false,
data: {
cartCount: 0,
orderCount: 0,
orderAmount: 0.0,
aftersaleCount: 0
},
title: '用户数据统计'
}
};
},
async created() {
this.$nextTick(() => {
this.$refs.seeAdsComponentRef.show();
});
},
computed: {
userId: {
get() {
return useUserStore().userId;
}
}
},
methods: {
async confirmOk(success) {
if (success) {
const res = await isStarRepo(
'zccbbg',
'RuoYi-Mall',
this.userId,
'https://mall.ichengle.top/member/member',
'ruoyi-mall-商城',
'https://gitee.com/zccbbg/RuoYi-Mall'
);
this.show = res;
if (res) {
this.getList();
}
}
},
showUpdateMark(record) {
this.remarkModal = {
visible: true,
mark: record.mark,
memberId: record.id
};
},
updateRemark() {
updateUmsMemberMark({ id: this.remarkModal.memberId, mark: this.remarkModal.mark }).then((res) => {
if (res > 0) {
this.$message.success('修改成功');
this.remarkModal.visible = false;
const obj = this.umsMemberList.filter((it) => it.id === this.remarkModal.memberId)[0];
obj.mark = this.remarkModal.mark;
} else {
this.$message.success('修改失败');
}
});
},
/** 查询会员信息列表 */
getList() {
this.loading = true;
const { pageNum, pageSize } = this.queryParams;
let query = { ...this.queryParams, pageNum: undefined, pageSize: undefined };
const pageReq = { page: pageNum - 1, size: pageSize };
if (!this.dateRange || this.dateRange.length > 0) {
query = { ...this.addDateRange2(query, this.dateRange) };
}
listUmsMember(query, pageReq).then((response) => {
const { content, totalElements } = response;
this.umsMemberList = content;
this.total = totalElements;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
nickname: null,
password: null,
phone: null,
mark: null,
status: 0,
avatar: null,
gender: null,
city: null,
province: null,
country: null,
remark: null,
birthday: null,
spreadUid: null,
spreadTime: null,
level: null,
integral: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.resetForm('form');
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = '添加会员信息';
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids;
getUmsMember(id).then((response) => {
this.form = response;
this.open = true;
this.title = '修改会员信息';
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (valid) {
if (this.form.id != null) {
updateUmsMember(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
} else {
addUmsMember(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal
.confirm('是否确认删除会员信息编号为"' + ids + '"的数据项?')
.then(function () {
return delUmsMember(ids);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal
.confirm('是否确认导出所有会员信息数据项?')
.then(() => {
this.exportLoading = true;
return exportUmsMember(queryParams);
})
.then((response) => {
this.$download.download(response);
this.exportLoading = false;
})
.catch(() => {});
},
//
changeStatus(row) {
const data = {
memberId: row.id,
status: row.status
};
changeAccountStatus(data).then((response) => {
if (response < 1) {
this.$modal.msgError('操作失败');
this.getList();
}
});
},
goOrder(phone) {
decryptedPhone(phone).then((res) => {
this.$router.push({
path: '/order/order',
query: {
phone: res
}
});
});
},
goCart(phone) {
decryptedPhone(phone).then((res) => {
this.$router.push({
path: '/member/shoppingCart',
query: {
phone: res
}
});
});
},
showStatistics(memberId) {
viewStatistics(memberId).then((response) => {
this.statisticsObj.data = response;
this.statisticsObj.open = true;
});
}
}
};
</script>

View File

@ -0,0 +1,350 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="收货人姓名" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入收货人姓名"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="手机号" prop="phone">
<el-input
v-model="queryParams.phone"
placeholder="请输入手机号"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="邮政编码" prop="postCode">
<el-input
v-model="queryParams.postCode"
placeholder="请输入邮政编码"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="省份/直辖市" prop="province">
<el-input
v-model="queryParams.province"
placeholder="请输入省份/直辖市"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="城市" prop="city">
<el-input
v-model="queryParams.city"
placeholder="请输入城市"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<template v-if="showMoreCondition">
<el-form-item label="区" prop="district">
<el-input
v-model="queryParams.district"
placeholder="请输入区"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="详细地址" prop="detailAddress">
<el-input
v-model="queryParams.detailAddress"
placeholder="请输入详细地址"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</template>
<el-form-item class="flex_one tr">
<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-button :icon="showMoreCondition ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" size="mini" @click="showMoreCondition = !showMoreCondition">{{showMoreCondition ? '收起条件' : '展开条件'}}</el-button>
</el-form-item>
</el-form>
<!-- <el-row :gutter="10" class="mb8">-->
<!-- <el-col :span="1.5">-->
<!-- <el-button-->
<!-- type="primary"-->
<!-- plain-->
<!-- icon="el-icon-plus"-->
<!-- size="mini"-->
<!-- @click="handleAdd"-->
<!-- v-hasPermi="['ums:memberAddress:add']"-->
<!-- >新增</el-button>-->
<!-- </el-col>-->
<!-- </el-col>-->
<!-- </el-row>-->
<el-table v-loading="loading" :data="umsMemberAddressList">
<!-- <el-table-column type="selection" width="55" align="center" />-->
<el-table-column label="收货人姓名" align="center" prop="name" >
<template v-slot="scope">
<div>{{ getHiddenName(scope.row.name) }}</div>
</template>
</el-table-column>
<el-table-column label="手机号" align="center" prop="phoneHidden" />
<el-table-column label="邮政编码" align="center" prop="postCode" />
<el-table-column label="省份/直辖市" align="center" prop="province" />
<el-table-column label="城市" align="center" prop="city" />
<el-table-column label="区" align="center" prop="district" />
<el-table-column label="详细地址" align="center" prop="detailAddress" width="250">
<template v-slot="scope">
<div>{{ getHiddenDetailAddress(scope.row.detailAddress) }}</div>
</template>
</el-table-column>
<!-- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">-->
<!-- <template slot-scope="scope">-->
<!-- <el-button-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-edit"-->
<!-- @click="handleUpdate(scope.row)"-->
<!-- v-hasPermi="['ums:memberAddress:edit']"-->
<!-- >修改</el-button>-->
<!-- <el-button-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-delete"-->
<!-- @click="handleDelete(scope.row)"-->
<!-- v-hasPermi="['ums:memberAddress:remove']"-->
<!-- >删除</el-button>-->
<!-- </template>-->
<!-- </el-table-column>-->
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改会员收货地址对话框 -->
<el-dialog :title="title" :visible.sync="open" width="50%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="108px" inline class="dialog-form-two">
<el-form-item label="MEMBER_ID" prop="memberId">
<el-input v-model="form.memberId" placeholder="请输入MEMBER_ID" />
</el-form-item>
<el-form-item label="收货人名称" prop="name">
<el-input v-model="form.name" placeholder="请输入收货人名称" />
</el-form-item>
<el-form-item label="PHONE" prop="phone">
<el-input v-model="form.phone" placeholder="请输入PHONE" />
</el-form-item>
<el-form-item label="是否为默认">
<el-radio-group v-model="form.defaultStatus">
<el-radio label="1">请选择字典生成</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="邮政编码" prop="postCode">
<el-input v-model="form.postCode" placeholder="请输入邮政编码" />
</el-form-item>
<el-form-item label="省份/直辖市" prop="province">
<el-input v-model="form.province" placeholder="请输入省份/直辖市" />
</el-form-item>
<el-form-item label="城市" prop="city">
<el-input v-model="form.city" placeholder="请输入城市" />
</el-form-item>
<el-form-item label="区" prop="district">
<el-input v-model="form.district" placeholder="请输入区" />
</el-form-item>
<el-form-item label="详细地址(街道)" prop="detailAddress">
<el-input v-model="form.detailAddress" placeholder="请输入详细地址(街道)" />
</el-form-item>
<el-form-item label="是否默认" prop="isDefault">
<el-input v-model="form.isDefault" placeholder="请输入是否默认" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listUmsMemberAddress, getUmsMemberAddress, delUmsMemberAddress, addUmsMemberAddress, updateUmsMemberAddress, exportUmsMemberAddress } from "@/api/ums/memberAddress";
export default {
name: "UmsMemberAddress",
data() {
return {
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
umsMemberAddressList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
memberId: null,
name: null,
phone: null,
defaultStatus: null,
postCode: null,
province: null,
city: null,
district: null,
detailAddress: null,
isDefault: null,
},
//
form: {},
//
rules: {
isDefault: [
{ required: true, message: "是否默认不能为空", trigger: "blur" }
],
},
showMoreCondition: false,
chineseNumbers: ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
};
},
created() {
this.getList();
},
methods: {
/** 查询会员收货地址列表 */
getList() {
this.loading = true;
const {pageNum, pageSize} = this.queryParams;
const query = {...this.queryParams, pageNum: undefined, pageSize: undefined};
const pageReq = {page: pageNum - 1, size: pageSize};
listUmsMemberAddress(query, pageReq).then(response => {
const { content, totalElements } = response
this.umsMemberAddressList = content;
this.total = totalElements;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
memberId: null,
name: null,
phone: null,
defaultStatus: 0,
postCode: null,
province: null,
city: null,
district: null,
detailAddress: null,
isDefault: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加会员收货地址";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getUmsMemberAddress(id).then(response => {
this.form = response;
this.open = true;
this.title = "修改会员收货地址";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateUmsMemberAddress(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addUmsMemberAddress(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除会员收货地址编号为"' + ids + '"的数据项?').then(function() {
return delUmsMemberAddress(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal.confirm('是否确认导出所有会员收货地址数据项?').then(() => {
this.exportLoading = true;
return exportUmsMemberAddress(queryParams);
}).then(response => {
this.$download.download(response);
this.exportLoading = false;
}).catch(() => {});
}
}
};
</script>

View File

@ -0,0 +1,295 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="用户手机号" prop="phone">
<el-input
v-model="queryParams.phone"
placeholder="用户手机号"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="商品名称" prop="productName">
<el-input
v-model="queryParams.productName"
placeholder="商品名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item class="flex_one tr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="umsMemberCartList" @selection-change="handleSelectionChange" border cell-class-name="my-cell">
<!-- <el-table-column type="selection" width="55" />-->
<el-table-column label="用户信息" prop="phoneHidden">
<template v-slot="scope">
<p>{{scope.row.phoneHidden}}</p>
<p>{{scope.row.nickname}}</p>
</template>
</el-table-column>
<el-table-column label="用户备注" prop="mark" />
<el-table-column label="商品名称" prop="productName" />
<el-table-column label="商品规格" prop="spData">
<template v-slot="scope">
<div class="product-container">
<el-popover
placement="right"
trigger="hover">
<el-image :src="scope.row.pic" style="width: 350px;height: 350px"/>
<el-image slot="reference" class="small-img product-item" :src="scope.row.pic" style="width: 40px;height: 40px"/>
</el-popover>
<div class="product-item" style="margin-left: 5px">
<div class="sp-data">
<span v-for="(value, key) in JSON.parse(scope.row.spData)">{{ key }}{{ value }}&nbsp;</span>
</div>
<div class="product-item quantity">
<span style="margin-right: 10px">{{ scope.row.price }}</span>
<span>x{{ scope.row.quantity }}</span>
</div>
</div>
</div>
</template>
</el-table-column>
<!-- <el-table-column label="价格" prop="price">-->
<!-- <template v-slot="scope">-->
<!-- <div>{{ scope.row.price.toFixed(2) }}</div>-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="状态" prop="skuIfExist">
<template v-slot="scope">
<el-tag effect="plain" size="medium" :type="scope.row.skuIfExist === 1 ? 'success' : 'error'">
{{ scope.row.skuIfExist === 1 ? '有效' : '失效' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="加入时间" prop="createTime">
<template v-slot="scope">
<div>{{ parseTime(scope.row.createTime, '')}}</div>
</template>
</el-table-column>
<!-- <el-table-column label="操作" class-name="small-padding fixed-width">-->
<!-- <template slot-scope="scope">-->
<!-- <el-button-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-edit"-->
<!-- @click="handleUpdate(scope.row)"-->
<!-- v-hasPermi="['ums:memberCart:edit']"-->
<!-- >修改</el-button>-->
<!-- <el-button-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-delete"-->
<!-- @click="handleDelete(scope.row)"-->
<!-- v-hasPermi="['ums:memberCart:remove']"-->
<!-- >删除</el-button>-->
<!-- </template>-->
<!-- </el-table-column>-->
</el-table>
<InBody v-show="total>0">
<pagination
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</InBody>
</div>
</template>
<script>
import {
addUmsMemberCart,
delUmsMemberCart,
exportUmsMemberCart,
getUmsMemberCart,
listUmsMemberCart,
updateUmsMemberCart
} from "@/api/ums/memberCart";
export default {
name: "UmsMemberCart",
data() {
return {
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
umsMemberCartList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
productName: null,
phone: null
},
//
form: {}
};
},
created() {
const { phone } = this.$route.query
if (phone){
this.queryParams.phone = phone
}
this.getList();
},
methods: {
/** 查询购物车列表 */
getList() {
this.loading = true;
const {pageNum, pageSize} = this.queryParams;
const query = {...this.queryParams, pageNum: undefined, pageSize: undefined};
const pageReq = {page: pageNum - 1, size: pageSize};
listUmsMemberCart(query, pageReq).then(response => {
const { content, totalElements } = response
this.umsMemberCartList = content;
this.total = totalElements;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
status: 0,
memberId: null,
productId: null,
pic: null,
skuId: null,
productName: null,
spData: null,
quantity: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
// this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加购物车";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getUmsMemberCart(id).then(response => {
this.form = response;
this.open = true;
this.title = "修改购物车";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateUmsMemberCart(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addUmsMemberCart(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除购物车编号为"' + ids + '"的数据项?').then(function() {
return delUmsMemberCart(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal.confirm('是否确认导出所有购物车数据项?').then(() => {
this.exportLoading = true;
return exportUmsMemberCart(queryParams);
}).then(response => {
this.$download.download(response);
this.exportLoading = false;
}).catch(() => {});
}
}
};
</script>
<style lang="scss">
.product-container{
display: flex;
flex-direction: row;
align-items: center;
width: 180px;
.product-item{
margin: auto;
width: 180px;
.sp-data{
font-size: 13px;
}
.quantity{
font-weight: bold;
font-size: 13px;
}
}
}
.el-table .my-cell {
vertical-align: top
}
</style>

View File

@ -0,0 +1,274 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="会员手机号" prop="phone">
<el-input
v-model="queryParams.phone"
placeholder="请输入会员手机号"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="登录IP地址" prop="ipaddr">
<el-input
v-model="queryParams.ipaddr"
placeholder="请输入登录IP地址"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="登录地点" prop="loginLocation">
<el-input
v-model="queryParams.loginLocation"
placeholder="请输入登录地点"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="浏览器类型" prop="browser">
<el-input
v-model="queryParams.browser"
placeholder="请输入浏览器类型"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="操作系统" prop="os">
<el-input
v-model="queryParams.os"
placeholder="请输入操作系统"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="登录时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
:clearable="false"
:picker-options='pickerOptions'
range-separator="-"
start-placeholder="开始时间"
end-placeholder="结束时间"
></el-date-picker>
</el-form-item>
<el-form-item class="flex_one tr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="umsMemberLogininforList" @selection-change="handleSelectionChange" border>
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="会员手机号" prop="phone"/>
<el-table-column label="会员id" prop="memberId"/>
<el-table-column label="登录IP地址" prop="ipaddr"/>
<el-table-column label="登录地点" prop="loginLocation"/>
<el-table-column label="浏览器类型" prop="browser"/>
<el-table-column label="操作系统" prop="os"/>
<el-table-column label="登陆时间" prop="loginTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.loginTime, '') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['ums:memberLogininfor:remove']"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<InBody v-show="total>0">
<pagination
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</InBody>
</div>
</template>
<script>
import {
addUmsMemberLogininfor,
delUmsMemberLogininfor,
exportUmsMemberLogininfor,
getUmsMemberLogininfor,
listUmsMemberLogininfor,
updateUmsMemberLogininfor
} from "@/api/ums/memberLogininfor";
import dateUtil from '@/utils/DateUtil';
export default {
name: "UmsMemberLogininfor",
data() {
return {
dateRange: [],
pickerOptions: {
shortcuts: dateUtil.getTimeShort()
},
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
umsMemberLogininforList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
phone: null,
ipaddr: null,
loginLocation: null,
browser: null,
os: null,
loginTime: null
},
//
form: {},
//
rules: {
},
};
},
created() {
this.getList();
},
methods: {
/** 查询会员登录记录列表 */
getList() {
this.loading = true;
const {pageNum, pageSize} = this.queryParams;
const query = {...this.queryParams, pageNum: undefined, pageSize: undefined};
const pageReq = {page: pageNum - 1, size: pageSize};
listUmsMemberLogininfor({...this.addDateRange2(query, this.dateRange)}, pageReq).then(response => {
const { content, totalElements } = response
this.umsMemberLogininforList = content;
this.total = totalElements;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
phone: null,
memberId: null,
ipaddr: null,
loginLocation: null,
browser: null,
os: null,
loginTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加会员登录记录";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getUmsMemberLogininfor(id).then(response => {
this.form = response;
this.open = true;
this.title = "修改会员登录记录";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateUmsMemberLogininfor(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addUmsMemberLogininfor(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除会员登录记录编号为"' + ids + '"的数据项?').then(function() {
return delUmsMemberLogininfor(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal.confirm('是否确认导出所有会员登录记录数据项?').then(() => {
this.exportLoading = true;
return exportUmsMemberLogininfor(queryParams);
}).then(response => {
this.$download.download(response);
this.exportLoading = false;
}).catch(() => {});
}
}
};
</script>

View File

@ -0,0 +1,404 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form">
<el-form-item label="MEMBER_ID" prop="memberId">
<el-input
v-model="queryParams.memberId"
placeholder="请输入MEMBER_ID"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段" prop="unionid">
<el-input
v-model="queryParams.unionid"
placeholder="请输入只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="用户的标识,对当前公众号唯一" prop="openid">
<el-input
v-model="queryParams.openid"
placeholder="请输入用户的标识,对当前公众号唯一"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="小程序唯一身份ID" prop="routineOpenid">
<el-input
v-model="queryParams.routineOpenid"
placeholder="请输入小程序唯一身份ID"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="用户所在的分组ID" prop="groupid">
<el-input
v-model="queryParams.groupid"
placeholder="请输入用户所在的分组ID"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="用户被打上的标签ID列表" prop="tagidList">
<el-input
v-model="queryParams.tagidList"
placeholder="请输入用户被打上的标签ID列表"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="用户是否订阅该公众号标识" prop="subscribe">
<el-input
v-model="queryParams.subscribe"
placeholder="请输入用户是否订阅该公众号标识"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<template v-if="showMoreCondition">
<el-form-item label="关注公众号时间" prop="subscribeTime">
<el-input
v-model="queryParams.subscribeTime"
placeholder="请输入关注公众号时间"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="小程序用户会话密匙" prop="sessionKey">
<el-input
v-model="queryParams.sessionKey"
placeholder="请输入小程序用户会话密匙"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="过期时间" prop="expiresIn">
<el-input
v-model="queryParams.expiresIn"
placeholder="请输入过期时间"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="过期时间" prop="expireTime">
<el-date-picker
clearable
size="small"
v-model="queryParams.expireTime"
type="datetime"
value-format="yyyy-MM-ddTHH:mm:ss"
placeholder="选择过期时间">
</el-date-picker>
</el-form-item>
</template>
<el-form-item class="flex_one tr">
<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-button :icon="showMoreCondition ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" size="mini" @click="showMoreCondition = !showMoreCondition">{{showMoreCondition ? '收起条件' : '展开条件'}}</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['ums:memberWechat:add']"
>新增</el-button>
</el-col>
</el-col>
</el-row>
<el-table v-loading="loading" :data="umsMemberWechatList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="MEMBER_ID" align="center" prop="memberId" />
<el-table-column label="只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段" align="center" prop="unionid" />
<el-table-column label="用户的标识,对当前公众号唯一" align="center" prop="openid" />
<el-table-column label="小程序唯一身份ID" align="center" prop="routineOpenid" />
<el-table-column label="用户所在的分组ID" align="center" prop="groupid" />
<el-table-column label="用户被打上的标签ID列表" align="center" prop="tagidList" />
<el-table-column label="用户是否订阅该公众号标识" align="center" prop="subscribe" />
<el-table-column label="关注公众号时间" align="center" prop="subscribeTime" />
<el-table-column label="小程序用户会话密匙" align="center" prop="sessionKey" />
<el-table-column label="token" align="center" prop="accessToken" />
<el-table-column label="过期时间" align="center" prop="expiresIn" />
<el-table-column label="刷新token" align="center" prop="refreshToken" />
<el-table-column label="过期时间" align="center" prop="expireTime" width="180" >
<template slot-scope="scope">
<span>{{ parseTime(scope.row.expireTime, '')}}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['ums:memberWechat:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['ums:memberWechat:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改用户微信信息对话框 -->
<el-dialog :title="title" :visible.sync="open" width="50%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="108px" inline class="dialog-form-two">
<el-form-item label="MEMBER_ID" prop="memberId">
<el-input v-model="form.memberId" placeholder="请输入MEMBER_ID" />
</el-form-item>
<el-form-item label="只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段" prop="unionid">
<el-input v-model="form.unionid" placeholder="请输入只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段" />
</el-form-item>
<el-form-item label="用户的标识,对当前公众号唯一" prop="openid">
<el-input v-model="form.openid" placeholder="请输入用户的标识,对当前公众号唯一" />
</el-form-item>
<el-form-item label="小程序唯一身份ID" prop="routineOpenid">
<el-input v-model="form.routineOpenid" placeholder="请输入小程序唯一身份ID" />
</el-form-item>
<el-form-item label="用户所在的分组ID" prop="groupid">
<el-input v-model="form.groupid" placeholder="请输入用户所在的分组ID" />
</el-form-item>
<el-form-item label="用户被打上的标签ID列表" prop="tagidList">
<el-input v-model="form.tagidList" placeholder="请输入用户被打上的标签ID列表" />
</el-form-item>
<el-form-item label="用户是否订阅该公众号标识" prop="subscribe">
<el-input v-model="form.subscribe" placeholder="请输入用户是否订阅该公众号标识" />
</el-form-item>
<el-form-item label="关注公众号时间" prop="subscribeTime">
<el-input v-model="form.subscribeTime" placeholder="请输入关注公众号时间" />
</el-form-item>
<el-form-item label="小程序用户会话密匙" prop="sessionKey">
<el-input v-model="form.sessionKey" placeholder="请输入小程序用户会话密匙" />
</el-form-item>
<el-form-item label="token" prop="accessToken">
<el-input v-model="form.accessToken" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="过期时间" prop="expiresIn">
<el-input v-model="form.expiresIn" placeholder="请输入过期时间" />
</el-form-item>
<el-form-item label="刷新token" prop="refreshToken">
<el-input v-model="form.refreshToken" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="过期时间" prop="expireTime">
<el-date-picker clearable size="small"
v-model="form.expireTime"
type="datetime"
value-format="yyyy-MM-ddTHH:mm:ss"
placeholder="选择过期时间">
</el-date-picker>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listUmsMemberWechat, getUmsMemberWechat, delUmsMemberWechat, addUmsMemberWechat, updateUmsMemberWechat, exportUmsMemberWechat } from "@/api/ums/memberWechat";
export default {
name: "UmsMemberWechat",
data() {
return {
//
loading: true,
//
exportLoading: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
umsMemberWechatList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
memberId: null,
unionid: null,
openid: null,
routineOpenid: null,
groupid: null,
tagidList: null,
subscribe: null,
subscribeTime: null,
sessionKey: null,
accessToken: null,
expiresIn: null,
refreshToken: null,
expireTime: null,
},
//
form: {},
//
rules: {
},
showMoreCondition: false
};
},
created() {
this.getList();
},
methods: {
/** 查询用户微信信息列表 */
getList() {
this.loading = true;
const {pageNum, pageSize} = this.queryParams;
const query = {...this.queryParams, pageNum: undefined, pageSize: undefined};
const pageReq = {page: pageNum - 1, size: pageSize};
listUmsMemberWechat(query, pageReq).then(response => {
const { content, totalElements } = response
this.umsMemberWechatList = content;
this.total = totalElements;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
memberId: null,
unionid: null,
openid: null,
routineOpenid: null,
groupid: null,
tagidList: null,
subscribe: null,
subscribeTime: null,
sessionKey: null,
accessToken: null,
expiresIn: null,
refreshToken: null,
expireTime: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加用户微信信息";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getUmsMemberWechat(id).then(response => {
this.form = response;
this.open = true;
this.title = "修改用户微信信息";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateUmsMemberWechat(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addUmsMemberWechat(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除用户微信信息编号为"' + ids + '"的数据项?').then(function() {
return delUmsMemberWechat(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$modal.confirm('是否确认导出所有用户微信信息数据项?').then(() => {
this.exportLoading = true;
return exportUmsMemberWechat(queryParams);
}).then(response => {
this.$download.download(response);
this.exportLoading = false;
}).catch(() => {});
}
}
};
</script>

View File

@ -42,7 +42,8 @@ export default defineConfig(({ mode, command }) => {
// additionalData: '@use "@/assets/styles/variables.module.scss as *";'
// javascriptEnabled: true
api: 'modern-compiler'
}
},
styl: {}
},
postcss: {
plugins: [