Merge branch 'dev_vite' of ssh://18.167.251.121:10002/aidlab/aida_front into dev_vite

This commit is contained in:
2026-01-22 13:34:44 +08:00
23 changed files with 1023 additions and 665 deletions

View File

@@ -16,29 +16,6 @@
</template> </template>
</a-range-picker> </a-range-picker>
</div> </div>
<!-- <div class="admin_state_item">
<span>Country or Region:</span>
<a-select
v-model:value="country"
:allowClear="true"
show-search
style="width: 230px"
:filter-option="filterOption"
placeholder="Select Item..."
max-tag-count="responsive"
:options="allCountry"
></a-select>
</div> -->
<!-- <div class="admin_state_item">
<span>Email:</span>
<input
v-model="email"
placeholder="Please enter email"
@keydown.enter="gettrialList"
type="text"
style="width: 230px"
/>
</div> -->
<div class="admin_state_item"> <div class="admin_state_item">
<span>{{ $t('admin.UserName') }}:</span> <span>{{ $t('admin.UserName') }}:</span>
<a-select <a-select
@@ -53,19 +30,6 @@
@keydown.enter="gettrialList" @keydown.enter="gettrialList"
></a-select> ></a-select>
</div> </div>
<!-- <div class="admin_state_item">
<span>User Type:</span>
<a-select
v-model:value="systemUser"
size="large"
style="width: 230px"
optionFilterProp="label"
:options="state"
placeholder="Please select"
allowClear
show-search
></a-select>
</div> -->
</div> </div>
<div class="admin_search"> <div class="admin_search">
<div class="admin_search_item" @click="searchHistoryList"> <div class="admin_search_item" @click="searchHistoryList">
@@ -116,6 +80,24 @@
</div> </div>
</div> </div>
<div class="admin_table_content" ref="historyTable"> <div class="admin_table_content" ref="historyTable">
<div class="admin_state_list plan_list">
<div
v-for="plan in planFilterOptions"
:key="plan.id"
class="plan_item"
:class="{
active: subscriptionPlanId === plan.id,
disabled: plan.status === 'PENDING'
}"
@click="plan.status !== 'PENDING' && selectPlanFilter(plan.id)"
>
<span class="plan_name">{{ plan.name }}</span>
<MoreOutlined
class="plan_more_icon"
@click.stop="plan.status !== 'PENDING' && openPlanRenameModal(plan)"
/>
</div>
</div>
<a-table <a-table
@resizeColumn="handleResizeColumn" @resizeColumn="handleResizeColumn"
:loading="tableLoading" :loading="tableLoading"
@@ -147,12 +129,6 @@
<div class="operate_item" @click="deleteAagree(record)"> <div class="operate_item" @click="deleteAagree(record)">
{{ $t('admin.Delete') }} {{ $t('admin.Delete') }}
</div> </div>
<!-- <div
class="operate_item"
@click="deleteGroup(record, index)"
>
Delete
</div> -->
</div> </div>
</template> </template>
</a-table> </a-table>
@@ -160,7 +136,31 @@
<allUserPoerationsVue <allUserPoerationsVue
ref="allUserPoerationsVue" ref="allUserPoerationsVue"
@searchHistoryList="searchHistoryList" @searchHistoryList="searchHistoryList"
:plan-options="planFilterOptions"
></allUserPoerationsVue> ></allUserPoerationsVue>
<div class="renamePlanModal" ref="renamePlanModal"></div>
<!-- 重命名订阅计划弹窗 -->
<a-modal
v-model:visible="renamePlanModalVisible"
:title="$t('admin.RenamePlan')"
@ok="confirmRenamePlan"
@cancel="cancelRenamePlan"
:ok-text="$t('admin.OK')"
:cancel-text="$t('admin.Cancel')"
:get-container="() => $refs.renamePlanModal"
>
<div class="rename-plan-form">
<div class="admin_state_item">
<span>{{ $t('admin.PlanName') }}:</span>
<a-input
v-model:value="renamePlanForm.planName"
:placeholder="$t('admin.InputPlanName')"
style="width: 250px"
@pressEnter="confirmRenamePlan"
/>
</div>
</div>
</a-modal>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
@@ -171,20 +171,23 @@ import {
computed, computed,
reactive, reactive,
toRefs, toRefs,
onMounted unref,
watch
} from 'vue' } from 'vue'
import { formatTime } from '@/tool/util' import { formatTime } from '@/tool/util'
import { useStore } from 'vuex' import { useStore } from 'vuex'
import { Https } from '@/tool/https' import { Https } from '@/tool/https'
import { Modal, message } from 'ant-design-vue' import { Modal, message, Input } from 'ant-design-vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue' import { ExclamationCircleOutlined, MoreOutlined } from '@ant-design/icons-vue'
import allUserPoerationsVue from './addAllUser.vue' import allUserPoerationsVue from './addAllUser.vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import SelectUser from '@/component/common/SelectUser.vue'
export default defineComponent({ export default defineComponent({
components: { allUserPoerationsVue }, components: { allUserPoerationsVue, MoreOutlined },
setup() { setup() {
const store: any = useStore() const store: any = useStore()
const currentOrganizationId = computed(
() => store.state.UserHabit.userDetail.organizationId
)
const selectedRowKeys = ref([]) as any const selectedRowKeys = ref([]) as any
const onSelectChange = (changableRowKeys: string[]) => { const onSelectChange = (changableRowKeys: string[]) => {
selectedRowKeys.value = changableRowKeys selectedRowKeys.value = changableRowKeys
@@ -203,6 +206,7 @@ export default defineComponent({
} }
}) })
}) })
const { t } = useI18n() const { t } = useI18n()
let filterData: any = reactive({ let filterData: any = reactive({
@@ -218,10 +222,16 @@ export default defineComponent({
systemUser: '', systemUser: '',
order: '', //'Ascending 升序 Descending 降序' order: '', //'Ascending 升序 Descending 降序'
orderBy: '', orderBy: '',
userName: '' userName: '',
subscriptionPlanId: ''
}) })
let renameData: any = ref({}) //修改名字选中的数据 let renameData: any = ref({}) //修改名字选中的数据
const renamePlanModalVisible = ref(false)
const renamePlanForm = reactive({
planId: null as number | null,
planName: ''
})
const columns: any = computed(() => { const columns: any = computed(() => {
return [ return [
{ {
@@ -248,13 +258,6 @@ export default defineComponent({
key: 'userName', key: 'userName',
width: 150, width: 150,
ellipsis: true ellipsis: true
// customRender: (record: any) => {
// let time = formatTime(
// record.text / 1000,
// "YYYY-MM-DD hh:mm:ss"
// );
// return time;
// },
}, },
{ {
title: t('admin.language'), title: t('admin.language'),
@@ -278,10 +281,6 @@ export default defineComponent({
{ {
title: t('admin.Credits'), title: t('admin.Credits'),
align: 'center', align: 'center',
// width: 150,
// minWidth: 100,
// maxWidth: 200,
// resizable: true,
dataIndex: 'credits', dataIndex: 'credits',
key: 'credits', key: 'credits',
width: 100, width: 100,
@@ -309,7 +308,6 @@ export default defineComponent({
width: 120, width: 120,
align: 'center', align: 'center',
fixed: 'right', fixed: 'right',
// slots:{customRender:'action'}
Operations: true Operations: true
} }
] ]
@@ -354,7 +352,8 @@ export default defineComponent({
(filterData.order = ''), //'Ascending 升序 Descending 降序' (filterData.order = ''), //'Ascending 升序 Descending 降序'
(filterData.orderBy = ''), //'Ascending 升序 Descending 降序' (filterData.orderBy = ''), //'Ascending 升序 Descending 降序'
(filterData.systemUser = ''), (filterData.systemUser = ''),
(filterData.userName = '') (filterData.userName = ''),
(filterData.subscriptionPlanId = '')
} }
let setHistoryListData = () => { let setHistoryListData = () => {
let startDate: any = filterData.rangePickerValue?.[0] let startDate: any = filterData.rangePickerValue?.[0]
@@ -377,18 +376,17 @@ export default defineComponent({
order: filterData.order, order: filterData.order,
orderBy: filterData.orderBy, orderBy: filterData.orderBy,
// userName: filterData.userName, // userName: filterData.userName,
userName: filterData.ids userName: filterData.ids,
subscriptionPlanId: filterData.subscriptionPlanId
} }
return data return data
} }
//获取列表 //获取列表
let gettrialList = () => { const gettrialList = () => {
filter.tableLoading = true filter.tableLoading = true
let data = setHistoryListData() let data = setHistoryListData()
Https.axiosPost(Https.httpUrls.subAccountList, data).then((rv: any) => { Https.axiosPost(Https.httpUrls.subAccountList, data).then((rv: any) => {
if (rv) { if (rv) {
console.log(rv)
// this.dataList = rv
filter.dataList = rv.content filter.dataList = rv.content
filterData.total = rv.total filterData.total = rv.total
filter.tableLoading = false filter.tableLoading = false
@@ -417,6 +415,66 @@ export default defineComponent({
// 使用 option.label 进行搜索 // 使用 option.label 进行搜索
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
} }
// 订阅计划筛选(按钮点击)
const selectPlanFilter = async (planId: string) => {
filterData.subscriptionPlanId = planId
// 切换管理员订阅计划
Https.axiosGet(Https.httpUrls.switchSubscribePlan, {
params: {
targetSubscriptionPlanId: planId,
adminAccId: store.state.UserHabit.userDetail.id
}
}).then((res: any) => {
console.log(res)
})
searchHistoryList()
}
const planFilterOptions = ref([])
const fetchSubscribePlanList = () => {
const orgId = currentOrganizationId.value
if (!orgId) return
Https.axiosPost(Https.httpUrls.searchSubscribeByOrg, {
organizationId: orgId,
status: ['ACTIVE', 'PENDING']
}).then(res => {
// 将与当前用户 subscriptionPlanId 相同的订阅计划放到第一个
const userSubscriptionPlanId = store.state.UserHabit.userDetail.subscriptionPlanId
if (userSubscriptionPlanId && Array.isArray(res)) {
const sortedList = [...res].sort((a: any, b: any) => {
const isAUserPlan = a.id == userSubscriptionPlanId
const isBUserPlan = b.id == userSubscriptionPlanId
if (isAUserPlan && !isBUserPlan) return -1
if (!isAUserPlan && isBUserPlan) return 1
return 0
})
planFilterOptions.value = sortedList
} else {
planFilterOptions.value = res
}
})
}
// 监听组织ID获取到值后再拉取订阅计划
watch(
() => currentOrganizationId.value,
orgId => {
if (orgId) {
fetchSubscribePlanList()
const userSubscriptionPlanId =
store.state.UserHabit.userDetail.subscriptionPlanId
if (userSubscriptionPlanId) {
selectPlanFilter(userSubscriptionPlanId)
}
}
},
{ immediate: true }
)
// 打开重命名弹窗(基于当前点击的计划)
const openPlanRenameModal = plan => {
renamePlanForm.planId = plan.id
renamePlanForm.planName = plan?.name || ''
renamePlanModalVisible.value = true
console.log(renamePlanForm)
}
let addhHistoryList = () => { let addhHistoryList = () => {
allUserPoerationsVue.value.init({ value: 'Add', label: t('admin.add') }, '') allUserPoerationsVue.value.init({ value: 'Add', label: t('admin.add') }, '')
} }
@@ -521,6 +579,33 @@ export default defineComponent({
gettrialList() gettrialList()
}) })
} }
// 确认重命名
const confirmRenamePlan = () => {
if (!renamePlanForm.planName || !renamePlanForm.planName.trim()) {
message.warning(t('admin.PlanNameRequired'))
return
}
Https.axiosPost(Https.httpUrls.updateSubscribePlan, {
id: renamePlanForm.planId,
name: renamePlanForm.planName.trim()
})
.then((rv: any) => {
message.success(t('admin.RenamePlanSuccess'))
renamePlanModalVisible.value = false
fetchSubscribePlanList()
})
.catch((error: any) => {
message.error(error.message || t('admin.RenamePlanFailed'))
})
}
// 取消重命名
const cancelRenamePlan = () => {
renamePlanModalVisible.value = false
renamePlanForm.planId = null
renamePlanForm.planName = ''
}
onMounted(() => { onMounted(() => {
let allCountry: any = sessionStorage.getItem('allCountry') let allCountry: any = sessionStorage.getItem('allCountry')
if (allCountry) { if (allCountry) {
@@ -545,7 +630,15 @@ export default defineComponent({
ExportAccountData, ExportAccountData,
uploadTemplate, uploadTemplate,
deleteList, deleteList,
deleteAagree deleteAagree,
planFilterOptions,
selectPlanFilter,
openPlanRenameModal,
renamePlanModalVisible,
renamePlanForm,
confirmRenamePlan,
cancelRenamePlan,
fetchSubscribePlanList
} }
}, },
data() { data() {
@@ -557,10 +650,21 @@ export default defineComponent({
} }
}, },
mounted() { mounted() {
let historyTable: any = this.$refs.historyTable this.updateTableHeight()
this.historyTableHeight = historyTable.clientHeight - 200 window.addEventListener('resize', this.updateTableHeight)
}, },
methods: {} beforeUnmount() {
window.removeEventListener('resize', this.updateTableHeight)
},
methods: {
updateTableHeight() {
const historyTable: any = this.$refs.historyTable
if (historyTable) {
// 为底部分页器预留固定空间,使表格部分高度固定且分页器始终可见
this.historyTableHeight = historyTable.clientHeight - 200
}
}
}
}) })
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@@ -590,6 +694,79 @@ export default defineComponent({
font-size: 1.6rem; font-size: 1.6rem;
} }
} }
.plan_list {
margin-top: 1rem;
display: flex;
// flex-wrap: wrap;
padding-left: 2.8rem;
column-gap: 0.6rem;
margin-bottom: 2rem;
.plan_item {
height: 4rem;
width: auto;
min-width: 10rem;
display: flex;
align-items: center;
justify-content: center;
// font-size: 1.8rem;
font-weight: 600;
border-radius: 1.3rem;
color: #fff;
cursor: pointer;
border: 1.8px solid #000;
background-color: #000;
padding: 0 1rem 0 2rem;
&:hover {
color: #000;
background-color: #fff;
}
&.active {
background: #ffffff;
color: #000000;
}
&.disabled {
opacity: 0.5;
cursor: not-allowed;
background-color: #d9d9d9;
border-color: #d9d9d9;
color: #999;
&:hover {
background-color: #d9d9d9;
color: #999;
}
}
}
.plan_item {
column-gap: 0.6rem;
}
.plan_more_icon {
font-size: 1.6rem;
cursor: pointer;
}
}
.subscription-plan-cell {
display: flex;
align-items: center;
justify-content: center;
}
.rename-plan-form {
padding: 2rem 0;
.admin_state_item {
display: flex;
align-items: center;
> span {
width: 10rem;
margin-right: 1rem;
}
}
}
.all-user { .all-user {
.admin_table_content { .admin_table_content {
:deep(.ant-table-wrapper) { :deep(.ant-table-wrapper) {
@@ -598,3 +775,4 @@ export default defineComponent({
} }
} }
</style> </style>

View File

@@ -207,7 +207,8 @@ export class BackgroundSizeCommand extends Command {
this.bgLayer = this.layers.value.find((layer) => layer.isBackground); this.bgLayer = this.layers.value.find((layer) => layer.isBackground);
// 记录原尺寸 // 记录原尺寸
this.backgroundObject = findObjectById(this.canvas, this.bgLayer.fabricObject.id).object; this.bgId = this.bgLayer.fabricObject?.id || this.bgLayer.fabricObjects?.[0]?.id;
this.backgroundObject = findObjectById(this.canvas, this.bgId).object;
this.oldWidth = this.backgroundObject.width; this.oldWidth = this.backgroundObject.width;
this.oldHeight = this.backgroundObject.height; this.oldHeight = this.backgroundObject.height;

View File

@@ -11,6 +11,7 @@ const layerManager = inject("layerManager");
const isShowLayerPanel = inject("isShowLayerPanel", ref(false)); const isShowLayerPanel = inject("isShowLayerPanel", ref(false));
const props = defineProps({ const props = defineProps({
title: String,
activeTool: String, activeTool: String,
canvasWidth: Number, canvasWidth: Number,
canvasHeight: Number, canvasHeight: Number,
@@ -274,7 +275,7 @@ onMounted(() => {
<template> <template>
<div class="canvas-header"> <div class="canvas-header">
<div class="canvas-header-wrapper"> <div class="canvas-header-wrapper">
<span class="canvas-title">{{ $t('Canvas.Canvas') }}</span> <span class="canvas-title">{{ props.title || $t("Canvas.Canvas") }}</span>
<!-- 默认设置 --> <!-- 默认设置 -->
<!-- v-if=" <!-- v-if="
!activeTool || !activeTool ||

View File

@@ -242,7 +242,7 @@ const canDeleteComputed = computed(() => {
return parentLayer?.children?.length > 1; return parentLayer?.children?.length > 1;
} }
// 否则直接返回根图层的可删除状态 // 否则直接返回根图层的可删除状态
return props.layers.length > 3; return true;
}); });
</script> </script>

View File

@@ -414,14 +414,14 @@ function deleteSelectedLayers() {
} }
// 检查删除后是否还有足够的普通图层 // 检查删除后是否还有足够的普通图层
const remainingNormalLayers = layers.value.filter( // const remainingNormalLayers = layers.value.filter(
(layer) => !layer.isBackground && !layer.isFixed && !selectedLayerIds.value.includes(layer.id) // (layer) => !layer.isBackground && !layer.isFixed && !selectedLayerIds.value.includes(layer.id)
).length; // ).length;
if (remainingNormalLayers < 1) { // if (remainingNormalLayers < 1) {
console.warn("不能删除所有普通图层"); // console.warn("不能删除所有普通图层");
return; // return;
} // }
// 确认删除 // 确认删除
if (selectedLayers.length > 1) { if (selectedLayers.length > 1) {
@@ -876,13 +876,15 @@ function toggleSelectedLayersVisibility() {
function canDeleteLayers() { function canDeleteLayers() {
const selectedLayers = getSelectedLayers(); const selectedLayers = getSelectedLayers();
console.log(selectedLayers);
if (selectedLayers.length === 0) return false; if (selectedLayers.length === 0) return false;
// 检查是否包含不能删除的图层 // 检查是否包含不能删除的图层
const undeletableLayers = selectedLayers.filter((layer) => layer.isBackground || layer.isFixed); const undeletableLayers = selectedLayers.filter((layer) => layer.isBackground || layer.isFixed);
if (undeletableLayers.length > 0) return false; if (undeletableLayers.length > 0) return false;
return true
// 检查删除后是否还有足够的普通图层 // 检查删除后是否还有足够的普通图层
const remainingNormalLayers = layers.value.filter( const remainingNormalLayers = layers.value.filter(
(layer) => !layer.isBackground && !layer.isFixed && !selectedLayerIds.value.includes(layer.id) (layer) => !layer.isBackground && !layer.isFixed && !selectedLayerIds.value.includes(layer.id)

View File

@@ -67,6 +67,10 @@ const emit = defineEmits([
]); ]);
const props = defineProps({ const props = defineProps({
title: {
type: String,
default: "", // 默认空
},
canvasJSON: { canvasJSON: {
type: [Object, String], type: [Object, String],
default: "", // 默认空 default: "", // 默认空
@@ -1192,6 +1196,7 @@ isContainNormalLayer})
<!-- 头部菜单组件 --> <!-- 头部菜单组件 -->
<div class="header-menu"> <div class="header-menu">
<HeaderMenu <HeaderMenu
:title="props.title"
v-if="canvasManagerLoaded" v-if="canvasManagerLoaded"
:activeTool="activeTool" :activeTool="activeTool"
:canvasWidth="canvasWidth" :canvasWidth="canvasWidth"

View File

@@ -1330,7 +1330,7 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
} }
// 解析JSON字符串 // 解析JSON字符串
try { try {
const parsedJson = JSON.parse(json); const parsedJson = window.testCanvasJson || JSON.parse(json);
console.log("加载画布JSON数据:", parsedJson); console.log("加载画布JSON数据:", parsedJson);
this.FixJsonIdLoss(parsedJson); this.FixJsonIdLoss(parsedJson);
this.canvasWidth.value = parsedJson.canvasWidth || this.width; this.canvasWidth.value = parsedJson.canvasWidth || this.width;
@@ -1411,7 +1411,7 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
// console.log("图层关联验证结果:", isValidate); // console.log("图层关联验证结果:", isValidate);
// 排序 // 排序
// 使用LayerSort工具重新排列画布对象如果可用 // 使用LayerSort工具重新排列画布对象如果可用
await this?.layerManager?.layerSort?.rearrangeObjects(); await this?.layerManager?.layerSort?.rearrangeObjectsAsync();
this.layerManager.activeLayerId.value = this.layers.value[0] this.layerManager.activeLayerId.value = this.layers.value[0]
.children?.length .children?.length
@@ -1455,14 +1455,20 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
const layers = json?.layers || []; const layers = json?.layers || [];
const objects = json?.canvas?.objects || []; const objects = json?.canvas?.objects || [];
layers.forEach((layer) => { layers.forEach((layer) => {
if(!layer.fabricObjects?.length && !layer.fabricObject){ if(!layer.fabricObjects?.[0]?.id && !layer.fabricObject?.id){
const obj = objects?.find((o) => o.layerId === layer.id); const obj = objects?.find((o) => o.layerId === layer.id);
if(!obj) return; if(obj) {
layer.fabricObjects = [{ layer.fabricObjects = [{
id: obj.id, id: obj.id,
type: obj.type, type: obj.type,
}] }]
} }
}
})
// 排序
objects.sort((a, b) => {
if (a.isBackground) return -1;
if (b.isBackground) return 1;
}) })
} }

View File

@@ -71,17 +71,17 @@ export class LayerSort {
// if (!layer.visible) { // if (!layer.visible) {
// continue; // continue;
// } // }
let id = layer.fabricObject?.id || layer.fabricObjects?.[0]?.id || null;
// 处理不同类型的图层 // 处理不同类型的图层
if (layer.isBackground && layer.fabricObject) { if (layer.isBackground && id) {
// 背景图层对象放在最底层 // 背景图层对象放在最底层
zIndexMap.set(layer.fabricObject.id, currentZIndex++); zIndexMap.set(id, currentZIndex++);
} else if (layer.isFixed && layer.fabricObject) { } else if (layer.isFixed && id) {
// 固定图层对象 // 固定图层对象
zIndexMap.set(layer.fabricObject.id, currentZIndex++); zIndexMap.set(id, currentZIndex++);
} else if (layer.isFixedOther && layer.fabricObject) { } else if (layer.isFixedOther && id) {
// 其他固定图层对象 // 其他固定图层对象
zIndexMap.set(layer.fabricObject.id, currentZIndex++); zIndexMap.set(id, currentZIndex++);
} else if (!layer.isBackground && !layer.isFixed) { } else if (!layer.isBackground && !layer.isFixed) {
// 普通图层 // 普通图层
currentZIndex = this.processLayerObjects( currentZIndex = this.processLayerObjects(
@@ -91,7 +91,6 @@ export class LayerSort {
); );
} }
} }
return zIndexMap; return zIndexMap;
} }

View File

@@ -545,6 +545,7 @@ export default defineComponent({
await detailDom.canvasBox.privewDetail() await detailDom.canvasBox.privewDetail()
await upDateFrontBackSketch() await upDateFrontBackSketch()
saveCanvasJSONToSession() saveCanvasJSONToSession()
await uploadSelectDetail()
detailData.loadingShow = false detailData.loadingShow = false
} }
} }
@@ -672,22 +673,16 @@ export default defineComponent({
if(detailData.isEditPattern.value == 'canvasEditor'){ if(detailData.isEditPattern.value == 'canvasEditor'){
// await detailDom.canvasBox.saveCanvas() // await detailDom.canvasBox.saveCanvas()
const allInfo = await (detailDom.canvasBox as any).getCanvasElement() const allInfo = await (detailDom.canvasBox as any).getCanvasElement()
if(allInfo.trims?.length > 0){ let trimsValue = {
// detailData.selectDetail.trims.prints = allInfo.trims data:allInfo.trims || [],
let value = {
data:allInfo.trims,
str:'element' str:'element'
} }
store.commit('DesignDetail/setNewDetail',value) store.commit('DesignDetail/setNewDetail',trimsValue)
} let printValue = {
if(allInfo.prints?.length > 0){ data:allInfo.prints || [],
// detailData.selectDetail.printObject.prints = allInfo.prints
let value = {
data:allInfo.prints,
str:'print' str:'print'
} }
store.commit('DesignDetail/setNewDetail',value) store.commit('DesignDetail/setNewDetail',printValue)
}
if(allInfo.color?.color?.rgba){ if(allInfo.color?.color?.rgba){
let canvasColor = allInfo.color.color; let canvasColor = allInfo.color.color;
let colorData:any = await getColorName(allInfo.color.color?.rgba) let colorData:any = await getColorName(allInfo.color.color?.rgba)
@@ -713,8 +708,61 @@ export default defineComponent({
if(detailData.currentDetailType == 'color'){ if(detailData.currentDetailType == 'color'){
detailData.detailLeftColorKey++ detailData.detailLeftColorKey++
} }
}else{
let value = {
data:{},
str:'color'
}
store.commit('DesignDetail/setNewDetail',value)
} }
} }
}
const uploadSelectDetail = async ()=>{//更新选中的detail
// await detailDom.canvasBox.saveCanvas()
const allInfo = await (detailDom.canvasBox as any).getCanvasElement()
let color:any = {}
if(allInfo.color?.color?.rgba){
let canvasColor = allInfo.color.color;
let colorData:any = await getColorName(allInfo.color.color?.rgba)
color = {
hsv:{
h:colorData.h,
s:colorData.s,
v:colorData.v,
},
name:colorData.name,
tcx:colorData.tcx,
rgba:canvasColor.rgba,
hex:rgbaToHex([canvasColor.rgba.r,canvasColor.rgba.g,canvasColor.rgba.b]),
}
if(canvasColor.gradient){
color.gradient = canvasColor.gradient
}
if(detailData.currentDetailType == 'color'){
detailData.detailLeftColorKey++
}
}
if(detailData.isEditPattern.value !== 'canvasEditor'){
delete detailData.selectDetail.newDetail
detailData.selectDetail.trims.prints = allInfo.trims || []
detailData.selectDetail.printObject.prints = allInfo.prints || []
detailData.selectDetail.color = color
}else{
if(detailData.currentDetailType == 'color'){
delete detailData.selectDetail.newDetail.color
detailData.selectDetail.color = color
}
if(detailData.currentDetailType == 'print'){
delete detailData.selectDetail.newDetail.print
detailData.selectDetail.printObject.prints = allInfo.prints || []
}
if(detailData.currentDetailType == 'element'){
delete detailData.selectDetail.newDetail.element
detailData.selectDetail.trims.prints = allInfo.trims || []
}
}
} }
const canvasReload = async ()=>{ const canvasReload = async ()=>{
if(detailData.isEditPattern.value){ if(detailData.isEditPattern.value){

View File

@@ -8,6 +8,7 @@
<div class="canvas" :class="{'active': currentView === 'canvasEditor'}"@click.stop> <div class="canvas" :class="{'active': currentView === 'canvasEditor'}"@click.stop>
<!-- :clothingMinIOPath="selectDetail.minIOPath" 部件选取 --> <!-- :clothingMinIOPath="selectDetail.minIOPath" 部件选取 -->
<editCanvas v-if="canvasLoad" :config="canvasConfig" <editCanvas v-if="canvasLoad" :config="canvasConfig"
:title="t('CanvasTitle.ModifyItem')"
@canvasInit="editSketchCanvasInit" @canvasInit="editSketchCanvasInit"
is-edit is-edit
:clothingImageUrl="selectDetail.path" :clothingImageUrl="selectDetail.path"
@@ -26,6 +27,7 @@
</div> </div>
<div class="editFrontBack" v-if="currentView === 'redGreenExample'" @click.stop> <div class="editFrontBack" v-if="currentView === 'redGreenExample'" @click.stop>
<editCanvas v-if="canvasLoad" :config="canvasConfig" <editCanvas v-if="canvasLoad" :config="canvasConfig"
:title="t('CanvasTitle.RedGreen')"
@canvasInit="editFrontBackCanvasInit" @canvasInit="editFrontBackCanvasInit"
:enabledRedGreenMode="true" :enabledRedGreenMode="true"
:clothingImageUrl="selectDetail.path" :clothingImageUrl="selectDetail.path"
@@ -40,7 +42,7 @@
</editCanvas> </editCanvas>
</div> </div>
<div class="editSketch" v-if="currentView === 'editSketch'" @click.stop> <div class="editSketch" v-if="currentView === 'editSketch'" @click.stop>
<generalMiniCanvas ref="generalMiniCanvas" :btnShow="false" :imgUrl="selectDetail.sketchString || selectDetail.path"></generalMiniCanvas> <generalMiniCanvas ref="generalMiniCanvas" :isChangeCanvasSize="false" :canvasTitle="t('CanvasTitle.ModifySketch')" :btnShow="false" :imgUrl="selectDetail.sketchString || selectDetail.path"></generalMiniCanvas>
</div> </div>
</div> </div>
@@ -287,12 +289,27 @@ export default defineComponent({
const saveCanvas = async (canvasData:any)=>{ const saveCanvas = async (canvasData:any)=>{
const index = detailData.designDetail.clothes.findIndex(item => item.id === canvasData.id); const index = detailData.designDetail.clothes.findIndex(item => item.id === canvasData.id);
await new Promise<void>((resolve, reject) => { await new Promise<void>((resolve, reject) => {
let canvasJSON = JSON.parse(canvasData.canvasJSON) if(!detailDom?.editCanvas)return resolve()
if(!canvasJSON)return resolve() let canvasJSON = detailDom?.editCanvas?.getJSON()
// canvasData.canvas.objects.forEach((objectsItem:any) => { let canvasData = JSON.parse(canvasJSON)
// if(objectsItem.type == 'image')objectsItem.minioUrl = getMinioUrl(objectsItem.src) if(!canvasData)return resolve()
// }); function deepProcessObjects(data:any, callback:any) {
let blob = new Blob([JSON.stringify(canvasJSON)], { type: "application/json" }); if (!Array.isArray(data)) return data;
return data.map(item => {
callback(item)
const processedItem = {...item};
if (processedItem.objects &&
Array.isArray(processedItem.objects) &&
processedItem.objects.length > 0) {
processedItem.objects = deepProcessObjects(processedItem.objects, callback);
}
return processedItem;
});
}
canvasData.canvas.objects = deepProcessObjects(canvasData.canvas.objects,(item:any)=>{
if(item.type == 'image')item.minioUrl = getMinioUrl(item.src)
})
let blob = new Blob([JSON.stringify(canvasData)], { type: "application/json" });
let formData = new FormData(); let formData = new FormData();
formData.append("file", blob, "data.json"); formData.append("file", blob, "data.json");
formData.append("designItemDetailId", detailData.selectDetail.id); formData.append("designItemDetailId", detailData.selectDetail.id);
@@ -410,6 +427,7 @@ export default defineComponent({
return{ return{
...toRefs(detailDom), ...toRefs(detailDom),
...toRefs(detailData), ...toRefs(detailData),
t,
editFront, editFront,
privewDetail, privewDetail,
setFrontBackColor, setFrontBackColor,

View File

@@ -14,7 +14,12 @@
<div ref="moveableContainer" class="moveableContainer"></div> <div ref="moveableContainer" class="moveableContainer"></div>
</div> </div>
<div class="designOpenrtion_imgMask" v-if="!frontBack?.body?.path"> <div class="designOpenrtion_imgMask" v-if="!frontBack?.body?.path">
<img :src="selectDetail?.undividedLayerWithSinglePrint || selectDetail?.undividedLayer || selectDetail?.path" style="object-fit: cover;" alt=""> <div class="designOpenrtion_print">
<img v-if="frontBack.back?.[0].imageUrl" :src="frontBack.back?.[0].imageUrl" style="object-fit: cover;" alt="">
</div>
<div class="detail_modal_item_front" style="position: relative;">
<img :src="frontBack.front?.[0].imageUrl || selectDetail?.path" style="object-fit: cover;" alt="">
</div>
<!-- <img @load="setSelectSketch()" :src="designDetail?.currentFullBodyView || selectDetail?.undividedLayer" style="object-fit: cover;" alt=""> --> <!-- <img @load="setSelectSketch()" :src="designDetail?.currentFullBodyView || selectDetail?.undividedLayer" style="object-fit: cover;" alt=""> -->
</div> </div>
</div> </div>

View File

@@ -925,6 +925,8 @@ export default defineComponent({
}, },
onCancel() {} onCancel() {}
}) })
}else{
this.fileList = this.fileList.filter((item: any) => item.imgUrl)
} }
}) })
}, },

View File

@@ -854,6 +854,10 @@ export default defineComponent({
font-size: 2.2rem; font-size: 2.2rem;
font-weight: bold; font-weight: bold;
color: #030303; color: #030303;
@media (max-width: 767px) {
font-size: 1.2rem;
margin-left: .5rem;
}
} }
.email_last_step_block_icon { .email_last_step_block_icon {
cursor: pointer; cursor: pointer;

View File

@@ -161,6 +161,13 @@
font-size: 2.4rem; font-size: 2.4rem;
line-height: 8.7rem; line-height: 8.7rem;
outline: none; outline: none;
@media (max-width: 767px) {
border-radius: .7rem;
width: 3.5rem;
height: 3.5rem;
font-size: 1.8rem;
line-height: 3.5rem;
}
} }
input:last-of-type { input:last-of-type {
margin-right: 0; margin-right: 0;

View File

@@ -335,9 +335,22 @@ export default defineComponent({
let canvasData = JSON.parse(canvasJSON) let canvasData = JSON.parse(canvasJSON)
if(!canvasData)return if(!canvasData)return
canvasData.canvas.objects.forEach((objectsItem:any) => { function deepProcessObjects(data:any, callback:any) {
if(objectsItem.type == 'image')objectsItem.minioUrl = getMinioUrl(objectsItem.src) if (!Array.isArray(data)) return data;
return data.map(item => {
callback(item)
const processedItem = {...item};
if (processedItem.objects &&
Array.isArray(processedItem.objects) &&
processedItem.objects.length > 0) {
processedItem.objects = deepProcessObjects(processedItem.objects, callback);
}
return processedItem;
}); });
}
canvasData.canvas.objects = deepProcessObjects(canvasData.canvas.objects,(item:any)=>{
if(item.type == 'image')item.minioUrl = getMinioUrl(item.src)
})
let blob = new Blob([JSON.stringify(canvasData)], { type: "application/json" }); let blob = new Blob([JSON.stringify(canvasData)], { type: "application/json" });
let formData = new FormData(); let formData = new FormData();
formData.append("file", blob, "data.json"); formData.append("file", blob, "data.json");

View File

@@ -206,11 +206,22 @@ export default defineComponent({
if(!canvasJSON)return if(!canvasJSON)return
if(!store.state.Workspace.probjects?.id)return if(!store.state.Workspace.probjects?.id)return
let canvasData = JSON.parse(canvasJSON) let canvasData = JSON.parse(canvasJSON)
console.log(canvasData) function deepProcessObjects(data:any, callback:any) {
canvasData.canvas.objects.forEach((objectsItem:any) => { if (!Array.isArray(data)) return data;
if(objectsItem.type == 'image')objectsItem.minioUrl = getMinioUrl(objectsItem.src) return data.map(item => {
callback(item)
const processedItem = {...item};
if (processedItem.objects &&
Array.isArray(processedItem.objects) &&
processedItem.objects.length > 0) {
processedItem.objects = deepProcessObjects(processedItem.objects, callback);
}
return processedItem;
}); });
}
canvasData.canvas.objects = deepProcessObjects(canvasData.canvas.objects,(item:any)=>{
if(item.type == 'image')item.minioUrl = getMinioUrl(item.src)
})
let blob = new Blob([JSON.stringify(canvasData)], { type: "application/json" }); let blob = new Blob([JSON.stringify(canvasData)], { type: "application/json" });
let formData = new FormData(); let formData = new FormData();
formData.append("file", blob, "data.json"); formData.append("file", blob, "data.json");

View File

@@ -79,7 +79,7 @@
Forgot password Forgot password
</div> --> </div> -->
</div> </div>
<div class="password_input_block"> <div class="password_input_block" v-show="emailStap !== 2">
<div v-show="passwordConditionShow" class="conditionShow"> <div v-show="passwordConditionShow" class="conditionShow">
<div class="item"> <div class="item">
<div class="icon"> <div class="icon">
@@ -144,12 +144,13 @@
@click="changePasswordType()" @click="changePasswordType()"
></div> ></div>
</div> </div>
<span style="font-weight: 400; opacity: 0.7" <span style="font-weight: 400; opacity: 0.7" v-show="emailStap !== 2"
>{{ userI18n[selectUserI18n].inputPasswordTip }}</span >{{ userI18n[selectUserI18n].inputPasswordTip }}</span
> >
<div class="login_form_title marign_top30">{{ userI18n[selectUserI18n].Email }}</div> <div class="login_form_title marign_top30" v-show="emailStap !== 2">{{ userI18n[selectUserI18n].Email }}</div>
<input <input
class="login_form_input" class="login_form_input"
v-show="emailStap !== 2"
:placeholder="userI18n[selectUserI18n].inputEmail" :placeholder="userI18n[selectUserI18n].inputEmail"
v-model="email" v-model="email"
@keydown.enter="submitPerLogin()" @keydown.enter="submitPerLogin()"
@@ -917,6 +918,7 @@ export default defineComponent({
position: relative; position: relative;
@media (max-width: 768px) { @media (max-width: 768px) {
margin-top: 2.4rem; margin-top: 2.4rem;
height: 20rem;
} }
&[state="2"] { &[state="2"] {
> * { > * {
@@ -1015,6 +1017,9 @@ export default defineComponent({
// margin-top: 4rem; // margin-top: 4rem;
.email_last_step_bottom { .email_last_step_bottom {
padding: 0 40px; padding: 0 40px;
@media (max-width: 767px) {
padding: 0 2rem;
}
} }
.email_last_step_block { .email_last_step_block {
padding: 10px; padding: 10px;
@@ -1028,6 +1033,10 @@ export default defineComponent({
font-size: 2.2rem; font-size: 2.2rem;
font-weight: bold; font-weight: bold;
color: #030303; color: #030303;
@media (max-width: 767px) {
font-size: 1.2rem;
margin-left: .5rem;
}
} }
.email_last_step_block_icon { .email_last_step_block_icon {
cursor: pointer; cursor: pointer;
@@ -1229,6 +1238,9 @@ export default defineComponent({
font-weight: bold; font-weight: bold;
color: #000; color: #000;
cursor: pointer; cursor: pointer;
@media (max-width: 767px) {
font-size: 1rem;
}
} }
.email_last_step_des { .email_last_step_des {
@@ -1237,16 +1249,25 @@ export default defineComponent({
justify-content: space-between; justify-content: space-between;
margin-top: 4rem; margin-top: 4rem;
margin-bottom: 2rem; margin-bottom: 2rem;
@media (max-width: 767px) {
margin-top: 2rem;
margin-bottom: 1rem;
}
.sent_email_content { .sent_email_content {
font-size: 1.8rem; font-size: 1.8rem;
font-weight: bold; font-weight: bold;
color: #a5b0c2; color: #a5b0c2;
@media (max-width: 767px) {
font-size: 1.2rem;
}
} }
.email_tip_content { .email_tip_content {
font-size: 1.4rem; font-size: 1.4rem;
color: #030303; color: #030303;
@media (max-width: 767px) {
font-size: 1.2rem;
}
} }
} }
} }

View File

@@ -2,11 +2,13 @@
<div class="generalCanvas"> <div class="generalCanvas">
<div class="canvasBox" ref="canvasBox"> <div class="canvasBox" ref="canvasBox">
<editCanvas v-if="canvasLoad" :config="canvasConfig" <editCanvas v-if="canvasLoad" :config="canvasConfig"
:title="canvasTitle"
@canvasInit="canvasInit" @canvasInit="canvasInit"
@changeCanvas="changeCanvas" @changeCanvas="changeCanvas"
is-general is-general
:hideCanvas="hideCanvas" :hideCanvas="hideCanvas"
:isBackgroundChangeable="false" :isBackgroundChangeable="false"
:isChangeCanvasSize="isChangeCanvasSize"
ref="editCanvas"></editCanvas> ref="editCanvas"></editCanvas>
</div> </div>
<div class="btn" v-if="btnShow"> <div class="btn" v-if="btnShow">
@@ -35,6 +37,14 @@ export default defineComponent({
editCanvas, editCanvas,
}, },
props:{ props:{
canvasTitle:{
type:String,
default:''
},
isChangeCanvasSize:{
type:Boolean,
default:true
},
imgUrl:{ imgUrl:{
type:String, type:String,
default:'' default:''
@@ -174,6 +184,7 @@ export default defineComponent({
return { return {
...toRefs(data), ...toRefs(data),
...toRefs(dataDom), ...toRefs(dataDom),
...toRefs(props),
isShowMark, isShowMark,
canvasLoadAddImg, canvasLoadAddImg,
getCanvasData, getCanvasData,

View File

@@ -165,9 +165,22 @@ export default defineComponent({
time = setTimeout(()=>{ time = setTimeout(()=>{
let canvasData = JSON.parse(canvasJSON) let canvasData = JSON.parse(canvasJSON)
if(!canvasData)return if(!canvasData)return
canvasData.canvas.objects.forEach((objectsItem:any) => { function deepProcessObjects(data:any, callback:any) {
if(objectsItem.type == 'image')objectsItem.minioUrl = getMinioUrl(objectsItem.src) if (!Array.isArray(data)) return data;
return data.map(item => {
callback(item)
const processedItem = {...item};
if (processedItem.objects &&
Array.isArray(processedItem.objects) &&
processedItem.objects.length > 0) {
processedItem.objects = deepProcessObjects(processedItem.objects, callback);
}
return processedItem;
}); });
}
canvasData.canvas.objects = deepProcessObjects(canvasData.canvas.objects,(item:any)=>{
if(item.type == 'image')item.minioUrl = getMinioUrl(item.src)
})
let blob = new Blob([JSON.stringify(canvasData)], { type: "application/json" }); let blob = new Blob([JSON.stringify(canvasData)], { type: "application/json" });
let formData = new FormData(); let formData = new FormData();
formData.append("file", blob, "data.json"); formData.append("file", blob, "data.json");

View File

@@ -1147,6 +1147,11 @@ export default {
System: '系统', System: '系统',
Library: '库' Library: '库'
}, },
CanvasTitle: {
ModifySketch: '修改草图',
ModifyItem: '修改单品',
RedGreen: '编辑前片后片',
},
Canvas: { Canvas: {
Canvas: '画布', Canvas: '画布',
layer: '图层', layer: '图层',

View File

@@ -1181,6 +1181,11 @@ export default {
System: 'System', System: 'System',
Library: 'Library' Library: 'Library'
}, },
CanvasTitle: {
ModifySketch: 'Modify Sketch',
ModifyItem: 'Modify Item',
RedGreen: 'Front and back section',
},
Canvas: { Canvas: {
Canvas: 'Canvas', Canvas: 'Canvas',
layer: 'Layer', layer: 'Layer',

View File

@@ -1814,6 +1814,8 @@ export default defineComponent({
} }
}); });
}else{
this.generateList[selectCodeStr] = this.generateList[selectCodeStr].filter((item: any) => item.imgUrl)
} }
}); });
}, },
@@ -2420,6 +2422,7 @@ export default defineComponent({
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
position: absolute;
} }
&:hover .img_item_hover{ &:hover .img_item_hover{
// display: block; // display: block;

View File

@@ -8,15 +8,15 @@
<!-- <div class="upgrade-content-text">System upgrading</div> --> <!-- <div class="upgrade-content-text">System upgrading</div> -->
<div class="upgrade-content-text">System maintenance</div> <div class="upgrade-content-text">System maintenance</div>
<!-- 没有截至时间 --> <!-- 没有截至时间 -->
<div class="upgrade-content-textab">The AiDA system cannot be accessed temporarily due to system server maintenance. We apologize for any inconvenience this may cause and thank you for your understanding.</div> <!-- <div class="upgrade-content-textab">The AiDA system cannot be accessed temporarily due to system server maintenance. We apologize for any inconvenience this may cause and thank you for your understanding.</div> -->
<!-- <div class="upgrade-content-textab">Due to the system server upgrade, we will start the upgrade from 9:30 am Hong Kong time on the weekend of October 20th until October 21st. During this time,<br> the AiDA system will be temporarily inaccessible. We apologize for any inconvenience this may cause and thank you for your understanding.</div> --> <!-- <div class="upgrade-content-textab">Due to the system server upgrade, we will start the upgrade from 9:30 am Hong Kong time on the weekend of October 20th until October 21st. During this time,<br> the AiDA system will be temporarily inaccessible. We apologize for any inconvenience this may cause and thank you for your understanding.</div> -->
<!-- 有截至时间 --> <!-- 有截至时间 -->
<!-- <div class="upgrade-content-textab">Due to system server upgrades, we will be upgrading from Tuesday, September 2 at 00:00 (HKT) to Wednesday, September 3 at 00:00. During this period, the AiDA system will be temporarily inaccessible. <br>We sincerely apologize for the inconvenience caused and thank you for your understanding</div> --> <div class="upgrade-content-textab">Due to system server upgrades, maintenance will be carried out from 21:00 to 22:00 on December 19.<br>The AiDA system will be temporarily unavailable during this period. We sincerely apologize for any inconvenience caused and thank you for your understanding.</div>
<br> <br>
<br> <br>
<br> <br>
<div class="upgrade-content-textab">由于系统服务器维护AiDA系统暂时无法访问对于由此造成的任何不便我们深表歉意并感谢您的理解</div> <!-- <div class="upgrade-content-textab">由于系统服务器维护AiDA系统暂时无法访问对于由此造成的任何不便我们深表歉意并感谢您的理解</div> -->
<!-- <div class="upgrade-content-textab">由于系统服务器升级我们将于9月2日星期二凌晨00:00香港时间至9月3日星期三凌晨00:00进行升级<br>在此期间AiDA系统将暂时无法访问给您带来的不便我们深表歉意并感谢您的理解</div> --> <div class="upgrade-content-textab">由于系统服务器升级我们将于12月19日21:00 至12月19日22:00进行升级<br>在此期间AiDA系统将暂时无法访问给您带来的不便我们深表歉意并感谢您的理解</div>
</div> </div>
</div> </div>
</template> </template>