Files
aida_front/src/component/home/design/mannequin/index.vue
X1627315083 dd3093656b fix
2025-09-03 16:36:06 +08:00

504 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="mannequin">
<div class="top">
<div class="left">
<!-- <div class="text">Style</div>
<div class="text" style="margin: 0 9rem 0 4rem;">{{ selectObject?.styleName }}</div>
<div class="gallery_btn" style="line-height: 5rem;" @click="setStyle">{{ $t('Habit.Select') }}</div> -->
<div class="text" v-show="systemUser">{{ $t('Model.Style') }}</div>
<div class="generalModel_state" style="width: 20rem;" v-show="systemUser">
<div class="generalModel_state_item" style="margin: 0; width: 100%;">
<a-select
v-model:value="selectObjectStyle"
:options="mannequinStyleList"
@change="setWorkspaceStyle"
style="width:100%"
size="large"
:fieldNames="{ label: 'name', value: 'value' }"
>
<template #suffixIcon
><span
class="icon iconfont icon-xiala"
style="color: #000"
></span
></template>
</a-select>
</div>
</div>
</div>
<div class="selectModel">
{{ $t('Model.CurrentModel') }} :
<div class="item" v-for="item ,index in selectObject.model" @click="deleteSelectModel(index)">
<img :src="item.url" alt="">
<span class="icon iconfont icon-shanchu"></span>
</div>
</div>
<div class="right">
<div class="text" :class="{active:systemUser}">{{ $t('Habit.System') }}</div>
<a-switch class="switch" :checked="!systemUser" @click="setSystemUser" />
<div class="text" :class="{active:!systemUser}">{{ $t('Habit.User') }}</div>
</div>
</div>
<div class="model" v-mousewheel>
<div class="item" v-for="item,index in modelList" :key="item.id" :class="[!!selectObject.model.find(objectItem => objectItem.id === item.id)?'active':'',!systemUser?'library':'']" @click="setSelectKey(item)">
<img :src="item.presignedUrl" alt="">
<span v-show="!systemUser" class="icon iconfont icon-tianxie" @click.stop="setEdit(item,!systemUser?'Library':'System','edit')"></span>
<span v-show="!systemUser" class="icon iconfont icon-shanchu" @click.stop="deleteSinglePic(item,index)"></span>
<span class="icon add" v-if="systemUser" :title="'Add to your library'" @click.stop="addSystemToUser(item)">+</span>
</div>
<div class="uploadBox">
<div class="upload" v-if="!systemUser">
<a-upload
:capture="null"
:before-upload="beforeUpload"
:maxCount="1"
accept=".jpg,.png,.jpeg,.bmp"
@change="fileUploadChange"
>
<i class="fi fi-br-upload"></i>
<div style="margin-top: 1rem; font-size: 1.8rem;">Upload mannequin</div>
</a-upload>
</div>
</div>
</div>
<edit ref="edit" :ageGroup="selectObject.ageGroup" @submit="getModel"></edit>
<habitSetStyle ref="habitSetStyle" @setWorkspaceStyle="setWorkspaceStyle"></habitSetStyle>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,createVNode,toRefs, reactive, onMounted, watch} from 'vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
import habitSetStyle from "@/component/modules/habitSetStyle.vue";
import edit from './edit.vue';
import { Modal,message,Upload,CascaderProps } from 'ant-design-vue';
import { Item } from 'ant-design-vue/lib/menu';
export default defineComponent({
components:{
habitSetStyle,edit
},
props:{
},
setup(props,{emit}) {
const {t} = useI18n()
const store = useStore();
const data = reactive({
systemList:[],
libraryList:[],
modelList:[],
systemUser:true,
selectObject:computed(()=>store.state.Workspace.probjects),//选择的项目
selectObjectStyle:'',
mannequinStyleList:[] as any,
mannequinStyle:computed(()=>store.state.UserHabit.mannequinStyle),//女性衣服位置
})
watch(()=>data.mannequinStyle,(newValue,oldValue)=>{
if(newValue != oldValue){
data.mannequinStyleList = JSON.parse(JSON.stringify(newValue))
// data.mannequinStyleList.unshift({
// name:'All',
// value:'',
// id:'',
// })
}
},{immediate:true})
watch(()=>data.selectObject.sex,(newVal)=>{
getModel()
})
watch(()=>data.selectObject.style,(newVal)=>{
data.selectObjectStyle = JSON.parse(JSON.stringify(newVal))
},{immediate:true})
const dataDom = reactive({
habitSetStyle:null as any,
edit:null as any,
})
const getModel = ()=>{
let value = {
sex:data.selectObject.sex,
style:data.selectObjectStyle,
ageGroup:data.selectObject.ageGroup,
}
Https.axiosGet(Https.httpUrls.getMannequins,{params:value}).then((rv: any) => {
if (rv) {
rv.forEach((item:any) => {
if(item.type == 'System'){
data.systemList = item.modelList
}else{
data.libraryList = item.modelList
}
});
if(rv.length == 1){
data.libraryList = []
}
if(data.libraryList?.[0]==null)data.systemUser=true
if(!data.systemUser){
data.modelList = data.libraryList
}else{
data.modelList = data.systemList
}
}
})
}
const setSelectKey = (item:any)=>{
let list = store.state.Workspace.probjects.model
let index = -1
list.forEach((val:any,listIndex:any)=>{
if(val.id == item.id){
index = listIndex
}
})
if(index != -1){
if(list.length > 1){
list.splice(index,1)
}else{
message.info(t('LibraryPage.jsContent13'))//至少选择一个
}
}else if(index == -1){
if(list.length <= 3){
let model = {
id:item.id,
url:item.presignedUrl || item.url,
type:item.type?item.type:data.systemUser?'System':'Library',
}
list.push(model)
}else{
message.info(t('LibraryPage.jsContent13'))//最多选择四个
}
}
}
const deleteSelectModel = (index:number)=>{
let list = store.state.Workspace.probjects.model
if(list.length > 1){
list.splice(index,1)
}else{
message.info(t('LibraryPage.jsContent13'))//最多选择四个
}
}
const setSystemUser = ()=>{
data.systemUser = !data.systemUser
if(!data.systemUser){
data.modelList = data.libraryList
}else{
data.modelList = data.systemList
}
}
const setStyle = ()=>{
dataDom.habitSetStyle.init(data.selectObject);
}
const setWorkspaceStyle = (item:any,value:any)=>{
// data.selectObject.styleName = value.name
// data.selectObject.style = value.value
// data.selectObject.styleId = value.id
getModel()
}
const openSetData = ()=>{
}
const setEdit = (item:any,type:any,editOrUpload:any)=>{
dataDom.edit.showPlacementModal(item,data.selectObject.sex,type,editOrUpload);
}
const beforeUpload = (file:any,fileList:any)=>{
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/bmp';
if (!isJpgOrPng) {
message.info(t('LibraryPage.jsContent3'));
}
const isLt2M = file.size / 1024 / 1024 < 5;
if (!isLt2M) {
message.info(t('LibraryPage.jsContent4'));
}
if(isJpgOrPng && isLt2M){
// currentUploadFileNum = fileList.length
}else{
return (isJpgOrPng && isLt2M) || Upload.LIST_IGNORE;
}
}
const fileUploadChange = (data:any)=>{
let file = data.file
let reader = new FileReader();
reader.onload = (e:any) => {
let data_new;
data_new = window.URL.createObjectURL(new Blob([e.target.result]));
setEdit({url:data_new,file:file.originFileObj},'Library','upload')
};
reader.readAsArrayBuffer(file.originFileObj);
}
const deleteSinglePic = (item:any,index:number)=>{
let list = store.state.Workspace.probjects.model
if(!!list.find((objectItem:any) => objectItem.id === item.id)){
message.info(t('LibraryPage.jsContent12'));
return
}
Modal.confirm({
title: t('LibraryPage.jsContent1'),
icon: createVNode(ExclamationCircleOutlined),
okText: 'Yes',
cancelText: 'No',
mask:false,
centered:true,
onOk() {
confirmDeletePic(item,index,'')
}
});
}
//确定删除图片 有data则是单个
const confirmDeletePic = (item:any,index:any,nData:any)=>{
let newData = {
libraryIds:[item.id],
deleteModelConfirm:1,
// deleteModelConfirm:item.deleteModelConfirm?item.deleteModelConfirm : 0,
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
}
if(nData)newData = nData
Https.axiosPost(Https.httpUrls.batchDeleteLibrary, newData).then(
(rv: any) => {
getModel()
}
).catch((res)=>{
});
}
const addSystemToUser = (item:any)=>{
let newData = {
sysModelId:item.id,
}
Https.axiosGet(Https.httpUrls.addSysModelToLib, {params:newData}).then(
(rv: any) => {
getModel()
let value = {
id:rv.id,
url:rv.url,
type:'Library',
}
setSelectKey(value)
data.systemUser = false
}
).catch((res)=>{
});
}
onMounted(()=>{
getModel()
})
return{
...toRefs(dataDom),
...toRefs(data),
setSelectKey,
deleteSelectModel,
setSystemUser,
setStyle,
setWorkspaceStyle,
openSetData,
setEdit,
beforeUpload,
fileUploadChange,
getModel,
deleteSinglePic,
addSystemToUser
}
},
directives:{
mousewheel:{
mounted (el) {
el.addEventListener('wheel',(e:WheelEvent)=>{
let num = 0
if(e.deltaY > 0){
num = 25
}else{
num = -25
}
el.scrollBy(num, 0);
},{ passive: true })
}
},
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.mannequin{
width: 100%;
height: 100%;
position: relative;
background: #fff;
font-weight: 600;
font-size: 1.8rem;
display: flex;
flex-direction: column;
align-items: center;
> .top,> .model{
width: 100%;
// width: 130rem;
}
> .top{
display: flex;
justify-content: space-between;
margin: 4rem 0 3rem;
> .left,> .right,> .selectModel{
display: flex;
align-items: center;
justify-content: space-between;
}
> .selectModel{
> .item{
height: 6rem;
width: 6rem;
margin: 0 .2rem;
position: relative;
>img{
height: 100%;
width: 100%;
object-fit: contain;
}
> span{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.2);
color: #fff;
cursor: pointer;
display: none;
}
&:hover{
> span{
display: flex;
}
}
}
margin-left: auto;
}
> .right{
> .switch{
margin: 0 2rem;
}
> .text{
color: rgba(0, 0, 0, 0.5);
&.active{
color: rgba(0, 0, 0, 1);
font-weight: 900;
}
}
}
}
> .model{
// height: 70rem;
width: auto;
max-width: 130rem;
display: flex;
flex-direction: row;
overflow-y: hidden;
// max-height: calc(100% - 20rem);
height: 100%;
position: relative;
flex: 1;
> .item{
width: 25rem;
height: 55rem;
max-height: 100%;
margin: auto 0;
flex-shrink: 0;
cursor: pointer;
margin-right: 1rem;
padding: 0 1rem;
position: relative;
&:last-child{
margin-right: 0;
}
&.active{
border-radius: 2rem;
border: 2px solid #000;
}
> .icon{
display: none;
position: absolute;
top: 2rem;
font-size: 2.5rem;
}
> .icon-tianxie{
right: 2rem;
}
> .icon-shanchu{
left: 2rem;
font-size: 2.7rem;
}
> .add{
top: 1rem;
right: 2rem;
padding: 1rem;
border-radius: 50%;
}
> img{
width: 100%;
height: 100%;
object-fit: contain;
}
&.item{
&:hover{
> .icon-tianxie{
display: block;
}
> .add {
display: flex;
}
}
}
&.library{
&:hover{
>.icon-shanchu{
display: block;
}
}
}
}
> .uploadBox{
padding: 0 2rem;
right: -1px;
position: sticky;
flex-shrink: 0;
background: #fff;
// margin: auto 0;
> .upload{
height: 100%;
// height: 55rem;
width: 29rem;
border: 1px dashed transparent;
background: linear-gradient(#fff, #fff) padding-box, repeating-linear-gradient(-45deg, #fff 0, #fff 0.3em, #000 0, #000 0.6em);
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
cursor: pointer;
i{
font-size: 4rem;
border-radius: 50%;
width: 5rem;
height: 5rem;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
}
:deep(.ant-upload-list-text){
display: none;
}
}
}
}
}
</style>