123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- <!--
- * @Author: your name
- * @Date: 2024-10-28 17:43:21
- * @LastEditTime: 2025-01-03 12:35:03
- * @LastEditors: milo-MBP
- * @Description: In User Settings Edit
- * @FilePath: /performance-test/src/views/performance/components/custonAsCom/DatabaseTable.vue
- -->
- <template>
- <div class="databaseContent">
- <template v-if="dialogVisible">
- <el-dialog
- title="连接服务器"
- :visible.sync="dialogVisible"
- width="550px"
- :before-close="handleClose"
- >
- <el-form
- label-position="right"
- label-width="120px"
- :model="formLabelAlign"
- :rules="rules"
- ref="ruleForm"
- size="small"
- >
- <el-form-item label="主机名IP地址:" prop="IP">
- <el-input v-model="formLabelAlign.IP"></el-input>
- </el-form-item>
- <el-form-item label="端口:" prop="host">
- <el-input v-model="formLabelAlign.host"></el-input>
- </el-form-item>
- <el-form-item label="数据库名称:" prop="baseName">
- <el-input v-model="formLabelAlign.baseName"></el-input>
- </el-form-item>
- <el-form-item label="用户名:" prop="username">
- <el-input v-model="formLabelAlign.username"></el-input>
- </el-form-item>
- <el-form-item label="密码:" prop="password">
- <el-input
- type="password"
- v-model="formLabelAlign.password"
- show-password
- ></el-input>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="submitForm('ruleForm')">
- 访问
- </el-button>
- </el-form-item>
- </el-form>
- </el-dialog>
- </template>
- <template v-if="showDialog">
- <el-dialog
- title="数据库导航器"
- :visible.sync="showDialog"
- width="550px"
- :before-close="handleClose"
- >
- <el-input
- placeholder="输入关键字进行过滤"
- v-model="filterText"
- ></el-input>
- <el-tree
- class="filter-tree"
- :data="treeData"
- show-checkbox
- :props="defaultProps"
- :check-strictly="false"
- :filter-node-method="filterNode"
- ref="tree"
- >
- <!-- :check-strictly="false"
- :render-content="renderContent" -->
- </el-tree>
- <el-row type="flex" class="row-bg" justify="space-between">
- <el-col :span="4">
- <el-button size="small" @click="handleClose">取消</el-button>
- </el-col>
- <el-col :span="4">
- <el-button size="small" type="primary" @click="loadData"
- >加载</el-button
- >
- </el-col>
- </el-row>
- </el-dialog>
- </template>
- </div>
- </template>
- <script>
- import axios from "axios";
- import { storeSetData, initDatabase } from "@/utils/indexedDb";
- import { mapMutations, mapState } from "vuex";
- import { format } from "date-fns";
- export default {
- props: {
- dialogVisible: {
- type: Boolean,
- default: false,
- },
- },
- data() {
- return {
- showDialog: false,
- formLabelAlign: {
- IP: "",
- host: "",
- baseName: "",
- username: "",
- password: "",
- },
- rules: {
- IP: { required: true, message: "请输入主机名/IP地址", trigger: "blur" },
- host: {
- required: true,
- message: "请输入端口",
- trigger: "blur",
- },
- baseName: {
- required: true,
- message: "请输入数据库名称",
- trigger: "blur",
- },
- username: { required: true, message: "请输入用户名", trigger: "blur" },
- password: { required: true, message: "请输入密码", trigger: "blur" },
- },
- defaultProps: {
- children: "children",
- label: "label",
- },
- // 转换后的树数据
- treeData: [],
- filterText: "", // 初始化 filterText
- data: [],
- };
- },
- computed: {
- ...mapState("dragChart", {
- updateTriggerGetData: "updateTriggerGetData",
- triggerGetData: "triggerGetData",
- }),
- },
- watch: {
- filterText(val) {
- this.$refs.tree.filter(val);
- },
- },
- methods: {
- ...mapMutations("dragChart", [
- "setTriggerGetData",
- "setUpdateTriggerGetData",
- ]),
- handleClose(done) {
- this.$confirm("确认关闭?")
- .then((_) => {
- !this.showDialog
- ? this.$emit("closeDialog")
- : (this.showDialog = false);
- })
- .catch((_) => {});
- },
- // 将原始数据转化为树形数据
- initializeTreeData(data) {
- // 构建树结构
- this.treeData = Object.keys(data).map((tableName) => ({
- label: tableName,
- children: data[tableName].map((field) => ({
- label: field,
- field: field,
- parentNode: tableName,
- })),
- }));
- },
- // 节点过滤方法
- filterNode(value, data) {
- if (!value) return true; // 如果没有输入过滤文本,则显示所有节点
- return data.label.indexOf(value) !== -1; // 如果节点的label包含过滤文本,则返回true
- },
- // 加载按钮的点击事件
- async loadData() {
- const selectedNodes = this.$refs.tree.getCheckedNodes();
- if (selectedNodes.length <= 0) {
- this.$message.warning("请最少选择1表数据");
- return;
- }
- const output = [];
- // 使用 Map 分组数据
- const grouped = new Map();
- selectedNodes.forEach((item) => {
- const { parentNode, label } = item;
- if (!grouped.has(parentNode)) {
- grouped.set(parentNode, []);
- }
- grouped.get(parentNode).push(label);
- });
- // 转换为目标结构
- grouped.forEach((checkChildNode, parentNode) => {
- output.push({ parentNode, checkChildNode });
- });
- const response = await axios.post(
- "/databaseApi/databaseApi/filterTablesData",
- {
- database: { ...this.formLabelAlign },
- filterData: output,
- }
- );
- this.conversionData(response.data);
- },
- submitForm(formName) {
- this.$refs[formName].validate(async (valid) => {
- if (valid) {
- try {
- const response = await axios.get(
- "/databaseApi/databaseApi/tables",
- {
- params: { ...this.formLabelAlign },
- }
- );
- // this.tableFieldMap = response.data;
- this.initializeTreeData(response.data);
- this.$emit("closeDialog");
- this.showDialog = true;
- } catch (error) {
- this.$message.error(
- "数据库连接失败,请查看填写的数据库数据是否有误" + error
- );
- console.error("Failed to fetch database structure:", error);
- }
- } else {
- return false;
- }
- });
- },
- async conversionData(data) {
- try {
- // 定义最终结果数组
- const result = Object.keys(data)
- .filter((key) => data[key].length > 0) // 过滤掉空数组的字段
- .map((key) => ({
- fileData: data[key],
- fileId: `${new Date().getTime()}_${key}`, // 添加唯一时间戳和字段标识
- fileOldName: `${key}.xlsx`, // 文件原始名称
- filename: `${format(new Date(), "yyyyMMdd-HH:mm:ss")}_${key}.xlsx`, // 包含时间戳的文件名
- }));
- // 初始化数据库
- const database = await initDatabase();
- // 遍历结果并存储数据
- for (const item of result) {
- await storeSetData(database, "files", "fileDataArray", item, () => {
- this.$message({
- type: "success",
- message: `关联完成,关联表可在数据表格中查看。`,
- });
- });
- }
- // 更新状态和关闭对话框
- //更新数据表格数据和自定义图表树形列表
- this.setTriggerGetData(true);
- this.setUpdateTriggerGetData(true);
- this.showDialog = false;
- // 重置表单
- this.formLabelAlign = {
- IP: "",
- host: "",
- baseName: "",
- username: "",
- password: "",
- };
- } catch (error) {
- console.error("操作失败:", error);
- this.$message({
- type: "error",
- message: "操作失败,详情请查看控制台。",
- });
- }
- },
- },
- };
- </script>
- <style scoped lang="scss">
- ::v-deep .el-form-item--small.el-form-item {
- margin-bottom: 18px;
- }
- .row-bg {
- margin-top: 30px;
- }
- .el-tree {
- height: 350px;
- overflow: scroll;
- }
- </style>
|