Compare commits
80 Commits
7aba4e30c9
...
StableVers
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ed5a37e5b | ||
|
|
5546c71ec0 | ||
|
|
8a7776a4b6 | ||
|
|
a1281c8e3f | ||
|
|
9a40e69081 | ||
|
|
e27b43dc67 | ||
|
|
b6a55a8124 | ||
| 6cace08a51 | |||
| 6207095221 | |||
|
|
7bb38bf2e5 | ||
|
|
743fc762d6 | ||
| 7297e4e7a4 | |||
| 3bff1ebb66 | |||
| 0d1656ee0a | |||
| 7d0873d874 | |||
| 82941bca7c | |||
| 949ff9292d | |||
|
|
11c9de8ced | ||
|
|
fd518ad9b3 | ||
|
|
a2b45e2041 | ||
|
|
da64b57c1c | ||
|
|
7c14b1d831 | ||
|
|
8966b52430 | ||
|
|
5fa049f73d | ||
|
|
575445f767 | ||
|
|
f43c56236b | ||
|
|
4352f7c2f4 | ||
|
|
c6b1bdbdf1 | ||
|
|
f16aa6ea14 | ||
|
|
a25abeb527 | ||
|
|
d359cd7763 | ||
| 23085d9a9b | |||
| bb021ae9ac | |||
| bfb4e128f5 | |||
| 2f9b33e4ca | |||
|
|
35c6dfe29c | ||
|
|
48c37e0810 | ||
| b869a82fae | |||
| e61a8e372d | |||
|
|
f5a74991c9 | ||
|
|
e58e8540c9 | ||
| e75ed7684e | |||
| 918d71072b | |||
|
|
242bc7a01d | ||
|
|
02ad8a340a | ||
|
|
0c250a21b4 | ||
|
|
f781060e7b | ||
|
|
832c9101ab | ||
|
|
c48e836f8e | ||
|
|
6f0780ac2e | ||
|
|
5acb91e584 | ||
|
|
f66ba9e6fa | ||
| 7a90cb8db9 | |||
| dafe87fad8 | |||
| c44747e2c2 | |||
|
|
341c765c73 | ||
|
|
ed6cc294a5 | ||
|
|
a77dc718f9 | ||
|
|
86953a91a1 | ||
| cabbb653bd | |||
| 99533c12b6 | |||
|
|
59da67e4b4 | ||
|
|
1428f191dd | ||
|
|
13024cdd99 | ||
|
|
fd85ea02c1 | ||
|
|
c196ab6678 | ||
|
|
c005b85c06 | ||
|
|
b50dbbc246 | ||
|
|
01d09f4c34 | ||
|
|
79c9a66296 | ||
|
|
761b1b3512 | ||
|
|
b2cb7378d6 | ||
| 4d9ea75146 | |||
| f7e6926ee9 | |||
|
|
96b3636aea | ||
|
|
3dfb607b91 | ||
|
|
181e6a87b8 | ||
|
|
012f0ef1b5 | ||
|
|
2d5d1b7a5e | ||
|
|
f6556ec9a9 |
@@ -21,18 +21,19 @@
|
|||||||
"id": 3,
|
"id": 3,
|
||||||
"title": "AiDA Global Design Awards 2026",
|
"title": "AiDA Global Design Awards 2026",
|
||||||
"imgUrl": "/image/events/award-poster.gif",
|
"imgUrl": "/image/events/award-poster.gif",
|
||||||
|
"tips": "For inquiries: awards2026@code-create.com.hk",
|
||||||
"textList": [
|
"textList": [
|
||||||
{
|
{
|
||||||
"paragraph": [
|
"paragraph": [
|
||||||
{
|
{
|
||||||
"text": "Scan the QR code for more information and to join the competition! The AiDA Global Design Award 2026 is an international design competition hosted by Code‑Create, a globally leading AI fashion solutions provider, celebrating the future of creativity powered by artificial intelligence. Open to designers from Hong Kong, China, Singapore, South Korea, and beyond, the competition brings together global talent, empowering AI as a creative partner—pushing fashion beyond traditional boundaries and unlocking new possibilities where technology amplifies human imagination."
|
"text": "Click the “View Details” button for more information and to join the competition! The AiDA Global Design Award 2026 is an international design competition hosted by Code‑Create, a globally leading AI fashion solutions provider, celebrating the future of creativity powered by artificial intelligence. Open to designers worldwide the competition brings together global talent, empowering AI as a creative partner—pushing fashion beyond traditional boundaries and unlocking new possibilities where technology amplifies human imagination."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"paragraph": [
|
"paragraph": [
|
||||||
{
|
{
|
||||||
"text": "Participants have the opportunity to compete for cash prizes totaling up to US$9,000, gain global media exposure showcased by top international platforms, and connect with designers and industry leaders worldwide. Finalists will also attend an exclusive award ceremony in Hong Kong, with travel support provided, allowing them to showcase their talent, network with professionals, and celebrate their achievements on an international stage."
|
"text": "Participants have the opportunity to compete for cash prizes totaling up to US$9,000, gain global media exposure showcased by top international platforms, and connect with designers and industry leaders worldwide. Finalists will also attend an exclusive award ceremony in Hong Kong, with travel allowance, allowing them to showcase their talent, network with professionals, and celebrate their achievements on an international stage."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,18 +21,19 @@
|
|||||||
"id": 3,
|
"id": 3,
|
||||||
"title": "AiDA全球设计奖 2026",
|
"title": "AiDA全球设计奖 2026",
|
||||||
"imgUrl": "/image/events/award-poster-zh.gif",
|
"imgUrl": "/image/events/award-poster-zh.gif",
|
||||||
|
"tips": "如有疑问,请联系:awards2026@code-create.com.hk",
|
||||||
"textList": [
|
"textList": [
|
||||||
{
|
{
|
||||||
"paragraph": [
|
"paragraph": [
|
||||||
{
|
{
|
||||||
"text": "秉承推动 AI 赋能创意设计的初衷,Code‑Create 举办了「AiDA 全球设计大奖 2026」,面向来自香港、中国、新加坡、韩国及全球的设计师,鼓励大家探索 AI 与时尚设计的无限可能,突破传统界限,释放科技与想象力的创新潜能。扫描二维码获取更多比赛信息,抓住成为 AI 时尚先锋的机会吧!"
|
"text": "秉承推动 AI 赋能创意设计的初衷,Code‑Create 举办了「AiDA 全球设计大奖 2026」,面向来全球的设计师,鼓励大家探索 AI 与时尚设计的无限可能,突破传统界限,释放科技与想象力的创新潜能。点击“查看详情”按钮获取更多比赛信息,抓住成为 AI 时尚先锋的机会吧!"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"paragraph": [
|
"paragraph": [
|
||||||
{
|
{
|
||||||
"text": "参赛者将有机会赢取总奖金 9,000 美元,作品还将获得国际媒体展示机会,并与全球设计师和行业领袖建立联系。入围决赛者将受邀参加在香港举办的 专属颁奖典礼,主办方提供差旅支持,让设计师在国际舞台展示才华、拓展人脉,并共同庆祝创意成果。"
|
"text": "参赛者将有机会赢取总奖金 9,000 美元,作品还将获得国际媒体展示机会,并与全球设计师和行业领袖建立联系。入围决赛者将受邀参加在香港举办的 专属颁奖典礼,主办方提供差旅津贴,让设计师在国际舞台展示才华、拓展人脉,并共同庆祝创意成果。"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,21 +2,36 @@
|
|||||||
<div class="account_systemMessage">
|
<div class="account_systemMessage">
|
||||||
<div class="account_generalMessage_title modal_title_text">
|
<div class="account_generalMessage_title modal_title_text">
|
||||||
<!-- <span>系统消息</span> -->
|
<!-- <span>系统消息</span> -->
|
||||||
<div class="account_generalMessage_title_setting" @click="allRead">{{$t('account.AllRead')}}</div>
|
<div class="account_generalMessage_title_setting" @click="allRead">
|
||||||
|
{{ $t("account.AllRead") }}
|
||||||
</div>
|
</div>
|
||||||
<div class="account_generalMessage_item modal_title_text" v-for="item in dataList" :key="item.id" @click="setRead(item)">
|
</div>
|
||||||
|
<div
|
||||||
|
class="account_generalMessage_item modal_title_text"
|
||||||
|
v-for="item in dataList"
|
||||||
|
:key="item.id"
|
||||||
|
@click="setRead(item)"
|
||||||
|
>
|
||||||
<a-badge :dot="item.isRead == 0"></a-badge>
|
<a-badge :dot="item.isRead == 0"></a-badge>
|
||||||
<div class="account_generalMessage_item_title">
|
<div class="account_generalMessage_item_title">
|
||||||
<div class="account_generalMessage_item_title_text" :title="item.content">{{ item.content.title }}</div>
|
<div class="account_generalMessage_item_title_text" :title="item.content">
|
||||||
|
{{ item.content.title }}
|
||||||
|
</div>
|
||||||
<div class="modal_title_text_intro">{{ item.createTime }}</div>
|
<div class="modal_title_text_intro">{{ item.createTime }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal_title_text_intro">
|
<div class="modal_title_text_intro">
|
||||||
{{ item.content.content }}
|
{{ item.content.content }}
|
||||||
<span v-if="item.content.link" class="account_generalMessage_item_link">{{ item.content.link }}</span>
|
<span v-if="item.content.link" class="account_generalMessage_item_link">{{
|
||||||
|
item.content.link
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="account_generalMessage_item modal_title_text" style="display:flex;justify-content: center;" v-if="dataList.length == 0 && isNoData">
|
<div
|
||||||
{{$t('account.dataNull')}}
|
class="account_generalMessage_item modal_title_text"
|
||||||
|
style="display: flex; justify-content: center"
|
||||||
|
v-if="dataList.length == 0 && isNoData"
|
||||||
|
>
|
||||||
|
{{ $t("account.dataNull") }}
|
||||||
</div>
|
</div>
|
||||||
<div class="page_loading_box" v-show="!isNoData">
|
<div class="page_loading_box" v-show="!isNoData">
|
||||||
<span class="page_loading" ref="loadingDom" v-show="!isShowMark"></span>
|
<span class="page_loading" ref="loadingDom" v-show="!isShowMark"></span>
|
||||||
@@ -27,34 +42,44 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent,computed,ref,reactive,nextTick,toRefs,createVNode, onMounted} from 'vue'
|
import {
|
||||||
import { Https } from "@/tool/https";
|
defineComponent,
|
||||||
import { useRouter,useRoute } from 'vue-router'
|
computed,
|
||||||
import { useStore } from "vuex";
|
ref,
|
||||||
import { useI18n } from 'vue-i18n'
|
reactive,
|
||||||
|
nextTick,
|
||||||
|
toRefs,
|
||||||
|
createVNode,
|
||||||
|
onMounted
|
||||||
|
} from "vue"
|
||||||
|
import { Https } from "@/tool/https"
|
||||||
|
import { useRouter, useRoute } from "vue-router"
|
||||||
|
import { useStore } from "vuex"
|
||||||
|
import { useI18n } from "vue-i18n"
|
||||||
|
import { isValidUrl } from "@/tool/util"
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components:{
|
components: {},
|
||||||
},
|
|
||||||
// emits:['putListData'],
|
// emits:['putListData'],
|
||||||
props:['setReadStatus','setAllmessage','getHistory'],
|
props: ["setReadStatus", "setAllmessage", "getHistory"],
|
||||||
setup(prop, { emit }) {
|
setup(prop, { emit }) {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const store = useStore();
|
const store = useStore()
|
||||||
let accountMessage = reactive({
|
let accountMessage = reactive({
|
||||||
dataList: [],
|
dataList: [],
|
||||||
page: 1,
|
page: 1,
|
||||||
size: 10,
|
size: 10,
|
||||||
isNoData: false,
|
isNoData: false,
|
||||||
isShowMark: false,
|
isShowMark: false
|
||||||
})
|
})
|
||||||
let loadingDom: any = ref(null)
|
let loadingDom: any = ref(null)
|
||||||
let setmessageList = () => {
|
let setmessageList = () => {
|
||||||
accountMessage.isShowMark = true
|
accountMessage.isShowMark = true
|
||||||
let data = {
|
let data = {
|
||||||
page: accountMessage.page,
|
page: accountMessage.page,
|
||||||
size: accountMessage.size,
|
size: accountMessage.size
|
||||||
}
|
}
|
||||||
prop.getHistory(data).then((rv:any)=>{
|
prop.getHistory(data)
|
||||||
|
.then((rv: any) => {
|
||||||
accountMessage.isShowMark = false
|
accountMessage.isShowMark = false
|
||||||
|
|
||||||
if (rv.content.length == 0) {
|
if (rv.content.length == 0) {
|
||||||
@@ -62,58 +87,67 @@ export default defineComponent({
|
|||||||
} else {
|
} else {
|
||||||
rv.content.forEach((item: any) => {
|
rv.content.forEach((item: any) => {
|
||||||
item.content = JSON.parse(item.content)
|
item.content = JSON.parse(item.content)
|
||||||
});
|
})
|
||||||
accountMessage.dataList.push(...rv.content)
|
accountMessage.dataList.push(...rv.content)
|
||||||
}
|
}
|
||||||
}).catch(() => {
|
})
|
||||||
|
.catch(() => {
|
||||||
accountMessage.isShowMark = false
|
accountMessage.isShowMark = false
|
||||||
accountMessage.isNoData = true
|
accountMessage.isNoData = true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
let setRead = (item: any) => {
|
let setRead = (item: any) => {
|
||||||
prop.setReadStatus(item).then((rv:any)=>{
|
let content = item.content.content
|
||||||
|
if (isValidUrl(content)) {
|
||||||
|
if (import.meta.env.VITE_APP_BASE_URL === "https://develop.api.aida.com.hk") {
|
||||||
|
content += "&env=dev"
|
||||||
|
}
|
||||||
|
window.open(content, "_blank")
|
||||||
|
}
|
||||||
|
|
||||||
|
prop.setReadStatus(item)
|
||||||
|
.then((rv: any) => {
|
||||||
item.isRead = 1
|
item.isRead = 1
|
||||||
}).catch((err:any)=>{
|
|
||||||
})
|
})
|
||||||
|
.catch((err: any) => {})
|
||||||
}
|
}
|
||||||
let allRead = () => {
|
let allRead = () => {
|
||||||
// emit('setAllmessage')
|
// emit('setAllmessage')
|
||||||
prop.setAllmessage().then(()=>{
|
prop.setAllmessage()
|
||||||
|
.then(() => {
|
||||||
accountMessage.dataList.forEach((item: any) => {
|
accountMessage.dataList.forEach((item: any) => {
|
||||||
item.isRead = 1
|
item.isRead = 1
|
||||||
})
|
})
|
||||||
}).catch((err:any)=>{
|
|
||||||
})
|
})
|
||||||
|
.catch((err: any) => {})
|
||||||
}
|
}
|
||||||
// provide('exhibitionList',exhibitionList)
|
// provide('exhibitionList',exhibitionList)
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
accountMessage.isNoData = false
|
accountMessage.isNoData = false
|
||||||
accountMessage.page = 0
|
accountMessage.page = 0
|
||||||
let imgParent:any = document.querySelector('.account_systemMessage .page_loading')
|
let imgParent: any = document.querySelector(".account_systemMessage .page_loading")
|
||||||
new IntersectionObserver(
|
new IntersectionObserver(
|
||||||
(entries, observer) => {
|
(entries, observer) => {
|
||||||
// 如果不是相交,则直接返回
|
// 如果不是相交,则直接返回
|
||||||
// console.log(entries[0]);
|
// console.log(entries[0]);
|
||||||
if (!entries[0].intersectionRatio) return;
|
if (!entries[0].intersectionRatio) return
|
||||||
accountMessage.page += 1
|
accountMessage.page += 1
|
||||||
setmessageList()
|
setmessageList()
|
||||||
},
|
}
|
||||||
// { root:worksPage }
|
// { root:worksPage }
|
||||||
).observe(loadingDom.value);
|
).observe(loadingDom.value)
|
||||||
})
|
})
|
||||||
return {
|
return {
|
||||||
...toRefs(accountMessage),
|
...toRefs(accountMessage),
|
||||||
setmessageList,
|
setmessageList,
|
||||||
setRead,
|
setRead,
|
||||||
allRead,
|
allRead,
|
||||||
loadingDom,
|
loadingDom
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return{
|
return {}
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@@ -133,7 +167,6 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
.modal_title_text_intro {
|
.modal_title_text_intro {
|
||||||
margin-left: 4rem;
|
margin-left: 4rem;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,6 +148,7 @@
|
|||||||
total: total,
|
total: total,
|
||||||
showQuickJumper: true,
|
showQuickJumper: true,
|
||||||
bordered: false,
|
bordered: false,
|
||||||
|
showTotal: (total) => `Total Transaction: ${total}`
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<template #bodyCell="{ column, text, record, index }">
|
<template #bodyCell="{ column, text, record, index }">
|
||||||
@@ -465,13 +466,16 @@ export default defineComponent({
|
|||||||
(rv: any) => {
|
(rv: any) => {
|
||||||
if (rv) {
|
if (rv) {
|
||||||
// this.dataList = rv
|
// this.dataList = rv
|
||||||
|
// console.log('rv----',rv);
|
||||||
|
|
||||||
filter.dataList = rv.content;
|
filter.dataList = rv.content;
|
||||||
filterData.total = rv.total;
|
filterData.total = rv.total;
|
||||||
filter.tableLoading = false;
|
filter.tableLoading = false;
|
||||||
filterData.totalPayer = rv.content.reduce((total: number, item: any) => {
|
filterData.totalPayer = rv.totalAmount;
|
||||||
const value = item && item.status === 'Success' ? parseFloat(item.payerTotal) : 0;
|
// filterData.totalPayer = rv.content.reduce((total: number, item: any) => {
|
||||||
return total + (isNaN(value) ? 0 : value);
|
// const value = item && item.status === 'Success' ? parseFloat(item.payerTotal) : 0;
|
||||||
}, 0);
|
// return total + (isNaN(value) ? 0 : value);
|
||||||
|
// }, 0);
|
||||||
|
|
||||||
// this.workspaceItem.position = this.singleTypeList[0].label
|
// this.workspaceItem.position = this.singleTypeList[0].label
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,16 +8,11 @@
|
|||||||
style="width: 250px"
|
style="width: 250px"
|
||||||
class="range_picker"
|
class="range_picker"
|
||||||
v-model:value="rangePickerValue"
|
v-model:value="rangePickerValue"
|
||||||
:placeholder="[
|
:placeholder="[$t('HistoryPage.StartDate'), $t('HistoryPage.EndDate')]"
|
||||||
$t('HistoryPage.StartDate'),
|
|
||||||
$t('HistoryPage.EndDate'),
|
|
||||||
]"
|
|
||||||
valueFormat="YYYY-MM-DD"
|
valueFormat="YYYY-MM-DD"
|
||||||
>
|
>
|
||||||
<template #suffixIcon>
|
<template #suffixIcon>
|
||||||
<span
|
<span class="icon iconfont range_picker_icon icon-rili"></span>
|
||||||
class="icon iconfont range_picker_icon icon-rili"
|
|
||||||
></span>
|
|
||||||
</template>
|
</template>
|
||||||
</a-range-picker>
|
</a-range-picker>
|
||||||
</div>
|
</div>
|
||||||
@@ -63,38 +58,50 @@
|
|||||||
show-search
|
show-search
|
||||||
></a-select>
|
></a-select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="admin_state_item">
|
||||||
|
<span>Orgnization:</span>
|
||||||
|
<a-select
|
||||||
|
v-model:value="organizationId"
|
||||||
|
placeholder="Select the organization"
|
||||||
|
allow-clear
|
||||||
|
style="width: 250px"
|
||||||
|
@popupScroll="handleOrganizationScroll"
|
||||||
|
>
|
||||||
|
<a-select-option
|
||||||
|
v-for="item in organizationOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:value="item.id"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="admin_search">
|
<div class="admin_search">
|
||||||
<div class="admin_search_item" @click="searchHistoryList" :style="{height:isAwayOrUnfold?'4rem':''}">
|
<div
|
||||||
|
class="admin_search_item"
|
||||||
|
@click="searchHistoryList"
|
||||||
|
:style="{ height: isAwayOrUnfold ? '4rem' : '' }"
|
||||||
|
>
|
||||||
Search
|
Search
|
||||||
</div>
|
</div>
|
||||||
<div class="admin_search_item" @click="addhHistoryList">
|
<div class="admin_search_item" @click="addhHistoryList">Add</div>
|
||||||
Add
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="admin_state_list">
|
<div class="admin_state_list">
|
||||||
<div
|
<div class="admin_state_list_item" @click="lastGeTrialList('year')">
|
||||||
class="admin_state_list_item"
|
|
||||||
@click="lastGeTrialList('year')"
|
|
||||||
>
|
|
||||||
Nearly a year
|
Nearly a year
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="admin_state_list_item" @click="lastGeTrialList('month')">
|
||||||
class="admin_state_list_item"
|
|
||||||
@click="lastGeTrialList('month')"
|
|
||||||
>
|
|
||||||
Last month
|
Last month
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="admin_state_list_item" @click="lastGeTrialList('week')">Last week</div>
|
||||||
class="admin_state_list_item"
|
|
||||||
@click="lastGeTrialList('week')"
|
|
||||||
>
|
|
||||||
Last week
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="awayOrUnfold" :class="{ active: isAwayOrUnfold }">
|
<div class="awayOrUnfold" :class="{ active: isAwayOrUnfold }">
|
||||||
<span class="icon iconfont menu_icon icon-xiala" @click="()=>isAwayOrUnfold = !isAwayOrUnfold"></span>
|
<span
|
||||||
|
class="icon iconfont menu_icon icon-xiala"
|
||||||
|
@click="() => (isAwayOrUnfold = !isAwayOrUnfold)"
|
||||||
|
></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="admin_table_content" ref="historyTable">
|
<div class="admin_table_content" ref="historyTable">
|
||||||
<a-table
|
<a-table
|
||||||
@@ -104,24 +111,19 @@
|
|||||||
:data-source="dataList"
|
:data-source="dataList"
|
||||||
:scroll="{ y: historyTableHeight }"
|
:scroll="{ y: historyTableHeight }"
|
||||||
@change="changePage"
|
@change="changePage"
|
||||||
:showSorterTooltip='false'
|
:showSorterTooltip="false"
|
||||||
:pagination="{
|
:pagination="{
|
||||||
showSizeChanger: true,
|
showSizeChanger: true,
|
||||||
current: currentPage,
|
current: currentPage,
|
||||||
pageSize: pageSize,
|
pageSize: pageSize,
|
||||||
total: total,
|
total: total,
|
||||||
showQuickJumper: true,
|
showQuickJumper: true,
|
||||||
bordered: false,
|
bordered: false
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<template #bodyCell="{ column, text, record, index }">
|
<template #bodyCell="{ column, text, record, index }">
|
||||||
<div class="operate_list" v-if="column?.Operations">
|
<div class="operate_list" v-if="column?.Operations">
|
||||||
<div
|
<div class="operate_item" @click="setAagree(record)">Edit</div>
|
||||||
class="operate_item"
|
|
||||||
@click="setAagree(record)"
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</div>
|
|
||||||
<!-- <div
|
<!-- <div
|
||||||
class="operate_item"
|
class="operate_item"
|
||||||
@click="deleteGroup(record, index)"
|
@click="deleteGroup(record, index)"
|
||||||
@@ -132,24 +134,19 @@
|
|||||||
</template>
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
</div>
|
</div>
|
||||||
<allUserPoerationsVue ref="allUserPoerationsVue" @searchHistoryList="searchHistoryList"></allUserPoerationsVue>
|
<allUserPoerationsVue
|
||||||
|
ref="allUserPoerationsVue"
|
||||||
|
@searchHistoryList="searchHistoryList"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {
|
import { defineComponent, ref, createVNode, computed, reactive, toRefs, onMounted } from "vue"
|
||||||
defineComponent,
|
import { formatTime } from "@/tool/util"
|
||||||
ref,
|
import { useStore } from "vuex"
|
||||||
createVNode,
|
import { Https } from "@/tool/https"
|
||||||
computed,
|
import allUserPoerationsVue from "./allUserPoerations.vue"
|
||||||
reactive,
|
import SelectUser from "@/component/common/SelectUser.vue"
|
||||||
toRefs,
|
|
||||||
onMounted,
|
|
||||||
} from "vue";
|
|
||||||
import { formatTime } from "@/tool/util";
|
|
||||||
import { useStore } from "vuex";
|
|
||||||
import { Https } from "@/tool/https";
|
|
||||||
import allUserPoerationsVue from "./allUserPoerations.vue";
|
|
||||||
import SelectUser from '@/component/common/SelectUser.vue'
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { allUserPoerationsVue, SelectUser },
|
components: { allUserPoerationsVue, SelectUser },
|
||||||
setup() {
|
setup() {
|
||||||
@@ -159,7 +156,7 @@ export default defineComponent({
|
|||||||
tableLoading: false,
|
tableLoading: false,
|
||||||
allCountry: [],
|
allCountry: [],
|
||||||
isAwayOrUnfold: false
|
isAwayOrUnfold: false
|
||||||
});
|
})
|
||||||
let filterData: any = reactive({
|
let filterData: any = reactive({
|
||||||
rangePickerValue: [],
|
rangePickerValue: [],
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
@@ -172,40 +169,41 @@ export default defineComponent({
|
|||||||
occupation: "",
|
occupation: "",
|
||||||
systemUser: "",
|
systemUser: "",
|
||||||
order: "", //'Ascending 升序 Descending 降序'
|
order: "", //'Ascending 升序 Descending 降序'
|
||||||
orderBy:'',
|
orderBy: "",
|
||||||
userName: "",
|
userName: "",
|
||||||
});
|
organizationId: null
|
||||||
|
})
|
||||||
let state: any = ref([
|
let state: any = ref([
|
||||||
{
|
{
|
||||||
label: "all",
|
label: "all",
|
||||||
value: "",
|
value: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label:'visitor',
|
label: "visitor",
|
||||||
value:'0',
|
value: "0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label:'yearly',
|
label: "yearly",
|
||||||
value:'1',
|
value: "1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label:'monthly',
|
label: "monthly",
|
||||||
value:'2',
|
value: "2"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label:'trial',
|
label: "trial",
|
||||||
value:'3',
|
value: "3"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "userInEvent",
|
label: "userInEvent",
|
||||||
value: "4",
|
value: "4"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Edu Admin",
|
label: "Edu Admin",
|
||||||
value: "7",
|
value: "7"
|
||||||
},
|
}
|
||||||
]);
|
])
|
||||||
let renameData: any = ref({}); //修改名字选中的数据
|
let renameData: any = ref({}) //修改名字选中的数据
|
||||||
const columns: any = computed(() => {
|
const columns: any = computed(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@@ -215,7 +213,7 @@ export default defineComponent({
|
|||||||
key: "id",
|
key: "id",
|
||||||
width: 100,
|
width: 100,
|
||||||
fixed: "left",
|
fixed: "left",
|
||||||
sorter: true,
|
sorter: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Email",
|
title: "Email",
|
||||||
@@ -246,7 +244,7 @@ export default defineComponent({
|
|||||||
dataIndex: "language",
|
dataIndex: "language",
|
||||||
key: "language",
|
key: "language",
|
||||||
width: 100,
|
width: 100,
|
||||||
ellipsis:true,
|
ellipsis: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Valid Start Time",
|
title: "Valid Start Time",
|
||||||
@@ -256,12 +254,12 @@ export default defineComponent({
|
|||||||
width: 200,
|
width: 200,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
customRender: (record: any) => {
|
customRender: (record: any) => {
|
||||||
let time = ''
|
let time = ""
|
||||||
if (record.text) {
|
if (record.text) {
|
||||||
time = formatTime(record.text / 1000, 'YYYY-MM-DD hh:mm:ss')
|
time = formatTime(record.text / 1000, "YYYY-MM-DD hh:mm:ss")
|
||||||
}
|
}
|
||||||
return time
|
return time
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Valid End Time",
|
title: "Valid End Time",
|
||||||
@@ -271,19 +269,19 @@ export default defineComponent({
|
|||||||
width: 200,
|
width: 200,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
customRender: (record: any) => {
|
customRender: (record: any) => {
|
||||||
let time = ''
|
let time = ""
|
||||||
if (record.text) {
|
if (record.text) {
|
||||||
time = formatTime(record.text / 1000, 'YYYY-MM-DD hh:mm:ss')
|
time = formatTime(record.text / 1000, "YYYY-MM-DD hh:mm:ss")
|
||||||
}
|
}
|
||||||
return time
|
return time
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Country or Region",
|
title: "Country or Region",
|
||||||
align: "center",
|
align: "center",
|
||||||
dataIndex: "country",
|
dataIndex: "country",
|
||||||
key: "country",
|
key: "country",
|
||||||
width:200,
|
width: 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Create Date",
|
title: "Create Date",
|
||||||
@@ -291,7 +289,7 @@ export default defineComponent({
|
|||||||
dataIndex: "createDate",
|
dataIndex: "createDate",
|
||||||
key: "createDate",
|
key: "createDate",
|
||||||
width: 200,
|
width: 200,
|
||||||
sorter: true,
|
sorter: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Is Beginner",
|
title: "Is Beginner",
|
||||||
@@ -301,21 +299,21 @@ export default defineComponent({
|
|||||||
width: 80,
|
width: 80,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
customRender: (record: any) => {
|
customRender: (record: any) => {
|
||||||
let str;
|
let str
|
||||||
if (record.value == 1) {
|
if (record.value == 1) {
|
||||||
str = "Yes";
|
str = "Yes"
|
||||||
} else {
|
} else {
|
||||||
str = "No";
|
str = "No"
|
||||||
|
}
|
||||||
|
return str
|
||||||
}
|
}
|
||||||
return str;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Machine Room Ip',
|
title: "Machine Room Ip",
|
||||||
align: "center",
|
align: "center",
|
||||||
dataIndex: "browserIdentifiers",
|
dataIndex: "browserIdentifiers",
|
||||||
key: "browserIdentifiers",
|
key: "browserIdentifiers",
|
||||||
width:200,
|
width: 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Credits",
|
title: "Credits",
|
||||||
@@ -327,10 +325,10 @@ export default defineComponent({
|
|||||||
dataIndex: "credits",
|
dataIndex: "credits",
|
||||||
key: "credits",
|
key: "credits",
|
||||||
width: 100,
|
width: 100,
|
||||||
sorter: true,
|
sorter: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'User Type',
|
title: "User Type",
|
||||||
align: "center",
|
align: "center",
|
||||||
// width: 150,
|
// width: 150,
|
||||||
// minWidth: 100,
|
// minWidth: 100,
|
||||||
@@ -340,22 +338,22 @@ export default defineComponent({
|
|||||||
key: "systemUser",
|
key: "systemUser",
|
||||||
width: 100,
|
width: 100,
|
||||||
customRender: (record: any) => {
|
customRender: (record: any) => {
|
||||||
let str;
|
let str
|
||||||
if (record.value == 0) {
|
if (record.value == 0) {
|
||||||
str = "visitor";
|
str = "visitor"
|
||||||
} else if (record.value == 1) {
|
} else if (record.value == 1) {
|
||||||
str = "yearly";
|
str = "yearly"
|
||||||
} else if (record.value == 2) {
|
} else if (record.value == 2) {
|
||||||
str = "monthly";
|
str = "monthly"
|
||||||
} else if (record.value == 3) {
|
} else if (record.value == 3) {
|
||||||
str = "trial";
|
str = "trial"
|
||||||
} else if (record.value == 4) {
|
} else if (record.value == 4) {
|
||||||
str = "userInEvent";
|
str = "userInEvent"
|
||||||
} else if (record.value == 7) {
|
} else if (record.value == 7) {
|
||||||
str = "Edu Admin";
|
str = "Edu Admin"
|
||||||
|
}
|
||||||
|
return str
|
||||||
}
|
}
|
||||||
return str;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Operations",
|
title: "Operations",
|
||||||
@@ -364,58 +362,58 @@ export default defineComponent({
|
|||||||
align: "center",
|
align: "center",
|
||||||
fixed: "right",
|
fixed: "right",
|
||||||
// slots:{customRender:'action'}
|
// slots:{customRender:'action'}
|
||||||
Operations: true,
|
Operations: true
|
||||||
},
|
}
|
||||||
];
|
]
|
||||||
});
|
})
|
||||||
//改变页码
|
//改变页码
|
||||||
let changePage = (e: any, filters: any, sorter: any) => {
|
let changePage = (e: any, filters: any, sorter: any) => {
|
||||||
filterData.currentPage = e.current;
|
filterData.currentPage = e.current
|
||||||
filterData.pageSize = e.pageSize;
|
filterData.pageSize = e.pageSize
|
||||||
if (sorter.order) {
|
if (sorter.order) {
|
||||||
if(sorter.columnKey == 'id'){
|
if (sorter.columnKey == "id") {
|
||||||
filterData.orderBy = 'id'
|
filterData.orderBy = "id"
|
||||||
} else if (sorter.columnKey == "createDate") {
|
} else if (sorter.columnKey == "createDate") {
|
||||||
filterData.orderBy = 'time'
|
filterData.orderBy = "time"
|
||||||
} else if (sorter.columnKey == "credits") {
|
} else if (sorter.columnKey == "credits") {
|
||||||
filterData.orderBy = 'credits'
|
filterData.orderBy = "credits"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sorter.order) {
|
if (sorter.order) {
|
||||||
filterData.order = sorter.order == "descend" ? "Descending" : "Ascending";
|
filterData.order = sorter.order == "descend" ? "Descending" : "Ascending"
|
||||||
} else {
|
} else {
|
||||||
filterData.order = ''
|
filterData.order = ""
|
||||||
|
}
|
||||||
|
gettrialList()
|
||||||
}
|
}
|
||||||
gettrialList();
|
|
||||||
};
|
|
||||||
|
|
||||||
//查询列表
|
//查询列表
|
||||||
let searchHistoryList = () => {
|
let searchHistoryList = () => {
|
||||||
filterData.currentPage = 1;
|
filterData.currentPage = 1
|
||||||
gettrialList();
|
gettrialList()
|
||||||
};
|
}
|
||||||
let clearHistoryList = () => {
|
let clearHistoryList = () => {
|
||||||
filterData.rangePickerValue = [],
|
;((filterData.rangePickerValue = []),
|
||||||
filterData.currentPage = 1,
|
(filterData.currentPage = 1),
|
||||||
filterData.pageSize = 10,
|
(filterData.pageSize = 10),
|
||||||
filterData.total = 0,
|
(filterData.total = 0),
|
||||||
filterData.country = "",
|
(filterData.country = ""),
|
||||||
filterData.email = "",
|
(filterData.email = ""),
|
||||||
filterData.userType = "",
|
(filterData.userType = ""),
|
||||||
filterData.ids = [],
|
(filterData.ids = []),
|
||||||
filterData.occupation = "",
|
(filterData.occupation = ""),
|
||||||
filterData.order = "", //'Ascending 升序 Descending 降序'
|
(filterData.order = ""), //'Ascending 升序 Descending 降序'
|
||||||
filterData.orderBy = "", //'Ascending 升序 Descending 降序'
|
(filterData.orderBy = ""), //'Ascending 升序 Descending 降序'
|
||||||
filterData.systemUser = "",
|
(filterData.systemUser = ""),
|
||||||
filterData.userName = "";
|
(filterData.userName = ""))
|
||||||
};
|
}
|
||||||
let setHistoryListData = () => {
|
let setHistoryListData = () => {
|
||||||
let startDate: any = filterData.rangePickerValue?.[0]
|
let startDate: any = filterData.rangePickerValue?.[0]
|
||||||
? filterData.rangePickerValue[0] + " " + "00:00:00"
|
? filterData.rangePickerValue[0] + " " + "00:00:00"
|
||||||
: "";
|
: ""
|
||||||
let endDate: any = filterData.rangePickerValue?.[1]
|
let endDate: any = filterData.rangePickerValue?.[1]
|
||||||
? filterData.rangePickerValue[1] + " " + "23:59:59"
|
? filterData.rangePickerValue[1] + " " + "23:59:59"
|
||||||
: "";
|
: ""
|
||||||
let data = {
|
let data = {
|
||||||
endTime: endDate,
|
endTime: endDate,
|
||||||
startTime: startDate,
|
startTime: startDate,
|
||||||
@@ -430,63 +428,118 @@ export default defineComponent({
|
|||||||
order: filterData.order,
|
order: filterData.order,
|
||||||
orderBy: filterData.orderBy,
|
orderBy: filterData.orderBy,
|
||||||
userName: filterData.userName,
|
userName: filterData.userName,
|
||||||
};
|
organizationId: filterData.organizationId
|
||||||
return data;
|
}
|
||||||
};
|
return data
|
||||||
|
}
|
||||||
//获取列表
|
//获取列表
|
||||||
let gettrialList = () => {
|
let gettrialList = () => {
|
||||||
filter.tableLoading = true;
|
filter.tableLoading = true
|
||||||
let data = setHistoryListData();
|
let data = setHistoryListData()
|
||||||
Https.axiosPost(Https.httpUrls.getUserInfo, data).then(
|
Https.axiosPost(Https.httpUrls.getUserInfo, data).then((rv: any) => {
|
||||||
(rv: any) => {
|
|
||||||
if (rv) {
|
if (rv) {
|
||||||
// this.dataList = rv
|
// this.dataList = rv
|
||||||
filter.dataList = rv.records;
|
filter.dataList = rv.records
|
||||||
filterData.total = rv.total;
|
filterData.total = rv.total
|
||||||
filter.tableLoading = false;
|
filter.tableLoading = false
|
||||||
|
|
||||||
// this.workspaceItem.position = this.singleTypeList[0].label
|
// this.workspaceItem.position = this.singleTypeList[0].label
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
);
|
|
||||||
};
|
|
||||||
let lastGeTrialList = (str: string) => {
|
let lastGeTrialList = (str: string) => {
|
||||||
clearHistoryList();
|
clearHistoryList()
|
||||||
let currentDate = new Date();
|
let currentDate = new Date()
|
||||||
let currentTimestamp = Math.floor(currentDate.getTime() / 1000);
|
let currentTimestamp = Math.floor(currentDate.getTime() / 1000)
|
||||||
// 计算30天前的时间戳
|
// 计算30天前的时间戳
|
||||||
let thirtyDaysAgoTimestamp;
|
let thirtyDaysAgoTimestamp
|
||||||
if (str == "year") {
|
if (str == "year") {
|
||||||
thirtyDaysAgoTimestamp = currentTimestamp - 360 * 24 * 60 * 60;
|
thirtyDaysAgoTimestamp = currentTimestamp - 360 * 24 * 60 * 60
|
||||||
} else if (str == "month") {
|
} else if (str == "month") {
|
||||||
thirtyDaysAgoTimestamp = currentTimestamp - 30 * 24 * 60 * 60;
|
thirtyDaysAgoTimestamp = currentTimestamp - 30 * 24 * 60 * 60
|
||||||
} else if (str == "week") {
|
} else if (str == "week") {
|
||||||
thirtyDaysAgoTimestamp = currentTimestamp - 7 * 24 * 60 * 60;
|
thirtyDaysAgoTimestamp = currentTimestamp - 7 * 24 * 60 * 60
|
||||||
|
}
|
||||||
|
filterData.rangePickerValue[0] = formatTime(thirtyDaysAgoTimestamp, "YYYY-MM-DD")
|
||||||
|
gettrialList()
|
||||||
}
|
}
|
||||||
filterData.rangePickerValue[0] = formatTime(
|
|
||||||
thirtyDaysAgoTimestamp,
|
|
||||||
"YYYY-MM-DD"
|
|
||||||
);
|
|
||||||
gettrialList();
|
|
||||||
};
|
|
||||||
let filterOption = (input: any, option: any) => {
|
let filterOption = (input: any, option: any) => {
|
||||||
// 使用 option.label 进行搜索
|
// 使用 option.label 进行搜索
|
||||||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
};
|
}
|
||||||
let addhHistoryList = () => {
|
let addhHistoryList = () => {
|
||||||
allUserPoerationsVue.value.init('Add','')
|
allUserPoerationsVue.value.init("Add", "")
|
||||||
};
|
}
|
||||||
let allUserPoerationsVue = ref()
|
let allUserPoerationsVue = ref()
|
||||||
let setAagree = (data: any) => {
|
let setAagree = (data: any) => {
|
||||||
allUserPoerationsVue.value.init('Edit',data)
|
allUserPoerationsVue.value.init("Edit", data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const organizationOptions = ref([])
|
||||||
|
const organizationParams = reactive({
|
||||||
|
page: 1,
|
||||||
|
size: 10,
|
||||||
|
total: 0
|
||||||
|
})
|
||||||
|
const organizationLoading = ref(false)
|
||||||
|
const getOrganizationList = async (isLoadMore = false) => {
|
||||||
|
console.log("111111")
|
||||||
|
if (organizationLoading.value) return
|
||||||
|
if (isLoadMore) {
|
||||||
|
const loaded = organizationParams.page * organizationParams.size
|
||||||
|
if (organizationParams.total && loaded >= organizationParams.total) return
|
||||||
|
organizationParams.page += 1
|
||||||
|
} else {
|
||||||
|
organizationParams.page = 1
|
||||||
|
organizationOptions.value = []
|
||||||
|
}
|
||||||
|
organizationLoading.value = true
|
||||||
|
try {
|
||||||
|
const { total, ...requestParams } = organizationParams
|
||||||
|
const rv: any = await Https.axiosPost(
|
||||||
|
Https.httpUrls.queryOrganization,
|
||||||
|
requestParams
|
||||||
|
)
|
||||||
|
if (rv) {
|
||||||
|
const newRecords = rv.records || []
|
||||||
|
// 遍历新数据,如果已存在则覆盖,不存在则追加
|
||||||
|
newRecords.forEach((newOrg: any) => {
|
||||||
|
const newOrgId = String(newOrg.id)
|
||||||
|
const existingIndex = organizationOptions.value.findIndex(
|
||||||
|
(org: any) => String(org.id) === newOrgId
|
||||||
|
)
|
||||||
|
if (existingIndex !== -1) {
|
||||||
|
// 如果已存在,用新数据覆盖旧项
|
||||||
|
organizationOptions.value[existingIndex] = newOrg
|
||||||
|
} else {
|
||||||
|
// 如果不存在,追加到末尾
|
||||||
|
organizationOptions.value.push(newOrg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
organizationParams.total = rv.total || 0
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
organizationLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleOrganizationScroll = (e: any) => {
|
||||||
|
const target = e?.target
|
||||||
|
if (!target) return
|
||||||
|
const nearBottom = target.scrollTop + target.clientHeight >= target.scrollHeight - 20
|
||||||
|
if (nearBottom) {
|
||||||
|
getOrganizationList(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
let allCountry: any = sessionStorage.getItem("allCountry");
|
let allCountry: any = sessionStorage.getItem("allCountry")
|
||||||
if (allCountry) {
|
if (allCountry) {
|
||||||
filter.allCountry = JSON.parse(allCountry);
|
filter.allCountry = JSON.parse(allCountry)
|
||||||
}
|
}
|
||||||
gettrialList();
|
gettrialList()
|
||||||
});
|
getOrganizationList()
|
||||||
|
})
|
||||||
return {
|
return {
|
||||||
...toRefs(filter),
|
...toRefs(filter),
|
||||||
...toRefs(filterData),
|
...toRefs(filterData),
|
||||||
@@ -501,22 +554,26 @@ export default defineComponent({
|
|||||||
filterOption,
|
filterOption,
|
||||||
allUserPoerationsVue,
|
allUserPoerationsVue,
|
||||||
setAagree,
|
setAagree,
|
||||||
};
|
handleOrganizationScroll,
|
||||||
|
getOrganizationList,
|
||||||
|
organizationOptions,
|
||||||
|
organizationParams
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
historyTableHeight: 0,
|
historyTableHeight: 0,
|
||||||
handleResizeColumn: (w: any, col: any) => {
|
handleResizeColumn: (w: any, col: any) => {
|
||||||
col.width = w;
|
col.width = w
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
let historyTable: any = this.$refs.historyTable;
|
let historyTable: any = this.$refs.historyTable
|
||||||
this.historyTableHeight = historyTable.clientHeight - 200;
|
this.historyTableHeight = historyTable.clientHeight - 200
|
||||||
},
|
},
|
||||||
methods: {},
|
methods: {}
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.admin_page .admin_table_search .admin_state {
|
.admin_page .admin_table_search .admin_state {
|
||||||
@@ -524,6 +581,5 @@ export default defineComponent({
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
.admin_page {
|
.admin_page {
|
||||||
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -321,6 +321,7 @@ export default defineComponent({
|
|||||||
data = setEditData()
|
data = setEditData()
|
||||||
if (!data.userName || !data.userEmail || !data.validEndTime || !data.systemUser)
|
if (!data.userName || !data.userEmail || !data.validEndTime || !data.systemUser)
|
||||||
return message.warning('Please check the input box marked with *')
|
return message.warning('Please check the input box marked with *')
|
||||||
|
delete data.userName
|
||||||
Https.axiosPost(Https.httpUrls.modifyUser, {}, { params: data }).then(rv => {
|
Https.axiosPost(Https.httpUrls.modifyUser, {}, { params: data }).then(rv => {
|
||||||
if (rv) {
|
if (rv) {
|
||||||
cancelDsign()
|
cancelDsign()
|
||||||
|
|||||||
99
src/component/Administrator/globalAwardPopularity.vue
Normal file
99
src/component/Administrator/globalAwardPopularity.vue
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
<template>
|
||||||
|
<div class="admin_page globalAwardPopularity" ref="adminPage">
|
||||||
|
<div class="admin_table_search">
|
||||||
|
<div class="admin_state">
|
||||||
|
<div class="admin_state_item">
|
||||||
|
<span>Current Time:</span>
|
||||||
|
<span>{{ currentTimeStr }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="admin_state_item">
|
||||||
|
<span>Raw Visi Count:</span>
|
||||||
|
<span>{{ rawVisitCount }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="admin_state_item">
|
||||||
|
<span>Unique Visit Count:</span>
|
||||||
|
<span>{{ uniqueVisitCount }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="admin_search">
|
||||||
|
<div class="admin_search_item" @click="getGlobalAwardPopularity">
|
||||||
|
<i class="fi fi-br-refresh"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="admin_table_content" ref="questionnaireTable">
|
||||||
|
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, ref, createVNode,toRefs, computed,reactive, onMounted, nextTick } from "vue";
|
||||||
|
import { Https } from "@/tool/https";
|
||||||
|
import type { TableColumnsType } from 'ant-design-vue';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
components: {},
|
||||||
|
setup() {
|
||||||
|
const currentTime = ref(new Date())
|
||||||
|
const currentTimeStr = computed(()=>{
|
||||||
|
return currentTime.value.toLocaleString()
|
||||||
|
})
|
||||||
|
const rawVisitCount = ref(0)
|
||||||
|
const uniqueVisitCount = ref(0)
|
||||||
|
const getGlobalAwardPopularity = () => {
|
||||||
|
Https.axiosGet(Https.httpUrls.getGlobalAwardPopularity,).then((rv)=>{
|
||||||
|
currentTime.value = new Date()
|
||||||
|
rawVisitCount.value = rv.rawVisitCount
|
||||||
|
uniqueVisitCount.value = rv.uniqueVisitCount
|
||||||
|
})
|
||||||
|
}
|
||||||
|
onMounted(()=>{
|
||||||
|
getGlobalAwardPopularity()
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
currentTimeStr,
|
||||||
|
getGlobalAwardPopularity,
|
||||||
|
rawVisitCount,
|
||||||
|
uniqueVisitCount,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.admin_page.globalAwardPopularity{
|
||||||
|
.admin_table_search{
|
||||||
|
// flex: 1;
|
||||||
|
width: min-content;
|
||||||
|
justify-content: flex-start;
|
||||||
|
border-radius: 2rem;
|
||||||
|
box-shadow: 0 0 1rem rgba(0, 0, 0, 0.2);
|
||||||
|
margin-left: 2rem;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
gap: 3rem;
|
||||||
|
}
|
||||||
|
.admin_state{
|
||||||
|
flex-direction: column;
|
||||||
|
width: auto;
|
||||||
|
cursor: auto;
|
||||||
|
.admin_state_item{
|
||||||
|
> span{
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.admin_search{
|
||||||
|
i{
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -5,8 +5,8 @@
|
|||||||
class="search-form"
|
class="search-form"
|
||||||
layout="inline"
|
layout="inline"
|
||||||
:model="searchForm"
|
:model="searchForm"
|
||||||
:label-col="{ style: { width: '12rem' } }"
|
:label-col="{ style: { width: '14rem' } }"
|
||||||
:wrapper-col="{ style: { width: '22rem' } }"
|
:wrapper-col="{ style: { width: '20rem' } }"
|
||||||
>
|
>
|
||||||
<a-form-item label="ID">
|
<a-form-item label="ID">
|
||||||
<a-input v-model:value="searchForm.id" allow-clear placeholder="Input the id" />
|
<a-input v-model:value="searchForm.id" allow-clear placeholder="Input the id" />
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
:options="countryList"
|
:options="countryList"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item class="search-form__actions">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-button type="primary" @click="handleSearch">Search</a-button>
|
<a-button type="primary" @click="handleSearch">Search</a-button>
|
||||||
<a-button @click="handleReset">Reset</a-button>
|
<a-button @click="handleReset">Reset</a-button>
|
||||||
@@ -92,6 +92,7 @@
|
|||||||
:loading="tableLoading"
|
:loading="tableLoading"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
|
:customRow="customPlanRow"
|
||||||
@change="changePage"
|
@change="changePage"
|
||||||
@resizeColumn="handleResizeColumn"
|
@resizeColumn="handleResizeColumn"
|
||||||
:scroll="{ y: historyTableHeight }"
|
:scroll="{ y: historyTableHeight }"
|
||||||
@@ -107,10 +108,11 @@
|
|||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
<template
|
<template
|
||||||
v-if="
|
v-if="
|
||||||
column.key === 'currentPeriodStart' || column.key === 'currentPeriodEnd'
|
column.key === 'currentPeriodStart' ||
|
||||||
|
column.key === 'currentPeriodEnd'
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{ formatTime(record[column.key], 'YYYY-MM-DD hh:mm:ss') }}
|
{{ formatTime(record[column.key], "YYYY-MM-DD hh:mm:ss") }}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-if="column.key === 'status'">
|
<template v-if="column.key === 'status'">
|
||||||
@@ -120,15 +122,15 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-else-if="column.key === 'actions'">
|
<template v-else-if="column.key === 'actions'">
|
||||||
<a-space>
|
<a-space class="plan-row-actions" @click.stop>
|
||||||
<a @click="openEdit(record)">Edit</a>
|
<a @click.stop="openEdit(record)">Edit</a>
|
||||||
<a-popconfirm
|
<a-popconfirm
|
||||||
title="Confirm to delete this subscription plan?"
|
title="Confirm to delete this subscription plan?"
|
||||||
ok-text="Confirm"
|
ok-text="Confirm"
|
||||||
cancel-text="Cancel"
|
cancel-text="Cancel"
|
||||||
@confirm="removePlan(record.id)"
|
@confirm="removePlan(record.id)"
|
||||||
>
|
>
|
||||||
<a class="danger-text">Delete</a>
|
<a class="danger-text" @click.stop>Delete</a>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
@@ -137,6 +139,50 @@
|
|||||||
</div>
|
</div>
|
||||||
</a-card>
|
</a-card>
|
||||||
|
|
||||||
|
<a-modal
|
||||||
|
v-model:visible="userInfoModalVisible"
|
||||||
|
title="User Info"
|
||||||
|
width="80%"
|
||||||
|
:footer="null"
|
||||||
|
:destroy-on-close="true"
|
||||||
|
class="user-info-modal"
|
||||||
|
>
|
||||||
|
<a-table
|
||||||
|
:columns="userInfoColumns"
|
||||||
|
:data-source="userInfoList"
|
||||||
|
:loading="userInfoLoading"
|
||||||
|
:pagination="{
|
||||||
|
showSizeChanger: true,
|
||||||
|
current: userInfoPage.current,
|
||||||
|
pageSize: userInfoPage.size,
|
||||||
|
total: userInfoPage.total,
|
||||||
|
showQuickJumper: true,
|
||||||
|
bordered: false
|
||||||
|
}"
|
||||||
|
row-key="id"
|
||||||
|
:scroll="{ x: 1280, y: 420 }"
|
||||||
|
@change="changeUserInfoPage"
|
||||||
|
>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template
|
||||||
|
v-if="
|
||||||
|
column.key === 'validStartTime' ||
|
||||||
|
column.key === 'validEndTime' ||
|
||||||
|
column.key === 'createDate'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ formatUserTime(record[column.key]) }}
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.key === 'systemUser'">
|
||||||
|
{{ getSystemUserLabel(record.systemUser) }}
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.key === 'isBeginner'">
|
||||||
|
{{ record.isBeginner == 1 ? "Yes" : "No" }}
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-modal>
|
||||||
|
|
||||||
<div class="subscriptionPlanModal" ref="subscriptionPlanModal"></div>
|
<div class="subscriptionPlanModal" ref="subscriptionPlanModal"></div>
|
||||||
<a-modal
|
<a-modal
|
||||||
class="subscriptionPlan_modal generalModel"
|
class="subscriptionPlan_modal generalModel"
|
||||||
@@ -213,7 +259,10 @@
|
|||||||
@select="handleOrganizationSelect"
|
@select="handleOrganizationSelect"
|
||||||
@change="handleOrganizationChange"
|
@change="handleOrganizationChange"
|
||||||
>
|
>
|
||||||
<a-select-option value="ADD_ORGANIZATION" class="add-organization-option">
|
<a-select-option
|
||||||
|
value="ADD_ORGANIZATION"
|
||||||
|
class="add-organization-option"
|
||||||
|
>
|
||||||
+ Create Organization
|
+ Create Organization
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
<a-select-option
|
<a-select-option
|
||||||
@@ -393,27 +442,30 @@ import {
|
|||||||
ref,
|
ref,
|
||||||
onMounted,
|
onMounted,
|
||||||
onBeforeUnmount,
|
onBeforeUnmount,
|
||||||
|
onActivated,
|
||||||
computed,
|
computed,
|
||||||
nextTick,
|
nextTick,
|
||||||
useTemplateRef
|
useTemplateRef
|
||||||
} from 'vue'
|
} from "vue"
|
||||||
import SelectUser from '@/component/common/SelectUser.vue'
|
import SelectUser from "@/component/common/SelectUser.vue"
|
||||||
import { message } from 'ant-design-vue'
|
import { message } from "ant-design-vue"
|
||||||
import { Https } from '@/tool/https'
|
import { Https } from "@/tool/https"
|
||||||
import { formatTime } from '@/tool/util'
|
import { formatTime } from "@/tool/util"
|
||||||
import store from '@/store'
|
import store from "@/store"
|
||||||
import type { FormInstance, Rule } from 'ant-design-vue/es/form'
|
import type { FormInstance, Rule } from "ant-design-vue/es/form"
|
||||||
import { debounce } from 'lodash-es'
|
import { debounce } from "lodash-es"
|
||||||
import dayjs, { Dayjs } from 'dayjs'
|
import dayjs, { Dayjs } from "dayjs"
|
||||||
|
|
||||||
type PlanStatus = 'PENDING' | 'ACTIVE' | 'EXPIRED'
|
type PlanStatus = "PENDING" | "ACTIVE" | "EXPIRED"
|
||||||
interface SubscriptionPlan {
|
interface SubscriptionPlan {
|
||||||
id: number
|
id: number
|
||||||
|
userId?: string | number
|
||||||
name: string
|
name: string
|
||||||
currentPeriodStart: string
|
currentPeriodStart: string
|
||||||
currentPeriodEnd: string
|
currentPeriodEnd: string
|
||||||
organizationId: string
|
organizationId: string
|
||||||
adminAccId: string
|
adminAccId: string
|
||||||
|
adminAccEmail?: string
|
||||||
status: PlanStatus
|
status: PlanStatus
|
||||||
creditLimit: number
|
creditLimit: number
|
||||||
accountNum?: number
|
accountNum?: number
|
||||||
@@ -421,17 +473,32 @@ interface SubscriptionPlan {
|
|||||||
endStamp: number
|
endStamp: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface UserInfoRecord {
|
||||||
|
id: number
|
||||||
|
userEmail?: string
|
||||||
|
userName?: string
|
||||||
|
language?: string
|
||||||
|
validStartTime?: number | string
|
||||||
|
validEndTime?: number | string
|
||||||
|
country?: string
|
||||||
|
createDate?: number | string
|
||||||
|
isBeginner?: number
|
||||||
|
browserIdentifiers?: string
|
||||||
|
credits?: number
|
||||||
|
systemUser?: number | string
|
||||||
|
}
|
||||||
|
|
||||||
const countryList = ref([])
|
const countryList = ref([])
|
||||||
const userRef = ref(null)
|
const userRef = ref(null)
|
||||||
|
|
||||||
const searchForm = reactive({
|
const searchForm = reactive({
|
||||||
name: '',
|
name: "",
|
||||||
startTime: '',
|
startTime: "",
|
||||||
endTime: '',
|
endTime: "",
|
||||||
organizationId: undefined as string | undefined,
|
organizationId: undefined as string | undefined,
|
||||||
adminAccId: undefined as string | undefined,
|
adminAccId: undefined as string | undefined,
|
||||||
status: [] as PlanStatus[] | [],
|
status: [] as PlanStatus[] | [],
|
||||||
id: '',
|
id: "",
|
||||||
countryOrRegion: null,
|
countryOrRegion: null,
|
||||||
page: 1,
|
page: 1,
|
||||||
size: 10,
|
size: 10,
|
||||||
@@ -442,15 +509,24 @@ const toSeconds = (dateStr: string) => Math.floor(new Date(dateStr).getTime() /
|
|||||||
|
|
||||||
const tableData = ref<SubscriptionPlan[]>([])
|
const tableData = ref<SubscriptionPlan[]>([])
|
||||||
const tableLoading = ref(false)
|
const tableLoading = ref(false)
|
||||||
|
const userInfoModalVisible = ref(false)
|
||||||
|
const userInfoLoading = ref(false)
|
||||||
|
const userInfoList = ref<UserInfoRecord[]>([])
|
||||||
|
const currentUserInfoPlanId = ref<string | number | null>(null)
|
||||||
|
const userInfoPage = reactive({
|
||||||
|
current: 1,
|
||||||
|
size: 10,
|
||||||
|
total: 0
|
||||||
|
})
|
||||||
|
|
||||||
const modalVisible = ref(false)
|
const modalVisible = ref(false)
|
||||||
const confirmLoading = ref(false)
|
const confirmLoading = ref(false)
|
||||||
const modalTitle = ref('New Subscription Plan')
|
const modalTitle = ref("New Subscription Plan")
|
||||||
const isEditMode = ref(false)
|
const isEditMode = ref(false)
|
||||||
const formState = reactive({
|
const formState = reactive({
|
||||||
name: '',
|
name: "",
|
||||||
currentPeriodStart: '',
|
currentPeriodStart: "",
|
||||||
currentPeriodEnd: '',
|
currentPeriodEnd: "",
|
||||||
organizationId: undefined as string | undefined,
|
organizationId: undefined as string | undefined,
|
||||||
adminAccId: undefined as string | undefined,
|
adminAccId: undefined as string | undefined,
|
||||||
creditLimit: null as number | null,
|
creditLimit: null as number | null,
|
||||||
@@ -461,44 +537,44 @@ const formState = reactive({
|
|||||||
|
|
||||||
const organizationModalVisible = ref(false)
|
const organizationModalVisible = ref(false)
|
||||||
const organizationForm = reactive({
|
const organizationForm = reactive({
|
||||||
name: '',
|
name: "",
|
||||||
type: undefined as string | undefined
|
type: undefined as string | undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
const statusLabelMap: Record<PlanStatus, string> = {
|
const statusLabelMap: Record<PlanStatus, string> = {
|
||||||
PENDING: 'Pending',
|
PENDING: "Pending",
|
||||||
ACTIVE: 'Active',
|
ACTIVE: "Active",
|
||||||
EXPIRED: 'Expired'
|
EXPIRED: "Expired"
|
||||||
}
|
}
|
||||||
const statusColorMap: Record<PlanStatus, string> = {
|
const statusColorMap: Record<PlanStatus, string> = {
|
||||||
PENDING: 'blue',
|
PENDING: "blue",
|
||||||
ACTIVE: 'green',
|
ACTIVE: "green",
|
||||||
EXPIRED: 'red'
|
EXPIRED: "red"
|
||||||
}
|
}
|
||||||
|
|
||||||
const statusOption = ref([
|
const statusOption = ref([
|
||||||
{
|
{
|
||||||
label: 'Pending',
|
label: "Pending",
|
||||||
value: 'PENDING'
|
value: "PENDING"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Active',
|
label: "Active",
|
||||||
value: 'ACTIVE'
|
value: "ACTIVE"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Expired',
|
label: "Expired",
|
||||||
value: 'EXPIRED'
|
value: "EXPIRED"
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
const disabledDate = (current: Dayjs) => {
|
const disabledDate = (current: Dayjs) => {
|
||||||
return current && current < dayjs().subtract(1, 'days').endOf('day')
|
return current && current < dayjs().subtract(1, "days").endOf("day")
|
||||||
}
|
}
|
||||||
|
|
||||||
const disableEndDate = (current: Dayjs) => {
|
const disableEndDate = (current: Dayjs) => {
|
||||||
if (isEditMode.value) {
|
if (isEditMode.value) {
|
||||||
const specificTime = dayjs(formState.currentPeriodEnd)
|
const specificTime = dayjs(formState.currentPeriodEnd)
|
||||||
return current && current < dayjs(formState.currentPeriodEnd * 1000).startOf('day')
|
return current && current < dayjs(formState.currentPeriodEnd * 1000).startOf("day")
|
||||||
}
|
}
|
||||||
return disabledDate(current)
|
return disabledDate(current)
|
||||||
}
|
}
|
||||||
@@ -509,7 +585,7 @@ const range = (start: number, end: number) => {
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
const disableEndTime = date => {
|
const disableEndTime = (date) => {
|
||||||
if (!formState.currentPeriodEnd || !isEditMode.value)
|
if (!formState.currentPeriodEnd || !isEditMode.value)
|
||||||
return {
|
return {
|
||||||
disabledHours: () => [],
|
disabledHours: () => [],
|
||||||
@@ -519,7 +595,7 @@ const disableEndTime = date => {
|
|||||||
|
|
||||||
const specificTime = dayjs.unix(formState.currentPeriodEnd)
|
const specificTime = dayjs.unix(formState.currentPeriodEnd)
|
||||||
|
|
||||||
if (date && date.isSame(specificTime, 'day')) {
|
if (date && date.isSame(specificTime, "day")) {
|
||||||
// 如果是指定日期当天,禁用时间戳之前的时间
|
// 如果是指定日期当天,禁用时间戳之前的时间
|
||||||
const hour = specificTime.hour()
|
const hour = specificTime.hour()
|
||||||
const minute = specificTime.minute()
|
const minute = specificTime.minute()
|
||||||
@@ -527,7 +603,7 @@ const disableEndTime = date => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
disabledHours: () => Array.from({ length: hour }, (_, i) => i), // 禁用小时之前
|
disabledHours: () => Array.from({ length: hour }, (_, i) => i), // 禁用小时之前
|
||||||
disabledMinutes: selectedHour => {
|
disabledMinutes: (selectedHour) => {
|
||||||
if (selectedHour === hour) {
|
if (selectedHour === hour) {
|
||||||
return Array.from({ length: minute }, (_, i) => i) // 同小时,禁用分钟之前
|
return Array.from({ length: minute }, (_, i) => i) // 同小时,禁用分钟之前
|
||||||
}
|
}
|
||||||
@@ -555,114 +631,328 @@ const normalizeStatus = (status?: string): PlanStatus | undefined => {
|
|||||||
return upper
|
return upper
|
||||||
}
|
}
|
||||||
const getStatusColor = (status?: string) =>
|
const getStatusColor = (status?: string) =>
|
||||||
statusColorMap[normalizeStatus(status) as PlanStatus] || 'default'
|
statusColorMap[normalizeStatus(status) as PlanStatus] || "default"
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{ title: 'Name', dataIndex: 'name', key: 'name', align: 'center', width: 180 },
|
{ title: "Name", dataIndex: "name", key: "name", align: "center", width: 180 },
|
||||||
{ title: 'ID', dataIndex: 'id', key: 'id', align: 'center', width: 80 },
|
{ title: "ID", dataIndex: "id", key: "id", align: "center", width: 80 },
|
||||||
{
|
{
|
||||||
title: 'Organization',
|
title: "Organization",
|
||||||
dataIndex: 'organizationName',
|
dataIndex: "organizationName",
|
||||||
key: 'organizationName',
|
key: "organizationName",
|
||||||
align: 'center',
|
align: "center",
|
||||||
width: 180
|
width: 180
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Admin Account',
|
title: "Admin Account",
|
||||||
dataIndex: 'adminAccEmail',
|
dataIndex: "adminAccEmail",
|
||||||
key: 'adminAccEmail',
|
key: "adminAccEmail",
|
||||||
align: 'center',
|
align: "center",
|
||||||
width: 180,
|
width: 180,
|
||||||
ellipsis: true
|
ellipsis: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Sub-Account Num',
|
title: "Sub-Account Num",
|
||||||
dataIndex: 'accountNum',
|
dataIndex: "accountNum",
|
||||||
key: 'accountNum',
|
key: "accountNum",
|
||||||
align: 'center',
|
align: "center",
|
||||||
width: 120,
|
width: 120,
|
||||||
ellipsis: true
|
ellipsis: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Country or Region',
|
title: "Country or Region",
|
||||||
dataIndex: 'countryOrRegion',
|
dataIndex: "countryOrRegion",
|
||||||
key: 'countryOrRegion',
|
key: "countryOrRegion",
|
||||||
align: 'center',
|
align: "center",
|
||||||
width: 120,
|
width: 120,
|
||||||
ellipsis: true
|
ellipsis: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Start Time',
|
title: "Start Time",
|
||||||
dataIndex: 'currentPeriodStart',
|
dataIndex: "currentPeriodStart",
|
||||||
key: 'currentPeriodStart',
|
key: "currentPeriodStart",
|
||||||
align: 'center',
|
align: "center",
|
||||||
width: 200
|
width: 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'End Time',
|
title: "End Time",
|
||||||
dataIndex: 'currentPeriodEnd',
|
dataIndex: "currentPeriodEnd",
|
||||||
key: 'currentPeriodEnd',
|
key: "currentPeriodEnd",
|
||||||
align: 'center',
|
align: "center",
|
||||||
width: 200
|
width: 200
|
||||||
},
|
},
|
||||||
{ title: 'Status', dataIndex: 'status', key: 'status', align: 'center', width: 100 },
|
{ title: "Status", dataIndex: "status", key: "status", align: "center", width: 100 },
|
||||||
{
|
{
|
||||||
title: 'Credit Limit',
|
title: "Credit Limit",
|
||||||
dataIndex: 'creditLimit',
|
dataIndex: "creditLimit",
|
||||||
key: 'creditLimit',
|
key: "creditLimit",
|
||||||
align: 'center',
|
align: "center",
|
||||||
width: 120
|
width: 120
|
||||||
},
|
},
|
||||||
{ title: 'Operations', key: 'actions', width: 160, align: 'center', fixed: 'right' }
|
{ title: "Operations", key: "actions", width: 160, align: "center", fixed: "right" }
|
||||||
]
|
]
|
||||||
|
|
||||||
const historyTable = ref()
|
const userInfoColumns = [
|
||||||
|
{ title: "User Id", dataIndex: "id", key: "id", align: "center", width: 100 },
|
||||||
|
{
|
||||||
|
title: "Email",
|
||||||
|
dataIndex: "userEmail",
|
||||||
|
key: "userEmail",
|
||||||
|
align: "center",
|
||||||
|
width: 200,
|
||||||
|
ellipsis: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "User Name",
|
||||||
|
dataIndex: "userName",
|
||||||
|
key: "userName",
|
||||||
|
align: "center",
|
||||||
|
width: 150,
|
||||||
|
ellipsis: true
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: "Valid Start Time",
|
||||||
|
dataIndex: "validStartTime",
|
||||||
|
key: "validStartTime",
|
||||||
|
align: "center",
|
||||||
|
width: 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Valid End Time",
|
||||||
|
dataIndex: "validEndTime",
|
||||||
|
key: "validEndTime",
|
||||||
|
align: "center",
|
||||||
|
width: 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Country or Region",
|
||||||
|
dataIndex: "country",
|
||||||
|
key: "country",
|
||||||
|
align: "center",
|
||||||
|
width: 180,
|
||||||
|
ellipsis: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Credits",
|
||||||
|
dataIndex: "credits",
|
||||||
|
key: "credits",
|
||||||
|
align: "center",
|
||||||
|
width: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "User Type",
|
||||||
|
dataIndex: "systemUser",
|
||||||
|
key: "systemUser",
|
||||||
|
align: "center",
|
||||||
|
width: 120
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const systemUserLabelMap: Record<string, string> = {
|
||||||
|
"0": "visitor",
|
||||||
|
"1": "yearly",
|
||||||
|
"2": "monthly",
|
||||||
|
"3": "trial",
|
||||||
|
"4": "userInEvent",
|
||||||
|
"7": "Edu Admin"
|
||||||
|
}
|
||||||
|
|
||||||
|
const getSystemUserLabel = (systemUser?: number | string) => {
|
||||||
|
if (systemUser === undefined || systemUser === null) return ""
|
||||||
|
return systemUserLabelMap[String(systemUser)] || String(systemUser)
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatUserTime = (value?: number | string) => {
|
||||||
|
if (!value) return ""
|
||||||
|
if (typeof value === "number") {
|
||||||
|
return formatTime(value / 1000, "YYYY-MM-DD hh:mm:ss")
|
||||||
|
}
|
||||||
|
if (/^\d+$/.test(value)) {
|
||||||
|
return formatTime(Number(value) / 1000, "YYYY-MM-DD hh:mm:ss")
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizeUserInfoList = (res: any): UserInfoRecord[] => {
|
||||||
|
if (Array.isArray(res)) return res
|
||||||
|
if (Array.isArray(res?.records)) return res.records
|
||||||
|
if (res) return [res]
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildUserInfoParams = (id: string | number) => ({
|
||||||
|
endTime: "",
|
||||||
|
startTime: "",
|
||||||
|
size: userInfoPage.size,
|
||||||
|
page: userInfoPage.current,
|
||||||
|
systemUser: "",
|
||||||
|
country: "",
|
||||||
|
email: "",
|
||||||
|
userType: "",
|
||||||
|
ids: [],
|
||||||
|
occupation: "",
|
||||||
|
order: "",
|
||||||
|
orderBy: "",
|
||||||
|
userName: "",
|
||||||
|
subscriptionPlanId: id
|
||||||
|
})
|
||||||
|
|
||||||
|
const fetchUserInfo = async () => {
|
||||||
|
if (currentUserInfoPlanId.value === null) return
|
||||||
|
userInfoLoading.value = true
|
||||||
|
userInfoList.value = []
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await Https.axiosPost(
|
||||||
|
Https.httpUrls.getUserInfo,
|
||||||
|
buildUserInfoParams(currentUserInfoPlanId.value)
|
||||||
|
)
|
||||||
|
const records = normalizeUserInfoList(res)
|
||||||
|
userInfoList.value = records
|
||||||
|
userInfoPage.total = Number(res?.total ?? records.length)
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || "Failed to load user info")
|
||||||
|
console.error(error)
|
||||||
|
} finally {
|
||||||
|
userInfoLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const openUserInfo = async (record: SubscriptionPlan) => {
|
||||||
|
console.log(record)
|
||||||
|
// debugger
|
||||||
|
|
||||||
|
currentUserInfoPlanId.value = record.id
|
||||||
|
userInfoPage.current = 1
|
||||||
|
userInfoModalVisible.value = true
|
||||||
|
await fetchUserInfo()
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeUserInfoPage = (pagination: any) => {
|
||||||
|
userInfoPage.current = pagination.current
|
||||||
|
userInfoPage.size = pagination.pageSize
|
||||||
|
fetchUserInfo()
|
||||||
|
}
|
||||||
|
|
||||||
|
const customPlanRow = (record: SubscriptionPlan) => {
|
||||||
|
return {
|
||||||
|
onClick: (event: MouseEvent) => {
|
||||||
|
const target = event.target as HTMLElement | null
|
||||||
|
if (target?.closest(".plan-row-actions")) return
|
||||||
|
openUserInfo(record)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const historyTable = ref<HTMLElement | null>(null)
|
||||||
const historyTableHeight = ref(0)
|
const historyTableHeight = ref(0)
|
||||||
|
const minTableBodyHeight = 120
|
||||||
|
let tableResizeObserver: ResizeObserver | null = null
|
||||||
|
let tableResizeTimer: ReturnType<typeof window.setTimeout> | null = null
|
||||||
|
|
||||||
const handleResizeColumn = (w: any, col: any) => {
|
const handleResizeColumn = (w: any, col: any) => {
|
||||||
col.width = w
|
col.width = w
|
||||||
}
|
}
|
||||||
|
|
||||||
const calculateTableHeight = () => {
|
const getElementOuterHeight = (element: Element | null) => {
|
||||||
nextTick(() => {
|
if (!element) return 0
|
||||||
if (historyTable.value) {
|
const htmlElement = element as HTMLElement
|
||||||
historyTableHeight.value = historyTable.value.clientHeight - 200
|
const style = window.getComputedStyle(htmlElement)
|
||||||
|
return (
|
||||||
|
htmlElement.offsetHeight +
|
||||||
|
Number.parseFloat(style.marginTop || "0") +
|
||||||
|
Number.parseFloat(style.marginBottom || "0")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const calculateTableHeight = () => {
|
||||||
|
if (tableResizeTimer) {
|
||||||
|
window.clearTimeout(tableResizeTimer)
|
||||||
|
}
|
||||||
|
tableResizeTimer = window.setTimeout(() => {
|
||||||
|
nextTick(() => {
|
||||||
|
const tableWrapper = historyTable.value
|
||||||
|
if (!tableWrapper) {
|
||||||
|
tableResizeTimer = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const tableHead = tableWrapper.querySelector(".ant-table-thead") ?? null
|
||||||
|
const pagination = tableWrapper.querySelector(".ant-pagination") ?? null
|
||||||
|
const tableHeadHeight = getElementOuterHeight(tableHead) || 55
|
||||||
|
const paginationHeight = getElementOuterHeight(pagination) || 48
|
||||||
|
const reservedHeight = tableHeadHeight + paginationHeight + 8
|
||||||
|
|
||||||
|
historyTableHeight.value = Math.max(
|
||||||
|
minTableBodyHeight,
|
||||||
|
tableWrapper.clientHeight - reservedHeight
|
||||||
|
)
|
||||||
|
tableResizeTimer = null
|
||||||
})
|
})
|
||||||
|
}, 50)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleResize = () => {
|
const handleResize = () => {
|
||||||
calculateTableHeight()
|
calculateTableHeight()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setupTableResizeObserver = () => {
|
||||||
|
if (!historyTable.value || typeof ResizeObserver === "undefined") return
|
||||||
|
tableResizeObserver?.disconnect()
|
||||||
|
tableResizeObserver = new ResizeObserver(() => {
|
||||||
|
calculateTableHeight()
|
||||||
|
})
|
||||||
|
tableResizeObserver.observe(historyTable.value)
|
||||||
|
|
||||||
|
const searchCard = historyTable.value
|
||||||
|
.closest(".subscription-plan")
|
||||||
|
?.querySelector(".search-card")
|
||||||
|
if (searchCard) {
|
||||||
|
tableResizeObserver.observe(searchCard)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await getOrganizationList()
|
await getOrganizationList()
|
||||||
await handleSearch()
|
await handleSearch()
|
||||||
calculateTableHeight()
|
calculateTableHeight()
|
||||||
window.addEventListener('resize', handleResize)
|
setupTableResizeObserver()
|
||||||
const list = sessionStorage.getItem('allCountry')
|
window.addEventListener("resize", handleResize)
|
||||||
|
const list = sessionStorage.getItem("allCountry")
|
||||||
countryList.value = list ? JSON.parse(list) : []
|
countryList.value = list ? JSON.parse(list) : []
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onActivated(() => {
|
||||||
|
calculateTableHeight()
|
||||||
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
window.removeEventListener('resize', handleResize)
|
window.removeEventListener("resize", handleResize)
|
||||||
|
tableResizeObserver?.disconnect()
|
||||||
|
if (tableResizeTimer) {
|
||||||
|
window.clearTimeout(tableResizeTimer)
|
||||||
|
tableResizeTimer = null
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleFetchTableData = async () => {
|
const handleFetchTableData = async () => {
|
||||||
tableLoading.value = true
|
tableLoading.value = true
|
||||||
return Https.axiosPost(Https.httpUrls.searchAllSubscribePlan, searchForm)
|
return Https.axiosPost(Https.httpUrls.searchAllSubscribePlan, searchForm)
|
||||||
.then(res => {
|
.then((res) => {
|
||||||
tableData.value = res.records
|
tableData.value = res.records
|
||||||
searchForm.total = res.total
|
searchForm.total = res.total
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
tableLoading.value = false
|
tableLoading.value = false
|
||||||
|
calculateTableHeight()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const resetFormState = () => {
|
const resetFormState = () => {
|
||||||
formState.name = ''
|
formState.name = ""
|
||||||
formState.currentPeriodStart = ''
|
formState.currentPeriodStart = ""
|
||||||
formState.currentPeriodEnd = ''
|
formState.currentPeriodEnd = ""
|
||||||
formState.organizationId = undefined
|
formState.organizationId = undefined
|
||||||
formState.adminAccId = undefined
|
formState.adminAccId = undefined
|
||||||
formState.creditLimit = null
|
formState.creditLimit = null
|
||||||
@@ -683,26 +973,26 @@ const handleSearch = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleReset = () => {
|
const handleReset = () => {
|
||||||
searchForm.name = ''
|
searchForm.name = ""
|
||||||
searchForm.startTime = ''
|
searchForm.startTime = ""
|
||||||
searchForm.endTime = ''
|
searchForm.endTime = ""
|
||||||
searchForm.organizationId = undefined
|
searchForm.organizationId = undefined
|
||||||
searchForm.adminAccId = undefined
|
searchForm.adminAccId = undefined
|
||||||
searchForm.status = []
|
searchForm.status = []
|
||||||
searchForm.id = ''
|
searchForm.id = ""
|
||||||
searchForm.countryOrRegion = null
|
searchForm.countryOrRegion = null
|
||||||
handleSearch()
|
handleSearch()
|
||||||
}
|
}
|
||||||
|
|
||||||
const openCreate = () => {
|
const openCreate = () => {
|
||||||
modalTitle.value = 'New Subscription Plan'
|
modalTitle.value = "New Subscription Plan"
|
||||||
isEditMode.value = false
|
isEditMode.value = false
|
||||||
resetFormState()
|
resetFormState()
|
||||||
modalVisible.value = true
|
modalVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const openEdit = (record: SubscriptionPlan) => {
|
const openEdit = (record: SubscriptionPlan) => {
|
||||||
modalTitle.value = 'Edit Subscription Plan'
|
modalTitle.value = "Edit Subscription Plan"
|
||||||
isEditMode.value = true
|
isEditMode.value = true
|
||||||
formState.name = record.name
|
formState.name = record.name
|
||||||
formState.currentPeriodStart = String(record.currentPeriodStart)
|
formState.currentPeriodStart = String(record.currentPeriodStart)
|
||||||
@@ -755,25 +1045,25 @@ const validateForm = (): boolean => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const requiredFields: FieldRule[] = [
|
const requiredFields: FieldRule[] = [
|
||||||
{ value: formState.currentPeriodStart, message: 'Please select the start time' },
|
{ value: formState.currentPeriodStart, message: "Please select the start time" },
|
||||||
{ value: formState.currentPeriodEnd, message: 'Please select the end time' },
|
{ value: formState.currentPeriodEnd, message: "Please select the end time" },
|
||||||
{ value: formState.adminAccId, message: 'Please select the admin account' },
|
{ value: formState.adminAccId, message: "Please select the admin account" },
|
||||||
{
|
{
|
||||||
value: formState.creditLimit,
|
value: formState.creditLimit,
|
||||||
message: 'Please input credit limit',
|
message: "Please input credit limit",
|
||||||
checkNull: true
|
checkNull: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: formState.accountNum,
|
value: formState.accountNum,
|
||||||
message: 'Please input account number',
|
message: "Please input account number",
|
||||||
checkNull: true
|
checkNull: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
if (!isEditMode.value) {
|
if (!isEditMode.value) {
|
||||||
requiredFields.push(
|
requiredFields.push(
|
||||||
{ value: formState.name, message: 'Please input the name' },
|
{ value: formState.name, message: "Please input the name" },
|
||||||
{ value: formState.organizationId, message: 'Please select organization' }
|
{ value: formState.organizationId, message: "Please select organization" }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -806,7 +1096,7 @@ const handleSubmit = async () => {
|
|||||||
res = await Https.axiosPost(Https.httpUrls.createSubscribePlan, params)
|
res = await Https.axiosPost(Https.httpUrls.createSubscribePlan, params)
|
||||||
}
|
}
|
||||||
message.success(
|
message.success(
|
||||||
`${isEditMode.value ? 'Subscription plan updated' : 'Subscription plan created'}`
|
`${isEditMode.value ? "Subscription plan updated" : "Subscription plan created"}`
|
||||||
)
|
)
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
message.error(error.message)
|
message.error(error.message)
|
||||||
@@ -835,8 +1125,8 @@ const cancelModal = () => {
|
|||||||
const removePlan = (id: number) => {
|
const removePlan = (id: number) => {
|
||||||
tableLoading.value = true
|
tableLoading.value = true
|
||||||
Https.axiosGet(Https.httpUrls.deleteSubscribePlan, { params: { id } })
|
Https.axiosGet(Https.httpUrls.deleteSubscribePlan, { params: { id } })
|
||||||
.then(res => {
|
.then((res) => {
|
||||||
message.success('Subscription plan deleted')
|
message.success("Subscription plan deleted")
|
||||||
handleReset()
|
handleReset()
|
||||||
})
|
})
|
||||||
.catch((error: any) => {
|
.catch((error: any) => {
|
||||||
@@ -901,15 +1191,15 @@ const handleOrganizationScroll = (e: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleOrganizationSelect = (value: string) => {
|
const handleOrganizationSelect = (value: string) => {
|
||||||
if (value === 'ADD_ORGANIZATION') {
|
if (value === "ADD_ORGANIZATION") {
|
||||||
// 打开添加组织弹窗
|
// 打开添加组织弹窗
|
||||||
organizationModalVisible.value = true
|
organizationModalVisible.value = true
|
||||||
// 使用nextTick确保值被重置,使其不被选中
|
// 使用nextTick确保值被重置,使其不被选中
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (searchForm.organizationId === 'ADD_ORGANIZATION') {
|
if (searchForm.organizationId === "ADD_ORGANIZATION") {
|
||||||
searchForm.organizationId = undefined
|
searchForm.organizationId = undefined
|
||||||
}
|
}
|
||||||
if (formState.organizationId === 'ADD_ORGANIZATION') {
|
if (formState.organizationId === "ADD_ORGANIZATION") {
|
||||||
formState.organizationId = undefined
|
formState.organizationId = undefined
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -918,12 +1208,12 @@ const handleOrganizationSelect = (value: string) => {
|
|||||||
|
|
||||||
const handleOrganizationChange = (value: string) => {
|
const handleOrganizationChange = (value: string) => {
|
||||||
// 如果change事件触发时值是"添加组织",立即重置
|
// 如果change事件触发时值是"添加组织",立即重置
|
||||||
if (value === 'ADD_ORGANIZATION') {
|
if (value === "ADD_ORGANIZATION") {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (searchForm.organizationId === 'ADD_ORGANIZATION') {
|
if (searchForm.organizationId === "ADD_ORGANIZATION") {
|
||||||
searchForm.organizationId = undefined
|
searchForm.organizationId = undefined
|
||||||
}
|
}
|
||||||
if (formState.organizationId === 'ADD_ORGANIZATION') {
|
if (formState.organizationId === "ADD_ORGANIZATION") {
|
||||||
formState.organizationId = undefined
|
formState.organizationId = undefined
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -932,13 +1222,13 @@ const handleOrganizationChange = (value: string) => {
|
|||||||
|
|
||||||
const cancelOrganizationModal = () => {
|
const cancelOrganizationModal = () => {
|
||||||
organizationModalVisible.value = false
|
organizationModalVisible.value = false
|
||||||
organizationForm.name = ''
|
organizationForm.name = ""
|
||||||
organizationForm.type = undefined
|
organizationForm.type = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCreateOrganization = async () => {
|
const handleCreateOrganization = async () => {
|
||||||
if (!organizationForm.name || !organizationForm.type) {
|
if (!organizationForm.name || !organizationForm.type) {
|
||||||
message.warning('Please fill in name and type')
|
message.warning("Please fill in name and type")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -948,7 +1238,7 @@ const handleCreateOrganization = async () => {
|
|||||||
type: organizationForm.type
|
type: organizationForm.type
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
message.success('Organization created successfully')
|
message.success("Organization created successfully")
|
||||||
cancelOrganizationModal()
|
cancelOrganizationModal()
|
||||||
// 刷新组织列表
|
// 刷新组织列表
|
||||||
await getOrganizationList()
|
await getOrganizationList()
|
||||||
@@ -960,26 +1250,28 @@ const handleCreateOrganization = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
message.error(error.message || 'Failed to create organization')
|
message.error(error.message || "Failed to create organization")
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterOption = (input: string, option: any) => {
|
const filterOption = (input: string, option: any) => {
|
||||||
const label = option?.label ?? option?.children ?? option?.key?.label ?? ''
|
const label = option?.label ?? option?.children ?? option?.key?.label ?? ""
|
||||||
return String(label).toLowerCase().includes(input.toLowerCase())
|
return String(label).toLowerCase().includes(input.toLowerCase())
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.subscription-plan {
|
.subscription-plan {
|
||||||
padding: 2rem 2.4rem 3.2rem 0;
|
padding: 2rem 2.4rem 0 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.search-card {
|
.search-card {
|
||||||
margin-bottom: 1.6rem;
|
margin-bottom: 1.6rem;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-card {
|
.table-card {
|
||||||
@@ -987,13 +1279,15 @@ const filterOption = (input: string, option: any) => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
min-height: 0;
|
||||||
|
|
||||||
:deep(.ant-card-body) {
|
:deep(.ant-card-body) {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 2.4rem;
|
padding: 2.4rem 2.4rem 0;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-card__header {
|
.table-card__header {
|
||||||
@@ -1007,6 +1301,42 @@ const filterOption = (input: string, option: any) => {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
|
||||||
|
:deep(.ant-table-wrapper),
|
||||||
|
:deep(.ant-spin-nested-loading),
|
||||||
|
:deep(.ant-spin-container) {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-spin-container) {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-table) {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-table-container) {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-table-content) {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-table-body) {
|
||||||
|
overflow-y: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-pagination) {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.danger-text {
|
.danger-text {
|
||||||
@@ -1026,8 +1356,23 @@ const filterOption = (input: string, option: any) => {
|
|||||||
:deep(.ant-table-tbody > tr:hover > td) {
|
:deep(.ant-table-tbody > tr:hover > td) {
|
||||||
background: rgb(202, 202, 202);
|
background: rgb(202, 202, 202);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:deep(.ant-table-tbody > tr) {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.plan-row-actions) {
|
||||||
|
cursor: default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info-modal {
|
||||||
|
:deep(.ant-modal-body) {
|
||||||
|
padding: 2.4rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.subscriptionPlan_modal) {
|
:deep(.subscriptionPlan_modal) {
|
||||||
.ant-modal-body {
|
.ant-modal-body {
|
||||||
// height: calc(65rem * 1.2);
|
// height: calc(65rem * 1.2);
|
||||||
@@ -1079,11 +1424,69 @@ const filterOption = (input: string, option: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
:deep(.search-form) {
|
:deep(.search-form) {
|
||||||
column-gap: 2rem;
|
--search-label-width: 14rem;
|
||||||
row-gap: 2rem;
|
--search-control-width: 20rem;
|
||||||
|
align-items: flex-start;
|
||||||
|
column-gap: 1.8rem;
|
||||||
|
row-gap: 1.8rem;
|
||||||
|
|
||||||
|
.ant-form-item {
|
||||||
|
min-width: calc(var(--search-label-width) + var(--search-control-width));
|
||||||
|
margin-right: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-form-item-label {
|
||||||
|
flex: 0 0 var(--search-label-width);
|
||||||
|
max-width: var(--search-label-width);
|
||||||
|
overflow: visible;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
> label {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-form-item-control {
|
||||||
|
flex: 0 0 var(--search-control-width);
|
||||||
|
max-width: var(--search-control-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-input,
|
||||||
|
.ant-input-affix-wrapper,
|
||||||
|
.ant-picker,
|
||||||
.ant-select {
|
.ant-select {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-form__actions {
|
||||||
|
min-width: auto;
|
||||||
|
|
||||||
|
.ant-form-item-control {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1600px) {
|
||||||
|
:deep(.search-form) {
|
||||||
|
--search-control-width: 22rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 760px) {
|
||||||
|
:deep(.search-form) {
|
||||||
|
.ant-form-item {
|
||||||
|
flex: 1 1 100%;
|
||||||
|
min-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-form-item-control {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
max-width: calc(100% - var(--search-label-width));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.ant-select-dropdown) {
|
:deep(.ant-select-dropdown) {
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ commandManager.setChangeCallback((info) => {
|
|||||||
emit("undo-redo-status-changed", {
|
emit("undo-redo-status-changed", {
|
||||||
canUndo: canUndo.value,
|
canUndo: canUndo.value,
|
||||||
canRedo: canRedo.value,
|
canRedo: canRedo.value,
|
||||||
|
type: info.type,
|
||||||
commandManager,
|
commandManager,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -409,7 +409,7 @@ export class BrushIndicator {
|
|||||||
// this.show(e.e);
|
// this.show(e.e);
|
||||||
this._mouseEnterHandler && this._mouseEnterHandler(e)
|
this._mouseEnterHandler && this._mouseEnterHandler(e)
|
||||||
} else {
|
} else {
|
||||||
// requestIdleCallback(() => {
|
// setTimeout(() => {
|
||||||
// this.updatePosition(e.e);
|
// this.updatePosition(e.e);
|
||||||
// });
|
// });
|
||||||
|
|
||||||
|
|||||||
@@ -623,17 +623,7 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
|
|||||||
this.updateMaskPosition(backgroundObject);
|
this.updateMaskPosition(backgroundObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新颜色层信息
|
this.setSpecialCliptInfo(false, true)
|
||||||
// const colorObject = this.getLayerObjectById(SpecialLayerId.COLOR);
|
|
||||||
// if(colorObject){
|
|
||||||
// await this.setObjecCliptInfo(colorObject);
|
|
||||||
// }
|
|
||||||
const groupLayer = this.layerManager.getLayerById(SpecialLayerId.SPECIAL_GROUP);
|
|
||||||
if(groupLayer){
|
|
||||||
const groupRect = new fabric.Rect({});
|
|
||||||
await this.setObjecCliptInfo(groupRect);
|
|
||||||
groupLayer.clippingMask = groupRect.toObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重新渲染画布
|
// 重新渲染画布
|
||||||
this.canvas.renderAll();
|
this.canvas.renderAll();
|
||||||
@@ -1335,7 +1325,7 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
loadJSON(json, calllBack) {
|
loadJSON(json, calllBack) {
|
||||||
|
this.canvas.loading.value = true;
|
||||||
// 确保传入的json是字符串格式
|
// 确保传入的json是字符串格式
|
||||||
if (typeof json === "object") {
|
if (typeof json === "object") {
|
||||||
json = JSON.stringify(json);
|
json = JSON.stringify(json);
|
||||||
@@ -1507,7 +1497,6 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
|
|||||||
*/
|
*/
|
||||||
async createOtherLayers(otherData) {
|
async createOtherLayers(otherData) {
|
||||||
if (!otherData) return console.warn("otherData 为空不需要添加");
|
if (!otherData) return console.warn("otherData 为空不需要添加");
|
||||||
this.canvas.loading.value = true;
|
|
||||||
let resolve = () => { };
|
let resolve = () => { };
|
||||||
this.awaitCanvasRun = () => (new Promise((v) => resolve = v))
|
this.awaitCanvasRun = () => (new Promise((v) => resolve = v))
|
||||||
const otherData_ = JSON.parse(JSON.stringify(otherData));
|
const otherData_ = JSON.parse(JSON.stringify(otherData));
|
||||||
@@ -1555,9 +1544,28 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
|
|||||||
console.log("==========创建其他图层成功");
|
console.log("==========创建其他图层成功");
|
||||||
resolve();
|
resolve();
|
||||||
this.awaitCanvasRun = null;
|
this.awaitCanvasRun = null;
|
||||||
this.canvas.loading.value = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//设置印花元素颜色的裁剪信息
|
||||||
|
async setSpecialCliptInfo(isColor = true, isGroup = true) {
|
||||||
|
// 更新颜色层信息
|
||||||
|
if (isColor) {
|
||||||
|
const colorObject = this.getLayerObjectById(SpecialLayerId.COLOR);
|
||||||
|
if (colorObject) {
|
||||||
|
await this.setObjecCliptInfo(colorObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// 更新特殊组图层信息
|
||||||
|
if (isGroup) {
|
||||||
|
const groupLayer = this.layerManager.getLayerById(SpecialLayerId.SPECIAL_GROUP);
|
||||||
|
if (groupLayer) {
|
||||||
|
const groupRect = new fabric.Rect({});
|
||||||
|
await this.setObjecCliptInfo(groupRect);
|
||||||
|
groupLayer.clippingMask = groupRect.toObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// 设置画布对象的裁剪信息
|
// 设置画布对象的裁剪信息
|
||||||
async setObjecCliptInfo(tagObject, data) {
|
async setObjecCliptInfo(tagObject, data) {
|
||||||
const fixedLayerObj = this.getFixedLayerObject();
|
const fixedLayerObj = this.getFixedLayerObject();
|
||||||
|
|||||||
@@ -606,7 +606,9 @@ export class ExportManager {
|
|||||||
imageSmoothingEnabled: true,
|
imageSmoothingEnabled: true,
|
||||||
});
|
});
|
||||||
// tempFabricCanvas.setZoom(1);
|
// tempFabricCanvas.setZoom(1);
|
||||||
console.log("==========", fixedLayerObject)
|
const ox = fixedLayerObject.left - fixedLayerObject.width * fixedLayerObject.scaleX / 2
|
||||||
|
const oy = fixedLayerObject.top - fixedLayerObject.height * fixedLayerObject.scaleY / 2
|
||||||
|
// console.log("==========", fixedLayerObject, ox, oy)
|
||||||
try {
|
try {
|
||||||
// 克隆并添加所有对象到临时画布,需要调整位置相对于固定图层
|
// 克隆并添加所有对象到临时画布,需要调整位置相对于固定图层
|
||||||
for (let i = 0; i < objectsToExport.length; i++) {
|
for (let i = 0; i < objectsToExport.length; i++) {
|
||||||
@@ -616,15 +618,20 @@ export class ExportManager {
|
|||||||
restoreOpacityInRedGreen && true
|
restoreOpacityInRedGreen && true
|
||||||
);
|
);
|
||||||
if (cloned) {
|
if (cloned) {
|
||||||
|
let scaleX = cloned.scaleX / fixedLayerObject.scaleX
|
||||||
|
let scaleY = cloned.scaleY / fixedLayerObject.scaleY
|
||||||
|
let top = (cloned.top - oy) * scaleY
|
||||||
|
let left = (cloned.left - ox) * scaleX
|
||||||
|
if (cloned.originX === "center" && cloned.originY === "center") {
|
||||||
|
top = canvasHeight / 2
|
||||||
|
left = canvasWidth / 2
|
||||||
|
}
|
||||||
cloned.set({
|
cloned.set({
|
||||||
left: canvasWidth / 2,
|
left: left,
|
||||||
top: canvasHeight / 2,
|
top: top,
|
||||||
scaleX: cloned.scaleX / fixedLayerObject.scaleX,
|
scaleX: scaleX,
|
||||||
scaleY: cloned.scaleY / fixedLayerObject.scaleY,
|
scaleY: scaleY,
|
||||||
originX: "center",
|
|
||||||
originY: "center",
|
|
||||||
});
|
});
|
||||||
console.log("==========", {...cloned})
|
|
||||||
// 更新对象坐标
|
// 更新对象坐标
|
||||||
cloned.setCoords();
|
cloned.setCoords();
|
||||||
tempFabricCanvas.add(cloned);
|
tempFabricCanvas.add(cloned);
|
||||||
|
|||||||
@@ -1580,7 +1580,7 @@ export class LayerManager {
|
|||||||
/**
|
/**
|
||||||
* 排序图层,确保图层顺序: 普通图层 > 固定图层 > 背景图层
|
* 排序图层,确保图层顺序: 普通图层 > 固定图层 > 背景图层
|
||||||
*/
|
*/
|
||||||
sortLayers() {
|
async sortLayers() {
|
||||||
// 对图层进行排序:背景图层在最底层(数组最后),固定图层在中间
|
// 对图层进行排序:背景图层在最底层(数组最后),固定图层在中间
|
||||||
this.layers.value.sort((a, b) => {
|
this.layers.value.sort((a, b) => {
|
||||||
// 如果a是背景图层,它应该排在后面(最底层)
|
// 如果a是背景图层,它应该排在后面(最底层)
|
||||||
@@ -1604,17 +1604,17 @@ export class LayerManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 更新画布对象顺序
|
// 更新画布对象顺序
|
||||||
this._rearrangeObjects();
|
await this._rearrangeObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重新排列画布上的对象以匹配图层顺序
|
* 重新排列画布上的对象以匹配图层顺序
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_rearrangeObjects() {
|
async _rearrangeObjects() {
|
||||||
if (this.layerSort) {
|
if (this.layerSort) {
|
||||||
// 使用LayerSort的高级排序
|
// 使用LayerSort的高级排序
|
||||||
this.layerSort.rearrangeObjects();
|
await this.layerSort.rearrangeObjects();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -133,11 +133,12 @@ export class RedGreenModeManager {
|
|||||||
this.canvas.on("mouse:up", (event) => {
|
this.canvas.on("mouse:up", (event) => {
|
||||||
// 可以在这里添加更多逻辑,比如生成图片或更新状态
|
// 可以在这里添加更多逻辑,比如生成图片或更新状态
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
requestIdleCallback(async () => {
|
setTimeout(async () => {
|
||||||
if (!this.isInitialized) {
|
if (!this.isInitialized) {
|
||||||
console.warn("红绿图模式未初始化,无法处理鼠标事件");
|
console.warn("红绿图模式未初始化,无法处理鼠标事件");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
console.log("鼠标抬起事件触发", this.onImageGenerated);
|
||||||
if (this.onImageGenerated) {
|
if (this.onImageGenerated) {
|
||||||
const imageData = await this.canvasManager.exportImage({
|
const imageData = await this.canvasManager.exportImage({
|
||||||
restoreOpacityInRedGreen: true, // 恢复红绿图模式下的透明度
|
restoreOpacityInRedGreen: true, // 恢复红绿图模式下的透明度
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ export class ThumbnailManager {
|
|||||||
|
|
||||||
// 延迟执行,避免阻塞UI
|
// 延迟执行,避免阻塞UI
|
||||||
fabricObjects.length > 0 &&
|
fabricObjects.length > 0 &&
|
||||||
requestIdleCallback(() => {
|
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
const base64 = await this._generateLayerThumbnailNow(fabricObjects, layer);
|
const base64 = await this._generateLayerThumbnailNow(fabricObjects, layer);
|
||||||
// this.layerThumbnails.set(layerId, base64);
|
// this.layerThumbnails.set(layerId, base64);
|
||||||
@@ -55,7 +54,6 @@ export class ThumbnailManager {
|
|||||||
console.error("生成图层缩略图时出错:", error);
|
console.error("生成图层缩略图时出错:", error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,7 +63,7 @@ export class ThumbnailManager {
|
|||||||
generateAllLayerThumbnails(layers) {
|
generateAllLayerThumbnails(layers) {
|
||||||
if (!layers || !Array.isArray(layers)) return;
|
if (!layers || !Array.isArray(layers)) return;
|
||||||
|
|
||||||
requestIdleCallback(() => {
|
setTimeout(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
layers.forEach((layer) => {
|
layers.forEach((layer) => {
|
||||||
if (layer && layer.id) {
|
if (layer && layer.id) {
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ export class CommandManager {
|
|||||||
this._recordPerformance("execute", command.constructor.name, duration);
|
this._recordPerformance("execute", command.constructor.name, duration);
|
||||||
|
|
||||||
// 通知状态变化
|
// 通知状态变化
|
||||||
this._notifyStateChange();
|
this._notifyStateChange("execute");
|
||||||
|
|
||||||
console.log(`✅ 命令执行成功: ${command.constructor.name}`);
|
console.log(`✅ 命令执行成功: ${command.constructor.name}`);
|
||||||
return result;
|
return result;
|
||||||
@@ -219,7 +219,7 @@ export class CommandManager {
|
|||||||
this._recordPerformance("undo", command.constructor.name, duration);
|
this._recordPerformance("undo", command.constructor.name, duration);
|
||||||
|
|
||||||
// 通知状态变化
|
// 通知状态变化
|
||||||
this._notifyStateChange();
|
this._notifyStateChange("undo");
|
||||||
|
|
||||||
console.log(`✅ 命令撤销成功: ${command.constructor.name}`);
|
console.log(`✅ 命令撤销成功: ${command.constructor.name}`);
|
||||||
return result;
|
return result;
|
||||||
@@ -258,7 +258,7 @@ export class CommandManager {
|
|||||||
this._recordPerformance("redo", command.constructor.name, duration);
|
this._recordPerformance("redo", command.constructor.name, duration);
|
||||||
|
|
||||||
// 通知状态变化
|
// 通知状态变化
|
||||||
this._notifyStateChange();
|
this._notifyStateChange("redo");
|
||||||
|
|
||||||
console.log(`✅ 命令重做成功: ${command.constructor.name}`);
|
console.log(`✅ 命令重做成功: ${command.constructor.name}`);
|
||||||
return result;
|
return result;
|
||||||
@@ -298,7 +298,7 @@ export class CommandManager {
|
|||||||
|
|
||||||
this.undoStack = [];
|
this.undoStack = [];
|
||||||
this.redoStack = [];
|
this.redoStack = [];
|
||||||
this._notifyStateChange();
|
this._notifyStateChange("clear");
|
||||||
// console.log("📝 命令历史已清空");
|
// console.log("📝 命令历史已清空");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,10 +417,12 @@ export class CommandManager {
|
|||||||
* 通知状态变化
|
* 通知状态变化
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_notifyStateChange() {
|
_notifyStateChange(type) {
|
||||||
if (this.onStateChange) {
|
if (this.onStateChange) {
|
||||||
try {
|
try {
|
||||||
this.onStateChange(this.getState());
|
const obj = this.getState();
|
||||||
|
obj.type = type;
|
||||||
|
this.onStateChange(obj);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("状态变化回调执行失败:", error);
|
console.error("状态变化回调执行失败:", error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ export class LiquifyRealTimeUpdater {
|
|||||||
|
|
||||||
if (isDrawing && this.config.useDirectUpdate) {
|
if (isDrawing && this.config.useDirectUpdate) {
|
||||||
// 拖拽过程中使用快速更新(降低质量以提高性能)
|
// 拖拽过程中使用快速更新(降低质量以提高性能)
|
||||||
this._fastUpdate(imageData);
|
await this._fastUpdate(imageData);
|
||||||
} else {
|
} else {
|
||||||
// 拖拽结束后使用完整更新(最高质量)
|
// 拖拽结束后使用完整更新(最高质量)
|
||||||
await this._fullUpdate(imageData);
|
await this._fullUpdate(imageData);
|
||||||
@@ -124,7 +124,7 @@ export class LiquifyRealTimeUpdater {
|
|||||||
* @param {ImageData} imageData 图像数据
|
* @param {ImageData} imageData 图像数据
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_fastUpdate(imageData) {
|
async _fastUpdate(imageData) {
|
||||||
if (!this.targetObject || !this.targetObject._element) {
|
if (!this.targetObject || !this.targetObject._element) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -138,12 +138,14 @@ export class LiquifyRealTimeUpdater {
|
|||||||
|
|
||||||
// 直接更新fabric对象的图像源(使用PNG格式保持质量)
|
// 直接更新fabric对象的图像源(使用PNG格式保持质量)
|
||||||
const targetElement = this.targetObject._element;
|
const targetElement = this.targetObject._element;
|
||||||
|
|
||||||
// 方案1: 直接设置src属性(最高性能)
|
// 方案1: 直接设置src属性(最高性能)
|
||||||
const dataURL = this.tempCanvas.toDataURL("image/png", quality);
|
const dataURL = this.tempCanvas.toDataURL("image/png", quality);
|
||||||
|
|
||||||
if (targetElement.src !== dataURL) {
|
if (targetElement.src !== dataURL) {
|
||||||
targetElement.src = dataURL;
|
// targetElement.src = dataURL;
|
||||||
|
const image = new Image();
|
||||||
|
image.src = dataURL;
|
||||||
|
await image.decode();
|
||||||
|
this.targetObject.setElement(image);
|
||||||
|
|
||||||
// 关键优化:直接设置fabric对象为脏状态,但不立即渲染
|
// 关键优化:直接设置fabric对象为脏状态,但不立即渲染
|
||||||
// this.targetObject.dirty = false; // 标记为不需要立即渲染
|
// this.targetObject.dirty = false; // 标记为不需要立即渲染
|
||||||
@@ -153,7 +155,7 @@ export class LiquifyRealTimeUpdater {
|
|||||||
// 使用requestAnimationFrame进行批量渲染优化
|
// 使用requestAnimationFrame进行批量渲染优化
|
||||||
// if (!this.renderingScheduled && !this.config.skipRenderDuringDrag) {
|
// if (!this.renderingScheduled && !this.config.skipRenderDuringDrag) {
|
||||||
// this.renderingScheduled = true;
|
// this.renderingScheduled = true;
|
||||||
// requestIdleCallback(() => {
|
// setTimeout(() => {
|
||||||
// this.canvas.renderAll();
|
// this.canvas.renderAll();
|
||||||
// this.renderingScheduled = false;
|
// this.renderingScheduled = false;
|
||||||
// });
|
// });
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ export class LayerSort {
|
|||||||
if (canvasObjects.length === 0) return;
|
if (canvasObjects.length === 0) return;
|
||||||
|
|
||||||
// 使用画布渲染优化
|
// 使用画布渲染优化
|
||||||
await optimizeCanvasRendering(this.canvas, () => {
|
await new Promise((resolve) => {
|
||||||
|
optimizeCanvasRendering(this.canvas, () => {
|
||||||
// 计算每个对象应该在的 z-index 位置
|
// 计算每个对象应该在的 z-index 位置
|
||||||
const objectZIndexMap = this.calculateObjectZIndexes();
|
const objectZIndexMap = this.calculateObjectZIndexes();
|
||||||
|
|
||||||
@@ -51,6 +52,8 @@ export class LayerSort {
|
|||||||
this.canvas.moveTo(item.object, index);
|
this.canvas.moveTo(item.object, index);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -375,6 +375,7 @@ const confirm = ()=>{
|
|||||||
/* 图片网格 */
|
/* 图片网格 */
|
||||||
.image-grid {
|
.image-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
align-content: start;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
min-height: 20rem;
|
min-height: 20rem;
|
||||||
|
|||||||
@@ -447,6 +447,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</CanvasEditor>
|
</CanvasEditor>
|
||||||
</div>
|
</div>
|
||||||
|
<img src="" alt="" id="canvas-test-dom">
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style>
|
<style>
|
||||||
@@ -458,6 +459,13 @@
|
|||||||
height: 600px !important;
|
height: 600px !important;
|
||||||
z-index: 99999999;
|
z-index: 99999999;
|
||||||
}
|
}
|
||||||
|
#canvas-test-dom{
|
||||||
|
position: fixed;
|
||||||
|
z-index: 9999999999;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
* {
|
* {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
:enabledRedGreenMode="false"
|
:enabledRedGreenMode="false"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn">123
|
<div class="btn">
|
||||||
<div class="gallery_btn" @click="exportElement">Export</div>
|
<div class="gallery_btn" @click="exportElement">Export</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -331,7 +331,6 @@ export default defineComponent({
|
|||||||
store.commit('DesignDetail/setCurrentDetailType',str)
|
store.commit('DesignDetail/setCurrentDetailType',str)
|
||||||
}
|
}
|
||||||
const setClothes = async (list:any,str:string)=>{
|
const setClothes = async (list:any,str:string)=>{
|
||||||
console.log(JSON.parse(JSON.stringify(list)))
|
|
||||||
let clothesList:any = []
|
let clothesList:any = []
|
||||||
if(detailData.isEditPattern.value == 'editSketch')await detailDom.canvasBox.submitBase64Data().then((rv)=>{
|
if(detailData.isEditPattern.value == 'editSketch')await detailDom.canvasBox.submitBase64Data().then((rv)=>{
|
||||||
detailData.selectDetail.sketchString = rv
|
detailData.selectDetail.sketchString = rv
|
||||||
@@ -369,7 +368,6 @@ export default defineComponent({
|
|||||||
// }else if(isCurrent){
|
// }else if(isCurrent){
|
||||||
|
|
||||||
// }
|
// }
|
||||||
console.log(JSON.parse(JSON.stringify(detailData.selectDetail.color)),'=====')
|
|
||||||
color = list[i].color?.rgba?.r != null?`${list[i].color.rgba.r} ${list[i].color.rgba.g} ${list[i].color.rgba.b}`:''
|
color = list[i].color?.rgba?.r != null?`${list[i].color.rgba.r} ${list[i].color.rgba.g} ${list[i].color.rgba.b}`:''
|
||||||
gradient = list[i].gradient
|
gradient = list[i].gradient
|
||||||
if((detailData.currentDetailType == 'sketch' && newData?.sketch) || detailData.isEditPattern.value == 'editSketch'){
|
if((detailData.currentDetailType == 'sketch' && newData?.sketch) || detailData.isEditPattern.value == 'editSketch'){
|
||||||
@@ -565,11 +563,14 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
//走画布合成图片并且直接分割
|
//走画布合成图片并且直接分割
|
||||||
|
if(detailData.isEditPattern.value !== 'canvasEditor' && detailData.isEditPattern.value !== 'redGreenExample'){
|
||||||
if(detailData.isEditPattern.value !== 'canvasEditor'){
|
if(detailData.isEditPattern.value !== 'canvasEditor'){
|
||||||
if(detailDom.detailRight?.privewDetail)await (detailDom.detailRight as any).privewDetail()
|
if(detailDom.detailRight?.privewDetail)await (detailDom.detailRight as any).privewDetail()
|
||||||
|
}
|
||||||
let otherData = await updateOtherLayers('single')
|
let otherData = await updateOtherLayers('single')
|
||||||
await detailDom.canvasBox.updateOtherLayers(otherData)
|
await detailDom.canvasBox.updateOtherLayers(otherData)
|
||||||
}
|
}
|
||||||
|
|
||||||
await detailDom.canvasBox.privewDetail()
|
await detailDom.canvasBox.privewDetail()
|
||||||
await upDateFrontBackSketch()
|
await upDateFrontBackSketch()
|
||||||
await uploadSelectDetail()
|
await uploadSelectDetail()
|
||||||
@@ -625,7 +626,7 @@ export default defineComponent({
|
|||||||
if(detailData.isEditPattern.value && detailData.isEditPattern.value == str){
|
if(detailData.isEditPattern.value && detailData.isEditPattern.value == str){
|
||||||
// await detailDom.canvasBox.saveCanvas()
|
// await detailDom.canvasBox.saveCanvas()
|
||||||
await (detailDom.canvasBox as any).privewDetail()
|
await (detailDom.canvasBox as any).privewDetail()
|
||||||
if(detailData.isEditPattern.value == 'canvasEditor')await uploadSelectDetail()
|
if(detailData.isEditPattern.value == 'canvasEditor' || detailData.isEditPattern.value == 'redGreenExample')await uploadSelectDetail()
|
||||||
detailData.isEditPattern.value = ''
|
detailData.isEditPattern.value = ''
|
||||||
}else{
|
}else{
|
||||||
// if(detailData.isEditPattern.value && (str == 'canvasEditor' || str == 'redGreenExample')){
|
// if(detailData.isEditPattern.value && (str == 'canvasEditor' || str == 'redGreenExample')){
|
||||||
@@ -759,7 +760,6 @@ export default defineComponent({
|
|||||||
const uploadSelectDetail = async ()=>{//更新选中的detail
|
const uploadSelectDetail = async ()=>{//更新选中的detail
|
||||||
// await detailDom.canvasBox.saveCanvas()
|
// await detailDom.canvasBox.saveCanvas()
|
||||||
const allInfo = await (detailDom.canvasBox as any).getCanvasElement()
|
const allInfo = await (detailDom.canvasBox as any).getCanvasElement()
|
||||||
console.log(allInfo)
|
|
||||||
let color:any = {}
|
let color:any = {}
|
||||||
if(allInfo.color?.color?.rgba || allInfo.color?.color?.gradient){
|
if(allInfo.color?.color?.rgba || allInfo.color?.color?.gradient){
|
||||||
let canvasColor = allInfo.color.color;
|
let canvasColor = allInfo.color.color;
|
||||||
@@ -781,8 +781,7 @@ export default defineComponent({
|
|||||||
color.gradient = canvasColor.gradient
|
color.gradient = canvasColor.gradient
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(detailData.isEditPattern.value == 'canvasEditor' || detailData.isEditPattern.value == 'redGreenExample'){
|
||||||
if(detailData.isEditPattern.value == 'canvasEditor'){
|
|
||||||
delete detailData.selectDetail.newDetail
|
delete detailData.selectDetail.newDetail
|
||||||
detailData.selectDetail.trims.prints = allInfo.trims || []
|
detailData.selectDetail.trims.prints = allInfo.trims || []
|
||||||
detailData.selectDetail.printObject.prints = allInfo.prints || []
|
detailData.selectDetail.printObject.prints = allInfo.prints || []
|
||||||
@@ -805,7 +804,6 @@ export default defineComponent({
|
|||||||
if(detailData.currentDetailType == 'color'){
|
if(detailData.currentDetailType == 'color'){
|
||||||
detailData.detailLeftColorKey++
|
detailData.detailLeftColorKey++
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
const canvasReload = async ()=>{
|
const canvasReload = async ()=>{
|
||||||
if(detailData.isEditPattern.value){
|
if(detailData.isEditPattern.value){
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
is-edit
|
is-edit
|
||||||
:clothingImageUrl="selectDetail.path"
|
:clothingImageUrl="selectDetail.path"
|
||||||
:clothingImageUrl2="selectDetail.maskUrl || selectDetail.layersObject[0].maskUrl"
|
:clothingImageUrl2="selectDetail.maskUrl || selectDetail.layersObject[0].maskUrl"
|
||||||
:clothingMinIOPath="selectDetail.minIOPath"
|
|
||||||
showFixedLayer
|
showFixedLayer
|
||||||
:canvasJSON="canvasJSON"
|
:canvasJSON="canvasJSON"
|
||||||
@canvasLoadJsonSuccess="canvasLoadJsonSuccess"
|
@canvasLoadJsonSuccess="canvasLoadJsonSuccess"
|
||||||
@@ -52,9 +51,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mark_loading" v-show="isShowMark">
|
<!-- <div class="mark_loading" v-show="isShowMark">
|
||||||
<a-spin size="large" />
|
<a-spin size="large" />
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
@@ -164,7 +163,6 @@ export default defineComponent({
|
|||||||
const privewDetail = async (oldSelectDetail = detailData.selectDetail)=>{
|
const privewDetail = async (oldSelectDetail = detailData.selectDetail)=>{
|
||||||
// if(!detailDom.editCanvas)return
|
// if(!detailDom.editCanvas)return
|
||||||
return new Promise(async (res,reject)=>{
|
return new Promise(async (res,reject)=>{
|
||||||
console.log(detailDom.editCanvas)
|
|
||||||
await detailDom.editCanvas.exportImage({
|
await detailDom.editCanvas.exportImage({
|
||||||
isContainFixed:true,
|
isContainFixed:true,
|
||||||
width:props.sketchSize.width,
|
width:props.sketchSize.width,
|
||||||
@@ -246,17 +244,27 @@ export default defineComponent({
|
|||||||
|
|
||||||
|
|
||||||
const frontBackChange = async (value:any)=>{
|
const frontBackChange = async (value:any)=>{
|
||||||
|
let front = detailData.frontBack.front[detailData.imgDomIndex]
|
||||||
|
let back = detailData.frontBack.back[detailData.imgDomIndex]
|
||||||
|
store.commit('DesignDetail/updataDetailItem',{maskUrl:value})
|
||||||
|
await nextTick()
|
||||||
if(!detailData.selectDetail.partialDesign.partialDesignPath && !detailData.selectDetail.partialDesign.partialDesignBase64){
|
if(!detailData.selectDetail.partialDesign.partialDesignPath && !detailData.selectDetail.partialDesign.partialDesignBase64){
|
||||||
await privewDetail()
|
await privewDetail()
|
||||||
|
}else{
|
||||||
|
await detailDom.editCanvas.exportImage({
|
||||||
|
isFrontBackUpdata: true,
|
||||||
|
isContainFixed:true,
|
||||||
|
width:props.sketchSize.width,
|
||||||
|
height:props.sketchSize.height,
|
||||||
|
}).then((rv)=>{
|
||||||
|
if(detailData.selectDetail?.partialDesign)detailData.selectDetail.partialDesign.partialDesignBase64 = rv
|
||||||
|
})
|
||||||
}
|
}
|
||||||
let full = detailData.selectDetail.partialDesign.partialDesignBase64 || detailData.selectDetail.partialDesign.partialDesignPath || detailData.selectDetail.path
|
let full = detailData.selectDetail.partialDesign.partialDesignBase64 || detailData.selectDetail.partialDesign.partialDesignPath || detailData.selectDetail.path
|
||||||
let size = {
|
let size = {
|
||||||
...detailData.canvasConfig,
|
...detailData.canvasConfig,
|
||||||
}
|
}
|
||||||
store.commit('DesignDetail/updataDetailItem',{maskUrl:value})
|
|
||||||
segmentImage(value,full,size).then(async (rv)=>{
|
segmentImage(value,full,size).then(async (rv)=>{
|
||||||
let front = detailData.frontBack.front[detailData.imgDomIndex]
|
|
||||||
let back = detailData.frontBack.back[detailData.imgDomIndex]
|
|
||||||
if(!front?.oldImageUrl)front.oldImageUrl = front.imageUrl
|
if(!front?.oldImageUrl)front.oldImageUrl = front.imageUrl
|
||||||
if(!front?.oldMaskUrl)front.oldMaskUrl = front.maskUrl
|
if(!front?.oldMaskUrl)front.oldMaskUrl = front.maskUrl
|
||||||
if(!back?.oldImageUrl)back.oldImageUrl = back.imageUrl
|
if(!back?.oldImageUrl)back.oldImageUrl = back.imageUrl
|
||||||
@@ -268,7 +276,6 @@ export default defineComponent({
|
|||||||
back.imageUrl = rv.targetBackUrl
|
back.imageUrl = rv.targetBackUrl
|
||||||
// store.commit('DesignDetail/updataDetailItem',{maskUrl:value})
|
// store.commit('DesignDetail/updataDetailItem',{maskUrl:value})
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
const editSketchCanvasInit = async (value:any)=>{
|
const editSketchCanvasInit = async (value:any)=>{
|
||||||
detailData.canvasInstance = value
|
detailData.canvasInstance = value
|
||||||
|
|||||||
@@ -40,11 +40,29 @@ export default defineComponent({
|
|||||||
setup(props,{emit}) {
|
setup(props,{emit}) {
|
||||||
const {t} = useI18n();
|
const {t} = useI18n();
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
const updateCatecory = (arr)=>{
|
||||||
|
arr.forEach((v:any) => {
|
||||||
|
if(props.catecoryList)props.catecoryList.forEach((item:any) => {
|
||||||
|
if(v.level2Type == item.value && !v.category){
|
||||||
|
v.category=item.name
|
||||||
|
v.categoryValue=item.value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
const detailData = reactive({
|
const detailData = reactive({
|
||||||
allBoardData:computed(()=>store.state.UploadFilesModule.allBoardData),
|
allBoardData:computed(()=>store.state.UploadFilesModule.allBoardData),
|
||||||
currentList:{
|
currentList:{
|
||||||
sketch:computed(()=>store.state.UploadFilesModule.allBoardData.sketchboardFiles),
|
sketch:computed(()=>{
|
||||||
print:computed(()=>store.state.UploadFilesModule.allBoardData.printboardFiles),
|
let sketch = store.state.UploadFilesModule.allBoardData.sketchboardFiles
|
||||||
|
updateCatecory(sketch)
|
||||||
|
return sketch
|
||||||
|
}),
|
||||||
|
print:computed(()=>{
|
||||||
|
let print = store.state.UploadFilesModule.allBoardData.printboardFiles
|
||||||
|
updateCatecory(print)
|
||||||
|
return print
|
||||||
|
}),
|
||||||
color:computed(()=>store.state.UploadFilesModule.allBoardData.colorBoards),
|
color:computed(()=>store.state.UploadFilesModule.allBoardData.colorBoards),
|
||||||
models:computed(()=>store.state.Workspace.probjects.model),
|
models:computed(()=>store.state.Workspace.probjects.model),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ export default defineComponent({
|
|||||||
selectImgItem(data)
|
selectImgItem(data)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
data.id = id
|
||||||
if(data?.imgUrl)data.url = data.imgUrl
|
if(data?.imgUrl)data.url = data.imgUrl
|
||||||
let value = {
|
let value = {
|
||||||
data,
|
data,
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ export default defineComponent({
|
|||||||
minIOPath:data.minIOPath || data.originalUrl,
|
minIOPath:data.minIOPath || data.originalUrl,
|
||||||
path:data.url,
|
path:data.url,
|
||||||
priority:printIndex,
|
priority:printIndex,
|
||||||
scale,
|
scale:editPrintElementData.stateOverallSingle == 'single'?scale:[1,1],
|
||||||
globalCompositeOperation:'',
|
globalCompositeOperation:'',
|
||||||
}
|
}
|
||||||
getItemPosition(item)
|
getItemPosition(item)
|
||||||
@@ -300,7 +300,7 @@ export default defineComponent({
|
|||||||
// location = [item.pattern.style.left,item.pattern.style.top]
|
// location = [item.pattern.style.left,item.pattern.style.top]
|
||||||
}
|
}
|
||||||
let value ={
|
let value ={
|
||||||
angle : item.pattern.transform.rotateZ,
|
angle:0,
|
||||||
// angle : !this.overallSingle ? 0:item.pattern.transform.rotateZ,
|
// angle : !this.overallSingle ? 0:item.pattern.transform.rotateZ,
|
||||||
location : location,
|
location : location,
|
||||||
priority:item.priority,
|
priority:item.priority,
|
||||||
@@ -312,7 +312,9 @@ export default defineComponent({
|
|||||||
ifSingle:!!item.ifSingle,
|
ifSingle:!!item.ifSingle,
|
||||||
globalCompositeOperation:'',
|
globalCompositeOperation:'',
|
||||||
}
|
}
|
||||||
if(item.object)value.object = item.object
|
if(item.object)value.object = item.object;
|
||||||
|
value.angle = value.ifSingle?item.pattern.transform.rotateZ:item.angle
|
||||||
|
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
if(editPrintElementData.printStyleList[props.type].single.length>0){
|
if(editPrintElementData.printStyleList[props.type].single.length>0){
|
||||||
@@ -359,7 +361,7 @@ export default defineComponent({
|
|||||||
//overall
|
//overall
|
||||||
left = item.location[0] / editPrintElementData.sketchWH.scale[0]
|
left = item.location[0] / editPrintElementData.sketchWH.scale[0]
|
||||||
top = item.location[1] / editPrintElementData.sketchWH.scale[1]
|
top = item.location[1] / editPrintElementData.sketchWH.scale[1]
|
||||||
item.scale = [1,1]
|
item.scale = item.scale || [1,1]
|
||||||
}
|
}
|
||||||
let pattern = {
|
let pattern = {
|
||||||
centers:{left:0,top:0},
|
centers:{left:0,top:0},
|
||||||
@@ -391,8 +393,8 @@ export default defineComponent({
|
|||||||
angle: 0,
|
angle: 0,
|
||||||
flipX: false,
|
flipX: false,
|
||||||
flipY: false,
|
flipY: false,
|
||||||
// blendMode: "multiply",
|
blendMode: "multiply",
|
||||||
blendMode: "source-over",
|
// blendMode: "source-over",
|
||||||
gapX: 0,
|
gapX: 0,
|
||||||
gapY: 0,
|
gapY: 0,
|
||||||
}
|
}
|
||||||
@@ -915,6 +917,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
const inputFillAngle = (angle:any)=>{
|
const inputFillAngle = (angle:any)=>{
|
||||||
let arr = editPrintElementData.printStyleList[props.type].overall
|
let arr = editPrintElementData.printStyleList[props.type].overall
|
||||||
|
console.log(angle)
|
||||||
arr[editPrintElementData.imgDomIndex].angle = angle
|
arr[editPrintElementData.imgDomIndex].angle = angle
|
||||||
editPrintElementDom.pingpuRef.updataList([
|
editPrintElementDom.pingpuRef.updataList([
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
:max="1000"
|
:max="1000"
|
||||||
:step="1"
|
:step="1"
|
||||||
is-input
|
is-input
|
||||||
:tipFormatter="(v) => `${scale.toFixed(0)}%`"
|
:tipFormatter="(v) => `${Number(scale)?.toFixed(0)}%`"
|
||||||
:value="scale"
|
:value="scale"
|
||||||
@input="inputFillScale"
|
@input="inputFillScale"
|
||||||
/>
|
/>
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<div class="repeat-setting-item">
|
<div class="repeat-setting-item">
|
||||||
<span class="label">Gap X</span>
|
<span class="label">Gap X</span>
|
||||||
<slider
|
<slider
|
||||||
:min="0"
|
:min="1"
|
||||||
:max="1000"
|
:max="1000"
|
||||||
:step="1"
|
:step="1"
|
||||||
is-input
|
is-input
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
<div class="repeat-setting-item">
|
<div class="repeat-setting-item">
|
||||||
<span class="label">Gap Y</span>
|
<span class="label">Gap Y</span>
|
||||||
<slider
|
<slider
|
||||||
:min="0"
|
:min="1"
|
||||||
:max="1000"
|
:max="1000"
|
||||||
:step="1"
|
:step="1"
|
||||||
is-input
|
is-input
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
const scale = computed(() => {
|
const scale = computed(() => {
|
||||||
// let scaleValue = props.object?.scale/10;
|
// let scaleValue = props.object?.scale/10;
|
||||||
// return props.object?.scale/10;
|
// return props.object?.scale/10;
|
||||||
return props.object?.scale[0] * 100;
|
return (props.object?.scale[0] * 100).toFixed(0);
|
||||||
});
|
});
|
||||||
const scalePrint = computed(() => {
|
const scalePrint = computed(() => {
|
||||||
let index = sketchWH.value[0] > sketchWH.value[1]?0:1;
|
let index = sketchWH.value[0] > sketchWH.value[1]?0:1;
|
||||||
|
|||||||
@@ -124,7 +124,11 @@ export default defineComponent({
|
|||||||
const handleResize = ()=>{
|
const handleResize = ()=>{
|
||||||
clearTimeout(time)
|
clearTimeout(time)
|
||||||
time = setTimeout(()=>{
|
time = setTimeout(()=>{
|
||||||
store.commit('DesignDetail/setDesignDetail',getDetailListData.designDetail)
|
let data = {
|
||||||
|
...getDetailListData.designDetail,
|
||||||
|
fromType:'resize',
|
||||||
|
}
|
||||||
|
store.commit('DesignDetail/setDesignDetail',data)
|
||||||
getDetailListDom.position?.updataPosition?.()
|
getDetailListDom.position?.updataPosition?.()
|
||||||
getDetailListDom.modelNav?.setItemPosition?.()
|
getDetailListDom.modelNav?.setItemPosition?.()
|
||||||
getDetailListDom.position?.updateRect?.()
|
getDetailListDom.position?.updateRect?.()
|
||||||
|
|||||||
@@ -189,11 +189,11 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
return { scaleX, scaleY, rotate };
|
return { scaleX, scaleY, rotate };
|
||||||
}
|
}
|
||||||
const initMoveableForSelected = () => {
|
const initMoveableForSelected = async (isDestroy:boolean = false) => {
|
||||||
// 销毁旧的实例
|
// 销毁旧的实例
|
||||||
if(selectItem.imgDomIndex == -1)return
|
if(selectItem.imgDomIndex == -1)return
|
||||||
if (moveableInstance.value) {
|
if (moveableInstance?.value?.destroy && !isDestroy) {
|
||||||
moveableInstance.value.destroy();
|
moveableInstance?.value?.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectedEl = elementRefs.value[selectItem.imgDomIndex];
|
const selectedEl = elementRefs.value[selectItem.imgDomIndex];
|
||||||
@@ -509,7 +509,7 @@ export default defineComponent({
|
|||||||
watch(()=>detailData.frontBack.front.length,(newValue,oldValue)=>{
|
watch(()=>detailData.frontBack.front.length,(newValue,oldValue)=>{
|
||||||
if(selectItem.selectDetail?.id)selectItem.imgDomIndex = detailData.frontBack.front.findIndex((item:any)=>item.id == selectItem.selectDetail?.id)
|
if(selectItem.selectDetail?.id)selectItem.imgDomIndex = detailData.frontBack.front.findIndex((item:any)=>item.id == selectItem.selectDetail?.id)
|
||||||
setTimeout(()=>{
|
setTimeout(()=>{
|
||||||
initMoveableForSelected()
|
initMoveableForSelected(oldValue == 0)
|
||||||
},100)
|
},100)
|
||||||
})
|
})
|
||||||
const setRevocation = async ()=>{
|
const setRevocation = async ()=>{
|
||||||
|
|||||||
@@ -18,10 +18,14 @@
|
|||||||
<div class="modal_title_text modal_title_text-header flex space-between">
|
<div class="modal_title_text modal_title_text-header flex space-between">
|
||||||
<div>{{ eventsDetail.title }}</div>
|
<div>{{ eventsDetail.title }}</div>
|
||||||
<div class="detail-btn" v-if="eventsDetail.id === 3" @click="openDetail">
|
<div class="detail-btn" v-if="eventsDetail.id === 3" @click="openDetail">
|
||||||
View Details
|
{{ $t("event.detail") }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal_title_text content" v-for="item in eventsDetail.textList">
|
<div
|
||||||
|
class="modal_title_text content"
|
||||||
|
v-for="item in eventsDetail.textList"
|
||||||
|
:class="{ award: eventsDetail.id === 3 }"
|
||||||
|
>
|
||||||
<div class="eventsDetail_content_right_btn_box">
|
<div class="eventsDetail_content_right_btn_box">
|
||||||
<div
|
<div
|
||||||
class="eventsDetail_content_right_btn"
|
class="eventsDetail_content_right_btn"
|
||||||
@@ -43,6 +47,7 @@
|
|||||||
v-detailText="introItem.text"
|
v-detailText="introItem.text"
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="tips" v-if="eventsDetail.tips">{{ eventsDetail.tips }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -70,6 +75,7 @@ import generalMenu from "@/component/HomePage/generalMenu.vue"
|
|||||||
import eventData from "@/assets/json/events.json"
|
import eventData from "@/assets/json/events.json"
|
||||||
import eventDataCn from "@/assets/json/events_cn.json"
|
import eventDataCn from "@/assets/json/events_cn.json"
|
||||||
import { useStore } from "vuex"
|
import { useStore } from "vuex"
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
generalMenu,
|
generalMenu,
|
||||||
@@ -82,6 +88,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
const { t, locale } = useI18n()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
let filter: any = reactive({
|
let filter: any = reactive({
|
||||||
@@ -118,11 +125,18 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
const openDetail = () => {
|
const openDetail = () => {
|
||||||
// window.open("https://aida-global-design-awards.com.hk", "_blank")
|
let language = locale.value === "ENGLISH" ? "en" : "cn"
|
||||||
router.push("/award/index")
|
let url = `https://aida-global-design-awards.com.hk/${language}`
|
||||||
|
// 如果是dev环境把域名换成http://192.168.31.198
|
||||||
|
|
||||||
|
if (import.meta.env.VITE_APP_BASE_URL === "https://develop.api.aida.com.hk") {
|
||||||
|
url += "?env=dev"
|
||||||
|
}
|
||||||
|
window.open(url, "_blank")
|
||||||
|
|
||||||
|
// router.push("/award/index")
|
||||||
}
|
}
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const { t, locale } = useI18n()
|
|
||||||
const currentLocale = locale.value
|
const currentLocale = locale.value
|
||||||
let eventLangData: any
|
let eventLangData: any
|
||||||
if (currentLocale == "ENGLISH") {
|
if (currentLocale == "ENGLISH") {
|
||||||
@@ -229,7 +243,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
.eventsDetail_content_right {
|
.eventsDetail_content_right {
|
||||||
.modal_title_text {
|
.modal_title_text {
|
||||||
letter-spacing: 0.4rem;
|
letter-spacing: 0.3rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
&-header {
|
&-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -261,18 +275,21 @@ export default defineComponent({
|
|||||||
.eventsDetail_content_right_btn_box {
|
.eventsDetail_content_right_btn_box {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-evenly;
|
justify-content: space-evenly;
|
||||||
.eventsDetail_content_right_btn {
|
// .eventsDetail_content_right_btn {
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
// .modal_title_text:last-child {
|
||||||
.modal_title_text:last-child {
|
// }
|
||||||
}
|
|
||||||
.modal_title_text:last-child::after {
|
.modal_title_text:last-child::after {
|
||||||
content: "";
|
content: "";
|
||||||
display: block;
|
display: block;
|
||||||
border-top: 3px solid;
|
border-top: 3px solid;
|
||||||
height: 6rem;
|
height: 6rem;
|
||||||
}
|
}
|
||||||
|
.modal_title_text.award:last-child:after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,4 +306,13 @@ export default defineComponent({
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
.tips{
|
||||||
|
color: rgba(0, 0, 0, 0.45);
|
||||||
|
font-size: var(--aida-fsize1-4);
|
||||||
|
font-weight: 400;
|
||||||
|
letter-spacing: 0.3rem;
|
||||||
|
}
|
||||||
|
.modal_title_text.content.award{
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -531,7 +531,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
const setSpeed = (item: any) => {
|
const setSpeed = (item: any) => {
|
||||||
speed.speedData = item
|
speed.speedData = {...item}
|
||||||
}
|
}
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (props.msg == 'Sketchboard') {
|
if (props.msg == 'Sketchboard') {
|
||||||
@@ -734,6 +734,8 @@ export default defineComponent({
|
|||||||
let maxImg = 8
|
let maxImg = 8
|
||||||
if (this.type_.type2 == 'Sketchboard') {
|
if (this.type_.type2 == 'Sketchboard') {
|
||||||
maxImg = 20
|
maxImg = 20
|
||||||
|
}else if(this.type_.type2 == 'Printboard'){
|
||||||
|
maxImg = 16
|
||||||
}
|
}
|
||||||
let parent: any = this.$parent
|
let parent: any = this.$parent
|
||||||
if (parent.isUseGenerate) {
|
if (parent.isUseGenerate) {
|
||||||
@@ -853,9 +855,7 @@ export default defineComponent({
|
|||||||
level2Type = this.sketchboardList?.[0]?.categoryValue
|
level2Type = this.sketchboardList?.[0]?.categoryValue
|
||||||
? this.sketchboardList[0].categoryValue
|
? this.sketchboardList[0].categoryValue
|
||||||
: ''
|
: ''
|
||||||
if (this.workspace.styleName) {
|
sloganText = `${this.workspace.styleName || 'all'},${sloganText}`
|
||||||
sloganText = `${this.workspace.styleName},${sloganText}`
|
|
||||||
}
|
|
||||||
} else if (this.upload.level1Type == 'Printboard') {
|
} else if (this.upload.level1Type == 'Printboard') {
|
||||||
level2Type = this.scene?.value
|
level2Type = this.scene?.value
|
||||||
if (level2Type == 'Slogan' && this.searchPictureName == '') {
|
if (level2Type == 'Slogan' && this.searchPictureName == '') {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
:get-container="() => $refs.upgradePlan"
|
:get-container="() => $refs.upgradePlan"
|
||||||
width="35%"
|
width="35%"
|
||||||
height="auto"
|
height="auto"
|
||||||
|
zIndex="9999999"
|
||||||
:maskClosable="false"
|
:maskClosable="false"
|
||||||
:centered="true"
|
:centered="true"
|
||||||
:closable="false"
|
:closable="false"
|
||||||
|
|||||||
@@ -205,7 +205,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="payment">
|
<div class="payment">
|
||||||
<div class="allocation">
|
<div class="allocation">
|
||||||
<div class="selectType">
|
<!-- <div class="selectType">
|
||||||
<div class="text">{{ $t('Renew.Payment') }}:</div>
|
<div class="text">{{ $t('Renew.Payment') }}:</div>
|
||||||
<label>
|
<label>
|
||||||
<input
|
<input
|
||||||
@@ -227,7 +227,7 @@
|
|||||||
/>
|
/>
|
||||||
{{ $t('Renew.Alipay') }}
|
{{ $t('Renew.Alipay') }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="gallery_btn gallery_btn_radius" @click="payment">
|
<div class="gallery_btn gallery_btn_radius" @click="payment">
|
||||||
{{ $t('upgradePlan.Continue') }}
|
{{ $t('upgradePlan.Continue') }}
|
||||||
|
|||||||
@@ -77,17 +77,10 @@ export default defineComponent({
|
|||||||
left: 50%;
|
left: 50%;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translate(-50%,-50%);
|
transform: translate(-50%,-50%);
|
||||||
width: 80%;
|
|
||||||
height: auto;
|
|
||||||
max-height: 80vh;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: max-content;
|
|
||||||
video{
|
video{
|
||||||
width: 100%;
|
|
||||||
max-height:80vh;
|
max-height:80vh;
|
||||||
height: 100%;
|
max-width:80vw;
|
||||||
object-fit: contain;
|
|
||||||
width: max-content;
|
|
||||||
}
|
}
|
||||||
.general_video_btn{
|
.general_video_btn{
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|||||||
@@ -517,6 +517,7 @@ defineExpose({
|
|||||||
/* 图片网格 */
|
/* 图片网格 */
|
||||||
.image-grid {
|
.image-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
align-content: start;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
|||||||
@@ -379,6 +379,7 @@ export default defineComponent({
|
|||||||
setup(props,{emit}) {
|
setup(props,{emit}) {
|
||||||
const {t,locale} = useI18n()
|
const {t,locale} = useI18n()
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
const route = useRoute()
|
||||||
const editDesignType = reactive({
|
const editDesignType = reactive({
|
||||||
selectProbject:computed(()=>{
|
selectProbject:computed(()=>{
|
||||||
return store.state.Workspace.probjects
|
return store.state.Workspace.probjects
|
||||||
@@ -624,6 +625,7 @@ export default defineComponent({
|
|||||||
collItemSize.collTime = setTimeout(()=>{
|
collItemSize.collTime = setTimeout(()=>{
|
||||||
nextTick(()=>{
|
nextTick(()=>{
|
||||||
let parentWidth = likeItemDom.value.parentElement.offsetWidth
|
let parentWidth = likeItemDom.value.parentElement.offsetWidth
|
||||||
|
if(parentWidth == 0)return
|
||||||
collItemSize.widthValue.value = collItemSize.widthValue.value == -1?100:collItemSize.widthValue.value
|
collItemSize.widthValue.value = collItemSize.widthValue.value == -1?100:collItemSize.widthValue.value
|
||||||
collItemSize.widthValue.value = collItemSize.widthValue.value > parentWidth?parentWidth:collItemSize.widthValue.value
|
collItemSize.widthValue.value = collItemSize.widthValue.value > parentWidth?parentWidth:collItemSize.widthValue.value
|
||||||
collItemSize.collValue = Math.floor(parentWidth / collItemSize.widthValue.value)
|
collItemSize.collValue = Math.floor(parentWidth / collItemSize.widthValue.value)
|
||||||
@@ -634,7 +636,6 @@ export default defineComponent({
|
|||||||
|
|
||||||
collItemSize.collStyle.width = (collItemDom.value.offsetWidth - 30) / 3 * collItemSize.scale[0] + 'px'
|
collItemSize.collStyle.width = (collItemDom.value.offsetWidth - 30) / 3 * collItemSize.scale[0] + 'px'
|
||||||
collItemSize.collStyle.height = (collItemDom.value.offsetWidth - 30) / 3 * collItemSize.scale[1] + 'px'
|
collItemSize.collStyle.height = (collItemDom.value.offsetWidth - 30) / 3 * collItemSize.scale[1] + 'px'
|
||||||
|
|
||||||
collItemSize.likeStyle.width = collItemSize.itemStyle.width + 'px'
|
collItemSize.likeStyle.width = collItemSize.itemStyle.width + 'px'
|
||||||
collItemSize.likeStyle.height = collItemSize.itemStyle.height + 'px'
|
collItemSize.likeStyle.height = collItemSize.itemStyle.height + 'px'
|
||||||
let elArr = likeItemDom.value.children
|
let elArr = likeItemDom.value.children
|
||||||
@@ -744,6 +745,12 @@ export default defineComponent({
|
|||||||
"userLikeId": likeItem.id
|
"userLikeId": likeItem.id
|
||||||
}
|
}
|
||||||
arrData.push(obj)
|
arrData.push(obj)
|
||||||
|
designData.selectLikeDesign.forEach((v:any)=>{
|
||||||
|
if(v.id === likeItem.id){
|
||||||
|
v.oldSort = v.sort
|
||||||
|
v.sort = likeItem.sort
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
let data = {
|
let data = {
|
||||||
"userLikeGroupId": userGroupId.value,
|
"userLikeGroupId": userGroupId.value,
|
||||||
@@ -1303,9 +1310,9 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const parents = designData.selectLikeDesign.filter((item:any) => item.resultType === 'Design');
|
const parents = designData.selectLikeDesign.filter((item:any) => item.resultType === 'Design').filter((item:any) => likeDesignCollectionList.value.some((v:any) => (v.id === item.id)));
|
||||||
parents.map((parent:any) => {
|
parents.map((parent:any) => {
|
||||||
parent.sort = parent.oldSort||parent.sort
|
parent.sort = likeDesignCollectionList.value.find((v:any) => v.id === parent.id)?.sort || parent.oldSort||parent.sort
|
||||||
delete parent.oldSort
|
delete parent.oldSort
|
||||||
return {
|
return {
|
||||||
...parent,
|
...parent,
|
||||||
@@ -1532,7 +1539,7 @@ export default defineComponent({
|
|||||||
this.observerData.time = setTimeout(()=>{
|
this.observerData.time = setTimeout(()=>{
|
||||||
|
|
||||||
this.setSystemDesigner(0)
|
this.setSystemDesigner(0)
|
||||||
this.setDesignItemStyle()
|
// this.setDesignItemStyle()
|
||||||
},100)
|
},100)
|
||||||
// const { width } = entry.contentRect;
|
// const { width } = entry.contentRect;
|
||||||
}
|
}
|
||||||
@@ -1930,6 +1937,7 @@ export default defineComponent({
|
|||||||
this.disLikeLoading = true;
|
this.disLikeLoading = true;
|
||||||
Https.axiosPost(Https.httpUrls.designDislike, data)
|
Https.axiosPost(Https.httpUrls.designDislike, data)
|
||||||
.then((rv: any) => {
|
.then((rv: any) => {
|
||||||
|
console.log(rv)
|
||||||
if (rv) {
|
if (rv) {
|
||||||
this.recycleDomHidden = true
|
this.recycleDomHidden = true
|
||||||
this.store.commit("addDesignCollectionList", [design]);
|
this.store.commit("addDesignCollectionList", [design]);
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ export default defineComponent({
|
|||||||
allCollectionStr.forEach((itemStr:any)=>{
|
allCollectionStr.forEach((itemStr:any)=>{
|
||||||
let list = [] as any
|
let list = [] as any
|
||||||
allCollection[itemStr.value].forEach((imgItem)=>{
|
allCollection[itemStr.value].forEach((imgItem)=>{
|
||||||
list.push({url:imgItem.url || imgItem.imgUrl})
|
list.push({url:imgItem?.url || imgItem?.imgUrl})
|
||||||
})
|
})
|
||||||
let obj = {
|
let obj = {
|
||||||
value:itemStr.value,
|
value:itemStr.value,
|
||||||
|
|||||||
@@ -196,9 +196,9 @@ export default defineComponent({
|
|||||||
type:rv.process == 'SERIES_DESIGN'?'seriesDesign':'singleProductDesign',
|
type:rv.process == 'SERIES_DESIGN'?'seriesDesign':'singleProductDesign',
|
||||||
httpType:rv.process,//项目类型
|
httpType:rv.process,//项目类型
|
||||||
ageGroup:rv.workspaceVO?.ageGroup,
|
ageGroup:rv.workspaceVO?.ageGroup,
|
||||||
style:rv.workspaceVO?.style,
|
style:rv.workspaceVO?.style || '',
|
||||||
styleId:rv.workspaceVO?.styleId,
|
styleId:rv.workspaceVO?.styleId || null,
|
||||||
styleName:rv.workspaceVO?.styleName,
|
styleName:rv.workspaceVO?.styleName || '',
|
||||||
sex:rv.workspaceVO?.sex,
|
sex:rv.workspaceVO?.sex,
|
||||||
userBrandDnaImg:rv.workspaceVO?.userBrandDnaImg,
|
userBrandDnaImg:rv.workspaceVO?.userBrandDnaImg,
|
||||||
userBrandDnaName:rv.workspaceVO?.userBrandDnaName,
|
userBrandDnaName:rv.workspaceVO?.userBrandDnaName,
|
||||||
|
|||||||
@@ -94,9 +94,9 @@ export default defineComponent({
|
|||||||
type:rv.process == 'SERIES_DESIGN'?'seriesDesign':'singleProductDesign',
|
type:rv.process == 'SERIES_DESIGN'?'seriesDesign':'singleProductDesign',
|
||||||
httpType:rv.process,//项目类型
|
httpType:rv.process,//项目类型
|
||||||
ageGroup:rv.workspaceVO.ageGroup,
|
ageGroup:rv.workspaceVO.ageGroup,
|
||||||
style:rv.workspaceVO.style,
|
style:rv.workspaceVO.style || '',
|
||||||
styleId:rv.workspaceVO.styleId,
|
styleId:rv.workspaceVO.styleId || null,
|
||||||
styleName:rv.workspaceVO.styleName,
|
styleName:rv.workspaceVO.styleName || '',
|
||||||
sex:rv.workspaceVO.sex,
|
sex:rv.workspaceVO.sex,
|
||||||
userBrandDnaImg:rv.workspaceVO.userBrandDnaImg,
|
userBrandDnaImg:rv.workspaceVO.userBrandDnaImg,
|
||||||
userBrandDnaName:rv.workspaceVO.userBrandDnaName,
|
userBrandDnaName:rv.workspaceVO.userBrandDnaName,
|
||||||
|
|||||||
@@ -41,10 +41,10 @@
|
|||||||
<div class="center">{{ selectObject?.styleName?selectObject?.styleName:$t('Header.All') }}</div>
|
<div class="center">{{ selectObject?.styleName?selectObject?.styleName:$t('Header.All') }}</div>
|
||||||
<div class="gallery_btn" @click="setStyle">{{ $t('Habit.Select') }}</div>
|
<div class="gallery_btn" @click="setStyle">{{ $t('Habit.Select') }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="style brand marginBottom">
|
<!-- <div class="style brand marginBottom">
|
||||||
<div class="text">{{$t('Habit.Brand')}}:</div>
|
<div class="text">{{$t('Habit.Brand')}}:</div>
|
||||||
<div class="gallery_btn" @click="setBrandDNA">{{ $t('Habit.Select') }}</div>
|
<div class="gallery_btn" @click="setBrandDNA">{{ $t('Habit.Select') }}</div>
|
||||||
</div>
|
</div> -->
|
||||||
<div class="brandImg" v-if="selectObject.userBrandDna"><img :src="selectObject.userBrandDnaImg"></div>
|
<div class="brandImg" v-if="selectObject.userBrandDna"><img :src="selectObject.userBrandDnaImg"></div>
|
||||||
<div class="brandDNAStrenght marginBottom" v-if="selectObject.userBrandDna">
|
<div class="brandDNAStrenght marginBottom" v-if="selectObject.userBrandDna">
|
||||||
<div class="text" style="font-size: 1.6rem;">
|
<div class="text" style="font-size: 1.6rem;">
|
||||||
@@ -179,9 +179,9 @@ export default defineComponent({
|
|||||||
dataDom.brandDNA.init(data.selectObject);
|
dataDom.brandDNA.init(data.selectObject);
|
||||||
}
|
}
|
||||||
const setWorkspaceStyle = (value:any)=>{
|
const setWorkspaceStyle = (value:any)=>{
|
||||||
data.selectObject.styleName = value.name
|
data.selectObject.styleName = value.name || ''
|
||||||
data.selectObject.style = value.value
|
data.selectObject.style = value.value || ''
|
||||||
data.selectObject.styleId = value.id
|
data.selectObject.styleId = value.id || null
|
||||||
// store.commit('setProbject',data)
|
// store.commit('setProbject',data)
|
||||||
}
|
}
|
||||||
const setWorkspaceBrandDNA = (value:any)=>{
|
const setWorkspaceBrandDNA = (value:any)=>{
|
||||||
@@ -238,9 +238,9 @@ export default defineComponent({
|
|||||||
// type:rv.process == 'SERIES_DESIGN'?'seriesDesign':'singleProductDesign',
|
// type:rv.process == 'SERIES_DESIGN'?'seriesDesign':'singleProductDesign',
|
||||||
// httpType:rv.process,//项目类型
|
// httpType:rv.process,//项目类型
|
||||||
ageGroup:rv.workspaceVO?.ageGroup,
|
ageGroup:rv.workspaceVO?.ageGroup,
|
||||||
style:rv.workspaceVO?.style,
|
style:rv.workspaceVO?.style || '',
|
||||||
styleId:rv.workspaceVO?.styleId,
|
styleId:rv.workspaceVO?.styleId || null,
|
||||||
styleName:rv.workspaceVO?.styleName,
|
styleName:rv.workspaceVO?.styleName || '',
|
||||||
sex:rv.workspaceVO?.sex,
|
sex:rv.workspaceVO?.sex,
|
||||||
userBrandDnaImg:rv.workspaceVO?.userBrandDnaImg,
|
userBrandDnaImg:rv.workspaceVO?.userBrandDnaImg,
|
||||||
userBrandDnaName:rv.workspaceVO?.userBrandDnaName,
|
userBrandDnaName:rv.workspaceVO?.userBrandDnaName,
|
||||||
|
|||||||
@@ -352,7 +352,8 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
isDesignPage: {
|
isDesignPage: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
|
required:false
|
||||||
},
|
},
|
||||||
source: {
|
source: {
|
||||||
type: String,
|
type: String,
|
||||||
@@ -773,7 +774,7 @@ export default defineComponent({
|
|||||||
data.lastSelectImg = res.data
|
data.lastSelectImg = res.data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 同步尾帧文件列表到全局 store
|
// 同步尾帧文件列表到全局 store(使用专门的 lastFrameList)
|
||||||
store.commit('setPoseTransferLastFrameList', {
|
store.commit('setPoseTransferLastFrameList', {
|
||||||
str: 'set',
|
str: 'set',
|
||||||
list: [file]
|
list: [file]
|
||||||
@@ -989,6 +990,7 @@ export default defineComponent({
|
|||||||
if (data.lastSelectImg?.id === item.id) {
|
if (data.lastSelectImg?.id === item.id) {
|
||||||
data.lastSelectImg = {}
|
data.lastSelectImg = {}
|
||||||
}
|
}
|
||||||
|
// 使用专门的 lastFrameList mutation 清空列表
|
||||||
store.commit('setPoseTransferLastFrameList')
|
store.commit('setPoseTransferLastFrameList')
|
||||||
} else {
|
} else {
|
||||||
// 如果删除的是当前选中的首帧,清空选中状态
|
// 如果删除的是当前选中的首帧,清空选中状态
|
||||||
@@ -1176,10 +1178,10 @@ export default defineComponent({
|
|||||||
firstFrameList.value = store.state.HomeStoreModule.uploadElement.filter(
|
firstFrameList.value = store.state.HomeStoreModule.uploadElement.filter(
|
||||||
item => item.frameType === 'first'
|
item => item.frameType === 'first'
|
||||||
)
|
)
|
||||||
|
// 注意:尾帧通过专门的 watch (lastFrameList) 监听,不需要从这里过滤
|
||||||
lastFrameList.value = store.state.HomeStoreModule.uploadElement.filter(
|
// lastFrameList.value = store.state.HomeStoreModule.uploadElement.filter(
|
||||||
item => item.frameType === 'last'
|
// item => item.frameType === 'last'
|
||||||
)
|
// )
|
||||||
// 更新 showFirstFrameList 中项的选中状态
|
// 更新 showFirstFrameList 中项的选中状态
|
||||||
showFirstFrameList.value.forEach((listItem: any) => {
|
showFirstFrameList.value.forEach((listItem: any) => {
|
||||||
if (listItem.id == data.selectImg.id) {
|
if (listItem.id == data.selectImg.id) {
|
||||||
|
|||||||
@@ -102,9 +102,9 @@ setup(props,{emit}) {
|
|||||||
// if(habitSetStyleData.styleList.length == 0){
|
// if(habitSetStyleData.styleList.length == 0){
|
||||||
// getStyleList()
|
// getStyleList()
|
||||||
// }
|
// }
|
||||||
oldDataId = data.styleId
|
oldDataId = data.styleId || null
|
||||||
habitSetStyleData.selectStyle.id = data.styleId
|
habitSetStyleData.selectStyle.id = data.styleId || null
|
||||||
habitSetStyleData.selectStyle.name = data.styleName
|
habitSetStyleData.selectStyle.name = data.styleName || ''
|
||||||
// habitSetStyleData.selectStyleId = 'feng2'
|
// habitSetStyleData.selectStyleId = 'feng2'
|
||||||
}
|
}
|
||||||
let setCover = (item:any)=>{
|
let setCover = (item:any)=>{
|
||||||
@@ -258,6 +258,7 @@ methods: {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.content_bottom_item:nth-child(4n){
|
.content_bottom_item:nth-child(4n){
|
||||||
|
|||||||
269
src/lang/cn.ts
269
src/lang/cn.ts
@@ -231,8 +231,7 @@ export default {
|
|||||||
colorboard: '调色板',
|
colorboard: '调色板',
|
||||||
sketchboard: '线稿板',
|
sketchboard: '线稿板',
|
||||||
mannequins: '人体模型',
|
mannequins: '人体模型',
|
||||||
masnnequinHint:
|
masnnequinHint: '您使用的模特与当前的衣服不匹配,这将导致生成的模型不使用所选的衣服',
|
||||||
'您使用的模特与当前的衣服不匹配,这将导致生成的模型不使用所选的衣服',
|
|
||||||
FinalizeCollection: '完成系列',
|
FinalizeCollection: '完成系列',
|
||||||
jsContent1: '您必须选择一种或多种颜色进行下一步。',
|
jsContent1: '您必须选择一种或多种颜色进行下一步。',
|
||||||
jsContent2: '您必须选择一种或多种颜色进行下一步。',
|
jsContent2: '您必须选择一种或多种颜色进行下一步。',
|
||||||
@@ -979,13 +978,17 @@ export default {
|
|||||||
subscriptionRenewal: '没有自动续订的订阅计划.'
|
subscriptionRenewal: '没有自动续订的订阅计划.'
|
||||||
},
|
},
|
||||||
guide: {
|
guide: {
|
||||||
guide1: '在<strong>工作空间</strong>中,您可以个性化您的设计设置,包括选择适用于男装或女装的设计,以及选择用于创作的人体模型。',
|
guide1:
|
||||||
|
'在<strong>工作空间</strong>中,您可以个性化您的设计设置,包括选择适用于男装或女装的设计,以及选择用于创作的人体模型。',
|
||||||
guide2: '选择您要设计的服装性别。',
|
guide2: '选择您要设计的服装性别。',
|
||||||
guide3: '在此更改人体模型。',
|
guide3: '在此更改人体模型。',
|
||||||
guide4: '您目前可以从我们的系统库中选择人体模型。稍后,您还可以在注册自己的人体模型后从用户库中进行选择。',
|
guide4:
|
||||||
|
'您目前可以从我们的系统库中选择人体模型。稍后,您还可以在注册自己的人体模型后从用户库中进行选择。',
|
||||||
guide5: '在这里开始您的创意之旅。 ',
|
guide5: '在这里开始您的创意之旅。 ',
|
||||||
guide6: '对于情绪板、印花或服装,我们提供三种不同的图片添加方法。第一种选择是<strong>上传</strong>,允许您直接从本地设备上传。',
|
guide6:
|
||||||
guide7: '第二种方法是从您的<strong>收藏</strong>中选择。<br> 您可能会注意到您的库页面目前是空的;不必担心。您上传的所有图像都将自动添加到您的库中。将来,您无需每次上传,只需从您的库中选择即可。',
|
'对于情绪板、印花或服装,我们提供三种不同的图片添加方法。第一种选择是<strong>上传</strong>,允许您直接从本地设备上传。',
|
||||||
|
guide7:
|
||||||
|
'第二种方法是从您的<strong>收藏</strong>中选择。<br> 您可能会注意到您的库页面目前是空的;不必担心。您上传的所有图像都将自动添加到您的库中。将来,您无需每次上传,只需从您的库中选择即可。',
|
||||||
guide8: '第三种方法是使用最新的图像生成技术<strong>生成</strong>图像。',
|
guide8: '第三种方法是使用最新的图像生成技术<strong>生成</strong>图像。',
|
||||||
guide9: '输入捕捉您希望表达的情绪的关键词,然后单击<strong>生成</strong>按钮。',
|
guide9: '输入捕捉您希望表达的情绪的关键词,然后单击<strong>生成</strong>按钮。',
|
||||||
guide10: '为您的心情板选择两个图像。',
|
guide10: '为您的心情板选择两个图像。',
|
||||||
@@ -1147,7 +1150,7 @@ export default {
|
|||||||
CanvasTitle: {
|
CanvasTitle: {
|
||||||
ModifySketch: '修改草图',
|
ModifySketch: '修改草图',
|
||||||
ModifyItem: '修改单品',
|
ModifyItem: '修改单品',
|
||||||
RedGreen: '编辑前片后片'
|
RedGreen: '编辑前片后片',
|
||||||
},
|
},
|
||||||
Canvas: {
|
Canvas: {
|
||||||
Canvas: '画布',
|
Canvas: '画布',
|
||||||
@@ -1505,7 +1508,7 @@ export default {
|
|||||||
PointSelection: '点选',
|
PointSelection: '点选',
|
||||||
MarqueeSelection: '框选',
|
MarqueeSelection: '框选',
|
||||||
BrushSelection: '画笔',
|
BrushSelection: '画笔',
|
||||||
Erase: '擦除'
|
Erase: '擦除',
|
||||||
},
|
},
|
||||||
speedList: {
|
speedList: {
|
||||||
High: '高级',
|
High: '高级',
|
||||||
@@ -1529,7 +1532,8 @@ export default {
|
|||||||
LiquefactionTool: '液化工具'
|
LiquefactionTool: '液化工具'
|
||||||
},
|
},
|
||||||
event: {
|
event: {
|
||||||
back: '返回'
|
back: '返回',
|
||||||
|
detail:'查看详情'
|
||||||
},
|
},
|
||||||
admin: {
|
admin: {
|
||||||
allUser: '所有用户',
|
allUser: '所有用户',
|
||||||
@@ -1611,7 +1615,8 @@ export default {
|
|||||||
ForgotPassword: '忘记密码',
|
ForgotPassword: '忘记密码',
|
||||||
Welcome: '欢迎来到',
|
Welcome: '欢迎来到',
|
||||||
AiDA: 'AiDA',
|
AiDA: 'AiDA',
|
||||||
Slogan: 'AiDA是一个业界首创的平台,致力于赋能时装设计师融汇灵感,人机协同,共创原创设计。',
|
Slogan:
|
||||||
|
'AiDA是一个业界首创的平台,致力于赋能时装设计师融汇灵感,人机协同,共创原创设计。',
|
||||||
LoginMethod: '使用以下方式登录:',
|
LoginMethod: '使用以下方式登录:',
|
||||||
Individual: '个人账号',
|
Individual: '个人账号',
|
||||||
Academic: '学术账号',
|
Academic: '学术账号',
|
||||||
@@ -1621,7 +1626,7 @@ export default {
|
|||||||
AgreePolicies: '请勾选条款、隐私政策和费用',
|
AgreePolicies: '请勾选条款、隐私政策和费用',
|
||||||
PasswordConditions: '您必须满足所有密码条件才能注册',
|
PasswordConditions: '您必须满足所有密码条件才能注册',
|
||||||
LoginWithGoogle: '使用谷歌账号登录',
|
LoginWithGoogle: '使用谷歌账号登录',
|
||||||
LoginWithWechat: '使用微信登录'
|
LoginWithWechat: '使用微信登录',
|
||||||
},
|
},
|
||||||
LoginPersonal: {
|
LoginPersonal: {
|
||||||
Email: '邮箱',
|
Email: '邮箱',
|
||||||
@@ -1714,247 +1719,5 @@ export default {
|
|||||||
IncorrectEmailFormat: '请输入正确的邮箱格式',
|
IncorrectEmailFormat: '请输入正确的邮箱格式',
|
||||||
CompleteVerificationCode: '请输入完整的验证码',
|
CompleteVerificationCode: '请输入完整的验证码',
|
||||||
PleaseEnterYourAccountNumberOrPassword: '请输入您的账号或密码'
|
PleaseEnterYourAccountNumberOrPassword: '请输入您的账号或密码'
|
||||||
},
|
|
||||||
AwardsPage: {
|
|
||||||
submitApplication: '提交申请',
|
|
||||||
applicationDeadline: '申请期限:2026年7月15日',
|
|
||||||
howToApply: '申请方法',
|
|
||||||
stepByStep: '步骤指南',
|
|
||||||
step1Title: '1. 成为 AiDA 订阅用户',
|
|
||||||
step1Desc:
|
|
||||||
'所有申请者在提交时必须是\n活跃的AiDA 订阅用户。\n您可以选择按月或按年订阅。',
|
|
||||||
step2Title: '2. 通过 AiDA 设计您的作品',
|
|
||||||
step2Desc: '申请者必须仅使用AiDA\n平台完成设计作品。',
|
|
||||||
step2ListTitle: '您的作品应清楚体现以下内容:',
|
|
||||||
step2List: [
|
|
||||||
'· AiDA在创作中的应用方式',
|
|
||||||
'· 您的设计理念和创意方向',
|
|
||||||
'· AI与人类创意的融合'
|
|
||||||
],
|
|
||||||
step3Title: '3. 准备提交材料',
|
|
||||||
processVideo: '创作过程视频',
|
|
||||||
processVideoDesc: '请提供一段屏幕录制视频,展示您\n使用AiDA的创作过程。',
|
|
||||||
videoRequirements: '视频要求:',
|
|
||||||
videoFormat: '格式:MP4',
|
|
||||||
videoResolution: '分辨率:1080×1920px',
|
|
||||||
videoDuration: '时长:最长1分钟',
|
|
||||||
videoSize: '文件大小:不超过20MB',
|
|
||||||
fileName: '文件命名',
|
|
||||||
fileNameDesc: 'AiDAGlobalDesignAward\n2026_[你的名字]',
|
|
||||||
designPortfolio: '设计作品集(PDF)',
|
|
||||||
submitPdf: '提交一份包含以下内容的单一PDF文件:',
|
|
||||||
requiredStructure: '',
|
|
||||||
pdfDesignTitle: '设计标题',
|
|
||||||
pdfMoodboard: '灵感板,情绪板',
|
|
||||||
pdfConcept: '概念说明',
|
|
||||||
pdfConceptDesc: '(说明如何使用AiDA进行设计创作)',
|
|
||||||
pdfRequirements: 'PDF要求:',
|
|
||||||
pdfMaxPages: '最多15页',
|
|
||||||
pdfMaxSize: '最大文件大小:不超过20MB',
|
|
||||||
pdfLanguage: '语言:英文,或本国语言附带英文翻译',
|
|
||||||
step4Title: '4. 决赛入围选手提交要求',
|
|
||||||
step4Subtitle: '(前20名设计师)',
|
|
||||||
step4Desc: '入围的20名决赛选手需提交实体服装以供最终评审。',
|
|
||||||
finalistPieces: '件数:1件套装',
|
|
||||||
finalistBasedOn: '服装要求:必须根据提交的AiDA生成设计制作',
|
|
||||||
finalistShipping: '运输说明:\n将由Code-create提供',
|
|
||||||
bloomYourCreativity: '绽放你的创造力',
|
|
||||||
themeOf2026: '赛事主题',
|
|
||||||
bloomText: {
|
|
||||||
desc1: {
|
|
||||||
regular1: '',
|
|
||||||
bold1: 'AiDA全球设计奖2026',
|
|
||||||
regular2: '是由全球领先的AI时尚解决方案提供商',
|
|
||||||
bold2: ' Code-create ',
|
|
||||||
regular3: '主办的',
|
|
||||||
bold3: '国际设计竞赛,\n',
|
|
||||||
regular4:
|
|
||||||
'旨在庆祝人工只能赋能下的未来创意。该赛事汇聚来自世界各地的设计师,\n将AI视为创意伙伴,突破传统时尚边界,探索技术与人类想象力结合的无限可能。',
|
|
||||||
bold4: '',
|
|
||||||
regular5: ''
|
|
||||||
},
|
|
||||||
desc2: {
|
|
||||||
regular1: '本届大赛以',
|
|
||||||
bold1: '"想象遇见创新,创意绽放"',
|
|
||||||
regular2:
|
|
||||||
'为主题,邀请参赛者将大胆创意转化为非凡设计,\n在 AI 辅助下实现艺术与科技的完美融合。AiDA 鼓励设计师突破常规,挑战时尚边界,\n并通过平台展示才华,与全球同行、行业领袖及 AI 专家建立深度联系,共同探索未来设计的可能。'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
panelOfJudges: '终审评委团',
|
|
||||||
expertise: '权威阵容',
|
|
||||||
judgesHat: {
|
|
||||||
jae: 'Code‑Create 韩国分公司总监\nBesfxxk 创意总监',
|
|
||||||
diego: 'OnTheList(香港)\n联合创始人兼首席执行官',
|
|
||||||
gregory: 'Gabriela Hearst\n(意大利)高级设计师',
|
|
||||||
vincenzo: '《南华早报》Style 杂志\n(香港)主编',
|
|
||||||
tim: '现代传播集团\n(上海)时尚总监',
|
|
||||||
desmond: '《Vogue》\n(新加坡)主编'
|
|
||||||
},
|
|
||||||
awardPrizes: '奖项与奖金',
|
|
||||||
recognition: '荣誉认可',
|
|
||||||
grandMoney: '5,000美元',
|
|
||||||
goldMoney: '3,000美元',
|
|
||||||
silverMoney: '1,000美元',
|
|
||||||
grandAwards: '最高奖项',
|
|
||||||
goldAwards: '金奖',
|
|
||||||
silverAwards: '银奖',
|
|
||||||
finalists: '决赛选手',
|
|
||||||
cashAward: '现金奖励',
|
|
||||||
awardCertificate: '获奖证书',
|
|
||||||
globalMediaExposure: '全球媒体曝光',
|
|
||||||
awardCertification: '获奖认证',
|
|
||||||
TravelAllowance: '差旅补贴',
|
|
||||||
selectionCriteria: '作品评选',
|
|
||||||
evaluation: '考量标准',
|
|
||||||
originality: '原创性',
|
|
||||||
originalityDesc:
|
|
||||||
'作品应体现设计师的独到视角与创新方法,展现突破常规的创意与实验性设计。',
|
|
||||||
creativity: '创造力',
|
|
||||||
creativityDesc:
|
|
||||||
'作品应展现设计师的艺术视野与卓越设计水准,体现高水平的创意表达与专业执行力。',
|
|
||||||
aidaIntegration: 'AiDA 创意整合程度',
|
|
||||||
aidaIntegrationDesc:
|
|
||||||
'作品应充分利用 AiDA 功能, 展现 AI 辅助创作在设计中的 有效应用与创新整合。',
|
|
||||||
execution: '样衣做工',
|
|
||||||
executionDesc:
|
|
||||||
'作品应具备高水平的呈现质量与精湛的技术工艺,体现专业执行力与细节把控能力。',
|
|
||||||
totalCashPrizes: '最高可达9,000美元',
|
|
||||||
totalCashPrizesLabel: '现金奖励总额',
|
|
||||||
globalMediaExpose: '全球媒体曝光',
|
|
||||||
globalMediaExposeLabel: '由国际顶级媒体平台展示',
|
|
||||||
networkingOpportunities: '链接全球行业人脉',
|
|
||||||
networkingOpportunitiesLabel: '对接设计师与行业领军人物',
|
|
||||||
awardCeremonyHongKong: '香港颁奖盛会',
|
|
||||||
awardCeremonyLabel: '入围者享有差旅支持',
|
|
||||||
competitionTimeline: '赛事时间表',
|
|
||||||
shapingTheFuture: '重要节点',
|
|
||||||
timelineApplicationLabel: '申请期限',
|
|
||||||
timelineDeadlineLabel: '',
|
|
||||||
timeJul15: '7月15日',
|
|
||||||
applicationDeadlineDesc: '申请截止日期及\n作品审核流程开始',
|
|
||||||
twentyFinalistsAnnounced: '20名入围者揭晓',
|
|
||||||
announcedLabel: '',
|
|
||||||
timeAug30: '8月30日',
|
|
||||||
twentyFinalistsDesc: '公布进入终评阶段的 20 名入围者',
|
|
||||||
finalistSubmission: '入围设计作品',
|
|
||||||
submissionLabel: '提交最后期限',
|
|
||||||
timeSept30: '9月30日',
|
|
||||||
finalistSubmissionDesc: '入围者上传完成的设计\n作品以进行终评',
|
|
||||||
receivingOutfits: '入围者',
|
|
||||||
fromFinalistsLabel: '提交成衣',
|
|
||||||
timeOctober: '10月',
|
|
||||||
receivingOutfitsDesc: 'AiDA 接收每位入围\n的1套实物服装',
|
|
||||||
awardCeremony: '奖项颁发仪式',
|
|
||||||
ceremonyLabel: '',
|
|
||||||
timeNov12: '11月12日',
|
|
||||||
awardCeremonyDesc: '颁奖盛典与设计师社\n群聚会 – Soho House',
|
|
||||||
submissionSuccessful: '提交成功',
|
|
||||||
submissionSuccessfulDesc:
|
|
||||||
'请在 AiDA 平台内的消息中查看您提交的信息。如有需要,您可以进行修改。\n比赛的最新消息和结果将通过邮箱发送。',
|
|
||||||
deadlinePassed: '申请截止日期已过',
|
|
||||||
deadlinePassedDesc:
|
|
||||||
'AiDA 全球设计奖 2026 的作品提交已截止。\n我们不再接受新的报名。',
|
|
||||||
uploadInProgress: '上传中…',
|
|
||||||
uploadSuccess: '上传成功',
|
|
||||||
uploadFailed: '上传失败',
|
|
||||||
pdfFileTip: 'PDF文件,不超过20MB',
|
|
||||||
videoFileTip: '视频文件(MP4, MOV),1080p,不超过100MB',
|
|
||||||
wechatTitle: '微信公众号',
|
|
||||||
wechatDesc: '请使用微信扫描二维码'
|
|
||||||
},
|
|
||||||
AwardApply: {
|
|
||||||
// 页面主标题区域
|
|
||||||
applicationForm: '参赛表格',
|
|
||||||
emailVerification: '邮箱验证',
|
|
||||||
aidaUsersOnly: '仅限 AiDA 用户',
|
|
||||||
slogan: '绽放你的创意 • AiDA 全球设计奖 2026',
|
|
||||||
// 邮箱验证部分
|
|
||||||
emailAddress: '邮箱',
|
|
||||||
sendCode: '发送验证码',
|
|
||||||
pleaseUseRegisteredEmail: '请使用您在 AiDA 注册的邮箱',
|
|
||||||
// 个人信息部分
|
|
||||||
personalInformation: '个人信息',
|
|
||||||
tellUsAboutYourself: '自我介绍',
|
|
||||||
firstName: '名',
|
|
||||||
lastName: '姓',
|
|
||||||
gender: '性别',
|
|
||||||
occupation: '职业',
|
|
||||||
age: '年龄',
|
|
||||||
countryRegionCity: '国家或地区及城市',
|
|
||||||
phoneNumber: '电话号码',
|
|
||||||
portfolioUrl: '作品集网址或Instagram(可选)',
|
|
||||||
// 性别选项
|
|
||||||
male: '男',
|
|
||||||
female: '女',
|
|
||||||
other: '其他',
|
|
||||||
// 设计信息部分
|
|
||||||
designInformation: '作品信息',
|
|
||||||
shareYourCreativeVision: '分享您的创意构想',
|
|
||||||
designTitle: '作品标题',
|
|
||||||
designDescription: '设计说明',
|
|
||||||
designDescriptionPlaceholder: '请简要描述您的设计理念、灵感和创意方向...',
|
|
||||||
// 提交文件部分
|
|
||||||
submissionFiles: '作品上传',
|
|
||||||
uploadYourDesignMaterials: '上传你的设计材料',
|
|
||||||
submissionRequirements: '提交要求',
|
|
||||||
pdfRequirement: `单独PDF文件\n 作品标题、灵感板及情绪板,设计说明\n+ 4套服装设计及材料说明(页数:最多15页)`,
|
|
||||||
rightContent: {
|
|
||||||
format: '格式:单个 PDF 文件,最多15页,最大 20MB',
|
|
||||||
video: `视频:创作过程,分辨率1080×1920 像素\n(9:16 纵向比例),最长 60 秒`
|
|
||||||
},
|
|
||||||
// PDF 上传
|
|
||||||
uploadPdfTitle: '您在设计过程中如何使用 AiDA?',
|
|
||||||
clickToUploadPdf: '点击选择或拖拽文件上传',
|
|
||||||
pdfFileLimit: 'PDF 文件,不超过 20MB',
|
|
||||||
// 视频上传
|
|
||||||
uploadVideoTitle: '您在设计过程中如何使用 AiDA?',
|
|
||||||
clickToUploadVideo: '点击选择或拖拽文件上传',
|
|
||||||
videoFileLimit: '视频文件(MP4, MOV),1080P,不超过100MB',
|
|
||||||
// 条款与条件
|
|
||||||
termsAndConditions: '参赛条款',
|
|
||||||
conditionFirst: '我确认所提交的作品均为原创,且由我本人独立创作。',
|
|
||||||
conditionSecond:
|
|
||||||
'我知悉 Code-Create 对提交的所有设计及视频享有市场宣传和推广权利。',
|
|
||||||
conditionThird: '我同意在入围决赛后参加相关活动,包括 AiDA 培训及颁奖典礼。',
|
|
||||||
conditionFourth: '我希望接收有关 AiDA 产品及未来比赛的最新信息。(可选)',
|
|
||||||
// 提交按钮
|
|
||||||
submitYourDesign: '提交作品',
|
|
||||||
unfinishedFormTip: 'AiDA 平台内消息中的链接可保存您未完成的表单。',
|
|
||||||
// 验证码弹窗
|
|
||||||
checkYourEmail: '请查看您的邮箱',
|
|
||||||
enterSixDigitCode: '请输入发送到邮箱的 6 位验证码',
|
|
||||||
verify: '验证',
|
|
||||||
resendCode: '重新发送',
|
|
||||||
resendCodeIn: '重新发送',
|
|
||||||
// 验证消息
|
|
||||||
verificationSuccess: '验证成功!',
|
|
||||||
pleaseVerifyEmailFirst: '请先验证您的邮箱',
|
|
||||||
pleaseCheckTerms: '请同意参赛条款',
|
|
||||||
pleaseFillRequiredFields: '请填写所有必填项',
|
|
||||||
pleaseEnterCompleteCode: '请输入完整的6位验证码',
|
|
||||||
// 上传状态
|
|
||||||
fileUploadedSuccess: '文件上传成功。',
|
|
||||||
fileUploadFailed: '文件上传失败。',
|
|
||||||
// 验证器消息
|
|
||||||
pleaseInputEmail: '请输入邮箱地址',
|
|
||||||
pleaseInputValidEmail: '请输入有效的邮箱地址',
|
|
||||||
pleaseInputFirstName: '请输入您的名',
|
|
||||||
pleaseInputLastName: '请输入您的姓',
|
|
||||||
pleaseSelectGender: '请选择您的性别',
|
|
||||||
pleaseInputOccupation: '请输入您的职业',
|
|
||||||
pleaseInputAge: '请输入您的年龄',
|
|
||||||
pleaseInputCountry: '请输入您的国家/地区及城市',
|
|
||||||
pleaseInputPhoneNumber: '请输入您的电话号码',
|
|
||||||
pleaseInputValidPhone: '请输入有效的电话号码',
|
|
||||||
pleaseInputDigits: '请输入数字',
|
|
||||||
pleaseInputDesignTitle: '请输入您的作品标题',
|
|
||||||
pleaseInputDesignDescription: '请输入您的设计说明',
|
|
||||||
pleaseUploadPdf: '请上传您的PDF文件',
|
|
||||||
pleaseUploadVideo: '请上传您的视频文件',
|
|
||||||
uploadPdfOnly: '请仅上传 PDF 文件。',
|
|
||||||
uploadVideoOnly: '请仅上传 MP4 或 MOV 文件。',
|
|
||||||
fileSizeExceeds: '文件大小超过 {sizeLimit} 限制。请上传较小的文件。',
|
|
||||||
videoDurationExceeds: '视频时长不可超过60秒',
|
|
||||||
uploadFailed: '上传失败'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
318
src/lang/en.ts
318
src/lang/en.ts
@@ -133,8 +133,7 @@ export default {
|
|||||||
UploadOpenimage: 'Upload/Open image',
|
UploadOpenimage: 'Upload/Open image',
|
||||||
jsContent1:
|
jsContent1:
|
||||||
"Have you saved your canvas content? If not, please click 'Save' before closing.",
|
"Have you saved your canvas content? If not, please click 'Save' before closing.",
|
||||||
jsContent2:
|
jsContent2: 'We only provide super-resolution capabilities for printboard images.',
|
||||||
'We only provide super-resolution capabilities for printboard images.',
|
|
||||||
jsContent3: 'Your points are less than one SR',
|
jsContent3: 'Your points are less than one SR',
|
||||||
jsContent4: 'Your points balance is insufficient',
|
jsContent4: 'Your points balance is insufficient',
|
||||||
jsContent5:
|
jsContent5:
|
||||||
@@ -556,8 +555,7 @@ export default {
|
|||||||
inputContent1: 'Input prompt',
|
inputContent1: 'Input prompt',
|
||||||
GeneratePrint: 'Pattern',
|
GeneratePrint: 'Pattern',
|
||||||
maximumLength: 'The entered content exceeds the maximum length.',
|
maximumLength: 'The entered content exceeds the maximum length.',
|
||||||
PatternTitle:
|
PatternTitle: 'Generates repeatable designs that can be fully tiled across garments.',
|
||||||
'Generates repeatable designs that can be fully tiled across garments.',
|
|
||||||
LogoTitle:
|
LogoTitle:
|
||||||
'Creates standalone graphic designs that can be placed individually or tiled.',
|
'Creates standalone graphic designs that can be placed individually or tiled.',
|
||||||
SloganTitle:
|
SloganTitle:
|
||||||
@@ -1006,15 +1004,21 @@ export default {
|
|||||||
subscriptionRenewal: 'There are no subscription plans with automatic renewal.'
|
subscriptionRenewal: 'There are no subscription plans with automatic renewal.'
|
||||||
},
|
},
|
||||||
guide: {
|
guide: {
|
||||||
guide1: "You can personalize your design settings right here in the <strong>Workspace</strong>, including choosing to design for men's or women's wear, as well as selecting the mannequin to use for your creations.",
|
guide1:
|
||||||
|
"You can personalize your design settings right here in the <strong>Workspace</strong>, including choosing to design for men's or women's wear, as well as selecting the mannequin to use for your creations.",
|
||||||
guide2: "Select the apparel type you'd like to work on.",
|
guide2: "Select the apparel type you'd like to work on.",
|
||||||
guide3: 'Change the mannequin here.',
|
guide3: 'Change the mannequin here.',
|
||||||
guide4: 'You can currently select a mannequin from our system library. Later, you can also choose from the user library after registering your own mannequin.',
|
guide4:
|
||||||
|
'You can currently select a mannequin from our system library. Later, you can also choose from the user library after registering your own mannequin.',
|
||||||
guide5: 'Begin your creative journey here. ',
|
guide5: 'Begin your creative journey here. ',
|
||||||
guide6: 'For the Moodboard, Printboard, or Sketchboard, we provide three different sourcing methods to add images. The first option is <strong>Upload</strong>, allowing you to <stront>upload</stront> directly from your local device.',
|
guide6:
|
||||||
guide7: "The second method is to select from your <strong>Library</strong>. <br> You might notice that your library page is currently empty; there's no need to worry. All the images you upload will be automatically added to your library. In the future, you won't have to upload each time—you can simply choose from your library instead.",
|
'For the Moodboard, Printboard, or Sketchboard, we provide three different sourcing methods to add images. The first option is <strong>Upload</strong>, allowing you to <stront>upload</stront> directly from your local device.',
|
||||||
guide8: 'The third method is to <strong>Generate</strong> images using the latest Image Generation technology.',
|
guide7:
|
||||||
guide9: 'Enter keywords that capture the mood you wish to express and then click the <strong>Low Quality</strong> button.',
|
"The second method is to select from your <strong>Library</strong>. <br> You might notice that your library page is currently empty; there's no need to worry. All the images you upload will be automatically added to your library. In the future, you won't have to upload each time—you can simply choose from your library instead.",
|
||||||
|
guide8:
|
||||||
|
'The third method is to <strong>Generate</strong> images using the latest Image Generation technology.',
|
||||||
|
guide9:
|
||||||
|
'Enter keywords that capture the mood you wish to express and then click the <strong>Low Quality</strong> button.',
|
||||||
guide10: 'Select two images for your moodboard.',
|
guide10: 'Select two images for your moodboard.',
|
||||||
guide11: 'Click here to layout your moodboard.',
|
guide11: 'Click here to layout your moodboard.',
|
||||||
guide12: 'Click here for next step.',
|
guide12: 'Click here for next step.',
|
||||||
@@ -1064,8 +1068,7 @@ export default {
|
|||||||
guide52: 'Click here to generate the product image.',
|
guide52: 'Click here to generate the product image.',
|
||||||
guide53: 'Click this button to apply more tools to the product image. ',
|
guide53: 'Click this button to apply more tools to the product image. ',
|
||||||
guide54: 'We can adjust the lighting and background of this image. ',
|
guide54: 'We can adjust the lighting and background of this image. ',
|
||||||
guide55:
|
guide55: 'Click here to generate a product image with lighting from the right side.',
|
||||||
'Click here to generate a product image with lighting from the right side.',
|
|
||||||
guide56: 'If you like this result, click the little heart to save it.',
|
guide56: 'If you like this result, click the little heart to save it.',
|
||||||
guide57: 'Click here to go to the export page. ',
|
guide57: 'Click here to go to the export page. ',
|
||||||
guide58: 'You can share your work to the gallery or export to your local device.',
|
guide58: 'You can share your work to the gallery or export to your local device.',
|
||||||
@@ -1229,8 +1232,7 @@ export default {
|
|||||||
touchDevicePrompts_2: 'Double-click an element to quickly enter edit mode.',
|
touchDevicePrompts_2: 'Double-click an element to quickly enter edit mode.',
|
||||||
touchDevicePrompts_3: 'Two-finger drag to pan the canvas.',
|
touchDevicePrompts_3: 'Two-finger drag to pan the canvas.',
|
||||||
touchDevicePrompts_4: 'Pinch to zoom.',
|
touchDevicePrompts_4: 'Pinch to zoom.',
|
||||||
touchDevicePrompts_5:
|
touchDevicePrompts_5: "Two-finger tap to display the element's transform handles.",
|
||||||
"Two-finger tap to display the element's transform handles.",
|
|
||||||
touchDevicePrompts_6: 'Three-finger swipe left or right to undo/redo.',
|
touchDevicePrompts_6: 'Three-finger swipe left or right to undo/redo.',
|
||||||
TheDetectedPlatform: 'Guide Detected Platform',
|
TheDetectedPlatform: 'Guide Detected Platform',
|
||||||
BasicOperations: 'Basic Operations',
|
BasicOperations: 'Basic Operations',
|
||||||
@@ -1361,8 +1363,7 @@ export default {
|
|||||||
furCurvature: 'Curvature',
|
furCurvature: 'Curvature',
|
||||||
furCurvatureDescription: 'Control the degree of hair curvature',
|
furCurvatureDescription: 'Control the degree of hair curvature',
|
||||||
randomizeDirection: 'Random Cirection',
|
randomizeDirection: 'Random Cirection',
|
||||||
randomizeDirectionDescription:
|
randomizeDirectionDescription: 'Whether to randomize the direction of hair growth',
|
||||||
'Whether to randomize the direction of hair growth',
|
|
||||||
//水墨
|
//水墨
|
||||||
InkSettings: 'Ink painting settings',
|
InkSettings: 'Ink painting settings',
|
||||||
InkAmount: 'The amount of ink',
|
InkAmount: 'The amount of ink',
|
||||||
@@ -1388,8 +1389,7 @@ export default {
|
|||||||
//马克笔
|
//马克笔
|
||||||
MarkerSettings: 'Marker Settings',
|
MarkerSettings: 'Marker Settings',
|
||||||
MarkerWidth: 'Brush stroke width',
|
MarkerWidth: 'Brush stroke width',
|
||||||
MarkerWidthDescription:
|
MarkerWidthDescription: 'Control the width of the brush strokes with the marker pen',
|
||||||
'Control the width of the brush strokes with the marker pen',
|
|
||||||
MarkerCapStyle: 'Writing style',
|
MarkerCapStyle: 'Writing style',
|
||||||
MarkerCapStyleDescription: 'Set the shape of the marker pen tip',
|
MarkerCapStyleDescription: 'Set the shape of the marker pen tip',
|
||||||
MarkerCapStyleRound: 'Round',
|
MarkerCapStyleRound: 'Round',
|
||||||
@@ -1520,18 +1520,15 @@ export default {
|
|||||||
CompositeMultiply: 'Multiply',
|
CompositeMultiply: 'Multiply',
|
||||||
CompositeMultiplyTip: 'Multiply: Darken the image',
|
CompositeMultiplyTip: 'Multiply: Darken the image',
|
||||||
CompositeColorBurn: 'Color Burn',
|
CompositeColorBurn: 'Color Burn',
|
||||||
CompositeColorBurnTip:
|
CompositeColorBurnTip: 'Color Burn: Increase contrast and darken the bottom color',
|
||||||
'Color Burn: Increase contrast and darken the bottom color',
|
|
||||||
CompositeLighten: 'Lighten',
|
CompositeLighten: 'Lighten',
|
||||||
CompositeLightenTip: 'Lighten: Take the brightest color',
|
CompositeLightenTip: 'Lighten: Take the brightest color',
|
||||||
CompositeScreen: 'Screen',
|
CompositeScreen: 'Screen',
|
||||||
CompositeScreenTip: 'Screen: Lighten the image',
|
CompositeScreenTip: 'Screen: Lighten the image',
|
||||||
CompositeColorDodge: 'Color Dodge',
|
CompositeColorDodge: 'Color Dodge',
|
||||||
CompositeColorDodgeTip:
|
CompositeColorDodgeTip: 'Color Dodge: Reduce contrast and lighten the bottom color',
|
||||||
'Color Dodge: Reduce contrast and lighten the bottom color',
|
|
||||||
CompositeLighter: 'Color Dodge (Add)',
|
CompositeLighter: 'Color Dodge (Add)',
|
||||||
CompositeLighterTip:
|
CompositeLighterTip: 'Color Dodge (Add): Add the brightness of the overlapping parts',
|
||||||
'Color Dodge (Add): Add the brightness of the overlapping parts',
|
|
||||||
CompositeOverlay: 'Overlay',
|
CompositeOverlay: 'Overlay',
|
||||||
CompositeOverlayTip: 'Overlay: Highlight effect',
|
CompositeOverlayTip: 'Overlay: Highlight effect',
|
||||||
CompositeSoftLight: 'Soft Light',
|
CompositeSoftLight: 'Soft Light',
|
||||||
@@ -1586,7 +1583,8 @@ export default {
|
|||||||
LiquefactionTool: 'Liquefaction Tool'
|
LiquefactionTool: 'Liquefaction Tool'
|
||||||
},
|
},
|
||||||
event: {
|
event: {
|
||||||
back: 'Back'
|
back: 'Back',
|
||||||
|
detail: 'View Details'
|
||||||
},
|
},
|
||||||
admin: {
|
admin: {
|
||||||
allUser: 'All User',
|
allUser: 'All User',
|
||||||
@@ -1668,7 +1666,8 @@ export default {
|
|||||||
ForgotPassword: '忘记密码',
|
ForgotPassword: '忘记密码',
|
||||||
Welcome: 'Welcome to',
|
Welcome: 'Welcome to',
|
||||||
AiDA: 'AiDA',
|
AiDA: 'AiDA',
|
||||||
Slogan: 'AiDA, a first-to-market technology that empowers fashion designers, based on their creative inspirations, to work with AI to create original designs.',
|
Slogan:
|
||||||
|
'AiDA, a first-to-market technology that empowers fashion designers, based on their creative inspirations, to work with AI to create original designs.',
|
||||||
LoginMethod: 'Continue with one of these:',
|
LoginMethod: 'Continue with one of these:',
|
||||||
Individual: 'Individual',
|
Individual: 'Individual',
|
||||||
Academic: 'Academic',
|
Academic: 'Academic',
|
||||||
@@ -1709,8 +1708,7 @@ export default {
|
|||||||
IncorrectEmail: 'The email format is incorrect',
|
IncorrectEmail: 'The email format is incorrect',
|
||||||
IncorrectEmailFormat: 'The email format is incorrect',
|
IncorrectEmailFormat: 'The email format is incorrect',
|
||||||
CompleteVerificationCode: 'Please enter the complete verification code.',
|
CompleteVerificationCode: 'Please enter the complete verification code.',
|
||||||
PleaseEnterYourAccountNumberOrPassword:
|
PleaseEnterYourAccountNumberOrPassword: 'Please enter your account number or password'
|
||||||
'Please enter your account number or password'
|
|
||||||
},
|
},
|
||||||
LoginSchool: {
|
LoginSchool: {
|
||||||
School: 'School',
|
School: 'School',
|
||||||
@@ -1741,8 +1739,7 @@ export default {
|
|||||||
IncorrectEmail: 'The email format is incorrect',
|
IncorrectEmail: 'The email format is incorrect',
|
||||||
IncorrectEmailFormat: 'The email format is incorrect',
|
IncorrectEmailFormat: 'The email format is incorrect',
|
||||||
CompleteVerificationCode: 'Please enter the complete verification code.',
|
CompleteVerificationCode: 'Please enter the complete verification code.',
|
||||||
PleaseEnterYourAccountNumberOrPassword:
|
PleaseEnterYourAccountNumberOrPassword: 'Please enter your account number or password'
|
||||||
'Please enter your account number or password'
|
|
||||||
},
|
},
|
||||||
LoginEnterprise: {
|
LoginEnterprise: {
|
||||||
Enterprise: 'Enterprise',
|
Enterprise: 'Enterprise',
|
||||||
@@ -1772,265 +1769,6 @@ export default {
|
|||||||
IncorrectEmail: 'The email format is incorrect',
|
IncorrectEmail: 'The email format is incorrect',
|
||||||
IncorrectEmailFormat: 'The email format is incorrect',
|
IncorrectEmailFormat: 'The email format is incorrect',
|
||||||
CompleteVerificationCode: 'Please enter the complete verification code.',
|
CompleteVerificationCode: 'Please enter the complete verification code.',
|
||||||
PleaseEnterYourAccountNumberOrPassword:
|
PleaseEnterYourAccountNumberOrPassword: 'Please enter your account number or password'
|
||||||
'Please enter your account number or password'
|
|
||||||
},
|
|
||||||
AwardsPage: {
|
|
||||||
submitApplication: 'Submit your Application',
|
|
||||||
applicationDeadline: 'Application Deadline:15th July 2026',
|
|
||||||
howToApply: 'How to Apply',
|
|
||||||
stepByStep: 'Step by step',
|
|
||||||
step1Title: 'Step 1. Become an\nAiDA Subscriber',
|
|
||||||
step1Desc:
|
|
||||||
'All applicants must be active\nAiDA subscribers at the time of\nsubmission. You may subscribe\nunder either a monthly or yearly plan.',
|
|
||||||
step2Title: 'Step 2. Create Your Design Using AiDA',
|
|
||||||
step2Desc:
|
|
||||||
'Applicants must create their\ndesigns exclusively using the\nAiDA platform. ',
|
|
||||||
step2ListTitle: 'Your work should clearly demonstrate:',
|
|
||||||
step2List: [
|
|
||||||
'· How AiDA is used as a creative tool',
|
|
||||||
'· Your design concept and creative direction',
|
|
||||||
'· The intergration of AI and human creativity'
|
|
||||||
],
|
|
||||||
step3Title: 'Step 3. Prepare Your Submission',
|
|
||||||
processVideo: 'Process Video',
|
|
||||||
processVideoDesc:
|
|
||||||
'Include a screen‑recorded video\nyour creative process\nusing AiDA.',
|
|
||||||
videoRequirements: 'Video requirements:',
|
|
||||||
videoFormat: 'Format: MP4',
|
|
||||||
videoResolution: 'Resolution: 1080×1920 px',
|
|
||||||
videoDuration: 'Duration: Maximum 1 minute',
|
|
||||||
videoSize: 'File size: Maximum 20MB',
|
|
||||||
fileName: 'File Name',
|
|
||||||
fileNameDesc: 'AiDAGlobalDesignAward\n2026_[Your Full Name]',
|
|
||||||
designPortfolio: 'Design Portfolio(PDF)',
|
|
||||||
submitPdf: 'Submit one single PDF file that includes:',
|
|
||||||
requiredStructure: 'Required structure:',
|
|
||||||
pdfDesignTitle: 'Design title',
|
|
||||||
pdfMoodboard: 'Moodboard',
|
|
||||||
pdfConcept: 'Concept explanation',
|
|
||||||
pdfConceptDesc: '(How to use AiDA to develop design)',
|
|
||||||
pdfRequirements: 'PDF requirements:',
|
|
||||||
pdfMaxPages: 'Maximum 15 pages',
|
|
||||||
pdfMaxSize: 'Maximum file size: 20MB',
|
|
||||||
pdfLanguage: 'Language: English or native language\nwith English translation',
|
|
||||||
step4Title: 'Step 4. Finalist Requirement',
|
|
||||||
step4Subtitle: '(for top 20 Designers)',
|
|
||||||
step4Desc:
|
|
||||||
'The 20 finalists will be required to\nsubmit physical garments for final\nevaluation',
|
|
||||||
finalistPieces: 'Number of pieces: 1 full outfit',
|
|
||||||
finalistBasedOn:
|
|
||||||
'Garments must be produced\nbased on the submitted\nAiDA-generated designs',
|
|
||||||
finalistShipping: 'Shipping instructions will be provided by\nCode-create',
|
|
||||||
bloomYourCreativity: 'Bloom Your Creativity',
|
|
||||||
themeOf2026: 'Theme of 2026',
|
|
||||||
bloomText: {
|
|
||||||
desc1: {
|
|
||||||
regular1: 'The',
|
|
||||||
bold1: 'AiDA Global Design Award 2026',
|
|
||||||
regular2: 'is an ',
|
|
||||||
bold2: 'international design competition ',
|
|
||||||
regular3: 'hosted by ',
|
|
||||||
bold3: 'Code-create ',
|
|
||||||
regular4: ', a globally leading\n',
|
|
||||||
bold4: 'AI fashion solutions provider,',
|
|
||||||
regular5:
|
|
||||||
'celebrating the future of creativity powered by artificial intelligence.\nBringing together designers from around the world, AiDA empowers AI as a creative partner—pushing fashion beyond traditional boundaries and unlocking new possibilities where technology amplifies human imagination.'
|
|
||||||
},
|
|
||||||
desc2: {
|
|
||||||
regular1: 'Under the theme',
|
|
||||||
bold1: '“Where Imagination Meets Innovation, Creativity Blooms,” ',
|
|
||||||
regular2:
|
|
||||||
'participants are invited to transform bold ideas into extraordinary designs, seamlessly merging human artistry with artificial intelligence to shape the next era of fashion.'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
bloomDesc1:
|
|
||||||
'The AiDA Global Design Award 2026 is an\ninternational design competition hosted by\nCode‑Create, a globally leading AI fashion solutions provider,\ncelebrating the future of creativity powered by artificial intelligence.\nBringing together designers from around the world, AiDA empowers AI as a creative partner—pushing fashion beyond traditional boundaries and unlocking new possibilities where technology amplifies human imagination.',
|
|
||||||
bloomDesc2:
|
|
||||||
'Under the theme “Where Imagination Meets Innovation, Creativity Blooms,” participants are invited to transform bold ideas into extraordinary designs, seamlessly merging human artistry with artificial intelligence to shape the next era of fashion.',
|
|
||||||
panelOfJudges: 'Panel of Judges',
|
|
||||||
expertise: 'Expertise',
|
|
||||||
judgesHat: {
|
|
||||||
jae: 'Code-create\nKorea Branch Director\nBesfxxk creative director',
|
|
||||||
diego: 'Co-founder & Chief Father\nOfficer of OnTheList\n(Hong Kong)',
|
|
||||||
gregory: 'Senior Designer at\nGabriela Heasrst (Italy)',
|
|
||||||
vincenzo: 'Cheif Editor of SCMP Style\n(Hong Kong)',
|
|
||||||
tim: 'Group Fashion Direction of\n Modern Media Group\n(Shanghai)',
|
|
||||||
desmond: 'Cheif Editor of Vogue\n(Singapore)'
|
|
||||||
},
|
|
||||||
awardPrizes: 'Award & Prizes',
|
|
||||||
recognition: 'Recognition',
|
|
||||||
grandMoney: 'US$5,000',
|
|
||||||
goldMoney: 'US$3,000',
|
|
||||||
silverMoney: 'US$1,000',
|
|
||||||
grandAwards: 'Grand Awards',
|
|
||||||
goldAwards: 'Gold Awards',
|
|
||||||
silverAwards: 'Silver Awards',
|
|
||||||
finalists: 'Finalists',
|
|
||||||
cashAward: 'Cash Award',
|
|
||||||
awardCertificate: 'Award Certificate',
|
|
||||||
globalMediaExposure: 'Global Media Exposure',
|
|
||||||
awardCertification: 'Award\nCertification',
|
|
||||||
TravelAllowance: 'Travel Allowance',
|
|
||||||
selectionCriteria: 'Selection Criteria',
|
|
||||||
evaluation: 'Evaluation',
|
|
||||||
originality: 'Originality',
|
|
||||||
originalityDesc: 'Unique perspective and\ninnovative approach to\nfashion design',
|
|
||||||
creativity: 'Creativity',
|
|
||||||
creativityDesc: 'Artistic vision and exceptional\ndesign excellence',
|
|
||||||
aidaIntegration: 'AiDA Integration',
|
|
||||||
aidaIntegrationDesc: 'Effective application of\nAiDA functions',
|
|
||||||
execution: 'Execution',
|
|
||||||
executionDesc: 'Quality of presentation and\ntechnical craftsmanship',
|
|
||||||
totalCashPrizes: 'UP TO\nUS$9000',
|
|
||||||
totalCashPrizesLabel: 'In total cash prizes',
|
|
||||||
globalMediaExpose: 'GLOBAL MEDIA\nEXPOSE',
|
|
||||||
globalMediaExposeLabel: 'Showcased by top\ninternational media platforms',
|
|
||||||
networkingOpportunities: 'NETWORKING\nOPPORTUNITIES',
|
|
||||||
networkingOpportunitiesLabel:
|
|
||||||
'Build connections with\ndesigners and industry leaders',
|
|
||||||
awardCeremonyHongKong: 'AWARD CEREMONY\nIN HONG KONG',
|
|
||||||
awardCeremonyLabel: 'Travel allowance\nprovided for finalists',
|
|
||||||
competitionTimeline: 'Competition Timeline',
|
|
||||||
shapingTheFuture: 'Shaping the Future',
|
|
||||||
timelineApplicationLabel: 'Application',
|
|
||||||
timelineDeadlineLabel: 'Deadline',
|
|
||||||
timeJul15: 'Jul 15',
|
|
||||||
applicationDeadlineDesc:
|
|
||||||
'Application deadline and\nentry review process\nbegins.',
|
|
||||||
twentyFinalistsAnnounced: '20 Finallists',
|
|
||||||
announcedLabel: 'Announced',
|
|
||||||
timeAug30: 'Aug 30',
|
|
||||||
twentyFinalistsDesc:
|
|
||||||
'Announcement of 20\nfinalists entering final\nevaluation stage.',
|
|
||||||
finalistSubmission: 'Finallist\nSubmission',
|
|
||||||
submissionLabel: 'Deadline',
|
|
||||||
timeSept30: 'Sept 30',
|
|
||||||
finalistSubmissionDesc:
|
|
||||||
'Finalists submit\ncompleted outfits for\nfinal assessment.',
|
|
||||||
receivingOutfits: 'Receiving Outfits',
|
|
||||||
fromFinalistsLabel: 'from Finallists',
|
|
||||||
timeOctober: 'October',
|
|
||||||
receivingOutfitsDesc: 'AiDA receives physical\noutfits from all 20\nfinalists.',
|
|
||||||
awardCeremony: 'Award',
|
|
||||||
ceremonyLabel: 'Ceremony',
|
|
||||||
timeNov12: 'Nov 12',
|
|
||||||
awardCeremonyDesc: 'Award Ceremony &\nCommunity Gathering\n– Soho House.',
|
|
||||||
submissionSuccessful: 'Submission Successful',
|
|
||||||
submissionSuccessfulDesc:
|
|
||||||
'Please review your submitted information in the AiDA in-platform message.\nYou may edit it if needed. Competition updates and results will be sent via email.',
|
|
||||||
deadlinePassed: 'Application Deadline Passed',
|
|
||||||
deadlinePassedDesc:
|
|
||||||
'The submission deadline for AiDA Global Fashion Award 2026 has ended.\nWe are no longer accepting new applications.',
|
|
||||||
uploadInProgress: 'Upload in progress…',
|
|
||||||
uploadSuccess: 'Uploaded Successfully',
|
|
||||||
uploadFailed: 'Upload failed',
|
|
||||||
pdfFileTip: 'PDF file, max 20MB',
|
|
||||||
videoFileTip: 'Video file (MP4, MOV), 1080p, max 100MB',
|
|
||||||
wechatTitle: 'WeChat Official Account',
|
|
||||||
wechatDesc: 'Scan the QR code in WeChat'
|
|
||||||
},
|
|
||||||
AwardApply: {
|
|
||||||
// 页面主标题区域
|
|
||||||
applicationForm: 'Application Form',
|
|
||||||
emailVerification: 'Email Verification',
|
|
||||||
aidaUsersOnly: 'AiDA Users Only',
|
|
||||||
slogan: 'BLOOM YOUR CREATIVITY • AIDA GLOBAL DESIGN AWARDS 2026',
|
|
||||||
// 邮箱验证部分
|
|
||||||
emailAddress: 'Email Address',
|
|
||||||
sendCode: 'Send Code',
|
|
||||||
pleaseUseRegisteredEmail:
|
|
||||||
'Please use the email address you registered with AiDA.',
|
|
||||||
// 个人信息部分
|
|
||||||
personalInformation: 'Personal Information',
|
|
||||||
tellUsAboutYourself: 'Tell us about yourself',
|
|
||||||
firstName: 'First Name',
|
|
||||||
lastName: 'Last Name',
|
|
||||||
gender: 'Gender',
|
|
||||||
occupation: 'Occupation',
|
|
||||||
age: 'Age',
|
|
||||||
countryRegionCity: 'Country/Region and City',
|
|
||||||
phoneNumber: 'Phone Number',
|
|
||||||
portfolioUrl: 'Portfolio Website/Instagram (Optional)',
|
|
||||||
// 性别选项
|
|
||||||
male: 'Male',
|
|
||||||
female: 'Female',
|
|
||||||
other: 'Other',
|
|
||||||
// 设计信息部分
|
|
||||||
designInformation: 'Design Information',
|
|
||||||
shareYourCreativeVision: 'Share your creative vision',
|
|
||||||
designTitle: 'Design Title',
|
|
||||||
designDescription: 'Design description',
|
|
||||||
designDescriptionPlaceholder:
|
|
||||||
'Briefly describe your design concept, inspiration, and creative direction...',
|
|
||||||
// 提交文件部分
|
|
||||||
submissionFiles: 'Submission Files',
|
|
||||||
uploadYourDesignMaterials: 'Upload your design materials',
|
|
||||||
submissionRequirements: 'Submission Requirements',
|
|
||||||
pdfRequirement: `Single PDF file\n Title, mood board, elaboration\n+ 4 outfit design with materials (max 15 pages)`,
|
|
||||||
rightContent: {
|
|
||||||
format: 'Format: Single PDF file, 15 pages, maximum 20MB',
|
|
||||||
video: `Video: Design process, 1080×1920 pixels (9:16 ratio), maximum 60 seconds`
|
|
||||||
},
|
|
||||||
// PDF 上传
|
|
||||||
uploadPdfTitle: 'How will you use AiDA in your design process?',
|
|
||||||
clickToUploadPdf: 'Click to upload or drag and drop',
|
|
||||||
pdfFileLimit: 'PDF file, max 20MB',
|
|
||||||
// 视频上传
|
|
||||||
uploadVideoTitle: 'How will you use AiDA in your design process?',
|
|
||||||
clickToUploadVideo: 'Click to upload or drag and drop',
|
|
||||||
videoFileLimit: 'Video file (MP4, MOV), 1080p, max 100MB',
|
|
||||||
// 条款与条件
|
|
||||||
termsAndConditions: 'Terms & Conditions',
|
|
||||||
conditionFirst:
|
|
||||||
'I confirm that all submitted work is original and created by me.',
|
|
||||||
conditionSecond:
|
|
||||||
'I understand that Code-Create has marketing and promotional rights to all submitted designs and videos.',
|
|
||||||
conditionThird:
|
|
||||||
'I agree to participate in finalist activities if selected, including AiDA training and award ceremony.',
|
|
||||||
conditionFourth:
|
|
||||||
'I would like to receive updates about AiDA products and future competitions. (Optional)',
|
|
||||||
// 提交按钮
|
|
||||||
submitYourDesign: 'Submit your Design',
|
|
||||||
unfinishedFormTip:
|
|
||||||
'The link in the AiDA in-platform message will save your unfinished form.',
|
|
||||||
// 验证码弹窗
|
|
||||||
checkYourEmail: 'Check your email',
|
|
||||||
enterSixDigitCode: 'Enter the 6-digit code sent to',
|
|
||||||
verify: 'Verify',
|
|
||||||
resendCode: 'Resend',
|
|
||||||
resendCodeIn: 'Resend Code in',
|
|
||||||
// 验证消息
|
|
||||||
verificationSuccess: 'Verification successful!',
|
|
||||||
pleaseVerifyEmailFirst: 'Please verify your email first',
|
|
||||||
pleaseCheckTerms: 'Please agree to the terms and conditions',
|
|
||||||
pleaseFillRequiredFields: 'Please fill in all the required fields',
|
|
||||||
pleaseEnterCompleteCode: 'Please enter the complete 6-digit verification code',
|
|
||||||
// 上传状态
|
|
||||||
fileUploadedSuccess: '{fileName} file uploaded successfully.',
|
|
||||||
fileUploadFailed: '{fileName} file upload failed.',
|
|
||||||
// 验证器消息
|
|
||||||
pleaseInputEmail: 'Please input the email address',
|
|
||||||
pleaseInputValidEmail: 'Please input a valid email address',
|
|
||||||
pleaseInputFirstName: 'Please input your first name',
|
|
||||||
pleaseInputLastName: 'Please input your last name',
|
|
||||||
pleaseSelectGender: 'Please select your gender',
|
|
||||||
pleaseInputOccupation: 'Please input your occupation',
|
|
||||||
pleaseInputAge: 'Please input your age',
|
|
||||||
pleaseInputCountry: 'Please input your country/region and city',
|
|
||||||
pleaseInputPhoneNumber: 'Please enter your phone number.',
|
|
||||||
pleaseInputValidPhone: 'Please enter a valid phone number.',
|
|
||||||
pleaseInputDigits: 'Please enter digits only',
|
|
||||||
pleaseInputDesignTitle: 'Please input your design title',
|
|
||||||
pleaseInputDesignDescription: 'Please input your design description',
|
|
||||||
pleaseUploadPdf: 'Please upload your PDF',
|
|
||||||
pleaseUploadVideo: 'Please upload your video',
|
|
||||||
uploadPdfOnly: 'Please upload a PDF file only.',
|
|
||||||
uploadVideoOnly: 'Please upload a MP4 or MOV file only.',
|
|
||||||
fileSizeExceeds:
|
|
||||||
'File size exceeds {sizeLimit} limit. Please upload a smaller file.',
|
|
||||||
videoDurationExceeds:
|
|
||||||
'Video duration exceeds 60 seconds limit. Please upload a shorter video.',
|
|
||||||
uploadFailed: 'Upload failed'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,12 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/Register.vue"),
|
component: () => import("@/views/Register.vue"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/register/:lang",
|
||||||
|
name: "registerLang",
|
||||||
|
meta: { enter: "all" },
|
||||||
|
component: () => import("@/views/Register.vue"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/upgrade",
|
path: "/upgrade",
|
||||||
name: "upgrade",
|
name: "upgrade",
|
||||||
@@ -172,6 +178,12 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/HomeRecommend.vue"),
|
component: () => import("@/views/HomeRecommend.vue"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/Square/:lang",
|
||||||
|
name: "HomeRecommendLang",
|
||||||
|
meta: { enter: "all" },
|
||||||
|
component: () => import("@/views/HomeRecommend.vue"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/administrator",
|
path: "/administrator",
|
||||||
name: "administrator",
|
name: "administrator",
|
||||||
@@ -325,6 +337,13 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () =>
|
component: () =>
|
||||||
import("@/component/Administrator/SE/getGenerateFrequency/index.vue"),
|
import("@/component/Administrator/SE/getGenerateFrequency/index.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "globalAwardPopularity",
|
||||||
|
name: "globalAwardPopularity",
|
||||||
|
meta: { enter: 3 },
|
||||||
|
component: () =>
|
||||||
|
import("@/component/Administrator/globalAwardPopularity.vue"),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -87,8 +87,10 @@ const DesignDetail : Module<DesignDetail,RootState> = {
|
|||||||
left:0,
|
left:0,
|
||||||
top:0,
|
top:0,
|
||||||
}
|
}
|
||||||
|
if(data?.fromType !== 'resize'){
|
||||||
v.maskMinioUrl = v.layersObject?.[0]?.maskMinioUrl
|
v.maskMinioUrl = v.layersObject?.[0]?.maskMinioUrl
|
||||||
v.maskUrl = v.layersObject?.[0]?.maskUrl
|
v.maskUrl = v.layersObject?.[0]?.maskUrl
|
||||||
|
}
|
||||||
v.layersObject[i].designOpenrtionBtn = false
|
v.layersObject[i].designOpenrtionBtn = false
|
||||||
if(v.layersObject[i].imageCategory.indexOf("back") == -1){
|
if(v.layersObject[i].imageCategory.indexOf("back") == -1){
|
||||||
front[index] = v.layersObject[i]
|
front[index] = v.layersObject[i]
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ const HomeStoreModule : Module<DesignDetail,RootState> = {
|
|||||||
},
|
},
|
||||||
setPoseTransferLastFrameList(state,data){
|
setPoseTransferLastFrameList(state,data){
|
||||||
// 支持两种方式:set 替换整个列表;add/删除与 uploadElement 一致
|
// 支持两种方式:set 替换整个列表;add/删除与 uploadElement 一致
|
||||||
if(data.str === 'set'){
|
if(data?.str === 'set'){
|
||||||
state.lastFrameList = data.list || []
|
state.lastFrameList = data.list || []
|
||||||
return
|
return
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ const userHabit : Module<UserHabit,RootState> = {
|
|||||||
followeeCount: '-',
|
followeeCount: '-',
|
||||||
followerCount: '-',
|
followerCount: '-',
|
||||||
accountExtendList:null,
|
accountExtendList:null,
|
||||||
systemList:[],
|
systemList:[1],
|
||||||
expireTime:null,
|
expireTime:null,
|
||||||
language:'',
|
language:'',
|
||||||
organizationId: null,
|
organizationId: null,
|
||||||
@@ -194,7 +194,7 @@ const userHabit : Module<UserHabit,RootState> = {
|
|||||||
followeeCount: '-',
|
followeeCount: '-',
|
||||||
followerCount: '-',
|
followerCount: '-',
|
||||||
accountExtendList:null,
|
accountExtendList:null,
|
||||||
systemList:[],
|
systemList:[1],
|
||||||
expireTime:null,
|
expireTime:null,
|
||||||
language:'',
|
language:'',
|
||||||
organizationId: null,
|
organizationId: null,
|
||||||
@@ -407,7 +407,7 @@ const userHabit : Module<UserHabit,RootState> = {
|
|||||||
item.name = name
|
item.name = name
|
||||||
});
|
});
|
||||||
// const {t} = useI18n()
|
// const {t} = useI18n()
|
||||||
rv.unshift({name:t('Model.all'),value:'',id:''})
|
rv.unshift({name:t('Model.all'),value:'',id:null})
|
||||||
store.commit('setMannequinStyle',rv)
|
store.commit('setMannequinStyle',rv)
|
||||||
resolve('')
|
resolve('')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,8 @@ const Workspace: Module<DesignDetail, RootState> = {
|
|||||||
},
|
},
|
||||||
setProbject(state, data) {
|
setProbject(state, data) {
|
||||||
for (const key in data) {
|
for (const key in data) {
|
||||||
if (data[key] == undefined) continue
|
let list = ['styleName','styleId','style']
|
||||||
|
if (data[key] == undefined && !list.includes(key)) continue
|
||||||
state.probjects[key] = data[key]
|
state.probjects[key] = data[key]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -198,6 +198,13 @@ const all = (t)=>{
|
|||||||
route: '/administrator/subscriptionPlan',
|
route: '/administrator/subscriptionPlan',
|
||||||
key: 'sub14',
|
key: 'sub14',
|
||||||
isShow: true
|
isShow: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Global Award Popularity',
|
||||||
|
icon: 'usetime',
|
||||||
|
route: '/administrator/globalAwardPopularity',
|
||||||
|
key: 'sub15',
|
||||||
|
isShow: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -346,6 +346,7 @@ export const Https = {
|
|||||||
switchSubscribePlan: '/api/subscription_plan/switchSubscriptionPlan', // 切换管理员订阅计划
|
switchSubscribePlan: '/api/subscription_plan/switchSubscriptionPlan', // 切换管理员订阅计划
|
||||||
switchSubAccountSubscribePlan:
|
switchSubAccountSubscribePlan:
|
||||||
'/api/subscription_plan/switchSubAccSubscriptionPlan', // 切换子账号订阅计划
|
'/api/subscription_plan/switchSubAccSubscriptionPlan', // 切换子账号订阅计划
|
||||||
|
getGlobalAwardPopularity: '/api/global-award/page/visit/count', // 获取global award流量
|
||||||
|
|
||||||
//云生成
|
//云生成
|
||||||
designCloud: `/api/design/designCloud`, //创建云生成
|
designCloud: `/api/design/designCloud`, //创建云生成
|
||||||
|
|||||||
@@ -272,12 +272,12 @@ const navTypeList = (t)=>{
|
|||||||
// },
|
// },
|
||||||
|
|
||||||
|
|
||||||
{
|
// {
|
||||||
icon:'fi fi-rr-puzzle-alt',
|
// icon:'fi fi-rr-puzzle-alt',
|
||||||
value:'deReconstruction',
|
// value:'deReconstruction',
|
||||||
label:t('Header.toolsDeReconstruction'),
|
// label:t('Header.toolsDeReconstruction'),
|
||||||
router:'tools=deReconstruction'
|
// router:'tools=deReconstruction'
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
icon:'fi fi-ss-box-open',
|
icon:'fi fi-ss-box-open',
|
||||||
value:'toProduct',
|
value:'toProduct',
|
||||||
@@ -294,18 +294,18 @@ const navTypeList = (t)=>{
|
|||||||
label:t('Header.toolsToTransferPose'),
|
label:t('Header.toolsToTransferPose'),
|
||||||
router:'tools=poseTransfer'
|
router:'tools=poseTransfer'
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
icon:'fi fi-rr-cubes',
|
// icon:'fi fi-rr-cubes',
|
||||||
value:'patternMaking3D',
|
// value:'patternMaking3D',
|
||||||
label:t('Header.toolsPatternMaking'),
|
// label:t('Header.toolsPatternMaking'),
|
||||||
router:'tools=patternMaking3D'
|
// router:'tools=patternMaking3D'
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
icon:'fi fi-rr-pen-swirl',
|
// icon:'fi fi-rr-pen-swirl',
|
||||||
value:'canvasUpload',
|
// value:'canvasUpload',
|
||||||
label:t('Header.toolsCanvas'),
|
// label:t('Header.toolsCanvas'),
|
||||||
router:'tools=canvasUpload'
|
// router:'tools=canvasUpload'
|
||||||
},
|
// },
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
library:{
|
library:{
|
||||||
@@ -340,12 +340,12 @@ const navTypeList = (t)=>{
|
|||||||
value:'Models',
|
value:'Models',
|
||||||
router:'library=Models'
|
router:'library=Models'
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
icon:'fi-ss-gem',
|
// icon:'fi-ss-gem',
|
||||||
label:t('LibraryPage.brandDNA'),
|
// label:t('LibraryPage.brandDNA'),
|
||||||
value:'MyBrand',
|
// value:'MyBrand',
|
||||||
router:'library=MyBrand'
|
// router:'library=MyBrand'
|
||||||
},
|
// },
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
// history:{
|
// history:{
|
||||||
|
|||||||
@@ -672,6 +672,17 @@ function sketchToMask(sketchImage) {
|
|||||||
img.src = sketchImage;
|
img.src = sketchImage;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isValidUrl(string) {
|
||||||
|
try {
|
||||||
|
const url = new URL(string)
|
||||||
|
// 通常我们只需要 http 或 https 协议
|
||||||
|
return url.protocol === "http:" || url.protocol === "https:"
|
||||||
|
} catch (err) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
isEmail,
|
isEmail,
|
||||||
getUploadUrl,
|
getUploadUrl,
|
||||||
@@ -695,5 +706,6 @@ export {
|
|||||||
calculateGradientCoordinate,
|
calculateGradientCoordinate,
|
||||||
segmentImage,
|
segmentImage,
|
||||||
UrlToFile,
|
UrlToFile,
|
||||||
sketchToMask
|
sketchToMask,
|
||||||
|
isValidUrl
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -400,7 +400,7 @@
|
|||||||
<a href="https://www.facebook.com/CodeCreateAI" target="_blank" >
|
<a href="https://www.facebook.com/CodeCreateAI" target="_blank" >
|
||||||
<img src="@/assets/images/socialMediaLogo/faceBookIcon.svg" alt="">
|
<img src="@/assets/images/socialMediaLogo/faceBookIcon.svg" alt="">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://www.youtube.com/@AiDA-3.1" target="_blank" >
|
<a href="https://www.youtube.com/@Code-Create_AiDA" target="_blank" >
|
||||||
<img src="@/assets/images/socialMediaLogo/socialIcons.svg" alt="">
|
<img src="@/assets/images/socialMediaLogo/socialIcons.svg" alt="">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://www.linkedin.com/company/code-create-limited" target="_blank" >
|
<a href="https://www.linkedin.com/company/code-create-limited" target="_blank" >
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
|
|||||||
import { useStore } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
import { setLang } from '@/tool/guide'
|
import { setLang } from '@/tool/guide'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
import { gsap, TweenMax } from 'gsap'
|
import { gsap, TweenMax } from 'gsap'
|
||||||
import { ScrollTrigger } from 'gsap/ScrollTrigger'
|
import { ScrollTrigger } from 'gsap/ScrollTrigger'
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@@ -71,6 +71,7 @@ export default defineComponent({
|
|||||||
const {t, locale} = useI18n()
|
const {t, locale} = useI18n()
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
let registerModel = ref()
|
let registerModel = ref()
|
||||||
let data = reactive({})
|
let data = reactive({})
|
||||||
|
|
||||||
@@ -117,7 +118,14 @@ export default defineComponent({
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
window.addEventListener('resize', updataIsMoblie)
|
window.addEventListener('resize', updataIsMoblie)
|
||||||
// 初始化语言设置
|
// 初始化语言设置
|
||||||
const savedLang = localStorage.getItem('loginLanguage')
|
let savedLang = localStorage.getItem('loginLanguage')
|
||||||
|
if(route?.params?.lang == 'cn'){
|
||||||
|
savedLang = 'CHINESE_SIMPLIFIED'
|
||||||
|
localStorage.setItem('loginLanguage', savedLang)
|
||||||
|
}{
|
||||||
|
savedLang = 'ENGLISH'
|
||||||
|
localStorage.setItem('loginLanguage', savedLang)
|
||||||
|
}
|
||||||
if (savedLang) {
|
if (savedLang) {
|
||||||
isChinese.value = savedLang === 'CHINESE_SIMPLIFIED'
|
isChinese.value = savedLang === 'CHINESE_SIMPLIFIED'
|
||||||
locale.value = savedLang
|
locale.value = savedLang
|
||||||
|
|||||||
@@ -1721,9 +1721,8 @@ export default defineComponent({
|
|||||||
sloganText = this.captionGeneration
|
sloganText = this.captionGeneration
|
||||||
if(this.selectCode == "Sketchboard"){
|
if(this.selectCode == "Sketchboard"){
|
||||||
level2Type = this.selectGenerateList?.[0]?.categoryValue?this.selectGenerateList[0].categoryValue:''
|
level2Type = this.selectGenerateList?.[0]?.categoryValue?this.selectGenerateList[0].categoryValue:''
|
||||||
if(this.workspace.styleName){
|
// sloganText = `${this.workspace.styleName || 'all'},${sloganText}`
|
||||||
sloganText = `${this.workspace.styleName},${sloganText}`
|
sloganText = `'all',${sloganText}`
|
||||||
}
|
|
||||||
}else if(this.selectCode == "Printboard"){
|
}else if(this.selectCode == "Printboard"){
|
||||||
level2Type = this.scene?.value
|
level2Type = this.scene?.value
|
||||||
if(level2Type == 'Slogan' && this.captionGeneration == ''){
|
if(level2Type == 'Slogan' && this.captionGeneration == ''){
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ import {
|
|||||||
import { setCookie, getCookie, WriteCookie, clonAllCookie } from '@/tool/cookie'
|
import { setCookie, getCookie, WriteCookie, clonAllCookie } from '@/tool/cookie'
|
||||||
import { Https } from '@/tool/https'
|
import { Https } from '@/tool/https'
|
||||||
import { useStore } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
import signUp from '@/component/mainPage/signUp/index.vue'
|
import signUp from '@/component/mainPage/signUp/index.vue'
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
@@ -93,6 +93,7 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
|
const route = useRoute();
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
let data = reactive({
|
let data = reactive({
|
||||||
homeRecommendMax: null,
|
homeRecommendMax: null,
|
||||||
@@ -148,7 +149,14 @@ export default defineComponent({
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
updataIsMoblie()
|
updataIsMoblie()
|
||||||
const savedLang = localStorage.getItem('loginLanguage')
|
let savedLang = localStorage.getItem('loginLanguage') || 'ENGLISH'
|
||||||
|
if(route?.params?.lang == 'cn'){
|
||||||
|
savedLang = 'CHINESE_SIMPLIFIED'
|
||||||
|
localStorage.setItem('loginLanguage', savedLang)
|
||||||
|
}else if(route?.params?.lang == 'en'){
|
||||||
|
savedLang = 'ENGLISH'
|
||||||
|
localStorage.setItem('loginLanguage', savedLang)
|
||||||
|
}
|
||||||
if (savedLang) {
|
if (savedLang) {
|
||||||
data.isSelectSuccessively = savedLang === 'CHINESE_SIMPLIFIED'
|
data.isSelectSuccessively = savedLang === 'CHINESE_SIMPLIFIED'
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user