<template>
|
<ywDialog
|
v-model="dialogIsShow"
|
:headerIcon="dialogHeaderIcon"
|
:title="dialogTitle"
|
width="470"
|
@dlgClosed="closeDialog"
|
@submit="submitFormValue"
|
>
|
<el-form :model="dialogFormValue" ref="dialogFormRef" :rules="dialogFormRules" label-width="96">
|
<el-form-item label="维度ID" prop="dim_id" v-if="!isEditDialog">
|
<el-input v-model="dialogFormValue.dim_id"></el-input>
|
</el-form-item>
|
<el-form-item label="定义" prop="dim_title">
|
<el-input type="textarea" :rows="3" v-model="dialogFormValue.dim_title"></el-input>
|
</el-form-item>
|
<el-form-item label="类型" prop="dim_type">
|
<el-select v-model="dialogFormValue.dim_type">
|
<el-option
|
v-for="item in Object.keys(DimensionTypeMap)"
|
:key="item"
|
:value="item"
|
:label="DimensionTypeMap[item]"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="别名" prop="dim_alias">
|
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-3">
|
<div class="flex items-center gap-2" v-for="(item, index) in editAlias" :key="index">
|
<el-input v-model="item.key" class="w-[60px] flex-0 mb-auto font-bold"></el-input>
|
<TagInput class="flex-auto mt-1" v-model="item.value" />
|
<el-button size="small" type="danger" circle @click="deleteAlias(index)">
|
<el-icon><Delete /></el-icon>
|
</el-button>
|
</div>
|
</div>
|
<el-button size="small" type="primary" @click="addAlias">添加别名</el-button>
|
</div>
|
</el-form-item>
|
<el-form-item label="名称" prop="dim_name">
|
<el-input v-model="dialogFormValue.dim_name"></el-input>
|
</el-form-item>
|
<el-form-item label="主题域" prop="dim_group">
|
<el-tree-select
|
filterable
|
:props="{
|
id: 'group_id',
|
label: 'group_name',
|
children: 'Children',
|
}"
|
v-model="dialogFormValue.dim_group"
|
node-key="group_id"
|
clearable
|
defaultExpandAll
|
:data="listTreeData"
|
placeholder="请选择主题域"
|
check-strictly
|
>
|
</el-tree-select>
|
</el-form-item>
|
<el-form-item label="单位" prop="dim_unit">
|
<el-input v-model="dialogFormValue.dim_unit"></el-input>
|
</el-form-item>
|
<el-form-item label="值列表" prop="dim_value_list">
|
<div class="flex flex-col gap-2 w-full">
|
<el-select v-model="activeValueListType" @change="changeValueListType">
|
<el-option
|
v-for="item in Object.keys(ValueListTypeMap)"
|
:key="item"
|
:value="item"
|
:label="ValueListTypeMap[item]"
|
></el-option>
|
</el-select>
|
|
<!-- <el-input v-model="dialogFormValue.dim_value_list" type="textarea" :rows="3"></el-input> -->
|
<TagInput
|
v-if="activeValueListType === ValueListType.Value"
|
class="flex-auto mt-1"
|
v-model="dialogFormValue.dim_value_list.values"
|
/>
|
<el-input
|
placeholder="请输入SQL语句"
|
v-if="activeValueListType === ValueListType.Sql"
|
v-model="dialogFormValue.dim_value_list.sql.sql"
|
type="textarea"
|
:rows="3"
|
></el-input>
|
<el-select placeholder="请选择数据库" v-if="activeValueListType === ValueListType.Sql" v-model="dialogFormValue.dim_value_list.sql.ds_id">
|
<el-option v-for="item in dataSources" :key="item.id" :label="item.title" :value="item.id"></el-option>
|
</el-select>
|
</div>
|
</el-form-item>
|
</el-form>
|
</ywDialog>
|
</template>
|
|
<script setup lang="ts">
|
import type { FormInstance, FormRules } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
import { storeToRefs } from 'pinia';
|
import { computed, ref, watch } from 'vue';
|
import * as dimensionApi from '/@/api/dimension';
|
import ywDialog from '/@/components/dialog/yw-dialog.vue';
|
import { useUserInfo } from '/@/stores/userInfo';
|
import { formatDate } from '/@/utils/formatTime';
|
import { deepClone } from '/@/utils/other';
|
import TagInput from './TagInput.vue';
|
import { DimensionTypeMap } from './constants';
|
import { getDataSourceList } from '/@/api/dataSource';
|
|
const enum ValueListType {
|
Sql = 'sql',
|
Value = 'value',
|
}
|
|
const activeValueListType = ref(ValueListType.Value);
|
const ValueListTypeMap = {
|
[ValueListType.Sql]: 'SQL查询',
|
[ValueListType.Value]: '值输入',
|
};
|
|
const getEmptyValueList = (type = activeValueListType.value) => {
|
return type === ValueListType.Sql
|
? {
|
sql: {
|
ds_id: '',
|
sql: '',
|
},
|
}
|
: {
|
values: [],
|
};
|
};
|
|
const changeValueListType = (val) => {
|
dialogFormValue.value.dim_value_list = getEmptyValueList(val);
|
};
|
|
const checkIsSql = (valueList) => {
|
return valueList && valueList.hasOwnProperty('sql');
|
};
|
const checkIsEmptyValueList = (valueList) => {
|
if (!checkIsSql(valueList)) {
|
return valueList.values.length === 0;
|
}
|
return valueList.sql.ds_id === '' && valueList.sql.sql === '';
|
};
|
|
const props = defineProps(['item', 'groupId', 'listTreeData', 'tableData', 'dataSources']);
|
const emit = defineEmits(['update', 'insert']);
|
|
const addAlias = () => {
|
editAlias.value.push({
|
key: '',
|
value: [],
|
});
|
};
|
|
const deleteAlias = (index) => {
|
editAlias.value.splice(index, 1);
|
};
|
|
//#region ====================== 增加、修改记录操作, dialog init======================
|
const isEditDialog = ref(false);
|
const dialogTitle = computed(() => {
|
return isEditDialog.value ? '修改维度' : '添加维度';
|
});
|
const dialogHeaderIcon = computed(() => {
|
return isEditDialog.value ? 'ele-Edit' : 'ele-Plus';
|
});
|
const dialogFormValue = ref(null);
|
const dialogIsShow = defineModel({
|
type: Boolean,
|
});
|
const dialogFormRef = ref<FormInstance>(null);
|
|
const dialogFormRules = ref<FormRules>({
|
dim_id: [
|
{ required: true, message: '请输入维度ID', trigger: 'blur' },
|
{
|
validator: (rule, value, callback) => {
|
if (!value) {
|
callback();
|
return;
|
}
|
const existItem = props.tableData.find((item) => item.id === value);
|
if (existItem) {
|
callback(new Error('维度ID已存在'));
|
return;
|
}
|
callback();
|
},
|
trigger: 'blur',
|
},
|
],
|
dim_title: [{ required: true, message: '请输入维度定义', trigger: 'blur' }],
|
dim_type: [{ required: true, message: '请选择维度类型', trigger: 'change' }],
|
dim_name: [{ required: true, message: '请输入维度名称', trigger: 'blur' }],
|
});
|
const editAlias = ref([]);
|
|
const openOperateDialog = (row?) => {
|
if (row) {
|
isEditDialog.value = true;
|
const {
|
id: dim_id,
|
prompt: dim_title,
|
type: dim_type,
|
alias: dim_alias,
|
title: dim_name,
|
group: dim_group,
|
unit: dim_unit,
|
dimValueList: dim_value_list,
|
} = row;
|
dialogFormValue.value = deepClone({
|
dim_id,
|
dim_title,
|
dim_type,
|
dim_alias,
|
dim_name,
|
dim_group,
|
dim_unit,
|
dim_value_list,
|
});
|
} else {
|
isEditDialog.value = false;
|
dialogFormValue.value = {
|
dim_id: null,
|
dim_title: null,
|
dim_type: null,
|
dim_alias: {},
|
dim_name: null,
|
dim_group: props.groupId,
|
dim_unit: null,
|
dim_value_list: null,
|
};
|
}
|
editAlias.value = Object.keys(dialogFormValue.value.dim_alias ?? {}).map((item) => {
|
return {
|
key: item,
|
value: dialogFormValue.value.dim_alias[item],
|
};
|
});
|
dialogFormValue.value.dim_value_list = dialogFormValue.value.dim_value_list ?? getEmptyValueList();
|
activeValueListType.value = checkIsSql(dialogFormValue.value.dim_value_list) ? ValueListType.Sql : ValueListType.Value;
|
console.log("🚀 ~ dialogFormValue.value.dim_value_list:", dialogFormValue.value.dim_value_list)
|
};
|
|
const closeDialog = () => {
|
dialogIsShow.value = false;
|
dialogFormRef.value?.clearValidate();
|
};
|
|
const stores = useUserInfo();
|
const { userInfos } = storeToRefs(stores);
|
|
const checkAlias = () => {
|
for (const item of editAlias.value) {
|
if (!item.key) {
|
ElMessage.error('别名的键不能为空');
|
return false;
|
}
|
}
|
|
const keyCount = editAlias.value.reduce((acc, item) => {
|
acc[item.key] = (acc[item.key] || 0) + 1;
|
return acc;
|
}, {});
|
|
for (const key in keyCount) {
|
if (keyCount[key] > 1) {
|
ElMessage.error(`别名的键 "${key}" 重复出现`);
|
return false;
|
}
|
}
|
return true;
|
};
|
|
const submitFormValue = async () => {
|
const valid = await dialogFormRef.value?.validate().catch(() => {});
|
if (!valid) return;
|
|
if (!checkAlias()) return;
|
dialogFormValue.value.dim_alias = editAlias.value.reduce((acc, item) => {
|
acc[item.key] = item.value;
|
return acc;
|
}, {});
|
|
const sendForm = {
|
...dialogFormValue.value,
|
dim_alias: JSON.stringify(dialogFormValue.value.dim_alias),
|
dim_value_list: checkIsEmptyValueList(dialogFormValue.value.dim_value_list)
|
? null
|
: JSON.stringify(dialogFormValue.value.dim_value_list),
|
};
|
|
if (isEditDialog.value) {
|
const res = await dimensionApi.updateDimensionByPost(sendForm);
|
emit('update', {
|
id: dialogFormValue.value.dim_id,
|
prompt: dialogFormValue.value.dim_title,
|
type: dialogFormValue.value.dim_type,
|
alias: dialogFormValue.value.dim_alias,
|
title: dialogFormValue.value.dim_name,
|
group: dialogFormValue.value.dim_group,
|
unit: dialogFormValue.value.dim_unit,
|
dimValueList: dialogFormValue.value.dim_value_list,
|
});
|
closeDialog();
|
ElMessage.success('修改维度成功');
|
} else {
|
const res = await dimensionApi.addDimensionByPost(sendForm);
|
const newData = {
|
id: dialogFormValue.value.dim_id,
|
prompt: dialogFormValue.value.dim_title,
|
type: dialogFormValue.value.dim_type,
|
alias: dialogFormValue.value.dim_alias,
|
title: dialogFormValue.value.dim_name,
|
group: dialogFormValue.value.dim_group,
|
unit: dialogFormValue.value.dim_unit,
|
dimValueList: dialogFormValue.value.dim_value_list,
|
};
|
emit('insert', newData);
|
closeDialog();
|
ElMessage.success('添加维度成功');
|
}
|
};
|
|
//#endregion
|
|
watch(
|
() => dialogIsShow.value,
|
(val) => {
|
if (!val) return;
|
openOperateDialog(props.item);
|
}
|
);
|
</script>
|
|
<style scoped lang="scss"></style>
|