Commit 22d95fa0 by 芋道源码 Committed by Gitee

!229 完善订单管理和售后管理相关问题

Merge pull request !229 from puhui999/dev-to-dev
parents 3918fab1 f0249e94
...@@ -15,11 +15,11 @@ export interface OrderVO { ...@@ -15,11 +15,11 @@ export interface OrderVO {
cancelTime?: Date | null // 订单取消时间 cancelTime?: Date | null // 订单取消时间
cancelType?: number | null // 取消类型 cancelType?: number | null // 取消类型
remark?: string // 商家备注 remark?: string // 商家备注
payOrderId: number | null // 支付订单编号 payOrderId?: number | null // 支付订单编号
payed?: boolean // 是否已支付 payed?: boolean // 是否已支付
payTime?: Date | null // 付款时间 payTime?: Date | null // 付款时间
payChannelCode?: string // 支付渠道 payChannelCode?: string // 支付渠道
originalPrice?: number | null // 商品原价(总) totalPrice?: number | null // 商品原价(总)
orderPrice?: number | null // 订单原价(总) orderPrice?: number | null // 订单原价(总)
discountPrice?: number | null // 订单优惠(总) discountPrice?: number | null // 订单优惠(总)
deliveryPrice?: number | null // 运费金额 deliveryPrice?: number | null // 运费金额
...@@ -44,12 +44,19 @@ export interface OrderVO { ...@@ -44,12 +44,19 @@ export interface OrderVO {
pointPrice?: number | null // 积分抵扣的金额 pointPrice?: number | null // 积分抵扣的金额
receiverAreaName?: string //收件人地区名字 receiverAreaName?: string //收件人地区名字
items?: OrderItemRespVO[] // 订单项列表 items?: OrderItemRespVO[] // 订单项列表
//用户信息 // 用户信息
user?: { user?: {
id?: number | null id?: number | null
nickname?: string nickname?: string
avatar?: string avatar?: string
} }
// 订单操作日志
orderLog: orderLog[]
}
export interface orderLog {
content?: string
createTime?: Date
} }
export interface OrderItemRespVO { export interface OrderItemRespVO {
...@@ -94,6 +101,11 @@ export const getOrder = async (id: number | null) => { ...@@ -94,6 +101,11 @@ export const getOrder = async (id: number | null) => {
return await request.get({ url: `/trade/order/get-detail?id=` + id }) return await request.get({ url: `/trade/order/get-detail?id=` + id })
} }
// 查询交易订单物流详情
export const getExpressTrackList = async (id: number | null) => {
return await request.get({ url: `/trade/order/get-express-track-list?id=` + id })
}
export interface DeliveryVO { export interface DeliveryVO {
id: number // 订单编号 id: number // 订单编号
logisticsId: number | null // 物流公司编号 logisticsId: number | null // 物流公司编号
......
...@@ -328,12 +328,10 @@ const tableHeaders = ref<{ prop: string; label: string }[]>([]) // 多属性表 ...@@ -328,12 +328,10 @@ const tableHeaders = ref<{ prop: string; label: string }[]>([]) // 多属性表
* 保存时,每个商品规格的表单要校验下。例如说,销售金额最低是 0.01 这种。 * 保存时,每个商品规格的表单要校验下。例如说,销售金额最低是 0.01 这种。
*/ */
const validateSku = () => { const validateSku = () => {
const checks = ['price', 'marketPrice', 'costPrice']
let warningInfo = '请检查商品各行相关属性配置,' let warningInfo = '请检查商品各行相关属性配置,'
let validate = true // 默认通过 let validate = true // 默认通过
for (const sku of formData.value!.skus!) { for (const sku of formData.value!.skus!) {
// 作为活动组件的校验 // 作为活动组件的校验
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)) {
...@@ -342,13 +340,6 @@ const validateSku = () => { ...@@ -342,13 +340,6 @@ const validateSku = () => {
break break
} }
} }
} else {
if (checks.some((check) => sku[check] < 0.01)) {
validate = false // 只要有一个不通过则直接不通过
warningInfo = '商品相关价格不能低于 0.01 元!!'
break
}
}
// 只要有一个不通过则结束后续的校验 // 只要有一个不通过则结束后续的校验
if (!validate) { if (!validate) {
message.warning(warningInfo) message.warning(warningInfo)
......
...@@ -24,7 +24,7 @@ interface RuleConfig { ...@@ -24,7 +24,7 @@ interface RuleConfig {
} }
/** /**
* 获得商品的规格列表 * 获得商品的规格列表 - 商品相关的公共函数
* *
* @param spu * @param spu
* @return PropertyAndValues 规格列表 * @return PropertyAndValues 规格列表
...@@ -51,4 +51,4 @@ const getPropertyList = (spu: Spu): PropertyAndValues[] => { ...@@ -51,4 +51,4 @@ const getPropertyList = (spu: Spu): PropertyAndValues[] => {
return properties return properties
} }
export { SkuList, getPropertyList, PropertyAndValues, RuleConfig } export { SkuList, PropertyAndValues, RuleConfig, getPropertyList }
...@@ -109,7 +109,12 @@ ...@@ -109,7 +109,12 @@
<!-- 多规格添加--> <!-- 多规格添加-->
<el-col :span="24"> <el-col :span="24">
<el-form-item v-if="!formData.specType"> <el-form-item v-if="!formData.specType">
<SkuList ref="skuListRef" :prop-form-data="formData" :propertyList="propertyList" /> <SkuList
ref="skuListRef"
:prop-form-data="formData"
:propertyList="propertyList"
:rule-config="ruleConfig"
/>
</el-form-item> </el-form-item>
<el-form-item v-if="formData.specType" label="商品属性"> <el-form-item v-if="formData.specType" label="商品属性">
<el-button class="mr-15px mb-10px" @click="attributesAddFormRef.open">添加规格</el-button> <el-button class="mr-15px mb-10px" @click="attributesAddFormRef.open">添加规格</el-button>
...@@ -120,7 +125,12 @@ ...@@ -120,7 +125,12 @@
<SkuList :is-batch="true" :prop-form-data="formData" :propertyList="propertyList" /> <SkuList :is-batch="true" :prop-form-data="formData" :propertyList="propertyList" />
</el-form-item> </el-form-item>
<el-form-item label="属性列表"> <el-form-item label="属性列表">
<SkuList ref="skuListRef" :prop-form-data="formData" :propertyList="propertyList" /> <SkuList
ref="skuListRef"
:prop-form-data="formData"
:propertyList="propertyList"
:rule-config="ruleConfig"
/>
</el-form-item> </el-form-item>
</template> </template>
</el-col> </el-col>
...@@ -175,7 +185,7 @@ import { propTypes } from '@/utils/propTypes' ...@@ -175,7 +185,7 @@ import { propTypes } from '@/utils/propTypes'
import { checkSelectedNode, defaultProps, handleTree, treeToString } from '@/utils/tree' import { checkSelectedNode, defaultProps, handleTree, treeToString } from '@/utils/tree'
import { createImageViewer } from '@/components/ImageViewer' import { createImageViewer } from '@/components/ImageViewer'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { getPropertyList, SkuList } from '@/views/mall/product/spu/components/index.ts' import { getPropertyList, RuleConfig, SkuList } from '@/views/mall/product/spu/components/index.ts'
import ProductAttributes from './ProductAttributes.vue' import ProductAttributes from './ProductAttributes.vue'
import ProductPropertyAddForm from './ProductPropertyAddForm.vue' import ProductPropertyAddForm from './ProductPropertyAddForm.vue'
import { basicInfoSchema } from './spu.data' import { basicInfoSchema } from './spu.data'
...@@ -186,6 +196,30 @@ import * as ExpressTemplateApi from '@/api/mall/trade/delivery/expressTemplate' ...@@ -186,6 +196,30 @@ import * as ExpressTemplateApi from '@/api/mall/trade/delivery/expressTemplate'
defineOptions({ name: 'ProductSpuBasicInfoForm' }) defineOptions({ name: 'ProductSpuBasicInfoForm' })
// sku 相关属性校验规则
const ruleConfig: RuleConfig[] = [
{
name: 'stock',
rule: (arg) => arg >= 1,
message: '商品库存必须大于等于 1 !!!'
},
{
name: 'price',
rule: (arg) => arg >= 0.01,
message: '商品销售价格必须大于等于 0.01 !!!'
},
{
name: 'marketPrice',
rule: (arg) => arg >= 0.01,
message: '商品市场价格必须大于等于 0.01 !!!'
},
{
name: 'costPrice',
rule: (arg) => arg >= 0.01,
message: '商品成本价格必须大于等于 0.01 !!!'
}
]
// ====== 商品详情相关操作 ====== // ====== 商品详情相关操作 ======
const { allSchemas } = useCrudSchemas(basicInfoSchema) const { allSchemas } = useCrudSchemas(basicInfoSchema)
/** 商品图预览 */ /** 商品图预览 */
......
...@@ -142,17 +142,17 @@ const submitForm = async () => { ...@@ -142,17 +142,17 @@ const submitForm = async () => {
await unref(otherSettingsRef)?.validate() await unref(otherSettingsRef)?.validate()
// 深拷贝一份, 这样最终 server 端不满足,不需要恢复, // 深拷贝一份, 这样最终 server 端不满足,不需要恢复,
const deepCopyFormData = cloneDeep(unref(formData.value)) as ProductSpuApi.Spu const deepCopyFormData = cloneDeep(unref(formData.value)) as ProductSpuApi.Spu
// 兜底处理 sku 空数据 // 兜底处理 sku 空数据 TODO 后续没得问题就移除
formData.value.skus!.forEach((sku) => { // formData.value.skus!.forEach((sku) => {
// 因为是空数据这里判断一下商品条码是否为空就行 // // 因为是空数据这里判断一下商品条码是否为空就行
if (sku.barCode === '') { // if (sku.barCode === '') {
const index = deepCopyFormData.skus!.findIndex( // const index = deepCopyFormData.skus!.findIndex(
(item) => JSON.stringify(item.properties) === JSON.stringify(sku.properties) // (item) => JSON.stringify(item.properties) === JSON.stringify(sku.properties)
) // )
// 删除这条 sku // // 删除这条 sku
deepCopyFormData.skus!.splice(index, 1) // deepCopyFormData.skus!.splice(index, 1)
} // }
}) // })
deepCopyFormData.skus!.forEach((item) => { deepCopyFormData.skus!.forEach((item) => {
// 给sku name赋值 // 给sku name赋值
item.name = deepCopyFormData.name item.name = deepCopyFormData.name
......
...@@ -122,8 +122,36 @@ ...@@ -122,8 +122,36 @@
</el-row> </el-row>
</el-descriptions-item> </el-descriptions-item>
</el-descriptions> </el-descriptions>
<!-- 售后信息 TODO @puhui999:需要接入 --> <el-descriptions title="售后日志">
<el-descriptions title="售后日志" /> <el-descriptions-item labelClassName="no-colon">
<el-timeline>
<el-timeline-item
v-for="saleLog in formData.afterSaleLog"
:key="saleLog.id"
:timestamp="formatDate(saleLog.createTime)"
placement="top"
>
<el-card>
<span>用户类型:</span>
<dict-tag :type="DICT_TYPE.USER_TYPE" :value="saleLog.userType" class="mr-10px" />
<span>售后状态(之前):</span>
<dict-tag
:type="DICT_TYPE.TRADE_AFTER_SALE_STATUS"
:value="saleLog.beforeStatus"
class="mr-10px"
/>
<span>售后状态(之后):</span>
<dict-tag
:type="DICT_TYPE.TRADE_AFTER_SALE_STATUS"
:value="saleLog.afterStatus"
class="mr-10px"
/>
<span>操作明细:{{ saleLog.content }}</span>
</el-card>
</el-timeline-item>
</el-timeline>
</el-descriptions-item>
</el-descriptions>
</ContentWrap> </ContentWrap>
<!-- 各种操作的弹窗 --> <!-- 各种操作的弹窗 -->
...@@ -140,10 +168,12 @@ import { isArray } from '@/utils/is' ...@@ -140,10 +168,12 @@ import { isArray } from '@/utils/is'
defineOptions({ name: 'TradeOrderDetailForm' }) defineOptions({ name: 'TradeOrderDetailForm' })
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗 const message = useMessage() // 消息弹窗
const { params } = useRoute() // 查询参数 const { params } = useRoute() // 查询参数
const formData = ref({ const formData = ref({
order: {} order: {},
afterSaleLog: []
}) })
const updateAuditReasonFormRef = ref() // 拒绝售后表单 Ref const updateAuditReasonFormRef = ref() // 拒绝售后表单 Ref
...@@ -155,11 +185,12 @@ const getDetail = async () => { ...@@ -155,11 +185,12 @@ const getDetail = async () => {
} }
} }
// TODO @puhui999:操作后,需要提示和刷新哈。
/** 同意售后 */ /** 同意售后 */
const agree = () => { const agree = () => {
message.confirm('是否同意售后?').then(() => { message.confirm('是否同意售后?').then(() => {
AfterSaleApi.agree(formData.value.id) AfterSaleApi.agree(formData.value.id)
message.success(t('common.success'))
getDetail()
}) })
} }
...@@ -172,6 +203,8 @@ const disagree = () => { ...@@ -172,6 +203,8 @@ const disagree = () => {
const receive = () => { const receive = () => {
message.confirm('是否确认收货?').then(() => { message.confirm('是否确认收货?').then(() => {
AfterSaleApi.receive(formData.value.id) AfterSaleApi.receive(formData.value.id)
message.success(t('common.success'))
getDetail()
}) })
} }
...@@ -179,6 +212,8 @@ const receive = () => { ...@@ -179,6 +212,8 @@ const receive = () => {
const refuse = () => { const refuse = () => {
message.confirm('是否拒绝收货?').then(() => { message.confirm('是否拒绝收货?').then(() => {
AfterSaleApi.refuse(formData.value.id) AfterSaleApi.refuse(formData.value.id)
message.success(t('common.success'))
getDetail()
}) })
} }
...@@ -186,6 +221,8 @@ const refuse = () => { ...@@ -186,6 +221,8 @@ const refuse = () => {
const refund = () => { const refund = () => {
message.confirm('是否确认退款?').then(() => { message.confirm('是否确认退款?').then(() => {
AfterSaleApi.refund(formData.value.id) AfterSaleApi.refund(formData.value.id)
message.success(t('common.success'))
getDetail()
}) })
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment