1.热区新增6个可拖拽的角

2.热区新增不可拖拽出去
3.已设置改为链接名称
4.热区数据增加类型约束
5.热区弹窗在打开后图片内的坐标会根据当前浏览器的大小进行动态调整
6.优化了热区回显没有完全对准的问题
7.热区图片大小从最大60rem更新为最大80rem
8.上传分类增加新增编辑删除
v1.0.0
sws 2024-08-13 18:27:31 +08:00
parent b7c5d87691
commit d6a6b8a71f
14 changed files with 539 additions and 214 deletions

View File

@ -0,0 +1,138 @@
.content-scrollbar {
height: calc(100vh - 13.8rem);
margin: 0 -1.6rem;
.left-content {
.img-scrollbar {
display: flex;
justify-content: center;
.img-container {
max-width: 80rem;
min-width: 30rem;
height: calc(100vh - 25.8rem);
position: relative;
padding: 0.8rem;
.img {
user-select: none;
cursor: crosshair;
}
.area {
position: absolute;
background: rgba(41, 128, 185, 0.3);
border: 1px dashed #34495e;
width: 0px;
height: 0px;
left: 0px;
top: 0px;
display: none;
}
.area-box {
position: absolute;
background: rgba(42, 148, 255, 0.25);
border: 1px dashed #8ec6ff;
display: flex;
justify-content: center;
align-items: center;
color: #1989fa;
font-size: 1.2rem;
cursor: move;
transition: transform 0.1s;
.del-btn {
display: flex;
justify-content: center;
align-items: center;
background: #1890ff;
color: #fff;
text-align: center;
border-radius: 0 0 0 0.3rem;
position: absolute;
right: 0.7rem;
top: 0.7rem;
transform: translate3d(50%, -50%, 0);
cursor: default;
width: 1.6rem;
height: 1.6rem;
line-height: 1.6rem;
z-index: 1;
i {
font-size: 0.9rem;
}
}
.drag-btn {
position: absolute;
width: 7px;
height: 7px;
background: #f0f0f0;
border: 1px solid #333;
z-index: 1;
}
.drag-tl {
left: -0.4rem;
top: -0.4rem;
cursor: nw-resize;
}
.drag-tc {
left: 50%;
top: -0.4rem;
transform: translateX(-50%);
cursor: n-resize;
}
.drag-lc {
left: -0.4rem;
top: 50%;
transform: translateY(-50%);
cursor: w-resize;
}
.drag-bl {
left: -0.4rem;
bottom: -0.4rem;
cursor: sw-resize;
}
.drag-bc {
left: 50%;
bottom: -0.4rem;
transform: translateX(-50%);
cursor: s-resize;
}
.drag-br {
right: -0.4rem;
bottom: -0.4rem;
cursor: se-resize;
}
.drag-rc {
right: -0.4rem;
top: 50%;
transform: translateY(-50%);
cursor: e-resize;
}
.text {
overflow: hidden;
display: flex;
flex-wrap: wrap;
justify-content: center;
max-width: 100%;
max-height: 100%;
text-align: center;
align-items: center;
color: #fff;
font-size: 1.2rem;
.name {
color: #fff;
margin: 0 0.2rem;
}
.status {
margin: 0 0.2rem;
}
}
}
}
}
}
.right-content {
.item {
max-width: 47.8rem;
.name {
width: 9.8rem;
}
}
}
}

View File

