Merge branch 'dev_vite' of ssh://18.167.251.121:10002/aidlab/aida_front into dev_vite
This commit is contained in:
@@ -20,6 +20,11 @@ This directory owns the seller listing edit/create detail page.
|
|||||||
- Child components should receive props and emit events only. Do not import listing APIs or mutate parent state directly from children.
|
- Child components should receive props and emit events only. Do not import listing APIs or mutate parent state directly from children.
|
||||||
- If a new visual section is added to this page, prefer a new child component under `components/` plus shared types in `types.ts`.
|
- If a new visual section is added to this page, prefer a new child component under `components/` plus shared types in `types.ts`.
|
||||||
|
|
||||||
|
## Vue SFC Order
|
||||||
|
|
||||||
|
- Vue single-file components must keep sections in this order: `<template>` first, then `<script setup lang="ts">`, then `<style>`.
|
||||||
|
- When creating or refactoring `.vue` files in this page, preserve that order even if external Vue guidance suggests another layout.
|
||||||
|
|
||||||
## Image Category Mapping
|
## Image Category Mapping
|
||||||
|
|
||||||
Detail API images are mapped by `category`:
|
Detail API images are mapped by `category`:
|
||||||
|
|||||||
@@ -1,15 +1,3 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import type { ListingItem } from "../types"
|
|
||||||
|
|
||||||
defineProps<{
|
|
||||||
sketchList: ListingItem["sketchList"]
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: "crop", data: string | null, type: "apparel", index?: number): void
|
|
||||||
}>()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="apparel-container">
|
<div class="apparel-container">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
@@ -23,13 +11,27 @@ const emit = defineEmits<{
|
|||||||
class="sketch-element flex flex-center"
|
class="sketch-element flex flex-center"
|
||||||
>
|
>
|
||||||
<img class="img-src" :src="item.url || ''" alt="" />
|
<img class="img-src" :src="item.url || ''" alt="" />
|
||||||
<div class="crop-tool flex flex-center" @click="emit('crop', item.url, 'apparel', index)">
|
<div
|
||||||
|
class="crop-tool flex flex-center"
|
||||||
|
@click="emit('crop', item.url, 'apparel', index)"
|
||||||
|
>
|
||||||
<SvgIcon name="CCrop" color="#fff" size="12" />
|
<SvgIcon name="CCrop" color="#fff" size="12" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { ListingItem } from "../types"
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
sketchList: ListingItem["sketchList"]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: "crop", data: string | null, type: "apparel", index?: number): void
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.apparel-container {
|
.apparel-container {
|
||||||
|
|||||||
@@ -1,26 +1,3 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import Radio from "./Radio.vue"
|
|
||||||
import type { RadioOption } from "../types"
|
|
||||||
|
|
||||||
defineProps<{
|
|
||||||
productName: string
|
|
||||||
price: string
|
|
||||||
desc: string
|
|
||||||
gender: string
|
|
||||||
category: string[] | null
|
|
||||||
genderOptions: RadioOption[]
|
|
||||||
categoryOptions: RadioOption[]
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: "update:productName", value: string): void
|
|
||||||
(e: "update:price", value: string): void
|
|
||||||
(e: "update:desc", value: string): void
|
|
||||||
(e: "update:gender", value: string): void
|
|
||||||
(e: "update:category", value: string[] | null): void
|
|
||||||
}>()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="form-container flex flex-col">
|
<div class="form-container flex flex-col">
|
||||||
<div class="form-item">
|
<div class="form-item">
|
||||||
@@ -102,6 +79,29 @@ const emit = defineEmits<{
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import Radio from "./Radio.vue"
|
||||||
|
import type { RadioOption } from "../types"
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
productName: string
|
||||||
|
price: string
|
||||||
|
desc: string
|
||||||
|
gender: string
|
||||||
|
category: string[] | null
|
||||||
|
genderOptions: RadioOption[]
|
||||||
|
categoryOptions: RadioOption[]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: "update:productName", value: string): void
|
||||||
|
(e: "update:price", value: string): void
|
||||||
|
(e: "update:desc", value: string): void
|
||||||
|
(e: "update:gender", value: string): void
|
||||||
|
(e: "update:category", value: string[] | null): void
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.required {
|
.required {
|
||||||
&::after {
|
&::after {
|
||||||
|
|||||||
@@ -1,19 +1,3 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { computed } from "vue"
|
|
||||||
import type { ListingItem } from "../types"
|
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
imageList: ListingItem["prodImageList"]
|
|
||||||
firstSelectedIndex: number | null
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: "select", index: number): void
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const selectedCount = computed(() => props.imageList.filter((item) => item.selected).length)
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="product-image-list-container">
|
<div class="product-image-list-container">
|
||||||
<div class="title flex align-center space-between">
|
<div class="title flex align-center space-between">
|
||||||
@@ -45,6 +29,21 @@ const selectedCount = computed(() => props.imageList.filter((item) => item.selec
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from "vue"
|
||||||
|
import type { ListingItem } from "../types"
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
imageList: ListingItem["prodImageList"]
|
||||||
|
firstSelectedIndex: number | null
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: "select", index: number): void
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const selectedCount = computed(() => props.imageList.filter((item) => item.selected).length)
|
||||||
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.product-image-list-container {
|
.product-image-list-container {
|
||||||
|
|||||||
@@ -1,22 +1,3 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import type { TopImageType } from "../types"
|
|
||||||
|
|
||||||
defineProps<{
|
|
||||||
images: Record<TopImageType, string | null>
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: "crop", data: string | null, type: TopImageType): void
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const topImageList: TopImageType[] = ["sketch", "mainProductImage", "cover"]
|
|
||||||
const topImageTitleMap: Record<TopImageType, string> = {
|
|
||||||
sketch: "SellerListEdit.sketch",
|
|
||||||
mainProductImage: "SellerListEdit.mainProductImage",
|
|
||||||
cover: "SellerListEdit.cover"
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="main-image-container flex">
|
<div class="main-image-container flex">
|
||||||
<div
|
<div
|
||||||
@@ -64,6 +45,24 @@ const topImageTitleMap: Record<TopImageType, string> = {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { TopImageType } from "../types"
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
images: Record<TopImageType, string | null>
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: "crop", data: string | null, type: TopImageType): void
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const topImageList: TopImageType[] = ["sketch", "mainProductImage", "cover"]
|
||||||
|
const topImageTitleMap: Record<TopImageType, string> = {
|
||||||
|
sketch: "SellerListEdit.sketch",
|
||||||
|
mainProductImage: "SellerListEdit.mainProductImage",
|
||||||
|
cover: "SellerListEdit.cover"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.c-svg {
|
.c-svg {
|
||||||
|
|||||||
@@ -267,7 +267,7 @@
|
|||||||
const handleClickCrop = (data: any, type: string, paramThree: any = []) => {
|
const handleClickCrop = (data: any, type: string, paramThree: any = []) => {
|
||||||
// 处理来自TopImageSection的调用: (data, type, list)
|
// 处理来自TopImageSection的调用: (data, type, list)
|
||||||
// 处理来自ApparelSketchList的调用: (data, type, index)
|
// 处理来自ApparelSketchList的调用: (data, type, index)
|
||||||
const index = typeof paramThree === 'number' ? paramThree : undefined
|
const index = typeof paramThree === "number" ? paramThree : undefined
|
||||||
const list = Array.isArray(paramThree) ? paramThree : []
|
const list = Array.isArray(paramThree) ? paramThree : []
|
||||||
|
|
||||||
// console.log(data, type)
|
// console.log(data, type)
|
||||||
@@ -376,7 +376,7 @@
|
|||||||
})
|
})
|
||||||
if (item.mainProductImage) {
|
if (item.mainProductImage) {
|
||||||
params.images.push({
|
params.images.push({
|
||||||
category: 'main_product',
|
category: "main_product",
|
||||||
imageUrl: item.mainProductImage,
|
imageUrl: item.mainProductImage,
|
||||||
isSeleted: 1
|
isSeleted: 1
|
||||||
})
|
})
|
||||||
@@ -404,7 +404,7 @@
|
|||||||
message.error("请先完成封面制作")
|
message.error("请先完成封面制作")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (status === "publish" && !validatePublishRequired()) return
|
if (!validatePublishRequired()) return
|
||||||
|
|
||||||
await handleSaveForm(status)
|
await handleSaveForm(status)
|
||||||
if (status === "draft") {
|
if (status === "draft") {
|
||||||
|
|||||||
Reference in New Issue
Block a user