mirror of
				https://github.com/Powerful-517/yys-editor.git
				synced 2025-11-03 21:19:51 +00:00 
			
		
		
		
	1。根据pinia调整toolbar和projecExplorer 2.删除按钮增加确认,禁止删除最后一个元素
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -2,3 +2,4 @@
 | 
				
			|||||||
/node_modules
 | 
					/node_modules
 | 
				
			||||||
/.idea
 | 
					/.idea
 | 
				
			||||||
/dist
 | 
					/dist
 | 
				
			||||||
 | 
					/dist.zip
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										54
									
								
								src/App.vue
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								src/App.vue
									
									
									
									
									
								
							@@ -21,51 +21,6 @@ const onResizing = (x, y, width, height) => {
 | 
				
			|||||||
  height.value = height;
 | 
					  height.value = height;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const handleExport = () => {
 | 
					 | 
				
			||||||
  const dataStr = JSON.stringify(filesStore.fileList, null, 2);
 | 
					 | 
				
			||||||
  const blob = new Blob([dataStr], { type: 'application/json;charset=utf-8' });
 | 
					 | 
				
			||||||
  const url = URL.createObjectURL(blob);
 | 
					 | 
				
			||||||
  const link = document.createElement('a');
 | 
					 | 
				
			||||||
  link.href = url;
 | 
					 | 
				
			||||||
  link.download = 'files.json';
 | 
					 | 
				
			||||||
  link.click();
 | 
					 | 
				
			||||||
  URL.revokeObjectURL(url);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const onHandleInport = (file) => {
 | 
					 | 
				
			||||||
  const reader = new FileReader();
 | 
					 | 
				
			||||||
  reader.onload = (e) => {
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
      const data = JSON.parse(e.target.result as string);
 | 
					 | 
				
			||||||
      if (data[0].visible === true) {
 | 
					 | 
				
			||||||
        // 新版本格式:直接替换 fileList
 | 
					 | 
				
			||||||
        filesStore.$patch({ fileList: data });
 | 
					 | 
				
			||||||
      } else  {
 | 
					 | 
				
			||||||
        // 旧版本格式:仅包含 groups 数组
 | 
					 | 
				
			||||||
        const newFile = {
 | 
					 | 
				
			||||||
          label: `File ${filesStore.fileList.length + 1}`,
 | 
					 | 
				
			||||||
          name: String(filesStore.fileList.length + 1),
 | 
					 | 
				
			||||||
          visible: true,
 | 
					 | 
				
			||||||
          groups: data
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        filesStore.addFile(newFile);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } catch (error) {
 | 
					 | 
				
			||||||
      console.error('Failed to import file', error);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
  reader.readAsText(file);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// const onHandleInport = (file) => {
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//   handleImport(file);
 | 
					 | 
				
			||||||
// };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const onHandleExport = () => {
 | 
					 | 
				
			||||||
  handleExport();
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const element = ref({
 | 
					const element = ref({
 | 
				
			||||||
  x: 400,
 | 
					  x: 400,
 | 
				
			||||||
  y: 20,
 | 
					  y: 20,
 | 
				
			||||||
@@ -74,11 +29,6 @@ const element = ref({
 | 
				
			|||||||
  isActive: false,
 | 
					  isActive: false,
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const handleFileSelected = (fileId) => {
 | 
					 | 
				
			||||||
  filesStore.setActiveFile(fileId);
 | 
					 | 
				
			||||||
  filesStore.setVisible(fileId, true);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const handleTabsEdit = (
 | 
					const handleTabsEdit = (
 | 
				
			||||||
    targetName: String | undefined,
 | 
					    targetName: String | undefined,
 | 
				
			||||||
    action: 'remove' | 'add'
 | 
					    action: 'remove' | 'add'
 | 
				
			||||||
@@ -129,12 +79,12 @@ const activeFileGroups = computed(() => {
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="container">
 | 
					  <div class="container">
 | 
				
			||||||
    <!-- 工具栏 -->
 | 
					    <!-- 工具栏 -->
 | 
				
			||||||
    <Toolbar title="yys-editor" username="示例用户" @handleExport="onHandleExport" @handleImport="onHandleInport" />
 | 
					    <Toolbar title="yys-editor" username="示例用户"/>
 | 
				
			||||||
    <!-- 侧边栏和工作区 -->
 | 
					    <!-- 侧边栏和工作区 -->
 | 
				
			||||||
    <div class="main-content">
 | 
					    <div class="main-content">
 | 
				
			||||||
      <!-- 侧边栏 -->
 | 
					      <!-- 侧边栏 -->
 | 
				
			||||||
      <aside class="sidebar">
 | 
					      <aside class="sidebar">
 | 
				
			||||||
        <ProjectExplorer :allFiles="filesStore.fileList" @file-selected="handleFileSelected" />
 | 
					        <ProjectExplorer :allFiles="filesStore.fileList" />
 | 
				
			||||||
      </aside>
 | 
					      </aside>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      <!-- 工作区 -->
 | 
					      <!-- 工作区 -->
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
import { defineProps, defineEmits } from 'vue';
 | 
					import { defineProps, defineEmits } from 'vue';
 | 
				
			||||||
 | 
					import { useFilesStore } from "@/stores/files";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const filesStore = useFilesStore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
  allFiles: {
 | 
					  allFiles: {
 | 
				
			||||||
@@ -18,7 +21,6 @@ const props = defineProps({
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const emit = defineEmits(['file-selected']);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const defaultProps = {
 | 
					const defaultProps = {
 | 
				
			||||||
  children: 'children',
 | 
					  children: 'children',
 | 
				
			||||||
@@ -26,7 +28,8 @@ const defaultProps = {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const handleNodeClick = (data) => {
 | 
					const handleNodeClick = (data) => {
 | 
				
			||||||
  emit('file-selected', data.name);
 | 
					  filesStore.setActiveFile(data.name);
 | 
				
			||||||
 | 
					  filesStore.setVisible(data.name, true);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -78,14 +78,17 @@
 | 
				
			|||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script setup>
 | 
					<script setup lang="ts">
 | 
				
			||||||
import {ref, reactive} from 'vue';
 | 
					import {ref, reactive} from 'vue';
 | 
				
			||||||
import html2canvas from "html2canvas";
 | 
					import html2canvas from "html2canvas";
 | 
				
			||||||
import {useI18n} from 'vue-i18n';
 | 
					import {useI18n} from 'vue-i18n';
 | 
				
			||||||
 | 
					import updateLogs from "../data/updateLog.json"
 | 
				
			||||||
 | 
					import {useFilesStore} from "@/stores/files";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const filesStore = useFilesStore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 获取当前的 i18n 实例
 | 
					// 获取当前的 i18n 实例
 | 
				
			||||||
const {t} = useI18n();
 | 
					const {t} = useI18n();
 | 
				
			||||||
const emit = defineEmits(['handleExport', 'handleImport']);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 定义响应式数据
 | 
					// 定义响应式数据
 | 
				
			||||||
const state = reactive({
 | 
					const state = reactive({
 | 
				
			||||||
@@ -96,26 +99,6 @@ const state = reactive({
 | 
				
			|||||||
  showFeedbackFormDialog: false, // 控制反馈表单对话框的显示状态
 | 
					  showFeedbackFormDialog: false, // 控制反馈表单对话框的显示状态
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 版本记录数据
 | 
					 | 
				
			||||||
const updateLogs = [
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    version: '2.0.0',
 | 
					 | 
				
			||||||
    date: '2025-03-16',
 | 
					 | 
				
			||||||
    changes: [
 | 
					 | 
				
			||||||
      '修复了相同式神不能正确设置属性的问题',
 | 
					 | 
				
			||||||
      '支持了多文件编辑',
 | 
					 | 
				
			||||||
      'PS:当前导出截图宽度无法'
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    version: '1.0.0',
 | 
					 | 
				
			||||||
    date: '2025-03-09',
 | 
					 | 
				
			||||||
    changes: [
 | 
					 | 
				
			||||||
      '首次发布'
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const showUpdateLog = () => {
 | 
					const showUpdateLog = () => {
 | 
				
			||||||
  state.showUpdateLogDialog = !state.showUpdateLogDialog;
 | 
					  state.showUpdateLogDialog = !state.showUpdateLogDialog;
 | 
				
			||||||
@@ -126,7 +109,14 @@ const showFeedbackForm = () => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const handleExport = () => {
 | 
					const handleExport = () => {
 | 
				
			||||||
  emit('handleExport');
 | 
					  const dataStr = JSON.stringify(filesStore.fileList, null, 2);
 | 
				
			||||||
 | 
					  const blob = new Blob([dataStr], { type: 'application/json;charset=utf-8' });
 | 
				
			||||||
 | 
					  const url = URL.createObjectURL(blob);
 | 
				
			||||||
 | 
					  const link = document.createElement('a');
 | 
				
			||||||
 | 
					  link.href = url;
 | 
				
			||||||
 | 
					  link.download = 'files.json';
 | 
				
			||||||
 | 
					  link.click();
 | 
				
			||||||
 | 
					  URL.revokeObjectURL(url);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const handleImport = () => {
 | 
					const handleImport = () => {
 | 
				
			||||||
@@ -135,7 +125,30 @@ const handleImport = () => {
 | 
				
			|||||||
  input.accept = '.json';
 | 
					  input.accept = '.json';
 | 
				
			||||||
  input.onchange = (e) => {
 | 
					  input.onchange = (e) => {
 | 
				
			||||||
    const file = e.target.files[0];
 | 
					    const file = e.target.files[0];
 | 
				
			||||||
    if (file) emit('handleImport', file);
 | 
					    if (file) {
 | 
				
			||||||
 | 
					      const reader = new FileReader();
 | 
				
			||||||
 | 
					      reader.onload = (e) => {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					          const data = JSON.parse(e.target.result as string);
 | 
				
			||||||
 | 
					          if (data[0].visible === true) {
 | 
				
			||||||
 | 
					            // 新版本格式:直接替换 fileList
 | 
				
			||||||
 | 
					            filesStore.$patch({ fileList: data });
 | 
				
			||||||
 | 
					          } else  {
 | 
				
			||||||
 | 
					            // 旧版本格式:仅包含 groups 数组
 | 
				
			||||||
 | 
					            const newFile = {
 | 
				
			||||||
 | 
					              label: `File ${filesStore.fileList.length + 1}`,
 | 
				
			||||||
 | 
					              name: String(filesStore.fileList.length + 1),
 | 
				
			||||||
 | 
					              visible: true,
 | 
				
			||||||
 | 
					              groups: data
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            filesStore.addFile(newFile);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        } catch (error) {
 | 
				
			||||||
 | 
					          console.error('Failed to import file', error);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					      reader.readAsText(file);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  input.click();
 | 
					  input.click();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -119,6 +119,7 @@ import '@vueup/vue-quill/dist/vue-quill.snow.css' // 引入样式文件
 | 
				
			|||||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
 | 
					import * as ElementPlusIconsVue from '@element-plus/icons-vue'
 | 
				
			||||||
import shikigamiData from '../data/Shikigami.json';
 | 
					import shikigamiData from '../data/Shikigami.json';
 | 
				
			||||||
import _ from 'lodash';
 | 
					import _ from 'lodash';
 | 
				
			||||||
 | 
					import {Action, ElMessage, ElMessageBox} from "element-plus";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps<{
 | 
					const props = defineProps<{
 | 
				
			||||||
  groups: any[];
 | 
					  groups: any[];
 | 
				
			||||||
@@ -215,11 +216,57 @@ const updateProperty = (property) => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const removeGroupElement = (groupIndex, positionIndex) => {
 | 
					const removeGroupElement = (groupIndex, positionIndex) => {
 | 
				
			||||||
  props.groups[groupIndex].groupInfo.splice(positionIndex, 1);
 | 
					  const group = props.groups[groupIndex];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (group.groupInfo.length === 1) {
 | 
				
			||||||
 | 
					    ElMessageBox.alert('无法删除', '提示', {
 | 
				
			||||||
 | 
					      confirmButtonText: '确定',
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ElMessageBox.confirm('确定要删除此元素吗?', '提示', {
 | 
				
			||||||
 | 
					    confirmButtonText: '确定',
 | 
				
			||||||
 | 
					    cancelButtonText: '取消',
 | 
				
			||||||
 | 
					    type: 'warning',
 | 
				
			||||||
 | 
					  }).then(() => {
 | 
				
			||||||
 | 
					    group.groupInfo.splice(positionIndex, 1);
 | 
				
			||||||
 | 
					    ElMessage({
 | 
				
			||||||
 | 
					      type: 'success',
 | 
				
			||||||
 | 
					      message: '删除成功!',
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }).catch(() => {
 | 
				
			||||||
 | 
					    ElMessage({
 | 
				
			||||||
 | 
					      type: 'info',
 | 
				
			||||||
 | 
					      message: '已取消删除',
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const removeGroup = (groupIndex) => {
 | 
					const removeGroup = (groupIndex) => {
 | 
				
			||||||
 | 
					  if (props.groups.length === 1) {
 | 
				
			||||||
 | 
					    ElMessageBox.alert('无法删除最后一个队伍', '提示', {
 | 
				
			||||||
 | 
					      confirmButtonText: '确定',
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ElMessageBox.confirm('确定要删除此组吗?', '提示', {
 | 
				
			||||||
 | 
					    confirmButtonText: '确定',
 | 
				
			||||||
 | 
					    cancelButtonText: '取消',
 | 
				
			||||||
 | 
					    type: 'warning',
 | 
				
			||||||
 | 
					  }).then(() => {
 | 
				
			||||||
    props.groups.splice(groupIndex, 1);
 | 
					    props.groups.splice(groupIndex, 1);
 | 
				
			||||||
 | 
					    ElMessage({
 | 
				
			||||||
 | 
					      type: 'success',
 | 
				
			||||||
 | 
					      message: '删除成功!',
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }).catch(() => {
 | 
				
			||||||
 | 
					    ElMessage({
 | 
				
			||||||
 | 
					      type: 'info',
 | 
				
			||||||
 | 
					      message: '已取消删除',
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const addGroup = () => {
 | 
					const addGroup = () => {
 | 
				
			||||||
@@ -392,7 +439,8 @@ defineExpose({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  .opt-btn {
 | 
					  .opt-btn {
 | 
				
			||||||
    position: absolute;
 | 
					    position: absolute;
 | 
				
			||||||
    top: -10px;
 | 
					    top: 0px;
 | 
				
			||||||
 | 
					    z-index: 10;
 | 
				
			||||||
    opacity: 0;
 | 
					    opacity: 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								src/data/updateLog.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/data/updateLog.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					[
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "2.0.0",
 | 
				
			||||||
 | 
					    "date": "2025-03-16",
 | 
				
			||||||
 | 
					    "changes": [
 | 
				
			||||||
 | 
					      "修复了相同式神不能正确设置属性的问题",
 | 
				
			||||||
 | 
					      "支持了多文件编辑",
 | 
				
			||||||
 | 
					      "PS:当前导出截图宽度无法"
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "1.0.0",
 | 
				
			||||||
 | 
					    "date": "2025-03-09",
 | 
				
			||||||
 | 
					    "changes": [
 | 
				
			||||||
 | 
					      "首次发布"
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
		Reference in New Issue
	
	Block a user