mall-app-t/pages/product/js/sku.js

351 lines
8.4 KiB
JavaScript
Raw Normal View History

2024-06-12 18:33:39 +08:00
import { ref, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import peach from '@/peach'
import GoodsApi from '@/peach/api/trade/goods'
import { SPEC_TYPE, SKU_RULE_CONFIG } from './config'
2024-06-04 18:43:13 +08:00
2024-06-12 18:33:39 +08:00
const pickerRef = ref(null)
2024-06-04 18:43:13 +08:00
2024-06-07 02:05:33 +08:00
// 多属性商品 sku 列表
2024-06-12 18:33:39 +08:00
const skus = ref([])
2024-06-07 02:05:33 +08:00
2024-06-12 18:33:39 +08:00
// 已选中商品规格的规格属性和值
const propertyList = ref([])
2024-06-05 18:58:12 +08:00
2024-06-12 18:33:39 +08:00
const goodsPropertyList = ref([])
2024-06-04 18:43:13 +08:00
2024-06-12 18:33:39 +08:00
const propertyListRef = ref(null)
2024-06-11 00:34:43 +08:00
2024-06-12 18:33:39 +08:00
const canEdit = computed(() => peach.$store('trade').canEdit)
2024-06-04 18:43:13 +08:00
const formData = ref({
2024-08-28 18:36:22 +08:00
specType: true,
specText: SPEC_TYPE[0].label,
2024-06-12 18:33:39 +08:00
})
2024-06-04 18:43:13 +08:00
2024-06-05 18:58:12 +08:00
async function showPropertyList() {
2024-08-28 18:36:22 +08:00
await getGoodsProperty()
propertyListRef.value.onOpen()
2024-06-05 18:58:12 +08:00
}
2024-06-04 18:43:13 +08:00
function onRDPickerConfirm(e) {
2024-08-28 18:36:22 +08:00
formData.value.specType = SPEC_TYPE[e.value[0]].value
formData.value.specText = SPEC_TYPE[e.value[0]].label
2024-06-11 18:33:56 +08:00
2024-08-28 18:36:22 +08:00
// 如果商品规格不一致,则需要重新初始化 sku 列表
initSku()
2024-06-04 18:43:13 +08:00
}
2024-06-05 18:58:12 +08:00
function pickerProperty() {
2024-08-28 18:36:22 +08:00
if (canEdit.value) {
let index = formData.value.specType ? 1 : 0
2024-06-11 18:33:56 +08:00
2024-08-28 18:36:22 +08:00
pickerRef.value.onOpen([index])
}
2024-06-05 18:58:12 +08:00
}
2024-06-07 02:05:33 +08:00
async function onPropertyConfirm(e) {
2024-08-28 18:36:22 +08:00
await getGoodsProperty()
2024-06-04 18:43:13 +08:00
}
2024-06-11 00:34:43 +08:00
function onConfirm() {
2024-08-28 18:36:22 +08:00
console.log(skus.value)
2024-06-11 00:34:43 +08:00
}
2024-06-07 18:34:58 +08:00
2024-06-11 00:34:43 +08:00
async function getGoodsProperty() {
2024-08-28 18:36:22 +08:00
let { data } = await GoodsApi.getHistoryProperty()
2024-06-11 18:33:56 +08:00
2024-08-28 18:36:22 +08:00
// 此处处理商品详情情况下,多规格属性
// 把 propertyList 中 id 相同的属性合并,并去重
propertyList.value = peach.$store('trade').selectedProperty || []
2024-06-11 18:33:56 +08:00
2024-08-28 18:36:22 +08:00
// 根据已经选择数据,设置默认选中
data.forEach((item) => {
// 判断属性是否已经选中
let propertyParent = propertyList.value.find((sitem) => sitem?.id === item.id)
2024-06-12 18:33:39 +08:00
2024-08-28 18:36:22 +08:00
item.checked = propertyParent ? true : false
2024-06-12 18:33:39 +08:00
2024-08-28 18:36:22 +08:00
// 如果属性已经选中,查询子类中是否有选中
if (item.checked) {
item.propertyValues.forEach((child) => {
let childResult = propertyParent?.children.some((schild) => schild === child.id)
child.checked = childResult ? true : false
})
}
})
2024-06-12 18:33:39 +08:00
2024-08-28 18:36:22 +08:00
goodsPropertyList.value = data
2024-06-12 18:33:39 +08:00
2024-08-28 18:36:22 +08:00
console.log(goodsPropertyList.value)
2024-06-07 18:34:58 +08:00
}
function changeSubProperty() {
2024-08-28 18:36:22 +08:00
// 修改子属性状态,需要同步更新 skus 的显示
console.log(goodsPropertyList.value)
// 过滤父属性 checked 选项,深拷贝避免后面循环改变元数据内容
let temp = JSON.parse(JSON.stringify(goodsPropertyList.value.filter((item) => item.checked)))
temp.forEach((item) => {
item.propertyValues = item.propertyValues.filter((child) => child.checked)
})
let result = temp.map((item) => {
return item.propertyValues.map((child) => ({
propertyId: item.id,
propertyName: item.name,
valueId: child.id,
valueName: child.name,
}))
})
let tempSkus = []
for (let item of reduceArr(result)) {
let obj = {
picUrl: '',
barCode: '',
price: 0,
marketPrice: 0,
costPrice: 0,
stock: 0,
weight: 0,
volume: 0,
properties: item,
2024-06-12 18:33:39 +08:00
}
2024-08-28 18:36:22 +08:00
tempSkus.push(obj)
}
2024-06-12 18:33:39 +08:00
2024-08-28 18:36:22 +08:00
skus.value = tempSkus
2024-06-07 18:34:58 +08:00
}
2024-06-11 18:33:56 +08:00
/**
* @author Ankkaya
* @description 新增商品初始化商品 sku
* @param {Type} -
* @returns {Type}
*/
function initSku() {
2024-08-28 18:36:22 +08:00
// 单规格
if (!formData.value.specType) {
let obj = {
picUrl: '',
barCode: '',
price: 0,
marketPrice: 0,
costPrice: 0,
stock: 0,
weight: null,
volume: null,
properties: [
{
propertyId: 0,
propertyName: '默认',
valueId: 0,
valueName: '默认',
},
],
2024-06-12 18:33:39 +08:00
}
2024-08-28 18:36:22 +08:00
skus.value = [obj]
} else {
// 初始化已选中规格,属性和格式化后的结果
propertyList.value = []
goodsPropertyList.value = []
// 多规格
skus.value = []
}
2024-06-11 18:33:56 +08:00
}
/**
* @author Ankkaya
* @description 确认属性
* @param {Type} -
* @returns {Type}
*/
function submitProperty() {
2024-08-28 18:36:22 +08:00
try {
validateSku(skus.value)
peach.$store('trade').$patch({
skus: skus.value,
specType: formData.value.specType,
})
peach.$router.back()
} catch (e) {
console.log(skus.value)
console.log(e, '校验失败')
}
2024-06-11 18:33:56 +08:00
}
function validateSku(skus) {
2024-08-28 18:36:22 +08:00
let warningInfo = '请检查商品各行相关属性配置,'
let validateStatue = true
let skusValue = skus ?? peach.$store('trade').skus
// 判断如果是多规格,并且 skusValue 为空 [],则提示
if (formData.value.specType && skusValue.length < 1) {
uni.showToast({
title: '请选择商品规格',
icon: 'none',
duration: 4000,
})
throw new Error('请选择商品规格')
}
for (const sku of skusValue) {
for (const rule of SKU_RULE_CONFIG) {
const arg = getValue(sku, rule.name)
if (!rule.rule(arg)) {
validateStatue = false
warningInfo += rule.message
break
}
2024-06-12 00:32:45 +08:00
}
2024-08-28 18:36:22 +08:00
if (!validateStatue) {
uni.showToast({
title: warningInfo,
icon: 'none',
duration: 4000,
})
throw new Error(warningInfo)
2024-06-11 18:33:56 +08:00
}
2024-08-28 18:36:22 +08:00
}
2024-06-11 18:33:56 +08:00
}
function getValue(obj, arg) {
2024-08-28 18:36:22 +08:00
const keys = arg.split('.')
let value = obj
for (const key of keys) {
if (value && typeof value === 'object' && key in value) {
value = value[key]
} else {
value = undefined
break
2024-06-11 00:34:43 +08:00
}
2024-08-28 18:36:22 +08:00
}
return value
2024-06-11 18:33:56 +08:00
}
function reduceArr(arr) {
2024-08-28 18:36:22 +08:00
return arr.reduce((acc, cur) => {
let tempAcc = []
if (acc.length < 1) {
cur.forEach((item, index) => {
if (tempAcc[index]) {
tempAcc[index].push(item)
2024-06-11 18:33:56 +08:00
} else {
2024-08-28 18:36:22 +08:00
tempAcc[index] = [item]
2024-06-11 18:33:56 +08:00
}
2024-08-28 18:36:22 +08:00
})
} else {
acc.forEach((item, index) => {
cur.forEach((sitem, sindex) => {
tempAcc.push([...item, sitem])
})
})
if (cur.length < 1) {
tempAcc = acc
}
}
return tempAcc
}, [])
2024-06-05 18:58:12 +08:00
}
2024-06-12 18:33:39 +08:00
const specType = computed(() => peach.$store('trade').specType)
2024-06-05 18:58:12 +08:00
function initial() {
2024-08-28 18:36:22 +08:00
onLoad(() => {
formData.value.specType = specType.value
formData.value.specText = SPEC_TYPE[specType.value ? 1 : 0].label
skus.value = JSON.parse(JSON.stringify(peach.$store('trade').skus))
// 如果新增商品 sku并且是单规格初始化 sku
if (!skus.value) {
initSku()
}
if (specType.value) {
getGoodsProperty()
}
})
}
const propertyValueTitle = ref('新增')
const inputPropertyValueDialogRef = ref()
const inputPropertyValueFormdata = ref({
id: '',
propertyId: '',
name: '',
remark: '',
})
function addPropertyValueClick(item) {
console.log(item)
propertyValueTitle.value = '新增'
inputPropertyValueFormdata.value.name = ''
inputPropertyValueFormdata.value.propertyId = item.id
inputPropertyValueDialogRef.value.open()
}
async function dialogInputPropertyValueConfirm(value) {
if (!value) {
peach.$helper.toast('请输入商品属性')
return
}
if (inputPropertyValueFormdata.value.id) {
await GoodsApi.editPropertyValue(inputPropertyValueFormdata.value)
} else {
await GoodsApi.createPropertyValue(inputPropertyValueFormdata.value)
}
await getGoodsProperty()
inputPropertyValueDialogRef.value.close()
}
function longPropertyValuePress(item) {
console.log(item)
if (canEdit.value) {
// 震动提示
uni.vibrateShort()
uni.showActionSheet({
itemList: ['编辑', '删除'],
success: async (res) => {
if (res.tapIndex === 0) {
propertyValueTitle.value = '编辑'
inputPropertyValueFormdata.value.id = item.id
inputPropertyValueFormdata.value.propertyId = item.propertyId
inputPropertyValueFormdata.value.name = item.name
inputPropertyValueDialogRef.value.open()
2024-06-12 18:33:39 +08:00
}
2024-08-28 18:36:22 +08:00
if (res.tapIndex === 1) {
await GoodsApi.delPropertyValue({ id: item.id })
await getGoodsProperty()
2024-06-12 18:33:39 +08:00
}
2024-08-28 18:36:22 +08:00
},
2024-06-12 18:33:39 +08:00
})
2024-08-28 18:36:22 +08:00
}
2024-06-05 18:58:12 +08:00
}
export {
2024-08-28 18:36:22 +08:00
initial,
canEdit,
skus,
pickerRef,
pickerProperty,
validateSku,
onConfirm,
submitProperty,
propertyListRef,
formData,
onRDPickerConfirm,
onPropertyConfirm,
propertyList,
showPropertyList,
goodsPropertyList,
changeSubProperty,
getGoodsProperty,
addPropertyValueClick,
dialogInputPropertyValueConfirm,
longPropertyValuePress,
inputPropertyValueDialogRef,
inputPropertyValueFormdata,
propertyValueTitle,
2024-06-12 18:33:39 +08:00
}