@ -11,17 +11,26 @@
<div class="left-content flex-1 pa-20">
<el-scrollbar class="img-scrollbar">
<div class="img-container">
<div ref="imgBoxRef" class="oh" @mousedown.prevent="start_drag" @mousemove.prevent="move_drag" @mouseup.prevent="end_drag">
<div ref="imgRef">
<el-image :src="hot_list.img" class="w img" @selectstart.prevent @contextmenu.prevent @dragstart.prevent></el-image>
</div>
<div ref="areaRef" class="area" :style="init_drag_style"></div>
<div v-for="(item, index) in hot_list.data" :key="index" class="area-box" :style="rect_style(item.drag_start, item.drag_end)" @mousedown.stop="start_drag_area_box(index, $event)" @dblclick="dbl_drag_event(item, index)">
<div class="del-btn" @click.stop="del_area_event(index)"><icon name="close"></icon></div>
<div class="drag-btn" :data-index="index" @mousedown.stop="start_drag_btn(index, $event)"></div>
<div class="text">
<div class="name">{{ item.name }}</div>
<div class="status" :class="!is_obj_empty(item.link) ? 'cr-primary' : 'cr-error'">{{ !is_obj_empty(item.link) ? '已设置' : '未设置' }}</div>
<div class="re">
<div ref="imgBoxRef" class="oh" @mousedown.prevent="start_drag" @mousemove.prevent="move_drag" @mouseup.prevent="end_drag">
<div ref="imgRef">
<el-image :src="hot_list.img" class="w img block" @selectstart.prevent @contextmenu.prevent @dragstart.prevent></el-image>
</div>
<div ref="areaRef" class="area" :style="init_drag_style"></div>
<div v-for="(item, index) in hot_list.data" :key="index" class="area-box" :style="rect_style(item.drag_start, item.drag_end)" @mousedown.stop="start_drag_area_box(index, $event)" @dblclick="dbl_drag_event(item, index)">
<div class="del-btn" @click.stop="del_area_event(index)"><icon name="close"></icon></div>
<div class="drag-btn drag-tl" :data-index="index" @mousedown.stop="start_drag_btn_tl(index, $event)"></div>
<div class="drag-btn drag-tc" :data-index="index" @mousedown.stop="start_drag_btn_tc(index, $event)"></div>
<div class="drag-btn drag-lc" :data-index="index" @mousedown.stop="start_drag_btn_lc(index, $event)"></div>
<div class="drag-btn drag-bl" :data-index="index" @mousedown.stop="start_drag_btn_bl(index, $event)"></div>
<div class="drag-btn drag-bc" :data-index="index" @mousedown.stop="start_drag_btn_bc(index, $event)"></div>
<!-- 已完成 -->
<div class="drag-btn drag-br" :data-index="index" @mousedown.stop="start_drag_btn_br(index, $event)"></div>
<div class="drag-btn drag-rc" :data-index="index" @mousedown.stop="start_drag_btn_rc(index, $event)"></div>
<div class="text">
<div class="name">{{ item.name }}</div>
<div class="status" :class="!is_obj_empty(item.link) ? 'cr-primary' : 'cr-error'">{{ !is_obj_empty(item.link) ? (item.link?.name ?? '未设置') : '未设置' }}</div>
</div>
</div>
</div>
</div>
@ -101,8 +110,11 @@ const rect_start = ref<rectCoords>({ x: 0, y: 0, width: 0, height: 0 });
const rect_end = ref<rectCoords>({ x: 0, y: 0, width: 0, height: 0 });
const areaRef = ref<HTMLElement | null>(null);
const init_drag_style = ref('');
//
const drag_bool = ref(false);
//
const drag_box_bool = ref(false);
//
const drag_box_scale_bool = ref(false);
const start_drag = (event: MouseEvent) => {
drag_bool.value = true;
@ -130,7 +142,7 @@ const end_drag = (event: MouseEvent) => {
if (rect_end.value.width > 16 && rect_end.value.height > 16) {
hot_list.value.data.push({
name: '热区' + (hot_list.value.data.length + 1),
link: {},
link: { name: '', link: '' },
drag_start: cloneDeep(rect_start.value),
drag_end: cloneDeep(rect_end.value),
});
@ -176,13 +188,15 @@ const start_drag_area_box = (index: number, event: MouseEvent) => {
}
//
if (new_coordinate.x + Math.max(clone_drag_end.width, 1) > imgBoxRef.value.getBoundingClientRect().width) {
new_coordinate.x = imgBoxRef.value.getBoundingClientRect().width - Math.max(clone_drag_end.width, 1) - 4;
new_coordinate.x = imgBoxRef.value.getBoundingClientRect().width - Math.max(clone_drag_end.width, 1);
}
if (new_coordinate.y + Math.max(clone_drag_end.height, 1) > imgBoxRef.value.getBoundingClientRect().height) {
new_coordinate.y = imgBoxRef.value.getBoundingClientRect().height - Math.max(clone_drag_end.height, 1) - 7;
new_coordinate.y = imgBoxRef.value.getBoundingClientRect().height - Math.max(clone_drag_end.height, 1);
}
hot_list.value.data[hot_list_index.value].drag_start.x = new_coordinate.x;
hot_list.value.data[hot_list_index.value].drag_start.y = new_coordinate.y;
hot_list.value.data[hot_list_index.value].drag_end.x = new_coordinate.x + Math.max(clone_drag_end.width, 1);
hot_list.value.data[hot_list_index.value].drag_end.y = new_coordinate.y + Math.max(clone_drag_end.height, 1);
}
};
document.onmouseup = (areaBoxEvent) => {
@ -191,7 +205,29 @@ const start_drag_area_box = (index: number, event: MouseEvent) => {
};
};
// drag-btn
const start_drag_btn = (index: number, event: MouseEvent) => {
const start_drag_btn_br = (index: number, event: MouseEvent) => {
start_drag_btn(index, event, 'br');
};
const start_drag_btn_bl = (index: number, event: MouseEvent) => {
start_drag_btn(index, event, 'bl');
};
const start_drag_btn_bc = (index: number, event: MouseEvent) => {
start_drag_btn(index, event, 'bc');
};
const start_drag_btn_tl = (index: number, event: MouseEvent) => {
start_drag_btn(index, event, 'tl');
};
const start_drag_btn_tc = (index: number, event: MouseEvent) => {
start_drag_btn(index, event, 'tc');
};
const start_drag_btn_lc = (index: number, event: MouseEvent) => {
start_drag_btn(index, event, 'lc');
};
const start_drag_btn_rc = (index: number, event: MouseEvent) => {
start_drag_btn(index, event, 'rc');
};
//
const start_drag_btn = (index: number, event: MouseEvent, type: string) => {
hot_list_index.value = index;
event.stopPropagation();
drag_box_scale_bool.value = true;
@ -202,14 +238,55 @@ const start_drag_btn = (index: number, event: MouseEvent) => {
//
if (drag_box_scale_bool.value) {
if (!imgBoxRef.value) return;
clone_drag_end.x = dragBtnEvent.clientX - imgBoxRef.value.getBoundingClientRect().left;
clone_drag_end.y = dragBtnEvent.clientY - imgBoxRef.value.getBoundingClientRect().top;
hot_list.value.data[hot_list_index.value].drag_end = {
x: clone_drag_end.x,
y: clone_drag_end.y,
width: clone_drag_end.x - clone_drag_start.x > 0 ? clone_drag_end.x - clone_drag_start.x : 0,
height: clone_drag_end.y - clone_drag_start.y > 0 ? clone_drag_end.y - clone_drag_start.y : 0,
};
switch (type) {
case 'br':
//
clone_drag_end.x = handleBoundary(dragBtnEvent.clientX - imgBoxRef.value.getBoundingClientRect().left, 0, imgBoxRef.value.getBoundingClientRect().width);
clone_drag_end.y = handleBoundary(dragBtnEvent.clientY - imgBoxRef.value.getBoundingClientRect().top, 0, imgBoxRef.value.getBoundingClientRect().height);
hot_list.value.data[hot_list_index.value].drag_end = updateDragEnd(clone_drag_start, clone_drag_end, clone_drag_end);
break;
case 'bl':
//
clone_drag_start.x = handleBoundary(dragBtnEvent.clientX - imgBoxRef.value.getBoundingClientRect().left, 0, clone_drag_end.x);
clone_drag_end.y = handleBoundary(dragBtnEvent.clientY - imgBoxRef.value.getBoundingClientRect().top, 0, imgBoxRef.value.getBoundingClientRect().height);
hot_list.value.data[hot_list_index.value].drag_start.x = clone_drag_start.x;
hot_list.value.data[hot_list_index.value].drag_end.y = clone_drag_end.y;
hot_list.value.data[hot_list_index.value].drag_end = updateDragEnd(clone_drag_start, clone_drag_end, { y: clone_drag_end.y });
break;
case 'bc':
//
clone_drag_end.y = handleBoundary(dragBtnEvent.clientY - imgBoxRef.value.getBoundingClientRect().top, 0, imgBoxRef.value.getBoundingClientRect().height);
hot_list.value.data[hot_list_index.value].drag_end.y = clone_drag_end.y;
hot_list.value.data[hot_list_index.value].drag_end = updateDragEnd(clone_drag_start, clone_drag_end, { y: clone_drag_end.y });
break;
case 'tl':
//
clone_drag_start.x = handleBoundary(dragBtnEvent.clientX - imgBoxRef.value.getBoundingClientRect().left, 0, clone_drag_end.x);
clone_drag_start.y = handleBoundary(dragBtnEvent.clientY - imgBoxRef.value.getBoundingClientRect().top, 0, clone_drag_end.y);
hot_list.value.data[hot_list_index.value].drag_start.x = clone_drag_start.x;
hot_list.value.data[hot_list_index.value].drag_start.y = clone_drag_start.y;
hot_list.value.data[hot_list_index.value].drag_end = updateDragEnd(clone_drag_start, clone_drag_end, {});
break;
case 'tc':
//
clone_drag_start.y = handleBoundary(dragBtnEvent.clientY - imgBoxRef.value.getBoundingClientRect().top, 0, clone_drag_end.y);
hot_list.value.data[hot_list_index.value].drag_start.y = clone_drag_start.y;
hot_list.value.data[hot_list_index.value].drag_end = updateDragEnd(clone_drag_start, clone_drag_end, { y: clone_drag_end.y });
break;
case 'lc':
//
clone_drag_start.x = handleBoundary(dragBtnEvent.clientX - imgBoxRef.value.getBoundingClientRect().left, 0, clone_drag_end.x);
hot_list.value.data[hot_list_index.value].drag_start.x = clone_drag_start.x;
hot_list.value.data[hot_list_index.value].drag_end = updateDragEnd(clone_drag_start, clone_drag_end, {});
break;
case 'rc':
//
clone_drag_end.x = handleBoundary(dragBtnEvent.clientX - imgBoxRef.value.getBoundingClientRect().left, 0, imgBoxRef.value.getBoundingClientRect().width);
hot_list.value.data[hot_list_index.value].drag_end.x = clone_drag_end.x;
hot_list.value.data[hot_list_index.value].drag_end = updateDragEnd(clone_drag_start, clone_drag_end, { x: clone_drag_end.x });
break;
}
}
};
document.onmouseup = (dragBtnEvent2) => {
@ -217,6 +294,29 @@ const start_drag_btn = (index: number, event: MouseEvent) => {
drag_box_scale_bool.value = false;
};
};
// drag_end
const updateDragEnd = (dragStart: { x: number; y: number }, dragEnd: { x: number; y: number }, newDragEnd: { x?: number; y?: number }) => {
const newX = newDragEnd.x !== undefined ? newDragEnd.x : dragEnd.x;
const newY = newDragEnd.y !== undefined ? newDragEnd.y : dragEnd.y;
return {
x: newX,
y: newY,
width: newX - dragStart.x > 0 ? newX - dragStart.x : 0,
height: newY - dragStart.y > 0 ? newY - dragStart.y : 0,
};
};
// drag_start
const updateDragStart = (dragStart: { x: number; y: number }, newDragStart: { x?: number; y?: number }) => {
const newX = newDragStart.x !== undefined ? newDragStart.x : dragStart.x;
const newY = newDragStart.y !== undefined ? newDragStart.y : dragStart.y;
return { x: newX, y: newY };
};
//
const handleBoundary = (value: number, min: number, max: number) => Math.max(min, Math.min(value, max));
const del_area_event = (index: number) => {
hot_list.value.data.splice(index, 1);
};
@ -225,6 +325,7 @@ const rect_style = computed(() => {
return `left: ${start.x}px;top: ${start.y}px;width: ${Math.max(end.width, 1)}px;height: ${Math.max(end.height, 1)}px;display: flex;`;
};
});
//#endregion -----------------------------------------------end
//#region -----------------------------------------------start
@ -235,16 +336,24 @@ const del_event = (index: number) => {
//#region -----------------------------------------------start
const hot_dialog_visible = ref(false);
const form = ref({
link: {},
interface formData {
link: linkData;
name: string;
}
const form = ref<formData>({
link: {
name: '',
},
name: '',
});
const hot_close_event = () => {
hot_dialog_visible.value = false;
};
const hot_confirm_event = () => {
hot_list.value.data[hot_list_index.value].link = form.value.link;
hot_list.value.data[hot_list_index.value].name = form.value.name;
if (hot_list.value.data[hot_list_index.value].link) {
hot_list.value.data[hot_list_index.value].link = form.value.link;
}
hot_close_event();
};
//#endregion -----------------------------------------------end
@ -254,7 +363,26 @@ const hot_confirm_event = () => {
const open_hot_event = () => {
if (modelValue.value.img.length > 0) {
dialog_visible.value = true;
hot_list.value = cloneDeep(modelValue.value);
hot_list.value.img = modelValue.value.img;
setTimeout(() => {
//
let temp_data = cloneDeep(modelValue.value);
//
temp_data.img_height = imgBoxRef.value?.clientHeight || 0;
temp_data.img_width = imgBoxRef.value?.clientWidth || 0;
//
const scale = temp_data.img_width / modelValue.value.img_width;
console.log(scale);
temp_data.data.forEach((item) => {
item.drag_start.x = item.drag_start.x * scale;
item.drag_start.y = item.drag_start.y * scale;
item.drag_end.x = item.drag_end.x * scale;
item.drag_end.y = item.drag_end.y * scale;
item.drag_end.width = item.drag_end.width * scale;
item.drag_end.height = item.drag_end.height * scale;
});
hot_list.value = temp_data;
}, 100);
} else {
ElMessage({
type: 'warning',
@ -285,8 +413,6 @@ const confirm_event = () => {
ElMessage.error('请设置热区链接!');
return;
} else {
hot_list.value.img_height = imgRef.value?.clientHeight || 0;
hot_list.value.img_width = imgRef.value?.clientWidth || 0;
modelValue.value = cloneDeep(hot_list.value);
close_event();
}
@ -297,106 +423,5 @@ const confirm_event = () => {
//#endregion -----------------------------------------------end
</script>
<style lang="scss" scoped>
.content-scrollbar {
height: calc(100vh - 13.8rem);
margin: 0 -1.6rem;
.left-content {
.img-scrollbar {
display: flex;
justify-content: center;
.img-container {
max-width: 60rem;
min-width: 30rem;
height: calc(100vh - 25.8rem);
position: relative;
.img {
user-select: none;
cursor: crosshair;
padding: 0 0.4rem 0.4rem 0;
}
.area {
position: absolute;
background: rgba(41, 128, 185, 0.3);
border: 1px dashed #34495e;
width: 0px;
height: 0px;
left: 0px;
top: 0px;
display: none;
}
.area-box {
position: absolute;
background: rgba(42, 148, 255, 0.25);
border: 1px dashed #8ec6ff;
display: flex;
justify-content: center;
align-items: center;
color: #1989fa;
font-size: 1.2rem;
cursor: move;
transition: transform 0.1s;
.del-btn {
display: flex;
justify-content: center;
align-items: center;
background: #1890ff;
color: #fff;
text-align: center;
border-radius: 0 0 0 0.3rem;
position: absolute;
right: 0.7rem;
top: 0.7rem;
transform: translate3d(50%, -50%, 0);
cursor: default;
width: 1.6rem;
height: 1.6rem;
line-height: 1.6rem;
z-index: 1;
i {
font-size: 0.9rem;
}
}
.drag-btn {
position: absolute;
width: 7px;
height: 7px;
background: #f0f0f0;
border: 1px solid #333;
right: -0.4rem;
bottom: -0.4rem;
cursor: nwse-resize;
z-index: 1;
}
.text {
overflow: hidden;
display: flex;
flex-wrap: wrap;
justify-content: center;
max-width: 100%;
max-height: 100%;
text-align: center;
align-items: center;
color: #fff;
font-size: 1.2rem;
.name {
color: #fff;
margin: 0 0.2rem;
}
.status {
margin: 0 0.2rem;
}
}
}
}
}
}
.right-content {
.item {
max-width: 47.8rem;
.name {
width: 9.8rem;
}
}
}
}
@import 'index.scss';
</style>

View File

@ -1,13 +1,108 @@
<template>
<el-dialog v-model="dialog_visible_category_oprate" class="radius-lg" width="1168" append-to-body>
<el-dialog v-model="dialog_visible_category_oprate" class="radius-lg" width="500" append-to-body>
<template #header>
<div class="title center re">
<div class="tc size-16 fw">添加分类</div>
<div class="tc size-16 fw">{{ type == 'add' ? '添加' : '编辑' }}附件分类</div>
</div>
</template>
<div class="mt-16 pa-20">
<el-form ref="ruleFormRef" :model="form" :rules="rules" label-width="60" status-icon>
<el-form-item label="名称" prop="name">
<el-input v-model="form.name" placeholder="请输入名称"></el-input>
</el-form-item>
<el-form-item label="路径" prop="path">
<el-input v-model="form.path" placeholder="请输入路径"></el-input>
</el-form-item>
<el-form-item label="排序">
<el-input v-model="form.sort" placeholder="请输入排序"></el-input>
</el-form-item>
<el-form-item label="是否启用">
<el-switch v-model="form.is_enable"></el-switch>
</el-form-item>
</el-form>
</div>
<template #footer>
<span class="dialog-footer">
<el-button class="plr-28 ptb-10" @click="cancel_event(ruleFormRef)"></el-button>
<el-button class="plr-28 ptb-10" type="primary" @click="confirm_event(ruleFormRef)"></el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
const dialog_visible_category_oprate = ref(false);
import { FormInstance, FormRules } from 'element-plus';
import { cloneDeep } from 'lodash';
/**
* @description: 分类操作
* @param modelValue{uploadList[]} 默认值
* @param visibleDialog{Boolean} 弹窗开启关闭
* @param type{String} 新增add编辑edit
* @return {*} update:modelValue confirm
*/
const props = defineProps({
value: {
type: Object as PropType<Tree>,
default: () => {},
},
type: {
type: String,
default: 'add',
},
categoryId: {
type: [String, Number],
default: '',
},
});
const dialog_visible_category_oprate = defineModel({ type: Boolean, default: false });
const form = ref<Tree>({
id: '',
name: '',
path: '',
sort: 0,
is_enable: true,
children: [],
});
watch(
() => dialog_visible_category_oprate.value,
(newValue) => {
if (newValue && props.type !== 'add') {
form.value = cloneDeep(props.value);
}
}
);
const ruleFormRef = ref<FormInstance>();
const rules = reactive<FormRules>({
name: [
{ required: true, trigger: 'blur', message: '请输入名称' },
{ min: 1, max: 60, message: '名称长度1~60个字符', trigger: 'blur' },
],
path: [
{ required: true, message: '请输入地址', trigger: 'blur' },
{ min: 1, max: 230, message: '路径长度1~230个字符', trigger: 'blur' },
],
});
onMounted(() => {
if (props.type == 'add') {
ruleFormRef.value?.resetFields();
}
});
const cancel_event = (formEl: FormInstance | undefined) => {
dialog_visible_category_oprate.value = false;
formEl?.resetFields();
};
const emit = defineEmits(['update:modelValue', 'confirm']);
const confirm_event = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid, fields) => {
if (valid) {
emit('confirm', form.value, props.categoryId);
cancel_event(formEl);
} else {
console.log('error submit!', fields);
}
});
};
</script>
<style lang="scss"></style>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,9 @@
// 分类树结构
type Tree = {
id: number | string;
name: string;
path: string;
is_enable: boolean;
sort: number;
children: Tree[];
};

View File

@ -19,10 +19,21 @@
<icon name="search" size="18"></icon>
</template>
</el-input>
<icon name="add" size="18" @click="add_type"></icon>
<icon name="add" size="18" class="c-pointer" @click="add_type"></icon>
</div>
<el-scrollbar height="490px">
<el-tree ref="treeRef" class="filter-tree" :data="type_data" node-key="id" highlight-current :expand-on-click-node="false" :props="defaultProps" empty-text="" default-expand-all :filter-node-method="filter_node" @node-click="tree_node_event" />
<el-tree ref="treeRef" class="filter-tree" :data="type_data" node-key="id" highlight-current :expand-on-click-node="false" :props="defaultProps" empty-text="" default-expand-all :filter-node-method="filter_node" @node-click="tree_node_event">
<template #default="{ node, data }">
<span class="custom-tree-node flex-row jc-sb align-c w pr-10">
<span>{{ data.name }}</span>
<span class="flex-row gap-10">
<icon name="add" size="12" color="primary" @click="append_type_event(data)"></icon>
<icon name="edit" size="12" color="primary" @click="edit_type_event(data)"></icon>
<icon name="del" size="12" color="primary" @click="remove_type_event(node, data)"></icon>
</span>
</span>
</template>
</el-tree>
</el-scrollbar>
</div>
<div class="right-content flex-1 flex-width">
@ -159,8 +170,10 @@
<!-- 图片预览 -->
<el-image-viewer v-if="preview_switch_img && upload_type == 'img'" :z-index="999999" :url-list="[preview_url]" :hide-on-click-modal="true" @close="preview_close"></el-image-viewer>
<upload-model v-model="upload_model_visible" :type="upload_type" :exts="props.type == 'img' ? ext_img_name_list : props.type == 'video' ? ext_video_name_list : ext_file_name_list" @close="close_upload_model"></upload-model>
<form-upload-category v-model="upload_category_model_visible" :value="upload_category_model" :type="upload_category_type" :category-id="upload_category_id" @confirm="upload_category_confirm"></form-upload-category>
</template>
<script lang="ts" setup>
import { get_math } from '@/utils/index';
const app = getCurrentInstance();
/**
* @description: 图片上传
@ -288,7 +301,7 @@ const upload_type_change = (type: any) => {
const treeRef = ref();
const defaultProps = {
children: 'children',
label: 'label',
label: 'name',
};
//
const search_filter = ref('');
@ -303,31 +316,36 @@ const search_name = ref('');
const page = ref(1);
//
const data_total = ref(0);
interface Tree {
id: number;
label: string;
children?: Tree[];
}
const filter_node = (value: string, data: any): boolean => {
if (!value) return true;
return data.label.indexOf(value) !== -1;
return data.name.indexOf(value) !== -1;
};
const type_data: Tree[] = [
const type_data = ref<Tree[]>([
{
id: 0,
label: '全部图片',
name: '全部图片',
path: '全部',
is_enable: true,
sort: 1,
children: [],
},
{
id: 1,
label: '金刚区',
children: [
{
id: 2,
label: '金刚区 1-1',
},
],
name: '全部视频',
path: '全部',
is_enable: true,
sort: 2,
children: [],
},
];
{
id: 2,
name: '全部文件',
path: '全部',
is_enable: true,
sort: 3,
children: [],
},
]);
// //
const category_list = [
{
@ -458,15 +476,82 @@ const search_data = ref({
const get_list = () => {
console.log('查询接口', search_data);
};
//
const upload_category_model = ref<Tree>({
id: '',
name: '',
path: '',
sort: 0,
is_enable: false,
children: [],
});
//
const upload_category_type = ref('add');
//
const dialog_visible_type_oprate = ref(false);
const upload_category_model_visible = ref(false);
//
const add_type = () => {};
const add_type = () => {
upload_category_type.value = 'add';
upload_category_model_visible.value = true;
upload_category_id.value = '';
};
//
const upload_category_confirm = (data: any) => {
if (upload_category_type.value == 'add') {
//
//
if (upload_category_id.value == '') {
//
console.log('添加子级分类');
// type_data.value = type_data.value.map((item: any) => {
// if (item.id == upload_category_id.value) {
// item.children.push(data);
// }
// return item;
// });
} else {
//
console.log('添加一级分类');
// type_data.value = [...type_data.value, data];
}
} else if (upload_category_type.value == 'edit') {
//
console.log('编辑分类');
// type_data.value = type_data.value.map((item: any) => {
// if (item.id == data.id) {
// item = data;
// }
// return item;
// });
}
};
//
const tree_node_event = (data: any) => {
// search_filter.value = data.id;
get_list();
};
const upload_category_id = ref<number | string>('');
//
const append_type_event = (data: Tree) => {
upload_category_type.value = 'add';
upload_category_id.value = data.id;
upload_category_model_visible.value = true;
};
//
const edit_type_event = (data: Tree) => {
upload_category_type.value = 'edit';
upload_category_id.value = data.id;
upload_category_model_visible.value = true;
upload_category_model.value = data;
};
// Nodenode使any
const remove_type_event = (node: any, data: Tree) => {
const parent = node.parent;
const children: Tree[] = parent.data.children || parent.data;
const index = children.findIndex((d) => d.id === data.id);
children.splice(index, 1);
// type_data.value = [...type_data.value];
};
//
const confirm_event = () => {
dialog_visible.value = false;

View File

@ -53,13 +53,7 @@ watch(
}
);
const modelValue = defineModel({ type: Object, default: {} });
interface User {
id: number;
name: string;
icon: string;
link: string;
}
const tableData: User[] = [
const tableData: linkData[] = [
{
id: 1,
name: '一级分类一级分类一级分类一级分类一级分类一级分类一级分类',
@ -99,7 +93,7 @@ const template_selection = ref('');
const row_click = (row: any) => {
const new_table_data = JSON.parse(JSON.stringify(tableData));
template_selection.value = new_table_data.findIndex((item: User) => item.id == row.id).toString();
template_selection.value = new_table_data.findIndex((item: linkData) => item.id == row.id).toString();
modelValue.value = row;
};
//#region -----------------------------------------------start

View File

@ -129,18 +129,11 @@ const address = computed(() => {
});
const ruleFormRef = ref<FormInstance>();
const emit = defineEmits(['update:link', 'required']);
interface formType {
id?: number;
name: string;
link: string;
lng?: number;
lat?: number;
}
const on_submit = () => {
if (!ruleFormRef.value) return;
ruleFormRef.value.validate((valid: boolean) => {
if (valid) {
let new_value: formType = {
let new_value: linkData = {
name: '',
link: '',
};

View File

@ -50,15 +50,7 @@ watch(
}
);
const modelValue = defineModel({ type: Object, default: {} });
interface User {
id: number;
name: string;
icon: string;
link: string;
hasChildren?: boolean;
children?: User[];
}
const tableData: User[] = [
const tableData: linkData[] = [
{
id: 1,
name: '一级分类',
@ -106,9 +98,9 @@ const options = ref([
const template_selection = ref('');
const row_click = (row: any) => {
let new_data: User[] = [];
let new_data: linkData[] = [];
//
const array_conversion = (item: User[]) => {
const array_conversion = (item: linkData[]) => {
item.forEach((item) => {
new_data.push(item);
if (item.children) {
@ -118,7 +110,7 @@ const row_click = (row: any) => {
return new_data;
};
const new_table_data = array_conversion(JSON.parse(JSON.stringify(tableData)));
template_selection.value = new_table_data.findIndex((item: User) => item.id == row.id).toString();
template_selection.value = new_table_data.findIndex((item: linkData) => item.id == row.id).toString();
modelValue.value = row;
};
//#region -----------------------------------------------start

View File

@ -197,16 +197,11 @@ const rules = ref<FormRules>({
key: [{ required: true, trigger: 'change', message: '关键词不能为空' }],
});
const ruleFormRef = ref<FormInstance>();
interface formType {
id?: number;
name: string;
link: string;
}
const on_submit = () => {
if (!ruleFormRef.value) return;
ruleFormRef.value.validate((valid: boolean) => {
if (valid) {
let new_value: formType = {
let new_value: linkData = {
name: form.key,
link: form.key,
};

View File

@ -50,13 +50,7 @@ watch(
}
);
const modelValue = defineModel({ type: Object, default: {} });
interface User {
id: number;
name: string;
icon: string;
link: string;
}
const tableData: User[] = [
const tableData: linkData[] = [
{
id: 1,
name: '一级分类',
@ -98,7 +92,7 @@ const template_selection = ref('');
const row_click = (row: any) => {
const new_table_data = JSON.parse(JSON.stringify(tableData));
template_selection.value = new_table_data.findIndex((item: User) => item.id == row.id).toString();
template_selection.value = new_table_data.findIndex((item: linkData) => item.id == row.id).toString();
modelValue.value = row;
};
//#region -----------------------------------------------start

View File

@ -40,13 +40,7 @@ watch(
);
const modelValue = defineModel({ type: Object, default: {} });
const search_value = ref('');
interface Data {
id: number;
name: string;
link?: String;
data?: Data[];
}
const base_data = ref<Data[]>([
const base_data = ref<linkData[]>([
{
id: 0,
name: '基础链接',
@ -101,7 +95,7 @@ const handle_search = () => {
};
const menu_active = ref('');
const emit = defineEmits(['update:link']);
const menu_link_event = (item: Data, parent_id: number) => {
const menu_link_event = (item: linkData, parent_id: number | undefined) => {
if (`${parent_id}-${item.id}` == menu_active.value) {
menu_active.value = '';
modelValue.value = {};

View File

@ -40,12 +40,7 @@ watch(
}
);
const modelValue = defineModel({ type: Object, default: {} });
interface User {
id: number;
name: string;
link: string;
}
const tableData: User[] = [
const tableData: linkData[] = [
{
id: 1,
name: '一级分类',
@ -76,7 +71,7 @@ const template_selection = ref('');
const row_click = (row: any) => {
const new_table_data = JSON.parse(JSON.stringify(tableData));
template_selection.value = new_table_data.findIndex((item: User) => item.id == row.id).toString();
template_selection.value = new_table_data.findIndex((item: linkData) => item.id == row.id).toString();
modelValue.value = row;
};
//#region -----------------------------------------------start

View File

@ -13,6 +13,7 @@ declare module 'vue' {
ColorPicker: typeof import('./../components/base/color-picker/index.vue')['default']
CommonStyles: typeof import('./../components/common/common-styles/index.vue')['default']
Components: typeof import('./../components/model-custom/components/index.vue')['default']
copy: typeof import('./../components/common/hot/index copy.vue')['default']
Dialog: typeof import('./../components/model-custom/components/dialog.vue')['default']
Drag: typeof import('./../components/base/drag/index.vue')['default']
ElBadge: typeof import('element-plus/es')['ElBadge']

17
src/types/global.d.ts vendored
View File

@ -97,6 +97,21 @@ declare global {
background_img_url: uploadList[];
};
/**
*
*/
type linkData = {
id?: number;
name: string;
link?: String;
data?: Data[];
icon?: string;
lng?: number;
lat?: number;
hasChildren?: boolean;
children?: linkData[];
};
/**
*
*/
@ -116,7 +131,7 @@ declare global {
drag_start: rectCoords;
drag_end: rectCoords;
name: string;
link: object;
link: linkData;
};
}
export {};