chat聊天功能

This commit is contained in:
X1627315083
2025-05-20 16:47:27 +08:00
parent 8bc0a52ab8
commit c235d0de4a
50 changed files with 4902 additions and 2861 deletions

View File

@@ -266,8 +266,8 @@ export default defineComponent({
.account_page{
height: 100%;
// overflow-y: auto;
padding: 0 30rem;
padding-top: 7rem;
padding: 0 7rem;
padding-top: 4rem;
display: flex;
overflow: hidden;
.account_page_titleImg{

View File

@@ -36,8 +36,8 @@
{{ $t('cancelRenewal.subscriptionRenewal') }}
</div>
<div class="button_box">
<div class="gallery_btn white" v-if="userDetail.status != 'active' && userDetail.systemUser != 3" @click="subscribe">{{ $t('cancelRenewal.Continue') }}</div>
<div class="gallery_btn" v-else @click="cancelSubscription">{{ $t('cancelRenewal.cancel') }}</div>
<div class="gallery_btn" v-if="userDetail.status == 'active' && userDetail.systemUser != 3" @click="cancelSubscription">{{ $t('cancelRenewal.cancel') }}</div>
<div class="gallery_btn white" v-else @click="subscribe">{{ $t('cancelRenewal.Continue') }}</div>
</div>
<div class="mark_loading" v-show="isShowMark">
<a-spin size="large" />

View File

@@ -0,0 +1,196 @@
<template>
<div class="allUserPoerationModal" ref="allUserPoerationModal"></div>
<a-modal
class="allUserPoeration_modal generalModel"
v-model:visible="operationsModal"
:footer="null"
:get-container="() => $refs.allUserPoerationModal"
width="50%"
height="35rem"
:maskClosable="false"
:centered="true"
:closable="false"
:mask="true"
wrapClassName="#app"
:keyboard="false"
>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="23" cy="23" r="23" fill="white" fill-opacity="0.3"/>
<rect x="32.5063" y="12" width="3" height="29" rx="1.5" transform="rotate(45 32.5063 12)" fill="white"/>
<rect x="34.6274" y="32.5059" width="3" height="29" rx="1.5" transform="rotate(135 34.6274 32.5059)" fill="white"/>
</svg>
</div>
</div>
<div class="modal_title_text">
<div>{{ title }} User</div>
</div>
<div class="allUserPoeration_center admin_page">
<div class="admin_state_item">
<span>User Name: <span>*</span></span>
<input
:readonly="title != 'Add'"
:class="{active:title != 'Add'}"
v-model="name"
placeholder="Please enter user name"
type="text"
style="width: 250px"
/>
</div>
<div class="admin_state_item">
<span>User Type:<span>*</span></span>
<a-select
v-model:value="systemUser"
size="large"
style="width: 250px"
optionFilterProp="label"
:options="state"
placeholder="Please select"
allowClear
show-search
></a-select>
</div>
</div>
<div class="allUserPoeration_btn admin_page">
<div class="admin_search_item" @click="cancelDsign">
Close
</div>
<div class="admin_search_item" @click="setOk">
OK
</div>
</div>
</a-modal>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
</template>
<script>
import { defineComponent, ref, reactive, watch, onMounted, nextTick, toRefs } from "vue";
import { Https } from "@/tool/https";
import { Modal, message } from "ant-design-vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
import { formatTime } from "@/tool/util";
export default defineComponent({
components: {
},
emits: ['searchHistoryList'],
setup(props,{emit}) {
let operations = reactive({
operationsModal:false,
operationsEdit:false,
loadingShow:false,
title:''
})
let operationsData = reactive({
name:'',
type:'Enterprise',
})
let state = ref([
{
label:'Enterprise',
value:'Enterprise',
},
{
label:'Education',
value:'Education',
},
]);
let init = (funStr,data)=>{
operations.operationsModal = true
operations.operationsEdit = true
operations.title = funStr
if(funStr == 'Add') operations.operationsEdit = false
if(funStr == 'Edit'){
operationsData.name=data.name
operationsData.type=data.type
}
}
let setAddData = ()=>{
return {
"name": operationsData.name,
"type": operationsData.type,
}
}
let setEditData = ()=>{
return {
"name": operationsData.country,
"type": operationsData.credits,
}
}
let cancelDsign = ()=>{
operationsData.name=''
operationsData.type='Enterprise'
}
let setOk = ()=>{
let data
if(operations.title == 'Add'){
data = setAddData()
if(!data.name)return message.warning('Please check the input box marked with *')
Https.axiosPost(Https.httpUrls.addOrganization, data).then(
(rv) => {
if (rv) {
cancelDsign()
emit('searchHistoryList')
}
}
);
}
}
return {
...toRefs(operations),
...toRefs(operationsData),
state,
cancelDsign,
init,
setOk,
};
},
data() {
return {
};
},
mounted() {},
methods: {
},
});
</script>
<style lang="less" scoped>
:deep(.allUserPoeration_modal){
.ant-modal-body{
height: auto;
display: flex;
flex-direction: column;
}
}
</style>
<style lang="less" scoped>
.allUserPoeration_modal {
.closeIcon {
z-index: 2;
}
.allUserPoeration_btn{
display: flex;
flex-direction: row;
height: auto;
justify-content: flex-end;
padding: 1rem 0;
.admin_search_item{
margin-bottom: 0;
}
}
.allUserPoeration_center{
flex: 1;
overflow-y: auto;
flex-direction: row;
flex-wrap: wrap;
}
}
</style>

View File

@@ -0,0 +1,230 @@
<template>
<div class="admin_page">
<div class="admin_table_search" >
<div class="admin_state">
<div class="admin_state_item">
<span>Status:</span>
<a-select
v-model:value="status"
size="large"
style="width: 250px"
optionFilterProp="label"
:options="statusList"
placeholder="Please select"
allowClear
show-search
></a-select>
</div>
</div>
<div class="admin_search">
<div class="admin_search_item" @click="searchHistoryList">
Search
</div>
<div class="admin_search_item" @click="addhHistoryList">
Add
</div>
</div>
</div>
<div class="admin_table_content" ref="historyTable">
<a-table
@resizeColumn="handleResizeColumn"
:loading="tableLoading"
:columns="columns"
:data-source="dataList"
:scroll="{ y: historyTableHeight }"
@change="changePage"
:showSorterTooltip='false'
:pagination="{
showSizeChanger: true,
current: currentPage,
pageSize: pageSize,
total: total,
showQuickJumper: true,
bordered: false,
}"
>
</a-table>
</div>
<add ref="add" @searchHistoryList="searchHistoryList"></add>
</div>
</template>
<script lang="ts">
import {
defineComponent,
ref,
createVNode,
computed,
reactive,
toRefs,
onMounted,
} from "vue";
import { formatTime } from "@/tool/util";
import { useStore } from "vuex";
import { Https } from "@/tool/https";
import {getCookie,clonAllCookie} from '@/tool/cookie'
import add from './add.vue'
export default defineComponent({
components: {add},
setup() {
const store:any = useStore()
let filter: any = reactive({
dataList: [],
tableLoading: false,
countryList: computed(()=>{
return store.state.adminPage.country
}),
add:null as any,
status:'',
});
let filterData: any = reactive({
currentPage: 1,
pageSize: 10,
total: 0,
country: "",
status: "",
type: "",
});
let selectList=reactive({
statusList:[
{
label: "all",
value: "",
},
{
label:'Enterprise',
value:'Enterprise',
},
{
label:'Education',
value:'Education',
},
],
})
let renameData: any = ref({}); //修改名字选中的数据
const columns: any = computed(() => {
return [
{
title: "City",
align: "center",
dataIndex: "city",
key: "city",
width:150,
ellipsis:true
},
{
title: "Country",
align: "center",
dataIndex: "country",
key: "country",
width:150,
ellipsis:true
},
{
title: "Create Time",
align: "center",
dataIndex: "createTime",
key: "createTime",
width:150,
ellipsis:true,
},
{
title: "Status",
align: "center",
dataIndex: "status",
key: "status",
fixed: "right",
width:150,
Operations: true,
ellipsis:true,
}
];
});
//改变页码
let changePage = (e: any, filters:any, sorter:any) => {
filterData.currentPage = e.current;
filterData.pageSize = e.pageSize;
gettrialList();
};
//查询列表
let searchHistoryList = () => {
filterData.currentPage = 1;
gettrialList();
};
//获取列表
let gettrialList = () => {
filter.tableLoading = true;
Https.axiosGet(Https.httpUrls.queryOrganization, {params:{type:'Enterprise'}}).then(
(rv: any) => {
if (rv) {
console.log(rv)
// this.dataList = rv
filter.dataList = rv.content;
filterData.total = rv.total;
filter.tableLoading = false;
// this.workspaceItem.position = this.singleTypeList[0].label
}
}
);
};
let addhHistoryList = () => {
filter.add.init('Add','')
};
onMounted(() => {
gettrialList();
});
return {
...toRefs(filter),
...toRefs(filterData),
...toRefs(selectList),
columns,
renameData,
changePage,
searchHistoryList,
gettrialList,
addhHistoryList,
};
},
data() {
return {
historyTableHeight: 0,
handleResizeColumn: (w: any, col: any) => {
col.width = w;
},
};
},
mounted() {
let historyTable: any = this.$refs.historyTable;
this.historyTableHeight = historyTable.clientHeight - 200;
},
methods: {},
});
</script>
<style lang="less" scoped>
.admin_page .admin_table_search .admin_state {
display: flex;
flex-wrap: wrap;
}
:deep(.operate_list){
.fi{
font-size: 2rem;
margin-right: 1rem;
}
.success{
.fi-ss-check-circle{
color: #3ab45c;
}
}
.pending{
.fi-ss-check-circle{
color: #ffc628;
}
}
.fail{
.fi-ss-check-circle{
color: #ff0000;
}
}
}
</style>

View File

@@ -653,7 +653,6 @@ export default defineComponent({
}
.modal_imgItem{
position: absolute;
overflow: hidden;
top: 0;
}

View File

@@ -711,7 +711,6 @@ export default defineComponent({
z-index: 3;
.modal_imgItem{
position: absolute;
overflow: hidden;
top: 0;
img{
width: 100%;

View File

@@ -755,8 +755,8 @@ export default defineComponent({
if(key == 'upImgFiles')imgWidth[key] = setImageWidth(key,img);
let url = imgUrl.split('?')[0]
var match = url.match(/:(\d+)\/(.*)/);
minioUrl = match[2]
var match = url.match(/^(?:https?:\/\/[^\/]+)\/(.*)/);
minioUrl = match[1]
// let id =
let proportion = img.height / img.width; //计算图形宽高比例
// let imgWidth = setImageWidth(key)

View File

@@ -246,7 +246,7 @@ export default defineComponent({
sketchCategory,
UpgradePlan,
},
props: ["msg",'sketchCatecoryList','scene'],
props: ["msg",'sketchCatecoryList','scene','gender'],
setup(props) {
// console.log(prop.msg);
let userDetail:any= computed(()=>{
@@ -366,8 +366,8 @@ export default defineComponent({
}),
upload: {
isPin: 0,
gender:'',
level1Type: prop.msg,
gender: prop.gender,
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
},
token: "",

View File

@@ -607,7 +607,6 @@ export default defineComponent({
flex: 1;
height: calc(30rem*1.2);
overflow-x: hidden;
border-right: 1px solid #e5e5e5;
display: flex;
flex-direction: column;
&.moodboard_body::-webkit-scrollbar {
@@ -705,8 +704,10 @@ export default defineComponent({
}
.modal_img_max{
// flex: 1;
width: calc(57rem*1.2);
height: calc(35rem*1.2);
// width: calc(57rem*1.2);
// height: calc(35rem*1.2);
width: 100%;
aspect-ratio: 1.62 / 1;
position: relative;
.mark_loading{
position: absolute;

View File

@@ -719,7 +719,6 @@ export default defineComponent({
padding-top: calc(2.5rem*1.2);
height: calc(30rem*1.2);
overflow-x: hidden;
border-right: 1px solid #e5e5e5;
&.printboard_body::-webkit-scrollbar {
display: none;
}

View File

@@ -127,6 +127,7 @@
v-show="openClick == 3"
ref="Generate"
msg="Sketchboard"
:gender="upload.gender"
:scene="scene"
:sketchCatecoryList="sketchCatecoryList"
></Generate>
@@ -682,7 +683,6 @@ export default defineComponent({
padding-top: calc(2.5rem*1.2);
height: calc(30rem*1.2);
overflow-x: hidden;
border-right: 1px solid #e5e5e5;
display: flex;
flex-direction: column;
&.moodboard_body::-webkit-scrollbar {

View File

@@ -299,7 +299,6 @@ export default defineComponent({
// overflow-x: hidden;
display: flex;
flex-direction: column;
border-right: 1px solid #e5e5e5;
position: relative;
.mark_loading{
position: absolute;

View File

@@ -577,7 +577,6 @@ export default defineComponent({
flex: 1;
height: calc(30rem*1.2);
overflow-x: hidden;
border-right: 1px solid #e5e5e5;
display: flex;
flex-direction: column;
&.moodboard_body::-webkit-scrollbar {
@@ -673,11 +672,10 @@ export default defineComponent({
padding-block: calc(2rem*1.2);
}
.modal_img_max{
// flex: 1;
// width: 57rem;
// height: 35rem;
width: 92rem;
height: 56.5rem;
// width: calc(57rem*1.2);
// height: calc(35rem*1.2);
width: 100%;
aspect-ratio: 1.62 / 1;
position: relative;
.mark_loading{
position: absolute;

View File

@@ -923,7 +923,6 @@ export default defineComponent({
position: relative;
cursor: pointer;
text-align: center;
overflow: hidden;
.moreBox{
position: absolute;
right: 1rem;

View File

@@ -129,6 +129,7 @@
ref="Generate"
msg="Sketchboard"
:scene="scene"
:gender="workspace.sex"
:sketchCatecoryList="sketchCatecoryList"
></Generate>
</div>
@@ -685,7 +686,6 @@ export default defineComponent({
padding-top: calc(2.5rem*1.2);
height: calc(30rem*1.2);
overflow-x: hidden;
border-right: 1px solid #e5e5e5;
display: flex;
flex-direction: column;
&.moodboard_body::-webkit-scrollbar {
@@ -877,7 +877,6 @@ export default defineComponent({
position: relative;
cursor: pointer;
text-align: center;
overflow: hidden;
.moreBox{
position: absolute;
right: 1rem;

View File

@@ -1,12 +1,14 @@
<template>
<div ref="placementModal" v-if="placementShow">
<a-modal class="generalModel fullScreen"
<a-modal class="generalModel "
:class="{fullScreen:!isPop}"
v-model:visible="placementShow"
:footer="null"
width="100%"
:width="isPop?'150rem':'100%'"
:height="isPop?'90rem':'100%'"
:get-container="() => $refs.placementModal"
height="100%"
:maskClosable="false"
:mask="mannEditMask"
:keyboard="false"
:centered="true"
:closable="false"
@@ -201,6 +203,16 @@ export default defineComponent({
components:{
VueCropper,
},
props: {
isPop: {
type: Boolean,
default: false,
},
ageGroup: {
type: String,
default: '',
}
},
emits:['submit'],
setup() {
const store = useStore()
@@ -219,6 +231,7 @@ export default defineComponent({
modelType:'Library',
slider:50,
editOrUpload:'edit',//edit 编辑 upload 上传
mannEditMask:false,
})
const dataDom = reactive({
placement:null as any,
@@ -430,6 +443,7 @@ export default defineComponent({
},
async showPlacementModal(value:any,sex:any,type:any,editOrUpload:any){
// this.sex = arr[0].value
this.editOrUpload = editOrUpload
this.placementShow = true
this.isShowMark = true
@@ -848,7 +862,7 @@ export default defineComponent({
cropper.getCropData(async (value:any) => {
// 转换为File对象
if(this.printObject.templateId || this.printObject.id){
this.printObject.id = this.printObject.relationId
if(this.printObject.relationId)this.printObject.id = this.printObject.relationId
this.confrimSubmit()
}else{
let file:any = base64toFile(value,this.printObject.file.name || '-');
@@ -988,8 +1002,8 @@ export default defineComponent({
level2Type:'',
checkMd5:1,
sex:this.sex,
ageGroup:this.$props.ageGroup,
modelType:modelType,
ageGroup:this.store.state.Workspace.probjects.ageGroup,
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
}
this.isShowMark = true
@@ -1133,19 +1147,22 @@ export default defineComponent({
})
</script>
<style lang="less" scoped>
:deep(.ant-modal-body){
padding: 4rem 5rem;
margin-bottom: 0;
.generalModel_btn {
.generalModel_closeIcon{
transform: translate(-100%, 100%);
svg{
color: #000;
:deep(.ant-modal-centered){
// position: absolute;
.ant-modal-body{
padding: 4rem 5rem;
margin-bottom: 0;
.generalModel_btn {
.generalModel_closeIcon{
transform: translate(-100%, 100%);
svg{
color: #000;
}
}
}
}
}
.close_icon{
width: 3.6rem;
height: 3.6rem;
@@ -1219,7 +1236,7 @@ export default defineComponent({
position: absolute;
left: 0;
top: 18rem;
left: 30rem;
left: 18rem;
.select_block{
// background: #FFFFFF;
margin-bottom: 3rem;

View File

@@ -57,7 +57,7 @@
</div>
<habitSetStyle ref="habitSetStyle" @setWorkspaceStyle="setWorkspaceStyle"></habitSetStyle>
<edit ref="edit" @submit="getModel"></edit>
<edit ref="edit" :ageGroup="selectObject.ageGroup" @submit="getModel"></edit>
</div>
</template>
<script lang="ts">

View File

@@ -279,7 +279,8 @@ export default defineComponent({
}
}
> .selectModel{
width: 70rem;
width: 40%;
// width: 70rem;
flex-shrink: 0;
height: 100%;
background: #f7f8fa;

View File

@@ -158,6 +158,7 @@ export default defineComponent({
const selectImgItem = (item:any,)=>{
data.selectImg = item
data.fileList.forEach((listItem:any)=>listItem.isChecked = false)
console.log(data.currentList)
data.currentList.forEach((listItem:any)=>listItem.isChecked = false)
item.isChecked = true
if(item.url || item.imgUrl)data.selectImg.minioUrl = getMinioUrl(item.url || item.imgUrl)

View File

@@ -81,6 +81,7 @@ export default defineComponent({
canvas:null as any,
})
const open = (str:any,button:any)=>{
console.log(button)
nextTick(()=>{
if(dataDom[str]?.openSetData){
dataDom[str].openSetData(button)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -277,7 +277,7 @@ export default defineComponent({
let bor = false
if(this.newPicName && this.selectCode == 'History'){//多选修改名字
await Https.axiosPost(Https.httpUrls.updateUserGroupName, data).then(
await Https.axiosPost(Https.httpUrls.saveOrUpdate, data).then(
(rv: any) => {
bor = true
}

View File

@@ -479,19 +479,18 @@ export default defineComponent({
operationType: "LOGIN",
ip: "",
};
this.clearTimer()
this.time = 60;
this.emailStap = 2;
this.emailCode = ["", "", "", "", "", ""];
this.createTimer();
if (this.loginTime) {
this.loginTime = false;
Https.axiosPost(Https.httpUrls.enterpriseLogin, data)
.then((rv: any) => {
if (rv) {
this.clearTimer()
this.time = 60;
this.emailStap = 2;
this.emailCode = ["", "", "", "", "", ""];
this.createTimer();
this.userId = rv.userId;
this.loginType = "email";
this.createTimer();
localStorage.setItem("loginEmail", this.email);
localStorage.setItem("loginPassword", this.password);
}

View File

@@ -460,11 +460,7 @@ export default defineComponent({
ip: "",
};
// this.loginType = 'email'
this.clearTimer()
this.time = 60;
this.emailStap = 2;
this.emailCode = ["", "", "", "", "", ""];
this.createTimer();
if (this.loginTime) {
this.loginTime = false;
Https.axiosPost(Https.httpUrls.preLogin, data)
@@ -473,6 +469,12 @@ export default defineComponent({
// this.loginType = 'email'
// }
if (rv) {
this.clearTimer()
this.time = 60;
this.emailStap = 2;
this.emailCode = ["", "", "", "", "", ""];
this.createTimer();
this.userId = rv.userId;
this.loginType = "email";

View File

@@ -478,16 +478,17 @@ export default defineComponent({
operationType: "LOGIN",
ip: "",
};
this.clearTimer()
this.time = 60;
this.emailStap = 2;
this.emailCode = ["", "", "", "", "", ""];
this.createTimer();
if (this.loginTime) {
this.loginTime = false;
Https.axiosPost(Https.httpUrls.schoolLogin, data)
.then((rv: any) => {
if (rv) {
this.clearTimer()
this.time = 60;
this.emailStap = 2;
this.emailCode = ["", "", "", "", "", ""];
this.createTimer();
this.userId = rv.userId;
this.loginType = "email";
localStorage.setItem("loginEmail", this.email);

View File

@@ -0,0 +1,531 @@
<template>
<div class="chat" :class="{active:!openChat}" @click.stop="">
<div v-show="!openChat" class="left" @click="()=>{openChat = !openChat;isChattingRecords=false}">
<i class="fi fi-br-angle-small-down"></i>
</div>
<div class="chatBox">
<div class="chattingRecords" v-show="chatList.length > 0 && isChattingRecords">
<div class="itemBox" ref="chatBox">
<div class="item" v-for="item in chatList" :class="{user:item.role == 'user'}">
<div class="textBox">
<div class="icon">ICON</div>
<div class="text" v-show="item.content.message || item.content.img || item.content.color">
<span>{{item.content.message}}</span>
<div class="fileBox">
<div v-if="item?.fileList?.length > 0" class="item" v-for="fileItem in item.fileList">
<div>{{fileItem.name}}</div>
</div>
</div>
<div class="imgBox">
<img v-if="item.content?.img?.length > 0" v-for="imgItem in item.content?.img" :src="imgItem.minioUrl" alt="">
</div>
<div class="colorBox">
<div v-if="item.content?.color?.length > 0" class="item" v-for="colorItem in item.content?.color">
<div class="color" :style="{'background-color':`rgba(${colorItem.rgb.replace(/\s+/g, ',')})`}"></div>
<div class="text">{{ colorItem.rgb.replace(/\s+/g, ',') }}</div>
</div>
</div>
</div>
<i class="fi fi-br-loading" v-if="!item.content.message && !item.content.img && !item.content.color"></i>
</div>
</div>
</div>
</div>
<div class="content" @click="openChattingRecords">
<textarea ref="textarea" @input="inputText($event)" @keydown.enter.prevent="sendChat" placeholder="Write your message"></textarea>
<div class="btn">
<div class="uploadBox">
<div class="filList">
<div class="item" v-for="item,index in filList">
<div>{{item.name}}</div>
<span class="icon iconfont icon-shanchu" @click="deleteFile(item,index)"></span>
</div>
</div>
<i class="fi fi-br-upload">
<input type="file" @change="handleFileUpload($event)">
</i>
</div>
<div class="sendBox">
<div class="enableThinking" :class="{active:enableThinking}" @click="()=>enableThinking = !enableThinking">Deep Thinking</div>
<div class="maxNum">{{ chatContent.length }}/10000</div>
<div class="send" :class="{active:chatContent.length>0}" @click="sendChat">
<i class="fi fi-ss-paper-plane-top"></i>
</div>
</div>
</div>
</div>
</div>
<div v-show="openChat" class="right" @click="()=>{openChat = !openChat;isChattingRecords=false}">
<i class="fi fi-br-angle-small-down"></i>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,inject,nextTick,createVNode,toRefs, reactive, watch} from 'vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { Modal,message,Upload,CascaderProps } from 'ant-design-vue';
import { useI18n } from 'vue-i18n'
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
export default defineComponent({
components:{
},
props:{
},
emits:['chatChange'],
setup(props,{emit}) {
const store = useStore();
const data = reactive({
chatContent:'',
openChat:true,
chatList:[
] as any,
isChattingRecords:false,
selectObject:computed(()=>store.state.Workspace.probjects) as any,//选择的项目
filList:[] as any,
setIsShowMark:inject('setIsShowMark') as any,
isFinish:true,
enableThinking:false,//深度思考
})
const dataDom = reactive({
textarea:null as any,
chatBox:null as any,
})
watch(()=>data.selectObject.id,(newValue,oldValue)=>{
if(newValue){
getChatHistory(newValue)
}
})
const inputText = (e:any)=>{
if(e.target.value.length <= 1000){
data.chatContent = e.target.value
}else{
e.target.value = data.chatContent
}
e.target.style.height = `${e.target.scrollHeight}px`;
}
const sendChat = ()=>{
if(!data.isFinish)return
if(!data.chatContent)return
let fileList = JSON.parse(JSON.stringify(data.filList))
let fileUrl = (fileList.filter((item:any)=>item.type == 'file').length > 0) ? fileList.filter((item:any)=>item.type == 'file')[0].minioPath : ''
let imageUrlList = (fileList.filter((item:any)=>item.type == 'image').length > 0)? fileList.filter((item:any)=>item.type == 'image').map((item:any)=>item.minioPath).join(',') : ''
data.chatList.push({content:{message:data.chatContent},role:'user',fileList:fileList})
data.chatList.push({content:{message:''},role:'system'})
const eventSource = new EventSource(`${process.env.VUE_APP_BASE_URL}${Https.httpUrls.llmStream}?token=${getCookie('token')}&prompt=${data.chatContent}&projectId=${data.selectObject.id}&fileUrl=${fileUrl}&imageUrlList=${imageUrlList}&enableThinking=${data.enableThinking}`);
data.chatContent = ''
dataDom.textarea.value = ''
data.filList = []
eventSource.onmessage = function(event) {
data.isFinish = false
// console.log('收到数据:', JSON.parse(event.data));
// if(event.data.status == 'DESIGN_SIGNAL'){
// emit('chatChange',{type:'design'})
// }else if(event.data.status == 'RUNNING'){
// data.chatList[data.chatList.length-1].content.message+=JSON.parse(event.data).content
// }
const container = dataDom.chatBox;
container.scrollTop = container.scrollHeight;
if(JSON.parse(event.data).status == "[RUNNING]"){
data.chatList[data.chatList.length-1].content.message+=JSON.parse(event.data).content
}else{
if(JSON.parse(event.data).status == "[DESIGN_SIGNAL]"){
}else if(JSON.parse(event.data).status == "[COLOR_SIGNAL]"){
data.chatList.push({content:{message:''},role:'system'})
data.chatList[data.chatList.length-1].content.color = JSON.parse(JSON.parse(event.data).tools_data).receiveCollectionElementList
data.chatList.push({content:{message:''},role:'system'})
}else{
data.chatList.push({content:{message:''},role:'system'})
data.chatList[data.chatList.length-1].content.img = JSON.parse(JSON.parse(event.data).tools_data).receiveCollectionElementList
data.chatList.push({content:{message:''},role:'system'})
}
console.log(data.chatList[data.chatList.length-1].content)
emit('chatChange',{type:JSON.parse(event.data).status})
}
};
eventSource.onerror = function(error) {
console.log(error,EventSource.CLOSED,eventSource.readyState)
if (eventSource.readyState === EventSource.CLOSED) {
data.chatList[data.chatList.length-1].content.message='服务器繁忙,请稍后再试。'
} else {
eventSource.close()
data.isFinish = true
}
};
}
const getChatHistory = (objectId:number)=>{
let value = {
projectId:objectId,
page:1,
pageSize:100,
}
Https.axiosPost(Https.httpUrls.getChatHistory,value).then((rv)=>{
if(rv){
rv.content.forEach((item:any,index:number) => {
if(rv.content[rv.content.length - index -1].role == 'system'){
let text = rv.content[rv.content.length - index -1].content
if(rv.content[rv.content.length - index -1].isImage == 1){
rv.content[rv.content.length - index -1].content={
img : JSON.parse(rv.content[rv.content.length - index -1].content)
}
}else if(rv.content[rv.content.length - index -1].isImage==2){
rv.content[rv.content.length - index -1].content={
color : JSON.parse(rv.content[rv.content.length - index -1].content)
}
}else{
rv.content[rv.content.length - index -1].content = {
message:text
}
}
}else{
let content = JSON.parse(rv.content[rv.content.length - index -1].content)
content.fileList = []
if(content.file || content.image){
let getName = (url:any)=>{
let minio = url.splice('?')[0]
return minio.splice('/')[minio.splice('/').length-1]
}
if(content.file){
content.file.forEach((item:any)=>{
content.fileList.push({name:getName(item),type:'file',url:item})
})
}
if(content.image){
content.image.forEach((item:any)=>{
content.fileList.push({name:getName(item),type:'image',url:item})
})
}
}
rv.content[rv.content.length - index -1].content = content
}
data.chatList.push(rv.content[rv.content.length - index -1])
});
}
})
}
const openChattingRecords = ()=>{
data.isChattingRecords = true
let setRecords = ()=>{
data.isChattingRecords = false
document.removeEventListener('click',setRecords)
}
document.addEventListener('click',setRecords)
}
const handleFileUpload = (event:any)=>{
if (event.target.files[0].size > 5 * 1024 * 1024) { // 5MB
message.info('The file size cannot exceed 5MB.');
return
}
let type = event.target.files[0].type.startsWith('image/')
if(type){
if(data.filList.filter((item:any)=>item.type == 'image').length >= 5){
message.info('You can only upload five pictures.');
return
}
}else{
if(data.filList.filter((item:any)=>item.type == 'file').length >= 1){
message.info('You can only upload one file.');
return
}
}
data.setIsShowMark(true)
const formData = new FormData();
formData.append('file', event.target.files[0]);
let config:any = {
headers:{'Content-Type':'multipart/form-data','Accept':'*/*' },
params:formData,
}
Https.axiosPost(Https.httpUrls.llmUploadFile,formData,config)
.then((rv: any) => {
let obj = {
name:event.target.files[0].name,
type:type?'image':'file',
minioPath:rv[0],
url:rv[1],
}
data.filList.push(obj)
// data.filList.unshift(rv)
data.setIsShowMark(false)
}
).catch(rv=>{
data.setIsShowMark(false)
})
}
const deleteFile = (item:any,index:number)=>{
data.filList.splice(index,1)
}
return{
...toRefs(dataDom),
...toRefs(data),
inputText,
sendChat,
openChattingRecords,
handleFileUpload,
deleteFile,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.chat{
position: absolute;
left: 50%;
transform: translateX(-50%);
z-index: 999;
bottom: 3.2rem;
top: auto;
width: 50%;
transition: all .3s;
border-radius: 2.4rem;
display: flex;
border: 1px solid #e5e5e5;
background: #fff;
overflow: hidden;
&.active{
left: auto;
right: 0;
transform: translateX(calc(100% - 3rem));
}
> .chatBox{
flex: 1;
overflow: hidden;
> .chattingRecords{
> .itemBox{
width: 100%;
padding: 1.6rem 2rem;
max-height: 75vh;
overflow-y: auto;
> .item{
display: flex;
line-height: 1.75;
// width: min-content;
&.user{
> .textBox{
margin-left: auto;
background: #f5f5f5;
max-width: 60%;
> .text{
> .fileBox{
> .item{
height: 3rem;
padding: .5rem 1rem;
background: #efeff1;
border-radius: .5rem;
margin-right: 1rem;
font-size: 1.4rem;
line-height: 2rem;
display: flex;
> div{
white-space: nowrap;
overflow: hidden;
max-width: 10rem;
text-overflow: ellipsis;
}
}
}
}
> .icon{
display: none;
}
}
}
> .textBox{
display: flex;
padding: 1.2rem 2rem;
border-radius: 2.4rem;
> .text{
// display: inline-block;
// width: min-content;
max-width: 100%;
width: 100%;
// width: min-content;
// word-wrap: break-word;
> .imgBox{
display: flex;
flex-wrap: wrap;
img{
width: 10rem;
height: 10rem;
cursor: pointer;
margin: .5rem;
}
}
> .colorBox{
display: flex;
flex-wrap: wrap;
>.item{
margin: .5rem;
border-radius: 1rem;
overflow: hidden;
border: 1px solid;
width: 10rem;
> .color{
width: 10rem;
height: 7rem;
}
> .text{
font-size: 1.4rem;
text-align: center;
}
}
}
}
> .icon{
margin-right: 1.2rem;
}
> i{
display: flex;
align-items: center;
justify-content: center;
animation: loading 1s linear infinite;
@keyframes loading {
from{
transform: rotate(0deg);
}
to{
transform: rotate(360deg);
}
}
}
}
}
}
}
> .content{
background: #f5f5f5;
// border-radius: 2.4rem;
> textarea{
padding: 1.6rem 2rem 0;
background: #f5f5f5;
width: 100%;
min-height: 7.2rem;
// border-radius: 2.4rem;
font-weight: 400;
line-height: 2rem;
font-size: 1.4rem;
resize: none;
border: none;
overflow-y: hidden;
}
> .btn{
padding: 0 1.2rem 1.2rem;
display: flex;
justify-content: space-between;
> .uploadBox{
display: flex;
align-items: center;
> .filList{
display: flex;
> .item{
height: 3rem;
padding: .5rem 1rem;
background: #efeff1;
border-radius: .5rem;
margin-right: 1rem;
font-size: 1.4rem;
line-height: 2rem;
display: flex;
> div{
white-space: nowrap;
overflow: hidden;
max-width: 10rem;
text-overflow: ellipsis;
}
> span{
cursor: pointer;
}
}
}
}
i{
font-size: 2rem;
display: flex;
cursor: pointer;
position: relative;
> input{
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
opacity: 0;
cursor: pointer;
&::-webkit-file-upload-button {
cursor: pointer;
}
}
}
> .sendBox{
display: flex;
align-items: center;
> .enableThinking{
width: 10rem;
padding: .2rem .4rem;
text-align: center;
font-size: 1.4rem;
border: 1px solid #000;
border-radius: .4rem;
cursor: pointer;
margin-right: 1rem;
&.active{
background: #000;
color: #fff;
}
}
> .maxNum{
font-size: 1.2rem;
margin-right: .8rem;
font-weight: 400;
}
> .send{
opacity: .5;
cursor: no-drop;
&.active{
opacity: 1;
cursor: pointer;
}
}
}
}
}
}
> .right,> .left{
display: flex;
align-items: center;
cursor: pointer;
width: 3rem;
justify-content: center;
> i{
display: flex;
font-size: 2rem;
transition: all .3s;
}
}
> .right{
border-left: 1px solid #e5e5e5;
> i{
transform: rotate(270deg);
}
}
> .left{
border-right: 1px solid #e5e5e5;
> i{
transform: rotate(90deg);
}
}
}
</style>

View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,394 @@
<template>
<div class="homeBox">
<div class="mark_loading" v-show="isShowMark">
<a-spin size="large" />
</div>
<div class="show">
<router-view v-if="(openType && openType != 'history' && !routeQuery.id) || $route.path != '/home'" @setTask="setTask">
</router-view>
<div v-else-if="routeQuery.id || openType == 'history'" class="function">
<design ref="design"></design>
</div>
<div v-else class="function">
<newPorject ref="newPorject"></newPorject>
</div>
</div>
</div>
<chat ref="chat" @chatChange="chatChange" v-if="openType"></chat>
</template>
<script lang="ts">
import { defineComponent,computed,ref,watch,nextTick,provide,toRefs, reactive} from 'vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
import { useRouter,useRoute } from 'vue-router'
import design from "./design/index.vue"
import newPorject from "./newProject/index.vue"
import chat from "./chat/index.vue"
export default defineComponent({
components:{
design,newPorject,chat
},
props:{
},
emits:['setTask'],
setup(props,{emit}) {
const store = useStore();
const route = useRoute()
const data = reactive({
openType:'',
isShowMark:false,
routeQuery:{} as any,
selectObject:computed(()=>store.state.Workspace.probjects) as any,//选择的项目
})
const setIsShowMark = (boolean:boolean)=>{
data.isShowMark = boolean
}
provide('setIsShowMark',setIsShowMark)
const dataDom = reactive({
design:null as any,
newPorject:null as any,
})
watch(() => route.query,
(query, oldQuery) => {
console.log(route)
data.routeQuery = query
const key = Object.keys(query)?.[0]
if(key){
data.openType = Object.keys(query)[0]
}else{
data.openType = ''
}
nextTick(()=>{
if(query.id || query.history){
data.isShowMark = true
if(query.type == 'Works'){
getWorks(query.id || query.history)
}else{
getHistory(query.id || query.history)
}
}
})
},
{ immediate: true } // 立即触发一次以处理初始参数
);
const createData = ()=>{
store.commit("clearAllData");
store.commit("clearAllCollection");
store.commit("setAllBoardDataChoose",{});
store.commit("clearShowSketchboard",{});
store.commit("clearAllCollection");
}
const getWorks = (id:any)=>{
let value:any = {
"accountId": 0,
"collectionId": 0,
"coverId": 0,
"createDate": "",
id,
"isDeleted": 0,
"portfolioDes": "",
"portfolioName": "",
"portfolioType": "",
"status": 0,
"updateDate": "",
"userLikeGroupId":''
}
Https.axiosPost(Https.httpUrls.setPorfolioChoose, value).then(
(rv: any) => {
setProjectData(rv)
}
).catch((res)=>{
data.isShowMark = false
});
}
const getHistory = (id:any)=>{
let value = {
id,
}
if(!id)return
createData()
Https.axiosPost(Https.httpUrls.selectHistoryProject,value).then((rv: any) => {
setProjectData(rv)
}).catch((res)=>{
data.isShowMark = false
})
}
const setTask = (item:any)=>{
emit('setTask',item)
}
const setProjectData = (rv:any)=>{
let storeData = {
name:rv.name,
id:rv.id,
type:rv.type,
httpType:rv.process,//项目类型
ageGroup:rv.workspaceVO.ageGroup,
style:rv.workspaceVO.style,
styleId:rv.workspaceVO.styleId,
styleName:rv.workspaceVO.styleName,
sex:rv.workspaceVO.sex,
systemDesignerPercentage:rv.workspaceVO.systemDesignerPercentage,
position:{
label:rv.workspaceVO.positionEnum.value,
value:rv.workspaceVO.positionEnum.name
},
positionList:[],
publishData:{
id:rv.portfolioDTO.id?rv.portfolioDTO.id:'',
portfolioDes:rv.portfolioDTO.portfolioDes?rv.portfolioDTO.portfolioDes:'',
portfolioName:rv.portfolioDTO.portfolioName?rv.portfolioDTO.portfolioName:'',
tagsDTO:rv.portfolioDTO.tagsDTO?rv.portfolioDTO.tagsDTO:[],
},
model:{}
}
let model:any = {}
let position = []
if(storeData.sex == "Female"){
model = {
id:rv.workspaceVO.mannequinFemaleId,
type:rv.workspaceVO.mannequinFemaleType,
url:rv.workspaceVO.femalePresignedUrl,
}
position = store.state.UserHabit.FemalePosition
}else{
model = {
id:rv.workspaceVO.mannequinMaleId,
type:rv.workspaceVO.mannequinMaleType,
url:rv.workspaceVO.malePresignedUrl,
}
position = store.state.UserHabit.MalePosition
}
storeData.model = model
data.selectObject.positionList = position
storeData.positionList = position
store.commit('setProbject',storeData)
// let list:any = projectList
// store.commit('setProjectList',list[type.value])
// nextTick(()=>{
// dataDom.workflow.isUpdataPorject = true
// })
getCollection()
}
// const setitemData = (arr:any)=>{
// return new Promise((resolve,reject)=>{
// nextTick(()=>{
// arr.forEach((rv:any)=>{
// if(arr.indexOf(rv) > -1 || !dataDom[rv])return
// dataDom[rv].openSetData()
// })
// resolve('')
// })
// })
// }
const getCollection = ()=>{
let value:any = {
"id":data.selectObject.id,
"moduleList":["moodBoard", "printBoard", "colorBoard", "sketchBoard",'design','toProduct','relight','poseTransfer','mannequin']
}
Https.axiosPost(Https.httpUrls.getModuleContent,value).then(async (rv)=>{
historyChooseData(rv)//设置历史数据
let allBoardData = ['sketchBoard','moodBoard','printBoard','colorBoard']
// let allBoardData = ['sketchBoard','moodBoard','printBoard','colorBoard','toProduct','relight','poseTransfer','mannequin']
let canvasData = ['canvas']
for (let index = 0; index < canvasData.length; index++) {
const item = canvasData[index];
await getCanvasData(item)
}
// await setitemData(allBoardData)
//还有一个canvas
if(rv.boundingBox)store.commit('setShowSketchboard',rv.boundingBox)
allBoardData.forEach((item)=>{
let value = {
type:item,
objectName:data.selectObject.type,
}
let arr = ['sketchBoard','moodBoard','printBoard','colorBoard']
if(arr.indexOf(item) != -1){
// store.dispatch('setAllBoardData',value)
}else{
store.dispatch('setModularData',value)
}
})
data.isShowMark = false
dataDom.design.openSetData()
})
}
const getCanvasData = (str:any)=>{
return new Promise((resolve, reject) => {
let value = {
module:str,
projectId:data.selectObject.id,
}
Https.axiosPost(Https.httpUrls.exportSearch, value)
.then((rv) => {
store.commit("setCanvasData", {type:str,file:rv});
resolve('')
})
.catch((rv) => {
resolve(null)
});
})
}
const historyChooseData = (dataValue:any)=>{
let collectionData = {
disposeMoodboard: dataValue.moodBoard?.moodTemplateId?[{
id:dataValue.moodBoard.moodTemplateId,
imgUrl:dataValue.moodBoard.moodTemplateUrl,
resData:{
name:dataValue.moodBoard.moodTemplateName,
}
}]:[],
moodboardPosition:dataValue.moodBoard?.moodboardPosition?JSON.parse(dataValue.moodBoard.moodboardPosition):{},
moodboardFiles: dealViewChooseData(
dataValue.moodBoard?.moodBoards,"Moodboard"
),
printboardFiles: dealViewChooseData(
dataValue.printBoard,"Printboard"
),
generatePrintFiles: [],
colorBoards: dealViewChooseColor(
dataValue.colorBoard
),
sketchboardFiles: dealViewChooseData(
dataValue.sketchBoard,"Sketchboard"
),
};
if(dataValue.moodBoard?.moodTemplateId)store.commit("setMoodTemplateId", dataValue.moodBoard.moodTemplateId);
store.commit("setAllBoardDataChoose", collectionData);
store.commit("setShowSketchboard", dataValue.sketchBoards);
let likeDesignCollectionList:any = []
if(dataValue.design?.userLikeDetails){
dataValue.design?.userLikeDetails.map(
(v: any) => {
let dataValue = {
...v,
groupDetailId: v.id,
designItemUrl: v.designOutfitUrl,
designItemId: v.designItemId,
};
return dataValue;
}
);
}
if(dataValue.design.userLikeDetails)store.commit("setLikeDesignCollectionList",dataValue.design.userLikeDetails);
store.commit("setUserGroupId", dataValue.design.userGroupId);
if(dataValue.toProduct){
let value = {
list: dataValue.toProduct,
str:'add',
index:-1,
}
store.commit("setToProductImage", value);
}
if(dataValue.relight){
let value = {
list: dataValue.relight,
str:'add',
index:-1,
}
store.commit("setRelightList", value);
}
if(dataValue.poseTransfer){
let value = {
list: dataValue.poseTransfer,
str:'add',
index:-1,
}
store.commit("setPoseTransfer", value);
}
}
//统一处理选择组的渲染数据
const dealViewChooseData = (dataValue: any,str:string)=> {
if (!dataValue) {
return [];
}
let filesList = dataValue.map((v: any) => {
let newData: any = {
imgUrl: v.url?v.url:v.designOutfitUrl,
id: v.id,
status: "done",
resData: v,
type_:{
type1:'material',
type2:v.level1Type
}
};
if (v.level1Type === "Sketchboard") {
newData.pin = v.isPin;
newData.categoryValue = v.level2Type;
newData.level2Type = v.level2Type;
}
if (v.level1Type === "Printboard") {
newData.pin = v.isPin;
newData.level2Type = v.level2Type;
newData.categoryValue = v.level2Type;
}
return newData;
});
return filesList;
}
//统一处理选择组的渲染数据
const dealViewChooseColor = (dataValue: any)=>{
let colorList = dataValue.map((v: any) => {
let rgbValue = v.rgbValue.split(" ");
let newData: any = {
id: v.id,
name: v.name,
tcx: v.tcx || "",
rgbValue: {
r: rgbValue[0],
g: rgbValue[1],
b: rgbValue[2],
a: 1,
},
};
if(v.gradient){
newData.gradient = v.gradient;
}else{
delete newData.gradient;
}
return newData;
});
return colorList;
}
const chatChange = (value:any)=>{
console.log(value)
if(value.type == '[DESIGN_SIGNAL]' && dataDom.design){
dataDom.design.designNewCollection()
}else{
getCollection()
}
}
return{
...toRefs(dataDom),
...toRefs(data),
setTask,
chatChange,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.homeBox{
width: 100%;
height: 100%;
position: relative;
> .show{
width: 100%;
height: 100%;
> .function{
width: 100%;
height: 100%;
}
}
}
</style>

View File

@@ -0,0 +1,415 @@
<template>
<div class="newProject">
<div class="contentBox">
<div class="content">
<div class="title">How can I help you today?</div>
<div class="selectFlow">
<div class="select">
<div class="item" @click="setFlow(item)" :class="{active:item.title == selectFlow.title}" v-for="item in flowList">{{ item.title }}</div>
</div>
<div class="describe">
<p v-for="item in selectFlow.describe">{{ item }}</p>
</div>
</div>
<div class="chatOrSetting">
<div class="select">
<div class="item" @click="setChatOrSetting('chat')" :class="{active:chatOrSetting == 'chat'}">Chat</div>
<div class="item" @click="setChatOrSetting('setting')" :class="{active:chatOrSetting == 'setting'}">Setting</div>
</div>
</div>
<div class="chatBox" v-show="chatOrSetting == 'chat'">
<textarea ref="textarea" @input="inputText($event)" placeholder="Write your message"></textarea>
<div class="btn">
<div class="uploadBox">
<div class="filList">
<div class="item" v-for="item,index in filList">
<div>{{item.name}}</div>
<span class="icon iconfont icon-shanchu" @click="deleteFile(item,index)"></span>
</div>
</div>
<i class="fi fi-br-upload">
<input type="file" @change="handleFileUpload($event)">
</i>
</div>
<div class="sendBox">
<div class="maxNum">{{ chatContent.length }}/10000</div>
<div class="send" @click="sendChat">
<i class="fi fi-ss-paper-plane-top"></i>
</div>
</div>
</div>
</div>
<div v-show="chatOrSetting != 'chat'">
<workspace @setProject="setProject" :httpWorkflowType="selectFlow.value"></workspace>
</div>
<div class="hint" v-show="chatOrSetting == 'chat'">
<div class="item" v-for="item in hintList" @click="addChatContent(item)">{{ item }}</div>
</div>
{{ text }}
</div>
</div>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,createVNode,toRefs, reactive} from 'vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { Modal,message,Upload,CascaderProps } from 'ant-design-vue';
import { useI18n } from 'vue-i18n'
import {getCookie,clonAllCookie} from '@/tool/cookie'
import router from '@/router';
import workspace from './workspace.vue'
export default defineComponent({
components:{
workspace,
},
props:{
},
emits:[],
setup(props,{emit}) {
const store = useStore();
const data = reactive({
flowList:[
{
title:'Series Design',
value:'SERIES_DESIGN',
describe:[
'12312312',
'12312312',
]
},
{
title:'Single Design',
value:'SINGLE_DESIGN',
describe:[
'12312312',
'12312312',
]
},
],
selectFlow:{
title:'Series Design',
value:'SERIES_DESIGN',
describe:[
'12312312',
'12312312',
]
},
chatContent:'',
hintList:[
'描述1',
'描述3',
'描述2',
],
uploadFile:null as any,
loadingShow:false,
text:'',
filList:[] as any,
textarea:null as any,
chatOrSetting:'chat',
})
const dataDom = reactive({
})
const setFlow = (item:any)=>{
data.selectFlow = item
}
const inputText = (e:any)=>{
if(e.target.value.length <= 1000){
data.chatContent = e.target.value
}else{
e.target.value = data.chatContent
}
e.target.style.height = `${e.target.scrollHeight}px`;
}
const addChatContent = (item:any)=>{
if((data.textarea.value += item.length) > 10000)return
data.chatContent += item
data.textarea.value += item
}
const sendChat = ()=>{
if(!data.chatContent)return
data.loadingShow = true
Https.axiosGet(Https.httpUrls.chatCreateProject, {params:{prompt:data.chatContent,process:data.selectFlow.value}}).then((rv)=>{
if(rv){
data.loadingShow = false
router.push(`home?history=${rv}`)
}
}).catch(()=>{
data.loadingShow = false
})
// const eventSource = new EventSource(`http://192.168.1.3:5567${Https.httpUrls.chatCreateProject}?prompt=${data.chatContent}&token=${getCookie('token')}`,{
// });
// eventSource.onmessage = function(event) {
// data.text+=event.data
// console.log('收到数据:', event.data);
// };
// eventSource.onerror = function(error) {
// console.log(EventSource.CLOSED,EventSource)
// console.log(eventSource.readyState )
// if (eventSource.readyState === EventSource.CLOSED) {
// console.log('连接已正常关闭');
// } else {
// console.error('错误:', error);
// // 处理错误重连逻辑
// }
// eventSource.close()
// };
}
const handleFileUpload = (event:any)=>{
if (event.target.files[0].size > 5 * 1024 * 1024) { // 5MB
message.info('The file size cannot exceed 5MB.');
return
}
let type = event.target.files[0].type.startsWith('image/')
if(type){
if(data.filList.filter((item:any)=>item.type == 'image').length >= 5){
message.info('You can only upload five pictures.');
return
}
}else{
if(data.filList.filter((item:any)=>item.type == 'file').length >= 1){
message.info('You can only upload one file.');
return
}
}
data.loadingShow = true
const formData = new FormData();
formData.append('file', event.target.files[0]);
let config:any = {
headers:{'Content-Type':'multipart/form-data','Accept':'*/*' },
params:formData,
}
Https.axiosPost(Https.httpUrls.llmUploadFile,formData,config)
.then((rv: any) => {
rv.name = event.target.files[0].name
rv.type = type?'image':'file'
data.filList.push(rv)
data.loadingShow = false
}
).catch(rv=>{
data.loadingShow = false
})
}
const deleteFile = (item:any,index:number)=>{
data.filList.splice(index,1)
}
const setChatOrSetting = (str:any)=>{
data.chatOrSetting = str
}
const setProject = (item:any)=>{
router.push(`home?history=${item.id}`)
}
return{
...toRefs(dataDom),
...toRefs(data),
setFlow,
inputText,
addChatContent,
sendChat,
handleFileUpload,
deleteFile,
setChatOrSetting,
setProject,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.newProject{
width: 100%;
height: 100%;
position: relative;
> .contentBox{
width: 100%;
height: calc(100% - 7.8rem);
display: flex;
align-items: center;
justify-content: center;
> .content{
// background: red;
width: 88rem;
// height: 100%;
> .title{
font-size: 2rem;
font-weight: 600;
text-align: center;
}
> .selectFlow{
margin-top: 4.8rem;
width: 100%;
border-radius: 2.4rem;
border: 1px solid #0000001a;
padding: 1.2rem;
> .select{
border: 1px solid #0000001a;
border-radius: 2.4rem;
display: flex;
padding: .2rem;
border-radius: 2rem;
> div{
white-space: nowrap;
justify-content: space-between;
border-radius: 2.2rem;
font-size: 1.6rem;
padding: .6rem .8rem;
min-width: 25%;
text-align: center;
font-weight: 600;
color: #71717a;
cursor: pointer;
&.active{
background: #efeff1;
color: #3f3f46;
}
}
}
> .describe{
margin-top: 1.6rem;
margin-left: .8rem;
> p{
margin: 0;
color: #71717a;
font-weight: 400;
}
}
}
> .chatOrSetting{
margin-top: 2.4rem;
width: min-content;
margin-left: auto;
> .select{
border: 1px solid #0000001a;
border-radius: 2.4rem;
display: flex;
padding: .2rem;
border-radius: 2rem;
> div{
white-space: nowrap;
justify-content: space-between;
border-radius: 2.2rem;
font-size: 1.6rem;
padding: .6rem .8rem;
min-width: 10rem;
text-align: center;
font-weight: 600;
color: #71717a;
cursor: pointer;
&.active{
background: #efeff1;
color: #3f3f46;
}
}
}
}
> .chatBox{
margin-top: .4rem;
border-radius: 2.4rem;
position: relative;
background: #f5f5f5;
> textarea{
padding: 1.6rem 2rem 0;
background: #f5f5f5;
width: 100%;
min-height: 7.2rem;
border-radius: 2.4rem;
font-weight: 400;
line-height: 2rem;
font-size: 1.4rem;
resize: none;
border: none;
overflow-y: hidden;
}
> .btn{
padding: 0 1.2rem 1.2rem;
display: flex;
justify-content: space-between;
> .uploadBox{
display: flex;
align-items: center;
> .filList{
display: flex;
> .item{
height: 3rem;
padding: .5rem 1rem;
background: #efeff1;
border-radius: .5rem;
margin-right: 1rem;
font-size: 1.4rem;
line-height: 2rem;
display: flex;
> div{
white-space: nowrap;
overflow: hidden;
max-width: 10rem;
text-overflow: ellipsis;
}
> span{
cursor: pointer;
}
}
}
}
i{
font-size: 2rem;
display: flex;
cursor: pointer;
position: relative;
> input{
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
opacity: 0;
cursor: pointer;
&::-webkit-file-upload-button {
cursor: pointer;
}
}
}
> .sendBox{
display: flex;
align-items: center;
> .maxNum{
font-size: 1.2rem;
margin-right: .8rem;
font-weight: 400;
}
}
}
}
> .hint{
display: flex;
margin-top: 2.4rem;
> div{
background: #efeff1;
width: 25rem;
height: 4.8rem;
margin-right: 1.2rem;
border-radius: 1.6rem;
cursor: pointer;
padding: 1.2rem;
&:hover{
background: #f5f5f5;
}
:first-child{
margin-right: 0;
}
}
}
}
}
}
</style>

View File

@@ -0,0 +1,376 @@
<template>
<div class="workspace">
<div class="workspaceBox">
<div class="projectName marginBottom" v-if="show.title">
<div class="text">Project name: <span style="color: red;">*</span></div>
<div class="input">
<input type="text" v-model="selectObject.name">
</div>
</div>
<div class="gender marginBottom" v-if="show.age">
<div class="text">Role</div>
<div class="radio">
<label>
<input type="radio" name="ageGroup" v-model="selectObject.ageGroup" value="Adult">
<span>Adult</span>
</label>
<label>
<input type="radio" name="ageGroup" v-model="selectObject.ageGroup" value="Child">
<span>Child</span>
</label>
</div>
</div>
<div class="gender marginBottom">
<div class="text">Gender</div>
<div class="radio">
<label>
<input type="radio" name="gender" v-model="selectObject.sex" value="Female">
<span>Female</span>
</label>
<label>
<input type="radio" name="gender" v-model="selectObject.sex" value="Male">
<span>Male</span>
</label>
</div>
</div>
<div class="style marginBottom" v-if="show.style">
<div class="text">Style</div>
<div class="text">{{ selectObject?.styleName?selectObject?.styleName:'All' }}</div>
<div class="gallery_btn" style="line-height: 5rem;" @click="setStyle">{{ $t('Habit.Select') }}</div>
</div>
<div class="systemDesigner marginBottom" v-if="show.systemDesigner">
<a-slider class="system_silder"
v-model:value="selectObject.systemDesignerPercentage"
:tip-formatter="formatter"
:tooltipVisible="false"
>
</a-slider>
<div class="text">
<div class="left">
{{ $t('Habit.System') }}<span>({{systemDesigner.designer}}%)</span>
</div>
<div class="right">
{{ $t('Habit.Designer') }}<span>({{systemDesigner.system}}%)</span>
</div>
</div>
</div>
<div class="position marginBottom" style="display: flex; align-items: center;justify-content: space-between;" v-show="show.position">
<div class="text">
Category:
</div>
<generalMenu style="width:80%" :selectWidth="'100%'" :dataList="selectObject.positionList" @setprintModel="setprintModel" :item="selectObject.position"></generalMenu>
</div>
<div class="complete">
<div class="gallery_btn" @click="complete">Complete</div>
</div>
</div>
<habitSetStyle ref="habitSetStyle" @setWorkspaceStyle="setWorkspaceStyle" :mannequinStyle="mannequinStyle"></habitSetStyle>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,watch,nextTick,onBeforeUnmount,toRefs, reactive, onMounted, inject} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
// import workspace from './model/workspace.vue'
import router from '@/router';
import habitSetStyle from "@/component/Detail/habitSetStyle.vue";
import generalMenu from "@/component/HomePage/generalMenu.vue";
import { Https } from '@/tool/https';
import { position } from 'html2canvas/dist/types/css/property-descriptors/position';
import { id } from 'element-plus/es/locale';
import { message } from 'ant-design-vue';
import {projectList} from '@/tool/listData'
export default defineComponent({
components:{
habitSetStyle,generalMenu
},
props:{
workflowType:{
type:String,
default:''
},
httpWorkflowType:{
type:String,
default:''
},
workflowTitle:{
type:String,
default:''
},
firstTime:{
type:Boolean,
default:false
}
},
emits:['setProject'],
setup(props,{emit}) {
const { t } = useI18n();
const store = useStore();
const data = reactive({
selectObject_:computed(()=>store.state.Workspace.probjects),//选择的项目
selectObject:{} as any,
femalePosition:computed(()=>store.state.UserHabit.FemalePosition),//男性衣服位置
malePosition:computed(()=>store.state.UserHabit.MalePosition),//女性衣服位置
mannequinStyle:computed(()=>store.state.UserHabit.mannequinStyle),//
show:{
title:true,
gender:true,
style:true,
age:true,
systemDesigner:true,
position:true,
},
systemDesigner:{
system:0,
designer:0,
},
setIsShowMark:inject('setIsShowMark') as any,
})
watch(()=>data.selectObject_,(newVal)=>{
data.selectObject = JSON.parse(JSON.stringify(newVal))
})
const dataDom = reactive({
habitSetStyle:null as any,
})
const setStyle = ()=>{
dataDom.habitSetStyle.init(data.selectObject);
}
const setWorkspaceStyle = (value:any)=>{
data.selectObject.styleName = value.name
data.selectObject.style = value.value
data.selectObject.styleId = value.id
// store.commit('setProbject',data)
}
const setprintModel = (value:any)=>{
data.selectObject.position = value
}
const formatter = (value: number)=>{
data.systemDesigner.system = 100 - value
data.systemDesigner.designer = value
let num = Math.abs((value-50)*2)
return `${num}%`;
}
const complete = ()=>{
if(!data.selectObject.name){
message.info(t('PrintboardUpload.jsContent7'))
return
}
let value = {
name:data.selectObject.name,
process:props.httpWorkflowType,
styleId:data.show.style?data.selectObject.styleId:null,
id:data.selectObject.id,
workspace:{
sex:data.selectObject.sex,
// sex:data.show.gender?data.selectObject.sex:null,
systemDesignerPercentage:data.show.systemDesigner?data.selectObject.systemDesignerPercentage:null,
position:data.show.position?data.selectObject.position.value:'Overall',
ageGroup:data.show.style?data.selectObject.ageGroup:null,
// position:data.selectObject,
} as any,
}
Https.axiosPost(Https.httpUrls.saveOrUpdate,value).then((rv)=>{
if(rv){
data.selectObject.id = rv.id
let model:any = {}
let position = []
if(data.selectObject.sex == "Female"){
// if(rv.workspaceVO.sex == "Female"){
model = {
id:rv.workspaceVO.mannequinFemaleId,
type:rv.workspaceVO.mannequinFemaleType,
url:rv.workspaceVO.femalePresignedUrl,
}
position = store.state.UserHabit.FemalePosition
}else{
model = {
id:rv.workspaceVO.mannequinMaleId,
type:rv.workspaceVO.mannequinMaleType,
url:rv.workspaceVO.malePresignedUrl,
}
position = store.state.UserHabit.MalePosition
}
// model.url = rv.workspaceVO.malePresignedUrl
data.selectObject.model = model
data.selectObject.positionList = position
// store.commit('setProbject',data.selectObject)
emit('setProject',data.selectObject)
}
})
}
const openSetData = ()=>{
}
onMounted(()=>{
data.selectObject = JSON.parse(JSON.stringify(data.selectObject_))
// data.show.gender = (props.workflowType == 'seriesDesign' || props.workflowType == 'singleProductDesign' || props.workflowType == 'printingDesign3D')
// data.show.style = (props.workflowType == 'seriesDesign' || props.workflowType == 'singleProductDesign')
// data.show.age = (props.workflowType == 'seriesDesign' || props.workflowType == 'singleProductDesign' || props.workflowType == 'sketchDesign')
// data.show.systemDesigner = (props.workflowType == 'seriesDesign' || props.workflowType == 'singleProductDesign')
// data.show.position = (props.workflowType == 'singleProductDesign')
if(!data.mannequinStyle){
data.setIsShowMark(true)
Https.axiosPost(Https.httpUrls.getStyleList, {}).then(
(rv) => {
data.setIsShowMark(false)
rv.forEach((item:any) => {
let name = item.value
item.value = item.name
item.name = name
});
data.selectObject.style = rv[0].value
data.selectObject.styleName = rv[0].name
data.selectObject.styleId = rv[0].id
store.commit('setMannequinStyle',rv)
}
).catch(res=>{
data.setIsShowMark(false)
});
}
})
watch(()=>data.selectObject.sex,(newVal)=>{
if(newVal == 'Male'){
data.selectObject.positionList = data.malePosition
}else{
data.selectObject.positionList = data.femalePosition
}
data.selectObject.position = data.selectObject.positionList[0]
})
return{
projectList,
...toRefs(dataDom),
...toRefs(data),
setStyle,
setWorkspaceStyle,
setprintModel,
formatter,
complete,
openSetData,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.workspace{
width: 100%;
height: 100%;
position: relative;
display: flex;
justify-content: center;
align-items: center;
font-weight: 600;
font-size: 1.8rem;
border: 1px solid #0000001a;
padding: 1.2rem;
border-radius: 2.4rem;
> .workspaceBox{
width: 55rem;
padding: 0 5rem;
width: 100%;
padding: 0;
// display: flex;
// flex-wrap: wrap;
// justify-content: space-between;
// align-content: flex-start;
> .marginBottom{
margin-bottom: 3rem;
// width: 44%;
}
> .title{
font-size: 2.7rem;
> span{
color: #999999;
font-size: 1.4rem;
}
}
> .projectName{
display: flex;
justify-content: space-between;
align-items: center;
> .text{
margin-right: 1rem;
}
> .input{
// flex: 1;
width: 80%;
padding: 1rem 2rem;
// padding: 2rem 2.7rem;
font-size: 1.6rem;
border-radius: 1.6rem;
border: 2px solid #D0D0D0;
display: flex;
> input{
flex: 1;
border: none;
}
> i{
display: flex;
color: #999999;
align-items: center;
font-size: 2.4rem;
}
}
}
> .gender{
display: flex;
align-items: center;
> .text{
width: 8rem;
}
> .radio{
display: flex;
margin-left: 4.5rem;
> label{
display: flex;
margin-right: 4rem;
>input{
margin-right: 1.5rem;
}
}
}
}
> .style{
display: flex;
align-items: center;
justify-content: space-between;
}
> .systemDesigner{
> .text{
margin-right: 1rem;
display: flex;
justify-content: space-between;
}
}
> .position{
> .text{
margin-right: 1rem;
}
:deep(.generalMenu_printModel){
position: relative;
margin: 0;
> div,> ul{
width: 100%;
border-radius: 1.6rem;
border: 2px solid #D0D0D0;
}
}
}
> .complete{
width: 100%;
text-align: right;
> div{
}
}
}
}
</style>

View File

@@ -58,15 +58,43 @@
</div> -->
</div>
<div class="password_input_block">
<div v-show="passwordConditionShow" class="conditionShow">
<div class="item">
<div class="icon">
<i v-show="!passwordCondition.length" class="fi fi-br-cross-small"></i>
<i v-show="passwordCondition.length" class="fi fi-br-check"></i>
</div>
<div class="text">At least 8 characters long</div>
</div>
<div class="item">
<div class="icon">
<i v-show="!passwordCondition.special" class="fi fi-br-cross-small"></i>
<i v-show="passwordCondition.special" class="fi fi-br-check"></i>
</div>
<div class="text">Must contain special characters</div>
</div>
<div class="item">
<div class="icon">
<i v-show="!passwordCondition.group" class="fi fi-br-cross-small"></i>
<i v-show="passwordCondition.group" class="fi fi-br-check"></i>
</div>
<div class="text">Mix of uppercase, lowercase and numbers</div>
</div>
</div>
<input
class="login_form_input"
:class="{active:Object.values(passwordCondition).filter(value => value === true).length<3}"
:type="passwordType"
placeholder="Enter your password"
v-model="password"
@keydown.enter="submitPerLogin()"
@input="passwordInput"
@focus="()=>passwordConditionShow = true"
@blur="()=>passwordConditionShow = false"
/>
<div class="icon iconfont icon-yanjing_yincang_o password_show_icon" @click="changePasswordType()"></div>
</div>
<span style="font-weight: 400;opacity: .7;">You must satisfy ALL password conditions to register.</span>
<div class="login_form_title marign_top30">Email</div>
<input
class="login_form_input"
@@ -271,7 +299,13 @@ export default defineComponent({
let register = reactive({
registerModel:false,
registerModelMask:true,
pageWidth:'50%'
pageWidth:'50%',
passwordConditionShow:false,
passwordCondition:{
length:false,
special:false,
group:false,
},
})
return{
store,
@@ -406,7 +440,15 @@ export default defineComponent({
checkRobot() {
this.isCheckRobot = !this.isCheckRobot;
},
passwordInput(){
this.isPassword(this.password)
},
isPassword(password:any){
this.passwordCondition.length = /.{8,}/.test(password)
this.passwordCondition.special = /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password)
this.passwordCondition.group = /[a-z]/.test(password) && /[A-Z]/.test(password) && /\d/.test(password)
return Object.values(this.passwordCondition).filter(value => value === true).length;
},
//提交账号密码预先登录
submitPerLogin() {
@@ -415,6 +457,9 @@ export default defineComponent({
if(this.emailStap>=2){
return;
}else{
if (/aida/i.test(this.username)) {
message.info('The name cannot contain "AiDA" or any combination of its uppercase and lowercase forms.');
}
if (!this.username || !this.password) {
message.info("Please enter your account number or password");
return;
@@ -434,6 +479,11 @@ export default defineComponent({
message.info("Agree to all terms, privacy fees and policies");
return;
}
if(this.isPassword(this.password) < 3){
message.info("You must satisfy ALL password conditions to register.");
return
}
let data = {
userPassword: md5(this.password + "abc"),
userName: this.username,
@@ -670,7 +720,7 @@ export default defineComponent({
// width: 80%;
background: #FFFFFF;
// box-shadow: -0.3rem 2rem 5.9rem 0px rgba(200,200,200,0.3);
padding: 3rem 6rem 6.5rem;
padding: 2rem 6rem 2rem;
box-sizing: border-box;
display: flex;
justify-content: space-between;
@@ -766,6 +816,35 @@ export default defineComponent({
top:1.7rem;
cursor: pointer;
}
> .conditionShow{
bottom: 0;
position: absolute;
right: 0;
left: auto;
transform: translateY(-5rem);
background: #404040;
color: #FFF;
font-size: 1.4rem;
padding: 2rem;
border-radius: 2rem;
> .item{
display: flex;
align-items: center;
margin-bottom: .5rem;
&:last-child{
margin-bottom: 0;
}
> .icon{
margin-right: 1rem;
i{
display: flex;
// &.fi-br-cross-small{
// color: red;
// }
}
}
}
}
}
.login_form_input {
@@ -786,6 +865,9 @@ export default defineComponent({
&::placeholder {
color: #a5b0c2;
}
&.active{
border: 0.1rem solid red;
}
}
}

View File

@@ -296,8 +296,8 @@ export default defineComponent({
}
let url = imgUrl.split('?')[0]
var match = url.match(/:(\d+)\/(.*)/);
minioUrl = match[2]
var match = url.match(/^(?:https?:\/\/[^\/]+)\/(.*)/);
minioUrl = match[1]
// let id =
let proportion = img.height / img.width; //计算图形宽高比例
let scaleWH = imgWidth[key] / img.width; //计算放到画布上缩小倍率

View File

@@ -1,77 +0,0 @@
<template>
<nav class="homeMain_nav_content">
<!-- <router-link :class="['nav_item',$route.name === 'homePage' ? 'select_nav' : '', ]" :to="`/home/homePage`">
{{$t('Header.HOME')}}
</router-link>
<router-link :class="['nav_item',$route.name === 'library' ? 'select_nav' : '', ]" :to="`/home/library`">
{{$t('Header.LIBRARY')}}
</router-link>
<router-link :class="['nav_item',$route.name === 'history' ? 'select_nav' : '', ]" :to="`/home/history`">
{{$t('Header.HISTORY')}}
</router-link>
<router-link :class="['nav_item',$route.name === 'works' ? 'select_nav' : '', ]" :to="`/home/works`">
{{$t('Header.WORKS')}}
</router-link> -->
<router-link v-for="item in routerList" :class="['nav_item',item.routerName.indexOf($route.name) > -1 ? 'select_nav' : '', ]" :to="item.router">{{ item.name }}</router-link>
</nav>
</template>
<script >
import { defineProps } from 'vue';
import { defineComponent, createVNode, ref, computed } from "vue";
export default defineComponent({
components: {
},
props:['routerList'],
setup(props,{emit}){
return {
}
},
})
</script>
<style lang="less" scoped>
.homeMain_nav_content {
display: flex;
// margin-left: 28.9rem;
// margin-left: 46.2rem;
align-items: center;
height: 7rem;
justify-content: center;
.nav_item {
padding: 1.1rem 1rem;
border-bottom: 0.1rem solid transparent;
margin-right: 3.4rem;
font-size: 1.6rem;
line-height: 1.3rem;
// color: #333333;
color: #000;
cursor: pointer;
font-weight: 900;
position: relative;
&.nav_item:last-child{
margin: 0;
}
&.nav_item::before {
position: absolute;
content: "";
display: block;
background: #000;
height: .3rem;
left: 50%;
transform: translateX(-50%);
bottom: .3rem;
width: 0px;
transition: 0.3s all;
}
&.select_nav {
color: #000;
transform: scale(1.15);
}
&.select_nav::before {
width: 80%;
}
}
}
</style>

View File

@@ -0,0 +1,109 @@
<template>
<div class="tools">
<div class="modelBox">
<toProduct ref="toProduct"
:productimgMenu="{value:'ToProductImage',label:$t('ProductImg.ProductImage')}"
class="toProduct"
:isState="openType =='toProduct'"
v-if="openType == 'toProduct'"
></toProduct>
<toProduct ref="relight"
:productimgMenu="{value:'Relight',label:$t('ProductImg.Relight')}"
class="relight"
:isState="openType =='relight'"
v-if="openType == 'relight'"
></toProduct>
<poseTransfer v-if="openType == 'poseTransfer'" ref="poseTransfer"></poseTransfer>
<deReconstruction v-if="openType == 'deReconstruction'" ref="deReconstruction"></deReconstruction>
<patternMaking3D v-if="openType == 'patternMaking3D'" ref="patternMaking3D"></patternMaking3D>
<canvasUpload v-if="openType == 'canvasUpload'" ref="canvasUpload"></canvasUpload>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,watch,toRefs, reactive} from 'vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
import { useRoute } from 'vue-router';
import MoodboardUpload from '@/component/HomePage/index/model/collection/MoodboardUpload.vue';
import PrintboardUpload from '@/component/HomePage/index/model/collection/PrintboardUpload.vue';
import ColorboardUpload from '@/component/HomePage/index/model/collection/ColorboardUpload.vue';
import toProduct from '@/component/HomePage/index/model/toProduct/index.vue';
import poseTransfer from '@/component/HomePage/index/model/poseTransfer/index.vue';
import deReconstruction from '@/component/HomePage/index/model/deReconstruction/index.vue';
import patternMaking3D from '@/component/HomePage/index/model/patternMaking3D/index.vue';
import canvasUpload from "@/component/Canvas/index.vue";
export default defineComponent({
components:{
toProduct,poseTransfer,deReconstruction,patternMaking3D,canvasUpload
},
props:{
},
emits:[],
setup(props,{emit}) {
const store = useStore();
const route = useRoute();
const data = reactive({
openType:'' as any,
isShowMark:false,
})
const dataDom:any = reactive({
toProduct:null as any,
relight:null as any,
poseTransfer:null as any,
deReconstruction:null as any,
patternMaking3D:null as any,
canvasUpload:null as any,
})
let driver__:any = computed(()=>{
return store.state.Guide.guide
})
provide('driver__',driver__)
const setIsShowMark = (boolean:boolean)=>{
data.isShowMark = boolean
}
const open = (str:any)=>{
nextTick(()=>{
if(dataDom[str]?.openSetData){
dataDom[str].openSetData()
}
})
}
provide('setIsShowMark',setIsShowMark)
watch(() => route.query,
(query, oldQuery) => {
if(oldQuery && query?.tools == oldQuery?.tools)return
let str = query.tools
nextTick(()=>{
console.log(str)
data.openType = str
open(str)
})
},
{ immediate: true } // 立即触发一次以处理初始参数
);
return{
...toRefs(dataDom),
...toRefs(data),
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.tools{
width: 100%;
height: 100%;
position: relative;
.modelBox{
width: 100%;
height: 100%;
}
}
</style>