Commit 464710f1 by ningjihai

123

parent 6bc33388
...@@ -125,7 +125,8 @@ ...@@ -125,7 +125,8 @@
.custom-dialog { .custom-dialog {
border-radius: 8px; border-radius: 8px;
.custom-dialog-header { .custom-dialog-header {
padding-top: 30px; width: 100%;
// padding-top: 30px;
padding-left: 28px; padding-left: 28px;
padding-right: 32px; padding-right: 32px;
display: flex; display: flex;
......
<template> <template>
<el-dialog <el-dialog
style="padding: 0;"
class="custom-dialog"
v-model="dialogVisible" v-model="dialogVisible"
:title="dialogTitle" :show-close="false"
destroy-on-close destroy-on-close
width="920px"
:before-close="handleClose" :before-close="handleClose"
> >
<template #header>
<div class="custom-dialog-header">
<div class="custom-dialog-title">
{{ dialogTitle }}
</div>
<img class="custom-dialog-close" :src="dialogCloseLogo" alt="" @click="closeDialog">
</div>
</template>
<!-- <el-divider class="dialog-divider"></el-divider> -->
<div class="dialog-content"> <div class="dialog-content">
<!-- 左侧表单 --> <!-- 左侧表单 -->
<div class="form-container"> <div class="form-container">
<ItemTitle title="基本信息" />
<!-- 第一步:基本信息 --> <!-- 第一步:基本信息 -->
<div v-if="activeStep === 1"> <div class="item-form-container">
<el-form <el-form
ref="basicInfoFormRef" ref="basicInfoFormRef"
:model="formData" :model="formData"
:rules="formRules" :rules="formRules"
label-width="100px" label-width="90px"
label-position="top" label-position="left"
:inline="true"
> >
<el-form-item label="项目名称" prop="name" required> <el-form-item label="项目名称" prop="name" required>
<el-input <el-input
v-model="formData.name" v-model="formData.name"
placeholder="请输入项目名称" placeholder="请输入项目名称"
maxlength="200"
show-word-limit
/> />
</el-form-item> </el-form-item>
<el-form-item label="项目备注" prop="remark"> <el-form-item label="项目备注" prop="remark">
<el-input <el-input
v-model="formData.remark" v-model="formData.remark"
type="textarea"
:rows="4"
placeholder="请输入项目备注信息" placeholder="请输入项目备注信息"
maxlength="200"
show-word-limit
/> />
</el-form-item> </el-form-item>
...@@ -46,212 +58,124 @@ ...@@ -46,212 +58,124 @@
</el-form> </el-form>
</div> </div>
<ItemTitle title="数据源配置" style="margin-top: 20px;" />
<!-- 第二步:数据库配置 --> <!-- 第二步:数据库配置 -->
<div v-if="activeStep === 2"> <div class="item-form-container">
<div class="step-title">数据库</div>
<div class="filter-container">
<el-select v-model="dbFilter.type" placeholder="请选择" class="filter-select" @change="selectChangeSql"> <!-- TreeSelect 组件 -->
<el-option v-for="(item,index) in sourceTypeList" :key="index" :label="item.text" :value="item.text" /> <div class="tree-select-container flex-container align-center" style="flex-wrap: nowrap;">
</el-select> <div class="step-title master" style="width: 90px;">数据库</div>
<el-tree-select
<el-input ref="treeSelectRef"
v-model="dbFilter.keyword" v-model="selectedDbNodes"
placeholder="输入数据源名称搜索" :data="treeData"
class="filter-input" :props="treeProps"
clearable :render-after-expand="false"
show-checkbox
node-key="tid"
:filter-node-method="filterNode"
placeholder="请选择数据源"
multiple
@check="handleTreeSelectCheck"
@node-click="handleNodeExpand"
:default-expand-all="false"
> >
<template #prefix> <template #default="{ node, data }">
<el-icon><search /></el-icon> <span class="tree-node-label">
{{ data.sysname || data.text }}
<span v-if="data.dbtype" class="tree-node-type">({{ data.dbtype }})</span>
</span>
</template> </template>
</el-input> </el-tree-select>
</div>
<div class="db-select-container">
<!-- 左侧可选数据库 -->
<div class="db-list">
<div class="db-list-header">
<span>可选择数据源(数据库)</span>
</div>
<el-scrollbar height="300px">
<div
v-for="db in filteredAvailableDatabases"
:key="db.tid"
class="db-item"
@click="selectDatabase(db)"
>
<div class="db-info">
<div class="db-name">{{ db.sysname }}</div>
<div class="db-type">{{ db.dbtype }}</div>
</div>
</div>
</el-scrollbar>
</div>
<!-- 右侧已选数据库 -->
<div class="db-list selected">
<div class="db-list-header">
<span>已选择数据源(数据库)</span>
<span style="color: #2d8cf0;cursor: pointer;" @click="handleClearSelected">清空</span>
</div>
<el-scrollbar height="300px">
<div
v-for="db in selectedDbDetails"
:key="db.tid"
class="selected-db-item"
@click="deselectDatabase(db)"
>
<div class="db-name">{{ db.sysname }}</div>
<!-- <div class="db-ip">{{ db.dbip }}</div> -->
<div class="db-type">{{ db.dbtype }}</div>
</div>
</el-scrollbar>
</div>
</div> </div>
</div> </div>
<ItemTitle title="Schema选择" style="margin-top: 20px;"/>
<!-- 第三步:Schema选择 --> <!-- 第三步:Schema选择 -->
<div v-if="activeStep === 3"> <div class="item-form-container">
<div class="step-title">Schema选择</div> <div v-if="selectedDbDetails.length === 0" class="flex-container align-center">
请先选择数据库
<div class="schema-container"> </div>
<!-- 左侧数据源 --> <div class="flex-container align-center wrap" v-else>
<div class="datasource-section"> <div
<div class="section-title">数据源</div> v-for="(db, dbIndex) in selectedDbDetails"
<el-scrollbar height="400px"> :key="db.tid"
<div class="datasource-list"> class="datasource-item flex-container align-center"
<div >
v-for="(db, dbIndex) in selectedDbDetails" <div style="width: 90px;">{{ db.sysname }}</div>
:key="db.tid" <el-select
class="datasource-item" v-model="selectedSchemas[dbIndex]"
:class="{ active: selectedDataSource === db.tid }" multiple
@click="selectDataSource(db.tid, dbIndex)" placeholder="请选择"
> style="width: 278px"
{{ db.sysname }} collapse-tags
</div> collapse-tags-tooltip
</div> :max-collapse-tags="2"
</el-scrollbar> @change="selectChangeSchema"
</div> >
<el-option
<!-- 右侧Schema选择 --> v-for="schema in allSchemas[dbIndex]"
<div class="schema-section"> :key="schema.value"
<div class="schema-header"> :label="schema.text"
<div class="section-title">SCHEMA</div> :value="schema.value"
<div class="schema-select-all"> />
<span class="schema-count">{{ selectedSchemas.length }}/{{ allSchemasCompute?.length }}</span> </el-select>
</div>
</div>
<el-scrollbar height="400px">
<el-checkbox-group v-model="selectedSchemas" @change="schemaChange">
<div
v-for="schema in allSchemasCompute"
:key="schema.value"
class="schema-item"
>
<el-checkbox
:value="schema.value"
:label="schema.text"
:checked="isSchemaSelected(schema.value)"
/>
</div>
</el-checkbox-group>
</el-scrollbar>
</div> </div>
</div> </div>
</div> </div>
<!-- 其他步骤内容保持不变 --> <!-- 其他步骤内容保持不变 -->
<ItemTitle title="规则选择" style="margin-top: 20px;"/>
<!-- 第四步:数据域选择 -->
<!-- 第四步:数据域选择 --> <!-- 第四步:数据域选择 -->
<div v-if="activeStep === 4"> <div class="item-form-container">
<div class="step-title">规则选择</div> <div class="tree-select-container flex-container align-center" style="flex-wrap: nowrap;">
<div class="step-title master" style="width: 90px;">规则</div>
<div class="domain-container"> <el-tree-select
<!-- 左侧可选择规则 --> ref="treeSelectRuleRef"
<div class="available-domains"> v-model="selectedRuleNode"
<div class="section-header"> node-key="id"
<div class="section-title">可选择规则</div> :data="transformedDomainGroups"
</div> :props="treeRuleProps"
placeholder="请选择规则"
<div class="domain-group" v-for="group in domainGroups" :key="group.id"> multiple
<div class="group-header"> :render-after-expand="false"
<el-checkbox show-checkbox
v-model="group.selectedAll" >
@change="(val) => toggleGroupSelection(group, val)" <template #default="{ node, data }">
> <span class="tree-node-label">
{{ group.dataarea }} {{ data.dataarea || data.name }}
</el-checkbox> </span>
</div> </template>
</el-tree-select>
<el-scrollbar height="150px">
<el-checkbox-group v-model="selectedDomains" @change="handleDomainSelectionChange">
<div
v-for="domain in group.list"
:key="domain.id"
class="domain-item"
>
<el-checkbox :value="domain.id" :checked="isDomainSelected(domain.id)">
<div class="domain-content">
<div class="domain-name">{{ domain.name }}</div>
<div v-if="domain.desc" class="domain-desc">{{ domain.desc }}</div>
</div>
</el-checkbox>
</div>
</el-checkbox-group>
</el-scrollbar>
</div>
</div>
<!-- 已选择规则 -->
<div class="selected-domains">
<div class="section-header">
<div class="section-title">已选择规则</div>
<div class="selection-info">
<span class="count">{{ selectedDomains.length }}</span>
<el-button type="text" @click="clearSelectedDomains">清空</el-button>
</div>
</div>
<el-scrollbar height="400px">
<div
v-for="domain in selectedDomainDetails"
:key="domain.id"
class="selected-domain-item"
>
<div class="domain-name">{{ domain.name }}</div>
<div v-if="domain.desc" class="domain-desc">{{ domain.desc }}</div>
<div class="domain-group-name" v-if="findDomainGroupName(domain.id)">
所属分组: {{ findDomainGroupName(domain.id) }}
</div>
</div>
</el-scrollbar>
</div>
</div> </div>
</div> </div>
</div> </div>
<!-- 右侧步骤条 --> <!-- 右侧步骤条 -->
<div class="steps-container"> <!-- <div class="steps-container">
<el-steps direction="vertical" :active="activeStep"> <el-steps direction="vertical" :active="activeStep">
<el-step :title="stepTitles[0]" /> <el-step :title="stepTitles[0]" />
<el-step :title="stepTitles[1]" /> <el-step :title="stepTitles[1]" />
<el-step :title="stepTitles[2]" /> <el-step :title="stepTitles[2]" />
<el-step :title="stepTitles[3]" /> <el-step :title="stepTitles[3]" />
</el-steps> </el-steps>
</div> </div> -->
</div> </div>
<template #footer> <template #footer>
<span class="dialog-footer">
<el-button type="primary" color="rgba(33, 103, 217, 1)" @click="handleSubmit">确认</el-button>
<el-button type="primary" plain>取消</el-button>
<!-- <span class="dialog-footer">
<el-button @click="handlePrevStep">上一步</el-button> <el-button @click="handlePrevStep">上一步</el-button>
<el-button type="primary" @click="handleNextStep"> <el-button type="primary" @click="handleNextStep">
{{ activeStep === 4 ? '完成' : '下一步' }} {{ activeStep === 4 ? '完成' : '下一步' }}
</el-button> </el-button>
</span> </span> -->
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
...@@ -260,6 +184,8 @@ ...@@ -260,6 +184,8 @@
import { ref, computed, watch } from 'vue' import { ref, computed, watch } from 'vue'
import { ElMessageBox, ElMessage } from 'element-plus' import { ElMessageBox, ElMessage } from 'element-plus'
import { Search } from '@element-plus/icons-vue' import { Search } from '@element-plus/icons-vue'
import dialogCloseLogo from '@/assets/images/dialogCloseLogo.png'
import { import {
getdatascopeprojectlist, getdatascopeprojectlist,
checkDatasystemName, checkDatasystemName,
...@@ -315,12 +241,53 @@ const initialized = ref(false) ...@@ -315,12 +241,53 @@ const initialized = ref(false)
// 监听对话框显示状态变化 // 监听对话框显示状态变化
watch(dialogVisible, (newVal) => { watch(dialogVisible, (newVal) => {
if (newVal && !initialized.value) { if (newVal && !initialized.value) {
initDialog() // initDialog()
fetchFirstLevelNodes()
fetchRules()
} else if (!newVal) { } else if (!newVal) {
initialized.value = false initialized.value = false
} }
}, { deep: true }) }, { deep: true })
const fetchRules = () => {
getAllDataAreaAndRule().then(res => {
domainGroups.value = res.data
// 如果是编辑模式,需要处理已选择的规则
if (props.mode === 'edit' && areaAndRuleListRead.value.length > 0) {
processAreaAndRuleListForEdit(areaAndRuleListRead.value)
}
})
}
const treeRuleProps = reactive({
label: 'dataarea',
children: 'children'
});
const selectedRuleNode = ref([])
// 转换数据格式以适应el-tree-select
const transformedDomainGroups = computed(() => {
return domainGroups.value.map(group => {
// 复制组的基本信息
const transformedGroup = {
id: group.id,
dataarea: group.dataarea,
children: []
};
// 将list转换为children
if (group.list && Array.isArray(group.list)) {
transformedGroup.children = group.list.map(rule => ({
...rule,
id: rule.id,
name: rule.name,
dataarea: rule.type, // 使用type作为数据域名称
ruleexample: rule.ruleexample,
isRule: true // 标记为规则节点
}));
}
return transformedGroup;
});
});
// 当对话框显示时执行的函数 // 当对话框显示时执行的函数
const initDialog = () => { const initDialog = () => {
querySelectOrDic() querySelectOrDic()
...@@ -335,6 +302,167 @@ const querySelectOrDic = () => { ...@@ -335,6 +302,167 @@ const querySelectOrDic = () => {
dbFilter.value.type = res.data.length > 0 ? res.data[res.data.length - 1].text : '' dbFilter.value.type = res.data.length > 0 ? res.data[res.data.length - 1].text : ''
}) })
} }
const treeData = ref([])
const selectedDbNodes = ref([])
const treeProps = ref({
label: 'sysname', // 显示文本的字段名
children: 'children',
// disabled: (data) => !data.tid // 只有二级节点可以选择
})
// 获取树形数据
const fetchFirstLevelNodes = async () => {
try {
const typeRes = await selectProDataSource({
systemstyle: 1
})
if (typeRes.flag && typeRes.data) {
treeData.value = typeRes.data.map(item => ({
id: item.value,
tid:item.value,
text: item.text,
value: item.value,
sysname: item.text,
isFirstLevel: true,
children: [] // 初始化空children,用于懒加载
})).filter(item => item.value !== '0')
}
} catch (error) {
console.error('获取一级节点数据失败:', error)
ElMessage.error('获取数据源类型失败')
}
}
// 处理节点展开事件(懒加载二级节点)
// 处理节点展开事件(懒加载二级节点)
const handleNodeExpand = async (nodeData) => {
console.log('节点展开:', nodeData)
// 只有一级节点需要懒加载,且没有子节点或子节点为空
if (nodeData.isFirstLevel && (!nodeData.children || nodeData.children.length === 0)) {
try {
// 设置加载状态
nodeData.loading = true;
const secondRes = await queryByEditSort({
projectId: formData.value.id || '',
dbtype: nodeData.text,
loginUser: loginUser,
flag: 1
})
if (secondRes.flag && secondRes.data) {
// 使用 Vue.set 或创建新对象来确保响应式更新
const newChildren = secondRes.data.map(db => ({
...db,
parentName: nodeData.text,
parentId: nodeData.id,
text: db.sysname,
isFirstLevel: false
}))
// 关键:使用 Vue.set 或创建新数组来触发响应式更新
if (!nodeData.children) {
nodeData.children = newChildren;
} else {
nodeData.children.splice(0, nodeData.children.length, ...newChildren);
}
// 强制更新树数据(创建新数组引用)
treeData.value = [...treeData.value]
// 手动触发节点展开
nextTick(() => {
const treeInstance = treeSelectRef.value;
if (treeInstance && treeInstance.expandNode) {
treeInstance.expandNode(nodeData, true);
}
});
}
} catch (error) {
console.error(`获取 ${nodeData.text} 的二级节点失败:`, error)
ElMessage.error(`获取 ${nodeData.text} 的数据源失败`)
} finally {
nodeData.loading = false;
}
}
}
const treeSelectRef = ref(null)
// 处理树选择变化
const handleTreeSelectCheck = (checkedNode, { checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys }) => {
// 完全排除一级节点的选择,只保留有tid的二级节点
const secondaryNodes = checkedNodes.filter(node => node.tid && !node.isFirstLevel);
// selectedDbDetails.value = secondaryNodes;
// 更新选中节点的keys(只包含二级节点)
selectedDbNodes.value = secondaryNodes.map(node => node.tid);
// console.log('更新后的 selectedDbNodes:', selectedDbNodes.value);
};
watch(selectedDbNodes, (newVal) => {
console.log('getCheckedNodes',treeSelectRef.value.getCheckedNodes())
console.log('节点监听器',selectedDbNodes.value)
if(newVal) {
selectedDbDetails.value = treeSelectRef.value.getCheckedNodes()
fetchAllSchemas(selectedDbDetails.value)
}
}, { deep: true })
// // 移除已选数据源
// const removeSelectedDb = (db) => {
// const index = selectedDbDetails.value.findIndex(item => item.tid === db.tid)
// if (index > -1) {
// selectedDbDetails.value.splice(index, 1)
// selectedDbNodes.value = selectedDbDetails.value.map(db => db.tid)
// // 从树选择器中移除
// const treeSelectRef = document.querySelector('.el-tree-select')
// if (treeSelectRef) {
// const selectedValues = selectedDbNodes.value
// // 这里需要根据实际情况更新树选择器的值
// }
// }
// }
// 过滤节点
const filterNode = (value, data) => {
if (!value) return true
return data.sysname?.toLowerCase().includes(value.toLowerCase()) ||
data.text?.toLowerCase().includes(value.toLowerCase())
}
// 获取显示名称(一级节点/二级节点)
const getDbDisplayName = (db) => {
return `${db.parentName} / ${db.sysname}`
}
// 自定义节点样式 - 隐藏一级节点的checkbox
const customNodeClass = (data) => {
return data.isFirstLevel ? 'first-level-node' : 'second-level-node'
}
// // 在对话框显示时加载数据
// watch(dialogVisible, (newVal) => {
// if (newVal) {
// setTimeout(() => {
// fetchTreeData()
// }, 1000);
// }
// })
const reset = () => { const reset = () => {
sourceTypeList.value = [] sourceTypeList.value = []
...@@ -507,23 +635,7 @@ const schemaChange = () => { ...@@ -507,23 +635,7 @@ const schemaChange = () => {
}) })
} }
const toggleGroupSelection = (group, selected) => {
const groupDomainIds = group.list.map(d => d.id)
if (selected) {
const newSelected = [...new Set([...selectedDomains.value, ...groupDomainIds])]
selectedDomains.value = newSelected
} else {
selectedDomains.value = selectedDomains.value.filter(id => !groupDomainIds.includes(id))
}
}
const clearSelectedDomains = () => {
selectedDomains.value = []
domainGroups.value.forEach(group => {
group.selectedAll = false
})
}
// 上一步 // 上一步
const handlePrevStep = () => { const handlePrevStep = () => {
...@@ -664,6 +776,19 @@ const validateStep1 = async () => { ...@@ -664,6 +776,19 @@ const validateStep1 = async () => {
}) })
} }
const closeDialog = () => {
ElMessageBox.confirm('确定要关闭吗?未保存的更改将会丢失', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(() => {
dialogVisible.value = false
reset()
done()
}).catch(() => {
// 取消关闭
})
}
// 关闭前处理 // 关闭前处理
const handleClose = (done) => { const handleClose = (done) => {
ElMessageBox.confirm('确定要关闭吗?未保存的更改将会丢失', '提示', { ElMessageBox.confirm('确定要关闭吗?未保存的更改将会丢失', '提示', {
...@@ -691,28 +816,28 @@ watch(selectedDomains, (newVal) => { ...@@ -691,28 +816,28 @@ watch(selectedDomains, (newVal) => {
} }
}, { deep: true }) }, { deep: true })
// 修改数据源监听器,确保编辑模式下正确显示schema // // 修改数据源监听器,确保编辑模式下正确显示schema
watch(selectedDbDetails.value, async (newVal, oldVal) => { // watch(selectedDbDetails.value, async (newVal, oldVal) => {
console.log('数据源监听器') // console.log('数据源监听器')
if(newVal.length > 0) { // if(newVal.length > 0) {
console.log('数据源监听器2') // console.log('数据源监听器2')
console.log(newVal) // console.log(newVal)
console.log(oldVal) // console.log(oldVal)
if(JSON.stringify(newVal)) { // if(JSON.stringify(newVal)) {
console.log('数据源监听器3') // console.log('数据源监听器3')
await fetchAllSchemas(newVal) // await fetchAllSchemas(newVal)
} // }
if(!selectedDataSource.value) { // if(!selectedDataSource.value) {
selectedDataSource.value = newVal[0].tid // selectedDataSource.value = newVal[0].tid
} // }
// 如果是编辑模式且有schema数据,确保正确回显 // // 如果是编辑模式且有schema数据,确保正确回显
if (props.mode === 'edit' && originalSchemalist.value.length > 0) { // if (props.mode === 'edit' && originalSchemalist.value.length > 0) {
processSchemalistForEdit(originalSchemalist.value) // processSchemalistForEdit(originalSchemalist.value)
} // }
} // }
}, { immediate: true }) // }, { immediate: true })
// 在第三步激活时确保数据正确加载 // 在第三步激活时确保数据正确加载
...@@ -764,6 +889,22 @@ const fetchAllSchemas = async (databases) => { ...@@ -764,6 +889,22 @@ const fetchAllSchemas = async (databases) => {
} }
} }
const selectChangeSchema = async () => {
console.log('selectedSchemas',selectedSchemas.value)
let list = []
selectedSchemas.value.forEach((element,elementIndex) => {
element.forEach(item => {
list.push({
schemaname: item,
dbtype: selectedDbDetails.value[elementIndex].dbtype,
osdsid: selectedDbDetails.value[elementIndex].tid,
})
});
});
console.log(list)
schemalist.value = list
}
// 修改处理数据域和规则的方法 // 修改处理数据域和规则的方法
const processAreaAndRuleListForEdit = (areaAndRuleList) => { const processAreaAndRuleListForEdit = (areaAndRuleList) => {
if (!areaAndRuleList || !Array.isArray(areaAndRuleList)) { if (!areaAndRuleList || !Array.isArray(areaAndRuleList)) {
...@@ -942,16 +1083,66 @@ const isSchemaSelected = (schemaValue) => { ...@@ -942,16 +1083,66 @@ const isSchemaSelected = (schemaValue) => {
return selectedSchemas.value.includes(schemaValue) return selectedSchemas.value.includes(schemaValue)
} }
const handleSubmit = ()=> {
if(!formData.value.name || formData.value.name === ''){
ElMessage.warning('请输入项目名称')
return
}
if(!selectedDbNodes.value || selectedDbNodes.value.length === 0) {
ElMessage.warning('请选择数据库')
return
}
if(!selectedSchemas.value || selectedSchemas.value.length === 0) {
ElMessage.warning('请选择Schema')
return
}
if(!selectedRuleNode.value || selectedRuleNode.value.length === 0) {
ElMessage.warning('请选择规则')
return
}
console.log('项目名称',formData.value.name)
console.log('项目备注',formData.value.remark)
console.log('项目数据源',selectedDbDetails.value)
console.log('Schema',schemalist.value)
console.log('Schema',selectedRuleNode.value)
formData.value.databases = selectedDbDetails.value
formData.value.schemas = schemalist.value
// formData.value.domains = selectedDomainDetails.value.map(item => ({
// dataarea_id: item.dataarea_id,
// rule_id: item.id
// }))
}
// const selectedDomainDetails = computed(() => {
// const allDomains = domainGroups.value.flatMap(group => group.list)
// return allDomains.filter(domain => selectedDomains.value.includes(domain.id))
// })
</script> </script>
<style scoped> <style scoped lang="scss">
.dialog-content { .dialog-content {
display: flex; display: flex;
min-height: 500px; // min-height: 500px;
} }
.form-container { .form-container {
flex: 1; flex: 1;
padding-right: 30px; .el-form-item--default{
margin-bottom: 0px;
}
// padding-right: 30px;
} }
.steps-container { .steps-container {
...@@ -961,9 +1152,11 @@ const isSchemaSelected = (schemaValue) => { ...@@ -961,9 +1152,11 @@ const isSchemaSelected = (schemaValue) => {
} }
.step-title { .step-title {
font-size: 16px; font-size: 14px;
font-weight: bold; font-weight: 400;
margin-bottom: 20px; letter-spacing: 0px;
line-height: 22px;
color: rgba(148, 148, 148, 1);
} }
/* 第二步样式 */ /* 第二步样式 */
...@@ -1066,15 +1259,15 @@ const isSchemaSelected = (schemaValue) => { ...@@ -1066,15 +1259,15 @@ const isSchemaSelected = (schemaValue) => {
.datasource-item { .datasource-item {
padding: 10px 15px; padding: 10px 15px;
cursor: pointer; cursor: pointer;
border-bottom: 1px solid #f0f0f0; // border-bottom: 1px solid #f0f0f0;
} }
.datasource-item:hover { .datasource-item:hover {
background-color: #f0f7ff; // background-color: #f0f7ff;
} }
.datasource-item.active { .datasource-item.active {
background-color: #e6f7ff; // background-color: #e6f7ff;
color: #1890ff; color: #1890ff;
} }
...@@ -1199,4 +1392,58 @@ const isSchemaSelected = (schemaValue) => { ...@@ -1199,4 +1392,58 @@ const isSchemaSelected = (schemaValue) => {
font-weight: bold; font-weight: bold;
padding-bottom: 8px; padding-bottom: 8px;
} }
</style> .item-form-container {
\ No newline at end of file margin-top: 14px;
border-radius: 5px;
background: rgba(247, 248, 250, 1);
padding-top: 25px;
padding-bottom: 27px;
padding-left: 15px;
padding-right: 15px;
:deep(.el-form-item__label) {
font-size: 14px;
font-weight: 400;
letter-spacing: 0px;
color: rgba(148, 148, 148, 1);
}
:deep(.el-input__wrapper){
width: 278px;
}
}
/* 一级节点隐藏checkbox */
:deep(.first-level-node .el-checkbox) {
display: none !important;
}
/* 确保一级节点仍然可以点击展开 */
:deep(.first-level-node .el-tree-node__expand-icon) {
display: inline-block !important;
}
/* 二级节点正常显示checkbox */
:deep(.second-level-node .el-checkbox) {
display: inline-block !important;
}
.flex-container {
display: flex;
}
.wrap {
flex-wrap: wrap;
}
.align-center{
align-items: center;
}
.justify-center {
justify-content: center;
}
.master {
&::before{
color: var(--el-color-danger);
content: "*";
margin-right: 4px;
}
}
</style>
...@@ -3,20 +3,16 @@ import { computed,ref,watch } from 'vue' ...@@ -3,20 +3,16 @@ import { computed,ref,watch } from 'vue'
import type { FormInstance } from 'element-plus' import type { FormInstance } from 'element-plus'
import PageWrapperSearch from '@/components/search/PageWrapperSearch.vue' import PageWrapperSearch from '@/components/search/PageWrapperSearch.vue'
import { import {
Check, Plus
Delete,
Edit,
Message,
Search,
Star,
} from '@element-plus/icons-vue' } from '@element-plus/icons-vue'
import { color } from 'echarts'
// import { useDict } from '@/utils/dict' // import { useDict } from '@/utils/dict'
// import { listDept } from '@/api/system/dept'// 部门 // import { listDept } from '@/api/system/dept'// 部门
// const { approve_status, invoice_status} = useDict('approve_status', 'invoice_status') // const { approve_status, invoice_status} = useDict('approve_status', 'invoice_status')
const emit = defineEmits(['update:modelValue', 'query', 'reset']) const emit = defineEmits(['update:modelValue', 'query', 'reset','showAddDialog'])
const invoice_status_filter = ref([]) const invoice_status_filter = ref([])
const employeesList = ref([]) const employeesList = ref([])
const props = defineProps<{ const props = defineProps<{
...@@ -48,12 +44,26 @@ function onReset(formRef: FormInstance) { ...@@ -48,12 +44,26 @@ function onReset(formRef: FormInstance) {
emit('reset', formRef) emit('reset', formRef)
} }
function showAddDialog() {
emit('showAddDialog')
}
</script> </script>
<template> <template>
<!-- el-form --> <!-- el-form -->
<page-wrapper-search <page-wrapper-search
:model="queryForm" :model="queryForm"
:extraButtons="[
{
text: '新增',
icon: Plus,
color: 'rgba(0, 189, 207, 1)',
type: 'success',
textClass: 'btn-fff',
onClick: showAddDialog
}
]"
@search="onSearch" @search="onSearch"
@reset="onReset"> @reset="onReset">
<el-form-item label="项目名称" prop="proName"> <el-form-item label="项目名称" prop="proName">
...@@ -108,6 +118,6 @@ function onReset(formRef: FormInstance) { ...@@ -108,6 +118,6 @@ function onReset(formRef: FormInstance) {
</page-wrapper-search> --> </page-wrapper-search> -->
</template> </template>
<style scoped> <style scoped lang="scss">
</style> </style>
...@@ -415,57 +415,116 @@ onMounted(()=>{ ...@@ -415,57 +415,116 @@ onMounted(()=>{
<template #title> <template #title>
项目管理 项目管理
</template> </template>
<template #buttons>
<el-button
:loading="addLoading"
type="primary"
icon="Plus"
@click="showAddDialog"
>
新增
</el-button>
</template>
</PageTitle> </PageTitle>
<div class="app-container__body"> <div class="app-container__body">
<div> <!-- <div> -->
<query-form <query-form
ref="QueryFormRef" ref="QueryFormRef"
v-model="queryParams" v-model="queryParams"
@query="onQuery" @query="onQuery"
@reset="onReset"/> @reset="onReset"
<el-row :gutter="20" v-loading="loading"> @showAddDialog="showAddDialog"/>
<el-col class="table-item" :span="6" v-for="(item, index) in tableList" :key="index"> <div style="flex: 1;">
<el-card shadow="always"> <el-table
<template #header> height="100%"
<div class="flex-container justify-between align-center"> :data="tableList"
{{ item.project }} v-loading="loading"
<el-dropdown placement="bottom-end" @command="(command) => handleCommandProject(command, item)"> border
<el-button type="primary" icon="Operation"> style="width: 100%; margin-top: 20px"
操作 >
</el-button> <el-table-column
<template #dropdown> type="index"
<el-dropdown-menu> label="序号"
<el-dropdown-item command="1">进入</el-dropdown-item> width="80"
<el-dropdown-item command="2">编辑</el-dropdown-item> align="center"
<el-dropdown-item command="3">删除</el-dropdown-item> fixed
<el-dropdown-item command="4">导入</el-dropdown-item> />
<el-dropdown-item command="5">导出</el-dropdown-item> <el-table-column
<el-dropdown-item command="6">下载插件</el-dropdown-item> prop="project"
</el-dropdown-menu> label="项目名称"
</template> min-width="180"
</el-dropdown> show-overflow-tooltip
</div> />
</template> <el-table-column
label="数据源"
width="100"
align="center"
>
<template #default="{ row }">
{{ row.list && row.list[0] ? row.list[0].value : '-' }}
</template>
</el-table-column>
<el-table-column
label="数据域"
width="100"
align="center"
>
<template #default="{ row }">
{{ row.list && row.list[1] ? row.list[1].value : '-' }}
</template>
</el-table-column>
<el-table-column
label="发现规则"
width="100"
align="center"
>
<template #default="{ row }">
{{ row.list && row.list[2] ? row.list[2].value : '-' }}
</template>
</el-table-column>
<el-table-column
prop="note"
label="项目备注"
min-width="100"
show-overflow-tooltip
/>
<el-table-column
label="操作"
min-width="520"
align="center"
fixed="right"
>
<template #default="{ row }">
<el-button plain color="rgba(0, 186, 173, 1)" size="small" icon="right" @click="handleEnterProject(row)">
进入
</el-button>
<el-button plain color="rgba(11, 136, 251, 1)" size="small" icon="edit" @click="handleEditProject(row)">
编辑
</el-button>
<el-button plain color="rgba(255, 141, 26, 1)" size="small" icon="delete" @click="handleDeleteProject(row)">
删除
</el-button>
<el-button plain color="rgba(121, 72, 234, 1)" size="small" icon="download" @click="handleDownloadPlugin(row)">
下载插件
</el-button>
<el-button plain color="rgba(237, 183, 5, 1)" size="small" icon="documentCopy" @click="handleImportProject(row)">
导入
</el-button>
<el-button plain color="rgba(172, 51, 193, 1)" size="small" icon="copyDocument" @click="handleExportProject(row)">
导出
</el-button>
<div class="item-content flex-container align-center" v-for="(x,y) in item.list">
<div class="label">{{x.label}}:</div> <!-- <el-dropdown placement="bottom-end" @command="(command) => handleCommandProject(command, row)">
<div class="value flex1">{{x.value}}</div>
</div> <template #dropdown>
<el-dropdown-menu>
</el-card> <el-dropdown-item command="1">进入</el-dropdown-item>
</el-col> <el-dropdown-item command="2">编辑</el-dropdown-item>
</el-row> <el-dropdown-item command="3">删除</el-dropdown-item>
<el-dropdown-item command="4">导入</el-dropdown-item>
<el-dropdown-item command="5">导出</el-dropdown-item>
<el-dropdown-item command="6">下载插件</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown> -->
</template>
</el-table-column>
</el-table>
</div>
<pagination <pagination
v-show="total > 0" v-show="total > 0"
...@@ -474,7 +533,7 @@ onMounted(()=>{ ...@@ -474,7 +533,7 @@ onMounted(()=>{
v-model:limit="queryParams.everypage" v-model:limit="queryParams.everypage"
@pagination="getList" @pagination="getList"
/> />
</div> <!-- </div> -->
</div> </div>
<ProjectEditDialog <ProjectEditDialog
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论