逻辑编排前端

PanelGlobal.vue 14KB

    <template> <div class="panel-global"> <el-tabs v-model="activeName" @tab-click="handleClick"> <el-tab-pane label="基础信息" name="basic"> <el-form :model="basicFormData" :rules="basicFormRules" label-position="top" > <el-form-item label="服务名称" prop="name"> <el-input v-model="basicFormData.name" placeholder="请输入场景名" ></el-input> </el-form-item> <el-form-item label="服务路径" prop="name"> <el-input v-model="basicFormData.path" placeholder="请输入路径" ></el-input> </el-form-item> <el-form-item label="服务方法" prop="method"> <el-select v-model="basicFormData.method" class="form-item" :options="methodsOptions" placeholder="请选择服务方法" ></el-select> </el-form-item> <el-form-item label="服务描述"> <el-input v-model="basicFormData.desc" type="textarea" clearable :autosize="{ minRows: 10, maxRows: 20 }" maxlength="200" show-word-limit placeholder="请输入服务描述" ></el-input> </el-form-item> </el-form> </el-tab-pane> <!-- <el-tab-pane label="模型属性声明" name="modelAttrs"> <el-button type="success" @click.stop="importModelAttr">引入</el-button> </el-tab-pane> --> <el-tab-pane label="自定义属性声明" name="customAttrs"> <div class="btn-box"> <span> <el-button type="success" @click.stop="addCustomAttr"> 新增 </el-button> <el-button @click.stop="viewCustomDetail">查看列表详情</el-button> <!-- <el-button @click.stop="downloadModule">模板下载</el-button> --> </span> <el-upload action accept=".xlsx, .xls" :auto-upload="false" :show-file-list="false" :on-change="useExcelHooks" > <el-button type="success">快速创建</el-button> </el-upload> </div> </el-tab-pane> <el-tab-pane label="模型声明" name="models"> <el-button type="success" @click.stop="importModel">引入</el-button> </el-tab-pane> </el-tabs> <!-- 模型属性声明 --> <!-- 自定义属性声明 --> <!-- 模型声明 --> <el-table v-if="activeName === 'models' || activeName === 'customAttrs'" class="global-table" :table-header="table[activeName]?.header" :table-data="table[activeName]?.data" > <template #custom="scope"> <el-icon v-if="activeName === 'customAttrs'" class="icon" @click="editFn(scope.row)" > <Edit></Edit> </el-icon> <!-- 删除 --> <el-popconfirm :title="deleteTitle[activeName]" @confirm="confirmEvent(scope.row)" @cancel="cancelEvent" > <template #reference> <el-icon class="icon"><Delete></Delete></el-icon> </template> </el-popconfirm> </template> </el-table> </div> <dialog-panel v-if="isShowPanel" :dialog-data="dialog[dialogType]" @confirm-dialog="confirmDialog" @close-dialog="closeDialog" > <!-- 引入模型 --> <import-model v-if="dialogType === 'importModel'"></import-model> <!-- 引入模型属性 --> <!-- 自定义属性 --> <custom-detail v-if="dialogType === 'addCustom'" :attr-info="attrInfo" ></custom-detail> <!-- 自定义属性列表 --> <custom-detail-list v-if="dialogType === 'viewCustomDetail'" :attr-datas="table.customAttrs.data" ></custom-detail-list> </dialog-panel> </template> <script setup> import { computed, reactive, ref, watch } from 'vue'; import XLSX from 'xlsx'; // 模型属性引入 import { useRoute } from 'vue-router'; import { useStore } from 'vuex'; // eslint-disable-next-line no-unused-vars import ImportModel from './global/ImportModel.vue'; import CustomDetailList from './global/CustomDetailList.vue'; import CustomDetail from './global/CustomDetail.vue'; const activeName = ref('customAttrs'); const route = useRoute(); const flowId = computed(() => route.query.id); const store = useStore(); console.log(store.getters['sceneFlow/curLogicFlowInfo']); const curLogicInfo = store.getters['sceneFlow/curLogicFlowInfo'] || null; // 表格信息 const table = ref({ modelAttrs: { header: [ { label: '模型名称', name: 'modelName', 'min-width': '150' }, { label: '模型ID', name: 'modelID', 'min-width': '150' }, { label: '属性名称', name: 'attrName', 'min-width': '150' }, { label: '属性ID', name: 'attrID', 'min-width': '150' }, { label: '操作', name: 'custom', type: 'custom', fixed: 'right', width: '100' } ], data: [ { modelName: '123', modelID: '123', attrName: 'shuxing', attrID: '222' } ] }, customAttrs: { header: [ { label: '属性名称', name: 'name', 'min-width': '150' }, { label: '属性ID', name: 'id', 'min-width': '150' }, { label: '操作', name: 'custom', type: 'custom', fixed: 'right', width: '100' } ], data: [] }, models: { header: [ { label: '模型名称', name: 'modelName', 'min-width': '150' }, { label: '模型ID', name: 'modelID', 'min-width': '150' }, { label: '操作', name: 'custom', type: 'custom', fixed: 'right', width: '100' } ], data: [] } }); const deleteTitle = reactive({ modelAttrs: '你确定删除这项模型属性吗?', customAttrs: '你确定删除这项自定义属性吗?', models: '你确定删除这项模型吗?' }); const isShowPanel = ref(false); const panelGlobal = JSON.parse(localStorage.getItem('panelGlobal')) || null; if (panelGlobal && 'customAttrs' in panelGlobal[flowId.value]) { // debugger table.value = JSON.parse(localStorage.getItem('panelGlobal'))[flowId.value]; } watch( table.value, () => { parsePanelGlobalData(); }, { deep: true } ); // 处理整体服务数据 function parsePanelGlobalData() { const panelGlobalData = ref({}); // if (localStorage.getItem('panelGlobal')) { // panelGlobalData.value = JSON.parse(localStorage.getItem('panelGlobal')) // } panelGlobalData.value[flowId.value] = table.value; localStorage.setItem('panelGlobal', JSON.stringify(panelGlobalData.value)); } parsePanelGlobalData(); // 删除确认 function confirmEvent(row) { table.value[activeName.value].data.forEach((item, index) => { if (item.id === row.id) { table.value[activeName.value].data.splice(index, 1); } }); } // 取消删除 function cancelEvent() {} const dialogType = ref('importModel'); const dialog = ref({ importModel: { title: '引入模型', name: 'importDialog' }, addCustom: { title: '新增属性声明', name: 'addCustom' }, viewCustomDetail: { title: '属性声明', name: 'viewDetail' }, modelAttrImport: { title: '模型属性声明', name: 'modelAttrs' } }); const initFormData = { id: '', name: '', type: '', isValidate: true, validateRules: { max: '', min: '', more: '', less: '', equal: '', unequal: '', nullable: true, scale: '', precision: '' } }; const attrInfo = ref({ type: 'add', formData: JSON.parse(JSON.stringify(initFormData)) }); function editFn(row) { isShowPanel.value = true; dialogType.value = 'addCustom'; attrInfo.value = { type: 'edit', formData: row }; dialog.value.addCustom.title = '编辑属性声明'; } /** 基本信息start */ function setBasicInfo() { const basicFormData = ref({ name: curLogicInfo?.name || '', path: curLogicInfo?.requestUrl || '', desc: curLogicInfo?.desc || '', method: curLogicInfo?.requestType || '' }); const methodsOptions = reactive([ { label: 'GET', value: 'GET' }, { label: 'POST', value: 'POST' }, { label: 'PUT', value: 'PUT' }, { label: 'DELETE', value: 'DELETE' }, { label: 'PATCH', value: 'PATCH' } ]); const basicFormRules = reactive({ name: [ { required: true, message: '请输入服务名称', trigger: 'blur' }, { min: 3, max: 100, message: '名称在3-100之间', trigger: 'blur' } ] }); return { basicFormData, methodsOptions, basicFormRules }; } const { basicFormData, methodsOptions, basicFormRules } = setBasicInfo(); /** 基本信息 end */ /** 模型属性声明 start */ // function setModelAttrsInfo() { // function importModelAttr(item) { // console.log(item); // isShowPanel.value = true; // dialogType.value = 'modelAttrImport'; // } // return { importModelAttr }; // } // const { importModelAttr } = setModelAttrsInfo(); /** 模型属性声明 end */ /** 自定义属性声明start */ function setCustomAttrs() { // 新增自定义属性 function addCustomAttr() { isShowPanel.value = true; dialog.value.addCustom.title = '新增属性声明'; attrInfo.value = { type: 'add', formData: JSON.parse(JSON.stringify(initFormData)) }; dialogType.value = 'addCustom'; } // 查看自定义属性详情列表 function viewCustomDetail() { isShowPanel.value = true; dialogType.value = 'viewCustomDetail'; } return { addCustomAttr, viewCustomDetail }; } const { addCustomAttr, viewCustomDetail } = setCustomAttrs(); /** 自定义属性声明 end */ /** 模型声明 start */ function setModelInfo() { function importModel() { isShowPanel.value = true; dialogType.value = 'importModel'; } return { importModel }; } const { importModel } = setModelInfo(); /** 模型声明 end */ function confirmDialog() { switch (dialogType.value) { case 'importModel': break; case 'addCustom': customAttrFn(); break; case 'viewCustomDetail': closeDialog(); break; default: break; } parsePanelGlobalData(); // } function closeDialog() { isShowPanel.value = false; } // 自定义属性表格操作 function customAttrFn() { if (attrInfo.value.type === 'add') { table.value.customAttrs.data.unshift(attrInfo.value.formData); attrInfo.value = { type: 'add', formData: JSON.parse(JSON.stringify(initFormData)) }; } else if (attrInfo.value.type === 'edit') { table.value.customAttrs.data.map((item) => { if (item.id === attrInfo.value.formData.id) { item = attrInfo.value.formData; } return item; }); } closeDialog(); } // excel表数据处理 const tableData = ref([]); function useExcelHooks(e) { const result = ref([]); // 文件读取 function readFile(file) { return new Promise((resolve) => { const reader = new FileReader(); reader.readAsBinaryString(file); reader.onload = (e) => { resolve(e.target.result); }; }); } function parseTableData(data) { tableData.value = []; if (Array.isArray(data) && data.length) { let el = {}; data.forEach((item) => { el = { id: item.id, isValidate: item.isValidate || '', name: item.name || '', type: item.type || '', validateRules: { equal: item.equal || '', less: item.less || '', max: item.max || '', min: item.min || '', more: item.more || '', nullable: item.nullable || false, precision: item.precision || '', scale: item.scale || '', unequal: item.unequal || '' } }; tableData.value.push(el); }); } } function duplication(data) { const set = new Set(); data.forEach((item) => set.add(item)); return Array.from(set); } function unique(arr) { const res = new Map(); return arr.filter( (a) => !res.has(a.id) && res.set(a.id, 1) && !res.has(a.name) && res.set(a.name, 1) ); } // excel转json function excelToJson() { const file = e.raw; readFile(file) .then((data) => { const workbook = XLSX.read(data, { type: 'binary' }); // 解析二进制格式数据 console.log(workbook); const worksheet = workbook.Sheets[workbook.SheetNames[0]]; // 获取第一个Sheet console.log(worksheet); result.value = XLSX.utils.sheet_to_json(worksheet); // json数据格式 parseTableData(result.value); console.log(result.value); }) .finally(() => { table.value[activeName.value].data = unique([ ...table.value[activeName.value].data, ...tableData.value ]); }); } excelToJson(); } // 模板下载 // function downloadModule() { // const title = '自定义属性模板.xlsx'; // const headers = [ // [ // 'id', // 'name', // 'type', // 'isValidate', // 'equal', // 'less', // 'max', // 'min', // 'more', // 'nullable', // 'precision', // 'scale', // 'unequal' // ], // ['', '', '', '', '', '', '', '', '', '', '', '', ''] // ]; // const worksheet = XLSX.utils.aoa_to_sheet(headers); // const workbook = XLSX.utils.book_new(); // XLSX.utils.book_append_sheet(workbook, worksheet, '自定义属性模板'); // XLSX.writeFile(workbook, title, { type: 'file' }); // } </script> <script> export default { name: 'PanelGlobal' }; </script> <style scoped lang="scss"> .global-table { margin-top: 10px; } .icon { margin-right: 10px; cursor: pointer; } .form-item { width: 100%; } .btn-box { display: flex; justify-content: space-between; } </style>