Merge branch 'dev_vite' of http://18.167.251.121:10003/aidlab/aida_front into dev_vite
This commit is contained in:
BIN
src/assets/images/seller/tips.png
Normal file
BIN
src/assets/images/seller/tips.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 686 B |
@@ -9,6 +9,11 @@
|
||||
"id": 2,
|
||||
"title": "AiDA X SFT AI Fashion Award 2024",
|
||||
"imgUrl": "/image/events/Fashion-Award-2024.png"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"title": "AiDA Global Design Awards 2026",
|
||||
"imgUrl": "/image/events/award-poster.gif"
|
||||
}
|
||||
],
|
||||
"eventsItem": [
|
||||
@@ -20,7 +25,7 @@
|
||||
{
|
||||
"paragraph": [
|
||||
{
|
||||
"text": "Click the “View Details” button for more information and to join the competition! The AiDA Global Design Award 2026 is an international design competition hosted by Code‑Create, a globally leading AI fashion solutions provider, celebrating the future of creativity powered by artificial intelligence. Open to designers from Hong Kong, China, Singapore, South Korea, and beyond, the competition brings together global talent, empowering AI as a creative partner—pushing fashion beyond traditional boundaries and unlocking new possibilities where technology amplifies human imagination."
|
||||
"text": "Click the “View Details” button for more information and to join the competition! The AiDA Global Design Award 2026 is an international design competition hosted by Code‑Create, a globally leading AI fashion solutions provider, celebrating the future of creativity powered by artificial intelligence. Open to designers worldwide the competition brings together global talent, empowering AI as a creative partner—pushing fashion beyond traditional boundaries and unlocking new possibilities where technology amplifies human imagination."
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
"id": 2,
|
||||
"title": "AiDA X SFT AI时尚设计比赛2024",
|
||||
"imgUrl": "/image/events/Fashion-Award-2024.png"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"title": "AiDA全球设计奖 2026",
|
||||
"imgUrl": "/image/events/award-poster-zh.gif"
|
||||
}
|
||||
],
|
||||
"eventsItem": [
|
||||
@@ -20,7 +25,7 @@
|
||||
{
|
||||
"paragraph": [
|
||||
{
|
||||
"text": "秉承推动 AI 赋能创意设计的初衷,Code‑Create 举办了「AiDA 全球设计大奖 2026」,面向来自香港、中国、新加坡、韩国及全球的设计师,鼓励大家探索 AI 与时尚设计的无限可能,突破传统界限,释放科技与想象力的创新潜能。点击“查看详情”按钮获取更多比赛信息,抓住成为 AI 时尚先锋的机会吧!"
|
||||
"text": "秉承推动 AI 赋能创意设计的初衷,Code‑Create 举办了「AiDA 全球设计大奖 2026」,面向来全球的设计师,鼓励大家探索 AI 与时尚设计的无限可能,突破传统界限,释放科技与想象力的创新潜能。点击“查看详情”按钮获取更多比赛信息,抓住成为 AI 时尚先锋的机会吧!"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1251,8 +1251,8 @@ tr > .ant-picker-cell-in-view.ant-picker-cell-range-hover-start:last-child::afte
|
||||
border-color: #000 !important;
|
||||
}
|
||||
.ant-spin .ant-spin-dot {
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
width: 4.5rem;
|
||||
height: 4.5rem;
|
||||
}
|
||||
.ant-spin-dot-item {
|
||||
background-color: #000000 !important;
|
||||
@@ -2470,6 +2470,22 @@ textarea:focus {
|
||||
opacity: 0.8;
|
||||
border-radius: 0.7rem;
|
||||
}
|
||||
.mini-scrollbar::-webkit-scrollbar {
|
||||
width: 0.4rem;
|
||||
}
|
||||
.mini-scrollbar::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.4rem;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.mosaic-bg {
|
||||
--mosaic-bg-size: 1rem;
|
||||
--mosaic-bg-color1: #efefef;
|
||||
--mosaic-bg-color2: #fff;
|
||||
background-image: repeating-conic-gradient(var(--mosaic-bg-color1) 0% 25%, var(--mosaic-bg-color2) 0% 50%);
|
||||
background-repeat: repeat;
|
||||
background-position: 50% 50%;
|
||||
background-size: var(--mosaic-bg-size) var(--mosaic-bg-size);
|
||||
}
|
||||
.mark_loading {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
@@ -2507,6 +2523,6 @@ textarea:focus {
|
||||
.justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
.flex-1{
|
||||
flex: 1;
|
||||
}
|
||||
.flex-1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@@ -1379,8 +1379,8 @@ tr > .ant-picker-cell-in-view.ant-picker-cell-range-hover-start:last-child::afte
|
||||
}
|
||||
//loding样式
|
||||
.ant-spin .ant-spin-dot{
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
width: 4.5rem;
|
||||
height: 4.5rem;
|
||||
}
|
||||
.ant-spin-dot-item{
|
||||
background-color: #000000 !important;
|
||||
|
||||
@@ -1,22 +1,37 @@
|
||||
<template>
|
||||
<div class="account_systemMessage">
|
||||
<div class="account_systemMessage">
|
||||
<div class="account_generalMessage_title modal_title_text">
|
||||
<!-- <span>系统消息</span> -->
|
||||
<div class="account_generalMessage_title_setting" @click="allRead">{{$t('account.AllRead')}}</div>
|
||||
<div class="account_generalMessage_title_setting" @click="allRead">
|
||||
{{ $t("account.AllRead") }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="account_generalMessage_item modal_title_text" v-for="item in dataList" :key="item.id" @click="setRead(item)">
|
||||
<div
|
||||
class="account_generalMessage_item modal_title_text"
|
||||
v-for="item in dataList"
|
||||
:key="item.id"
|
||||
@click="setRead(item)"
|
||||
>
|
||||
<a-badge :dot="item.isRead == 0"></a-badge>
|
||||
<div class="account_generalMessage_item_title">
|
||||
<div class="account_generalMessage_item_title_text" :title="item.content">{{ item.content.title }}</div>
|
||||
<div class="account_generalMessage_item_title_text" :title="item.content">
|
||||
{{ item.content.title }}
|
||||
</div>
|
||||
<div class="modal_title_text_intro">{{ item.createTime }}</div>
|
||||
</div>
|
||||
<div class="modal_title_text_intro">
|
||||
{{ item.content.content }}
|
||||
<span v-if="item.content.link" class="account_generalMessage_item_link">{{ item.content.link }}</span>
|
||||
<span v-if="item.content.link" class="account_generalMessage_item_link">{{
|
||||
item.content.link
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="account_generalMessage_item modal_title_text" style="display:flex;justify-content: center;" v-if="dataList.length == 0 && isNoData">
|
||||
{{$t('account.dataNull')}}
|
||||
<div
|
||||
class="account_generalMessage_item modal_title_text"
|
||||
style="display: flex; justify-content: center"
|
||||
v-if="dataList.length == 0 && isNoData"
|
||||
>
|
||||
{{ $t("account.dataNull") }}
|
||||
</div>
|
||||
<div class="page_loading_box" v-show="!isNoData">
|
||||
<span class="page_loading" ref="loadingDom" v-show="!isShowMark"></span>
|
||||
@@ -24,120 +39,138 @@
|
||||
<a-spin size="large" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent,computed,ref,reactive,nextTick,toRefs,createVNode, onMounted} from 'vue'
|
||||
import { Https } from "@/tool/https";
|
||||
import { useRouter,useRoute } from 'vue-router'
|
||||
import { useStore } from "vuex";
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import {
|
||||
defineComponent,
|
||||
computed,
|
||||
ref,
|
||||
reactive,
|
||||
nextTick,
|
||||
toRefs,
|
||||
createVNode,
|
||||
onMounted
|
||||
} from "vue"
|
||||
import { Https } from "@/tool/https"
|
||||
import { useRouter, useRoute } from "vue-router"
|
||||
import { useStore } from "vuex"
|
||||
import { useI18n } from "vue-i18n"
|
||||
import { isValidUrl } from "@/tool/util"
|
||||
export default defineComponent({
|
||||
components:{
|
||||
},
|
||||
components: {},
|
||||
// emits:['putListData'],
|
||||
props:['setReadStatus','setAllmessage','getHistory'],
|
||||
setup(prop,{emit}) {
|
||||
props: ["setReadStatus", "setAllmessage", "getHistory"],
|
||||
setup(prop, { emit }) {
|
||||
const router = useRouter()
|
||||
const store = useStore();
|
||||
const store = useStore()
|
||||
let accountMessage = reactive({
|
||||
dataList: [],
|
||||
page:1,
|
||||
size:10,
|
||||
page: 1,
|
||||
size: 10,
|
||||
isNoData: false,
|
||||
isShowMark: false,
|
||||
isShowMark: false
|
||||
})
|
||||
let loadingDom:any = ref(null)
|
||||
let setmessageList = ()=>{
|
||||
let loadingDom: any = ref(null)
|
||||
let setmessageList = () => {
|
||||
accountMessage.isShowMark = true
|
||||
let data = {
|
||||
page: accountMessage.page,
|
||||
size: accountMessage.size,
|
||||
size: accountMessage.size
|
||||
}
|
||||
prop.getHistory(data).then((rv:any)=>{
|
||||
accountMessage.isShowMark = false
|
||||
|
||||
if(rv.content.length == 0) {
|
||||
prop.getHistory(data)
|
||||
.then((rv: any) => {
|
||||
accountMessage.isShowMark = false
|
||||
|
||||
if (rv.content.length == 0) {
|
||||
accountMessage.isNoData = true
|
||||
} else {
|
||||
rv.content.forEach((item: any) => {
|
||||
item.content = JSON.parse(item.content)
|
||||
})
|
||||
accountMessage.dataList.push(...rv.content)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
accountMessage.isShowMark = false
|
||||
accountMessage.isNoData = true
|
||||
}else{
|
||||
rv.content.forEach((item:any) => {
|
||||
item.content = JSON.parse(item.content)
|
||||
});
|
||||
accountMessage.dataList.push(...rv.content)
|
||||
})
|
||||
}
|
||||
let setRead = (item: any) => {
|
||||
let content = item.content.content
|
||||
if (isValidUrl(content)) {
|
||||
if (import.meta.env.VITE_APP_BASE_URL === "https://develop.api.aida.com.hk") {
|
||||
content += "&env=dev"
|
||||
}
|
||||
}).catch(() => {
|
||||
accountMessage.isShowMark = false
|
||||
accountMessage.isNoData = true
|
||||
})
|
||||
}
|
||||
let setRead = (item:any)=>{
|
||||
prop.setReadStatus(item).then((rv:any)=>{
|
||||
item.isRead = 1
|
||||
}).catch((err:any)=>{
|
||||
})
|
||||
}
|
||||
let allRead = ()=>{
|
||||
// emit('setAllmessage')
|
||||
prop.setAllmessage().then(()=>{
|
||||
accountMessage.dataList.forEach((item:any)=>{
|
||||
window.open(content, "_blank")
|
||||
}
|
||||
|
||||
prop.setReadStatus(item)
|
||||
.then((rv: any) => {
|
||||
item.isRead = 1
|
||||
})
|
||||
}).catch((err:any)=>{
|
||||
})
|
||||
.catch((err: any) => {})
|
||||
}
|
||||
let allRead = () => {
|
||||
// emit('setAllmessage')
|
||||
prop.setAllmessage()
|
||||
.then(() => {
|
||||
accountMessage.dataList.forEach((item: any) => {
|
||||
item.isRead = 1
|
||||
})
|
||||
})
|
||||
.catch((err: any) => {})
|
||||
}
|
||||
// provide('exhibitionList',exhibitionList)
|
||||
onMounted (()=>{
|
||||
onMounted(() => {
|
||||
accountMessage.isNoData = false
|
||||
accountMessage.page = 0
|
||||
let imgParent:any = document.querySelector('.account_systemMessage .page_loading')
|
||||
let imgParent: any = document.querySelector(".account_systemMessage .page_loading")
|
||||
new IntersectionObserver(
|
||||
(entries, observer) => {
|
||||
// 如果不是相交,则直接返回
|
||||
// console.log(entries[0]);
|
||||
if (!entries[0].intersectionRatio) return;
|
||||
accountMessage.page+=1
|
||||
if (!entries[0].intersectionRatio) return
|
||||
accountMessage.page += 1
|
||||
setmessageList()
|
||||
},
|
||||
}
|
||||
// { root:worksPage }
|
||||
).observe(loadingDom.value);
|
||||
).observe(loadingDom.value)
|
||||
})
|
||||
return{
|
||||
...toRefs(accountMessage),
|
||||
setmessageList,
|
||||
setRead,
|
||||
allRead,
|
||||
loadingDom,
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
|
||||
}
|
||||
},
|
||||
return {
|
||||
...toRefs(accountMessage),
|
||||
setmessageList,
|
||||
setRead,
|
||||
allRead,
|
||||
loadingDom
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.account_systemMessage{
|
||||
.account_systemMessage {
|
||||
width: 100%;
|
||||
.account_generalMessage_item{
|
||||
.account_generalMessage_item {
|
||||
font-size: var(--aida-fsize1-6);
|
||||
.account_generalMessage_item_title{
|
||||
.account_generalMessage_item_title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
.account_generalMessage_item_title_text{
|
||||
.account_generalMessage_item_title_text {
|
||||
max-width: 80%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.modal_title_text_intro{
|
||||
.modal_title_text_intro {
|
||||
margin-left: 4rem;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
.modal_title_text_intro{
|
||||
.modal_title_text_intro {
|
||||
word-break: break-word;
|
||||
white-space: pre-wrap;
|
||||
font-family: Arial, sans-serif;
|
||||
|
||||
@@ -233,10 +233,10 @@ export default defineComponent({
|
||||
let sketchH = editPrintElementData.sketchWH.height * editPrintElementData.sketchWH.scale[1]
|
||||
let x = sketchW / 2 - (sketchW * (width / editPrintElementData.sketchWH.width)/2)
|
||||
let y = sketchH / 2 -(sketchH * height/2)
|
||||
if(editPrintElementData.stateOverallSingle !== 'single'){
|
||||
x = sketchW / 2
|
||||
y = sketchH / 2
|
||||
}
|
||||
// if(editPrintElementData.stateOverallSingle !== 'single'){
|
||||
// x = sketchW / 2
|
||||
// y = sketchH / 2
|
||||
// }
|
||||
let location = [x,y]
|
||||
resolve({scale,location})
|
||||
}
|
||||
|
||||
@@ -21,7 +21,11 @@
|
||||
{{ $t("event.detail") }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal_title_text content" v-for="item in eventsDetail.textList">
|
||||
<div
|
||||
class="modal_title_text content"
|
||||
v-for="item in eventsDetail.textList"
|
||||
:class="{ award: eventsDetail.id === 3 }"
|
||||
>
|
||||
<div class="eventsDetail_content_right_btn_box">
|
||||
<div
|
||||
class="eventsDetail_content_right_btn"
|
||||
@@ -122,9 +126,14 @@ export default defineComponent({
|
||||
const openDetail = () => {
|
||||
let language = locale.value === "ENGLISH" ? "en" : "zh"
|
||||
let url = `https://aida-global-design-awards.com.hk/${language}`
|
||||
// 如果是dev环境把域名换成http://192.168.31.198
|
||||
|
||||
if (import.meta.env.VITE_APP_BASE_URL === "https://develop.api.aida.com.hk") {
|
||||
url += "?env=dev"
|
||||
}
|
||||
window.open(url, "_blank")
|
||||
|
||||
// router.push("/award/index")
|
||||
// router.push("/award/index")
|
||||
}
|
||||
onMounted(() => {
|
||||
const currentLocale = locale.value
|
||||
@@ -265,18 +274,21 @@ export default defineComponent({
|
||||
.eventsDetail_content_right_btn_box {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
.eventsDetail_content_right_btn {
|
||||
}
|
||||
// .eventsDetail_content_right_btn {
|
||||
// }
|
||||
}
|
||||
}
|
||||
.modal_title_text:last-child {
|
||||
}
|
||||
// .modal_title_text:last-child {
|
||||
// }
|
||||
.modal_title_text:last-child::after {
|
||||
content: "";
|
||||
display: block;
|
||||
border-top: 3px solid;
|
||||
height: 6rem;
|
||||
}
|
||||
.modal_title_text.award:last-child:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1748,5 +1748,17 @@ export default {
|
||||
productImageSubTitle:' (来自设计集)',
|
||||
apparelSketchTitle:'服装线稿图 ',
|
||||
apparelSketchSubTitle:' (来自设计集)',
|
||||
productName:'商品名称',
|
||||
price:'价格',
|
||||
productDescription:'商品描述',
|
||||
designFor:'目标人群',
|
||||
productCategory:'商品类别',
|
||||
categoryTips:'请选择所有适用选项',
|
||||
policy:'默认情况下,所有销售均遵循平台的许可政策——买家在下载后将获得使用许可',
|
||||
learnMore:'了解更多',
|
||||
draftSaved: '草稿已保存',
|
||||
draftDesc: '您的商品已保存为草稿。\n您可以继续编辑,或稍后在“我的商品”中发布。',
|
||||
listingLive:'商品已上架',
|
||||
publishDesc:'您的商品现已上架。\n买家可以浏览并购买您的设计。'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1799,5 +1799,17 @@ export default {
|
||||
productImageSubTitle:'(from design collection)',
|
||||
apparelSketchTitle:'Apparel Sketch ',
|
||||
apparelSketchSubTitle:'(from design collection)',
|
||||
productName:'Product Name',
|
||||
price:'Price',
|
||||
productDescription:'Product Description',
|
||||
designFor:'Designed For',
|
||||
productCategory:'Product Category',
|
||||
categoryTips:'select all that apply',
|
||||
policy:'By default, all sales follow the platform\'s licensing policy — buyers will receive a usage license upon download.',
|
||||
learnMore:'Learn more',
|
||||
draftSaved: 'Draft Saved',
|
||||
draftDesc: 'Your listing has been saved as a draft. \nYou can continue editing or publish it later from My Listings.',
|
||||
listingLive:'Listing Live',
|
||||
publishDesc:'Your listing is now live on the marketplace.\nBuyers can discover and purchase your design.'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,6 +220,13 @@ const routes: Array<RouteRecordRaw> = [
|
||||
meta: { enter: "all" },
|
||||
component: () =>
|
||||
import("@/views/SellerDashboard/MyListings/EditDetail/index.vue")
|
||||
},
|
||||
{
|
||||
path:'edit/status/:status',
|
||||
name:'Status',
|
||||
meta:{enter:'all'},
|
||||
component: () =>
|
||||
import("@/views/SellerDashboard/MyListings/EditDetail/Status.vue")
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -483,7 +490,6 @@ const routes: Array<RouteRecordRaw> = [
|
||||
},
|
||||
component: () => import("@/views/userManual.vue")
|
||||
},
|
||||
|
||||
{
|
||||
path: "/:catchAll(.*)",
|
||||
redirect: "/404"
|
||||
|
||||
@@ -672,6 +672,17 @@ function sketchToMask(sketchImage) {
|
||||
img.src = sketchImage;
|
||||
});
|
||||
}
|
||||
|
||||
function isValidUrl(string) {
|
||||
try {
|
||||
const url = new URL(string)
|
||||
// 通常我们只需要 http 或 https 协议
|
||||
return url.protocol === "http:" || url.protocol === "https:"
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
isEmail,
|
||||
getUploadUrl,
|
||||
@@ -695,5 +706,6 @@ export {
|
||||
calculateGradientCoordinate,
|
||||
segmentImage,
|
||||
UrlToFile,
|
||||
sketchToMask
|
||||
sketchToMask,
|
||||
isValidUrl
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<div class="edit-detail-wrapper">
|
||||
<div class="edit-detail-header flex align-center space-between">
|
||||
<div class="bread-crumb">导航</div>
|
||||
<div class="operate-menu flex">
|
||||
<div class="menu-btn flex align-center save">
|
||||
<span>Save Draft</span>
|
||||
<SvgIcon name="CSave" color="#000000" size="16" />
|
||||
</div>
|
||||
<div class="menu-btn flex align-center publish">
|
||||
<span>Publish</span>
|
||||
<SvgIcon name="CPublish" color="#ffffff" size="16" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="edit-detail-content"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.c-svg {
|
||||
width: initial;
|
||||
}
|
||||
.edit-detail-wrapper {
|
||||
.menu-btn {
|
||||
height: 6rem;
|
||||
border: 0.15rem solid #000000;
|
||||
border-radius: 4rem;
|
||||
text-align: center;
|
||||
line-height: 6rem;
|
||||
padding: 0 2rem;
|
||||
font-weight: 400;
|
||||
font-size: 1.6rem;
|
||||
column-gap: 0.8rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
.edit-detail-header {
|
||||
width: 100%;
|
||||
height: 6rem;
|
||||
margin-bottom: 2rem;
|
||||
.operate-menu {
|
||||
column-gap: 2rem;
|
||||
.publish {
|
||||
background-color: #000000;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.edit-detail-content{
|
||||
padding-right: 6.4rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
78
src/views/SellerDashboard/MyListings/EditDetail/Status.vue
Normal file
78
src/views/SellerDashboard/MyListings/EditDetail/Status.vue
Normal file
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<div class="status-wrapper flex flex-col 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' },
|
||||
{ title: $t(title), name: 'Status' }
|
||||
]"
|
||||
/>
|
||||
<div class="status-container flex flex-col flex-1 flex-center">
|
||||
<img src="@/assets/images/seller/success-0.png" class="icon" alt="" />
|
||||
<div class="title">{{ $t(title) }}</div>
|
||||
<div class="desc">
|
||||
{{ $t(desc) }}
|
||||
</div>
|
||||
<div class="btn">Back to My Listings</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from "vue"
|
||||
import { useRoute } from "vue-router"
|
||||
import SellerHeader from "../../seller-header.vue"
|
||||
const ROUTE = useRoute()
|
||||
const title = computed(() => {
|
||||
if (ROUTE.params.status === "publish") return "SellerListEdit.listingLive"
|
||||
if (ROUTE.params.status === "draft") return "SellerListEdit.draftSaved"
|
||||
})
|
||||
|
||||
const desc = computed(() => {
|
||||
if (ROUTE.params.status === "publish") return "SellerListEdit.publishDesc"
|
||||
if (ROUTE.params.status === "draft") return "SellerListEdit.draftDesc"
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.status-wrapper {
|
||||
.status-container {
|
||||
row-gap: 2.4rem;
|
||||
font-weight: 400;
|
||||
.title {
|
||||
font-size: 2.2rem;
|
||||
}
|
||||
.icon {
|
||||
width: 8.33rem;
|
||||
height: 8.33rem;
|
||||
}
|
||||
.desc {
|
||||
width: 58.2rem;
|
||||
text-align: center;
|
||||
white-space: pre-line;
|
||||
color: #585858;
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-top: 3.6rem;
|
||||
height: 6rem;
|
||||
width: 30rem;
|
||||
border-radius: 4rem;
|
||||
text-align: center;
|
||||
line-height: 6rem;
|
||||
padding: 0 2rem;
|
||||
font-size: 1.6rem;
|
||||
column-gap: 0.8rem;
|
||||
cursor: pointer;
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<div class="radio-button-group">
|
||||
<button
|
||||
v-for="item in options"
|
||||
:key="item.key"
|
||||
type="button"
|
||||
:class="[
|
||||
'radio-button',
|
||||
{
|
||||
'is-active': multiple
|
||||
? selectedValues.includes(item.key)
|
||||
: modelValue === item.key
|
||||
}
|
||||
]"
|
||||
@click="selectOption(item.key)"
|
||||
>
|
||||
{{ item.name }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue"
|
||||
|
||||
interface Option {
|
||||
name: string | number
|
||||
value: string | number | boolean
|
||||
key: string
|
||||
optype: boolean
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: string | number | boolean | Array<string | number | boolean> | null
|
||||
options: Option[] // 按钮选项数组
|
||||
multiple?: boolean // 是否支持多选,默认为 false
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "update:modelValue", value: any): void
|
||||
}>()
|
||||
|
||||
const multiple = props.multiple === true
|
||||
|
||||
const selectedValues = computed(() => {
|
||||
if (!multiple) {
|
||||
return typeof props.modelValue === 'undefined' || props.modelValue === null
|
||||
? []
|
||||
: [props.modelValue]
|
||||
}
|
||||
|
||||
return Array.isArray(props.modelValue) ? props.modelValue : []
|
||||
})
|
||||
|
||||
const selectOption = (value: any) => {
|
||||
if (multiple) {
|
||||
const current = Array.isArray(props.modelValue) ? [...props.modelValue] : []
|
||||
const index = current.indexOf(value)
|
||||
if (index >= 0) {
|
||||
current.splice(index, 1)
|
||||
} else {
|
||||
current.push(value)
|
||||
}
|
||||
emit("update:modelValue", current)
|
||||
return
|
||||
}
|
||||
|
||||
if (props.modelValue !== value) {
|
||||
emit("update:modelValue", value)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.radio-button-group {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.radio-button {
|
||||
border: 1px solid #d9d9d9;
|
||||
height: 3.2rem;
|
||||
min-width: 8rem;
|
||||
padding: 0 1.7rem;
|
||||
color: #000;
|
||||
cursor: pointer;
|
||||
border-radius: 2rem;
|
||||
outline: none;
|
||||
background-color: #fff;
|
||||
font-size: 1.2rem;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.radio-button:hover {
|
||||
border-color: #000;
|
||||
}
|
||||
|
||||
.radio-button.is-active {
|
||||
color: #fff;
|
||||
background-color: #000;
|
||||
border-color: #000;
|
||||
font-family: pingfang_medium;
|
||||
}
|
||||
</style>
|
||||
@@ -12,18 +12,21 @@
|
||||
>
|
||||
<template #right>
|
||||
<div class="operate-menu flex">
|
||||
<div class="menu-btn flex align-center save">
|
||||
<div class="menu-btn flex align-center save" @click="handleClickMenu('draft')">
|
||||
<span>{{ $t("SellerListEdit.saveDraft") }}</span>
|
||||
<SvgIcon name="CSave" color="#000000" size="16" />
|
||||
<SvgIcon name="CSave" size="16" />
|
||||
</div>
|
||||
<div class="menu-btn flex align-center publish">
|
||||
<div
|
||||
class="menu-btn flex align-center publish"
|
||||
@click="handleClickMenu('publish')"
|
||||
>
|
||||
<span>{{ $t("SellerListEdit.publish") }}</span>
|
||||
<SvgIcon name="CPublish" color="#ffffff" size="16" />
|
||||
<SvgIcon name="CPublish" size="16" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</seller-header>
|
||||
<div class="edit-detail-content flex space-between">
|
||||
<div class="edit-detail-content flex">
|
||||
<div class="left">
|
||||
<div class="main-image-container flex">
|
||||
<div
|
||||
@@ -32,25 +35,20 @@
|
||||
:class="`main-image-item flex flex-col align-center ${type}`"
|
||||
>
|
||||
<div class="title" :class="{ required: type !== 'mainProductImage' }">
|
||||
{{ $t(`SellerListEdit.${type}`) }}
|
||||
{{ topImageTitleMap[type] }}
|
||||
</div>
|
||||
<div class="sketch-item flex flex-center" :class="type">
|
||||
<div
|
||||
v-show="selectList[currentIndex][type]"
|
||||
class="crop-tool flex flex-center"
|
||||
>
|
||||
<div v-if="previewImageMap[type]" class="crop-tool flex flex-center">
|
||||
<SvgIcon name="CCrop" color="#fff" size="12" />
|
||||
</div>
|
||||
<img
|
||||
v-show="selectList[currentIndex][type]"
|
||||
:src="selectList[currentIndex][type]"
|
||||
v-if="previewImageMap[type]"
|
||||
:src="previewImageMap[type]"
|
||||
class="sketch-img"
|
||||
:class="{ cover: type === 'cover' }"
|
||||
alt=""
|
||||
/>
|
||||
<div
|
||||
class="trigger flex flex-col align-center"
|
||||
v-show="!selectList[currentIndex][type]"
|
||||
>
|
||||
<div v-else class="trigger flex flex-col align-center">
|
||||
<template v-if="type === 'cover'">
|
||||
<SvgIcon
|
||||
class="trigger-icon"
|
||||
@@ -63,10 +61,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<img
|
||||
src="@/assets/images/seller/image-placeholder.png"
|
||||
class="trigger-img"
|
||||
/>
|
||||
<div class="trigger-img placeholder"></div>
|
||||
<div class="trigger-tips">
|
||||
{{ $t("SellerListEdit.productImageDesc") }}
|
||||
</div>
|
||||
@@ -92,17 +87,18 @@
|
||||
<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 }"
|
||||
:key="index"
|
||||
@click="handleSelectProdImg(index)"
|
||||
>
|
||||
<img
|
||||
v-show="item.selected"
|
||||
v-if="item.selected"
|
||||
src="@/assets/images/seller/checked.png"
|
||||
class="checked"
|
||||
alt=""
|
||||
/>
|
||||
<img class="img-src" :src="item.url" />
|
||||
<img class="img-src" :src="item.url" alt="" />
|
||||
<div
|
||||
v-if="item.selected && index === firstSelectedIndex"
|
||||
class="main-pic"
|
||||
@@ -127,7 +123,7 @@
|
||||
:key="index"
|
||||
class="sketch-element flex flex-center"
|
||||
>
|
||||
<img class="img-src" :src="item.url" />
|
||||
<img class="img-src" :src="item.url" alt="" />
|
||||
<div class="crop-tool flex flex-center">
|
||||
<SvgIcon name="CCrop" color="#fff" size="12" />
|
||||
</div>
|
||||
@@ -138,12 +134,13 @@
|
||||
<div class="right">
|
||||
<div class="form-container flex flex-col">
|
||||
<div class="form-item">
|
||||
<div class="form-item-label required">Product Name</div>
|
||||
<div class="form-item-label required">
|
||||
{{ $t("SellerListEdit.productName") }}
|
||||
</div>
|
||||
<div class="form-item-value product-name">
|
||||
<a-input
|
||||
v-model:value="selectList[currentIndex].productName"
|
||||
v-model:value="currentListing.productName"
|
||||
show-count
|
||||
:rows="2"
|
||||
placeholder="Enter product name"
|
||||
:bordered="false"
|
||||
:maxlength="60"
|
||||
@@ -151,16 +148,66 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-item-label required">Price</div>
|
||||
<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="selectList[currentIndex].desc"
|
||||
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 :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">
|
||||
<a-pagination
|
||||
v-model:current="currentPage"
|
||||
:total="selectList.length"
|
||||
:page-size="1"
|
||||
showQuickJumper
|
||||
showLessItems
|
||||
responsive
|
||||
:showSizeChanger="false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -168,14 +215,62 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from "vue"
|
||||
import { computed, ref, watch, defineOptions } from "vue"
|
||||
import { useRouter } from "vue-router"
|
||||
import SellerHeader from "../../seller-header.vue"
|
||||
import testImg from "@/assets/images/test.png"
|
||||
import { ElInput } from "element-plus"
|
||||
import Radio from "./components/Radio.vue"
|
||||
import { Https } from "@/tool/https"
|
||||
import { useStore } from "vuex"
|
||||
|
||||
const topImageList = ["sketch", "mainProductImage", "cover"]
|
||||
const currentIndex = ref(0)
|
||||
const selectList = ref([
|
||||
const ROUTER = useRouter()
|
||||
|
||||
defineOptions({
|
||||
name: "EditDetail"
|
||||
})
|
||||
|
||||
const STORE = useStore()
|
||||
|
||||
type CategoryOption = {
|
||||
label: string
|
||||
value: string
|
||||
}
|
||||
|
||||
type ListingItem = {
|
||||
sketch: string
|
||||
mainProductImage: string
|
||||
cover: string
|
||||
productImage: string[]
|
||||
apparelSketch: string[]
|
||||
productName: string
|
||||
price: string
|
||||
desc: string
|
||||
gender: string
|
||||
category: string
|
||||
prodImageList: Array<{
|
||||
url: string
|
||||
selected: boolean
|
||||
}>
|
||||
}
|
||||
|
||||
const topImageList = ["sketch", "mainProductImage", "cover"] as const
|
||||
const topImageTitleMap: Record<(typeof topImageList)[number], string> = {
|
||||
sketch: "Sketch",
|
||||
mainProductImage: "Main Product Image",
|
||||
cover: "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 selectList = ref<ListingItem[]>([
|
||||
{
|
||||
sketch: testImg,
|
||||
mainProductImage: "",
|
||||
@@ -183,69 +278,117 @@ const selectList = ref([
|
||||
productImage: [],
|
||||
apparelSketch: [],
|
||||
productName: "",
|
||||
price: "",
|
||||
price: "12",
|
||||
desc: "",
|
||||
gender: "FEMALE",
|
||||
category: "",
|
||||
prodImageList: [
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false }
|
||||
]
|
||||
},
|
||||
{
|
||||
sketch: testImg,
|
||||
mainProductImage: "",
|
||||
cover: "",
|
||||
productImage: [],
|
||||
apparelSketch: [],
|
||||
productName: "",
|
||||
price: "12",
|
||||
desc: "",
|
||||
gender: "",
|
||||
category: ""
|
||||
}
|
||||
])
|
||||
const prodImgList = ref([
|
||||
{
|
||||
url: testImg,
|
||||
selected: false
|
||||
category: "",
|
||||
prodImageList: [
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false }
|
||||
]
|
||||
},
|
||||
{
|
||||
url: testImg,
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
url: testImg,
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
url: testImg,
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
url: testImg,
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
url: testImg,
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
url: testImg,
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
url: testImg,
|
||||
selected: false
|
||||
sketch: testImg,
|
||||
mainProductImage: "",
|
||||
cover: "",
|
||||
productImage: [],
|
||||
apparelSketch: [],
|
||||
productName: "",
|
||||
price: "12",
|
||||
desc: "",
|
||||
gender: "",
|
||||
category: "",
|
||||
prodImageList: [
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false },
|
||||
{ url: testImg, selected: false }
|
||||
]
|
||||
}
|
||||
])
|
||||
|
||||
const prodImgList = computed(() => currentListing.value.prodImageList || [])
|
||||
|
||||
const sketchList = ref([{ url: testImg }, { url: testImg }, { url: testImg }])
|
||||
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 ||
|
||||
currentListing.value.mainProductImage ||
|
||||
currentListing.value.sketch
|
||||
}))
|
||||
|
||||
const firstSelectedIndex = ref(null) //显示main标签的图片索引
|
||||
const selectedProdImgs = computed(() => {
|
||||
return prodImgList.value.filter((item) => item.selected).length
|
||||
})
|
||||
|
||||
const firstSelectedIndex = ref(-1)
|
||||
|
||||
const handleSelectProdImg = (index: number) => {
|
||||
const item = prodImgList.value[index]
|
||||
item.selected = !item.selected
|
||||
const target = prodImgList.value[index]
|
||||
|
||||
if (item.selected) {
|
||||
if (firstSelectedIndex.value === -1) {
|
||||
firstSelectedIndex.value = index
|
||||
selectList.value[currentIndex.value].mainProductImage = item.url
|
||||
}
|
||||
} else if (firstSelectedIndex.value === index) {
|
||||
selectList.value[currentIndex.value].mainProductImage = null
|
||||
firstSelectedIndex.value = -1
|
||||
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 sketchList = ref([{ url: testImg }, { url: testImg }, { url: testImg }])
|
||||
const handleClickMenu = (status: "draft" | "publish") => {
|
||||
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" } })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@@ -255,8 +398,13 @@ const sketchList = ref([{ url: testImg }, { url: testImg }, { url: testImg }])
|
||||
}
|
||||
|
||||
.edit-detail-wrapper {
|
||||
overflow-y: auto;
|
||||
// set the scollbar hidden
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
margin-top: -1rem;
|
||||
overflow: hidden;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
@@ -268,26 +416,47 @@ const sketchList = ref([{ url: testImg }, { url: testImg }, { url: testImg }])
|
||||
text-align: center;
|
||||
line-height: 6rem;
|
||||
padding: 0 2rem;
|
||||
font-weight: 400;
|
||||
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;
|
||||
}
|
||||
// .publish {
|
||||
// background-color: #000000;
|
||||
// color: #ffffff;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
.edit-detail-content {
|
||||
padding-right: 6.4rem;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
justify-content: space-between;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.required {
|
||||
&::after {
|
||||
content: "*";
|
||||
@@ -295,17 +464,23 @@ const sketchList = ref([{ url: testImg }, { url: testImg }, { url: testImg }])
|
||||
margin-left: 0.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
// flex: 1;
|
||||
// min-width: 0;
|
||||
|
||||
.main-image-container {
|
||||
column-gap: 3.6rem;
|
||||
// max-width: 80.2rem;
|
||||
|
||||
.main-image-item {
|
||||
flex-shrink: 0;
|
||||
|
||||
.title {
|
||||
font-weight: 400;
|
||||
font-style: bold;
|
||||
font-size: 1.4rem;
|
||||
margin-bottom: 0.8rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sketch-item {
|
||||
width: 11.6rem;
|
||||
height: 20.4rem;
|
||||
@@ -313,62 +488,77 @@ const sketchList = ref([{ url: testImg }, { url: testImg }, { url: testImg }])
|
||||
border-radius: 1rem;
|
||||
position: relative;
|
||||
background-color: #f6f6f6;
|
||||
overflow: hidden;
|
||||
|
||||
&.cover {
|
||||
width: 16.17rem;
|
||||
// border-style: dashed;
|
||||
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;
|
||||
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' fill='none' stroke='%23D1D1D1' stroke-width='1.5' stroke-dasharray='13%2c 5' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e");
|
||||
}
|
||||
|
||||
.crop-tool {
|
||||
position: absolute;
|
||||
top: 0.4rem;
|
||||
right: 0.4rem;
|
||||
top: 0.8rem;
|
||||
right: 0.8rem;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
background-color: #000000;
|
||||
z-index: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.sketch-img {
|
||||
// width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.trigger {
|
||||
row-gap: 1.2rem;
|
||||
cursor: pointer;
|
||||
height: 100%;
|
||||
padding-top: 6.8rem;
|
||||
.trigger-img {
|
||||
padding: 6rem 2rem 0;
|
||||
|
||||
.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;
|
||||
width: 9rem;
|
||||
text-align: center;
|
||||
color: #585858;
|
||||
line-height: 1.3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.product-image-list-container {
|
||||
margin-top: 3rem;
|
||||
|
||||
.title {
|
||||
font-weight: 400;
|
||||
font-style: bold;
|
||||
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;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
.product-image-list {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
@@ -376,19 +566,18 @@ const sketchList = ref([{ url: testImg }, { url: testImg }, { url: testImg }])
|
||||
max-width: 80.2rem;
|
||||
padding-bottom: 1.2rem;
|
||||
|
||||
//滚动条高度0.8rem,背景色#D9D9D9,滚动条圆角0.4rem,小方块为黑色
|
||||
&::-webkit-scrollbar {
|
||||
height: 0.8rem;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: #d9d9d9;
|
||||
border-radius: 0.8rem;
|
||||
height: 0.8rem;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: #000000;
|
||||
border-radius: 0.8rem;
|
||||
height: 0.8rem;
|
||||
}
|
||||
|
||||
.product-image-item {
|
||||
@@ -398,6 +587,9 @@ const sketchList = ref([{ url: testImg }, { url: testImg }, { url: testImg }])
|
||||
border: 0.15rem solid #c7c7c7;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -409,22 +601,28 @@ const sketchList = ref([{ url: testImg }, { url: testImg }, { url: testImg }])
|
||||
opacity: 0.7;
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
// border-color: #000000;
|
||||
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;
|
||||
@@ -433,8 +631,7 @@ const sketchList = ref([{ url: testImg }, { url: testImg }, { url: testImg }])
|
||||
right: 0.8rem;
|
||||
bottom: 0.8rem;
|
||||
z-index: 1;
|
||||
background: #000000cc;
|
||||
font-weight: 400;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
color: #fff;
|
||||
font-size: 1.4rem;
|
||||
border-radius: 1.2rem;
|
||||
@@ -443,34 +640,46 @@ const sketchList = ref([{ url: testImg }, { url: testImg }, { url: testImg }])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.apparel-container {
|
||||
margin-top: 3rem;
|
||||
|
||||
.title {
|
||||
font-weight: 400;
|
||||
font-style: bold;
|
||||
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 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.crop-tool {
|
||||
position: absolute;
|
||||
top: 0.4rem;
|
||||
@@ -478,24 +687,40 @@ const sketchList = ref([{ url: testImg }, { url: testImg }, { url: testImg }])
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
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;
|
||||
@@ -503,32 +728,87 @@ const sketchList = ref([{ url: testImg }, { url: testImg }, { url: testImg }])
|
||||
padding: 1.6rem;
|
||||
box-sizing: border-box;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 400;
|
||||
color: #000;
|
||||
|
||||
&.no-border {
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&.price {
|
||||
column-gap: 0.6rem;
|
||||
}
|
||||
|
||||
:deep(.ant-input) {
|
||||
:deep(.ant-input),
|
||||
:deep(.ant-input-affix-wrapper),
|
||||
:deep(.ant-input-textarea textarea) {
|
||||
border: none;
|
||||
padding: 0;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 400;
|
||||
color: #000;
|
||||
box-shadow: none;
|
||||
}
|
||||
:deep(.ant-input-affix-wrapper) {
|
||||
padding: 0;
|
||||
font-weight: 400;
|
||||
input {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
: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>
|
||||
|
||||
@@ -245,7 +245,7 @@ const { showDrafts } = toRefs(data);
|
||||
v-bind="config"
|
||||
:group="{
|
||||
name: 'sortable',
|
||||
pull: true,
|
||||
pull: false,
|
||||
put: true
|
||||
}"
|
||||
>
|
||||
|
||||
@@ -20,8 +20,8 @@ const fun = ref(null)
|
||||
|
||||
let deleteDraftsRef = ref(null)
|
||||
|
||||
const open = (fun)=>{
|
||||
fun.value = fun
|
||||
const open = (deleteFun)=>{
|
||||
fun.value = deleteFun
|
||||
emit('update:visible', true)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user