Merge remote-tracking branch 'origin/dev' into member_dev
# Conflicts: # src/views/member/user/UserForm.vue
This commit is contained in:
commit
2e68a5239d
@ -7,18 +7,20 @@ export interface BargainActivityVO {
|
|||||||
startTime?: Date
|
startTime?: Date
|
||||||
endTime?: Date
|
endTime?: Date
|
||||||
status?: number
|
status?: number
|
||||||
spuId?: number
|
|
||||||
userSize?: number // 达到该人数,才能砍到低价
|
userSize?: number // 达到该人数,才能砍到低价
|
||||||
bargainCount?: number // 最大帮砍次数
|
bargainCount?: number // 最大帮砍次数
|
||||||
totalLimitCount?: number // 最大购买次数
|
totalLimitCount?: number // 最大购买次数
|
||||||
stock?: number // 活动总库存
|
spuId: number
|
||||||
|
skuId: number
|
||||||
|
bargainFirstPrice: number // 砍价起始价格,单位分
|
||||||
|
bargainPrice: number // 砍价底价
|
||||||
|
stock: number // 活动库存
|
||||||
randomMinPrice?: number // 用户每次砍价的最小金额,单位:分
|
randomMinPrice?: number // 用户每次砍价的最小金额,单位:分
|
||||||
randomMaxPrice?: number // 用户每次砍价的最大金额,单位:分
|
randomMaxPrice?: number // 用户每次砍价的最大金额,单位:分
|
||||||
successCount?: number // 砍价成功数量
|
successCount?: number // 砍价成功数量
|
||||||
products?: BargainProductVO[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 砍价活动所需属性
|
// 砍价活动所需属性。选择的商品和属性的时候使用方便使用活动的通用封装
|
||||||
export interface BargainProductVO {
|
export interface BargainProductVO {
|
||||||
spuId: number
|
spuId: number
|
||||||
skuId: number
|
skuId: number
|
||||||
|
@ -19,6 +19,11 @@ export const getDeliveryExpress = async (id: number) => {
|
|||||||
return await request.get({ url: '/trade/delivery/express/get?id=' + id })
|
return await request.get({ url: '/trade/delivery/express/get?id=' + id })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获得快递公司精简信息列表
|
||||||
|
export const getSimpleDeliveryExpressList = () => {
|
||||||
|
return request.get({ url: '/trade/delivery/express/list-all-simple' })
|
||||||
|
}
|
||||||
|
|
||||||
// 新增快递公司
|
// 新增快递公司
|
||||||
export const createDeliveryExpress = async (data: DeliveryExpressVO) => {
|
export const createDeliveryExpress = async (data: DeliveryExpressVO) => {
|
||||||
return await request.post({ url: '/trade/delivery/express/create', data })
|
return await request.post({ url: '/trade/delivery/express/create', data })
|
||||||
|
@ -16,7 +16,7 @@ export interface DeliveryPickUpStoreVO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 查询自提门店列表
|
// 查询自提门店列表
|
||||||
export const getDeliveryPickUpStorePage = async (params: DeliveryPickUpStorePageReqVO) => {
|
export const getDeliveryPickUpStorePage = async (params) => {
|
||||||
return await request.get({ url: '/trade/delivery/pick-up-store/page', params })
|
return await request.get({ url: '/trade/delivery/pick-up-store/page', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +25,11 @@ export const getDeliveryPickUpStore = async (id: number) => {
|
|||||||
return await request.get({ url: '/trade/delivery/pick-up-store/get?id=' + id })
|
return await request.get({ url: '/trade/delivery/pick-up-store/get?id=' + id })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查询自提门店精简列表
|
||||||
|
export const getListAllSimple = async () => {
|
||||||
|
return await request.get({ url: '/trade/delivery/pick-up-store/list-all-simple' })
|
||||||
|
}
|
||||||
|
|
||||||
// 新增自提门店
|
// 新增自提门店
|
||||||
export const createDeliveryPickUpStore = async (data: DeliveryPickUpStoreVO) => {
|
export const createDeliveryPickUpStore = async (data: DeliveryPickUpStoreVO) => {
|
||||||
return await request.post({ url: '/trade/delivery/pick-up-store/create', data })
|
return await request.post({ url: '/trade/delivery/pick-up-store/create', data })
|
||||||
@ -39,8 +44,3 @@ export const updateDeliveryPickUpStore = async (data: DeliveryPickUpStoreVO) =>
|
|||||||
export const deleteDeliveryPickUpStore = async (id: number) => {
|
export const deleteDeliveryPickUpStore = async (id: number) => {
|
||||||
return await request.delete({ url: '/trade/delivery/pick-up-store/delete?id=' + id })
|
return await request.delete({ url: '/trade/delivery/pick-up-store/delete?id=' + id })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导出自提门店 Excel
|
|
||||||
export const exportDeliveryPickUpStoreApi = async (params) => {
|
|
||||||
return await request.download({ url: '/trade/delivery/pick-up-store/export-excel', params })
|
|
||||||
}
|
|
||||||
|
@ -1,12 +1,121 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
|
||||||
// 获得交易订单分页
|
export interface OrderVO {
|
||||||
// TODO @xiaobai:改成 getOrderPage
|
id?: number | null // 订单编号
|
||||||
export const getOrderList = (params: PageParam) => {
|
no?: string // 订单流水号
|
||||||
return request.get({ url: '/trade/order/page', params })
|
createTime?: Date | null // 下单时间
|
||||||
|
type?: number | null // 订单类型
|
||||||
|
terminal?: number | null // 订单来源
|
||||||
|
userId?: number | null // 用户编号
|
||||||
|
userIp?: string // 用户 IP
|
||||||
|
userRemark?: string // 用户备注
|
||||||
|
status?: number | null // 订单状态
|
||||||
|
productCount?: number | null // 购买的商品数量
|
||||||
|
finishTime?: Date | null // 订单完成时间
|
||||||
|
cancelTime?: Date | null // 订单取消时间
|
||||||
|
cancelType?: number | null // 取消类型
|
||||||
|
remark?: string // 商家备注
|
||||||
|
payOrderId: number | null // 支付订单编号
|
||||||
|
payed?: boolean // 是否已支付
|
||||||
|
payTime?: Date | null // 付款时间
|
||||||
|
payChannelCode?: string // 支付渠道
|
||||||
|
originalPrice?: number | null // 商品原价(总)
|
||||||
|
orderPrice?: number | null // 订单原价(总)
|
||||||
|
discountPrice?: number | null // 订单优惠(总)
|
||||||
|
deliveryPrice?: number | null // 运费金额
|
||||||
|
adjustPrice?: number | null // 订单调价(总)
|
||||||
|
payPrice?: number | null // 应付金额(总)
|
||||||
|
deliveryType?: number | null // 发货方式
|
||||||
|
deliveryTemplateId?: number | null // 配送模板编号
|
||||||
|
logisticsId?: number | null | null // 发货物流公司编号
|
||||||
|
logisticsNo?: string // 发货物流单号
|
||||||
|
deliveryStatus?: number | null // 发货状态
|
||||||
|
deliveryTime?: Date | null // 发货时间
|
||||||
|
receiveTime?: Date | null // 收货时间
|
||||||
|
receiverName?: string // 收件人名称
|
||||||
|
receiverMobile?: string // 收件人手机
|
||||||
|
receiverAreaId?: number | null // 收件人地区编号
|
||||||
|
receiverPostCode?: number | null // 收件人邮编
|
||||||
|
receiverDetailAddress?: string // 收件人详细地址
|
||||||
|
afterSaleStatus?: number | null // 售后状态
|
||||||
|
refundPrice?: number | null // 退款金额
|
||||||
|
couponId?: number | null // 优惠劵编号
|
||||||
|
couponPrice?: number | null // 优惠劵减免金额
|
||||||
|
pointPrice?: number | null // 积分抵扣的金额
|
||||||
|
receiverAreaName?: string //收件人地区名字
|
||||||
|
items?: OrderItemRespVO[] // 订单项列表
|
||||||
|
//用户信息
|
||||||
|
user?: {
|
||||||
|
id?: number | null
|
||||||
|
nickname?: string
|
||||||
|
avatar?: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获得交易订单详情
|
export interface OrderItemRespVO {
|
||||||
export const getOrderDetail = (id: number) => {
|
// ========== 订单项基本信息 ==========
|
||||||
return request.get({ url: '/trade/order/get-detail?id=' + id })
|
id?: number | null // 编号
|
||||||
|
userId?: number | null // 用户编号
|
||||||
|
orderId?: number | null // 订单编号
|
||||||
|
// ========== 商品基本信息 ==========
|
||||||
|
spuId?: number | null // 商品 SPU 编号
|
||||||
|
spuName?: string //商品 SPU 名称
|
||||||
|
skuId?: number | null // 商品 SKU 编号
|
||||||
|
picUrl?: string //商品图片
|
||||||
|
count?: number | null //购买数量
|
||||||
|
// ========== 价格 + 支付基本信息 ==========
|
||||||
|
originalPrice?: number | null //商品原价(总)
|
||||||
|
originalUnitPrice?: number | null //商品原价(单)
|
||||||
|
discountPrice?: number | null //商品优惠(总)
|
||||||
|
payPrice?: number | null //商品实付金额(总)
|
||||||
|
orderPartPrice?: number | null //子订单分摊金额(总)
|
||||||
|
orderDividePrice?: number | null //分摊后子订单实付金额(总)
|
||||||
|
// ========== 营销基本信息 ==========
|
||||||
|
// TODO 芋艿:在捉摸一下
|
||||||
|
// ========== 售后基本信息 ==========
|
||||||
|
afterSaleStatus?: number | null // 售后状态
|
||||||
|
properties?: ProductPropertiesVO[] //属性数组
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProductPropertiesVO {
|
||||||
|
propertyId?: number | null // 属性的编号
|
||||||
|
propertyName?: string // 属性的名称
|
||||||
|
valueId?: number | null //属性值的编号
|
||||||
|
valueName?: string // 属性值的名称
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询交易订单列表
|
||||||
|
export const getOrderPage = async (params) => {
|
||||||
|
return await request.get({ url: `/trade/order/page`, params })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询交易订单详情
|
||||||
|
export const getOrder = async (id: number | null) => {
|
||||||
|
return await request.get({ url: `/trade/order/get-detail?id=` + id })
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeliveryVO {
|
||||||
|
id: number // 订单编号
|
||||||
|
logisticsId: number | null // 物流公司编号
|
||||||
|
logisticsNo: string // 物流编号
|
||||||
|
}
|
||||||
|
|
||||||
|
// 订单发货
|
||||||
|
export const delivery = async (data: DeliveryVO) => {
|
||||||
|
return await request.post({ url: `/trade/order/delivery`, data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 订单备注
|
||||||
|
export const remark = async (data) => {
|
||||||
|
return await request.post({ url: `/trade/order/remark`, data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 订单调价
|
||||||
|
export const adjustPrice = async (data) => {
|
||||||
|
return await request.post({ url: `/trade/order/adjust-price`, data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改订单地址
|
||||||
|
export const adjustAddress = async (data) => {
|
||||||
|
return await request.post({ url: `/trade/order/adjust-address`, data })
|
||||||
}
|
}
|
||||||
|
@ -1,228 +0,0 @@
|
|||||||
// TODO @xiaobai:这个放到 order/index.ts 里哈
|
|
||||||
// TODO @xiaobai:注释放到变量后面,这样简洁一点
|
|
||||||
// TODO @xiaobai:这个改成 TradeOrderRespVO
|
|
||||||
export interface TradeOrderPageItemRespVO {
|
|
||||||
// 订单编号
|
|
||||||
id?: number
|
|
||||||
// 订单流水号
|
|
||||||
no?: string
|
|
||||||
// 下单时间
|
|
||||||
createTime?: Date
|
|
||||||
// 订单类型
|
|
||||||
type?: number
|
|
||||||
// 订单来源
|
|
||||||
terminal?: number
|
|
||||||
// 用户编号
|
|
||||||
userId?: number
|
|
||||||
// 用户 IP
|
|
||||||
userIp?: string
|
|
||||||
// 用户备注
|
|
||||||
userRemark?: string
|
|
||||||
// 订单状态
|
|
||||||
status?: number
|
|
||||||
// 购买的商品数量
|
|
||||||
productCount?: number
|
|
||||||
// 订单完成时间
|
|
||||||
finishTime?: Date
|
|
||||||
// 订单取消时间
|
|
||||||
cancelTime?: Date
|
|
||||||
// 取消类型
|
|
||||||
cancelType?: number
|
|
||||||
// 商家备注
|
|
||||||
remark?: string
|
|
||||||
// 支付订单编号
|
|
||||||
payOrderId: number
|
|
||||||
// 是否已支付
|
|
||||||
payed?: boolean
|
|
||||||
// 付款时间
|
|
||||||
payTime?: Date
|
|
||||||
// 支付渠道
|
|
||||||
payChannelCode?: string
|
|
||||||
// 商品原价(总)
|
|
||||||
originalPrice?: number
|
|
||||||
// 订单原价(总)
|
|
||||||
orderPrice?: number
|
|
||||||
// 订单优惠(总)
|
|
||||||
discountPrice?: number
|
|
||||||
// 运费金额
|
|
||||||
deliveryPrice?: number
|
|
||||||
// 订单调价(总)
|
|
||||||
adjustPrice?: number
|
|
||||||
// 应付金额(总)
|
|
||||||
payPrice?: number
|
|
||||||
// 配送模板编号
|
|
||||||
deliveryTemplateId?: number
|
|
||||||
// 发货物流公司编号
|
|
||||||
logisticsId?: number
|
|
||||||
// 发货物流单号
|
|
||||||
logisticsNo?: string
|
|
||||||
// 发货状态
|
|
||||||
deliveryStatus?: number
|
|
||||||
// 发货时间
|
|
||||||
deliveryTime?: Date
|
|
||||||
// 收货时间
|
|
||||||
receiveTime?: Date
|
|
||||||
// 收件人名称
|
|
||||||
receiverName?: string
|
|
||||||
// 收件人手机
|
|
||||||
receiverMobile?: string
|
|
||||||
// 收件人地区编号
|
|
||||||
receiverAreaId?: number
|
|
||||||
// 收件人邮编
|
|
||||||
receiverPostCode?: number
|
|
||||||
// 收件人详细地址
|
|
||||||
receiverDetailAddress?: string
|
|
||||||
// 售后状态
|
|
||||||
afterSaleStatus?: number
|
|
||||||
// 退款金额
|
|
||||||
refundPrice?: number
|
|
||||||
// 优惠劵编号
|
|
||||||
couponId?: number
|
|
||||||
// 优惠劵减免金额
|
|
||||||
couponPrice?: number
|
|
||||||
// 积分抵扣的金额
|
|
||||||
pointPrice?: number
|
|
||||||
//收件人地区名字
|
|
||||||
receiverAreaName?: string
|
|
||||||
// 订单项列表
|
|
||||||
items?: TradeOrderItemBaseVO[]
|
|
||||||
//用户信息
|
|
||||||
user?: MemberUserRespDTO
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO @xiaobai:这个改成 TradeOrderItemRespVO
|
|
||||||
/**
|
|
||||||
* 交易订单项 Base VO,提供给添加、修改、详细的子 VO 使用
|
|
||||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
|
||||||
*/
|
|
||||||
export interface TradeOrderItemBaseVO {
|
|
||||||
// ========== 订单项基本信息 ==========
|
|
||||||
/**
|
|
||||||
* 编号
|
|
||||||
*/
|
|
||||||
id?: number
|
|
||||||
/**
|
|
||||||
* 用户编号
|
|
||||||
*/
|
|
||||||
userId?: number
|
|
||||||
/**
|
|
||||||
* 订单编号
|
|
||||||
*/
|
|
||||||
orderId?: number
|
|
||||||
// ========== 商品基本信息 ==========
|
|
||||||
/**
|
|
||||||
* 商品 SPU 编号
|
|
||||||
*/
|
|
||||||
spuId?: number
|
|
||||||
/**
|
|
||||||
* 商品 SPU 名称
|
|
||||||
*/
|
|
||||||
spuName?: string
|
|
||||||
/**
|
|
||||||
* 商品 SKU 编号
|
|
||||||
*/
|
|
||||||
skuId?: number
|
|
||||||
/**
|
|
||||||
* 商品图片
|
|
||||||
*/
|
|
||||||
picUrl?: string
|
|
||||||
/**
|
|
||||||
* 购买数量
|
|
||||||
*/
|
|
||||||
count?: number
|
|
||||||
// ========== 价格 + 支付基本信息 ==========
|
|
||||||
/**
|
|
||||||
* 商品原价(总)
|
|
||||||
*/
|
|
||||||
originalPrice?: number
|
|
||||||
/**
|
|
||||||
* 商品原价(单)
|
|
||||||
*/
|
|
||||||
originalUnitPrice?: number
|
|
||||||
/**
|
|
||||||
* 商品优惠(总)
|
|
||||||
*/
|
|
||||||
discountPrice?: number
|
|
||||||
/**
|
|
||||||
* 商品实付金额(总)
|
|
||||||
*/
|
|
||||||
payPrice?: number
|
|
||||||
/**
|
|
||||||
* 子订单分摊金额(总)
|
|
||||||
*/
|
|
||||||
orderPartPrice?: number
|
|
||||||
/**
|
|
||||||
* 分摊后子订单实付金额(总)
|
|
||||||
*/
|
|
||||||
orderDividePrice?: number
|
|
||||||
// ========== 营销基本信息 ==========
|
|
||||||
// TODO 芋艿:在捉摸一下
|
|
||||||
// ========== 售后基本信息 ==========
|
|
||||||
/**
|
|
||||||
* 售后状态
|
|
||||||
*/
|
|
||||||
afterSaleStatus?: number
|
|
||||||
//属性数组
|
|
||||||
properties?: ProductPropertyValueDetailRespVO[]
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 管理后台 - 商品属性值的明细 Response VO
|
|
||||||
*/
|
|
||||||
export interface ProductPropertyValueDetailRespVO {
|
|
||||||
/**
|
|
||||||
* 属性的编号
|
|
||||||
*/
|
|
||||||
propertyId?: number
|
|
||||||
/**
|
|
||||||
* 属性的名称
|
|
||||||
*/
|
|
||||||
propertyName?: string
|
|
||||||
/**
|
|
||||||
* 属性值的编号
|
|
||||||
*/
|
|
||||||
valueId?: number
|
|
||||||
/**
|
|
||||||
* 属性值的名称
|
|
||||||
*/
|
|
||||||
valueName?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单详情查询 请求
|
|
||||||
*/
|
|
||||||
export interface TradeOrderPageReqVO {
|
|
||||||
pageNo: number
|
|
||||||
pageSize: number
|
|
||||||
no?: string
|
|
||||||
userId?: string
|
|
||||||
userNickname?: string
|
|
||||||
userMobile?: string
|
|
||||||
receiverName?: string
|
|
||||||
receiverMobile?: string
|
|
||||||
terminal?: string
|
|
||||||
type?: number
|
|
||||||
status?: number
|
|
||||||
payChannelCode?: string
|
|
||||||
createTime?: [Date, Date]
|
|
||||||
spuName?: string
|
|
||||||
itemCount?: string
|
|
||||||
all?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
//用户信息
|
|
||||||
export interface MemberUserRespDTO {
|
|
||||||
id?: number
|
|
||||||
nickname?: string
|
|
||||||
status?: number
|
|
||||||
avatar?: string
|
|
||||||
mobile?: string
|
|
||||||
}
|
|
||||||
//订单详情选中type
|
|
||||||
export interface SelectType {
|
|
||||||
queryParams: TradeOrderPageReqVO
|
|
||||||
selectTotal: number //选中的数量
|
|
||||||
selectAllFlag: boolean //全选标识
|
|
||||||
selectData: Map<number, Set<string>> //存放涉及选中得页面以及每页选中得数据订单号 全选时根据条件查询 排除取消的list订单
|
|
||||||
unSelectList: Set<string> //登记取消的list 全选标识为true 时登记单独取消的list,再次选中时排除, 全选标识为false 时清空list
|
|
||||||
}
|
|
@ -5,7 +5,7 @@ export interface LevelVO {
|
|||||||
name: string
|
name: string
|
||||||
experience: number
|
experience: number
|
||||||
value: number
|
value: number
|
||||||
discount: number
|
discountPercent: number
|
||||||
icon: string
|
icon: string
|
||||||
bgUrl: string
|
bgUrl: string
|
||||||
status: number
|
status: number
|
||||||
|
@ -8,10 +8,7 @@ export interface RecordVO {
|
|||||||
description: string
|
description: string
|
||||||
point: number
|
point: number
|
||||||
totalPoint: number
|
totalPoint: number
|
||||||
status: number
|
|
||||||
userId: number
|
userId: number
|
||||||
freezingTime: Date
|
|
||||||
thawingTime: Date
|
|
||||||
createDate: Date
|
createDate: Date
|
||||||
}
|
}
|
||||||
|
|
@ -8,26 +8,26 @@ export interface SignInConfigVO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 查询积分签到规则列表
|
// 查询积分签到规则列表
|
||||||
export const getSignInConfigPage = async () => {
|
export const getSignInConfigList = async () => {
|
||||||
return await request.get({ url: `/member/point/sign-in-config/list` })
|
return await request.get({ url: `/member/sign-in/config/list` })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询积分签到规则详情
|
// 查询积分签到规则详情
|
||||||
export const getSignInConfig = async (id: number) => {
|
export const getSignInConfig = async (id: number) => {
|
||||||
return await request.get({ url: `/member/point/sign-in-config/get?id=` + id })
|
return await request.get({ url: `/member/sign-in/config/get?id=` + id })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增积分签到规则
|
// 新增积分签到规则
|
||||||
export const createSignInConfig = async (data: SignInConfigVO) => {
|
export const createSignInConfig = async (data: SignInConfigVO) => {
|
||||||
return await request.post({ url: `/member/point/sign-in-config/create`, data })
|
return await request.post({ url: `/member/sign-in/config/create`, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修改积分签到规则
|
// 修改积分签到规则
|
||||||
export const updateSignInConfig = async (data: SignInConfigVO) => {
|
export const updateSignInConfig = async (data: SignInConfigVO) => {
|
||||||
return await request.put({ url: `/member/point/sign-in-config/update`, data })
|
return await request.put({ url: `/member/sign-in/config/update`, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除积分签到规则
|
// 删除积分签到规则
|
||||||
export const deleteSignInConfig = async (id: number) => {
|
export const deleteSignInConfig = async (id: number) => {
|
||||||
return await request.delete({ url: `/member/point/sign-in-config/delete?id=` + id })
|
return await request.delete({ url: `/member/sign-in/config/delete?id=` + id })
|
||||||
}
|
}
|
13
src/api/member/signin/record/index.ts
Normal file
13
src/api/member/signin/record/index.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
export interface SignInRecordVO {
|
||||||
|
id: number
|
||||||
|
userId: number
|
||||||
|
day: number
|
||||||
|
point: number
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询用户签到积分列表
|
||||||
|
export const getSignInRecordPage = async (params) => {
|
||||||
|
return await request.get({ url: `/member/sign-in/record/page`, params })
|
||||||
|
}
|
@ -18,6 +18,25 @@ export interface UserVO {
|
|||||||
createTime: Date
|
createTime: Date
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO @梦:和 UserVO 搞成一个把。
|
||||||
|
export interface UserBaseInfoVO {
|
||||||
|
id: number | undefined | null
|
||||||
|
mobile: string
|
||||||
|
password: string | null | undefined
|
||||||
|
status: number
|
||||||
|
registerIp: string | null | undefined
|
||||||
|
loginIp: string | null | undefined
|
||||||
|
loginDate: Date | null | undefined
|
||||||
|
nickname: string | null | undefined
|
||||||
|
avatar: string | null | undefined
|
||||||
|
name: string | null | undefined
|
||||||
|
sex: number
|
||||||
|
areaId: number | null | undefined
|
||||||
|
birthday: Date | null | undefined
|
||||||
|
mark: string | null | undefined
|
||||||
|
createTime: Date | null | undefined
|
||||||
|
}
|
||||||
|
|
||||||
// 查询会员用户列表
|
// 查询会员用户列表
|
||||||
export const getUserPage = async (params) => {
|
export const getUserPage = async (params) => {
|
||||||
return await request.get({ url: `/member/user/page`, params })
|
return await request.get({ url: `/member/user/page`, params })
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
import request from '@/config/axios'
|
|
||||||
|
|
||||||
export interface SignInRecordVO {
|
|
||||||
id: number
|
|
||||||
userId: number
|
|
||||||
day: number
|
|
||||||
point: number
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询用户签到积分列表
|
|
||||||
export const getSignInRecordPage = async (params) => {
|
|
||||||
return await request.get({ url: `/member/point/sign-in-record/page`, params })
|
|
||||||
}
|
|
||||||
|
|
||||||
// 导出用户签到积分 Excel
|
|
||||||
export const exportSignInRecord = async (params) => {
|
|
||||||
return await request.download({ url: `/member/point/sign-in-record/export-excel`, params })
|
|
||||||
}
|
|
@ -31,7 +31,7 @@ let requestList: any[] = []
|
|||||||
// 是否正在刷新中
|
// 是否正在刷新中
|
||||||
let isRefreshToken = false
|
let isRefreshToken = false
|
||||||
// 请求白名单,无须token的接口
|
// 请求白名单,无须token的接口
|
||||||
const whiteList: string[] = ['/login', '/refresh-token', '/system/tenant/get-id-by-name']
|
const whiteList: string[] = ['/login', '/refresh-token']
|
||||||
|
|
||||||
// 创建axios实例
|
// 创建axios实例
|
||||||
const service: AxiosInstance = axios.create({
|
const service: AxiosInstance = axios.create({
|
||||||
@ -47,7 +47,8 @@ service.interceptors.request.use(
|
|||||||
let isToken = (config!.headers || {}).isToken === false
|
let isToken = (config!.headers || {}).isToken === false
|
||||||
whiteList.some((v) => {
|
whiteList.some((v) => {
|
||||||
if (config.url) {
|
if (config.url) {
|
||||||
return (isToken = config.url.indexOf(v) > -1)
|
config.url.indexOf(v) > -1
|
||||||
|
return (isToken = false)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (getAccessToken() && !isToken) {
|
if (getAccessToken() && !isToken) {
|
||||||
|
@ -5,32 +5,32 @@ const { t } = useI18n()
|
|||||||
* redirect: noredirect 当设置 noredirect 的时候该路由在面包屑导航中不可被点击
|
* redirect: noredirect 当设置 noredirect 的时候该路由在面包屑导航中不可被点击
|
||||||
* name:'router-name' 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
|
* name:'router-name' 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
|
||||||
* meta : {
|
* meta : {
|
||||||
hidden: true 当设置 true 的时候该路由不会再侧边栏出现 如404,login等页面(默认 false)
|
hidden: true 当设置 true 的时候该路由不会再侧边栏出现 如404,login等页面(默认 false)
|
||||||
|
|
||||||
alwaysShow: true 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式,
|
alwaysShow: true 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式,
|
||||||
只有一个时,会将那个子路由当做根路由显示在侧边栏,
|
只有一个时,会将那个子路由当做根路由显示在侧边栏,
|
||||||
若你想不管路由下面的 children 声明的个数都显示你的根路由,
|
若你想不管路由下面的 children 声明的个数都显示你的根路由,
|
||||||
你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,
|
你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,
|
||||||
一直显示根路由(默认 false)
|
一直显示根路由(默认 false)
|
||||||
|
|
||||||
title: 'title' 设置该路由在侧边栏和面包屑中展示的名字
|
title: 'title' 设置该路由在侧边栏和面包屑中展示的名字
|
||||||
|
|
||||||
icon: 'svg-name' 设置该路由的图标
|
icon: 'svg-name' 设置该路由的图标
|
||||||
|
|
||||||
noCache: true 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
|
noCache: true 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
|
||||||
|
|
||||||
breadcrumb: false 如果设置为false,则不会在breadcrumb面包屑中显示(默认 true)
|
breadcrumb: false 如果设置为false,则不会在breadcrumb面包屑中显示(默认 true)
|
||||||
|
|
||||||
affix: true 如果设置为true,则会一直固定在tag项中(默认 false)
|
affix: true 如果设置为true,则会一直固定在tag项中(默认 false)
|
||||||
|
|
||||||
noTagsView: true 如果设置为true,则不会出现在tag中(默认 false)
|
noTagsView: true 如果设置为true,则不会出现在tag中(默认 false)
|
||||||
|
|
||||||
activeMenu: '/dashboard' 显示高亮的路由路径
|
activeMenu: '/dashboard' 显示高亮的路由路径
|
||||||
|
|
||||||
followAuth: '/dashboard' 跟随哪个路由进行权限过滤
|
followAuth: '/dashboard' 跟随哪个路由进行权限过滤
|
||||||
|
|
||||||
canTo: true 设置为true即使hidden为true,也依然可以进行路由跳转(默认 false)
|
canTo: true 设置为true即使hidden为true,也依然可以进行路由跳转(默认 false)
|
||||||
}
|
}
|
||||||
**/
|
**/
|
||||||
const remainingRouter: AppRouteRecordRaw[] = [
|
const remainingRouter: AppRouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
@ -347,9 +347,9 @@ const remainingRouter: AppRouteRecordRaw[] = [
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/property',
|
path: '/property', // TODO @puhui999:这里的 path 有问题,应该是 /product/property
|
||||||
component: Layout,
|
component: Layout,
|
||||||
name: 'property',
|
name: 'Property',
|
||||||
meta: {
|
meta: {
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
@ -411,6 +411,40 @@ const remainingRouter: AppRouteRecordRaw[] = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/trade/order',
|
||||||
|
component: Layout,
|
||||||
|
name: 'Detail',
|
||||||
|
meta: {
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'detail/:orderId(\\d+)',
|
||||||
|
component: () => import('@/views/mall/trade/order/components/OrderDetailForm.vue'),
|
||||||
|
name: 'TradeOrderDetailForm',
|
||||||
|
meta: { title: '订单详情', icon: '', activeMenu: '/trade/trade/order' }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/member',
|
||||||
|
component: Layout,
|
||||||
|
name: 'member',
|
||||||
|
meta: { hidden: true },
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'user/detail',
|
||||||
|
name: 'MemberUserDetail',
|
||||||
|
meta: {
|
||||||
|
title: '会员详情',
|
||||||
|
noCache: true,
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
component: () => import('@/views/member/user/detail/index.vue')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/pay',
|
path: '/pay',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
|
@ -90,6 +90,7 @@ export enum DICT_TYPE {
|
|||||||
USER_TYPE = 'user_type',
|
USER_TYPE = 'user_type',
|
||||||
COMMON_STATUS = 'common_status',
|
COMMON_STATUS = 'common_status',
|
||||||
SYSTEM_TENANT_PACKAGE_ID = 'system_tenant_package_id',
|
SYSTEM_TENANT_PACKAGE_ID = 'system_tenant_package_id',
|
||||||
|
TERMINAL = 'terminal', // 终端
|
||||||
|
|
||||||
// ========== SYSTEM 模块 ==========
|
// ========== SYSTEM 模块 ==========
|
||||||
SYSTEM_USER_SEX = 'system_user_sex',
|
SYSTEM_USER_SEX = 'system_user_sex',
|
||||||
@ -142,7 +143,6 @@ export enum DICT_TYPE {
|
|||||||
|
|
||||||
// ========== MALL - 会员模块 ==========
|
// ========== MALL - 会员模块 ==========
|
||||||
MEMBER_POINT_BIZ_TYPE = 'member_point_biz_type', // 积分的业务类型
|
MEMBER_POINT_BIZ_TYPE = 'member_point_biz_type', // 积分的业务类型
|
||||||
MEMBER_POINT_STATUS = 'member_point_status', // 积分的状态
|
|
||||||
|
|
||||||
// ========== MALL - 商品模块 ==========
|
// ========== MALL - 商品模块 ==========
|
||||||
PRODUCT_UNIT = 'product_unit', // 商品单位
|
PRODUCT_UNIT = 'product_unit', // 商品单位
|
||||||
@ -156,7 +156,7 @@ export enum DICT_TYPE {
|
|||||||
TRADE_ORDER_TYPE = 'trade_order_type', // 订单 - 类型
|
TRADE_ORDER_TYPE = 'trade_order_type', // 订单 - 类型
|
||||||
TRADE_ORDER_STATUS = 'trade_order_status', // 订单 - 状态
|
TRADE_ORDER_STATUS = 'trade_order_status', // 订单 - 状态
|
||||||
TRADE_ORDER_ITEM_AFTER_SALE_STATUS = 'trade_order_item_after_sale_status', // 订单项 - 售后状态
|
TRADE_ORDER_ITEM_AFTER_SALE_STATUS = 'trade_order_item_after_sale_status', // 订单项 - 售后状态
|
||||||
TERMINAL = 'terminal', // 终端
|
TRADE_DELIVERY_TYPE = 'trade_delivery_type', // 配送方式
|
||||||
|
|
||||||
// ========== MALL - 营销模块 ==========
|
// ========== MALL - 营销模块 ==========
|
||||||
PROMOTION_DISCOUNT_TYPE = 'promotion_discount_type', // 优惠类型
|
PROMOTION_DISCOUNT_TYPE = 'promotion_discount_type', // 优惠类型
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
v-model="loginData.loginForm.tenantName"
|
v-model="loginData.loginForm.tenantName"
|
||||||
:placeholder="t('login.tenantNamePlaceholder')"
|
:placeholder="t('login.tenantNamePlaceholder')"
|
||||||
:prefix-icon="iconHouse"
|
:prefix-icon="iconHouse"
|
||||||
type="primary"
|
|
||||||
link
|
link
|
||||||
|
type="primary"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -148,8 +148,6 @@ import { ElLoading } from 'element-plus'
|
|||||||
import LoginFormTitle from './LoginFormTitle.vue'
|
import LoginFormTitle from './LoginFormTitle.vue'
|
||||||
import type { RouteLocationNormalizedLoaded } from 'vue-router'
|
import type { RouteLocationNormalizedLoaded } from 'vue-router'
|
||||||
|
|
||||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
|
||||||
const { wsCache } = useCache()
|
|
||||||
import { useIcon } from '@/hooks/web/useIcon'
|
import { useIcon } from '@/hooks/web/useIcon'
|
||||||
|
|
||||||
import * as authUtil from '@/utils/auth'
|
import * as authUtil from '@/utils/auth'
|
||||||
@ -246,7 +244,6 @@ const handleLogin = async (params) => {
|
|||||||
if (!res) {
|
if (!res) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
wsCache.delete(CACHE_KEY.USER) // 清除上次登录用户信息
|
|
||||||
ElLoading.service({
|
ElLoading.service({
|
||||||
lock: true,
|
lock: true,
|
||||||
text: '正在加载系统中...',
|
text: '正在加载系统中...',
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<Form ref="formRef" :labelWidth="80" :rules="rules" :schema="schema">
|
<Form ref="formRef" :labelWidth="200" :rules="rules" :schema="schema">
|
||||||
<template #sex="form">
|
<template #sex="form">
|
||||||
<el-radio-group v-model="form['sex']">
|
<el-radio-group v-model="form['sex']">
|
||||||
<el-radio :label="1">{{ t('profile.user.man') }}</el-radio>
|
<el-radio :label="1">{{ t('profile.user.man') }}</el-radio>
|
||||||
@ -7,8 +7,10 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</template>
|
</template>
|
||||||
</Form>
|
</Form>
|
||||||
<XButton :title="t('common.save')" @click="submit()" />
|
<div style="text-align: center">
|
||||||
<XButton :title="t('common.reset')" type="danger" @click="init()" />
|
<XButton :title="t('common.save')" type="primary" @click="submit()" />
|
||||||
|
<XButton :title="t('common.reset')" type="danger" @click="init()" />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { FormRules } from 'element-plus'
|
import type { FormRules } from 'element-plus'
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-form ref="formRef" :model="password" :rules="rules" label-width="80px">
|
<el-form ref="formRef" :model="password" :rules="rules" :label-width="200">
|
||||||
<el-form-item :label="t('profile.password.oldPassword')">
|
<el-form-item :label="t('profile.password.oldPassword')" prop="oldPassword">
|
||||||
<InputPassword v-model="password.oldPassword" />
|
<InputPassword v-model="password.oldPassword" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('profile.password.newPassword')">
|
<el-form-item :label="t('profile.password.newPassword')" prop="newPassword">
|
||||||
<InputPassword v-model="password.newPassword" strength />
|
<InputPassword v-model="password.newPassword" strength />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('profile.password.confirmPassword')">
|
<el-form-item :label="t('profile.password.confirmPassword')" prop="confirmPassword">
|
||||||
<InputPassword v-model="password.confirmPassword" strength />
|
<InputPassword v-model="password.confirmPassword" strength />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@ -33,17 +33,18 @@ const password = reactive({
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 表单校验
|
// 表单校验
|
||||||
const equalToPassword = (value, callback) => {
|
const equalToPassword = (_rule, value, callback) => {
|
||||||
if (password.newPassword !== value) {
|
if (password.newPassword !== value) {
|
||||||
callback(new Error(t('profile.password.diffPwd')))
|
callback(new Error(t('profile.password.diffPwd')))
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const rules = reactive<FormRules>({
|
const rules = reactive<FormRules>({
|
||||||
oldPassword: [
|
oldPassword: [
|
||||||
{ required: true, message: t('profile.password.oldPwdMsg'), trigger: 'blur' },
|
{ required: true, message: t('profile.password.oldPwdMsg'), trigger: 'blur' },
|
||||||
{ min: 3, max: 5, message: t('profile.password.pwdRules'), trigger: 'blur' }
|
{ min: 6, max: 20, message: t('profile.password.pwdRules'), trigger: 'blur' }
|
||||||
],
|
],
|
||||||
newPassword: [
|
newPassword: [
|
||||||
{ required: true, message: t('profile.password.newPwdMsg'), trigger: 'blur' },
|
{ required: true, message: t('profile.password.newPwdMsg'), trigger: 'blur' },
|
||||||
@ -54,6 +55,7 @@ const rules = reactive<FormRules>({
|
|||||||
{ required: true, validator: equalToPassword, trigger: 'blur' }
|
{ required: true, validator: equalToPassword, trigger: 'blur' }
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
const submit = (formEl: FormInstance | undefined) => {
|
const submit = (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
formEl.validate(async (valid) => {
|
formEl.validate(async (valid) => {
|
||||||
@ -63,6 +65,7 @@ const submit = (formEl: FormInstance | undefined) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const reset = (formEl: FormInstance | undefined) => {
|
const reset = (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
formEl.resetFields()
|
formEl.resetFields()
|
||||||
|
@ -45,9 +45,9 @@
|
|||||||
<el-button class="float-right" text type="primary" @click="copy(item.code)">
|
<el-button class="float-right" text type="primary" @click="copy(item.code)">
|
||||||
{{ t('common.copy') }}
|
{{ t('common.copy') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<div>
|
<el-scrollbar height="600px">
|
||||||
<pre><code v-dompurify-html="highlightedCode(item)" class="hljs"></code></pre>
|
<pre><code v-dompurify-html="highlightedCode(item)" class="hljs"></code></pre>
|
||||||
</div>
|
</el-scrollbar>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
@ -73,9 +73,7 @@
|
|||||||
>
|
>
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button link type="primary">
|
<el-button link type="primary" @click="goValueList(scope.row.id)">属性值</el-button>
|
||||||
<router-link :to="'/property/value/' + scope.row.id">属性值</router-link>
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['product:property:delete']"
|
v-hasPermi="['product:property:delete']"
|
||||||
link
|
link
|
||||||
@ -103,6 +101,7 @@
|
|||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
import * as PropertyApi from '@/api/mall/product/property'
|
import * as PropertyApi from '@/api/mall/product/property'
|
||||||
import PropertyForm from './PropertyForm.vue'
|
import PropertyForm from './PropertyForm.vue'
|
||||||
|
const { push } = useRouter()
|
||||||
|
|
||||||
defineOptions({ name: 'ProductProperty' })
|
defineOptions({ name: 'ProductProperty' })
|
||||||
|
|
||||||
@ -163,6 +162,11 @@ const handleDelete = async (id: number) => {
|
|||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 跳转商品属性列表 */
|
||||||
|
const goValueList = (id: number) => {
|
||||||
|
push({ path: '/property/value/' + id })
|
||||||
|
}
|
||||||
|
|
||||||
/** 初始化 **/
|
/** 初始化 **/
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList()
|
getList()
|
||||||
|
@ -334,7 +334,7 @@ const validateSku = () => {
|
|||||||
for (const sku of formData.value!.skus!) {
|
for (const sku of formData.value!.skus!) {
|
||||||
// 作为活动组件的校验
|
// 作为活动组件的校验
|
||||||
if (props.isActivityComponent) {
|
if (props.isActivityComponent) {
|
||||||
for (const rule of props.ruleConfig) {
|
for (const rule of props?.ruleConfig) {
|
||||||
const arg = getValue(sku, rule.name)
|
const arg = getValue(sku, rule.name)
|
||||||
if (!rule.rule(arg)) {
|
if (!rule.rule(arg)) {
|
||||||
validate = false // 只要有一个不通过则直接不通过
|
validate = false // 只要有一个不通过则直接不通过
|
||||||
@ -534,9 +534,10 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
const activitySkuListRef = ref<InstanceType<typeof ElTable>>()
|
const activitySkuListRef = ref<InstanceType<typeof ElTable>>()
|
||||||
const clearSelection = () => {
|
|
||||||
activitySkuListRef.value.clearSelection()
|
const getSkuTableRef = () => {
|
||||||
|
return activitySkuListRef.value
|
||||||
}
|
}
|
||||||
// 暴露出生成 sku 方法,给添加属性成功时调用
|
// 暴露出生成 sku 方法,给添加属性成功时调用
|
||||||
defineExpose({ generateTableData, validateSku, clearSelection })
|
defineExpose({ generateTableData, validateSku, getSkuTableRef })
|
||||||
</script>
|
</script>
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
</template>
|
</template>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
<SpuSelect ref="spuSelectRef" :isSelectSku="true" @confirm="selectSpu" />
|
<SpuSelect ref="spuSelectRef" :isSelectSku="true" :radio="true" @confirm="selectSpu" />
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import * as BargainActivityApi from '@/api/mall/promotion/bargain/bargainActivity'
|
import * as BargainActivityApi from '@/api/mall/promotion/bargain/bargainActivity'
|
||||||
@ -83,17 +83,17 @@ const ruleConfig: RuleConfig[] = [
|
|||||||
{
|
{
|
||||||
name: 'productConfig.bargainFirstPrice',
|
name: 'productConfig.bargainFirstPrice',
|
||||||
rule: (arg) => arg > 0,
|
rule: (arg) => arg > 0,
|
||||||
message: '商品砍价起始价格不能小于0 !!!'
|
message: '商品砍价起始价格不能小于 0 !!!'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'productConfig.bargainPrice',
|
name: 'productConfig.bargainPrice',
|
||||||
rule: (arg) => arg > 0,
|
rule: (arg) => arg >= 0,
|
||||||
message: '商品砍价底价不能小于0 !!!'
|
message: '商品砍价底价不能小于 0 !!!'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'productConfig.stock',
|
name: 'productConfig.stock',
|
||||||
rule: (arg) => arg > 1,
|
rule: (arg) => arg >= 1,
|
||||||
message: '商品活动库存不能小于1 !!!'
|
message: '商品活动库存不能小于 1 !!!'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
const selectSpu = (spuId: number, skuIds: number[]) => {
|
const selectSpu = (spuId: number, skuIds: number[]) => {
|
||||||
@ -164,7 +164,20 @@ const open = async (type: string, id?: number) => {
|
|||||||
// 用户每次砍价金额分转元, 分转元
|
// 用户每次砍价金额分转元, 分转元
|
||||||
data.randomMinPrice = formatToFraction(data.randomMinPrice)
|
data.randomMinPrice = formatToFraction(data.randomMinPrice)
|
||||||
data.randomMaxPrice = formatToFraction(data.randomMaxPrice)
|
data.randomMaxPrice = formatToFraction(data.randomMaxPrice)
|
||||||
await getSpuDetails(data.spuId!, data.products?.map((sku) => sku.skuId), data.products)
|
// 对齐活动商品处理结构
|
||||||
|
await getSpuDetails(
|
||||||
|
data.spuId!,
|
||||||
|
[data.skuId],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
spuId: data.spuId!,
|
||||||
|
skuId: data.skuId,
|
||||||
|
bargainFirstPrice: data.bargainFirstPrice, // 砍价起始价格,单位分
|
||||||
|
bargainPrice: data.bargainPrice, // 砍价底价
|
||||||
|
stock: data.stock // 活动库存
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
formRef.value.setValues(data)
|
formRef.value.setValues(data)
|
||||||
} finally {
|
} finally {
|
||||||
formLoading.value = false
|
formLoading.value = false
|
||||||
@ -201,12 +214,12 @@ const submitForm = async () => {
|
|||||||
// 用户每次砍价金额分转元, 元转分
|
// 用户每次砍价金额分转元, 元转分
|
||||||
data.randomMinPrice = convertToInteger(data.randomMinPrice)
|
data.randomMinPrice = convertToInteger(data.randomMinPrice)
|
||||||
data.randomMaxPrice = convertToInteger(data.randomMaxPrice)
|
data.randomMaxPrice = convertToInteger(data.randomMaxPrice)
|
||||||
data.products = products
|
const formData = { ...data, ...products[0] }
|
||||||
if (formType.value === 'create') {
|
if (formType.value === 'create') {
|
||||||
await BargainActivityApi.createBargainActivity(data)
|
await BargainActivityApi.createBargainActivity(formData)
|
||||||
message.success(t('common.createSuccess'))
|
message.success(t('common.createSuccess'))
|
||||||
} else {
|
} else {
|
||||||
await BargainActivityApi.updateBargainActivity(data)
|
await BargainActivityApi.updateBargainActivity(formData)
|
||||||
message.success(t('common.updateSuccess'))
|
message.success(t('common.updateSuccess'))
|
||||||
}
|
}
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
<template>
|
||||||
|
<div></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" name="CombinationRecord" setup></script>
|
@ -127,7 +127,8 @@ defineOptions({ name: 'PromotionSpuSelect' })
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
// 默认不需要(不需要的情况下只返回 spu,需要的情况下返回 选中的 spu 和 sku 列表)
|
// 默认不需要(不需要的情况下只返回 spu,需要的情况下返回 选中的 spu 和 sku 列表)
|
||||||
// 其它活动需要选择商品和商品属性导入此组件即可,需添加组件属性 :isSelectSku='true'
|
// 其它活动需要选择商品和商品属性导入此组件即可,需添加组件属性 :isSelectSku='true'
|
||||||
isSelectSku: propTypes.bool.def(false) // 是否需要选择 sku 属性
|
isSelectSku: propTypes.bool.def(false), // 是否需要选择 sku 属性
|
||||||
|
radio: propTypes.bool.def(false) // 是否单选 sku
|
||||||
})
|
})
|
||||||
|
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
@ -146,7 +147,7 @@ const queryParams = ref({
|
|||||||
}) // 查询参数
|
}) // 查询参数
|
||||||
const propertyList = ref<PropertyAndValues[]>([]) // 商品属性列表
|
const propertyList = ref<PropertyAndValues[]>([]) // 商品属性列表
|
||||||
const spuListRef = ref<InstanceType<typeof ElTable>>()
|
const spuListRef = ref<InstanceType<typeof ElTable>>()
|
||||||
const skuListRef = ref() // 商品属性选择 Ref
|
const skuListRef = ref<InstanceType<typeof SkuList>>() // 商品属性选择 Ref
|
||||||
const spuData = ref<ProductSpuApi.Spu>() // 商品详情
|
const spuData = ref<ProductSpuApi.Spu>() // 商品详情
|
||||||
const isExpand = ref(false) // 控制 SKU 列表显示
|
const isExpand = ref(false) // 控制 SKU 列表显示
|
||||||
const expandRowKeys = ref<number[]>() // 控制展开行需要设置 row-key 属性才能使用,该属性为展开行的 keys 数组。
|
const expandRowKeys = ref<number[]>() // 控制展开行需要设置 row-key 属性才能使用,该属性为展开行的 keys 数组。
|
||||||
@ -155,12 +156,30 @@ const expandRowKeys = ref<number[]>() // 控制展开行需要设置 row-key 属
|
|||||||
const selectedSpuId = ref<number>(0) // 选中的商品 spuId
|
const selectedSpuId = ref<number>(0) // 选中的商品 spuId
|
||||||
const selectedSkuIds = ref<number[]>([]) // 选中的商品 skuIds
|
const selectedSkuIds = ref<number[]>([]) // 选中的商品 skuIds
|
||||||
const selectSku = (val: ProductSpuApi.Sku[]) => {
|
const selectSku = (val: ProductSpuApi.Sku[]) => {
|
||||||
|
const skuTable = skuListRef.value?.getSkuTableRef()
|
||||||
if (selectedSpuId.value === 0) {
|
if (selectedSpuId.value === 0) {
|
||||||
message.warning('请先选择商品再选择相应的规格!!!')
|
message.warning('请先选择商品再选择相应的规格!!!')
|
||||||
skuListRef.value.clearSelection()
|
skuTable?.clearSelection()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
selectedSkuIds.value = val.map((sku) => sku.id!)
|
if (val.length === 0) {
|
||||||
|
selectedSkuIds.value = []
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (props.radio) {
|
||||||
|
// 只选择一个
|
||||||
|
selectedSkuIds.value = [val.map((sku) => sku.id!)[0]]
|
||||||
|
// 如果大于1个
|
||||||
|
if (val.length > 1) {
|
||||||
|
// 清空选择
|
||||||
|
skuTable?.clearSelection()
|
||||||
|
// 变更为最后一次选择的
|
||||||
|
skuTable?.toggleRowSelection(val.pop(), true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selectedSkuIds.value = val.map((sku) => sku.id!)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const selectSpu = (val: ProductSpuApi.Spu[]) => {
|
const selectSpu = (val: ProductSpuApi.Spu[]) => {
|
||||||
if (val.length === 0) {
|
if (val.length === 0) {
|
||||||
@ -176,9 +195,9 @@ const selectSpu = (val: ProductSpuApi.Spu[]) => {
|
|||||||
// 如果大于1个
|
// 如果大于1个
|
||||||
if (val.length > 1) {
|
if (val.length > 1) {
|
||||||
// 清空选择
|
// 清空选择
|
||||||
spuListRef.value.clearSelection()
|
spuListRef.value?.clearSelection()
|
||||||
// 变更为最后一次选择的
|
// 变更为最后一次选择的
|
||||||
spuListRef.value.toggleRowSelection(val.pop(), true)
|
spuListRef.value?.toggleRowSelection(val.pop(), true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
expandChange(val[0], val)
|
expandChange(val[0], val)
|
||||||
@ -194,7 +213,7 @@ const expandChange = async (row: ProductSpuApi.Spu, expandedRows?: ProductSpuApi
|
|||||||
expandRowKeys.value = [selectedSpuId.value]
|
expandRowKeys.value = [selectedSpuId.value]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 如果以展开 skuList 则选择此对应的 spu 不需要重新获取渲染 skuList
|
// 如果已展开 skuList 则选择此对应的 spu 不需要重新获取渲染 skuList
|
||||||
if (isExpand.value && spuData.value?.id === row.id) {
|
if (isExpand.value && spuData.value?.id === row.id) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 搜索工作栏 -->
|
<!-- 搜索工作栏 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true">
|
<el-form ref="queryFormRef" :inline="true" :model="queryParams" class="-mb-15px">
|
||||||
<el-form-item label="门店手机" prop="phone">
|
<el-form-item label="门店手机" prop="phone">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.phone"
|
v-model="queryParams.phone"
|
||||||
placeholder="请输门店手机"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
class="!w-240px"
|
class="!w-240px"
|
||||||
|
clearable
|
||||||
|
placeholder="请输门店手机"
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="门店名称" prop="name">
|
<el-form-item label="门店名称" prop="name">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.name"
|
v-model="queryParams.name"
|
||||||
placeholder="请输门店名称"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
class="!w-240px"
|
class="!w-240px"
|
||||||
|
clearable
|
||||||
|
placeholder="请输门店名称"
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="门店状态" prop="status">
|
<el-form-item label="门店状态" prop="status">
|
||||||
<el-select v-model="queryParams.status" placeholder="门店状态" clearable class="!w-240px">
|
<el-select v-model="queryParams.status" class="!w-240px" clearable placeholder="门店状态">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
@ -33,32 +33,30 @@
|
|||||||
<el-form-item label="创建时间" prop="createTime">
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="queryParams.createTime"
|
v-model="queryParams.createTime"
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
type="datetimerange"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
class="!w-240px"
|
class="!w-240px"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
type="datetimerange"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
<el-button @click="handleQuery">
|
||||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
<Icon class="mr-5px" icon="ep:search" />
|
||||||
<el-button
|
搜索
|
||||||
type="primary"
|
</el-button>
|
||||||
plain
|
<el-button @click="resetQuery">
|
||||||
@click="openForm('create')"
|
<Icon class="mr-5px" icon="ep:refresh" />
|
||||||
v-hasPermi="['trade:delivery:pick-up-store:create']"
|
重置
|
||||||
>
|
|
||||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
type="success"
|
v-hasPermi="['trade:delivery:pick-up-store:create']"
|
||||||
plain
|
plain
|
||||||
@click="handleExport"
|
type="primary"
|
||||||
:loading="exportLoading"
|
@click="openForm('create')"
|
||||||
v-hasPermi="['trade:delivery:pick-up-store:export']"
|
|
||||||
>
|
>
|
||||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
<Icon class="mr-5px" icon="ep:plus" />
|
||||||
|
新增
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
@ -75,34 +73,34 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="门店名称" prop="name" />
|
<el-table-column label="门店名称" prop="name" />
|
||||||
<el-table-column label="门店手机" prop="phone" />
|
<el-table-column label="门店手机" prop="phone" />
|
||||||
<el-table-column label="门店详细地址" align="center" prop="detailAddress" />
|
<el-table-column align="center" label="门店详细地址" prop="detailAddress" />
|
||||||
<el-table-column label="开启状态" align="center" prop="status">
|
<el-table-column align="center" label="开启状态" prop="status">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="创建时间"
|
:formatter="dateFormatter"
|
||||||
align="center"
|
align="center"
|
||||||
|
label="创建时间"
|
||||||
prop="createTime"
|
prop="createTime"
|
||||||
width="180"
|
width="180"
|
||||||
:formatter="dateFormatter"
|
|
||||||
/>
|
/>
|
||||||
<el-table-column label="操作" align="center">
|
<el-table-column align="center" label="操作">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
|
v-hasPermi="['trade:delivery:pick-up-store:update']"
|
||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="openForm('update', scope.row.id)"
|
@click="openForm('update', scope.row.id)"
|
||||||
v-hasPermi="['trade:delivery:pick-up-store:update']"
|
|
||||||
>
|
>
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
|
v-hasPermi="['trade:delivery:pick-up-store:delete']"
|
||||||
link
|
link
|
||||||
type="danger"
|
type="danger"
|
||||||
@click="handleDelete(scope.row.id)"
|
@click="handleDelete(scope.row.id)"
|
||||||
v-hasPermi="['trade:delivery:pick-up-store:delete']"
|
|
||||||
>
|
>
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
@ -113,18 +111,17 @@
|
|||||||
<!-- 表单弹窗:添加/修改 -->
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
<DeliveryPickUpStoreForm ref="formRef" @success="getList" />
|
<DeliveryPickUpStoreForm ref="formRef" @success="getList" />
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts" name="DeliveryPickUpStore">
|
<script lang="ts" name="DeliveryPickUpStore" setup>
|
||||||
import * as DeliveryPickUpStoreApi from '@/api/mall/trade/delivery/pickUpStore'
|
import * as DeliveryPickUpStoreApi from '@/api/mall/trade/delivery/pickUpStore'
|
||||||
import DeliveryPickUpStoreForm from './PickUpStoreForm.vue'
|
import DeliveryPickUpStoreForm from './PickUpStoreForm.vue'
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
import download from '@/utils/download'
|
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
const total = ref(0) // 列表的总页数
|
const total = ref(0) // 列表的总页数
|
||||||
const loading = ref(true) // 列表的加载中
|
const loading = ref(true) // 列表的加载中
|
||||||
const exportLoading = ref(false) // 导出的加载中
|
|
||||||
const list = ref<any[]>([]) // 列表的数据
|
const list = ref<any[]>([]) // 列表的数据
|
||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
@ -179,21 +176,6 @@ const resetQuery = () => {
|
|||||||
handleQuery()
|
handleQuery()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 导出按钮操作 */
|
|
||||||
const handleExport = async () => {
|
|
||||||
try {
|
|
||||||
// 导出的二次确认
|
|
||||||
await message.exportConfirm()
|
|
||||||
// 发起导出
|
|
||||||
exportLoading.value = true
|
|
||||||
const data = await DeliveryPickUpStoreApi.exportDeliveryPickUpStoreApi(queryParams)
|
|
||||||
download.excel(data, '自提门店.xls')
|
|
||||||
} catch {
|
|
||||||
} finally {
|
|
||||||
exportLoading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 初始化 **/
|
/** 初始化 **/
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList()
|
getList()
|
||||||
|
97
src/views/mall/trade/order/components/DeliveryOrderForm.vue
Normal file
97
src/views/mall/trade/order/components/DeliveryOrderForm.vue
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog v-model="dialogVisible" title="订单发货" width="25%">
|
||||||
|
<el-form ref="formRef" v-loading="formLoading" :model="formData" label-width="80px">
|
||||||
|
<el-form-item label="发货方式">
|
||||||
|
<el-radio-group v-model="radio">
|
||||||
|
<el-radio border label="1">快递物流</el-radio>
|
||||||
|
<el-radio border label="2">无需发货</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<template v-if="radio === '1'">
|
||||||
|
<el-form-item label="物流公司">
|
||||||
|
<el-select v-model="formData.logisticsId" placeholder="请选择" style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
v-for="item in deliveryExpressList"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="物流单号">
|
||||||
|
<el-input v-model="formData.logisticsNo" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import * as DeliveryExpressApi from '@/api/mall/trade/delivery/express'
|
||||||
|
import * as TradeOrderApi from '@/api/mall/trade/order'
|
||||||
|
|
||||||
|
// TODO @puhui999:是不是名字叫 OrderDeliveryForm 保持统一
|
||||||
|
defineOptions({ name: 'DeliveryOrderForm' })
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const radio = ref('1') // TODO @puhui999:尽量不用 radio 这种命名,无业务含义。这里的话,可以考虑用 expressType,如果值是 express,则是快递;none 则是无;未来做同城配送,就比较容易拓展啦;
|
||||||
|
const formData = ref<TradeOrderApi.DeliveryVO>({
|
||||||
|
id: 0, // 订单编号
|
||||||
|
logisticsId: null, // 物流公司编号
|
||||||
|
logisticsNo: '' // 物流编号
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
// TODO @puhui999:每次点击发货的时候,是不是可以把之前的信息带过来哈。
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (orderId: number) => {
|
||||||
|
resetForm()
|
||||||
|
// 设置数据
|
||||||
|
formData.value.id = orderId
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = unref(formData)
|
||||||
|
if (radio.value === '2') {
|
||||||
|
// 无需发货的情况
|
||||||
|
data.logisticsId = 0
|
||||||
|
data.logisticsNo = ''
|
||||||
|
}
|
||||||
|
await TradeOrderApi.delivery(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success', true)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
id: 0, // 订单编号
|
||||||
|
logisticsId: null, // 物流公司编号
|
||||||
|
logisticsNo: '' // 物流编号
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
const deliveryExpressList = ref([])
|
||||||
|
onMounted(async () => {
|
||||||
|
deliveryExpressList.value = await DeliveryExpressApi.getSimpleDeliveryExpressList()
|
||||||
|
})
|
||||||
|
</script>
|
@ -0,0 +1,82 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog v-model="dialogVisible" title="修改订单收货地址" width="35%">
|
||||||
|
<el-form ref="formRef" v-loading="formLoading" :model="formData" label-width="120px">
|
||||||
|
<el-form-item label="收件人名称">
|
||||||
|
<el-input v-model="formData.receiverName" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="收件人手机">
|
||||||
|
<el-input v-model="formData.receiverMobile" />
|
||||||
|
</el-form-item>
|
||||||
|
<!-- TODO @puhui999:应该是个地区下拉框,可以看下 UserForm 所在地 -->
|
||||||
|
<el-form-item label="收件人地区编号">
|
||||||
|
<el-input v-model="formData.receiverAreaId" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="收件人详细地址">
|
||||||
|
<el-input v-model="formData.receiverDetailAddress" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import * as TradeOrderApi from '@/api/mall/trade/order'
|
||||||
|
import { copyValueToTarget } from '@/utils'
|
||||||
|
|
||||||
|
// TODO @puhui999:OrderAdjustAddressForm 改成 OrderUpdateAddressForm 更新哈,保持统一;
|
||||||
|
defineOptions({ name: 'OrderAdjustAddressForm' })
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formData = ref({
|
||||||
|
id: 0, // 订单编号
|
||||||
|
receiverName: '', // 收件人名称
|
||||||
|
receiverMobile: '', // 收件人手机
|
||||||
|
receiverAreaId: null, //收件人地区编号
|
||||||
|
receiverDetailAddress: '' //收件人详细地址
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (row: TradeOrderApi.OrderVO) => {
|
||||||
|
resetForm()
|
||||||
|
// 设置数据
|
||||||
|
copyValueToTarget(formData.value, row)
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = unref(formData)
|
||||||
|
await TradeOrderApi.adjustAddress(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success', true)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
id: 0, // 订单编号
|
||||||
|
receiverName: '', // 收件人名称
|
||||||
|
receiverMobile: '', // 收件人手机
|
||||||
|
receiverAreaId: null, //收件人地区编号
|
||||||
|
receiverDetailAddress: '' //收件人详细地址
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
@ -0,0 +1,90 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog v-model="dialogVisible" title="订单调价" width="25%">
|
||||||
|
<el-form ref="formRef" v-loading="formLoading" :model="formData" label-width="100px">
|
||||||
|
<el-form-item label="应付金额(总)">
|
||||||
|
<el-input v-model="formData.payPrice" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="订单调价">
|
||||||
|
<el-input-number v-model="formData.adjustPrice" :precision="2" :step="0.1" class="w-100%" />
|
||||||
|
<el-tag class="mt-10px" type="warning">订单调价。 正数,加价;负数,减价</el-tag>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="调价后">
|
||||||
|
<el-input v-model="formData.newPayPrice" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import * as TradeOrderApi from '@/api/mall/trade/order'
|
||||||
|
import { convertToInteger, formatToFraction } from '@/utils'
|
||||||
|
import { cloneDeep } from 'lodash-es'
|
||||||
|
|
||||||
|
// TODO @puhui999:OrderAdjustPriceForm 改成 OrderUpdatePriceForm 更新哈,保持统一;
|
||||||
|
defineOptions({ name: 'OrderAdjustPriceForm' })
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formData = ref({
|
||||||
|
id: 0, // 订单编号
|
||||||
|
adjustPrice: 0, // 订单调价
|
||||||
|
payPrice: '', // 应付金额(总)
|
||||||
|
newPayPrice: '' // 调价后应付金额(总)
|
||||||
|
})
|
||||||
|
watch(
|
||||||
|
() => formData.value.adjustPrice,
|
||||||
|
(data: number) => {
|
||||||
|
formData.value.newPayPrice = formData.value.payPrice.replace('元', '') * 1 + data + '元'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (row: TradeOrderApi.OrderVO) => {
|
||||||
|
resetForm()
|
||||||
|
formData.value.id = row.id
|
||||||
|
// 设置数据
|
||||||
|
formData.value.adjustPrice = formatToFraction(row.adjustPrice)
|
||||||
|
formData.value.payPrice = formatToFraction(row.payPrice) + '元'
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = cloneDeep(unref(formData))
|
||||||
|
data.adjustPrice = convertToInteger(data.adjustPrice)
|
||||||
|
delete data.payPrice
|
||||||
|
delete data.newPayPrice
|
||||||
|
await TradeOrderApi.adjustPrice(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success', true)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
id: 0, // 订单编号
|
||||||
|
adjustPrice: 0, // 订单调价
|
||||||
|
payPrice: '', // 应付金额(总)
|
||||||
|
newPayPrice: '' // 调价后应付金额(总)
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
@ -2,31 +2,32 @@
|
|||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<!-- 订单信息 -->
|
<!-- 订单信息 -->
|
||||||
<el-descriptions title="订单信息">
|
<el-descriptions title="订单信息">
|
||||||
<el-descriptions-item label="订单号: ">{{ order.no }}</el-descriptions-item>
|
<el-descriptions-item label="订单号: ">{{ orderInfo.no }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="配送方式: ">物流配送</el-descriptions-item>
|
<el-descriptions-item label="配送方式: ">
|
||||||
<!-- TODO 芋艿:待实现 -->
|
<dict-tag :type="DICT_TYPE.TRADE_DELIVERY_TYPE" :value="orderInfo.deliveryType" />
|
||||||
<el-descriptions-item label="营销活动: ">物流配送</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<!-- TODO 芋艿:待实现 -->
|
<!-- TODO 营销活动待实现 -->
|
||||||
|
<el-descriptions-item label="营销活动: ">秒杀活动</el-descriptions-item>
|
||||||
<el-descriptions-item label="订单类型: ">
|
<el-descriptions-item label="订单类型: ">
|
||||||
<dict-tag :type="DICT_TYPE.TRADE_ORDER_TYPE" :value="order.type" />
|
<dict-tag :type="DICT_TYPE.TRADE_ORDER_TYPE" :value="orderInfo.type" />
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="收货人: ">{{ order.receiverName }}</el-descriptions-item>
|
<el-descriptions-item label="收货人: ">{{ orderInfo.receiverName }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="买家留言: ">{{ order.userRemark }}</el-descriptions-item>
|
<el-descriptions-item label="买家留言: ">{{ orderInfo.userRemark }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="订单来源: ">
|
<el-descriptions-item label="订单来源: ">
|
||||||
<dict-tag :type="DICT_TYPE.TERMINAL" :value="order.terminal" />
|
<dict-tag :type="DICT_TYPE.TERMINAL" :value="orderInfo.terminal" />
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="联系电话: ">{{ order.receiverMobile }}</el-descriptions-item>
|
<el-descriptions-item label="联系电话: ">{{ orderInfo.receiverMobile }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="商家备注: ">{{ order.remark }}</el-descriptions-item>
|
<el-descriptions-item label="商家备注: ">{{ orderInfo.remark }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="支付单号: ">{{ order.payOrderId }}</el-descriptions-item>
|
<el-descriptions-item label="支付单号: ">{{ orderInfo.payOrderId }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="付款方式: ">
|
<el-descriptions-item label="付款方式: ">
|
||||||
<dict-tag :type="DICT_TYPE.PAY_CHANNEL_CODE_TYPE" :value="order.payChannelCode" />
|
<dict-tag :type="DICT_TYPE.PAY_CHANNEL_CODE" :value="orderInfo.payChannelCode" />
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<!-- <el-descriptions-item label="买家: ">{{ order.user.nickname }}</el-descriptions-item> -->
|
<!-- <el-descriptions-item label="买家: ">{{ orderInfo.user.nickname }}</el-descriptions-item> -->
|
||||||
<!-- TODO 芋艿:待实现:跳转会员 -->
|
<!-- TODO 芋艿:待实现:跳转会员 -->
|
||||||
<el-descriptions-item label="收货地址: ">
|
<el-descriptions-item label="收货地址: ">
|
||||||
{{ order.receiverAreaName }} {{ order.receiverDetailAddress }}
|
{{ orderInfo.receiverAreaName }} {{ orderInfo.receiverDetailAddress }}
|
||||||
<el-link
|
<el-link
|
||||||
v-clipboard:copy="order.receiverAreaName + ' ' + order.receiverDetailAddress"
|
v-clipboard:copy="orderInfo.receiverAreaName + ' ' + orderInfo.receiverDetailAddress"
|
||||||
v-clipboard:success="clipboardSuccess"
|
v-clipboard:success="clipboardSuccess"
|
||||||
icon="ep:document-copy"
|
icon="ep:document-copy"
|
||||||
type="primary"
|
type="primary"
|
||||||
@ -35,32 +36,15 @@
|
|||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
|
|
||||||
<!-- 订单状态 -->
|
<!-- 订单状态 -->
|
||||||
<el-descriptions title="订单状态" :column="1">
|
<el-descriptions :column="1" title="订单状态">
|
||||||
<el-descriptions-item label="订单状态: ">
|
<el-descriptions-item label="订单状态: ">
|
||||||
<!-- TODO xiaobai:status 一定有值哈,不用判断 -->
|
<dict-tag :type="DICT_TYPE.TRADE_ORDER_STATUS" :value="orderInfo.status" />
|
||||||
<dict-tag
|
|
||||||
v-if="order.status !== ''"
|
|
||||||
:type="DICT_TYPE.TRADE_ORDER_STATUS"
|
|
||||||
:value="order.status"
|
|
||||||
/>
|
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label-class-name="no-colon">
|
<el-descriptions-item label-class-name="no-colon">
|
||||||
<el-button type="primary" size="small">调整价格</el-button>
|
<el-button type="primary" @click="openForm('adjustPrice')">调整价格</el-button>
|
||||||
<!-- TODO 芋艿:待实现 -->
|
<el-button type="primary" @click="openForm('remark')">备注</el-button>
|
||||||
<el-button type="primary" size="small">备注</el-button>
|
<el-button type="primary" @click="openForm('delivery')">发货</el-button>
|
||||||
<!-- TODO 芋艿:待实现 -->
|
<el-button type="primary" @click="openForm('adjustAddress')">修改地址</el-button>
|
||||||
<el-button type="primary" size="small">发货</el-button>
|
|
||||||
<!-- TODO 芋艿:待实现 -->
|
|
||||||
<el-button type="primary" size="small">关闭订单</el-button>
|
|
||||||
<!-- TODO 芋艿:待实现 -->
|
|
||||||
<el-button type="primary" size="small">修改地址</el-button>
|
|
||||||
<!-- TODO 芋艿:待实现 -->
|
|
||||||
<el-button type="primary" size="small">打印电子面单</el-button>
|
|
||||||
<!-- TODO 芋艿:待实现 -->
|
|
||||||
<el-button type="primary" size="small">打印发货单</el-button>
|
|
||||||
<!-- TODO 芋艿:待实现 -->
|
|
||||||
<el-button type="primary" size="small">确认收货</el-button>
|
|
||||||
<!-- TODO 芋艿:待实现 -->
|
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item>
|
<el-descriptions-item>
|
||||||
<template #label><span style="color: red">提醒: </span></template>
|
<template #label><span style="color: red">提醒: </span></template>
|
||||||
@ -70,34 +54,28 @@
|
|||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
|
|
||||||
<!-- 物流信息 TODO -->
|
|
||||||
|
|
||||||
<!-- 商品信息 -->
|
<!-- 商品信息 -->
|
||||||
<el-descriptions title="商品信息">
|
<el-descriptions title="商品信息">
|
||||||
<el-descriptions-item labelClassName="no-colon">
|
<el-descriptions-item labelClassName="no-colon">
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="15">
|
<el-col :span="15">
|
||||||
<el-table :data="order.items" border>
|
<el-table :data="orderInfo.items" border>
|
||||||
<el-table-column prop="spuName" label="商品" width="auto">
|
<el-table-column label="商品" prop="spuName" width="auto">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ row.spuName }}
|
{{ row.spuName }}
|
||||||
<el-tag
|
<el-tag v-for="property in row.properties" :key="property.propertyId">
|
||||||
size="medium"
|
{{ property.propertyName }}: {{ property.valueName }}
|
||||||
v-for="property in row.properties"
|
</el-tag>
|
||||||
:key="property.propertyId"
|
|
||||||
>
|
|
||||||
{{ property.propertyName }}: {{ property.valueName }}</el-tag
|
|
||||||
>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="price" label="商品原价(元)" width="150">
|
<el-table-column label="商品原价(元)" prop="price" width="150">
|
||||||
<template #default="{ row }"> ¥{{ (row.price / 100.0).toFixed(2) }} </template>
|
<template #default="{ row }">{{ formatToFraction(row.price) }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="count" label="数量" width="100" />
|
<el-table-column label="数量" prop="count" width="100" />
|
||||||
<el-table-column prop="payPrice" label="合计(元)" width="150">
|
<el-table-column label="合计(元)" prop="payPrice" width="150">
|
||||||
<template #default="{ row }"> ¥{{ (row.payPrice / 100.0).toFixed(2) }} </template>
|
<template #default="{ row }">{{ formatToFraction(row.payPrice) }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="afterSaleStatus" label="售后状态" width="auto">
|
<el-table-column label="售后状态" prop="afterSaleStatus" width="120">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<dict-tag
|
<dict-tag
|
||||||
:type="DICT_TYPE.TRADE_ORDER_ITEM_AFTER_SALE_STATUS"
|
:type="DICT_TYPE.TRADE_ORDER_ITEM_AFTER_SALE_STATUS"
|
||||||
@ -110,51 +88,41 @@
|
|||||||
<el-col :span="10" />
|
<el-col :span="10" />
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<!-- 占位 -->
|
|
||||||
<!-- <el-descriptions-item v-for="item in 5" label-class-name="no-colon" :key="item" /> -->
|
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
<el-descriptions column="6">
|
<el-descriptions :column="6">
|
||||||
<el-descriptions-item label="商品总额: ">
|
<el-descriptions-item label="商品总额: ">
|
||||||
<!-- TODO xiaobai: 是不是 (item.payPrice / 100.0).toFixed(2) -->
|
{{ formatToFraction(orderInfo.totalPrice) }}元
|
||||||
¥{{ parseFloat((order.totalPrice / 100.0) as unknown as string).toFixed(2) }}
|
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="运费金额: ">
|
<el-descriptions-item label="运费金额: ">
|
||||||
¥{{ parseFloat((order.deliveryPrice / 100.0) as unknown as string).toFixed(2) }}
|
{{ formatToFraction(orderInfo.deliveryPrice) }}元
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="订单调价: ">
|
<el-descriptions-item label="订单调价: ">
|
||||||
¥{{
|
{{ formatToFraction(orderInfo.adjustPrice) }}元
|
||||||
parseFloat((order.adjustPrice / 100.0) as unknown as string).toFixed(2)
|
</el-descriptions-item>
|
||||||
}}</el-descriptions-item
|
|
||||||
>
|
|
||||||
|
|
||||||
<el-descriptions-item>
|
<el-descriptions-item>
|
||||||
<template #label><span style="color: red">商品优惠: </span></template>
|
<template #label><span style="color: red">商品优惠: </span></template>
|
||||||
<!-- 没理解TODO order.totalPrice - order.totalPrice -->
|
{{ formatToFraction(orderInfo.couponPrice) }}元
|
||||||
¥{{
|
|
||||||
parseFloat(((order.totalPrice - order.totalPrice) / 100.0) as unknown as string).toFixed(
|
|
||||||
2
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item>
|
<el-descriptions-item>
|
||||||
<template #label><span style="color: red">订单优惠: </span></template>
|
<template #label><span style="color: red">订单优惠: </span></template>
|
||||||
¥{{ parseFloat((order.discountPrice / 100.0) as unknown as string).toFixed(2) }}
|
{{ formatToFraction(orderInfo.discountPrice) }}元
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item>
|
<el-descriptions-item>
|
||||||
<template #label><span style="color: red">积分抵扣: </span></template>
|
<template #label><span style="color: red">积分抵扣: </span></template>
|
||||||
¥{{ parseFloat((order.pointPrice / 100.0) as unknown as string).toFixed(2) }}
|
{{ formatToFraction(orderInfo.pointPrice) }}元
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
|
||||||
<el-descriptions-item v-for="item in 5" label-class-name="no-colon" :key="item" />
|
<el-descriptions-item v-for="item in 5" :key="item" label-class-name="no-colon" />
|
||||||
<!-- 占位 -->
|
<!-- 占位 -->
|
||||||
<el-descriptions-item label="应付金额: ">
|
<el-descriptions-item label="应付金额: ">
|
||||||
¥{{ (order.payPrice / 100.0).toFixed(2) }}
|
{{ formatToFraction(orderInfo.payPrice) }}元
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
|
|
||||||
<!-- TODO 芋艿:需要改改 -->
|
<!-- TODO 芋艿:需要改改 -->
|
||||||
<div v-for="group in detailGroups" :key="group.title">
|
<div v-for="group in detailGroups" :key="group.title">
|
||||||
<el-descriptions v-bind="group.groupProps" :title="group.title">
|
<el-descriptions :title="group.title" v-bind="group.groupProps">
|
||||||
<!-- 订单操作日志 -->
|
<!-- 订单操作日志 -->
|
||||||
<el-descriptions-item v-if="group.key === 'orderLog'" labelClassName="no-colon">
|
<el-descriptions-item v-if="group.key === 'orderLog'" labelClassName="no-colon">
|
||||||
<el-timeline>
|
<el-timeline>
|
||||||
@ -168,7 +136,7 @@
|
|||||||
</el-timeline>
|
</el-timeline>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
|
||||||
<!-- 物流信息 -->
|
<!-- 物流信息 TODO 等物流接口搞定重构一下 -->
|
||||||
<!-- TODO @xiaobai:改成一个包裹哈;目前只允许发货一次 -->
|
<!-- TODO @xiaobai:改成一个包裹哈;目前只允许发货一次 -->
|
||||||
<el-descriptions-item v-if="group.key === 'expressInfo'" labelClassName="no-colon">
|
<el-descriptions-item v-if="group.key === 'expressInfo'" labelClassName="no-colon">
|
||||||
<!-- 循环包裹物流信息 -->
|
<!-- 循环包裹物流信息 -->
|
||||||
@ -177,9 +145,9 @@
|
|||||||
<el-descriptions class="m-5">
|
<el-descriptions class="m-5">
|
||||||
<el-descriptions-item
|
<el-descriptions-item
|
||||||
v-for="(pkgChild, pkgCIdx) in group.children"
|
v-for="(pkgChild, pkgCIdx) in group.children"
|
||||||
v-bind="pkgChild.childProps"
|
|
||||||
:key="`pkgChild_${pkgCIdx}`"
|
:key="`pkgChild_${pkgCIdx}`"
|
||||||
:label="pkgChild.label"
|
:label="pkgChild.label"
|
||||||
|
v-bind="pkgChild.childProps"
|
||||||
>
|
>
|
||||||
<!-- 包裹商品列表 -->
|
<!-- 包裹商品列表 -->
|
||||||
<template v-if="pkgChild.valueKey === 'goodsList' && pkgInfo[pkgChild.valueKey]">
|
<template v-if="pkgChild.valueKey === 'goodsList' && pkgInfo[pkgChild.valueKey]">
|
||||||
@ -189,14 +157,16 @@
|
|||||||
style="display: flex"
|
style="display: flex"
|
||||||
>
|
>
|
||||||
<el-image
|
<el-image
|
||||||
style="width: 100px; height: 100px; flex: none"
|
|
||||||
:src="goodInfo.imgUrl"
|
:src="goodInfo.imgUrl"
|
||||||
|
style="width: 100px; height: 100px; flex: none"
|
||||||
/>
|
/>
|
||||||
<el-descriptions :column="1">
|
<el-descriptions :column="1">
|
||||||
<el-descriptions-item labelClassName="no-colon">{{
|
<el-descriptions-item labelClassName="no-colon"
|
||||||
goodInfo.name
|
>{{ goodInfo.name }}
|
||||||
}}</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="数量">{{ goodInfo.count }}</el-descriptions-item>
|
<el-descriptions-item label="数量"
|
||||||
|
>{{ goodInfo.count }}
|
||||||
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -204,7 +174,7 @@
|
|||||||
<!-- 包裹物流详情 -->
|
<!-- 包裹物流详情 -->
|
||||||
<template v-else-if="pkgChild.valueKey === 'wlxq'">
|
<template v-else-if="pkgChild.valueKey === 'wlxq'">
|
||||||
<el-row :gutter="10">
|
<el-row :gutter="10">
|
||||||
<el-col :span="6" :offset="1">
|
<el-col :offset="1" :span="6">
|
||||||
<el-timeline>
|
<el-timeline>
|
||||||
<el-timeline-item
|
<el-timeline-item
|
||||||
v-for="(activity, index) in pkgInfo[pkgChild.valueKey]"
|
v-for="(activity, index) in pkgInfo[pkgChild.valueKey]"
|
||||||
@ -227,24 +197,73 @@
|
|||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
</template>
|
|
||||||
<script lang="ts" name="TradeOrderDetail" setup>
|
|
||||||
// TODO @xiaobai:在 order 下创建一个 order/detail,然后改名为 index.vue
|
|
||||||
import { DICT_TYPE } from '@/utils/dict'
|
|
||||||
import * as TradeOrderApi from '@/api/mall/trade/order'
|
|
||||||
const message = useMessage() // 消息弹窗
|
|
||||||
|
|
||||||
const { query } = useRoute()
|
<!-- 各种操作的弹窗 -->
|
||||||
const queryParams = reactive({
|
<DeliveryOrderForm ref="deliveryFormRef" @success="getDetail" />
|
||||||
id: query.id
|
<OrderRemarksForm ref="remarksFormRef" @success="getDetail" />
|
||||||
})
|
<OrderAdjustAddressForm ref="adjustAddressFormRef" @success="getDetail" />
|
||||||
const dialogVisible = ref(false)
|
<OrderAdjustPriceForm ref="adjustPriceFormRef" @success="getDetail" />
|
||||||
const loading = ref(false)
|
</template>
|
||||||
const order = ref<any>({
|
<script lang="ts" setup>
|
||||||
|
import * as TradeOrderApi from '@/api/mall/trade/order'
|
||||||
|
import { formatToFraction } from '@/utils'
|
||||||
|
import { DICT_TYPE } from '@/utils/dict'
|
||||||
|
import OrderRemarksForm from '@/views/mall/trade/order/components/OrderRemarksForm.vue'
|
||||||
|
import DeliveryOrderForm from '@/views/mall/trade/order/components/DeliveryOrderForm.vue'
|
||||||
|
import OrderAdjustAddressForm from '@/views/mall/trade/order/components/OrderAdjustAddressForm.vue'
|
||||||
|
import OrderAdjustPriceForm from '@/views/mall/trade/order/components/OrderAdjustPriceForm.vue'
|
||||||
|
|
||||||
|
// TODO @puhui999:TradeOrderDetailForm 可以挪到 order/detail/index.vue 中,它是一个 vue 界面哈。
|
||||||
|
defineOptions({ name: 'TradeOrderDetailForm' })
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
const { params } = useRoute() // 查询参数
|
||||||
|
// TODO @puhui999:orderInfo 应该不用把属性弄出来也;
|
||||||
|
const orderInfo = ref<TradeOrderApi.OrderVO>({
|
||||||
|
no: '',
|
||||||
|
createTime: null,
|
||||||
|
type: null,
|
||||||
|
terminal: null,
|
||||||
|
userId: null,
|
||||||
|
userIp: '',
|
||||||
|
userRemark: '',
|
||||||
|
status: null,
|
||||||
|
productCount: null,
|
||||||
|
finishTime: null,
|
||||||
|
cancelTime: null,
|
||||||
|
cancelType: null,
|
||||||
|
remark: '',
|
||||||
|
payOrderId: null,
|
||||||
|
payed: false,
|
||||||
|
payTime: null,
|
||||||
|
payChannelCode: '',
|
||||||
|
originalPrice: null,
|
||||||
|
orderPrice: null,
|
||||||
|
discountPrice: null,
|
||||||
|
deliveryPrice: null,
|
||||||
|
adjustPrice: null,
|
||||||
|
payPrice: null,
|
||||||
|
deliveryTemplateId: null,
|
||||||
|
logisticsId: null,
|
||||||
|
logisticsNo: '',
|
||||||
|
deliveryStatus: null,
|
||||||
|
deliveryTime: null,
|
||||||
|
receiveTime: null,
|
||||||
|
receiverName: '',
|
||||||
|
receiverMobile: '',
|
||||||
|
receiverAreaId: null,
|
||||||
|
receiverPostCode: null,
|
||||||
|
receiverDetailAddress: '',
|
||||||
|
afterSaleStatus: null,
|
||||||
|
refundPrice: null,
|
||||||
|
couponPrice: null,
|
||||||
|
pointPrice: null,
|
||||||
|
receiverAreaName: '',
|
||||||
items: [],
|
items: [],
|
||||||
user: {}
|
user: {}
|
||||||
}) // 详情数据
|
})
|
||||||
|
|
||||||
|
// TODO @puhui999:这个改成直接读属性,不用按照这种写法;
|
||||||
const detailGroups = ref([
|
const detailGroups = ref([
|
||||||
{
|
{
|
||||||
title: '物流信息',
|
title: '物流信息',
|
||||||
@ -263,39 +282,39 @@ const detailGroups = ref([
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
// TODO @puhui999:从后台读数据哈。
|
||||||
const detailInfo = ref({
|
const detailInfo = ref({
|
||||||
expressInfo:
|
// 物流信息
|
||||||
// 物流信息
|
expressInfo: {
|
||||||
{
|
label: '包裹1',
|
||||||
label: '包裹1',
|
name: 'bg1',
|
||||||
name: 'bg1',
|
fhsj: '2022-11-03 16:50:45',
|
||||||
fhsj: '2022-11-03 16:50:45',
|
wlgs: '极兔',
|
||||||
wlgs: '极兔',
|
ydh: '2132123',
|
||||||
ydh: '2132123',
|
wlzt: '不支持此快递公司',
|
||||||
wlzt: '不支持此快递公司',
|
wlxq: [
|
||||||
wlxq: [
|
{
|
||||||
{
|
content: '正在派送途中,请您准备签收(派件人:王涛,电话:13854563814)',
|
||||||
content: '正在派送途中,请您准备签收(派件人:王涛,电话:13854563814)',
|
timestamp: '2018-04-15 15:00:16'
|
||||||
timestamp: '2018-04-15 15:00:16'
|
},
|
||||||
},
|
{
|
||||||
{
|
content: '快件到达 【烟台龙口东江村委营业点】',
|
||||||
content: '快件到达 【烟台龙口东江村委营业点】',
|
timestamp: '2018-04-13 14:54:19'
|
||||||
timestamp: '2018-04-13 14:54:19'
|
},
|
||||||
},
|
{
|
||||||
{
|
content: '快件已发车',
|
||||||
content: '快件已发车',
|
timestamp: '2018-04-11 12:55:52'
|
||||||
timestamp: '2018-04-11 12:55:52'
|
},
|
||||||
},
|
{
|
||||||
{
|
content: '快件已发车',
|
||||||
content: '快件已发车',
|
timestamp: '2018-04-11 12:55:52'
|
||||||
timestamp: '2018-04-11 12:55:52'
|
},
|
||||||
},
|
{
|
||||||
{
|
content: '快件已发车',
|
||||||
content: '快件已发车',
|
timestamp: '2018-04-11 12:55:52'
|
||||||
timestamp: '2018-04-11 12:55:52'
|
}
|
||||||
}
|
]
|
||||||
]
|
},
|
||||||
},
|
|
||||||
orderLog: [
|
orderLog: [
|
||||||
// 订单操作日志
|
// 订单操作日志
|
||||||
{
|
{
|
||||||
@ -309,23 +328,41 @@ const detailInfo = ref({
|
|||||||
],
|
],
|
||||||
goodsInfo: [] // 商品详情tableData
|
goodsInfo: [] // 商品详情tableData
|
||||||
})
|
})
|
||||||
// 暂考虑一次性加载详情页面所有数据 TODO
|
|
||||||
const getlist = async () => {
|
const deliveryFormRef = ref() // 发货表单 Ref
|
||||||
dialogVisible.value = true
|
const remarksFormRef = ref() // 订单备注表单 Ref
|
||||||
loading.value = true
|
const adjustAddressFormRef = ref() // 收货地址表单 Ref
|
||||||
try {
|
const adjustPriceFormRef = ref() // 订单调价表单 Ref
|
||||||
const res = await TradeOrderApi.getOrderDetail(queryParams.id as unknown as number)
|
const openForm = (type: string) => {
|
||||||
order.value = res
|
switch (type) {
|
||||||
console.log(order)
|
case 'remark':
|
||||||
} catch {
|
remarksFormRef.value?.open(orderInfo.value)
|
||||||
message.error('获取详情数据失败')
|
break
|
||||||
} finally {
|
case 'delivery':
|
||||||
loading.value = false
|
deliveryFormRef.value?.open(orderInfo.value.id)
|
||||||
|
break
|
||||||
|
case 'adjustAddress':
|
||||||
|
adjustAddressFormRef.value?.open(orderInfo.value)
|
||||||
|
break
|
||||||
|
case 'adjustPrice':
|
||||||
|
adjustPriceFormRef.value?.open(orderInfo.value)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 获得详情 */
|
||||||
|
const getDetail = async () => {
|
||||||
|
const id = params.orderId as unknown as number
|
||||||
|
if (id) {
|
||||||
|
const res = (await TradeOrderApi.getOrder(id)) as TradeOrderApi.OrderVO
|
||||||
|
orderInfo.value = res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await getlist()
|
await getDetail()
|
||||||
})
|
})
|
||||||
|
|
||||||
const clipboardSuccess = () => {
|
const clipboardSuccess = () => {
|
||||||
message.success('复制成功')
|
message.success('复制成功')
|
||||||
}
|
}
|
67
src/views/mall/trade/order/components/OrderRemarksForm.vue
Normal file
67
src/views/mall/trade/order/components/OrderRemarksForm.vue
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog v-model="dialogVisible" title="商家备注" width="25%">
|
||||||
|
<el-form ref="formRef" v-loading="formLoading" :model="formData" label-width="80px">
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input v-model="formData.remark" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import * as TradeOrderApi from '@/api/mall/trade/order'
|
||||||
|
|
||||||
|
// TODO @puhui999:OrderRemarksForm 改成 OrderUpdateRemarkForm 更新哈,保持统一;
|
||||||
|
defineOptions({ name: 'OrderRemarksForm' })
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formData = ref({
|
||||||
|
id: 0, // 订单编号
|
||||||
|
remark: '' // 订单备注
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (row: TradeOrderApi.OrderVO) => {
|
||||||
|
resetForm()
|
||||||
|
// 设置数据
|
||||||
|
formData.value.id = row.id
|
||||||
|
formData.value.remark = row.remark
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = unref(formData)
|
||||||
|
console.log(data)
|
||||||
|
await TradeOrderApi.remark(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success', true)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
id: 0, // 订单编号
|
||||||
|
remark: '' // 订单备注
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
@ -3,16 +3,16 @@
|
|||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-form
|
<el-form
|
||||||
ref="queryFormRef"
|
ref="queryFormRef"
|
||||||
|
:inline="true"
|
||||||
:model="queryParams"
|
:model="queryParams"
|
||||||
class="-mb-15px"
|
class="-mb-15px"
|
||||||
label-width="68px"
|
label-width="68px"
|
||||||
:inline="true"
|
|
||||||
>
|
>
|
||||||
<el-form-item label="订单状态" prop="status">
|
<el-form-item label="订单状态" prop="status">
|
||||||
<el-select class="!w-280px" v-model="queryParams.status" clearable placeholder="全部">
|
<el-select v-model="queryParams.status" class="!w-280px" clearable placeholder="全部">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getStrDictOptions(DICT_TYPE.TRADE_ORDER_STATUS)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.TRADE_ORDER_STATUS)"
|
||||||
:key="dict.value as string"
|
:key="dict.value"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
:value="dict.value"
|
:value="dict.value"
|
||||||
/>
|
/>
|
||||||
@ -26,8 +26,8 @@
|
|||||||
placeholder="全部"
|
placeholder="全部"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getStrDictOptions(DICT_TYPE.PAY_CHANNEL_CODE_TYPE)"
|
v-for="dict in getStrDictOptions(DICT_TYPE.PAY_CHANNEL_CODE)"
|
||||||
:key="dict.value as string"
|
:key="dict.value"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
:value="dict.value"
|
:value="dict.value"
|
||||||
/>
|
/>
|
||||||
@ -38,43 +38,69 @@
|
|||||||
v-model="queryParams.createTime"
|
v-model="queryParams.createTime"
|
||||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
class="!w-280px"
|
class="!w-280px"
|
||||||
start-placeholder="自定义时间"
|
|
||||||
end-placeholder="自定义时间"
|
end-placeholder="自定义时间"
|
||||||
|
start-placeholder="自定义时间"
|
||||||
type="daterange"
|
type="daterange"
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="订单来源" prop="terminal">
|
<el-form-item label="订单来源" prop="terminal">
|
||||||
<el-select class="!w-280px" v-model="queryParams.terminal" clearable placeholder="全部">
|
<el-select v-model="queryParams.terminal" class="!w-280px" clearable placeholder="全部">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getStrDictOptions(DICT_TYPE.TERMINAL)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.TERMINAL)"
|
||||||
:key="dict.value as string"
|
:key="dict.value"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
:value="dict.value"
|
:value="dict.value"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="订单类型" prop="type">
|
<el-form-item label="订单类型" prop="type">
|
||||||
<el-select class="!w-280px" v-model="queryParams.type" clearable placeholder="全部">
|
<el-select v-model="queryParams.type" class="!w-280px" clearable placeholder="全部">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getStrDictOptions(DICT_TYPE.TRADE_ORDER_TYPE)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.TRADE_ORDER_TYPE)"
|
||||||
:key="dict.value as string"
|
:key="dict.value"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
:value="dict.value"
|
:value="dict.value"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="快递公司" prop="type">
|
||||||
<el-form-item label="订单搜索">
|
<el-select v-model="queryParams.logisticsId" class="!w-280px" clearable placeholder="全部">
|
||||||
|
<el-option
|
||||||
|
v-for="item in deliveryExpressList"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="自提门店" prop="type">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.pickUpStoreId"
|
||||||
|
class="!w-280px"
|
||||||
|
clearable
|
||||||
|
multiple
|
||||||
|
placeholder="全部"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in pickUpStoreList"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- TODO 考虑是否移除或重构;这个还是需要的哈-->
|
||||||
|
<el-form-item label="聚合搜索">
|
||||||
<el-input
|
<el-input
|
||||||
v-show="true"
|
v-show="true"
|
||||||
class="!w-280px"
|
|
||||||
v-model="queryType.v"
|
v-model="queryType.v"
|
||||||
|
class="!w-280px"
|
||||||
clearable
|
clearable
|
||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
>
|
>
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<el-select style="width: 110px" v-model="queryType.k" clearable placeholder="全部">
|
<el-select v-model="queryType.k" clearable placeholder="全部" class="!w-110px">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in searchList"
|
v-for="dict in searchList"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
@ -86,180 +112,191 @@
|
|||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery" v-hasPermi="['trade:order:query']">
|
<el-button @click="handleQuery">
|
||||||
<Icon class="mr-5px" icon="ep:search" />
|
<Icon class="mr-5px" icon="ep:search" />
|
||||||
搜索
|
搜索
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button @click="resetQuery" v-hasPermi="['trade:order:query']">
|
<el-button @click="resetQuery">
|
||||||
<Icon class="mr-5px" icon="ep:refresh" />
|
<Icon class="mr-5px" icon="ep:refresh" />
|
||||||
重置
|
重置
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="success" plain @click="handleExport" :loading="exportLoading">
|
|
||||||
<!-- v-hasPermi="['trade:order:export']" -->
|
|
||||||
<Icon icon="ep:download" class="mr-5px" /> 导出TODO
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
<!-- 表格 -->
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<!-- TODO @puhui999:列表有可能尽量对齐 https://gitee.com/niushop_team/niushop_b2c_v5_stand/raw/master/image/back_end5.png 哇,主要感觉视觉上有点无法分辨一个订单项,是和哪个订单关联。
|
||||||
|
|
||||||
|
1、订单号、订单类型、订单来源、支付时间那一行,直接做到订单项的数据中
|
||||||
|
2、商品信息、商品原价那一行,应该是在最顶上一行,不用每个订单项都写一条
|
||||||
|
3、然后点击展开和收拢订单项,可以不做哈。
|
||||||
|
-->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<!-- 表单 -->
|
<el-table
|
||||||
<el-table v-loading="loading" :data="list">
|
v-loading="loading"
|
||||||
<el-table-column type="expand" fixed="left">
|
:data="list"
|
||||||
|
:show-overflow-tooltip="true"
|
||||||
|
:stripe="true"
|
||||||
|
default-expand-all
|
||||||
|
>
|
||||||
|
<el-table-column fixed="left" type="expand">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-descriptions class="mx-40">
|
<el-table :data="scope.row.items" :span-method="spanMethod" border style="width: 100%">
|
||||||
<el-descriptions-item label="商品原价(总): ">{{
|
<el-table-column label="商品信息" min-width="300" prop="spuName">
|
||||||
'¥ ' +
|
<template #default="{ row }">
|
||||||
parseFloat((scope.row.originalPrice / 100) as unknown as string).toFixed(2) +
|
<div class="flex items-center">
|
||||||
' 元'
|
|
||||||
}}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="下单时间: ">
|
|
||||||
{{ formatDate(scope.row.createTime) }}</el-descriptions-item
|
|
||||||
>
|
|
||||||
<el-descriptions-item label="推广人: ">TODO</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="用户备注: ">{{
|
|
||||||
scope.row.userRemark
|
|
||||||
}}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="商家备注: ">{{ scope.row.remark }}</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column width="100" fixed="left">
|
|
||||||
<template #header>
|
|
||||||
<el-dropdown icon="eq:search" @command="handleDropType">
|
|
||||||
<el-button link type="primary">全选({{ orderSelect.selectTotal }}) </el-button>
|
|
||||||
|
|
||||||
<template #dropdown>
|
|
||||||
<el-dropdown-menu>
|
|
||||||
<el-dropdown-item command="1">当前页</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="2">所有页</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</template>
|
|
||||||
</el-dropdown>
|
|
||||||
</template>
|
|
||||||
<template #default="scope">
|
|
||||||
<el-checkbox v-model="scope.row.itemSelect" @change="handcheckclick(scope.row)" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column label="订单号" align="center" min-width="110">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-button link type="primary" @click="showOrderDetail(scope.row)">{{
|
|
||||||
scope.row.no
|
|
||||||
}}</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="订单类型" align="center" min-width="100">
|
|
||||||
<template #default="scope">
|
|
||||||
<dict-tag :type="DICT_TYPE.TRADE_ORDER_TYPE" :value="scope.row.type" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="用户信息" align="center" min-width="100">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-button link type="primary" @click="goUserDetail(scope.row)"
|
|
||||||
>{{ scope.row.userId }}{{ '[' + scope.row.user.nickname + ']' }}</el-button
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
|
||||||
label="创建时间"
|
|
||||||
prop="createTime"
|
|
||||||
min-width="180"
|
|
||||||
/>
|
|
||||||
<el-table-column label="订单来源" align="center" min-width="100">
|
|
||||||
<template #default="scope">
|
|
||||||
<dict-tag
|
|
||||||
v-if="scope.row.terminal"
|
|
||||||
:type="DICT_TYPE.TERMINAL"
|
|
||||||
:value="scope.row.terminal"
|
|
||||||
/>
|
|
||||||
<span v-else>{{ scope.terminal }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column label="商品信息" align="left" min-width="200" prop="items">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-popover
|
|
||||||
ref="popover"
|
|
||||||
placement="bottom"
|
|
||||||
:title="'订单:' + scope.row.no"
|
|
||||||
:width="400"
|
|
||||||
trigger="hover"
|
|
||||||
>
|
|
||||||
<template #reference>
|
|
||||||
<div>
|
|
||||||
<div v-for="item in scope.row.items" :key="item">
|
|
||||||
<el-image
|
<el-image
|
||||||
style="width: 36px; height: 36px"
|
:src="row.picUrl"
|
||||||
:src="item.picUrl"
|
class="w-30px h-30px mr-10px"
|
||||||
:preview-src-list="[item.picUrl]"
|
@click="imagePreview(row.picUrl)"
|
||||||
fit="cover"
|
|
||||||
@click="imagePreview(item.picUrl)"
|
|
||||||
/>
|
/>
|
||||||
<span class="m-2">{{ item.spuName }}</span>
|
<span class="mr-10px">{{ row.spuName }}</span>
|
||||||
|
<el-tag
|
||||||
|
v-for="property in row.properties"
|
||||||
|
:key="property.propertyId"
|
||||||
|
class="mr-10px"
|
||||||
|
>
|
||||||
|
{{ property.propertyName }}: {{ property.valueName }}
|
||||||
|
</el-tag>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
</template>
|
</el-table-column>
|
||||||
<div v-for="item in scope.row.items" :key="item">
|
<el-table-column label="商品原价*数量" prop="price" width="150">
|
||||||
<div>
|
<template #default="{ row }">
|
||||||
<p>{{ item.spuName }}</p>
|
<!-- TODO @puhui999:价格,要有 xxx.00 这种格式 -->
|
||||||
<!-- TODO xiaobai: 是不是 (item.payPrice / 100.0).toFixed(2) -->
|
{{ formatToFraction(row.price) }} 元 * {{ row.count }}
|
||||||
<p>{{
|
</template>
|
||||||
'¥ ' +
|
</el-table-column>
|
||||||
parseFloat((item.payPrice / 100) as unknown as string).toFixed(2) +
|
<el-table-column label="合计" prop="payPrice" width="150">
|
||||||
'元 x ' +
|
<template #default="{ row }">{{ formatToFraction(row.payPrice) }}元</template>
|
||||||
item.count
|
</el-table-column>
|
||||||
}}</p>
|
<el-table-column label="售后状态" prop="afterSaleStatus" width="120">
|
||||||
</div>
|
<template #default="{ row }">
|
||||||
</div>
|
<dict-tag
|
||||||
</el-popover>
|
:type="DICT_TYPE.TRADE_ORDER_ITEM_AFTER_SALE_STATUS"
|
||||||
|
:value="row.afterSaleStatus"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="实际支付" min-width="120" prop="payPrice">
|
||||||
|
<template #default>
|
||||||
|
<!-- TODO @puhui999:价格,要有 xxx.00 这种格式 -->
|
||||||
|
{{ formatToFraction(scope.row.payPrice) + '元' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="买家/收货人" min-width="160">
|
||||||
|
<template #default>
|
||||||
|
<!-- 快递发货 -->
|
||||||
|
<div v-if="scope.row.deliveryType === 1" class="flex flex-col">
|
||||||
|
<span>买家:{{ scope.row.user.nickname }}</span>
|
||||||
|
<span>
|
||||||
|
收货人:{{ scope.row.receiverName }} {{ scope.row.receiverMobile }}
|
||||||
|
{{ scope.row.receiverAreaName }} {{ scope.row.receiverDetailAddress }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<!-- 自提 -->
|
||||||
|
<div v-if="scope.row.deliveryType === 2" class="flex flex-col">
|
||||||
|
<span>
|
||||||
|
门店名称:
|
||||||
|
{{ pickUpStoreList.find((p) => p.id === scope.row.pickUpStoreId)?.name }}
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
门店手机:
|
||||||
|
{{ pickUpStoreList.find((p) => p.id === scope.row.pickUpStoreId)?.phone }}
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
自提门店:
|
||||||
|
{{
|
||||||
|
pickUpStoreList.find((p) => p.id === scope.row.pickUpStoreId)?.detailAddress
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="配送方式" width="120">
|
||||||
|
<template #default>
|
||||||
|
<dict-tag :type="DICT_TYPE.TRADE_DELIVERY_TYPE" :value="scope.row.deliveryType" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" fixed="right" label="操作" width="160">
|
||||||
|
<template #default>
|
||||||
|
<!-- TODO 权限后续补齐 -->
|
||||||
|
<div class="flex justify-center items-center">
|
||||||
|
<el-button link type="primary" @click="openForm(scope.row.id)">
|
||||||
|
<Icon icon="ep:notification" />
|
||||||
|
详情
|
||||||
|
</el-button>
|
||||||
|
<el-dropdown @command="(command) => handleCommand(command, scope.row)">
|
||||||
|
<el-button link type="primary">
|
||||||
|
<Icon icon="ep:d-arrow-right" />
|
||||||
|
更多
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<!-- TODO puhui999:可以判断下状态 + 物流类型,展示【发货】按钮 -->
|
||||||
|
<el-dropdown-item command="delivery">
|
||||||
|
<Icon icon="ep:takeaway-box" />
|
||||||
|
发货
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="orderRemarks">
|
||||||
|
<Icon icon="ep:chat-line-square" />
|
||||||
|
订单备注
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="实际支付(元)" align="center" prop="payPrice" min-width="100">
|
<el-table-column align="center" label="订单号" min-width="110" prop="no" />
|
||||||
<template #default="scope">
|
<el-table-column align="center" label="订单类型" min-width="100">
|
||||||
{{ '¥ ' + parseFloat((scope.row.payPrice / 100) as unknown as string).toFixed(2) }}
|
<template #default="{ row }">
|
||||||
|
<dict-tag :type="DICT_TYPE.TRADE_ORDER_TYPE" :value="row.type" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="订单来源" min-width="145">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<dict-tag v-if="row.terminal" :type="DICT_TYPE.TERMINAL" :value="row.terminal" />
|
||||||
|
<span v-else>{{ row.terminal }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
:formatter="dateFormatter"
|
:formatter="dateFormatter"
|
||||||
align="center"
|
align="center"
|
||||||
label="支付时间"
|
label="支付时间"
|
||||||
prop="payTime"
|
|
||||||
min-width="180"
|
min-width="180"
|
||||||
|
prop="payTime"
|
||||||
/>
|
/>
|
||||||
<el-table-column label="支付类型" align="center" min-width="100" prop="payChannelCode">
|
<el-table-column align="center" label="支付类型" min-width="120" prop="payChannelCode">
|
||||||
<template #default="scope">
|
<template #default="{ row }">
|
||||||
<dict-tag
|
<dict-tag
|
||||||
v-if="scope.row.payChannelCode"
|
v-if="row.payChannelCode"
|
||||||
:type="DICT_TYPE.PAY_CHANNEL_CODE_TYPE"
|
:type="DICT_TYPE.PAY_CHANNEL_CODE"
|
||||||
:value="scope.row.payChannelCode"
|
:value="row.payChannelCode"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="订单状态" align="center" prop="status" min-width="100">
|
<el-table-column align="center" label="订单状态" min-width="100" prop="status">
|
||||||
<template #default="scope">
|
<template #default="{ row }">
|
||||||
<dict-tag
|
<dict-tag
|
||||||
v-if="scope.row.status !== ''"
|
v-if="row.status !== ''"
|
||||||
:type="DICT_TYPE.TRADE_ORDER_STATUS"
|
:type="DICT_TYPE.TRADE_ORDER_STATUS"
|
||||||
:value="scope.row.status"
|
:value="row.status"
|
||||||
/>
|
/>
|
||||||
<span v-else>{{ scope.status }}</span>
|
<span v-else>{{ row.status }}</span>
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="操作" align="center" fixed="right" min-width="150">
|
|
||||||
<template #default="scope">
|
|
||||||
<!-- <el-button v-if="scope.row.status == '0'" link type="primary" @click="sendXX(scope.row)"
|
|
||||||
>待支付</el-button> -->
|
|
||||||
<el-button v-if="scope.row.status == '10'" link type="primary" @click="sendXX(scope.row)"
|
|
||||||
>发货</el-button
|
|
||||||
>
|
|
||||||
<el-button link type="primary" @click="showOrderDetail(scope.row)">详情</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
align="center"
|
||||||
|
label="创建时间"
|
||||||
|
min-width="180"
|
||||||
|
prop="createTime"
|
||||||
|
/>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<Pagination
|
<Pagination
|
||||||
v-model:limit="queryParams.pageSize"
|
v-model:limit="queryParams.pageSize"
|
||||||
@ -268,305 +305,157 @@
|
|||||||
@pagination="getList"
|
@pagination="getList"
|
||||||
/>
|
/>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
<el-image-viewer
|
|
||||||
v-if="imgViewVisible"
|
<!-- 各种操作的弹窗 -->
|
||||||
:url-list="imageViewerList"
|
<DeliveryOrderForm ref="deliveryOrderFormRef" @success="getList" />
|
||||||
@close="imgViewVisible = false"
|
<OrderRemarksForm ref="orderRemarksFormRef" @success="getList" />
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts" name="OrderList">
|
|
||||||
import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
|
<script lang="ts" name="Order" setup>
|
||||||
|
import type { FormInstance, TableColumnCtx } from 'element-plus'
|
||||||
|
import DeliveryOrderForm from './components/DeliveryOrderForm.vue'
|
||||||
|
import OrderRemarksForm from './components/OrderRemarksForm.vue'
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
import * as TradeOrderApi from '@/api/mall/trade/order'
|
import * as TradeOrderApi from '@/api/mall/trade/order'
|
||||||
import {
|
// @puhui999:通过 TradeOrderApi 去引用对应的 VO 就可以啦
|
||||||
TradeOrderPageReqVO,
|
import { OrderItemRespVO, OrderVO } from '@/api/mall/trade/order'
|
||||||
SelectType,
|
// @puhui999:使用 XXXApi 哈
|
||||||
TradeOrderPageItemRespVO
|
import { getListAllSimple } from '@/api/mall/trade/delivery/pickUpStore'
|
||||||
} from '@/api/mall/trade/order/type/orderType'
|
import { DICT_TYPE, getStrDictOptions, getIntDictOptions } from '@/utils/dict'
|
||||||
import { dateFormatter, formatDate } from '@/utils/formatTime'
|
import { formatToFraction } from '@/utils'
|
||||||
import download from '@/utils/download'
|
import { createImageViewer } from '@/components/ImageViewer'
|
||||||
|
import * as DeliveryExpressApi from '@/api/mall/trade/delivery/express'
|
||||||
|
|
||||||
const message = useMessage()
|
const { currentRoute, push } = useRouter() // 路由跳转
|
||||||
const { push } = useRouter()
|
|
||||||
const imgViewVisible = ref(false) // 商品图预览
|
|
||||||
const imageViewerList = ref<string[]>([]) // 商品图预览列表
|
|
||||||
const queryFormRef = ref()
|
|
||||||
const loading = ref(false)
|
|
||||||
const exportLoading = ref(false)
|
|
||||||
const total = ref(0) // 总记录数
|
|
||||||
const list = ref<Array<TradeOrderPageItemRespVO | any>>([]) //表数据
|
|
||||||
|
|
||||||
// 选中状态选中处理
|
const loading = ref(true) // 列表的加载中
|
||||||
const orderSelect: SelectType = reactive({
|
const total = ref(2) // 列表的总页数
|
||||||
queryParams: {} as TradeOrderPageReqVO,
|
const list = ref<OrderVO[]>([]) // 列表的数据
|
||||||
selectTotal: 0,
|
const queryFormRef = ref<FormInstance>() // 搜索的表单
|
||||||
selectAllFlag: false,
|
// 表单搜索
|
||||||
selectData: new Map<number, Set<string>>(),
|
const queryParams = reactive({
|
||||||
unSelectList: new Set<string>()
|
|
||||||
})
|
|
||||||
|
|
||||||
//表单搜索
|
|
||||||
const queryParams: TradeOrderPageReqVO = reactive({
|
|
||||||
pageNo: 1, //首页
|
pageNo: 1, //首页
|
||||||
pageSize: 10 //页面大小
|
pageSize: 10, //页面大小
|
||||||
|
no: '',
|
||||||
|
userId: '',
|
||||||
|
userNickname: '',
|
||||||
|
userMobile: '',
|
||||||
|
receiverName: '',
|
||||||
|
receiverMobile: '',
|
||||||
|
terminal: '',
|
||||||
|
type: null,
|
||||||
|
status: null,
|
||||||
|
payChannelCode: '',
|
||||||
|
createTime: [],
|
||||||
|
spuName: '',
|
||||||
|
itemCount: '',
|
||||||
|
pickUpStoreId: [],
|
||||||
|
logisticsId: null,
|
||||||
|
all: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
const queryType = reactive({ k: '', v: '' }) // 订单搜索类型kv
|
const queryType = reactive({ k: '', v: '' }) // 订单搜索类型kv
|
||||||
|
/**
|
||||||
/*
|
* 订单聚合搜索
|
||||||
* 订单搜索
|
* 商品名称、商品件数、全部
|
||||||
* 商品名称 商品件数 全部 需要后端支持TODO
|
*
|
||||||
|
* 需要后端支持 TODO
|
||||||
*/
|
*/
|
||||||
const searchList = ref([
|
const searchList = ref([
|
||||||
{ value: 'no', label: '订单号' },
|
{ value: 'no', label: '订单号' },
|
||||||
{ value: 'userId', label: '用户UID' },
|
{ value: 'userId', label: '用户UID' },
|
||||||
{ value: 'userNickname', label: '用户昵称' },
|
{ value: 'userNickname', label: '用户昵称' },
|
||||||
{ value: 'userMobile', label: '用户电话' },
|
{ value: 'userMobile', label: '用户电话' }
|
||||||
{ value: 'spuName', label: '商品名称TODO' },
|
|
||||||
{ value: 'itemCount', label: '商品件数TODO' }
|
|
||||||
])
|
])
|
||||||
|
|
||||||
/**
|
interface SpanMethodProps {
|
||||||
|
row: OrderItemRespVO
|
||||||
当前页/? 如果pageNo存在,则将但前数据全部按照单个选中模式取消 ,不存在,则新增全页 增加 Map.pageNo Map.roderNoList
|
column: TableColumnCtx<OrderItemRespVO>
|
||||||
单个选中 如果pagelist存在,订单号选中状态取反,并对总数按选中状态加减。如果pagelist不存在,订单号选中状态取反,并对总数按选中状态加减,增加 Map.pageNo,
|
rowIndex: number
|
||||||
如果当前Map.pageNo 所对应list 为空 ,清除pageNo
|
columnIndex: number
|
||||||
* @param command ===1 当前页 选中 ===2 所有页面选中
|
}
|
||||||
*/
|
const spanMethod = ({ rowIndex, columnIndex }: SpanMethodProps) => {
|
||||||
const handleDropType = (command: string) => {
|
const colIndex = [4, 5, 6, 7]
|
||||||
let i = 0
|
// 处理列
|
||||||
//当前页按钮
|
if (colIndex.includes(columnIndex)) {
|
||||||
if (command === '1') {
|
// 处理被合并的行
|
||||||
//如果该页面有选中数据 则选中事件触发时 取消该页面
|
if (rowIndex !== 0) {
|
||||||
if (orderSelect.selectData && orderSelect.selectData.has(queryParams.pageNo)) {
|
return {
|
||||||
for (i = 0; i < list.value.length; i++) {
|
rowspan: 0,
|
||||||
if (orderSelect.selectData.get(queryParams.pageNo)!.has(list.value[i].id)) {
|
colspan: 0
|
||||||
//选中数量减少
|
|
||||||
orderSelect.selectTotal -= 1
|
|
||||||
//考虑全选中,针对某一页面选中当前页时 会将所有数据中去掉该页面, 需要登记到 orderSelect.unSelectList
|
|
||||||
unSelectListRecord(list.value[i].id, 'add')
|
|
||||||
}
|
|
||||||
list.value[i]['itemSelect'] = false
|
|
||||||
}
|
|
||||||
orderSelect.selectData.delete(queryParams.pageNo) //移除该页面
|
|
||||||
} else {
|
|
||||||
//当前页选中状态中 默认全选中
|
|
||||||
orderSelect.selectData.set(queryParams.pageNo, new Set<string>())
|
|
||||||
for (i = 0; i < list.value.length; i++) {
|
|
||||||
list.value[i]['itemSelect'] = true
|
|
||||||
orderSelect.selectData.get(queryParams.pageNo)!.add(list.value[i].id)
|
|
||||||
//选中数量增加
|
|
||||||
orderSelect.selectTotal += 1
|
|
||||||
//对于登记过取消状态中的数据排除
|
|
||||||
unSelectListRecord(list.value[i].id, 'del')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return {
|
||||||
//所有页按钮
|
rowspan: 2,
|
||||||
if (command === '2') {
|
colspan: 1
|
||||||
orderSelect.selectAllFlag = !orderSelect.selectAllFlag
|
|
||||||
|
|
||||||
if (orderSelect.selectAllFlag) {
|
|
||||||
//打勾勾 //全选
|
|
||||||
orderSelect.selectData?.set(queryParams.pageNo, new Set<string>())
|
|
||||||
for (i = 0; i < list.value.length; i++) {
|
|
||||||
list.value[i]['itemSelect'] = true
|
|
||||||
orderSelect.selectData?.get(queryParams.pageNo)?.add(list.value[i].id) //id是主键不重复
|
|
||||||
}
|
|
||||||
orderSelect.selectTotal = total.value
|
|
||||||
} else {
|
|
||||||
//取消勾勾
|
|
||||||
for (i; i < list.value.length; i++) {
|
|
||||||
list.value[i]['itemSelect'] = false
|
|
||||||
}
|
|
||||||
initSelect() //重置之前选中的类容清空
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//对全选状态中的 单选或者当前页面单选时登记取消的数据
|
/** 查询列表 */
|
||||||
const unSelectListRecord = (id: string, op: string) => {
|
|
||||||
if (!orderSelect.selectAllFlag) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (op == 'add') {
|
|
||||||
orderSelect.unSelectList.add(id)
|
|
||||||
} else {
|
|
||||||
orderSelect.unSelectList.delete(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/***复选框选中 */
|
|
||||||
const handcheckclick = (row: any) => {
|
|
||||||
if (row.itemSelect) {
|
|
||||||
orderSelect.selectTotal += 1
|
|
||||||
if (!orderSelect.selectData.has(queryParams.pageNo)) {
|
|
||||||
orderSelect.selectData?.set(queryParams.pageNo, new Set<string>())
|
|
||||||
}
|
|
||||||
orderSelect.selectData?.get(queryParams.pageNo)?.add(row.id)
|
|
||||||
unSelectListRecord(row.id, 'del')
|
|
||||||
} else {
|
|
||||||
orderSelect.selectTotal -= 1
|
|
||||||
orderSelect.selectData.get(queryParams.pageNo)?.delete(row.id)
|
|
||||||
unSelectListRecord(row.id, 'add')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 导出数据
|
|
||||||
*/
|
|
||||||
|
|
||||||
const handleExport = async () => {
|
|
||||||
try {
|
|
||||||
// 导出的二次确认
|
|
||||||
await message.exportConfirm()
|
|
||||||
//增加查询条件 用于全选时后台查询数据
|
|
||||||
orderSelect.queryParams = queryParams
|
|
||||||
|
|
||||||
// 发起导出
|
|
||||||
exportLoading.value = true
|
|
||||||
//全选时 根据上送的条件查询所有数据,在排除unseleectList 数据,
|
|
||||||
//非全选时, 根据上送的selectData 直接查询数据 后台实现导出数据接口即可
|
|
||||||
console.log(orderSelect)
|
|
||||||
download.excel(orderSelect as any, '订单信息.xls') //?
|
|
||||||
} catch {
|
|
||||||
} finally {
|
|
||||||
exportLoading.value = false
|
|
||||||
}
|
|
||||||
//TODO
|
|
||||||
exportLoading.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 搜索按钮操作 */
|
|
||||||
const handleQuery = () => {
|
|
||||||
getList()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 重置按钮操作 */
|
|
||||||
const resetQuery = () => {
|
|
||||||
queryFormRef.value.resetFields()
|
|
||||||
queryType.v = '' //重置
|
|
||||||
queryType.k = ''
|
|
||||||
//休眠0.1s 等待watch响应
|
|
||||||
setTimeout(() => {
|
|
||||||
initSelect() //重置对选中设置恢复初始状态
|
|
||||||
handleQuery()
|
|
||||||
}, 100)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**选中状态初始化**/
|
|
||||||
const initSelect = () => {
|
|
||||||
orderSelect.queryParams = {} as TradeOrderPageReqVO
|
|
||||||
orderSelect.selectTotal = 0
|
|
||||||
orderSelect.selectAllFlag = false
|
|
||||||
orderSelect.selectData?.clear()
|
|
||||||
orderSelect.unSelectList?.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
const getList = async () => {
|
const getList = async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const data = await TradeOrderApi.getOrderList(queryParams)
|
const data = await TradeOrderApi.getOrderPage(queryParams)
|
||||||
list.value = data.list
|
list.value = data.list
|
||||||
total.value = data.total
|
total.value = data.total
|
||||||
let i = 0
|
|
||||||
if (orderSelect.selectData && orderSelect.selectData.has(queryParams.pageNo)) {
|
|
||||||
//该页面已经加载过了。直接按照之前状态设置选中状态值
|
|
||||||
for (i = 0; i < list.value.length; i++) {
|
|
||||||
if (orderSelect.selectData.get(queryParams.pageNo)!.has(list.value[i].id)) {
|
|
||||||
list.value[i]['itemSelect'] = true //之前已经选取过了
|
|
||||||
} else {
|
|
||||||
list.value[i]['itemSelect'] = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (orderSelect.selectAllFlag) {
|
|
||||||
//全选状态中 首次加载页面 默认全部选中
|
|
||||||
orderSelect.selectData.set(queryParams.pageNo, new Set<string>())
|
|
||||||
for (i = 0; i < list.value.length; i++) {
|
|
||||||
list.value[i]['itemSelect'] = true
|
|
||||||
orderSelect.selectData.get(queryParams.pageNo)!.add(list.value[i].id)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//非全选状态中 首次加载默认非选中状态
|
|
||||||
for (i; i < list.value.length; i++) {
|
|
||||||
list.value[i]['itemSelect'] = false //设置状态为未选中状态
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 搜索按钮操作 */
|
||||||
* 跳转订单详情
|
const handleQuery = () => {
|
||||||
*/
|
queryParams.pageNo = 1
|
||||||
const showOrderDetail = (row: any) => {
|
getList()
|
||||||
push({ name: 'TradeOrderDetail', query: { id: row.id } })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 重置按钮操作 */
|
||||||
* 跳转用户详情
|
const resetQuery = () => {
|
||||||
*/
|
queryFormRef.value?.resetFields()
|
||||||
const goUserDetail = (row: any) => {
|
handleQuery()
|
||||||
console.log('TODO User Detail: ' + row.userId)
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 发货
|
|
||||||
*/
|
|
||||||
const sendXX = (row: any) => {
|
|
||||||
console.log('TODO Send XX: ' + row.no)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 商品图预览 */
|
||||||
* 商品图预览
|
|
||||||
* @param imgUrl
|
|
||||||
*/
|
|
||||||
const imagePreview = (imgUrl: string) => {
|
const imagePreview = (imgUrl: string) => {
|
||||||
imageViewerList.value = [imgUrl]
|
createImageViewer({
|
||||||
imgViewVisible.value = true
|
urlList: [imgUrl]
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//针对订单搜索类型和值进行调整 使用监听器
|
/** 查看商品详情 */
|
||||||
|
const openForm = (id: number) => {
|
||||||
|
// TODO @puhui999:这里最好用 name 来跳转,因为 url 可能会改
|
||||||
|
push('/trade/order/detail/' + id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 操作分发 */
|
||||||
|
const deliveryOrderFormRef = ref()
|
||||||
|
const orderRemarksFormRef = ref()
|
||||||
|
const handleCommand = (command: string, row: OrderVO) => {
|
||||||
|
switch (command) {
|
||||||
|
case 'orderRemarks': // TODO @puhui999:orderRemarks 是不是改成 remark 会好点,保持统一
|
||||||
|
orderRemarksFormRef.value?.open(row)
|
||||||
|
break
|
||||||
|
case 'delivery':
|
||||||
|
deliveryOrderFormRef.value?.open(row.id)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听路由变化更新列表,解决商品保存后,列表不刷新的问题。
|
||||||
watch(
|
watch(
|
||||||
() => [queryType.k, queryType.v],
|
() => currentRoute.value,
|
||||||
([newK, newV], [oldK]) => {
|
() => {
|
||||||
//重置oldK对应得value
|
getList()
|
||||||
if (oldK != newK) {
|
|
||||||
if (oldK == 'no' && queryParams.no != '') {
|
|
||||||
queryParams.no = ''
|
|
||||||
} else if (oldK == 'userId' && queryParams.userId != '') {
|
|
||||||
queryParams.userId = ''
|
|
||||||
} else if (oldK == 'userNickname' && queryParams.userNickname != '') {
|
|
||||||
queryParams.userNickname = ''
|
|
||||||
} else if (oldK == 'userMobile' && queryParams.userMobile !== '') {
|
|
||||||
queryParams.userMobile = ''
|
|
||||||
} else if (oldK == 'spuName' && queryParams.spuName !== '') {
|
|
||||||
queryParams.spuName = ''
|
|
||||||
} else if (oldK == 'itemCount' && queryParams.itemCount !== '') {
|
|
||||||
queryParams.itemCount = ''
|
|
||||||
} else if (oldK == '' && queryParams.all !== '') {
|
|
||||||
queryParams.all = ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 根据选中得k设置Value
|
|
||||||
if (newK == 'no') {
|
|
||||||
queryParams.no = newV
|
|
||||||
} else if (newK == 'userId') {
|
|
||||||
queryParams.userId = newV
|
|
||||||
} else if (newK == 'userNickname') {
|
|
||||||
queryParams.userNickname = newV
|
|
||||||
} else if (newK == 'userMobile') {
|
|
||||||
queryParams.userMobile = newV
|
|
||||||
} else if (newK == 'spuName') {
|
|
||||||
queryParams.spuName = newV
|
|
||||||
} else if (newK == 'itemCount') {
|
|
||||||
queryParams.itemCount = newV
|
|
||||||
} else if (newK == '') {
|
|
||||||
queryParams.all = newV
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const pickUpStoreList = ref([]) // 自提门店精简列表
|
||||||
|
const deliveryExpressList = ref([]) // 物流公司
|
||||||
/** 初始化 **/
|
/** 初始化 **/
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
initSelect()
|
await getList()
|
||||||
getList()
|
pickUpStoreList.value = await getListAllSimple()
|
||||||
|
deliveryExpressList.value = await DeliveryExpressApi.getSimpleDeliveryExpressList()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@ -10,9 +10,6 @@
|
|||||||
<el-form-item label="名称" prop="name">
|
<el-form-item label="名称" prop="name">
|
||||||
<el-input v-model="formData.name" placeholder="请输入名称" />
|
<el-input v-model="formData.name" placeholder="请输入名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="备注" prop="remark">
|
|
||||||
<el-input v-model="formData.remark" type="textarea" placeholder="请输入备注" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="状态" prop="status">
|
<el-form-item label="状态" prop="status">
|
||||||
<el-radio-group v-model="formData.status">
|
<el-radio-group v-model="formData.status">
|
||||||
<el-radio
|
<el-radio
|
||||||
@ -24,6 +21,9 @@
|
|||||||
</el-radio>
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input v-model="formData.remark" type="textarea" placeholder="请输入备注" />
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import * as GroupApi from '@/api/member/group'
|
import * as GroupApi from '@/api/member/group'
|
||||||
|
|
||||||
|
@ -38,9 +38,9 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="享受折扣(%)" prop="discount">
|
<el-form-item label="享受折扣(%)" prop="discountPercent">
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-model="formData.discount"
|
v-model="formData.discountPercent"
|
||||||
:min="0"
|
:min="0"
|
||||||
:max="100"
|
:max="100"
|
||||||
:precision="0"
|
:precision="0"
|
||||||
@ -100,7 +100,7 @@ const formData = ref({
|
|||||||
name: undefined,
|
name: undefined,
|
||||||
experience: undefined,
|
experience: undefined,
|
||||||
level: undefined,
|
level: undefined,
|
||||||
discount: undefined,
|
discountPercent: undefined,
|
||||||
icon: undefined,
|
icon: undefined,
|
||||||
backgroundUrl: undefined,
|
backgroundUrl: undefined,
|
||||||
status: CommonStatusEnum.ENABLE
|
status: CommonStatusEnum.ENABLE
|
||||||
@ -109,7 +109,7 @@ const formRules = reactive({
|
|||||||
name: [{ required: true, message: '等级名称不能为空', trigger: 'blur' }],
|
name: [{ required: true, message: '等级名称不能为空', trigger: 'blur' }],
|
||||||
experience: [{ required: true, message: '升级经验不能为空', trigger: 'blur' }],
|
experience: [{ required: true, message: '升级经验不能为空', trigger: 'blur' }],
|
||||||
level: [{ required: true, message: '等级不能为空', trigger: 'blur' }],
|
level: [{ required: true, message: '等级不能为空', trigger: 'blur' }],
|
||||||
discount: [{ required: true, message: '享受折扣不能为空', trigger: 'blur' }],
|
discountPercent: [{ required: true, message: '享受折扣不能为空', trigger: 'blur' }],
|
||||||
status: [{ required: true, message: '状态不能为空', trigger: 'change' }]
|
status: [{ required: true, message: '状态不能为空', trigger: 'change' }]
|
||||||
})
|
})
|
||||||
const formRef = ref() // 表单 Ref
|
const formRef = ref() // 表单 Ref
|
||||||
@ -165,7 +165,7 @@ const resetForm = () => {
|
|||||||
name: undefined,
|
name: undefined,
|
||||||
experience: undefined,
|
experience: undefined,
|
||||||
level: undefined,
|
level: undefined,
|
||||||
discount: undefined,
|
discountPercent: undefined,
|
||||||
icon: undefined,
|
icon: undefined,
|
||||||
backgroundUrl: undefined,
|
backgroundUrl: undefined,
|
||||||
status: CommonStatusEnum.ENABLE
|
status: CommonStatusEnum.ENABLE
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import * as LevelApi from '@/api/member/level'
|
import * as LevelApi from '@/api/member/level'
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
<el-table-column label="等级名称" align="center" prop="name" min-width="100" />
|
<el-table-column label="等级名称" align="center" prop="name" min-width="100" />
|
||||||
<el-table-column label="等级" align="center" prop="level" min-width="60" />
|
<el-table-column label="等级" align="center" prop="level" min-width="60" />
|
||||||
<el-table-column label="升级经验" align="center" prop="experience" min-width="80" />
|
<el-table-column label="升级经验" align="center" prop="experience" min-width="80" />
|
||||||
<el-table-column label="享受折扣(%)" align="center" prop="discount" min-width="110" />
|
<el-table-column label="享受折扣(%)" align="center" prop="discountPercent" min-width="110" />
|
||||||
<el-table-column label="状态" align="center" prop="status" min-width="70">
|
<el-table-column label="状态" align="center" prop="status" min-width="70">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import * as ConfigApi from '@/api/point/config'
|
import * as ConfigApi from '@/api/member/point/config'
|
||||||
|
|
||||||
defineOptions({ name: 'MemberPointConfig' })
|
defineOptions({ name: 'MemberPointConfig' })
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
class="!w-240px"
|
class="!w-240px"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getStrDictOptions(DICT_TYPE.MEMBER_POINT_BIZ_TYPE)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.MEMBER_POINT_BIZ_TYPE)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
:value="dict.value"
|
:value="dict.value"
|
||||||
@ -41,16 +41,6 @@
|
|||||||
class="!w-240px"
|
class="!w-240px"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="积分状态" prop="status">
|
|
||||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable class="!w-240px">
|
|
||||||
<el-option
|
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.MEMBER_POINT_STATUS)"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="获得时间" prop="createDate">
|
<el-form-item label="获得时间" prop="createDate">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="queryParams.createDate"
|
v-model="queryParams.createDate"
|
||||||
@ -78,48 +68,32 @@
|
|||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table v-loading="loading" :data="list">
|
<el-table v-loading="loading" :data="list">
|
||||||
<el-table-column label="编号" align="center" prop="id" />
|
<el-table-column label="编号" align="center" prop="id" width="180" />
|
||||||
<el-table-column label="用户" align="center" prop="nickname" />
|
|
||||||
<el-table-column label="积分标题" align="center" prop="title" />
|
|
||||||
<el-table-column label="积分描述" align="center" prop="description" />
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="获得时间"
|
label="获得时间"
|
||||||
align="center"
|
align="center"
|
||||||
prop="createTime"
|
prop="createTime"
|
||||||
:formatter="dateFormatter"
|
:formatter="dateFormatter"
|
||||||
|
width="180"
|
||||||
/>
|
/>
|
||||||
<el-table-column label="积分" align="center" prop="point">
|
<el-table-column label="用户" align="center" prop="nickname" width="200" />
|
||||||
|
<el-table-column label="获得积分" align="center" prop="point" width="100">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag v-if="scope.row.point > 0" class="ml-2" type="success" effect="dark">
|
<el-tag v-if="scope.row.point > 0" class="ml-2" type="success" effect="dark">
|
||||||
{{ scope.row.point }}
|
+{{ scope.row.point }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<el-tag v-else class="ml-2" type="danger" effect="dark"> {{ scope.row.point }} </el-tag>
|
<el-tag v-else class="ml-2" type="danger" effect="dark"> {{ scope.row.point }} </el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="变动后的积分" align="center" prop="totalPoint" />
|
<el-table-column label="总积分" align="center" prop="totalPoint" width="100" />
|
||||||
|
<el-table-column label="标题" align="center" prop="title" />
|
||||||
|
<el-table-column label="描述" align="center" prop="description" />
|
||||||
<el-table-column label="业务编码" align="center" prop="bizId" />
|
<el-table-column label="业务编码" align="center" prop="bizId" />
|
||||||
<el-table-column label="业务类型" align="center" prop="bizType">
|
<el-table-column label="业务类型" align="center" prop="bizType">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.MEMBER_POINT_BIZ_TYPE" :value="scope.row.bizType" />
|
<dict-tag :type="DICT_TYPE.MEMBER_POINT_BIZ_TYPE" :value="scope.row.bizType" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="状态" align="center" prop="status">
|
|
||||||
<template #default="scope">
|
|
||||||
<dict-tag :type="DICT_TYPE.MEMBER_POINT_STATUS" :value="scope.row.status" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
label="冻结时间"
|
|
||||||
align="center"
|
|
||||||
prop="freezingTime"
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
/>
|
|
||||||
<el-table-column
|
|
||||||
label="解冻时间"
|
|
||||||
align="center"
|
|
||||||
prop="thawingTime"
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
/>
|
|
||||||
</el-table>
|
</el-table>
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<Pagination
|
<Pagination
|
||||||
@ -135,9 +109,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { DICT_TYPE, getStrDictOptions, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
import * as RecordApi from '@/api/point/record'
|
import * as RecordApi from '@/api//member/point/record'
|
||||||
|
|
||||||
defineOptions({ name: 'PointRecord' })
|
defineOptions({ name: 'PointRecord' })
|
||||||
|
|
||||||
@ -149,9 +123,7 @@ const queryParams = reactive({
|
|||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
nickname: null,
|
nickname: null,
|
||||||
bizType: null,
|
bizType: null,
|
||||||
type: null,
|
|
||||||
title: null,
|
title: null,
|
||||||
status: null,
|
|
||||||
createDate: []
|
createDate: []
|
||||||
})
|
})
|
||||||
const queryFormRef = ref() // 搜索的表单
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
@ -10,12 +10,23 @@
|
|||||||
<el-form-item label="签到天数" prop="day">
|
<el-form-item label="签到天数" prop="day">
|
||||||
<el-input-number v-model="formData.day" :min="1" :max="7" :precision="0" />
|
<el-input-number v-model="formData.day" :min="1" :max="7" :precision="0" />
|
||||||
<el-text class="mx-1" style="margin-left: 10px" type="danger">
|
<el-text class="mx-1" style="margin-left: 10px" type="danger">
|
||||||
只允许设置1-7,默认签到7天为一个周期</el-text
|
只允许设置 1-7,默认签到 7 天为一个周期
|
||||||
>
|
</el-text>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="签到分数" prop="point">
|
<el-form-item label="签到分数" prop="point">
|
||||||
<el-input-number v-model="formData.point" :precision="0" />
|
<el-input-number v-model="formData.point" :precision="0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="开启状态" prop="status">
|
||||||
|
<el-radio-group v-model="formData.status">
|
||||||
|
<el-radio
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
@ -24,7 +35,9 @@
|
|||||||
</Dialog>
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import * as SignInConfigApi from '@/api/point/signInConfig'
|
import * as SignInConfigApi from '@/api/member/signin/config'
|
||||||
|
import { CommonStatusEnum } from '@/utils/constants'
|
||||||
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
@ -92,7 +105,8 @@ const resetForm = () => {
|
|||||||
formData.value = {
|
formData.value = {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
day: undefined,
|
day: undefined,
|
||||||
point: undefined
|
point: undefined,
|
||||||
|
status: CommonStatusEnum.ENABLE
|
||||||
}
|
}
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
@ -21,17 +21,9 @@
|
|||||||
:formatter="(_, __, cellValue) => ['第', cellValue, '天'].join(' ')"
|
:formatter="(_, __, cellValue) => ['第', cellValue, '天'].join(' ')"
|
||||||
/>
|
/>
|
||||||
<el-table-column label="获得积分" align="center" prop="point" />
|
<el-table-column label="获得积分" align="center" prop="point" />
|
||||||
<el-table-column label="是否开启" align="center">
|
<el-table-column label="状态" align="center" prop="status">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div>
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||||
<el-switch
|
|
||||||
v-model="scope.row.enable"
|
|
||||||
@change="handleSwitchChange(scope.row, $event)"
|
|
||||||
inline-prompt
|
|
||||||
active-text="开启"
|
|
||||||
inactive-text="关闭"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" align="center">
|
<el-table-column label="操作" align="center">
|
||||||
@ -60,11 +52,10 @@
|
|||||||
<!-- 表单弹窗:添加/修改 -->
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
<SignInConfigForm ref="formRef" @success="getList" />
|
<SignInConfigForm ref="formRef" @success="getList" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import * as SignInConfigApi from '@/api/point/signInConfig'
|
import * as SignInConfigApi from '@/api/member/signin/config'
|
||||||
import SignInConfigForm from './SignInConfigForm.vue'
|
import SignInConfigForm from './SignInConfigForm.vue'
|
||||||
import { SignInConfigVO } from '@/api/point/signInConfig'
|
import { DICT_TYPE } from '@/utils/dict'
|
||||||
|
|
||||||
defineOptions({ name: 'SignInConfig' })
|
defineOptions({ name: 'SignInConfig' })
|
||||||
|
|
||||||
@ -78,7 +69,7 @@ const list = ref([]) // 列表的数据
|
|||||||
const getList = async () => {
|
const getList = async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const data = await SignInConfigApi.getSignInConfigPage()
|
const data = await SignInConfigApi.getSignInConfigList()
|
||||||
console.log(data)
|
console.log(data)
|
||||||
list.value = data
|
list.value = data
|
||||||
} finally {
|
} finally {
|
||||||
@ -105,14 +96,6 @@ const handleDelete = async (id: number) => {
|
|||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSwitchChange = async (row, e) => {
|
|
||||||
console.log('开关状态变更,id:', row, '新状态:', e)
|
|
||||||
// 创建对象
|
|
||||||
const signInConfig: SignInConfigVO = { enable: e }
|
|
||||||
;({ id: signInConfig.id, day: signInConfig.day, point: signInConfig.point, enable: e } = row)
|
|
||||||
await SignInConfigApi.updateSignInConfig(signInConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 初始化 **/
|
/** 初始化 **/
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList()
|
getList()
|
||||||
|
@ -40,15 +40,6 @@
|
|||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
<el-button
|
|
||||||
type="success"
|
|
||||||
plain
|
|
||||||
@click="handleExport"
|
|
||||||
:loading="exportLoading"
|
|
||||||
v-hasPermi="['point:sign-in-record:export']"
|
|
||||||
>
|
|
||||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
@ -57,7 +48,6 @@
|
|||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table v-loading="loading" :data="list">
|
<el-table v-loading="loading" :data="list">
|
||||||
<el-table-column label="编号" align="center" prop="id" />
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
<!-- TODO @xiaqing:展示用户昵称 -->
|
|
||||||
<el-table-column label="签到用户" align="center" prop="nickname" />
|
<el-table-column label="签到用户" align="center" prop="nickname" />
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="签到天数"
|
label="签到天数"
|
||||||
@ -65,7 +55,14 @@
|
|||||||
prop="day"
|
prop="day"
|
||||||
:formatter="(_, __, cellValue) => ['第', cellValue, '天'].join(' ')"
|
:formatter="(_, __, cellValue) => ['第', cellValue, '天'].join(' ')"
|
||||||
/>
|
/>
|
||||||
<el-table-column label="获得积分" align="center" prop="point" />
|
<el-table-column label="获得积分" align="center" prop="point" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.point > 0" class="ml-2" type="success" effect="dark">
|
||||||
|
+{{ scope.row.point }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag v-else class="ml-2" type="danger" effect="dark"> {{ scope.row.point }} </el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="签到时间"
|
label="签到时间"
|
||||||
align="center"
|
align="center"
|
||||||
@ -81,15 +78,11 @@
|
|||||||
@pagination="getList"
|
@pagination="getList"
|
||||||
/>
|
/>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
<!-- 表单弹窗:添加/修改 -->
|
|
||||||
<SignInRecordForm ref="formRef" @success="getList" />
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
import download from '@/utils/download'
|
import * as SignInRecordApi from '@/api/member/signin/record'
|
||||||
import * as SignInRecordApi from '@/api/point/signInRecord'
|
|
||||||
|
|
||||||
defineOptions({ name: 'SignInRecord' })
|
defineOptions({ name: 'SignInRecord' })
|
||||||
|
|
||||||
@ -132,21 +125,6 @@ const resetQuery = () => {
|
|||||||
handleQuery()
|
handleQuery()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 导出按钮操作 */
|
|
||||||
const handleExport = async () => {
|
|
||||||
try {
|
|
||||||
// 导出的二次确认
|
|
||||||
await message.exportConfirm()
|
|
||||||
// 发起导出
|
|
||||||
exportLoading.value = true
|
|
||||||
const data = await SignInRecordApi.exportSignInRecord(queryParams)
|
|
||||||
download.excel(data, '用户签到积分.xls')
|
|
||||||
} catch {
|
|
||||||
} finally {
|
|
||||||
exportLoading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 初始化 **/
|
/** 初始化 **/
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList()
|
getList()
|
||||||
|
61
src/views/member/user/components/account-info.vue
Normal file
61
src/views/member/user/components/account-info.vue
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<template>
|
||||||
|
<el-descriptions :column="2">
|
||||||
|
<!-- TODO @梦:要不 icon 也给加下? -->
|
||||||
|
<!-- TODO @梦:积分、成长值、等级,已经可以读取了,可以看下 -->
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template #label>
|
||||||
|
<div class="cell-item"> 等级 </div>
|
||||||
|
</template>
|
||||||
|
{{ 0 }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template #label>
|
||||||
|
<div class="cell-item"> 成长值 </div>
|
||||||
|
</template>
|
||||||
|
{{ 0 }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template #label>
|
||||||
|
<div class="cell-item"> 当前积分 </div>
|
||||||
|
</template>
|
||||||
|
{{ 0 }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template #label>
|
||||||
|
<div class="cell-item"> 总积分 </div>
|
||||||
|
</template>
|
||||||
|
{{ 0 }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template #label>
|
||||||
|
<div class="cell-item"> 当前余额 </div>
|
||||||
|
</template>
|
||||||
|
{{ 0 }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template #label>
|
||||||
|
<div class="cell-item"> 支出金额 </div>
|
||||||
|
</template>
|
||||||
|
{{ 0 }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template #label>
|
||||||
|
<div class="cell-item"> 充值金额 </div>
|
||||||
|
</template>
|
||||||
|
{{ 0 }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
defineComponent({
|
||||||
|
name: 'AccountInfo'
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.cell-item {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
.cell-item::after {
|
||||||
|
content: ':';
|
||||||
|
}
|
||||||
|
</style>
|
14
src/views/member/user/components/address-list.vue
Normal file
14
src/views/member/user/components/address-list.vue
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'AddressList'
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- TODO @梦:可以读 address 表 -->
|
||||||
|
<template>
|
||||||
|
<div>收货地址列表</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
14
src/views/member/user/components/balance-list.vue
Normal file
14
src/views/member/user/components/balance-list.vue
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'BalanceList'
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- TODO @芋艿:未来实现,等周建的 -->
|
||||||
|
<template>
|
||||||
|
<div>余额列表</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
36
src/views/member/user/components/card-title.vue
Normal file
36
src/views/member/user/components/card-title.vue
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
defineComponent({
|
||||||
|
name: 'CardTitle'
|
||||||
|
})
|
||||||
|
|
||||||
|
const { title } = defineProps({
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<span class="card-title">{{ title }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.card-title {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
width: 3px;
|
||||||
|
height: 14px;
|
||||||
|
//background-color: #105cfb;
|
||||||
|
background: var(--el-color-primary);
|
||||||
|
position: relative;
|
||||||
|
left: -5px;
|
||||||
|
top: 8px;
|
||||||
|
border-radius: 5px;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
14
src/views/member/user/components/growth-list.vue
Normal file
14
src/views/member/user/components/growth-list.vue
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'GrowthList'
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- TODO @梦:可以读取 member_experience_log 表 -->
|
||||||
|
<template>
|
||||||
|
<div>成长值列表</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
156
src/views/member/user/components/point-list.vue
Normal file
156
src/views/member/user/components/point-list.vue
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
<template>
|
||||||
|
<ContentWrap>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form
|
||||||
|
class="-mb-15px"
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryFormRef"
|
||||||
|
:inline="true"
|
||||||
|
label-width="68px"
|
||||||
|
>
|
||||||
|
<el-form-item label="业务类型" prop="bizType">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.bizType"
|
||||||
|
placeholder="请选择业务类型"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.MEMBER_POINT_BIZ_TYPE)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="积分标题" prop="title">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.title"
|
||||||
|
placeholder="请输入积分标题"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="获得时间" prop="createDate">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.createDate"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleQuery">
|
||||||
|
<Icon icon="ep:search" class="mr-5px" />
|
||||||
|
搜索
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="resetQuery">
|
||||||
|
<Icon icon="ep:refresh" class="mr-5px" />
|
||||||
|
重置
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table v-loading="loading" :data="list">
|
||||||
|
<el-table-column label="编号" align="center" prop="id" width="180" />
|
||||||
|
<el-table-column
|
||||||
|
label="获得时间"
|
||||||
|
align="center"
|
||||||
|
prop="createTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180"
|
||||||
|
/>
|
||||||
|
<el-table-column label="用户" align="center" prop="nickname" width="200" />
|
||||||
|
<el-table-column label="获得积分" align="center" prop="point" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.point > 0" class="ml-2" type="success" effect="dark">
|
||||||
|
+{{ scope.row.point }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag v-else class="ml-2" type="danger" effect="dark"> {{ scope.row.point }} </el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="总积分" align="center" prop="totalPoint" width="100" />
|
||||||
|
<el-table-column label="标题" align="center" prop="title" />
|
||||||
|
<el-table-column label="描述" align="center" prop="description" />
|
||||||
|
<el-table-column label="业务编码" align="center" prop="bizId" />
|
||||||
|
<el-table-column label="业务类型" align="center" prop="bizType">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.MEMBER_POINT_BIZ_TYPE" :value="scope.row.bizType" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</ContentWrap>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import * as RecordApi from '@/api//member/point/record'
|
||||||
|
|
||||||
|
defineOptions({ name: 'PointList' })
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
const list = ref([]) // 列表的数据
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
bizType: undefined,
|
||||||
|
title: null,
|
||||||
|
createDate: [],
|
||||||
|
userId: null
|
||||||
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const data = await RecordApi.getRecordPage(queryParams)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO @梦:改成 userId 哈
|
||||||
|
const { memberId } = defineProps({
|
||||||
|
memberId: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(() => {
|
||||||
|
queryParams.userId = memberId
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
</script>
|
138
src/views/member/user/components/sign-list.vue
Normal file
138
src/views/member/user/components/sign-list.vue
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
<template>
|
||||||
|
<ContentWrap>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form
|
||||||
|
class="-mb-15px"
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryFormRef"
|
||||||
|
:inline="true"
|
||||||
|
label-width="68px"
|
||||||
|
>
|
||||||
|
<el-form-item label="签到用户" prop="nickname">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.nickname"
|
||||||
|
placeholder="请输入签到用户"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="签到天数" prop="day">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.day"
|
||||||
|
placeholder="请输入签到天数"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="签到时间" prop="createTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.createTime"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table v-loading="loading" :data="list">
|
||||||
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
|
<el-table-column label="签到用户" align="center" prop="nickname" />
|
||||||
|
<el-table-column
|
||||||
|
label="签到天数"
|
||||||
|
align="center"
|
||||||
|
prop="day"
|
||||||
|
:formatter="(_, __, cellValue) => ['第', cellValue, '天'].join(' ')"
|
||||||
|
/>
|
||||||
|
<el-table-column label="获得积分" align="center" prop="point" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.point > 0" class="ml-2" type="success" effect="dark">
|
||||||
|
+{{ scope.row.point }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag v-else class="ml-2" type="danger" effect="dark"> {{ scope.row.point }} </el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
label="签到时间"
|
||||||
|
align="center"
|
||||||
|
prop="createTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
/>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</ContentWrap>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import * as SignInRecordApi from '@/api/member/signin/record'
|
||||||
|
|
||||||
|
defineOptions({ name: 'SignList' })
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
const list = ref([]) // 列表的数据
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
nickname: null,
|
||||||
|
day: null,
|
||||||
|
createTime: []
|
||||||
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const data = await SignInRecordApi.getSignInRecordPage(queryParams)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO @梦:改成 userId 哈
|
||||||
|
const { memberId } = defineProps({
|
||||||
|
memberId: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(() => {
|
||||||
|
queryParams.userId = memberId
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
</script>
|
237
src/views/member/user/detail/index.vue
Normal file
237
src/views/member/user/detail/index.vue
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
<template>
|
||||||
|
<div v-loading="loading">
|
||||||
|
<el-row :gutter="10" class="detail-info-warp">
|
||||||
|
<!-- 左上角:基本信息 -->
|
||||||
|
<el-col :span="14" class="detail-info-item">
|
||||||
|
<el-card shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<!-- TODO @梦:如果不要小蓝线,是不是直接用 el-card 自带的 title 即可? -->
|
||||||
|
<CardTitle title="基本信息" />
|
||||||
|
<el-button
|
||||||
|
v-if="user.id"
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
text
|
||||||
|
@click="openForm('update', user.id)"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="4">
|
||||||
|
<ElAvatar shape="square" :size="140" :src="user.avatar || undefined" />
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="20">
|
||||||
|
<el-descriptions :column="2">
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template #label>
|
||||||
|
<div class="cell-item">
|
||||||
|
<Icon icon="ep:user" />
|
||||||
|
用户名
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
{{ user.name || '空' }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template #label>
|
||||||
|
<div class="cell-item">
|
||||||
|
<Icon icon="ep:user" />
|
||||||
|
昵称
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
{{ user.nickname }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="手机号">
|
||||||
|
<template #label>
|
||||||
|
<div class="cell-item">
|
||||||
|
<Icon icon="ep:phone" />
|
||||||
|
手机号
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
{{ user.mobile }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template #label>
|
||||||
|
<div class="cell-item">
|
||||||
|
<Icon icon="fa:mars-double" />
|
||||||
|
性别
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<dict-tag :type="DICT_TYPE.SYSTEM_USER_SEX" :value="user.sex" />
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template #label>
|
||||||
|
<div class="cell-item">
|
||||||
|
<Icon icon="ep:location" />
|
||||||
|
所在地
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<!-- TODO @梦:这里后端返回的时候,要返回 areaName -->
|
||||||
|
{{ user.areaId }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template #label>
|
||||||
|
<div class="cell-item">
|
||||||
|
<Icon icon="ep:position" />
|
||||||
|
注册 IP
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
{{ user.registerIp }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template #label>
|
||||||
|
<div class="cell-item">
|
||||||
|
<Icon icon="fa:birthday-cake" />
|
||||||
|
生日
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
{{ user.birthday ? formatDate(user.birthday) : '空' }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template #label>
|
||||||
|
<div class="cell-item">
|
||||||
|
<Icon icon="ep:calendar" />
|
||||||
|
注册时间
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
{{ user.createTime ? formatDate(user.createTime) : '空' }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template #label>
|
||||||
|
<div class="cell-item">
|
||||||
|
<Icon icon="ep:calendar" />
|
||||||
|
最后登录时间
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
{{ user.loginDate ? formatDate(user.loginDate) : '空' }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<!-- 右上角:账户信息 -->
|
||||||
|
<el-col :span="10" class="detail-info-item">
|
||||||
|
<el-card shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<CardTitle title="账户信息" />
|
||||||
|
</template>
|
||||||
|
<AccountInfo />
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<!-- 下边:账户明细 -->
|
||||||
|
<!-- TODO 芋艿:【收货地址】【订单管理】【售后管理】【收藏记录】【优惠劵】 -->
|
||||||
|
<el-card header="账户明细" style="width: 100%; margin-top: 20px" shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<CardTitle title="账户明细" />
|
||||||
|
</template>
|
||||||
|
<el-tabs v-model="activeName">
|
||||||
|
<el-tab-pane label="积分" name="point">
|
||||||
|
<PointList v-if="user.id" :member-id="user.id" />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="签到" name="sign">
|
||||||
|
<SignList v-if="user.id" :member-id="user.id" />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="成长值" name="third">成长值(WIP)</el-tab-pane>
|
||||||
|
<el-tab-pane label="余额" name="fourth">余额(WIP)</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</el-card>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
|
<UserForm ref="formRef" @success="getUserData(user.id)" />
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
// TODO @梦:组件对应的 vue,都大写
|
||||||
|
import PointList from '@/views/member/user/components/point-list.vue'
|
||||||
|
import SignList from '@/views/member/user/components/sign-list.vue'
|
||||||
|
import CardTitle from '@/views/member/user/components/card-title.vue'
|
||||||
|
// TODO @梦:参考别的模块,UserApi 这样去引用
|
||||||
|
import { getUser, UserBaseInfoVO } from '@/api/member/user'
|
||||||
|
import { formatDate } from '@/utils/formatTime'
|
||||||
|
import { DICT_TYPE } from '@/utils/dict'
|
||||||
|
import UserForm from '@/views/member/user/UserForm.vue'
|
||||||
|
// TODO @梦:把用户信息,也抽成一个组件,类似 AccountInfo
|
||||||
|
import AccountInfo from '@/views/member/user/components/account-info.vue'
|
||||||
|
|
||||||
|
defineOptions({ name: 'MemberDetail' })
|
||||||
|
|
||||||
|
const activeName = ref('point') // 账户明细 选中的 tabs
|
||||||
|
const loading = ref(true) // 加载中
|
||||||
|
let user = ref<UserBaseInfoVO>({
|
||||||
|
areaId: undefined,
|
||||||
|
avatar: undefined,
|
||||||
|
birthday: undefined,
|
||||||
|
createTime: undefined,
|
||||||
|
id: undefined,
|
||||||
|
loginDate: undefined,
|
||||||
|
loginIp: '',
|
||||||
|
mark: '',
|
||||||
|
mobile: '',
|
||||||
|
name: '',
|
||||||
|
nickname: '',
|
||||||
|
password: null,
|
||||||
|
registerIp: undefined,
|
||||||
|
sex: 0,
|
||||||
|
status: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
/** 获得用户 */
|
||||||
|
const getUserData = async (id: number) => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
user.value = await getUser(id)
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
formRef.value.open(type, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 */
|
||||||
|
const route = useRoute()
|
||||||
|
const router = useRouter()
|
||||||
|
// TODO @梦:改成 id 路径参数,而不是 query
|
||||||
|
// TODO @梦:会员列表,把【详情】按钮加上哈
|
||||||
|
const member_id = route.query.member_id as number
|
||||||
|
onMounted(() => {
|
||||||
|
if (!member_id) {
|
||||||
|
// TODO
|
||||||
|
ElMessage.warning('参数错误,会员编号不能为空!')
|
||||||
|
router.back()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
getUserData(member_id)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style scoped lang="css">
|
||||||
|
/** TODO 这 3 个 css 貌似没用? */
|
||||||
|
.detail-info-item:first-child {
|
||||||
|
padding-left: 0 !important;
|
||||||
|
}
|
||||||
|
/* first-child 不生效有没有大佬给看下q.q */
|
||||||
|
.detail-info-item:nth-child(2) {
|
||||||
|
padding-right: 0 !important;
|
||||||
|
}
|
||||||
|
.card-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.cell-item {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
/** TODO 下面 css 貌似没啥用? */
|
||||||
|
.cell-item::after {
|
||||||
|
content: ':';
|
||||||
|
}
|
||||||
|
</style>
|
@ -84,10 +84,12 @@
|
|||||||
:show-overflow-tooltip="false"
|
:show-overflow-tooltip="false"
|
||||||
>
|
>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag v-for="(tagName, index) in scope.row.tagNames" :key="index">{{ tagName }}</el-tag>
|
<el-tag v-for="(tagName, index) in scope.row.tagNames" :key="index" class="mr-5px">
|
||||||
|
{{ tagName }}
|
||||||
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="积分" align="center" width="100px" />
|
<el-table-column label="积分" align="center" prop="point" width="100px" />
|
||||||
<el-table-column label="状态" align="center" prop="status" width="100px">
|
<el-table-column label="状态" align="center" prop="status" width="100px">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
class="!w-240px"
|
class="!w-240px"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getStrDictOptions(DICT_TYPE.PAY_CHANNEL_CODE_TYPE)"
|
v-for="dict in getStrDictOptions(DICT_TYPE.PAY_CHANNEL_CODE)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
:value="dict.value"
|
:value="dict.value"
|
||||||
|
Loading…
Reference in New Issue
Block a user