959 lines
22 KiB
Vue
959 lines
22 KiB
Vue
<template>
|
|
<div class="edit-detail-wrapper flex-1">
|
|
<seller-header
|
|
class="edit-detail-header"
|
|
title="Edit Listing Details"
|
|
:breadcrumbs="[
|
|
{ title: 'My Listings', name: 'myListingsIndex' },
|
|
{ title: 'Select Collection', name: 'myListingsSelect' },
|
|
{ title: 'Select Sketch', name: 'myListingsSelectItem' },
|
|
{ title: 'Edit Listing Details', name: 'EditDetail' }
|
|
]"
|
|
>
|
|
<template #right>
|
|
<div class="operate-menu flex">
|
|
<div class="menu-btn flex align-center save" @click="handleClickMenu('draft')">
|
|
<span>{{ $t("SellerListEdit.saveDraft") }}</span>
|
|
<SvgIcon name="CSave" size="16" />
|
|
</div>
|
|
<div
|
|
class="menu-btn flex align-center publish"
|
|
@click="handleClickMenu('publish')"
|
|
>
|
|
<span>{{ $t("SellerListEdit.publish") }}</span>
|
|
<SvgIcon name="CPublish" size="16" />
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</seller-header>
|
|
<div class="edit-detail-content flex">
|
|
<div class="left">
|
|
<div class="main-image-container flex">
|
|
<div
|
|
v-for="type in topImageList"
|
|
:key="type"
|
|
:class="`main-image-item flex flex-col align-center ${type}`"
|
|
>
|
|
<div class="title" :class="{ required: type !== 'mainProductImage' }">
|
|
{{ $t(topImageTitleMap[type]) }}
|
|
</div>
|
|
<div class="sketch-item flex flex-center" :class="type">
|
|
<div
|
|
v-if="previewImageMap[type]"
|
|
class="crop-tool flex flex-center"
|
|
@click="handleClickCrop(previewImageMap[type], type)"
|
|
>
|
|
<SvgIcon name="CCrop" color="#fff" size="12" />
|
|
</div>
|
|
<img
|
|
v-if="previewImageMap[type]"
|
|
:src="previewImageMap[type]"
|
|
class="sketch-img"
|
|
:class="type"
|
|
alt=""
|
|
/>
|
|
<div v-else class="trigger flex flex-col align-center">
|
|
<div
|
|
v-if="type === 'cover'"
|
|
class="cover-trigger flex flex-col align-center"
|
|
@click="handleClickCrop(null, 'cover')"
|
|
>
|
|
<SvgIcon
|
|
class="trigger-icon"
|
|
name="CCrop"
|
|
color="#585858"
|
|
size="24"
|
|
/>
|
|
<div class="trigger-tips">
|
|
{{ $t("SellerListEdit.cropDesc") }}
|
|
</div>
|
|
</div>
|
|
<template v-else>
|
|
<div class="trigger-img placeholder"></div>
|
|
<div class="trigger-tips">
|
|
{{ $t("SellerListEdit.productImageDesc") }}
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="product-image-list-container">
|
|
<div class="title flex align-center space-between">
|
|
<div class="title-left">
|
|
<span class="main-title">{{
|
|
$t("SellerListEdit.productImageMainTitle")
|
|
}}</span>
|
|
<span class="sub-title">{{
|
|
$t("SellerListEdit.productImageSubTitle")
|
|
}}</span>
|
|
</div>
|
|
<div class="title-right">
|
|
{{ selectedProdImgs }}/{{ prodImgList.length }} selected
|
|
</div>
|
|
</div>
|
|
<div class="product-image-list flex">
|
|
<div
|
|
v-for="(item, index) in prodImgList"
|
|
:key="index"
|
|
class="product-image-item flex flex-center"
|
|
:class="{ selected: item.selected }"
|
|
@click="handleSelectProdImg(index)"
|
|
>
|
|
<img
|
|
v-if="item.selected"
|
|
src="@/assets/images/seller/checked.png"
|
|
class="checked"
|
|
alt=""
|
|
/>
|
|
<img class="img-src" :src="item.url" alt="" />
|
|
<div
|
|
v-if="item.selected && index === firstSelectedIndex"
|
|
class="main-pic"
|
|
>
|
|
main
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="apparel-container">
|
|
<div class="title">
|
|
<span class="main-title">{{
|
|
$t("SellerListEdit.apparelSketchTitle")
|
|
}}</span>
|
|
<span class="sub-title">
|
|
{{ $t("SellerListEdit.apparelSketchSubTitle") }}</span
|
|
>
|
|
</div>
|
|
<div class="sketch-list-container flex">
|
|
<div
|
|
v-for="(item, index) in selectList[currentIndex].sketchList"
|
|
:key="index"
|
|
class="sketch-element flex flex-center"
|
|
>
|
|
<img class="img-src" :src="item.url" alt="" />
|
|
<div
|
|
class="crop-tool flex flex-center"
|
|
@click="handleClickCrop(item.url, 'apparel')"
|
|
>
|
|
<SvgIcon name="CCrop" color="#fff" size="12" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="right">
|
|
<div class="form-container flex flex-col">
|
|
<div class="form-item">
|
|
<div class="form-item-label required">
|
|
{{ $t("SellerListEdit.productName") }}
|
|
</div>
|
|
<div class="form-item-value product-name">
|
|
<a-input
|
|
v-model:value="currentListing.productName"
|
|
show-count
|
|
placeholder="Enter product name"
|
|
:bordered="false"
|
|
:maxlength="60"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="form-item">
|
|
<div class="form-item-label required">{{ $t("SellerListEdit.price") }}</div>
|
|
<div class="form-item-value price flex align-center">
|
|
<span>HK$</span>
|
|
<a-input
|
|
v-model:value="currentListing.price"
|
|
placeholder="0.00"
|
|
:bordered="false"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="form-item">
|
|
<div class="form-item-label required">
|
|
{{ $t("SellerListEdit.productDescription") }}
|
|
</div>
|
|
<div class="form-item-value desc">
|
|
<a-textarea
|
|
v-model:value="currentListing.desc"
|
|
show-count
|
|
:rows="4"
|
|
placeholder="Enter product description"
|
|
:bordered="false"
|
|
:maxlength="500"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="form-item">
|
|
<div class="form-item-label required">
|
|
{{ $t("SellerListEdit.designFor") }}
|
|
</div>
|
|
<div class="form-item-value no-border">
|
|
<Radio :options="genderOptions" v-model="currentListing.gender" />
|
|
</div>
|
|
</div>
|
|
<div class="form-item">
|
|
<div class="form-item-label with-tip">
|
|
<span class="required">{{ $t("SellerListEdit.productCategory") }}</span>
|
|
<span class="help-text">{{ $t("SellerListEdit.categoryTips") }}</span>
|
|
</div>
|
|
<div class="form-item-value no-border">
|
|
<Radio multiple :options="categoryOptions" v-model="currentListing.category" />
|
|
</div>
|
|
</div>
|
|
<div class="license-note flex align-center">
|
|
<img src="@/assets/images/seller/tips.png" class="info-icon" />
|
|
<div class="note-copy">
|
|
{{ $t("SellerListEdit.policy") }}
|
|
<a href="javascript:void(0)">{{ $t("SellerListEdit.learnMore") }}</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="page-control flex align-center" v-if="selectList.length > 1">
|
|
<a-pagination
|
|
v-model:current="currentPage"
|
|
:total="selectList.length"
|
|
:page-size="1"
|
|
showQuickJumper
|
|
showLessItems
|
|
responsive
|
|
:showSizeChanger="false"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<ImageClipDialog
|
|
ref="imageClipDialogRef"
|
|
fixedBox
|
|
isProduct
|
|
:info="false"
|
|
v-bind="$attrs"
|
|
:type="cropType"
|
|
/>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed, ref, watch, onMounted } from "vue"
|
|
import { useRouter } from "vue-router"
|
|
import { useI18n } from "vue-i18n"
|
|
import { message } from "ant-design-vue"
|
|
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, fetchUpdateListing } from "./api"
|
|
|
|
const ROUTER = useRouter()
|
|
const { t } = useI18n()
|
|
|
|
const imageClipDialogRef = ref<InstanceType<typeof ImageClipDialog> | null>(null)
|
|
|
|
defineOptions({
|
|
name: "EditDetail"
|
|
})
|
|
|
|
const STORE = useStore()
|
|
|
|
type CategoryOption = {
|
|
label: string
|
|
value: string
|
|
}
|
|
|
|
type ListingItem = {
|
|
designItemId: number | string | null
|
|
sketch: string | null
|
|
mainProductImage: string
|
|
cover: string
|
|
productImage: string[]
|
|
apparelSketch: string[]
|
|
productName: string
|
|
price: string
|
|
desc: string
|
|
gender: string
|
|
category: string[]
|
|
prodImageList: Array<{
|
|
url: string
|
|
selected?: boolean
|
|
}>
|
|
sketchList: Array<{ url: string | null }>
|
|
}
|
|
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",
|
|
mainProductImage: "SellerListEdit.mainProductImage",
|
|
cover: "SellerListEdit.cover"
|
|
}
|
|
|
|
const genderOptions = STORE.state.UserHabit?.sex.value || []
|
|
|
|
const fallbackCategoryOptions: Record<string, CategoryOption[]> = {
|
|
MALE: STORE.state.UserHabit?.MalePosition || [],
|
|
FEMALE: STORE.state.UserHabit?.FemalePosition || []
|
|
}
|
|
|
|
const currentPage = ref(1)
|
|
const currentIndex = computed(() => currentPage.value - 1)
|
|
|
|
const itemId = ref("")
|
|
const selectList = ref<ListingItem[]>([createListingItem()])
|
|
|
|
const prodImgList = computed(() => currentListing.value.prodImageList || [])
|
|
|
|
const categoryOptions = computed(() => {
|
|
const gender = selectList.value[currentIndex.value].gender
|
|
return fallbackCategoryOptions[gender] || []
|
|
})
|
|
|
|
const currentListing = computed(() => selectList.value[currentIndex.value])
|
|
|
|
const previewImageMap = computed(() => ({
|
|
sketch: currentListing.value.sketch,
|
|
mainProductImage: currentListing.value.mainProductImage,
|
|
cover: currentListing.value.cover
|
|
}))
|
|
|
|
const firstSelectedIndex = ref(null) //显示main标签的图片索引
|
|
const selectedProdImgs = computed(() => {
|
|
return prodImgList.value.filter((item) => item.selected).length
|
|
})
|
|
|
|
const handleSelectProdImg = (index: number) => {
|
|
const target = prodImgList.value[index]
|
|
|
|
const willSelect = !target.selected
|
|
|
|
target.selected = willSelect
|
|
|
|
if (willSelect && !currentListing.value.mainProductImage) {
|
|
currentListing.value.mainProductImage = target.url
|
|
firstSelectedIndex.value = index
|
|
}
|
|
|
|
if (!willSelect && currentListing.value.mainProductImage === target.url) {
|
|
firstSelectedIndex.value = null
|
|
currentListing.value.mainProductImage = ""
|
|
}
|
|
}
|
|
|
|
const cropType = ref("")
|
|
const handleClickCrop = (data, type, list = []) => {
|
|
// console.log(data, type)
|
|
// console.log(selectList.value[currentIndex.value])
|
|
let origin = []
|
|
const currentItem = selectList.value[currentIndex.value]
|
|
if (currentItem.sketch) {
|
|
origin.push({ type: "sketch", url: currentItem.sketch })
|
|
}
|
|
if (currentItem.mainProductImage) {
|
|
origin.push({ type: "mainProductImage", url: currentItem.mainProductImage })
|
|
}
|
|
if (type !== "cover") origin = []
|
|
const titleList = {
|
|
sketch: "Crop Sketch",
|
|
mainProductImage: "Crop Main Product Image",
|
|
cover: "Crop Cover",
|
|
apparel: "Crop Apparel Sketch"
|
|
}
|
|
const ratio = type === "cover" ? [4, 5] : [9, 16]
|
|
cropType.value = type
|
|
imageClipDialogRef.value.open(
|
|
data,
|
|
(file) => {
|
|
// console.log(file)
|
|
uploadFile(file).then((res) => {
|
|
console.log(res)
|
|
selectList.value[currentIndex.value][type] = res
|
|
})
|
|
},
|
|
{ ratio, isPreview: true, title: titleList[type], isProduct: true },
|
|
origin
|
|
)
|
|
}
|
|
|
|
const hasValue = (value: unknown) =>
|
|
value !== null && value !== undefined && String(value).trim() !== ""
|
|
|
|
const getMissingRequiredField = (item: ListingItem) => {
|
|
const cover = item.cover || item.mainProductImage || item.sketch
|
|
const requiredFields = [
|
|
{ value: item.sketch, label: t("SellerListEdit.sketch") },
|
|
{ value: cover, label: t("SellerListEdit.cover") },
|
|
{ value: item.productName, label: t("SellerListEdit.productName") },
|
|
{ value: item.price, label: t("SellerListEdit.price") },
|
|
{ value: item.desc, label: t("SellerListEdit.productDescription") },
|
|
{ value: item.gender, label: t("SellerListEdit.designFor") },
|
|
{ value: item.category, label: t("SellerListEdit.productCategory") }
|
|
]
|
|
const missingField = requiredFields.find((field) => !hasValue(field.value))
|
|
if (missingField) return missingField.label
|
|
|
|
const missingSketchIndex = item.sketchList.findIndex((sketch) => !hasValue(sketch.url))
|
|
if (item.sketchList.length === 0 || missingSketchIndex !== -1) {
|
|
return `${t("SellerListEdit.apparelSketchTitle").trim()} ${
|
|
missingSketchIndex === -1 ? 1 : missingSketchIndex + 1
|
|
}`
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
const validatePublishRequired = () => {
|
|
for (let index = 0; index < selectList.value.length; index += 1) {
|
|
const field = getMissingRequiredField(selectList.value[index])
|
|
if (!field) continue
|
|
|
|
currentPage.value = index + 1
|
|
message.warning(
|
|
t(
|
|
selectList.value.length > 1
|
|
? "SellerListEdit.requiredFieldTipsWithPage"
|
|
: "SellerListEdit.requiredFieldTips",
|
|
{ index: index + 1, field }
|
|
)
|
|
)
|
|
return false
|
|
}
|
|
|
|
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 handleSaveForm(status)
|
|
if (status === "draft") {
|
|
// save draft logic
|
|
// console.log("Saving draft...", currentListing.value)
|
|
ROUTER.push({ name: "Status", params: { status: "draft" } })
|
|
} else if (status === "publish") {
|
|
// publish logic
|
|
// console.log("Publishing...", currentListing.value)
|
|
ROUTER.push({ name: "Status", params: { status: "publish" } })
|
|
}
|
|
}
|
|
|
|
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
|
|
}))
|
|
})
|
|
})
|
|
// fetchListingDetailById(itemId.value).then(res => {
|
|
// console.log('iddetail',res)
|
|
// })
|
|
}
|
|
|
|
onMounted(() => {
|
|
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)
|
|
})
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
.c-svg {
|
|
width: initial;
|
|
height: initial;
|
|
}
|
|
|
|
.edit-detail-wrapper {
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100%;
|
|
min-height: 0;
|
|
margin-top: -1rem;
|
|
overflow: hidden;
|
|
|
|
&::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
.menu-btn {
|
|
height: 6rem;
|
|
border: 0.15rem solid #000000;
|
|
border-radius: 4rem;
|
|
text-align: center;
|
|
line-height: 6rem;
|
|
padding: 0 2rem;
|
|
font-size: 1.6rem;
|
|
column-gap: 0.8rem;
|
|
cursor: pointer;
|
|
transition: all 0.25s ease;
|
|
|
|
&:hover {
|
|
background: #000;
|
|
color: #fff;
|
|
}
|
|
|
|
// &.publish:hover {
|
|
// background: #fff;
|
|
// color: #000;
|
|
// }
|
|
}
|
|
|
|
.edit-detail-header {
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.operate-menu {
|
|
column-gap: 2rem;
|
|
|
|
// .publish {
|
|
// background-color: #000000;
|
|
// color: #ffffff;
|
|
// }
|
|
}
|
|
}
|
|
|
|
.edit-detail-content {
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow-y: auto;
|
|
justify-content: space-between;
|
|
|
|
&::-webkit-scrollbar {
|
|
width: 0;
|
|
height: 0;
|
|
}
|
|
|
|
.required {
|
|
&::after {
|
|
content: "*";
|
|
color: #df2b2c;
|
|
margin-left: 0.4rem;
|
|
}
|
|
}
|
|
|
|
.left {
|
|
// flex: 1;
|
|
// min-width: 0;
|
|
|
|
.main-image-container {
|
|
// max-width: 80.2rem;
|
|
column-gap: 3.5rem;
|
|
.main-image-item {
|
|
flex-shrink: 0;
|
|
|
|
.title {
|
|
font-size: 1.4rem;
|
|
margin-bottom: 0.8rem;
|
|
text-align: center;
|
|
}
|
|
|
|
.sketch-item {
|
|
width: 11.6rem;
|
|
height: 20.4rem;
|
|
border: 0.15rem solid #d1d1d1;
|
|
border-radius: 1rem;
|
|
position: relative;
|
|
background-color: #f6f6f6;
|
|
overflow: hidden;
|
|
|
|
&.cover {
|
|
width: 16.2rem;
|
|
background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' rx='11' ry='11' fill='none' stroke='%23D1D1D1' stroke-width='1.5' stroke-dasharray='8%2c 5' stroke-linecap='square'/%3e%3c/svg%3e");
|
|
border: none;
|
|
}
|
|
|
|
.crop-tool {
|
|
position: absolute;
|
|
top: 0.8rem;
|
|
right: 0.8rem;
|
|
width: 2rem;
|
|
height: 2rem;
|
|
border-radius: 50%;
|
|
background-color: #000000;
|
|
z-index: 1;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.sketch-img {
|
|
height: 100%;
|
|
&.sketch {
|
|
height: initial;
|
|
width: 100%;
|
|
}
|
|
}
|
|
|
|
.trigger {
|
|
cursor: pointer;
|
|
height: 100%;
|
|
padding: 6rem 2rem 0;
|
|
&,
|
|
.cover-trigger {
|
|
row-gap: 1.2rem;
|
|
}
|
|
|
|
.placeholder {
|
|
width: 2.4rem;
|
|
height: 2.4rem;
|
|
border-radius: 0.6rem;
|
|
background: linear-gradient(135deg, #efefef 0%, #cdcdcd 100%);
|
|
}
|
|
|
|
.trigger-tips {
|
|
font-size: 1.2rem;
|
|
text-align: center;
|
|
color: #585858;
|
|
line-height: 1.3;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.product-image-list-container {
|
|
margin-top: 3rem;
|
|
|
|
.title {
|
|
font-size: 1.4rem;
|
|
margin-bottom: 1.2rem;
|
|
|
|
.main-title {
|
|
font-weight: 400;
|
|
font-style: bold;
|
|
}
|
|
|
|
.sub-title {
|
|
font-size: 1.2rem;
|
|
color: #999;
|
|
}
|
|
|
|
.title-right {
|
|
color: #585858;
|
|
font-size: 1.4rem;
|
|
}
|
|
}
|
|
|
|
.product-image-list {
|
|
overflow-x: auto;
|
|
overflow-y: hidden;
|
|
column-gap: 0.8rem;
|
|
max-width: 80.2rem;
|
|
padding-bottom: 1.2rem;
|
|
|
|
&::-webkit-scrollbar {
|
|
height: 0.8rem;
|
|
}
|
|
|
|
&::-webkit-scrollbar-track {
|
|
background: #d9d9d9;
|
|
border-radius: 0.8rem;
|
|
}
|
|
|
|
&::-webkit-scrollbar-thumb {
|
|
background: #000000;
|
|
border-radius: 0.8rem;
|
|
}
|
|
|
|
.product-image-item {
|
|
width: 11.6rem;
|
|
height: 20.6rem;
|
|
border-radius: 1rem;
|
|
border: 0.15rem solid #c7c7c7;
|
|
position: relative;
|
|
cursor: pointer;
|
|
overflow: hidden;
|
|
flex-shrink: 0;
|
|
|
|
&::after {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
content: "";
|
|
background-color: #fcfcfc;
|
|
opacity: 0.7;
|
|
border-radius: 1rem;
|
|
}
|
|
|
|
&.selected {
|
|
border-color: #000;
|
|
|
|
&::after {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
.checked {
|
|
width: 2rem;
|
|
height: 2rem;
|
|
position: absolute;
|
|
top: 0.8rem;
|
|
right: 0.8rem;
|
|
z-index: 1;
|
|
}
|
|
|
|
.img-src {
|
|
height: 100%;
|
|
}
|
|
|
|
.main-pic {
|
|
position: absolute;
|
|
height: 2.4rem;
|
|
line-height: 2.4rem;
|
|
left: 0.8rem;
|
|
right: 0.8rem;
|
|
bottom: 0.8rem;
|
|
z-index: 1;
|
|
background: rgba(0, 0, 0, 0.8);
|
|
color: #fff;
|
|
font-size: 1.4rem;
|
|
border-radius: 1.2rem;
|
|
text-align: center;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.apparel-container {
|
|
margin-top: 3rem;
|
|
|
|
.title {
|
|
font-size: 1.4rem;
|
|
margin-bottom: 0.8rem;
|
|
|
|
.main-title {
|
|
font-weight: 400;
|
|
font-style: bold;
|
|
|
|
&::after {
|
|
content: "*";
|
|
color: #df2b2c;
|
|
}
|
|
}
|
|
|
|
.sub-title {
|
|
font-size: 1.2rem;
|
|
color: #999;
|
|
}
|
|
}
|
|
|
|
.sketch-list-container {
|
|
column-gap: 1rem;
|
|
flex-wrap: wrap;
|
|
|
|
.sketch-element {
|
|
width: 10rem;
|
|
height: 14.6rem;
|
|
border: 0.15rem solid #c7c7c7;
|
|
border-radius: 1.2rem;
|
|
position: relative;
|
|
overflow: hidden;
|
|
|
|
.img-src {
|
|
// height: 100%;
|
|
width: 100%;
|
|
}
|
|
|
|
.crop-tool {
|
|
position: absolute;
|
|
top: 0.4rem;
|
|
right: 0.4rem;
|
|
width: 2rem;
|
|
height: 2rem;
|
|
border-radius: 50%;
|
|
background-color: #000000;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.right {
|
|
width: 55.2rem;
|
|
flex-shrink: 0;
|
|
|
|
.form-container {
|
|
row-gap: 3rem;
|
|
|
|
.form-item {
|
|
.form-item-label {
|
|
font-size: 1.4rem;
|
|
font-weight: 400;
|
|
font-style: bold;
|
|
margin-bottom: 0.6rem;
|
|
line-height: 1.5;
|
|
|
|
&.with-tip {
|
|
display: flex;
|
|
align-items: center;
|
|
column-gap: 0.8rem;
|
|
}
|
|
|
|
.help-text {
|
|
font-size: 1rem;
|
|
color: #999;
|
|
}
|
|
}
|
|
|
|
.form-item-value {
|
|
border: 0.16rem solid #d1d1d1;
|
|
border-radius: 1.2rem;
|
|
position: relative;
|
|
padding: 1.6rem;
|
|
box-sizing: border-box;
|
|
font-size: 1.2rem;
|
|
color: #000;
|
|
|
|
&.no-border {
|
|
border: none;
|
|
padding: 0;
|
|
}
|
|
|
|
&.price {
|
|
column-gap: 0.6rem;
|
|
}
|
|
|
|
:deep(.ant-input),
|
|
:deep(.ant-input-affix-wrapper),
|
|
:deep(.ant-input-textarea textarea) {
|
|
border: none;
|
|
padding: 0;
|
|
font-size: 1.2rem;
|
|
color: #000;
|
|
box-shadow: none;
|
|
}
|
|
|
|
:deep(.ant-input) {
|
|
line-height: 1.5;
|
|
}
|
|
|
|
:deep(.ant-input-show-count-suffix) {
|
|
color: #df2c2c;
|
|
font-size: 1rem;
|
|
}
|
|
|
|
:deep(textarea.ant-input) {
|
|
resize: none;
|
|
min-height: 5.4rem;
|
|
padding-bottom: 1.8rem;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
:deep(.ant-input-textarea-show-count) {
|
|
position: relative;
|
|
&::after {
|
|
float: none;
|
|
position: absolute;
|
|
color: #df2c2c;
|
|
bottom: 0;
|
|
right: 1.6rem;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.license-note {
|
|
padding: 1.6rem;
|
|
column-gap: 1.6rem;
|
|
background: #f7f7f7;
|
|
border-radius: 0.8rem;
|
|
|
|
.info-icon {
|
|
width: 2.4rem;
|
|
height: 2.4rem;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.note-copy {
|
|
font-size: 1.2rem;
|
|
line-height: 1.5;
|
|
color: #000;
|
|
font-weight: 400;
|
|
font-style: medium;
|
|
|
|
a {
|
|
color: #0080ed;
|
|
text-decoration: underline;
|
|
margin-left: 0.4rem;
|
|
}
|
|
}
|
|
}
|
|
.page-control {
|
|
justify-content: flex-end;
|
|
margin-top: 4rem;
|
|
}
|
|
}
|
|
}
|
|
</style>
|