434 lines
13 KiB
Vue
434 lines
13 KiB
Vue
<template>
|
|
<div class="go-content-charts-item-animation-patch">
|
|
<div
|
|
ref="contentChartsItemBoxRef"
|
|
class="go-content-charts-item-box"
|
|
:class="[chartMode === ChartModeEnum.DOUBLE ? 'double' : 'single']"
|
|
>
|
|
<!-- 每一项组件的渲染 -->
|
|
<div
|
|
class="item-box"
|
|
v-for="(item, index) in menuOptions"
|
|
:key="item.title"
|
|
draggable
|
|
@dragstart="!item.disabled && dragStartHandle($event, item)"
|
|
@dragend="!item.disabled && dragendHandle()"
|
|
@dblclick="dblclickHandle(item)"
|
|
@click="clickHandle(item)"
|
|
>
|
|
<div class="list-header">
|
|
<mac-os-control-btn
|
|
class="list-header-control-btn"
|
|
:mini="true"
|
|
:disabled="true"
|
|
></mac-os-control-btn>
|
|
<n-text class="list-header-text" depth="3">
|
|
<n-ellipsis>{{ item.title }}</n-ellipsis>
|
|
<span class="span-icon" @click="deleteComponent(item, index)">
|
|
<TrashIcon v-if="item.key == 'GroupItem'" />
|
|
</span>
|
|
</n-text>
|
|
</div>
|
|
<div class="list-center go-flex-center go-transition" draggable="true">
|
|
<GoIconify
|
|
v-if="item.icon"
|
|
class="list-img"
|
|
:icon="item.icon"
|
|
color="#999"
|
|
width="48"
|
|
style="height: auto"
|
|
/>
|
|
<chart-glob-image v-else class="list-img" :chartConfig="item" />
|
|
</div>
|
|
<div class="list-bottom">
|
|
<n-text class="list-bottom-text" depth="3">
|
|
<n-ellipsis style="max-width: 90%">{{ item.title }}</n-ellipsis>
|
|
</n-text>
|
|
</div>
|
|
<!-- 遮罩 -->
|
|
<div v-if="item.disabled" class="list-model"></div>
|
|
<!-- 工具栏 -->
|
|
<div
|
|
v-if="isShowTools(item)"
|
|
class="list-tools go-transition"
|
|
@click="deleteHandle(item, index)"
|
|
>
|
|
<n-button text type="default" color="#ffffff">
|
|
<template #icon>
|
|
<n-icon>
|
|
<TrashIcon />
|
|
</n-icon>
|
|
</template>
|
|
<span>删除</span>
|
|
</n-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { PropType, watch, ref, Ref, computed, nextTick } from 'vue';
|
|
import { MacOsControlBtn } from '@/components/Tips/MacOsControlBtn/index';
|
|
import { ChartGlobImage } from '@/components/Pages/ChartGlobImage';
|
|
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
|
|
import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d';
|
|
import { ChartModeEnum } from '@/store/modules/chartLayoutStore/chartLayoutStore.d';
|
|
import { useChartLayoutStore } from '@/store/modules/chartLayoutStore/chartLayoutStore';
|
|
import { usePackagesStore } from '@/store/modules/packagesStore/packagesStore';
|
|
import {
|
|
componentInstall,
|
|
loadingStart,
|
|
loadingFinish,
|
|
loadingError,
|
|
JSONStringify,
|
|
goDialog,
|
|
getUUID,
|
|
} from '@/utils';
|
|
import { DragKeyEnum } from '@/enums/editPageEnum';
|
|
import { createComponent } from '@/packages';
|
|
import {
|
|
ConfigType,
|
|
CreateComponentType,
|
|
PackagesCategoryEnum,
|
|
CreateComponentGroupType,
|
|
} from '@/packages/index.d';
|
|
import { ChatCategoryEnum } from '@/packages/components/Photos/index.d';
|
|
import { fetchConfigComponent, fetchChartComponent } from '@/packages/index';
|
|
import { GoIconify } from '@/components/GoIconify';
|
|
import { icon } from '@/plugins';
|
|
import { HistoryActionTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d';
|
|
|
|
import omit from 'lodash/omit';
|
|
import cloneDeep from 'lodash/cloneDeep';
|
|
import { customComponentSaveDelete } from '@/api/path/project.api';
|
|
|
|
const chartEditStore = useChartEditStore();
|
|
const { TrashIcon } = icon.ionicons5;
|
|
|
|
const emit = defineEmits(['deletePhoto']);
|
|
const props = defineProps({
|
|
menuOptions: {
|
|
type: Array as PropType<ConfigType[]>,
|
|
default: () => [],
|
|
},
|
|
});
|
|
|
|
const chartLayoutStore = useChartLayoutStore();
|
|
const contentChartsItemBoxRef = ref();
|
|
|
|
// 判断工具栏展示
|
|
const isShowTools = (item: ConfigType) => {
|
|
return (
|
|
!item.disabled &&
|
|
item.package === PackagesCategoryEnum.PHOTOS &&
|
|
item.category === ChatCategoryEnum.PRIVATE
|
|
);
|
|
};
|
|
|
|
// 组件展示状态
|
|
const chartMode: Ref<ChartModeEnum> = computed(() => {
|
|
return chartLayoutStore.getChartType;
|
|
});
|
|
|
|
// 拖拽处理
|
|
const dragStartHandle = (e: DragEvent, item: ConfigType) => {
|
|
if (item.disabled) return;
|
|
// 动态注册图表组件
|
|
componentInstall(item.chartKey, fetchChartComponent(item));
|
|
componentInstall(item.conKey, fetchConfigComponent(item));
|
|
// 将配置项绑定到拖拽属性上
|
|
e!.dataTransfer!.setData(DragKeyEnum.DRAG_KEY, JSONStringify(omit(item, ['image'])));
|
|
// 修改状态
|
|
chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_CREATE, true);
|
|
};
|
|
|
|
// 拖拽结束
|
|
const dragendHandle = () => {
|
|
chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_CREATE, false);
|
|
};
|
|
|
|
// 双击添加
|
|
const dblclickHandle = async (item: ConfigType) => {
|
|
console.log('双击添加', item);
|
|
if (item.disabled) return;
|
|
// 保存的分组,进行使用
|
|
if (item.key == 'GroupItem') {
|
|
console.log('分组');
|
|
try {
|
|
loadingStart();
|
|
const recordCharts = item.json;
|
|
|
|
if (recordCharts === undefined) {
|
|
loadingFinish();
|
|
return;
|
|
}
|
|
const parseHandle = (e: CreateComponentType | CreateComponentGroupType) => {
|
|
e = cloneDeep(e);
|
|
e.attr.x = chartEditStore.getMousePosition.startX;
|
|
e.attr.y = chartEditStore.getMousePosition.startY;
|
|
// 外层生成新 id
|
|
e.id = getUUID();
|
|
// 分组列表生成新 id
|
|
if (e.isGroup) {
|
|
(e as CreateComponentGroupType).groupList.forEach(async (item: CreateComponentType) => {
|
|
item.id = getUUID();
|
|
});
|
|
}
|
|
|
|
return e;
|
|
};
|
|
const createComponentInstall = (e) => {
|
|
if (e.isGroup) {
|
|
// 分组
|
|
e.groupList.forEach(async (item) => {
|
|
// // 动态注册图表组件
|
|
componentInstall(item.chartConfig.chartKey, fetchChartComponent(item.chartConfig));
|
|
componentInstall(item.chartConfig.conKey, fetchConfigComponent(item.chartConfig));
|
|
});
|
|
} else {
|
|
componentInstall(e.chartConfig.chartKey, fetchChartComponent(e.chartConfig));
|
|
componentInstall(e.chartConfig.conKey, fetchConfigComponent(e.chartConfig));
|
|
}
|
|
};
|
|
const isCut = recordCharts.type === HistoryActionTypeEnum.CUT;
|
|
const targetList = Array.isArray(recordCharts.charts)
|
|
? recordCharts.charts
|
|
: [recordCharts.charts];
|
|
// 多项
|
|
targetList.forEach((e: CreateComponentType | CreateComponentGroupType) => {
|
|
createComponentInstall(e);
|
|
chartEditStore.addComponentList(parseHandle(e), undefined, true);
|
|
// 剪切需删除原数据
|
|
if (isCut) {
|
|
chartEditStore.setTargetSelectChart(e.id);
|
|
chartEditStore.removeComponentList(undefined, true);
|
|
}
|
|
});
|
|
if (isCut) chartEditStore.setRecordChart(undefined);
|
|
loadingFinish();
|
|
} catch (value) {
|
|
window['$message'].warning(`图表正在研发中, 敬请期待...`);
|
|
loadingError();
|
|
}
|
|
} else {
|
|
try {
|
|
loadingStart();
|
|
// 动态注册图表组件
|
|
componentInstall(item.chartKey, fetchChartComponent(item));
|
|
componentInstall(item.conKey, fetchConfigComponent(item));
|
|
// 创建新图表组件
|
|
let newComponent: CreateComponentType = await createComponent(item);
|
|
if (item.redirectComponent) {
|
|
item.dataset && (newComponent.option.dataset = item.dataset);
|
|
newComponent.chartConfig.title = item.title;
|
|
newComponent.chartConfig.chartFrame = item.chartFrame;
|
|
}
|
|
// 添加
|
|
chartEditStore.addComponentList(newComponent, false, true);
|
|
// 选中
|
|
chartEditStore.setTargetSelectChart(newComponent.id);
|
|
loadingFinish();
|
|
} catch (error) {
|
|
loadingError();
|
|
console.log('chartItemBox-index');
|
|
window['$message'].warning(`图表正在研发中, 敬请期待...`);
|
|
}
|
|
}
|
|
};
|
|
|
|
// 单击事件
|
|
const clickHandle = (item: ConfigType) => {
|
|
item?.configEvents?.addHandle(item);
|
|
};
|
|
|
|
const deleteHandle = (item: ConfigType, index: number) => {
|
|
goDialog({
|
|
message: '是否删除此图片?',
|
|
transformOrigin: 'center',
|
|
onPositiveCallback: () => {
|
|
const packagesStore = usePackagesStore();
|
|
emit('deletePhoto', item, index);
|
|
packagesStore.deletePhotos(item, index);
|
|
},
|
|
});
|
|
};
|
|
|
|
watch(
|
|
() => chartMode.value,
|
|
(newValue: ChartModeEnum) => {
|
|
if (newValue === ChartModeEnum.DOUBLE) {
|
|
nextTick(() => {
|
|
contentChartsItemBoxRef.value.classList.add('miniAnimation');
|
|
});
|
|
}
|
|
},
|
|
);
|
|
const deleteComponent = (item: ConfigType, index: number) => {
|
|
props.menuOptions.splice(index, 1);
|
|
customComponentSaveDelete({
|
|
ids: item.id,
|
|
}).then((res) => {
|
|
if (res) {
|
|
window['$message'].success(`删除成功`);
|
|
} else {
|
|
window['$message'].success(`删除失败`);
|
|
}
|
|
});
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
/* 列表项宽度 */
|
|
$itemWidth: 100%;
|
|
$maxItemWidth: 180px;
|
|
$halfItemWidth: 46%;
|
|
/* 内容高度 */
|
|
$centerHeight: 100px;
|
|
$halfCenterHeight: 50px;
|
|
|
|
@include go('content-charts-item-animation-patch') {
|
|
padding: 10px;
|
|
}
|
|
|
|
@include go('content-charts-item-box') {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
justify-content: space-between;
|
|
gap: 9px;
|
|
transition: all 0.7s linear;
|
|
.item-box {
|
|
position: relative;
|
|
margin: 0;
|
|
width: $itemWidth;
|
|
overflow: hidden;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
border: 1px solid rgba(0, 0, 0, 0);
|
|
@include fetch-bg-color('background-color2');
|
|
&:hover {
|
|
@include hover-border-color('background-color4');
|
|
.list-img {
|
|
transform: scale(1.08);
|
|
}
|
|
.list-tools {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
.list-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 2px 15px;
|
|
@include fetch-bg-color('background-color3');
|
|
&-text {
|
|
font-size: 12px;
|
|
margin-left: 8px;
|
|
user-select: none;
|
|
}
|
|
}
|
|
.list-center {
|
|
padding: 6px 0;
|
|
height: $centerHeight;
|
|
overflow: hidden;
|
|
.list-img {
|
|
height: 100px;
|
|
max-width: 140px;
|
|
border-radius: 6px;
|
|
object-fit: contain;
|
|
@extend .go-transition;
|
|
}
|
|
}
|
|
.list-bottom {
|
|
display: none;
|
|
.list-bottom-text {
|
|
font-size: 12px;
|
|
padding-left: 5px;
|
|
}
|
|
}
|
|
.list-model {
|
|
z-index: 1;
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: rgba(0, 0, 0, 0);
|
|
}
|
|
.list-tools {
|
|
position: absolute;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
bottom: 0;
|
|
left: 0;
|
|
margin: 0 4px 2px;
|
|
height: 26px;
|
|
width: calc(100% - 8px);
|
|
opacity: 0;
|
|
border-radius: 6px;
|
|
backdrop-filter: blur(20px);
|
|
background-color: rgba(255, 255, 255, 0.15);
|
|
&:hover {
|
|
background-color: rgba(232, 128, 128, 0.7);
|
|
}
|
|
}
|
|
}
|
|
&.single {
|
|
.item-box {
|
|
@extend .go-transition;
|
|
}
|
|
}
|
|
&.double {
|
|
.list-header {
|
|
padding: 2px 5px;
|
|
.list-header-text {
|
|
display: none;
|
|
}
|
|
.list-header-control-btn {
|
|
transform: scale(0.7);
|
|
}
|
|
}
|
|
.item-box {
|
|
width: $halfItemWidth;
|
|
max-width: $maxItemWidth;
|
|
.list-img {
|
|
max-width: 76px;
|
|
}
|
|
}
|
|
.list-center {
|
|
height: $halfCenterHeight;
|
|
padding-bottom: 0px;
|
|
.list-img {
|
|
height: $halfCenterHeight;
|
|
width: auto;
|
|
transition: all 0.2s;
|
|
object-fit: contain;
|
|
}
|
|
}
|
|
.list-bottom {
|
|
display: block;
|
|
}
|
|
}
|
|
/* 缩小展示 */
|
|
@keyframes miniAnimation {
|
|
from {
|
|
width: $itemWidth * 2;
|
|
}
|
|
to {
|
|
width: $itemWidth;
|
|
}
|
|
}
|
|
&.miniAnimation {
|
|
animation: miniAnimation 0.5s;
|
|
}
|
|
}
|
|
.span-icon {
|
|
font-size: 16px;
|
|
display: inline-block;
|
|
width: 20px;
|
|
height: 20px;
|
|
margin-left: 5px;
|
|
}
|
|
</style>
|