2025-04-01 15:25:15 +08:00
|
|
|
|
<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> -->
|
2025-04-09 14:09:19 +08:00
|
|
|
|
<div class="text" v-show="systemUser">Style:</div>
|
|
|
|
|
|
<div class="generalModel_state" style="width: 20rem;" v-show="systemUser">
|
2025-04-01 15:25:15 +08:00
|
|
|
|
<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>
|
2025-04-09 14:09:19 +08:00
|
|
|
|
<a-switch class="switch" :checked="!systemUser" @click="setSystemUser" />
|
2025-04-01 15:25:15 +08:00
|
|
|
|
<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>
|
2025-04-09 14:09:19 +08:00
|
|
|
|
<span class="icon add" v-if="systemUser" :title="'Add to your library'" @click.stop="addSystemToUser(item)">+</span>
|
2025-04-01 15:25:15 +08:00
|
|
|
|
</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" @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';
|
2025-04-09 14:09:19 +08:00
|
|
|
|
import { Item } from 'ant-design-vue/lib/menu';
|
2025-04-01 15:25:15 +08:00
|
|
|
|
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),//选择的项目
|
2025-04-09 14:09:19 +08:00
|
|
|
|
mannequinStyleList:[] as any,
|
2025-04-01 15:25:15 +08:00
|
|
|
|
mannequinStyle:computed(()=>store.state.UserHabit.mannequinStyle),//女性衣服位置
|
|
|
|
|
|
})
|
|
|
|
|
|
watch(()=>data.mannequinStyle,(newValue,oldValue)=>{
|
|
|
|
|
|
if(newValue != oldValue){
|
|
|
|
|
|
data.mannequinStyleList = JSON.parse(JSON.stringify(newValue))
|
|
|
|
|
|
data.mannequinStyleList.unshift({
|
2025-04-09 14:09:19 +08:00
|
|
|
|
name:'All',
|
2025-04-01 15:25:15 +08:00
|
|
|
|
value:'',
|
|
|
|
|
|
id:'',
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
},{immediate:true})
|
|
|
|
|
|
|
|
|
|
|
|
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)=>{
|
2025-04-09 14:09:19 +08:00
|
|
|
|
|
2025-04-01 15:25:15 +08:00
|
|
|
|
});
|
|
|
|
|
|
}
|
2025-04-09 14:09:19 +08:00
|
|
|
|
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)=>{
|
|
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2025-04-01 15:25:15 +08:00
|
|
|
|
onMounted(()=>{
|
|
|
|
|
|
getModel()
|
|
|
|
|
|
})
|
|
|
|
|
|
return{
|
|
|
|
|
|
...toRefs(dataDom),
|
|
|
|
|
|
...toRefs(data),
|
|
|
|
|
|
setSelectKey,
|
|
|
|
|
|
setSystemUser,
|
|
|
|
|
|
setStyle,
|
|
|
|
|
|
setWorkspaceStyle,
|
|
|
|
|
|
openSetData,
|
|
|
|
|
|
setEdit,
|
|
|
|
|
|
|
|
|
|
|
|
beforeUpload,
|
|
|
|
|
|
fileUploadChange,
|
|
|
|
|
|
getModel,
|
2025-04-09 14:09:19 +08:00
|
|
|
|
deleteSinglePic,
|
|
|
|
|
|
addSystemToUser
|
2025-04-01 15:25:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
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;
|
2025-04-09 14:09:19 +08:00
|
|
|
|
max-height: 100%;
|
2025-04-01 15:25:15 +08:00
|
|
|
|
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{
|
2025-04-09 14:09:19 +08:00
|
|
|
|
padding: 0 2rem;
|
|
|
|
|
|
right: 0;
|
2025-04-01 15:25:15 +08:00
|
|
|
|
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>
|