Files
inkreach-official-website/apps/admin/src/views/product-family/CustomMemberDialog.vue
T

144 lines
5.4 KiB
Vue

<script setup lang="ts">
import { computed, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { Delete, Plus } from '@element-plus/icons-vue'
import type { CustomMemberVariantInput } from '@/types'
import { productFamiliesApi } from '@/api/product-families'
import ImageUpload from '@/components/ImageUpload.vue'
const props = defineProps<{ modelValue: boolean; familyId: string | null }>()
const emit = defineEmits<{
(e: 'update:modelValue', v: boolean): void
(e: 'created'): void
}>()
const visible = computed({
get: () => props.modelValue,
set: (v) => emit('update:modelValue', v),
})
const submitting = ref(false)
const form = ref({
goodName: '',
goodImage: '',
logisticsLabel: '',
craftLabel: '',
skuCode: '',
warehouseLabel: '',
})
const variants = ref<CustomMemberVariantInput[]>([{ sku: '', sizeId: '', sizeName: '', colorId: '', colorName: '', price: 0 }])
function addVariant() {
variants.value.push({ sku: '', sizeId: '', sizeName: '', colorId: '', colorName: '', price: 0 })
}
function removeVariant(i: number) {
variants.value.splice(i, 1)
}
function reset() {
form.value = { goodName: '', goodImage: '', logisticsLabel: '', craftLabel: '', skuCode: '', warehouseLabel: '' }
variants.value = [{ sku: '', sizeId: '', sizeName: '', colorId: '', colorName: '', price: 0 }]
}
async function submit() {
if (!props.familyId) return
if (!form.value.goodName.trim() || !form.value.logisticsLabel.trim() || !form.value.craftLabel.trim()) {
ElMessage.warning('名称、物流、工艺为必填(价格矩阵归因依赖)')
return
}
const payload = variants.value.filter((v) => v.sku.trim())
if (!payload.length) {
ElMessage.warning('至少一条变体(含价格)')
return
}
submitting.value = true
try {
await productFamiliesApi.createCustomMember(props.familyId, {
goodName: form.value.goodName.trim(),
goodImage: form.value.goodImage || null,
logisticsLabel: form.value.logisticsLabel.trim(),
craftLabel: form.value.craftLabel.trim(),
skuCode: form.value.skuCode.trim() || null,
warehouseLabel: form.value.warehouseLabel.trim() || null,
variants: payload.map((v) => ({
sku: v.sku.trim(),
sizeId: v.sizeId?.trim() || null,
sizeName: v.sizeName?.trim() || null,
colorId: v.colorId?.trim() || null,
colorName: v.colorName?.trim() || null,
price: v.price,
})),
})
ElMessage.success('自定义成员已创建,族已重算')
visible.value = false
reset()
emit('created')
} catch (e: any) {
ElMessage.error(e?.response?.data?.message ?? '创建失败')
} finally {
submitting.value = false
}
}
</script>
<template>
<el-dialog v-model="visible" title="新建自定义成员(人工商品)" width="720px" destroy-on-close @closed="reset">
<el-form label-width="90px">
<el-form-item label="商品名" required>
<el-input v-model="form.goodName" placeholder="如 美国(海运)180g纯棉T恤-DG001-烫画" />
</el-form-item>
<el-form-item label="主图">
<ImageUpload v-model="form.goodImage" label="上传图片" />
</el-form-item>
<el-row :gutter="12">
<el-col :span="12">
<el-form-item label="物流" required>
<el-input v-model="form.logisticsLabel" placeholder="如 海运(矩阵归因必填)" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工艺" required>
<el-input v-model="form.craftLabel" placeholder="如 烫画 / 双面印花(必填)" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="12">
<el-col :span="12">
<el-form-item label="SKU 编码">
<el-input v-model="form.skuCode" placeholder="可留空" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="仓库">
<el-input v-model="form.warehouseLabel" placeholder="可留空" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="变体价格">
<div class="cmd-variants">
<div v-for="(v, i) in variants" :key="i" class="cmd-variant-row">
<el-input v-model="v.sku" placeholder="SKU" style="width: 150px" />
<el-input v-model="v.sizeId" placeholder="尺码ID(size_S)" style="width: 120px" />
<el-input v-model="v.sizeName" placeholder="尺码名(S)" style="width: 80px" />
<el-input v-model="v.colorId" placeholder="颜色ID" style="width: 120px" />
<el-input v-model="v.colorName" placeholder="颜色名" style="width: 80px" />
<el-input-number v-model="v.price" :min="0.01" :precision="2" :controls="false" placeholder="价格" style="width: 100px" />
<el-button link type="danger" :icon="Delete" :disabled="variants.length <= 1" @click="removeVariant(i)" />
</div>
<el-button size="small" :icon="Plus" @click="addVariant">加一行</el-button>
</div>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" :loading="submitting" @click="submit">创建并入族</el-button>
</template>
</el-dialog>
</template>
<style scoped>
.cmd-variants { display: flex; flex-direction: column; gap: 6px; width: 100%; }
.cmd-variant-row { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
</style>