Merge branch 'dev_vite' of ssh://18.167.251.121:10002/aidlab/aida_front into dev_vite
This commit is contained in:
@@ -116,8 +116,18 @@
|
||||
() => props.isEdit,
|
||||
(v) => (v ? edit() : cancel())
|
||||
)
|
||||
const edit = () => {}
|
||||
const cancel = () => {}
|
||||
const edit = () => {
|
||||
formData.storeName = "测试"
|
||||
formData.fullName = "测试"
|
||||
formData.email = "测试"
|
||||
formData.phoneNumber = "测试"
|
||||
formData.description = "测试"
|
||||
formData.links = ["https://www.baidu.com", "https://www.taobao.com"]
|
||||
}
|
||||
const cancel = () => {
|
||||
formRef.value.clearValidate()
|
||||
edit()
|
||||
}
|
||||
const submit = async () => {
|
||||
const valid = await formRef.value.validate()
|
||||
if (!valid) return Promise.reject(false)
|
||||
|
||||
166
src/views/SellerDashboard/BrandProfile/image-clip-dialog.vue
Normal file
166
src/views/SellerDashboard/BrandProfile/image-clip-dialog.vue
Normal file
@@ -0,0 +1,166 @@
|
||||
<template>
|
||||
<a-modal
|
||||
class="image-clip-dialog generalModel"
|
||||
v-model:visible="show"
|
||||
:footer="null"
|
||||
width="70%"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
:closable="false"
|
||||
wrapClassName="#app"
|
||||
:keyboard="false"
|
||||
>
|
||||
<div class="image-clip-dialog-box">
|
||||
<div class="header">
|
||||
<div class="title">{{ data.title }}</div>
|
||||
<div class="right">
|
||||
<div class="submit" v-if="!data.isPreview" @click="onSubmit">
|
||||
<svg-icon name="seller-dui" size="24" />
|
||||
</div>
|
||||
<button @click="onCancel">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<image-clip
|
||||
ref="imageClipRef"
|
||||
:ratio="data.ratio"
|
||||
:url="data.url"
|
||||
@change="(v) => (data.preview_url = v)"
|
||||
/>
|
||||
<div class="preview" v-if="data.isPreview">
|
||||
<div class="title">
|
||||
<span class="icon"><svg-icon name="seller-preview" size="24" /></span>
|
||||
<span class="label">Crop Preview</span>
|
||||
</div>
|
||||
<img :src="data.preview_url" />
|
||||
<div class="submit" @click="onSubmit">
|
||||
<svg-icon name="seller-dui" size="24" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue"
|
||||
import ImageClip from "./image-clip.vue"
|
||||
const data = reactive({
|
||||
url: "",
|
||||
title: "Crop Image",
|
||||
preview_url: "",
|
||||
ratio: [1, 1],
|
||||
isPreview: true,
|
||||
callback: null
|
||||
})
|
||||
const show = ref(false)
|
||||
const open = (url, callback, options) => {
|
||||
if (!url || !callback) return
|
||||
data.url = url
|
||||
data.callback = callback
|
||||
data.ratio = [1, 1]
|
||||
data.isPreview = true
|
||||
data.preview_url = ""
|
||||
data.title = "Crop Image"
|
||||
if (options) {
|
||||
if (options.hasOwnProperty("isPreview")) data.isPreview = options.isPreview
|
||||
if (options.hasOwnProperty("ratio")) data.ratio = options.ratio
|
||||
if (options.hasOwnProperty("title")) data.title = options.title
|
||||
}
|
||||
show.value = true
|
||||
}
|
||||
const onCancel = () => {
|
||||
show.value = false
|
||||
}
|
||||
const imageClipRef = ref(null)
|
||||
const onSubmit = () => {
|
||||
imageClipRef.value.getCropBlob().then((blob) => {
|
||||
if (data.callback) data.callback(blobToFile(blob, "image.png"))
|
||||
onCancel()
|
||||
})
|
||||
}
|
||||
// 将blob转换为file对象
|
||||
const blobToFile = (blob, fileName) => {
|
||||
return new File([blob], fileName, { type: blob.type })
|
||||
}
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.image-clip-dialog-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.submit {
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
border-radius: 50%;
|
||||
background: #262626;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
> .header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 5rem;
|
||||
> .title {
|
||||
font-family: pingfang_heavy;
|
||||
font-size: 2.4rem;
|
||||
color: #595959;
|
||||
}
|
||||
> .right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 2rem;
|
||||
> button {
|
||||
width: 10rem;
|
||||
height: 4.8rem;
|
||||
border-radius: 4rem;
|
||||
border: none;
|
||||
background: #e4e5eb;
|
||||
font-family: pingfang_heavy;
|
||||
font-size: 1.6rem;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
> .content {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
> .image-clip {
|
||||
flex: 1;
|
||||
}
|
||||
> .preview {
|
||||
margin-left: 6rem;
|
||||
width: 28rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 2.4rem;
|
||||
> .title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1.2rem;
|
||||
> .label {
|
||||
font-family: pingfang_heavy;
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
}
|
||||
> img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
157
src/views/SellerDashboard/BrandProfile/image-clip.vue
Normal file
157
src/views/SellerDashboard/BrandProfile/image-clip.vue
Normal file
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<div class="image-clip">
|
||||
<div class="image-clip-body" ref="imageClipBody">
|
||||
<VueCropper
|
||||
ref="cropper"
|
||||
:img="url"
|
||||
crossOrigin="Anonymous"
|
||||
:autoCrop="true"
|
||||
:fixedNumber="ratio"
|
||||
fixed
|
||||
movable
|
||||
centerBox
|
||||
@realTime="onChange"
|
||||
></VueCropper>
|
||||
</div>
|
||||
<div class="clip_opterate">
|
||||
<div class="item" @click="rotateLeft()">
|
||||
<span class="icon iconfont icon-chexiao operate_icon"></span>
|
||||
</div>
|
||||
<div class="item" @click="rotateRight()">
|
||||
<span class="icon iconfont icon-chexiao operate_icon icon_chexiao_sec"></span>
|
||||
</div>
|
||||
<div class="item" @click="changeScale(-0.1)">
|
||||
<span class="operate_icon icon_font">-</span>
|
||||
</div>
|
||||
<div class="item" @click="changeScale(0.1)">
|
||||
<span class="operate_icon icon_font">+</span>
|
||||
</div>
|
||||
<div class="item" @click="refreshCrop()">
|
||||
<span class="icon iconfont icon-shuaxin operate_icon"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, useAttrs, onMounted, onBeforeUnmount } from "vue"
|
||||
import "vue-cropper/dist/index.css"
|
||||
import { VueCropper } from "vue-cropper"
|
||||
const props = defineProps({
|
||||
url: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
ratio: {
|
||||
type: Array,
|
||||
default: () => [1, 1]
|
||||
}
|
||||
})
|
||||
const attrs = useAttrs()
|
||||
|
||||
const onChange = (data) => {
|
||||
if (attrs.onChange) {
|
||||
getCropUrl().then((url) => attrs.onChange(url))
|
||||
}
|
||||
}
|
||||
const cropper = ref(null)
|
||||
const imageClipBody = ref(null)
|
||||
const observer = new ResizeObserver((entries) => {
|
||||
refreshCrop()
|
||||
})
|
||||
onMounted(() => {
|
||||
observer.observe(imageClipBody.value)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
observer.disconnect()
|
||||
})
|
||||
const rotateLeft = () => {
|
||||
cropper.value.rotateLeft()
|
||||
}
|
||||
const rotateRight = () => {
|
||||
cropper.value.rotateRight()
|
||||
}
|
||||
const refreshCrop = () => {
|
||||
cropper.value.refresh()
|
||||
}
|
||||
const changeScale = (num = 1) => {
|
||||
cropper.value.changeScale(num)
|
||||
}
|
||||
const getCropUrl = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
cropper.value.getCropData(resolve)
|
||||
})
|
||||
}
|
||||
const getCropBlob = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
cropper.value.getCropBlob(resolve)
|
||||
})
|
||||
}
|
||||
defineExpose({
|
||||
getCropUrl,
|
||||
getCropBlob
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.image-clip {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// height: 100%;
|
||||
background: #fff;
|
||||
border-radius: calc(2rem * 1.2);
|
||||
padding: calc(1.3rem * 1.2) calc(1.3rem * 1.2) calc(2rem * 1.2);
|
||||
box-sizing: border-box;
|
||||
|
||||
.image-clip-body {
|
||||
width: 100%;
|
||||
height: calc(40rem * 1.2);
|
||||
// height: 53rem;
|
||||
background: yellow;
|
||||
}
|
||||
|
||||
.clip_opterate {
|
||||
margin: calc(2.7rem * 1.2) auto 0;
|
||||
border-radius: calc(1.6rem * 1.2);
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
border: 1px solid #e2e2e4;
|
||||
width: calc(24rem * 1.2);
|
||||
|
||||
.item {
|
||||
width: calc(4.7rem * 1.2);
|
||||
height: calc(4rem * 1.2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-right: 0.1rem solid #e6e8ea;
|
||||
cursor: pointer;
|
||||
|
||||
.icon_chexiao_sec {
|
||||
transform: rotateY(180deg); /* 垂直镜像翻转 */
|
||||
}
|
||||
|
||||
.operate_icon {
|
||||
font-size: calc(1.8rem * 1.2);
|
||||
color: rgba(102, 102, 102, 1);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.icon_font {
|
||||
font-size: calc(2.5rem * 1.2);
|
||||
position: relative;
|
||||
top: calc(-0.3rem * 1.2);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.icon-shuaxin {
|
||||
font-size: calc(1.4rem * 1.2);
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="brand-profile-index">
|
||||
<div class="brand-profile-index mini-scrollbar">
|
||||
<div class="header">
|
||||
<div class="bg">
|
||||
<img v-if="banner" :src="banner" />
|
||||
@@ -7,7 +7,7 @@
|
||||
<span class="icon"><svg-icon name="seller-picture" size="60" /></span>
|
||||
<span class="tip">Your brand banner has not been set up yet.</span>
|
||||
</div>
|
||||
<button>Change Brand Banner</button>
|
||||
<button @click="onChangeBanner">Change Brand Banner</button>
|
||||
</div>
|
||||
<!-- 头像 -->
|
||||
<div class="avatar">
|
||||
@@ -15,7 +15,7 @@
|
||||
<div v-else class="null">
|
||||
<svg-icon name="seller-user" size="48" />
|
||||
</div>
|
||||
<span class="icon">
|
||||
<span class="icon" @click="onChangeAvatar">
|
||||
<svg-icon name="seller-camera" size="24" />
|
||||
</span>
|
||||
</div>
|
||||
@@ -37,15 +37,56 @@
|
||||
<p class="tip"> </p>
|
||||
</template>
|
||||
</div>
|
||||
<image-clip-dialog ref="imageClipDialogRef" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue"
|
||||
import BrandInfo from "./brand-info.vue"
|
||||
const banner = ref("http://118.31.39.42:3000/falls/5bd8065cbb396eb5a8ef0a142605139358734e57.png")
|
||||
const avatar = ref("http://118.31.39.42:3000/falls/20251024140128_10355_1.jpg")
|
||||
import ImageClipDialog from "./image-clip-dialog.vue"
|
||||
const banner = ref("")
|
||||
const avatar = ref("")
|
||||
const isEdit = ref(false)
|
||||
const brandInfoRef = ref(null)
|
||||
const imageClipDialogRef = ref(null)
|
||||
|
||||
// 选择本机图片
|
||||
const uploadImg = (onChange) => {
|
||||
const input = document.createElement("input")
|
||||
input.type = "file"
|
||||
input.accept = "image/*"
|
||||
// 监听文件输入框的变化事件
|
||||
input.addEventListener("change", (event) => {
|
||||
event.preventDefault()
|
||||
const file = event.target.files[0]
|
||||
const url = URL.createObjectURL(file)
|
||||
onChange({ url, file })
|
||||
})
|
||||
input.click()
|
||||
}
|
||||
|
||||
const onChangeBanner = () => {
|
||||
uploadImg(({ url }) => {
|
||||
imageClipDialogRef.value.open(
|
||||
url,
|
||||
(file) => {
|
||||
banner.value = URL.createObjectURL(file)
|
||||
},
|
||||
{ ratio: [40, 7], isPreview: false, title: "Crop Brand Banner" }
|
||||
)
|
||||
})
|
||||
}
|
||||
const onChangeAvatar = () => {
|
||||
uploadImg(({ url }) => {
|
||||
imageClipDialogRef.value.open(
|
||||
url,
|
||||
(file) => {
|
||||
avatar.value = URL.createObjectURL(file)
|
||||
},
|
||||
{ ratio: [1, 1], isPreview: true, title: "Crop Avatar" }
|
||||
)
|
||||
})
|
||||
}
|
||||
const onEdit = () => {
|
||||
isEdit.value = true
|
||||
}
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
|
||||
|
||||
//const props = defineProps({
|
||||
//})
|
||||
const emit = defineEmits([
|
||||
'selectCollectionItem',
|
||||
])
|
||||
const current = ref(1)
|
||||
const list = ref([
|
||||
{
|
||||
imgList:[
|
||||
{
|
||||
url:'https://www.minio-api.aida.com.hk/aida-users/83/avatar/2b3d5756-ea29-4020-86a9-3b02cfc73b5a.png?response-content-type=image%2Fpng&response-content-disposition=inline&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20260410%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260410T013002Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=eedfd4114bde66f0ff8fe5e4d7a7274d9007b25deb40ee82a19427f29601e89b',
|
||||
},{
|
||||
url:'https://www.minio-api.aida.com.hk/aida-users/83/avatar/2b3d5756-ea29-4020-86a9-3b02cfc73b5a.png?response-content-type=image%2Fpng&response-content-disposition=inline&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20260410%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260410T013002Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=eedfd4114bde66f0ff8fe5e4d7a7274d9007b25deb40ee82a19427f29601e89b',
|
||||
},{
|
||||
url:'https://www.minio-api.aida.com.hk/aida-users/83/avatar/2b3d5756-ea29-4020-86a9-3b02cfc73b5a.png?response-content-type=image%2Fpng&response-content-disposition=inline&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20260410%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260410T013002Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=eedfd4114bde66f0ff8fe5e4d7a7274d9007b25deb40ee82a19427f29601e89b',
|
||||
},{
|
||||
url:'https://www.minio-api.aida.com.hk/aida-users/83/avatar/2b3d5756-ea29-4020-86a9-3b02cfc73b5a.png?response-content-type=image%2Fpng&response-content-disposition=inline&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20260410%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260410T013002Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=eedfd4114bde66f0ff8fe5e4d7a7274d9007b25deb40ee82a19427f29601e89b',
|
||||
},
|
||||
],
|
||||
type:'Series',
|
||||
name:'Christmas',
|
||||
sketchNum: 7,
|
||||
date: 'today',
|
||||
id:'1',
|
||||
},{
|
||||
imgList:[
|
||||
{
|
||||
url:'https://www.minio-api.aida.com.hk/aida-users/83/avatar/2b3d5756-ea29-4020-86a9-3b02cfc73b5a.png?response-content-type=image%2Fpng&response-content-disposition=inline&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20260410%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260410T013002Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=eedfd4114bde66f0ff8fe5e4d7a7274d9007b25deb40ee82a19427f29601e89b',
|
||||
},{
|
||||
url:'https://www.minio-api.aida.com.hk/aida-users/83/avatar/2b3d5756-ea29-4020-86a9-3b02cfc73b5a.png?response-content-type=image%2Fpng&response-content-disposition=inline&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20260410%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260410T013002Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=eedfd4114bde66f0ff8fe5e4d7a7274d9007b25deb40ee82a19427f29601e89b',
|
||||
},{
|
||||
url:'https://www.minio-api.aida.com.hk/aida-users/83/avatar/2b3d5756-ea29-4020-86a9-3b02cfc73b5a.png?response-content-type=image%2Fpng&response-content-disposition=inline&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20260410%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260410T013002Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=eedfd4114bde66f0ff8fe5e4d7a7274d9007b25deb40ee82a19427f29601e89b',
|
||||
},{
|
||||
url:'https://www.minio-api.aida.com.hk/aida-users/83/avatar/2b3d5756-ea29-4020-86a9-3b02cfc73b5a.png?response-content-type=image%2Fpng&response-content-disposition=inline&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20260410%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260410T013002Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=eedfd4114bde66f0ff8fe5e4d7a7274d9007b25deb40ee82a19427f29601e89b',
|
||||
},
|
||||
],
|
||||
type:'Series',
|
||||
name:'Christmas',
|
||||
sketchNum: 7,
|
||||
date: 'today',
|
||||
id:'2',
|
||||
},{
|
||||
imgList:[
|
||||
{
|
||||
url:'https://www.minio-api.aida.com.hk/aida-users/83/avatar/2b3d5756-ea29-4020-86a9-3b02cfc73b5a.png?response-content-type=image%2Fpng&response-content-disposition=inline&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20260410%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260410T013002Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=eedfd4114bde66f0ff8fe5e4d7a7274d9007b25deb40ee82a19427f29601e89b',
|
||||
},{
|
||||
url:'https://www.minio-api.aida.com.hk/aida-users/83/avatar/2b3d5756-ea29-4020-86a9-3b02cfc73b5a.png?response-content-type=image%2Fpng&response-content-disposition=inline&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20260410%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260410T013002Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=eedfd4114bde66f0ff8fe5e4d7a7274d9007b25deb40ee82a19427f29601e89b',
|
||||
},{
|
||||
url:'https://www.minio-api.aida.com.hk/aida-users/83/avatar/2b3d5756-ea29-4020-86a9-3b02cfc73b5a.png?response-content-type=image%2Fpng&response-content-disposition=inline&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20260410%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260410T013002Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=eedfd4114bde66f0ff8fe5e4d7a7274d9007b25deb40ee82a19427f29601e89b',
|
||||
},{
|
||||
url:'https://www.minio-api.aida.com.hk/aida-users/83/avatar/2b3d5756-ea29-4020-86a9-3b02cfc73b5a.png?response-content-type=image%2Fpng&response-content-disposition=inline&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20260410%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260410T013002Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=eedfd4114bde66f0ff8fe5e4d7a7274d9007b25deb40ee82a19427f29601e89b',
|
||||
},
|
||||
],
|
||||
type:'Series',
|
||||
name:'Christmas',
|
||||
sketchNum: 7,
|
||||
date: 'today',
|
||||
id:'1',
|
||||
},{
|
||||
imgList:[
|
||||
{
|
||||
url:'https://www.minio-api.aida.com.hk/aida-users/83/avatar/2b3d5756-ea29-4020-86a9-3b02cfc73b5a.png?response-content-type=image%2Fpng&response-content-disposition=inline&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20260410%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260410T013002Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=eedfd4114bde66f0ff8fe5e4d7a7274d9007b25deb40ee82a19427f29601e89b',
|
||||
},{
|
||||
url:'https://www.minio-api.aida.com.hk/aida-users/83/avatar/2b3d5756-ea29-4020-86a9-3b02cfc73b5a.png?response-content-type=image%2Fpng&response-content-disposition=inline&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20260410%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260410T013002Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=eedfd4114bde66f0ff8fe5e4d7a7274d9007b25deb40ee82a19427f29601e89b',
|
||||
},{
|
||||
url:'https://www.minio-api.aida.com.hk/aida-users/83/avatar/2b3d5756-ea29-4020-86a9-3b02cfc73b5a.png?response-content-type=image%2Fpng&response-content-disposition=inline&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20260410%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260410T013002Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=eedfd4114bde66f0ff8fe5e4d7a7274d9007b25deb40ee82a19427f29601e89b',
|
||||
},{
|
||||
url:'https://www.minio-api.aida.com.hk/aida-users/83/avatar/2b3d5756-ea29-4020-86a9-3b02cfc73b5a.png?response-content-type=image%2Fpng&response-content-disposition=inline&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20260410%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260410T013002Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=eedfd4114bde66f0ff8fe5e4d7a7274d9007b25deb40ee82a19427f29601e89b',
|
||||
},
|
||||
],
|
||||
type:'Series',
|
||||
name:'Christmas',
|
||||
sketchNum: 7,
|
||||
date: 'today',
|
||||
id:'1',
|
||||
},
|
||||
])
|
||||
|
||||
const selectCollectionItem = (item:any)=>{
|
||||
emit('selectCollectionItem',item)
|
||||
}
|
||||
onMounted(()=>{
|
||||
})
|
||||
onUnmounted(()=>{
|
||||
})
|
||||
defineExpose({})
|
||||
</script>
|
||||
<template>
|
||||
<div class="historyList">
|
||||
<div class="list">
|
||||
<div v-for="(item,index) in list" :key="index" class="item" @click="selectCollectionItem(item)">
|
||||
<div class="imgList">
|
||||
<div v-for="(img,index) in item.imgList" :key="index" class="img">
|
||||
<img :src="img.url" alt="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail">
|
||||
<div class="name">{{item.name}}</div>
|
||||
<div class="bottom">
|
||||
<div>{{item.sketchNum}} sketchs</div>
|
||||
<div>{{item.date}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="type" :class="item.type">
|
||||
{{item.type}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pagination">
|
||||
<a-pagination v-model:current="current" :pageSize="6" :showSizeChanger="false" show-quick-jumper :total="100" show-less-items />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="less" scoped>
|
||||
.historyList{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 3rem;
|
||||
> .list{
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
row-gap: 2.4rem; /* 垂直间距 3px */
|
||||
column-gap: 3.2rem; /* 横向间距 2px */
|
||||
align-content: start;
|
||||
overflow-y: auto;
|
||||
&::-webkit-scrollbar{
|
||||
display: none;
|
||||
}
|
||||
> .item{
|
||||
width: 42.6rem;
|
||||
height: auto;
|
||||
// height: 27.6rem;
|
||||
border: 1.5px solid #C7C7C7;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: 2rem;
|
||||
cursor: pointer;
|
||||
transition: all .3s;
|
||||
> .imgList{
|
||||
background-color: #eaeaea;
|
||||
height: 19.2rem;
|
||||
padding: 1rem 1.3rem;
|
||||
display: flex;
|
||||
gap: .4rem;
|
||||
> .img{
|
||||
width: 9.7rem;
|
||||
height: 17.2rem;
|
||||
border-radius: 1rem;
|
||||
overflow: hidden;
|
||||
> img{
|
||||
object-fit: cover;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
> .detail{
|
||||
padding: 2rem 2.4rem;
|
||||
> .name{
|
||||
font-family: pingfang_heavy;
|
||||
font-weight: 400;
|
||||
font-size: 1.797rem;
|
||||
line-height: 1;
|
||||
}
|
||||
> .bottom{
|
||||
display: flex;
|
||||
margin-top: .8rem;
|
||||
justify-content: space-between;
|
||||
> div{
|
||||
font-size: 1.2rem;
|
||||
font-family: pingfang_regular;
|
||||
font-weight: 400;
|
||||
font-size: 1.6rem;
|
||||
line-height: 1;
|
||||
color: #585858;
|
||||
}
|
||||
> div:nth-child(2){
|
||||
color: #979797;
|
||||
}
|
||||
}
|
||||
}
|
||||
> .type{
|
||||
width: 7.6rem;
|
||||
height: 3rem;
|
||||
border-radius: 2rem;
|
||||
border: 1px solid #727070;
|
||||
background: #7E7C7C;
|
||||
font-weight: 500;
|
||||
font-size: 1.4rem;
|
||||
line-height: 150%;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
top: .5rem;
|
||||
right: .5rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
&.Series{
|
||||
|
||||
}
|
||||
&.Single{
|
||||
background-color: #ffffff;
|
||||
color: #727070;
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
border: 1.5px solid #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
> .pagination{
|
||||
margin-top: 3rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,13 +1,25 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
|
||||
import sellerHeader from "../../seller-header.vue"
|
||||
import historyList from "./historyList.vue"
|
||||
import { useRouter } from "vue-router"
|
||||
|
||||
//const props = defineProps({
|
||||
//})
|
||||
//const emit = defineEmits([
|
||||
//])
|
||||
const router = useRouter()
|
||||
let data = reactive({
|
||||
})
|
||||
const searchType = ref('all')
|
||||
const searchText = ref('')
|
||||
|
||||
const historyListRef = ref(null)
|
||||
const handleSearch = () => {
|
||||
}
|
||||
const selectCollectionItem = (item:any) => {
|
||||
router.push({path:'/home/seller/myListings/select/'+item.id})
|
||||
}
|
||||
onMounted(()=>{
|
||||
})
|
||||
onUnmounted(()=>{
|
||||
@@ -26,7 +38,27 @@ const {} = toRefs(data);
|
||||
>
|
||||
</seller-header>
|
||||
<div class="content">
|
||||
1231222aaa
|
||||
<div class="title">
|
||||
<div class="left">
|
||||
<div :class="{active:searchType == 'all'}" @click="searchType = 'all'">All</div>
|
||||
<div :class="{active:searchType == 'series'}" @click="searchType = 'series'">Series Design</div>
|
||||
<div :class="{active:searchType == 'single'}" @click="searchType = 'single'">Single Design</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="search_input flex flex-align-center">
|
||||
<input
|
||||
class="search_input_inner"
|
||||
v-model="searchText"
|
||||
:bordered="false"
|
||||
@keydown.enter="handleSearch"
|
||||
placeholder="123123"
|
||||
/>
|
||||
<!-- <SearchOutlined class="search_input_icon" @click="handleSearch" /> -->
|
||||
<SvgIcon name="CSearch" size="20" class="search_input_icon" @click="handleSearch" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<historyList ref="historyListRef" @selectCollectionItem="selectCollectionItem"></historyList>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -42,6 +74,71 @@ const {} = toRefs(data);
|
||||
margin-top: 2rem;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
padding: 2.4rem 3rem;
|
||||
background-color: #f9fafa;
|
||||
border-radius: 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
> .title{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
> .left{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1.2rem;
|
||||
> div{
|
||||
min-width: 9rem;
|
||||
padding: .4rem 2.6rem;
|
||||
background-color: #fff;
|
||||
border-radius: 4rem;
|
||||
border: 1px solid #000000;
|
||||
font-weight: 500;
|
||||
font-size: 1.6rem;
|
||||
line-height: 150%;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
&:hover{
|
||||
color: #fff;
|
||||
background-color: #000;
|
||||
|
||||
}
|
||||
}
|
||||
> .active{
|
||||
color: #fff;
|
||||
background-color: #000;
|
||||
}
|
||||
}
|
||||
> .right{
|
||||
.search_input {
|
||||
height: 3.2rem;
|
||||
width: 27rem; // 默认宽度
|
||||
background-color: #fff;
|
||||
border: 1px solid #000;
|
||||
border-radius: 3rem;
|
||||
// column-gap: 3rem;
|
||||
padding: 0 2rem;
|
||||
.search_input_inner {
|
||||
border: none;
|
||||
height: 100%;
|
||||
width: calc(100% - 2rem);
|
||||
padding: .6rem 0;
|
||||
font-size: 1.2rem;
|
||||
&::placeholder {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
&::-webkit-input-placeholder{
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
.search_input_icon {
|
||||
font-size: 1.6rem;
|
||||
color: #000;
|
||||
width: initial;
|
||||
height: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
|
||||
import sellerHeader from "../../seller-header.vue"
|
||||
import { VueDraggable } from "vue-draggable-plus"
|
||||
import selectMenu from '@/component/modules/selectMenu.vue'
|
||||
|
||||
//const props = defineProps({
|
||||
//})
|
||||
@@ -8,7 +10,101 @@ import sellerHeader from "../../seller-header.vue"
|
||||
//])
|
||||
let data = reactive({
|
||||
})
|
||||
const domSize = ref('Small')
|
||||
const domSizeList = ref([
|
||||
{
|
||||
label:'Small',
|
||||
value:'Small',
|
||||
},
|
||||
{
|
||||
label:'Medium',
|
||||
value:'Medium',
|
||||
},
|
||||
{
|
||||
label:'Large',
|
||||
value:'Large',
|
||||
},
|
||||
])
|
||||
const list = ref([
|
||||
{ id: "1" },
|
||||
{ id: "2" },
|
||||
{ id: "3" },
|
||||
{ id: "4" },
|
||||
{ id: "5" },
|
||||
{ id: "6" },
|
||||
{ id: "7" },
|
||||
{ id: "8" },
|
||||
{ id: "9" },
|
||||
{ id: "10" }
|
||||
])
|
||||
const chooseList = ref([])
|
||||
const chooseItem = (item:any)=>{
|
||||
chooseList.value.push(item)
|
||||
}
|
||||
|
||||
const next = ()=>{
|
||||
if(chooseList.value.length == 0)return
|
||||
}
|
||||
|
||||
const config = ref({
|
||||
"data-container-type": "root",
|
||||
"data-parent-id": "null",
|
||||
animation: 250,
|
||||
handle: ".item", // 可拖动的元素
|
||||
"ghost-class": "ghost", // 拖动时的类名
|
||||
"chosen-class": "chosen", // 选中时的类名
|
||||
"drag-class": "drag", // 拖动时的类名
|
||||
"swap-threshold": 0.5,
|
||||
"empty-insert-threshold": 5,
|
||||
"force-fallback": false,
|
||||
"fallback-tolerance": 3,
|
||||
"scroll-sensitivity": 100,
|
||||
"scroll-speed": 10,
|
||||
onEnd: (e) => {}
|
||||
})
|
||||
|
||||
|
||||
let resizeObserver = null as any
|
||||
|
||||
const gap = ref({
|
||||
Small: '16px',
|
||||
Medium: '24px',
|
||||
Large: '30px',
|
||||
})
|
||||
//根据宽度设置列表宽度
|
||||
let upDataDomWidthTime = null as any
|
||||
const listingsBoxRef = ref(null) as any
|
||||
const setDomSize = (width: number)=>{
|
||||
if(!listingsBoxRef.value)return
|
||||
let listDom = listingsBoxRef.value.querySelector('.list')
|
||||
let listItemDom = listDom.querySelector('.item')
|
||||
let offsetWidth = listItemDom.getBoundingClientRect().width
|
||||
let lineNum = Math.floor(width / offsetWidth)
|
||||
let itemNum = Math.floor((width - (lineNum - 1) * parseInt(gap.value[domSize.value])) / offsetWidth)
|
||||
listDom.style.maxWidth = ((itemNum - 1) * parseInt(gap.value[domSize.value]) + itemNum * (offsetWidth)) + 'px'
|
||||
}
|
||||
|
||||
const changeDomSize = ()=>{
|
||||
setTimeout(()=>{
|
||||
setDomSize(listingsBoxRef.value.clientWidth)
|
||||
},350)
|
||||
}
|
||||
onMounted(()=>{
|
||||
// 创建观察器
|
||||
nextTick(()=>{
|
||||
resizeObserver = new ResizeObserver((entries) => {
|
||||
for (const entry of entries) {
|
||||
// 获取元素尺寸
|
||||
const width = entry.contentRect.width
|
||||
if(upDataDomWidthTime)clearTimeout(upDataDomWidthTime)
|
||||
upDataDomWidthTime = setTimeout(()=>{
|
||||
setDomSize(width)
|
||||
},200)
|
||||
}
|
||||
})
|
||||
// 开始监听
|
||||
if(resizeObserver)resizeObserver.observe(listingsBoxRef.value)
|
||||
})
|
||||
})
|
||||
onUnmounted(()=>{
|
||||
})
|
||||
@@ -25,9 +121,95 @@ const {} = toRefs(data);
|
||||
{title:'Select Sketch', name: 'myListingsSelectItem' }
|
||||
]"
|
||||
>
|
||||
<template #right>
|
||||
<div class="header-right">
|
||||
<div class="chooseNum">
|
||||
{{ chooseList.length }} sketches selected
|
||||
</div>
|
||||
<div class="button" @click="next">
|
||||
<span>Next</span>
|
||||
<div class="icon">
|
||||
<i class="fi fi-rr-arrow-small-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</seller-header>
|
||||
<div class="content">
|
||||
1231222aaa
|
||||
<div class="content" ref="listingsBoxRef">
|
||||
<div class="title">
|
||||
<div class="left">
|
||||
<i class="fi fi-rs-comments"></i>
|
||||
<span>Active Listings</span>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="generalModel_state">
|
||||
<div>
|
||||
<selectMenu
|
||||
:selectList="domSizeList"
|
||||
@change="changeDomSize"
|
||||
:isBtnOpen='true'
|
||||
:style="{
|
||||
'border-radius':'0rem',
|
||||
'border':'none',
|
||||
'font-weight': '900',
|
||||
'border-right':'2px solid rgba(0,0,0,.2)',
|
||||
'line-height': '3rem',
|
||||
'height': '3rem',
|
||||
'background': 'rgba(0,0,0,0)',
|
||||
}"
|
||||
v-model:select="domSize"
|
||||
>
|
||||
<template v-slot:btnText>
|
||||
{{ $t('Header.Filter') }}
|
||||
</template>
|
||||
</selectMenu>
|
||||
</div>
|
||||
<div>
|
||||
<selectMenu
|
||||
:selectList="domSizeList"
|
||||
@change="changeDomSize"
|
||||
:isBtnOpen='true'
|
||||
:style="{
|
||||
'border-radius':'0rem',
|
||||
'border':'none',
|
||||
'font-weight': '900',
|
||||
'line-height': '3rem',
|
||||
'height': '3rem',
|
||||
'background': 'rgba(0,0,0,0)',
|
||||
}"
|
||||
v-model:select="domSize"
|
||||
>
|
||||
<template v-slot:btnText>
|
||||
{{ $t('Header.Size') }}
|
||||
</template>
|
||||
</selectMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<VueDraggable
|
||||
v-model="list"
|
||||
class="list"
|
||||
:class="domSize"
|
||||
v-bind="config"
|
||||
:style="{gap: gap[domSize] || '1.6rem'}"
|
||||
:group="{
|
||||
name: 'sortable',
|
||||
pull: false,
|
||||
put: true
|
||||
}"
|
||||
>
|
||||
<div v-for="v in list" :key="v.id"
|
||||
:draging="true"
|
||||
class="item"
|
||||
@click="chooseItem(v)"
|
||||
:class="{'active':chooseList.some(item => item.id === v.id)}"
|
||||
>
|
||||
<div class="choose">
|
||||
<i class="fi fi-rr-check"></i>
|
||||
</div>
|
||||
</div>
|
||||
</VueDraggable>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -39,10 +221,143 @@ const {} = toRefs(data);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.header-right{
|
||||
display: flex;
|
||||
.chooseNum{
|
||||
font-family: pingfang_regular;
|
||||
font-weight: 400;
|
||||
font-size: 1.6rem;
|
||||
line-height: 140%;
|
||||
margin-right: 2rem;
|
||||
line-height: 6rem;
|
||||
}
|
||||
.button {
|
||||
width: 12.3rem;
|
||||
height: 6rem;
|
||||
border-radius: 4rem;
|
||||
display: flex;
|
||||
border: 1.5px solid #000000;
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
transition: all .3s;
|
||||
gap: .8rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.6rem;
|
||||
cursor: pointer;
|
||||
i{
|
||||
color: #fff;
|
||||
display: flex;
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
&:hover{
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
i{
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> .content {
|
||||
margin-top: 2rem;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
padding: 2.4rem 3rem;
|
||||
background-color: #f9fafa;
|
||||
border-radius: 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
> .title{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 3rem;
|
||||
> .left{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-family: pingfang_heavy;
|
||||
font-weight: 400;
|
||||
font-size: 1.8rem;
|
||||
line-height: 130%;
|
||||
letter-spacing: 0%;
|
||||
gap: 1.2rem;
|
||||
> i{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 2.4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
.list{
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 auto;
|
||||
overflow-y: auto;
|
||||
align-content: flex-start;
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
&.Small{
|
||||
--itemWidth: 17rem;
|
||||
--itemHeight: 26.1rem;
|
||||
--iconFS: 1.4rem;
|
||||
--iconWH: 2.4rem;
|
||||
--iconTR: 1.2rem;
|
||||
}
|
||||
&.Medium{
|
||||
--itemWidth: 22.6rem;
|
||||
--itemHeight: 34.6rem;
|
||||
--iconFS: 1.6rem;
|
||||
--iconWH: 3rem;
|
||||
--iconTR: 1.4rem;
|
||||
}
|
||||
&.Large{
|
||||
--itemWidth: 29.2rem;
|
||||
--itemHeight: 44.8rem;
|
||||
--iconFS: 2.2rem;
|
||||
--iconWH: 4rem;
|
||||
--iconTR: 1.62rem;
|
||||
}
|
||||
> .item{
|
||||
width: var(--itemWidth);
|
||||
height: var(--itemHeight);
|
||||
border-radius: 2rem;
|
||||
border: 1.5px solid #C7C7C7;
|
||||
// transition: all .3s;
|
||||
position: relative;
|
||||
> .choose{
|
||||
display: flex;
|
||||
width: var(--iconWH);
|
||||
height: var(--iconWH);
|
||||
position: absolute;
|
||||
background-color: #000;
|
||||
border-radius: 50%;
|
||||
display: none;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
top: var(--iconTR);
|
||||
right: var(--iconTR);
|
||||
> i{
|
||||
color: #fff;
|
||||
font-size: var(--iconFS);
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
&.active{
|
||||
border: 1.5px solid #000;
|
||||
> .choose{
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
border: 1.5px solid #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
|
||||
import { VueDraggable } from "vue-draggable-plus"
|
||||
import contentItem from "./contentItem.vue"
|
||||
import selectMenu from '@/component/modules/selectMenu.vue'
|
||||
import deleteDrafts from './deleteDrafts.vue'
|
||||
|
||||
//const props = defineProps({
|
||||
//})
|
||||
@@ -19,11 +22,6 @@ const list = ref([
|
||||
{ id: "7" },
|
||||
{ id: "8" },
|
||||
{ id: "9" },
|
||||
{ id: "9" },
|
||||
{ id: "9" },
|
||||
{ id: "9" },
|
||||
{ id: "9" },
|
||||
{ id: "9" },
|
||||
{ id: "10" }
|
||||
])
|
||||
const list2 = ref([
|
||||
@@ -54,9 +52,99 @@ const config = ref({
|
||||
"scroll-speed": 10,
|
||||
onEnd: (e) => {}
|
||||
})
|
||||
const domSize = ref('Small')
|
||||
const domSizeList = ref([
|
||||
{
|
||||
label:'Small',
|
||||
value:'Small',
|
||||
},
|
||||
{
|
||||
label:'Medium',
|
||||
value:'Medium',
|
||||
},
|
||||
{
|
||||
label:'Large',
|
||||
value:'Large',
|
||||
},
|
||||
])
|
||||
|
||||
const visible = ref(false)
|
||||
const deleteDraftsRef = ref(null)
|
||||
|
||||
const deleteDraft = (item: any)=>{
|
||||
deleteDraftsRef.value.open(()=>{
|
||||
list2.value = list2.value.filter((v: any)=>v.id != item.id)
|
||||
})
|
||||
}
|
||||
|
||||
const draftListing = (item: any)=>{
|
||||
//数组前面添加item
|
||||
list2.value.unshift(item)
|
||||
list.value = list.value.filter((v: any)=>v.id != item.id)
|
||||
}
|
||||
|
||||
const publishListing = (item: any)=>{
|
||||
list.value.unshift(item)
|
||||
list2.value = list2.value.filter((v: any)=>v.id != item.id)
|
||||
}
|
||||
|
||||
const editListing = (item: any)=>{
|
||||
}
|
||||
|
||||
|
||||
const listingsBoxRef = ref(null) as any
|
||||
let resizeObserver = null as any
|
||||
|
||||
const gap = ref({
|
||||
Small: '16px',
|
||||
Medium: '24px',
|
||||
Large: '30px',
|
||||
})
|
||||
|
||||
//根据宽度设置列表宽度
|
||||
let upDataDomWidthTime = null
|
||||
const setDomSize = (width: number)=>{
|
||||
if(!listingsBoxRef.value)return
|
||||
let listDom = listingsBoxRef.value.querySelector('.list')
|
||||
let listItemDom = listDom.querySelector('.item')
|
||||
let offsetWidth = listItemDom.getBoundingClientRect().width
|
||||
let lineNum = Math.floor(width / offsetWidth)
|
||||
let itemNum = Math.floor((width - (lineNum - 1) * parseInt(gap.value[domSize.value])) / offsetWidth)
|
||||
listDom.style.maxWidth = ((itemNum - 1) * parseInt(gap.value[domSize.value]) + itemNum * (offsetWidth)) + 'px'
|
||||
}
|
||||
|
||||
const changeDomSize = ()=>{
|
||||
setTimeout(()=>{
|
||||
setDomSize(listingsBoxRef.value.clientWidth)
|
||||
},350)
|
||||
}
|
||||
|
||||
const unfoldDrafits = ()=>{
|
||||
data.showDrafts = !data.showDrafts
|
||||
}
|
||||
onMounted(()=>{
|
||||
// 创建观察器
|
||||
nextTick(()=>{
|
||||
resizeObserver = new ResizeObserver((entries) => {
|
||||
for (const entry of entries) {
|
||||
// 获取元素尺寸
|
||||
const width = entry.contentRect.width
|
||||
const height = entry.contentRect.height
|
||||
const borderBoxSize = entry.borderBoxSize[0] // 包含边框
|
||||
const contentBoxSize = entry.contentBoxSize[0] // 内容区域
|
||||
if(upDataDomWidthTime)clearTimeout(upDataDomWidthTime)
|
||||
upDataDomWidthTime = setTimeout(()=>{
|
||||
setDomSize(width)
|
||||
},200)
|
||||
}
|
||||
})
|
||||
// 开始监听
|
||||
if(resizeObserver)resizeObserver.observe(listingsBoxRef.value)
|
||||
})
|
||||
})
|
||||
onUnmounted(()=>{
|
||||
// 停止监听
|
||||
if(listingsBoxRef?.value)resizeObserver?.unobserve(listingsBoxRef?.value)
|
||||
})
|
||||
defineExpose({})
|
||||
const { showDrafts } = toRefs(data);
|
||||
@@ -64,19 +152,62 @@ const { showDrafts } = toRefs(data);
|
||||
<template>
|
||||
<div class="listings">
|
||||
<div class="listingsBox listingsBox1">
|
||||
<div class="box">
|
||||
<div class="box" :class="domSize" ref="listingsBoxRef">
|
||||
<div class="title">
|
||||
<div class="left">
|
||||
<i class="fi fi-rs-comments"></i>
|
||||
<span>Active Listings</span>
|
||||
</div>
|
||||
<div class="right">
|
||||
|
||||
<div class="generalModel_state">
|
||||
<div>
|
||||
<selectMenu
|
||||
:selectList="domSizeList"
|
||||
@change="changeDomSize"
|
||||
:isBtnOpen='true'
|
||||
:style="{
|
||||
'border-radius':'0rem',
|
||||
'border':'none',
|
||||
'font-weight': '900',
|
||||
'border-right':'2px solid rgba(0,0,0,.2)',
|
||||
'line-height': '3rem',
|
||||
'height': '3rem',
|
||||
'background': 'rgba(0,0,0,0)',
|
||||
}"
|
||||
v-model:select="domSize"
|
||||
>
|
||||
<template v-slot:btnText>
|
||||
{{ $t('Header.Filter') }}
|
||||
</template>
|
||||
</selectMenu>
|
||||
</div>
|
||||
<div>
|
||||
<selectMenu
|
||||
:selectList="domSizeList"
|
||||
@change="changeDomSize"
|
||||
:isBtnOpen='true'
|
||||
:style="{
|
||||
'border-radius':'0rem',
|
||||
'border':'none',
|
||||
'font-weight': '900',
|
||||
'line-height': '3rem',
|
||||
'height': '3rem',
|
||||
'background': 'rgba(0,0,0,0)',
|
||||
}"
|
||||
v-model:select="domSize"
|
||||
>
|
||||
<template v-slot:btnText>
|
||||
{{ $t('Header.Size') }}
|
||||
</template>
|
||||
</selectMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<VueDraggable
|
||||
v-model="list"
|
||||
class="list"
|
||||
:style="{gap: gap[domSize] || '1.6rem'}"
|
||||
v-bind="config"
|
||||
:group="{
|
||||
name: 'sortable',
|
||||
@@ -84,20 +215,33 @@ const { showDrafts } = toRefs(data);
|
||||
put: true
|
||||
}"
|
||||
>
|
||||
<div class="item" v-for="v in list" :key="v.id" :draging="true">
|
||||
{{ v.id }}
|
||||
</div>
|
||||
|
||||
<contentItem
|
||||
v-for="v in list"
|
||||
:key="v.id"
|
||||
:item="v"
|
||||
type="listings"
|
||||
:domSize="domSize"
|
||||
@draftListing="draftListing"
|
||||
@editListing="editListing"
|
||||
/>
|
||||
</VueDraggable>
|
||||
</div>
|
||||
<div class="openOrCloseDrafts" :class="{'active': showDrafts}" @click="showDrafts = !showDrafts">
|
||||
<div class="openOrCloseDrafts" :class="{'active': showDrafts}" @click="unfoldDrafits">
|
||||
<span class="icon iconfont icon-xiala"></span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="listingsBox listingsBox2" :class="{'active': showDrafts}">
|
||||
<div class="box">
|
||||
<div class="listingsBox listingsBox2" :class="{'active': showDrafts}">
|
||||
<div class="box Small">
|
||||
<div class="title">
|
||||
<div class="left">
|
||||
<i class="fi fi-rs-comments"></i>
|
||||
<span>Drafts</span>
|
||||
</div>
|
||||
</div>
|
||||
<VueDraggable
|
||||
v-model="list2"
|
||||
class="list"
|
||||
class="list2"
|
||||
v-bind="config"
|
||||
:group="{
|
||||
name: 'sortable',
|
||||
@@ -105,12 +249,20 @@ const { showDrafts } = toRefs(data);
|
||||
put: true
|
||||
}"
|
||||
>
|
||||
<div class="item" v-for="v in list" :key="v.id" :draging="true">
|
||||
{{ v.id }}
|
||||
</div>
|
||||
<contentItem
|
||||
v-for="v in list2"
|
||||
:key="v.id"
|
||||
:item="v"
|
||||
domSize="Small"
|
||||
type="drafts"
|
||||
@deleteDraft="deleteDraft"
|
||||
@editListing="editListing"
|
||||
@publishListing="publishListing"
|
||||
/>
|
||||
</VueDraggable>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<deleteDrafts ref="deleteDraftsRef" v-model:visible="visible"></deleteDrafts>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="less" scoped>
|
||||
@@ -123,16 +275,19 @@ const { showDrafts } = toRefs(data);
|
||||
.listingsBox{
|
||||
background-color: #f9fafa;
|
||||
border-radius: 2rem;
|
||||
flex: 1;
|
||||
position: relative;
|
||||
// overflow: hidden;
|
||||
display: flex;
|
||||
transition: all .3s;
|
||||
.box{
|
||||
width: 100%;
|
||||
padding: 2.4rem 4rem;
|
||||
padding: 2.4rem 0;
|
||||
padding-bottom: 0;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
padding: 2.4rem 4rem;
|
||||
> .title{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -148,6 +303,7 @@ const { showDrafts } = toRefs(data);
|
||||
line-height: 130%;
|
||||
letter-spacing: 0%;
|
||||
gap: 1.2rem;
|
||||
align-content: flex-start;
|
||||
> i{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -156,34 +312,32 @@ const { showDrafts } = toRefs(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
.list{
|
||||
.list2{
|
||||
gap: 1.6rem;
|
||||
width: 100%;
|
||||
.item{
|
||||
width: 19.2rem;
|
||||
}
|
||||
}
|
||||
.list,.list2{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
.item{
|
||||
width: 197px;
|
||||
height: 249px;
|
||||
border-radius: 20px;
|
||||
border: 1.5px solid #C7C7C7;
|
||||
&:hover{
|
||||
border: 2px solid #000000;
|
||||
}
|
||||
// flex: 1;
|
||||
margin: 0 auto;
|
||||
align-items: flex-start;
|
||||
overflow: auto;
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.listingsBox1{
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
.box{
|
||||
.list{
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.listingsBox2{
|
||||
width: 48.8rem;
|
||||
transition: all .3s;
|
||||
overflow: hidden;
|
||||
&.active{
|
||||
width: 0;
|
||||
|
||||
225
src/views/SellerDashboard/MyListings/main/contentItem.vue
Normal file
225
src/views/SellerDashboard/MyListings/main/contentItem.vue
Normal file
@@ -0,0 +1,225 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
|
||||
const props = defineProps({
|
||||
domSize: {
|
||||
type: String,
|
||||
default: 'Small'
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'listings'
|
||||
},
|
||||
item: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
const emit = defineEmits([
|
||||
'deleteDraft',
|
||||
'editListing',
|
||||
'draftListing',
|
||||
'publishListing'
|
||||
])
|
||||
let data = reactive({
|
||||
})
|
||||
onMounted(()=>{
|
||||
})
|
||||
onUnmounted(()=>{
|
||||
})
|
||||
defineExpose({})
|
||||
const {} = toRefs(data);
|
||||
</script>
|
||||
<template>
|
||||
<div class="item" :draging="true" :class="domSize">
|
||||
<div class="imgBox">
|
||||
<img src="" alt="">
|
||||
<div class="maskBtn">
|
||||
<div @click="$emit('editListing',item)">
|
||||
<svgIcon name="seller-edit" :size="domSize == 'Small'?32:domSize == 'Medium'?40:48" />
|
||||
<div>Edit</div>
|
||||
</div>
|
||||
<div v-if="type == 'listings'" @click="$emit('draftListing',item)">
|
||||
<svgIcon name="seller-draft" :size="domSize == 'Small'?32:domSize == 'Medium'?40:48" />
|
||||
<div>Draft</div>
|
||||
</div>
|
||||
<div v-else-if="type == 'drafts'" @click="$emit('publishListing',item)">
|
||||
<svgIcon name="seller-share" :size="domSize == 'Small'?32:domSize == 'Medium'?40:48" />
|
||||
<div>Publish</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail">
|
||||
<div class="left">
|
||||
<div class="name">item name</div>
|
||||
<div class="price">$1123</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="detailItem" v-if="type == 'listings'">
|
||||
<div class="shopping1">
|
||||
<i class="fi fi-rr-shopping-bag-add"></i>
|
||||
</div>
|
||||
<span>123</span>
|
||||
</div>
|
||||
<div class="detailItem" v-if="type == 'listings'">
|
||||
<div class="eye1">
|
||||
<i class="fi fi-rs-eye"></i>
|
||||
</div>
|
||||
<span>123</span>
|
||||
</div>
|
||||
<div class="detailItem drafts" v-if="type == 'drafts'" @click="$emit('deleteDraft',item)">
|
||||
<div class="">
|
||||
<i class="fi fi-rr-trash"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="less" scoped>
|
||||
.item{
|
||||
// height: 30.2rem;
|
||||
&.Small{
|
||||
--itemWidth: 19.7rem;
|
||||
--itemImgHeight: 24.9rem;
|
||||
--maskBtnGap: .8rem;
|
||||
--maskBtnWidth: 6rem;
|
||||
--maskBtnFS: 1.6rem;
|
||||
--detailPadding: .8rem 1.2rem;
|
||||
--detailLeftNameSize: 1.4rem;
|
||||
--detailLeftPriceSize: 1.2rem;
|
||||
--detailRightGap: .8rem;
|
||||
--detailRightItemGap: .4rem;
|
||||
--detailRightItemIcon: 1.6rem;
|
||||
--detailRightItemDraftsIcon: 2rem;
|
||||
}
|
||||
&.Medium{
|
||||
--itemWidth: 25.4rem;
|
||||
--itemImgHeight: 32.2rem;
|
||||
--maskBtnGap: 1rem;
|
||||
--maskBtnWidth: 7.6rem;
|
||||
--maskBtnFS: 2.07rem;
|
||||
--detailPadding: 1.2rem 1.4rem;
|
||||
--detailLeftNameSize: 1.6rem;
|
||||
--detailLeftPriceSize: 1.4rem;
|
||||
--detailRightGap: 1rem;
|
||||
--detailRightItemGap: .4rem;
|
||||
--detailRightItemIcon: 2rem;
|
||||
--detailRightItemDraftsIcon: 2rem;
|
||||
}
|
||||
&.Large{
|
||||
--itemWidth: 31.4rem;
|
||||
--itemImgHeight: 39.8rem;
|
||||
--maskBtnGap: 1.2rem;
|
||||
--maskBtnWidth: 7.6rem;
|
||||
--maskBtnFS: 2.56rem;
|
||||
--detailPadding: 1.2rem 1.6rem;
|
||||
--detailLeftNameSize: 1.98rem;
|
||||
--detailLeftPriceSize: 1.73rem;
|
||||
--detailRightGap: 1.2rem;
|
||||
--detailRightItemGap: .4rem;
|
||||
--detailRightItemIcon: 2.6rem;
|
||||
--detailRightItemDraftsIcon: 2rem;
|
||||
}
|
||||
width: var(--itemWidth);
|
||||
border-radius: 2rem;
|
||||
border: 1.5px solid #C7C7C7;
|
||||
overflow: hidden;
|
||||
.imgBox{
|
||||
position: relative;
|
||||
height: var(--itemImgHeight);
|
||||
width: 100%;
|
||||
> .maskBtn{
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #00000066;
|
||||
opacity: 0;
|
||||
transition: all .3s;
|
||||
top: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: var(--maskBtnGap);
|
||||
> div{
|
||||
font-family: pingfang_bold;
|
||||
font-weight: 400;
|
||||
font-size: var(--maskBtnFS);
|
||||
line-height: 150%;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
width: var(--maskBtnWidth);
|
||||
text-align: center;
|
||||
> div{
|
||||
margin-top: .8rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.detail{
|
||||
padding: var(--detailPadding);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
--rightColor: #979797;
|
||||
.left{
|
||||
gap: var(--detailRightItemGap);
|
||||
.name{
|
||||
font-weight: 500;
|
||||
font-size: var(--detailLeftNameSize);
|
||||
line-height: 150%;
|
||||
}
|
||||
.price{
|
||||
font-family: pingfang_regular;
|
||||
font-weight: 400;
|
||||
font-size: var(--detailLeftPriceSize);
|
||||
line-height: 150%;
|
||||
}
|
||||
}
|
||||
.right{
|
||||
display: flex;
|
||||
gap: var(--detailRightGap);
|
||||
.detailItem{
|
||||
display: flex;
|
||||
gap: var(--detailRightItemGap);
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
> div{
|
||||
color: var(--rightColor);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
> i{
|
||||
font-size: var(--detailRightItemIcon);
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
> span{
|
||||
color: var(--rightColor);
|
||||
font-family: pingfang_regular;
|
||||
font-weight: 400;
|
||||
font-size: var(--detailLeftPriceSize);
|
||||
line-height: 150%;
|
||||
}
|
||||
&.drafts{
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
> div{
|
||||
> i{
|
||||
font-size: var(--detailRightItemDraftsIcon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
border: 1.5px solid #000000;
|
||||
.imgBox{
|
||||
> .maskBtn{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.detail{
|
||||
--rightColor: #000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
219
src/views/SellerDashboard/MyListings/main/deleteDrafts.vue
Normal file
219
src/views/SellerDashboard/MyListings/main/deleteDrafts.vue
Normal file
@@ -0,0 +1,219 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
})
|
||||
const emit = defineEmits([
|
||||
'update:visible'
|
||||
])
|
||||
const router = useRouter()
|
||||
const {t} = useI18n()
|
||||
let data = reactive({
|
||||
})
|
||||
|
||||
const fun = ref(null)
|
||||
|
||||
let deleteDraftsRef = ref(null)
|
||||
|
||||
const open = (fun)=>{
|
||||
fun.value = fun
|
||||
emit('update:visible', true)
|
||||
}
|
||||
|
||||
const deleteDrafts = ()=>{
|
||||
if(fun.value){
|
||||
fun?.value()
|
||||
}
|
||||
cleardata()
|
||||
}
|
||||
|
||||
|
||||
|
||||
const cleardata = ()=>{
|
||||
emit('update:visible', false)
|
||||
}
|
||||
|
||||
|
||||
onMounted(()=>{
|
||||
})
|
||||
onUnmounted(()=>{
|
||||
})
|
||||
defineExpose({open})
|
||||
const { showAgain } = toRefs(data);
|
||||
</script>
|
||||
<template>
|
||||
<div ref="deleteDraftsRef" class="deleteDrafts" v-if="visible">
|
||||
<a-modal
|
||||
class="collection generalModel"
|
||||
v-model:visible="props.visible"
|
||||
:footer="null"
|
||||
:get-container="() => deleteDraftsRef"
|
||||
width="76.4rem"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
:closable="false"
|
||||
:mask="true"
|
||||
:keyboard="false"
|
||||
:destroyOnClose="false"
|
||||
:zIndex="1000"
|
||||
>
|
||||
<div class="generalModel_btn">
|
||||
<div class="generalModel_closeIcon" @click.stop="cleardata()">
|
||||
<SvgIcon name="seller-sellerToolTipClose" size="30"></SvgIcon>
|
||||
</div>
|
||||
</div>
|
||||
<div class="deleteTitle">
|
||||
<div class="icon">
|
||||
<i class="fi fi-rr-trash"></i>
|
||||
</div>
|
||||
<div class="titleText">
|
||||
<h1>Delete this listing?</h1>
|
||||
<p>Your listing and its details will be permanently removed.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="deleteContent">
|
||||
<div class="img">
|
||||
<img src="" alt="">
|
||||
</div>
|
||||
<div class="detail">
|
||||
<div class="name">Item Name</div>
|
||||
<div class="price">HK$392.00 · Draft</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btnBox">
|
||||
<div class="btn" @click.stop="cleardata()">Cancel</div>
|
||||
<div class="btn" @click.stop="deleteDrafts()">Delete</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<style lang="less" scoped>
|
||||
.deleteDrafts{
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
position: absolute;
|
||||
:deep(.generalModel){
|
||||
height: auto;
|
||||
.ant-modal-body{
|
||||
padding: 6rem 5.5rem;
|
||||
.generalModel_btn{
|
||||
.generalModel_closeIcon{
|
||||
transform: translate(0%, 0%);
|
||||
top: 4rem;
|
||||
right: 4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.deleteTitle{
|
||||
margin-bottom: 4rem;
|
||||
display: flex;
|
||||
> .icon{
|
||||
width: 10rem;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 10rem;
|
||||
background-color: #fceaea;
|
||||
margin-right: 3.2rem;
|
||||
> i{
|
||||
display: flex;
|
||||
font-size: 3.7rem;
|
||||
color: #DF2C2C;
|
||||
}
|
||||
}
|
||||
> .titleText{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
> h1{
|
||||
font-size: 2.4rem;
|
||||
font-family: pingfang_heavy;
|
||||
font-weight: 400;
|
||||
line-height: 130%;
|
||||
margin-bottom: .8rem;
|
||||
}
|
||||
> p{
|
||||
font-weight: 400;
|
||||
font-family: pingfang_regular;
|
||||
font-size: 2rem;
|
||||
line-height: 130%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.deleteContent{
|
||||
width: 100%;
|
||||
background-color: #f6f6f6;
|
||||
border-radius: 1.2rem;
|
||||
padding: 1.2rem;
|
||||
margin-bottom: 4rem;
|
||||
display: flex;
|
||||
> .img{
|
||||
width: 9.8rem;
|
||||
height: 15rem;
|
||||
border-radius: 1.2rem;
|
||||
margin-right: 3.6rem;
|
||||
overflow: hidden;
|
||||
> img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
> .detail{
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
> .name{
|
||||
margin-bottom: .8rem;
|
||||
font-family: pingfang_heavy;
|
||||
font-weight: 400;
|
||||
font-size: 2.4rem;
|
||||
line-height: 130%;
|
||||
}
|
||||
> .price{
|
||||
font-weight: 400;
|
||||
font-family: pingfang_regular;
|
||||
font-size: 2rem;
|
||||
line-height: 130%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.btnBox{
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
> .btn{
|
||||
width: 16rem;
|
||||
height: 6rem;
|
||||
border-radius: 4rem;
|
||||
font-weight: 400;
|
||||
font-size: 2.2rem;
|
||||
line-height: 130%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
&:nth-child(1){
|
||||
color: #999999;
|
||||
background-color: #fff;
|
||||
border: 1.5px solid #C7C7C7;
|
||||
}
|
||||
&:nth-child(2){
|
||||
margin-left: 2rem;
|
||||
color: #fff;
|
||||
background-color: #df2c2c;
|
||||
border: 1.5px solid #df2c2c;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -2,6 +2,7 @@
|
||||
import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
|
||||
import sellerHeader from "../../seller-header.vue"
|
||||
import sellerContent from "./content.vue"
|
||||
import myEvent from "@/tool/myEvents.js"
|
||||
|
||||
//const props = defineProps({
|
||||
//})
|
||||
@@ -9,6 +10,9 @@ import sellerContent from "./content.vue"
|
||||
//])
|
||||
let data = reactive({
|
||||
})
|
||||
const newListing = ()=>{
|
||||
myEvent.emit('newListing')
|
||||
}
|
||||
onMounted(()=>{
|
||||
})
|
||||
onUnmounted(()=>{
|
||||
@@ -23,7 +27,7 @@ const {} = toRefs(data);
|
||||
tip="Active listings and unpublished inventory."
|
||||
>
|
||||
<template #right>
|
||||
<div class="button">
|
||||
<div class="button" @click="newListing">
|
||||
<span>New Listing</span>
|
||||
<div class="icon">
|
||||
<i class="fi fi-br-plus"></i>
|
||||
|
||||
360
src/views/SellerDashboard/MyOrders/index.vue
Normal file
360
src/views/SellerDashboard/MyOrders/index.vue
Normal file
@@ -0,0 +1,360 @@
|
||||
<template>
|
||||
<div class="my-orders-index mini-scrollbar">
|
||||
<div class="total-box">
|
||||
<div class="total-item" v-for="v in totals" :key="v.title">
|
||||
<div class="title">
|
||||
<span class="icon"><svg-icon :name="v.icon" size="18" /></span>
|
||||
<span class="label">{{ v.title }}</span>
|
||||
</div>
|
||||
<div class="value">{{ v.value }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-box">
|
||||
<div class="left">
|
||||
<div class="title">All Invoice</div>
|
||||
<div class="tip">A summary of all completed transactions.</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="input">
|
||||
<span class="icon"
|
||||
><svg-icon name="seller-search" size="20" @click="getList(true)"
|
||||
/></span>
|
||||
<input
|
||||
type="text"
|
||||
v-model="nameOrId"
|
||||
placeholder="Search by item name or order ID"
|
||||
@keydown.enter.prevent="getList(true)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table">
|
||||
<div class="header">
|
||||
<div class="order-id">Order ID</div>
|
||||
<div class="item">Item</div>
|
||||
<div class="price">Price</div>
|
||||
<div class="buyer-username">Buyer Username</div>
|
||||
<div class="date">Date</div>
|
||||
</div>
|
||||
<div class="body">
|
||||
<div class="item" v-for="v in list" :key="v.orderId">
|
||||
<div class="order-id">{{ v.orderId }}</div>
|
||||
<div class="item">
|
||||
<div class="images">
|
||||
<img
|
||||
v-for="(v, i) in v.item.slice(0, maxItemNum)"
|
||||
:key="i"
|
||||
:src="v.url"
|
||||
/>
|
||||
<span v-if="v.item.length > maxItemNum"
|
||||
>+{{ v.item.length - maxItemNum }} more</span
|
||||
>
|
||||
</div>
|
||||
<div class="titles">
|
||||
<div v-for="(v, i) in v.item.slice(0, maxItemNum)" :key="i">
|
||||
{{ v.title }}
|
||||
</div>
|
||||
<span v-if="v.item.length > maxItemNum">...</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="price">{{ v.price }}</div>
|
||||
<div class="buyer-username">{{ v.username }}</div>
|
||||
<div class="date">
|
||||
<div>{{ v.date }}</div>
|
||||
<div>{{ v.time }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="placeholder" ref="placeholderRef" v-show="!loading"></div>
|
||||
<div class="footer" v-if="!finish"><a-spin :delay="0.5" v-show="loading" /></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onBeforeUnmount } from "vue"
|
||||
const totals = ref([
|
||||
{
|
||||
icon: "seller-qiandaizi",
|
||||
title: "Total Revenue",
|
||||
value: "HK$ 54,32.00"
|
||||
},
|
||||
{
|
||||
icon: "seller-gouwudai",
|
||||
title: "Total Purchases",
|
||||
value: "128"
|
||||
},
|
||||
{
|
||||
icon: "seller-eye",
|
||||
title: "Total Views",
|
||||
value: "4,982"
|
||||
}
|
||||
])
|
||||
const maxItemNum = ref(2)
|
||||
const loading = ref(false)
|
||||
const finish = ref(false)
|
||||
const total = ref(0)
|
||||
const page = ref(1)
|
||||
const size = ref(10)
|
||||
const nameOrId = ref("")
|
||||
const list = ref([])
|
||||
const getList = (isReload = false) => {
|
||||
loading.value = true
|
||||
if (isReload) {
|
||||
list.value = []
|
||||
page.value = 1
|
||||
finish.value = false
|
||||
}
|
||||
const data = {
|
||||
page: page.value,
|
||||
size: size.value
|
||||
}
|
||||
if (nameOrId.value) data.nameOrId = nameOrId.value
|
||||
console.log(data)
|
||||
setTimeout(() => {
|
||||
for (let i = 0; i < size.value; i++) {
|
||||
let { date, time, dateTime } = formatTimestamp(new Date(2026, 4, 20, 13, 14).getTime())
|
||||
list.value.push({
|
||||
orderId: "SP" + Math.random().toString().substring(2, 10),
|
||||
price: "HK$ " + (Math.random() * 500).toFixed(2),
|
||||
username: "@liuyuchen",
|
||||
date: date,
|
||||
time: time,
|
||||
item: [
|
||||
{
|
||||
url: "http://118.31.39.42:3000/falls/o-1.png",
|
||||
title: "North Outfit Set"
|
||||
},
|
||||
{
|
||||
url: "http://118.31.39.42:3000/falls/o-2.png",
|
||||
title: "Heritage Layered Set"
|
||||
},
|
||||
{},
|
||||
{}
|
||||
]
|
||||
})
|
||||
}
|
||||
total.value = 30
|
||||
page.value++
|
||||
finish.value = page.value > total.value / 10
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
}
|
||||
getList(true)
|
||||
const placeholderRef = ref(null)
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
if (!entries[0].intersectionRatio || loading.value || finish.value) return
|
||||
getList()
|
||||
},
|
||||
{ root: document.body }
|
||||
)
|
||||
onMounted(() => {
|
||||
observer.observe(placeholderRef.value)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
observer.disconnect()
|
||||
})
|
||||
const formatTimestamp = (ts) => {
|
||||
const d = new Date(ts)
|
||||
const h = d.getHours()
|
||||
const m = d.getMinutes()
|
||||
const date = `${d.toLocaleString("en-US", {
|
||||
month: "long"
|
||||
})} ${d.getDate()}, ${d.getFullYear()}`
|
||||
const time = `${h.toString().padStart(2, "0")}:${m.toString().padStart(2, "0")} ${
|
||||
h >= 12 ? "PM" : "AM"
|
||||
}`
|
||||
return {
|
||||
date,
|
||||
time,
|
||||
dateTime: `${date}\n${time}`
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.my-orders-index {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 3rem;
|
||||
margin: 0 3rem;
|
||||
gap: 4rem;
|
||||
> .total-box {
|
||||
display: flex;
|
||||
gap: 1.8rem;
|
||||
> .total-item {
|
||||
flex: 1;
|
||||
padding: 2.4rem;
|
||||
background-color: #f6f6f6;
|
||||
border-radius: 1.2rem;
|
||||
> .title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 1.2rem;
|
||||
gap: 1.2rem;
|
||||
> .icon {
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
border-radius: 50%;
|
||||
background-color: #ffffff;
|
||||
border: 0.08rem solid #e4e4e4;
|
||||
}
|
||||
> .label {
|
||||
font-size: 2rem;
|
||||
color: #585858;
|
||||
}
|
||||
}
|
||||
> .value {
|
||||
font-family: "pingfang_heavy";
|
||||
font-size: 3.6rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
> .filter-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
> .left {
|
||||
> .title {
|
||||
font-family: "pingfang_heavy";
|
||||
font-size: 2.4rem;
|
||||
color: #000;
|
||||
}
|
||||
> .tip {
|
||||
font-family: "pingfang_regular";
|
||||
font-size: 1.4rem;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
> .right {
|
||||
> .input {
|
||||
width: 30rem;
|
||||
height: 4rem;
|
||||
border-bottom: 0.15rem solid #000000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> .icon {
|
||||
margin: 0 0.5rem;
|
||||
}
|
||||
> input {
|
||||
padding: 0 2rem;
|
||||
width: 0;
|
||||
flex: 1;
|
||||
outline: none;
|
||||
border: none;
|
||||
height: 100%;
|
||||
font-family: "pingfang_regular";
|
||||
font-size: 1.2rem;
|
||||
color: #000;
|
||||
&::placeholder {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> .table {
|
||||
width: 100%;
|
||||
> .body > .item,
|
||||
> .header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> div {
|
||||
padding: 0 1.5rem;
|
||||
flex: 1;
|
||||
}
|
||||
> .order-id {
|
||||
flex: 1.5;
|
||||
}
|
||||
> .item {
|
||||
flex: 3;
|
||||
}
|
||||
> .buyer-username {
|
||||
flex: 1.5;
|
||||
}
|
||||
}
|
||||
> .header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background-color: #f6f6f6;
|
||||
height: 5.6rem;
|
||||
border-width: 0.15rem 0 0.15rem 0;
|
||||
border-style: solid;
|
||||
border-color: #eaeaea;
|
||||
> div {
|
||||
font-size: 2rem;
|
||||
color: #979797;
|
||||
}
|
||||
}
|
||||
> .body {
|
||||
> .item {
|
||||
padding-top: 1.6rem;
|
||||
padding-bottom: 1.6rem;
|
||||
border-bottom: 0.1rem solid #f6f6f6;
|
||||
color: #000;
|
||||
> .order-id {
|
||||
font-family: "pingfang_regular";
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
> .price {
|
||||
font-family: "pingfang_medium";
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
> .buyer-username {
|
||||
font-family: "pingfang_regular";
|
||||
font-size: 1.8rem;
|
||||
color: #666;
|
||||
}
|
||||
> .date {
|
||||
font-family: "pingfang_regular";
|
||||
font-size: 1.6rem;
|
||||
color: #666;
|
||||
}
|
||||
> .item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 3rem;
|
||||
> .images {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1.2rem;
|
||||
> img {
|
||||
width: auto;
|
||||
height: 10rem;
|
||||
border-radius: 0.8rem;
|
||||
border: 0.1rem solid #e9e9e9;
|
||||
}
|
||||
> span {
|
||||
font-family: "pingfang_medium";
|
||||
font-size: 1.4rem;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
> .titles {
|
||||
font-family: "pingfang_medium";
|
||||
font-size: 1.8rem;
|
||||
color: #000;
|
||||
> span {
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> .footer {
|
||||
min-height: 10rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
> .placeholder {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
323
src/views/SellerDashboard/Settings/index.vue
Normal file
323
src/views/SellerDashboard/Settings/index.vue
Normal file
@@ -0,0 +1,323 @@
|
||||
<template>
|
||||
<div class="settings-index">
|
||||
<div>
|
||||
<div class="notification">
|
||||
<div class="header">Notifications</div>
|
||||
<div class="content">
|
||||
<div class="left">
|
||||
<div class="title">New order notification</div>
|
||||
<div class="tip">Receive an inbox message when a new order is placed.</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<a-switch v-model:checked="checked" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="payout">
|
||||
<div class="header">Payout</div>
|
||||
<div class="content">
|
||||
<div class="header">
|
||||
<div class="title">Payment Providers</div>
|
||||
<div class="tip">Select how you want to receive payments.</div>
|
||||
</div>
|
||||
<div class="pay-item" v-for="v in payList" :key="v.type">
|
||||
<div class="left">
|
||||
<img :src="v.icon" />
|
||||
<div class="value">{{ v.value || "Unbound" }}</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button v-if="v.value" class="manage">Manage</button>
|
||||
<button v-else class="bind-now">Bind Now</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="left">
|
||||
<div class="title">Payment Currency</div>
|
||||
<div class="tip">HKD - Hong Kong Dollar</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button>Fixed</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="data-privacy">
|
||||
<div class="header">Data & Privacy</div>
|
||||
<div class="content">
|
||||
<div class="title">Copyright licence</div>
|
||||
<div class="tip">
|
||||
A licence certificate is automatically included with every purchase
|
||||
download. View the default licensing terms applied to your listings.
|
||||
</div>
|
||||
<div class="tip">
|
||||
This licence is issued by Code-Create and is legally binding upon purchase.
|
||||
It certifies the buyer's right to use the purchased design asset in
|
||||
accordance with the terms below.
|
||||
</div>
|
||||
<div class="tip">
|
||||
For custom licensing arrangements, <span>contact us</span>.
|
||||
</div>
|
||||
<div class="btns">
|
||||
<button>
|
||||
<span class="icon"><svg-icon name="seller-download" size="14" /></span>
|
||||
<span class="label">Download to View</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stop">
|
||||
<div class="header">Stop Selling</div>
|
||||
<div class="content">
|
||||
<div class="title">Deactivate seller account</div>
|
||||
<div class="tip">
|
||||
Permanently deactivate your seller account. All listings and invoice records
|
||||
will be deleted. You may re-register as a seller in the future, but your
|
||||
previous sales data cannot be recovered.
|
||||
</div>
|
||||
<div class="btns">
|
||||
<button>Deactivate</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue"
|
||||
import paypal from "@/assets/images/seller/setting/paypal.png"
|
||||
import stripe from "@/assets/images/seller/setting/stripe.png"
|
||||
import alipayHk from "@/assets/images/seller/setting/alipay-hk.png"
|
||||
import alipayChinese from "@/assets/images/seller/setting/alipay-chinese.png"
|
||||
const checked = ref(true)
|
||||
const payList = ref([
|
||||
{
|
||||
type: "paypal",
|
||||
icon: paypal,
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
type: "stripe",
|
||||
icon: stripe,
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
type: "alipay-hk",
|
||||
icon: alipayHk,
|
||||
value: "123123"
|
||||
},
|
||||
{
|
||||
type: "alipay-chinese",
|
||||
icon: alipayChinese,
|
||||
value: "123123"
|
||||
}
|
||||
])
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.settings-index {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
margin: 0 16rem;
|
||||
display: flex;
|
||||
gap: 4.2rem;
|
||||
> div {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4.2rem;
|
||||
> div {
|
||||
border-radius: 1.2rem;
|
||||
overflow: hidden;
|
||||
border: 0.15rem solid #d1d1d1;
|
||||
> .header {
|
||||
line-height: 5rem;
|
||||
background-color: #f6f6f6;
|
||||
padding-left: 2.4rem;
|
||||
font-size: 2rem;
|
||||
color: #666;
|
||||
}
|
||||
> .content {
|
||||
padding: 2.4rem;
|
||||
}
|
||||
}
|
||||
> .stop {
|
||||
border-color: rgba(223, 44, 44, 0.2);
|
||||
> .header {
|
||||
background-color: rgba(223, 44, 44, 0.2);
|
||||
}
|
||||
}
|
||||
> .notification > .content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.8rem;
|
||||
> .left {
|
||||
> .title {
|
||||
font-family: pingfang_medium;
|
||||
font-size: 1.6rem;
|
||||
color: #000;
|
||||
}
|
||||
> .tip {
|
||||
font-family: pingfang_regular;
|
||||
font-size: 1.4rem;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
> .right {
|
||||
.ant-switch {
|
||||
width: 4.8rem;
|
||||
height: 2.6rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
> .payout > .content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.8rem;
|
||||
> .header {
|
||||
> .title {
|
||||
font-family: pingfang_medium;
|
||||
font-size: 1.6rem;
|
||||
color: #000;
|
||||
}
|
||||
> .tip {
|
||||
font-family: pingfang_regular;
|
||||
font-size: 1.4rem;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
> .pay-item {
|
||||
padding: 1.7rem 2.4rem;
|
||||
border-radius: 0.8rem;
|
||||
border: 0.06rem solid #c4c4c4;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.8rem;
|
||||
> .left {
|
||||
> img {
|
||||
width: auto;
|
||||
height: 1.8rem;
|
||||
margin-right: 0.8rem;
|
||||
}
|
||||
> .value {
|
||||
font-family: pingfang_regular;
|
||||
font-size: 1.2rem;
|
||||
color: #585858;
|
||||
}
|
||||
}
|
||||
> .right {
|
||||
> button {
|
||||
width: 10rem;
|
||||
height: 3.8rem;
|
||||
border-radius: 2rem;
|
||||
font-family: pingfang_heavy;
|
||||
font-size: 1.2rem;
|
||||
color: #fff;
|
||||
background: #000000;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
> .manage {
|
||||
background: #fff;
|
||||
border: 0.1rem solid #000000;
|
||||
color: #000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
> .footer {
|
||||
margin-top: 2rem;
|
||||
border-top: 0.1rem solid #c4c4c4;
|
||||
padding: 1.4rem 2.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.8rem;
|
||||
> .left {
|
||||
> .title {
|
||||
font-family: pingfang_medium;
|
||||
font-size: 1.6rem;
|
||||
color: #000;
|
||||
}
|
||||
> .tip {
|
||||
font-family: pingfang_regular;
|
||||
font-size: 1.2rem;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
> .right {
|
||||
> button {
|
||||
width: 10rem;
|
||||
height: 3.8rem;
|
||||
border-radius: 2rem;
|
||||
font-family: pingfang_heavy;
|
||||
font-size: 1.2rem;
|
||||
color: #bdbdbd;
|
||||
background: #f6f6f6;
|
||||
border: none;
|
||||
// cursor: pointer;
|
||||
// &:active {
|
||||
// opacity: 0.8;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> .stop > .content,
|
||||
> .data-privacy > .content {
|
||||
> .title {
|
||||
font-family: pingfang_medium;
|
||||
font-size: 1.6rem;
|
||||
color: #000;
|
||||
margin-bottom: 2.4rem;
|
||||
}
|
||||
> .tip {
|
||||
font-family: pingfang_regular;
|
||||
font-size: 1.4rem;
|
||||
color: #999;
|
||||
margin-bottom: 3rem;
|
||||
> span {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
color: #0080ed;
|
||||
}
|
||||
}
|
||||
> .btns {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 1.2rem;
|
||||
> button {
|
||||
padding: 0 2.4rem;
|
||||
height: 4rem;
|
||||
border-radius: 4rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
font-family: pingfang_heavy;
|
||||
font-size: 1.2rem;
|
||||
color: #fff;
|
||||
background: #000000;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> .stop > .content {
|
||||
> .btns {
|
||||
> button {
|
||||
background: #df2c2c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -4,7 +4,7 @@
|
||||
<div
|
||||
v-for="v in list"
|
||||
:key="v.path"
|
||||
:class="{ active: v.path === activePath }"
|
||||
:class="{ active: new RegExp(`^${v.path}`).test(activePath) }"
|
||||
@click="handleClick(v.path)"
|
||||
>
|
||||
<div class="icon"><svg-icon :name="v.icon" size="20" /></div>
|
||||
@@ -21,6 +21,7 @@
|
||||
import { ref, computed } from "vue"
|
||||
import { useRoute, useRouter } from "vue-router"
|
||||
import toolTipBox from "./toolTipBox.vue"
|
||||
import myEvent from "@/tool/myEvents.js"
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const visible = ref(false)
|
||||
@@ -51,6 +52,14 @@
|
||||
if (path === activePath.value) return
|
||||
router.push(path)
|
||||
}
|
||||
onMounted(()=>{
|
||||
myEvent.add('newListing',()=>{
|
||||
visible.value = true
|
||||
})
|
||||
})
|
||||
onUnmounted(()=>{
|
||||
myEvent.remove('newListing')
|
||||
})
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.seller-dashboard-index {
|
||||
|
||||
@@ -13,7 +13,12 @@
|
||||
:class="{
|
||||
last: i === breadcrumbs.length - 1
|
||||
}"
|
||||
@click="() => router.push({ name: v.name })"
|
||||
@click="
|
||||
() => {
|
||||
const index = -(breadcrumbs.length - i - 1)
|
||||
if (index < 0) router.go(index)
|
||||
}
|
||||
"
|
||||
>{{ v.title }}</span
|
||||
>
|
||||
<span class="icon" v-show="i < breadcrumbs.length - 1">
|
||||
|
||||
@@ -4,7 +4,7 @@ import sellerToolTipImg1 from '@/assets/images/seller/sellerToolTip-1.png'
|
||||
import sellerToolTipImg2 from '@/assets/images/seller/sellerToolTip-2.png'
|
||||
import sellerToolTipImg3 from '@/assets/images/seller/sellerToolTip-3.png'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { useRouter } from 'vue-router'
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
@@ -14,9 +14,9 @@ const props = defineProps({
|
||||
const emit = defineEmits([
|
||||
'update:visible','close'
|
||||
])
|
||||
const router = useRouter()
|
||||
const {t} = useI18n()
|
||||
let data = reactive({
|
||||
visible: props.visible,
|
||||
stepList: [
|
||||
{
|
||||
img: sellerToolTipImg1,
|
||||
@@ -44,6 +44,12 @@ const cleardata = ()=>{
|
||||
emit('close', data.showAgain)
|
||||
}
|
||||
|
||||
const getStarted = ()=>{
|
||||
emit('update:visible', false)
|
||||
router.push({path:'/home/seller/myListings/select'})
|
||||
}
|
||||
|
||||
|
||||
onMounted(()=>{
|
||||
})
|
||||
onUnmounted(()=>{
|
||||
@@ -55,7 +61,7 @@ const { showAgain } = toRefs(data);
|
||||
<div ref="toolTipBoxRef" class="toolTipBox" v-if="visible">
|
||||
<a-modal
|
||||
class="collection generalModel"
|
||||
v-model:visible="data.visible"
|
||||
v-model:visible="props.visible"
|
||||
:footer="null"
|
||||
:get-container="() => toolTipBoxRef"
|
||||
width="126.2rem"
|
||||
@@ -105,7 +111,7 @@ const { showAgain } = toRefs(data);
|
||||
{{t('SellerToolTip.showAgain')}}
|
||||
</label>
|
||||
</div>
|
||||
<div class="gallery_btn" @click="cleardata()">
|
||||
<div class="gallery_btn" @click="getStarted">
|
||||
{{t('SellerToolTip.GetStarted')}}
|
||||
<i class="fi fi-rr-arrow-small-right"></i>
|
||||
</div>
|
||||
@@ -116,9 +122,9 @@ const { showAgain } = toRefs(data);
|
||||
</template>
|
||||
<style lang="less" scoped>
|
||||
.toolTipBox{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
// position: relative;
|
||||
:deep(.generalModel){
|
||||
height: auto;
|
||||
.ant-modal-body{
|
||||
|
||||
Reference in New Issue
Block a user