From 05178c4cb06923f8655e9a3e7bc90ba58e63c9fd Mon Sep 17 00:00:00 2001 From: zhangyahui Date: Mon, 27 Apr 2026 16:58:45 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8F=90=E4=BA=A4=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BrandProfile/image-clip-dialog.vue | 23 +++- .../BrandProfile/image-clip.vue | 19 ++- .../EditDetail/components/Radio.vue | 2 +- .../MyListings/EditDetail/index.vue | 116 +++++++++++++----- 4 files changed, 107 insertions(+), 53 deletions(-) diff --git a/src/views/SellerDashboard/BrandProfile/image-clip-dialog.vue b/src/views/SellerDashboard/BrandProfile/image-clip-dialog.vue index d279ad65..399f15c3 100644 --- a/src/views/SellerDashboard/BrandProfile/image-clip-dialog.vue +++ b/src/views/SellerDashboard/BrandProfile/image-clip-dialog.vue @@ -15,14 +15,19 @@
{{ data.title }}
-
+
Crop from:
-
+
Sketch
Main product image @@ -42,7 +47,7 @@ ref="imageClipRef" v-bind="$attrs" :ratio="data.ratio" - :fixedBox="data.isProduct ? type !== 'apparel' : false" + :isProduct="isProduct" :url="data.url" :type="type" @change="(v) => (data.preview_url = v)" @@ -112,8 +117,11 @@ const data = reactive({ callback: null, isProduct: false // 是否商品编辑 }) + +const currentOrigin = ref("sketch") const coverOrigin = ref([]) const handleChangeOrigin = (type) => { + currentOrigin.value = type data.url = coverOrigin.value.filter((el) => el.type === type)[0].url } @@ -132,7 +140,10 @@ const open = (url, callback, options, origin) => { if (options.hasOwnProperty("isPreview")) data.isPreview = options.isPreview data.isProduct = options.isProduct } - if (origin) coverOrigin.value = origin + if (origin?.length) { + coverOrigin.value = origin + data.url = origin[0].url + } console.log("-------", origin) show.value = true } @@ -303,7 +314,7 @@ defineExpose({ } &.is-cover { > .preview-image > img { - // width: 29.7rem; + width: 29.7rem; height: 37.5rem; } } diff --git a/src/views/SellerDashboard/BrandProfile/image-clip.vue b/src/views/SellerDashboard/BrandProfile/image-clip.vue index f0009b42..14ce35b3 100644 --- a/src/views/SellerDashboard/BrandProfile/image-clip.vue +++ b/src/views/SellerDashboard/BrandProfile/image-clip.vue @@ -7,10 +7,9 @@ crossOrigin="Anonymous" :autoCrop="true" :fixedNumber="ratio" - :fixed="type !== 'apparel' && isProduct" + :fixed="isProduct ? type !== 'apparel' : true" movable centerBox - :fixedBox="fixedBox" @realTime="onChange" outputType="png" v-bind="bindProps" @@ -52,10 +51,6 @@ const props = defineProps({ type: Boolean, default: false }, - fixedBox: { - type: Boolean, - default: true - }, type: { type: String, default: () => "" @@ -73,12 +68,12 @@ const autoCropHeight = computed(() => { const bindProps = computed(() => { // :autoCropWidth="isProduct ? undefined : type === 'cover' ? 297 : 242" // :autoCropHeight="isProduct ? undefined : autoCropHeight" - if (props.isProduct) { - return { - autoCropHeight: autoCropHeight.value, - autoCropWidth: props.type === "cover" ? 297 : 242 - } - } + // if (props.isProduct) { + // return { + // autoCropHeight: autoCropHeight.value, + // autoCropWidth: props.type === "cover" ? 297 : 242 + // } + // } }) const onChange = (data) => { diff --git a/src/views/SellerDashboard/MyListings/EditDetail/components/Radio.vue b/src/views/SellerDashboard/MyListings/EditDetail/components/Radio.vue index 6806b9fa..1273fd1e 100644 --- a/src/views/SellerDashboard/MyListings/EditDetail/components/Radio.vue +++ b/src/views/SellerDashboard/MyListings/EditDetail/components/Radio.vue @@ -58,7 +58,7 @@ const selectOption = (value: any) => { if (index >= 0) { current.splice(index, 1) } else { - current.push(value) + current.push(value.toLocaleLowerCase) } emit("update:modelValue", current) return diff --git a/src/views/SellerDashboard/MyListings/EditDetail/index.vue b/src/views/SellerDashboard/MyListings/EditDetail/index.vue index 0a117e82..8baf9caa 100644 --- a/src/views/SellerDashboard/MyListings/EditDetail/index.vue +++ b/src/views/SellerDashboard/MyListings/EditDetail/index.vue @@ -198,7 +198,7 @@ {{ $t("SellerListEdit.categoryTips") }}
- +
@@ -242,7 +242,7 @@ import SellerHeader from "../../seller-header.vue" import Radio from "./components/Radio.vue" import ImageClipDialog from "../../BrandProfile/image-clip-dialog.vue" import { useStore } from "vuex" -import { fetchSketchDetail, uploadFile, fetchListingDetailById, fetchChangeStatus } from "./api" +import { fetchSketchDetail, uploadFile, fetchListingDetailById, fetchUpdateListing } from "./api" const ROUTER = useRouter() const { t } = useI18n() @@ -261,6 +261,7 @@ type CategoryOption = { } type ListingItem = { + designItemId: number | string | null sketch: string | null mainProductImage: string cover: string @@ -270,7 +271,7 @@ type ListingItem = { price: string desc: string gender: string - category: string + category: string[] prodImageList: Array<{ url: string selected?: boolean @@ -279,6 +280,25 @@ type ListingItem = { } type StatusType = "draft" | "publish" +const createListingItem = ( + sketch: string | null = null, + designItemId: number | string | null = null +): ListingItem => ({ + designItemId, + sketch, + mainProductImage: "", + cover: "", + productImage: [], + apparelSketch: [], + productName: "", + price: "", + desc: "", + gender: "FEMALE", + category: null, + prodImageList: [], + sketchList: [] +}) + const topImageList = ["sketch", "mainProductImage", "cover"] as const const topImageTitleMap: Record<(typeof topImageList)[number], string> = { sketch: "SellerListEdit.sketch", @@ -297,22 +317,7 @@ const currentPage = ref(1) const currentIndex = computed(() => currentPage.value - 1) const itemId = ref("") -const selectList = ref([ - { - sketch: null, - mainProductImage: "", - cover: "", - productImage: [], - apparelSketch: [], - productName: "", - price: "", - desc: "", - gender: "FEMALE", - category: "", - prodImageList: [], - sketchList: [{ url: null }] - } -]) +const selectList = ref([createListingItem()]) const prodImgList = computed(() => currentListing.value.prodImageList || []) @@ -355,7 +360,7 @@ const handleSelectProdImg = (index: number) => { const cropType = ref("") const handleClickCrop = (data, type, list = []) => { // console.log(data, type) - console.log(selectList.value[currentIndex.value]) + // console.log(selectList.value[currentIndex.value]) let origin = [] const currentItem = selectList.value[currentIndex.value] if (currentItem.sketch) { @@ -371,7 +376,7 @@ const handleClickCrop = (data, type, list = []) => { cover: "Crop Cover", apparel: "Crop Apparel Sketch" } - const ratio = type === "apparel" ? [4, 5] : [9, 16] + const ratio = type === "cover" ? [4, 5] : [9, 16] cropType.value = type imageClipDialogRef.value.open( data, @@ -379,7 +384,7 @@ const handleClickCrop = (data, type, list = []) => { // console.log(file) uploadFile(file).then((res) => { console.log(res) - selectList.value[currentIndex.value].sketch = res + selectList.value[currentIndex.value][type] = res }) }, { ratio, isPreview: true, title: titleList[type], isProduct: true }, @@ -387,10 +392,6 @@ const handleClickCrop = (data, type, list = []) => { ) } -const handleSetStatus = (type: StatusType) => { - // fetchChangeStatus() -} - const hasValue = (value: unknown) => value !== null && value !== undefined && String(value).trim() !== "" @@ -438,17 +439,59 @@ const validatePublishRequired = () => { return true } +const handleSaveForm = async (type: StatusType) => { + const paramsList = [] + selectList.value.forEach((item) => { + const params = { + id: null, + title: selectList.value[currentIndex.value].productName, + description: selectList.value[currentIndex.value].desc, + price: selectList.value[currentIndex.value].price, + status: type === "draft" ? 0 : 1, + images: [], + designFor: selectList.value[currentIndex.value].gender.toLowerCase, + productCategory: selectList.value[currentIndex.value].category + } + // + topImageList.forEach((el) => { + params.images.push({ + category: el, + imageUrl: selectList.value[currentIndex.value][el], + isSelected: 1 + }) + }) + selectList.value[currentIndex.value].prodImageList.forEach((item) => { + if (item.selected) { + params.images.push({ + category: "main_product", + imageUrl: item.url, + isSelected: Number(item.selected) + }) + } + }) + selectList.value[currentIndex.value].sketchList.forEach((item) => { + params.images.push({ + category: "apparel", + imageUrl: item.url, + isSelected: 1 + }) + }) + paramsList.push(params) + }) + console.log(paramsList) + fetchUpdateListing(paramsList) +} const handleClickMenu = async (status: StatusType) => { if (status === "publish" && !validatePublishRequired()) return - await handleSetStatus(status) + await handleSaveForm(status) if (status === "draft") { // save draft logic - console.log("Saving draft...", currentListing.value) + // console.log("Saving draft...", currentListing.value) ROUTER.push({ name: "Status", params: { status: "draft" } }) } else if (status === "publish") { // publish logic - console.log("Publishing...", currentListing.value) + // console.log("Publishing...", currentListing.value) ROUTER.push({ name: "Status", params: { status: "publish" } }) } } @@ -457,6 +500,7 @@ const handleFetchItemDetial = (list) => { fetchSketchDetail(list).then((res) => { console.log(res) res.forEach((item, index) => { + if (!selectList.value[index]) return selectList.value[index].sketchList = item.clothes.map((el) => ({ url: el })) selectList.value[index].prodImageList = item.toProductImageUrls.map((el) => ({ url: el @@ -469,11 +513,15 @@ const handleFetchItemDetial = (list) => { } onMounted(() => { - itemId.value = history.state.id - history.state.designItemIds.forEach((item, index) => { - selectList.value[index].sketch = item.designOutfitUrl - }) - const list = history.state.designItemIds.map((el) => el.designItemId) + const designItemIds = history.state?.designItemIds || [] + itemId.value = history.state?.id || "" + if (!designItemIds.length) return + + currentPage.value = 1 + selectList.value = designItemIds.map((item) => + createListingItem(item.designOutfitUrl, item.designItemId) + ) + const list = designItemIds.map((el) => el.designItemId) console.log("list", list.length, list) handleFetchItemDetial(list) })