From f9780b636c3f7320e71707f2d0bc9311632d68db Mon Sep 17 00:00:00 2001 From: puhui999 Date: Thu, 31 Aug 2023 21:13:20 +0800 Subject: [PATCH 1/4] =?UTF-8?q?fix:=201=E3=80=81=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=90=A5=E9=94=80=E6=B4=BB=E5=8A=A8=E7=9B=B8=E5=85=B3=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E6=89=93=E4=B8=8D=E5=BC=80=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=202=E3=80=81=E4=BF=AE=E5=A4=8D=20spu=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98=202=E3=80=81?= =?UTF-8?q?=E9=87=8D=E6=9E=84=20spu=20=E7=9A=84=20sku=20=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=E4=B8=BA=E9=80=9A=E7=94=A8=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E7=9A=84=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/product/spu/components/SkuList.vue | 17 ++----- .../mall/product/spu/components/index.ts | 31 ++++++++++++- .../mall/product/spu/form/BasicInfoForm.vue | 44 +++++++++++++++++-- src/views/mall/product/spu/form/index.vue | 22 +++++----- 4 files changed, 86 insertions(+), 28 deletions(-) diff --git a/src/views/mall/product/spu/components/SkuList.vue b/src/views/mall/product/spu/components/SkuList.vue index 1cc70298..81e2347d 100644 --- a/src/views/mall/product/spu/components/SkuList.vue +++ b/src/views/mall/product/spu/components/SkuList.vue @@ -328,24 +328,15 @@ const tableHeaders = ref<{ prop: string; label: string }[]>([]) // 多属性表 * 保存时,每个商品规格的表单要校验下。例如说,销售金额最低是 0.01 这种。 */ const validateSku = () => { - const checks = ['price', 'marketPrice', 'costPrice'] let warningInfo = '请检查商品各行相关属性配置,' let validate = true // 默认通过 for (const sku of formData.value!.skus!) { // 作为活动组件的校验 - if (props.isActivityComponent) { - for (const rule of props?.ruleConfig) { - const arg = getValue(sku, rule.name) - if (!rule.rule(arg)) { - validate = false // 只要有一个不通过则直接不通过 - warningInfo += rule.message - break - } - } - } else { - if (checks.some((check) => sku[check] < 0.01)) { + for (const rule of props?.ruleConfig) { + const arg = getValue(sku, rule.name) + if (!rule.rule(arg)) { validate = false // 只要有一个不通过则直接不通过 - warningInfo = '商品相关价格不能低于 0.01 元!!' + warningInfo += rule.message break } } diff --git a/src/views/mall/product/spu/components/index.ts b/src/views/mall/product/spu/components/index.ts index 8f793c51..e2cbe73d 100644 --- a/src/views/mall/product/spu/components/index.ts +++ b/src/views/mall/product/spu/components/index.ts @@ -1,4 +1,5 @@ import SkuList from './SkuList.vue' +import { Spu } from '@/api/mall/product/spu' interface PropertyAndValues { id: number @@ -22,4 +23,32 @@ interface RuleConfig { message: string } -export { SkuList, PropertyAndValues, RuleConfig } +/** + * 获得商品的规格列表 - 商品相关的公共函数 + * + * @param spu + * @return PropertyAndValues 规格列表 + */ +const getPropertyList = (spu: Spu): PropertyAndValues[] => { + // 直接拿返回的 skus 属性逆向生成出 propertyList + const properties: PropertyAndValues[] = [] + // 只有是多规格才处理 + if (spu.specType) { + spu.skus?.forEach((sku) => { + sku.properties?.forEach(({ propertyId, propertyName, valueId, valueName }) => { + // 添加属性 + if (!properties?.some((item) => item.id === propertyId)) { + properties.push({ id: propertyId!, name: propertyName!, values: [] }) + } + // 添加属性值 + const index = properties?.findIndex((item) => item.id === propertyId) + if (!properties[index].values?.some((value) => value.id === valueId)) { + properties[index].values?.push({ id: valueId!, name: valueName! }) + } + }) + }) + } + return properties +} + +export { SkuList, PropertyAndValues, RuleConfig, getPropertyList } diff --git a/src/views/mall/product/spu/form/BasicInfoForm.vue b/src/views/mall/product/spu/form/BasicInfoForm.vue index 678b564d..50fb8793 100644 --- a/src/views/mall/product/spu/form/BasicInfoForm.vue +++ b/src/views/mall/product/spu/form/BasicInfoForm.vue @@ -109,7 +109,12 @@ - + 添加规格 @@ -120,7 +125,12 @@ - + @@ -175,7 +185,11 @@ import { propTypes } from '@/utils/propTypes' import { checkSelectedNode, defaultProps, handleTree, treeToString } from '@/utils/tree' import { createImageViewer } from '@/components/ImageViewer' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' -import { PropertyAndValues, SkuList } from '@/views/mall/product/spu/components/index.ts' +import { + PropertyAndValues, + RuleConfig, + SkuList +} from '@/views/mall/product/spu/components/index.ts' import ProductAttributes from './ProductAttributes.vue' import ProductPropertyAddForm from './ProductPropertyAddForm.vue' import { basicInfoSchema } from './spu.data' @@ -186,6 +200,30 @@ import * as ExpressTemplateApi from '@/api/mall/trade/delivery/expressTemplate' 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) /** 商品图预览 */ diff --git a/src/views/mall/product/spu/form/index.vue b/src/views/mall/product/spu/form/index.vue index db5b0445..526bb338 100644 --- a/src/views/mall/product/spu/form/index.vue +++ b/src/views/mall/product/spu/form/index.vue @@ -142,17 +142,17 @@ const submitForm = async () => { await unref(otherSettingsRef)?.validate() // 深拷贝一份, 这样最终 server 端不满足,不需要恢复, const deepCopyFormData = cloneDeep(unref(formData.value)) as ProductSpuApi.Spu - // 兜底处理 sku 空数据 - formData.value.skus!.forEach((sku) => { - // 因为是空数据这里判断一下商品条码是否为空就行 - if (sku.barCode === '') { - const index = deepCopyFormData.skus!.findIndex( - (item) => JSON.stringify(item.properties) === JSON.stringify(sku.properties) - ) - // 删除这条 sku - deepCopyFormData.skus!.splice(index, 1) - } - }) + // 兜底处理 sku 空数据 TODO 后续没得问题就移除 + // formData.value.skus!.forEach((sku) => { + // // 因为是空数据这里判断一下商品条码是否为空就行 + // if (sku.barCode === '') { + // const index = deepCopyFormData.skus!.findIndex( + // (item) => JSON.stringify(item.properties) === JSON.stringify(sku.properties) + // ) + // // 删除这条 sku + // deepCopyFormData.skus!.splice(index, 1) + // } + // }) deepCopyFormData.skus!.forEach((item) => { // 给sku name赋值 item.name = deepCopyFormData.name From 3e7945e437791695dd8a04ec58cad5fab6cccfb4 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Fri, 1 Sep 2023 01:24:46 +0800 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=B7=AE=E5=BC=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/product/spu/form/BasicInfoForm.vue | 34 +------------------ 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/src/views/mall/product/spu/form/BasicInfoForm.vue b/src/views/mall/product/spu/form/BasicInfoForm.vue index 50fb8793..c6426090 100644 --- a/src/views/mall/product/spu/form/BasicInfoForm.vue +++ b/src/views/mall/product/spu/form/BasicInfoForm.vue @@ -185,11 +185,7 @@ import { propTypes } from '@/utils/propTypes' import { checkSelectedNode, defaultProps, handleTree, treeToString } from '@/utils/tree' import { createImageViewer } from '@/components/ImageViewer' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' -import { - PropertyAndValues, - RuleConfig, - 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 ProductPropertyAddForm from './ProductPropertyAddForm.vue' import { basicInfoSchema } from './spu.data' @@ -241,34 +237,6 @@ const imagePreview = (args) => { }) } -/** - * 获得商品的规格列表 - * - * @param spu - * @return PropertyAndValues 规格列表 - */ -const getPropertyList = (spu: Spu): PropertyAndValues[] => { - // 直接拿返回的 skus 属性逆向生成出 propertyList - const properties: PropertyAndValues[] = [] - // 只有是多规格才处理 - if (spu.specType) { - spu.skus?.forEach((sku) => { - sku.properties?.forEach(({ propertyId, propertyName, valueId, valueName }) => { - // 添加属性 - if (!properties?.some((item) => item.id === propertyId)) { - properties.push({ id: propertyId!, name: propertyName!, values: [] }) - } - // 添加属性值 - const index = properties?.findIndex((item) => item.id === propertyId) - if (!properties[index].values?.some((value) => value.id === valueId)) { - properties[index].values?.push({ id: valueId!, name: valueName! }) - } - }) - }) - } - return properties -} - // ====== end ====== const message = useMessage() // 消息弹窗 From 07a0530fc92021c4a7080a37402c9bb5242f4446 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Fri, 1 Sep 2023 10:32:05 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E5=94=AE=E5=90=8E=E9=80=80=E6=AC=BE?= =?UTF-8?q?=EF=BC=9A=E5=AE=8C=E5=96=84=E5=94=AE=E5=90=8E=E7=AE=A1=E7=90=86?= =?UTF-8?q?=EF=BC=88=E5=88=97=E8=A1=A8=E3=80=81=E8=AF=A6=E6=83=85=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/trade/afterSale/detail/index.vue | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/src/views/mall/trade/afterSale/detail/index.vue b/src/views/mall/trade/afterSale/detail/index.vue index 360800ad..2fa6e01c 100644 --- a/src/views/mall/trade/afterSale/detail/index.vue +++ b/src/views/mall/trade/afterSale/detail/index.vue @@ -122,8 +122,36 @@ - - + + + + + + 用户类型: + + 售后状态(之前): + + 售后状态(之后): + + 操作明细:{{ saleLog.content }} + + + + + @@ -140,10 +168,12 @@ import { isArray } from '@/utils/is' defineOptions({ name: 'TradeOrderDetailForm' }) +const { t } = useI18n() // 国际化 const message = useMessage() // 消息弹窗 const { params } = useRoute() // 查询参数 const formData = ref({ - order: {} + order: {}, + afterSaleLog: [] }) const updateAuditReasonFormRef = ref() // 拒绝售后表单 Ref @@ -155,11 +185,12 @@ const getDetail = async () => { } } -// TODO @puhui999:操作后,需要提示和刷新哈。 /** 同意售后 */ const agree = () => { message.confirm('是否同意售后?').then(() => { AfterSaleApi.agree(formData.value.id) + message.success(t('common.success')) + getDetail() }) } @@ -172,6 +203,8 @@ const disagree = () => { const receive = () => { message.confirm('是否确认收货?').then(() => { AfterSaleApi.receive(formData.value.id) + message.success(t('common.success')) + getDetail() }) } @@ -179,6 +212,8 @@ const receive = () => { const refuse = () => { message.confirm('是否拒绝收货?').then(() => { AfterSaleApi.refuse(formData.value.id) + message.success(t('common.success')) + getDetail() }) } @@ -186,6 +221,8 @@ const refuse = () => { const refund = () => { message.confirm('是否确认退款?').then(() => { AfterSaleApi.refund(formData.value.id) + message.success(t('common.success')) + getDetail() }) } From f0249e94a5829fb3fa2eff0b1b9955c96e0ebe6d Mon Sep 17 00:00:00 2001 From: puhui999 Date: Fri, 1 Sep 2023 12:04:33 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E8=AE=A2=E5=8D=95=E7=AE=A1=E7=90=86?= =?UTF-8?q?=EF=BC=9A=E5=AE=8C=E5=96=84=E8=AE=A2=E5=8D=95=E8=AF=A6=E6=83=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/mall/trade/order/index.ts | 18 +- src/views/mall/trade/order/detail/index.vue | 244 ++++++-------------- 2 files changed, 90 insertions(+), 172 deletions(-) diff --git a/src/api/mall/trade/order/index.ts b/src/api/mall/trade/order/index.ts index 9413b73c..d4a22944 100644 --- a/src/api/mall/trade/order/index.ts +++ b/src/api/mall/trade/order/index.ts @@ -15,11 +15,11 @@ export interface OrderVO { cancelTime?: Date | null // 订单取消时间 cancelType?: number | null // 取消类型 remark?: string // 商家备注 - payOrderId: number | null // 支付订单编号 + payOrderId?: number | null // 支付订单编号 payed?: boolean // 是否已支付 payTime?: Date | null // 付款时间 payChannelCode?: string // 支付渠道 - originalPrice?: number | null // 商品原价(总) + totalPrice?: number | null // 商品原价(总) orderPrice?: number | null // 订单原价(总) discountPrice?: number | null // 订单优惠(总) deliveryPrice?: number | null // 运费金额 @@ -44,12 +44,19 @@ export interface OrderVO { pointPrice?: number | null // 积分抵扣的金额 receiverAreaName?: string //收件人地区名字 items?: OrderItemRespVO[] // 订单项列表 - //用户信息 + // 用户信息 user?: { id?: number | null nickname?: string avatar?: string } + // 订单操作日志 + orderLog: orderLog[] +} + +export interface orderLog { + content?: string + createTime?: Date } export interface OrderItemRespVO { @@ -94,6 +101,11 @@ export const getOrder = async (id: number | null) => { 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 { id: number // 订单编号 logisticsId: number | null // 物流公司编号 diff --git a/src/views/mall/trade/order/detail/index.vue b/src/views/mall/trade/order/detail/index.vue index ef2d9958..e2f790f1 100644 --- a/src/views/mall/trade/order/detail/index.vue +++ b/src/views/mall/trade/order/detail/index.vue @@ -2,32 +2,32 @@ - {{ orderInfo.no }} + {{ formData.no }} - + 秒杀活动 - + - {{ orderInfo.receiverName }} - {{ orderInfo.userRemark }} + {{ formData.receiverName }} + {{ formData.userRemark }} - + - {{ orderInfo.receiverMobile }} - {{ orderInfo.remark }} - {{ orderInfo.payOrderId }} + {{ formData.receiverMobile }} + {{ formData.remark }} + {{ formData.payOrderId }} - + - + - {{ orderInfo.receiverAreaName }} {{ orderInfo.receiverDetailAddress }} + {{ formData.receiverAreaName }} {{ formData.receiverDetailAddress }} - + 调整价格 @@ -59,7 +59,7 @@ - +