Files
aida_front/src/component/HomePage/index/model/mannequin/index.vue
2025-05-20 16:47:27 +08:00

421 lines
11 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">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="selectObject.style"
:options="mannequinStyleList"
@change="setWorkspaceStyle"
style="width:100%"
size="large"
:fieldNames="{ label: 'name', value: 'value' }"
>
<template #suffixIcon
><span
class="icon iconfont icon-xiala"
style="color: #343579"
></span
></template>
</a-select>
</div>
</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="[item.id == selectObject.model.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>
<habitSetStyle ref="habitSetStyle" @setWorkspaceStyle="setWorkspaceStyle"></habitSetStyle>
<edit ref="edit" :ageGroup="selectObject.ageGroup" @submit="getModel"></edit>
</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/Detail/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),//选择的项目
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()
})
const dataDom = reactive({
habitSetStyle:null as any,
edit:null as any,
})
const getModel = ()=>{
let value = {
sex:data.selectObject.sex,
style:data.selectObject?.style?data.selectObject?.style:'',
ageGroup:store.state.Workspace.probjects.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(data.libraryList?.[0]==null)data.systemUser=true
if(!data.systemUser){
data.modelList = data.libraryList
}else{
data.modelList = data.systemList
}
}
})
}
const setSelectKey = (item:any)=>{
let value = {
model:{
id:item.id,
url:item.presignedUrl,
type:data.systemUser?'System':'Library',
}
}
store.commit('setProbject',value)
}
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)=>{
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: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,
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: 130rem;
}
> .top{
display: flex;
justify-content: space-between;
margin: 4rem 0 3rem;
> .left,> .right{
display: flex;
align-items: center;
justify-content: space-between;
}
> .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: auto;
max-height: calc(100% - 20rem);
position: relative;
> .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: 0;
position: sticky;
flex-shrink: 0;
background: #fff;
margin: auto 0;
> .upload{
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>