Commit c156c399 authored by liang's avatar liang

数据库-字段配置

parent 079f5808
<template>
<div class="widget-config">
<el-form
label-suffix=":"
v-if="this.data && Object.keys(this.data).length > 0"
labelPosition="left"
labelWidth="110px"
size="small"
>
<el-collapse v-model="collapse">
<el-collapse-item name="1" title="基本属性">
<el-form-item label="类型" v-if="data.type && !data.component">
<el-select
v-model="data.type"
style="width: 100%"
placeholder="请选择类型"
@change="handleChangeType"
:disabled="fieldNotEdit"
>
<el-option-group
v-for="group in fields"
:key="group.title"
:label="group.title"
>
<el-option
v-for="item in group.list"
:key="item.type"
:label="item.label"
:value="item.type"
>
</el-option>
</el-option-group>
</el-select>
</el-form-item>
<el-form-item label="属性值">
<el-input
v-model="data.prop"
clearable
placeholder="属性值"
:disabled="fieldNotEdit || propNotEdit"
></el-input>
</el-form-item>
<el-form-item label="标题">
<el-input
v-model="data.label"
clearable
placeholder="标题"
:disabled="
fieldNotEdit && !['group', 'dynamic'].includes(data.type)
"
></el-input>
</el-form-item>
<el-form-item label="宽度" v-if="data.subfield">
<el-input-number
style="width: 100%"
v-model="data.width"
controls-position="right"
placeholder="宽度"
:min="100"
></el-input-number>
</el-form-item>
<el-form-item
label="表单栅格"
v-if="!data.subfield && !['group'].includes(data.type)"
>
<el-input-number
style="width: 100%"
v-model="data.span"
controls-position="right"
placeholder="表单栅格"
:min="8"
:max="24"
></el-input-number>
</el-form-item>
<el-form-item
label="数据类型"
v-if="
[
'cascader',
'checkbox',
'radio',
'select',
'tree',
'upload',
'img',
'array',
'slider',
'timerange',
'daterange',
'datetimerange',
].includes(data.type)
"
>
<template slot="label">
<el-link
:underline="false"
href="https://avuejs.com/doc/dataType"
target="_blank"
>数据类型 <i class="el-icon-question"></i
></el-link>
</template>
<el-select
v-model="data.dataType"
placeholder="数据类型"
clearable
style="width: 100%"
>
<el-option label="String" value="string"></el-option>
<el-option label="Number" value="number"></el-option>
<el-option label="Array" value="array"></el-option>
</el-select>
</el-form-item>
<el-form-item label="深结构" v-if="data.type && !data.component">
<template slot="label">
<el-link
:underline="false"
href="https://avuejs.com/doc/form/form-bind"
target="_blank"
>深结构 <i class="el-icon-question"></i
></el-link>
</template>
<el-input
v-model="data.bind"
clearable
placeholder="深结构"
></el-input>
</el-form-item>
<el-form-item label="字段提示">
<template slot="label">
<el-link
:underline="false"
href="https://avuejs.com/doc/form/form-tip"
target="_blank"
>字段提示 <i class="el-icon-question"></i
></el-link>
</template>
<el-input
v-model="data.tip"
clearable
placeholder="字段提示"
></el-input>
</el-form-item>
<el-form-item
v-if="data.tip && !['upload'].includes(data.type)"
label="字段提示位置"
label-width="110px"
>
<el-select
v-model="data.tipPlacement"
placeholder="字段提示位置"
style="width: 100%"
clearable
>
<el-option label="上" value="top"></el-option>
<el-option label="下" value="bottom"></el-option>
<el-option label="左" value="left"></el-option>
<el-option label="右" value="right"></el-option>
</el-select>
</el-form-item>
<el-form-item label="标题提示">
<template slot="label">
<el-link
:underline="false"
href="https://avuejs.com/doc/form/form-tip"
target="_blank"
>标题提示 <i class="el-icon-question"></i
></el-link>
</template>
<el-input
v-model="data.labelTip"
clearable
placeholder="标题提示"
></el-input>
</el-form-item>
<el-form-item
v-if="data.labelTip && !['upload'].includes(data.type)"
label="标题提示位置"
label-width="110px"
>
<el-select
v-model="data.labelTipPlacement"
placeholder="标题提示位置"
clearable
>
<el-option label="上" value="top"></el-option>
<el-option label="下" value="bottom"></el-option>
<el-option label="左" value="left"></el-option>
<el-option label="右" value="right"></el-option>
</el-select>
</el-form-item>
<component :is="getComponent" :data="data"></component>
</el-collapse-item>
<el-collapse-item
name="2"
title="事件属性"
v-if="!['group', 'dynamic'].includes(data.type)"
>
<el-form-item label="change">
<el-input
v-model="data.change"
type="textarea"
placeholder="改变事件"
rows="5"
clearable
></el-input>
</el-form-item>
<el-form-item label="click">
<el-input
v-model="data.click"
type="textarea"
placeholder="点击事件"
rows="5"
></el-input>
</el-form-item>
<el-form-item label="focus">
<el-input
v-model="data.focus"
type="textarea"
placeholder="获取焦点事件"
rows="5"
></el-input>
</el-form-item>
<el-form-item label="blur">
<el-input
v-model="data.blur"
type="textarea"
placeholder="失去焦点事件"
rows="5"
></el-input>
</el-form-item>
</el-collapse-item>
<slot name="dbtable"></slot>
<el-collapse-item
name="99"
title="其他"
v-if="!['group', 'dynamic', 'title'].includes(data.type)"
>
<dynamic-sh :data="data"></dynamic-sh>
</el-collapse-item>
</el-collapse>
</el-form>
<div>拖拽字段进行配置</div>
</div>
</template>
<script>
import fields from "./fieldsConfig.js"
import DynamicSh from "./components/DynamicSh"
const dateArr = [
"year",
"month",
"week",
"date",
"datetime",
"time",
"daterange",
"timerange",
"datetimerange",
"dates",
]
export default {
name: "widget-config",
components: { DynamicSh },
props: {
data: {
type: Array | Object,
},
fieldNotEdit: {
type: Boolean,
default: false,
},
propNotEdit: {
type: Boolean,
default: false,
},
},
computed: {
getComponent() {
const prefix = "config-"
const { type, component } = this.data
if ((!type || component) && type != "ueditor") return prefix + "custom"
let result = "input"
if ([undefined, "input", "password", "url"].includes(type))
result = "input"
else if (dateArr.includes(type)) result = "date"
else if (["array", "img"].includes(type)) result = "array"
else if (["tree", "cascader"].includes(type)) result = "tree"
else if (["radio", "checkbox", "select"].includes(type)) result = "select"
else result = type
return prefix + result
},
},
data() {
return {
fields,
collapse: "1",
}
},
methods: {
async handleChangeType(type) {
if (type) {
const config = await this.getConfigByType(type)
config.prop = this.data.prop
for (let key in config) {
if (
config &&
Object.prototype.hasOwnProperty.call(config, key) &&
!["icon", "label", "span"].includes(key)
) {
const val = config[key]
this.$set(this.data, key, val)
}
}
}
},
getConfigByType(type) {
return new Promise((resolve, reject) => {
fields.forEach((field) => {
field.list.forEach((config) => {
if (config.type == type) resolve(config)
})
})
reject()
})
},
},
}
</script>
<style lang="scss">
.widget-config {
ul {
margin: 0;
padding: 0;
li {
display: flex;
align-items: center;
width: 100%;
.ghost {
list-style: none;
font-size: 0;
height: 35px;
}
}
}
}
</style>
......@@ -40,9 +40,6 @@
:disabled="propNotEdit"
></el-input>
</el-form-item>
<el-form-item label="数据库">
<el-input :value="data.tableCode" clearable disabled></el-input>
</el-form-item>
<el-form-item label="标题">
<el-input
v-model="data.label"
......
<template>
<div>
<span
v-if="item.type == 'title'"
:style="item.styles"
style="margin-left: 5px"
>
{{ item.value }}
</span>
<component
v-else
:is="getComponent(item.type, item.component)"
v-bind="
Object.assign(deepClone(item), params, { size: item.size || 'small' })
"
:multiple="false"
:placeholder="item.placeholder || getPlaceholder(item)"
:dic="item.dicData"
:value="
['time', 'timerange', 'checkbox'].includes(item.type)
? item.dicData
: undefined
"
>
<span v-if="params.html" v-html="params.html"></span>
</component>
</div>
</template>
<script>
export default {
name: "widget-form-item",
props: {
item: {
type: Object,
default: () => {
return {}
},
},
params: {
type: Object,
default: () => {
return {}
},
},
},
data() {
return {
form: {},
}
},
methods: {
getComponent(type, component) {
let KEY_COMPONENT_NAME = "avue-"
let result = "input"
if (component) return component
else if (["array", "img", "url"].includes(type)) result = "array"
else if (type === "select") result = "select"
else if (type === "radio") result = "radio"
else if (type === "checkbox") result = "checkbox"
else if (["time", "timerange"].includes(type)) result = "time"
else if (
[
"dates",
"date",
"datetime",
"datetimerange",
"daterange",
"week",
"month",
"year",
].includes(type)
)
result = "date"
else if (type === "cascader") result = "cascader"
else if (type === "number") result = "input-number"
else if (type === "password") result = "input"
else if (type === "switch") result = "switch"
else if (type === "rate") result = "rate"
else if (type === "upload") result = "upload"
else if (type === "slider") result = "slider"
else if (type === "dynamic") result = "dynamic"
else if (type === "icon") result = "input-icon"
else if (type === "color") result = "input-color"
else if (type === "map") result = "input-map"
return KEY_COMPONENT_NAME + result
},
getPlaceholder(item) {
const label = item.label
if (
[
"select",
"checkbox",
"radio",
"tree",
"color",
"dates",
"date",
"datetime",
"datetimerange",
"daterange",
"week",
"month",
"year",
"map",
"icon",
].includes(item.type)
)
return `请选择 ${label}`
else return `请输入 ${label}`
},
},
}
</script>
import request from "@/utils/request"
import { add } from "lodash"
/* 数据库管理 */
......@@ -10,6 +11,14 @@ export function getDbPage(params = {}) {
})
}
export function getDbList(params = {}) {
return request({
url: "/cloud-upms/sys/db/info/list",
method: "get",
params,
})
}
export function addDb(data = {}) {
return request({
url: "/cloud-upms/sys/db/info",
......@@ -26,3 +35,21 @@ export function testDb(data = {}) {
data,
})
}
// 根据数据库id 查数据表
export function getTableList(id) {
return request({
url: `/cloud-upms/sys/table/list?dbId=${id}`,
method: "get",
})
}
// 新增数据表
export function addDbTable(data = {}) {
return request({
url: "/cloud-upms/sys/table",
method: "post",
data,
})
}
......@@ -12,6 +12,14 @@ export function getFieldPage(params = {}) {
params,
})
}
export function getFieldList(params = {}) {
return request({
url: "/cloud-upms/field/dict/list/table",
method: "get",
params,
})
}
export function delField(id) {
return request({
url: `/cloud-upms/field/dict/${id}`,
......
......@@ -490,9 +490,6 @@ export default {
text-align: center;
}
}
.el-input-group__prepend {
padding: 0;
}
.input-with-input {
.el-input-group__prepend {
background-color: #ffffff;
......
......@@ -75,13 +75,13 @@ export default {
columns: [
{
label: "数据库名称",
minWidth: 120,
minWidth: 180,
value: "dbName",
},
{
label: "库表前缀",
minWidth: 80,
value: "prefix",
label: "数据源名称",
minWidth: 120,
value: "name",
},
{
......@@ -103,6 +103,12 @@ export default {
return this.$handle.formatDicList(this.dictMap["db_type"], row.type)
},
},
{
label: "库表前缀",
minWidth: 80,
value: "prefix",
},
{
label: "内网url",
minWidth: 120,
......@@ -164,20 +170,11 @@ export default {
rules: [{ required: true, message: "请输入数据库名称" }],
spanCount: 12,
},
{
type: "input",
label: "库表前缀",
placeholder: "请输入库表前缀",
prop: "prefix",
rules: [{ required: true, message: "请输入库表前缀" }],
spanCount: 12,
},
{
type: "input",
label: "数据源名称",
placeholder: "请输入数据源名称",
prop: "dbName",
prop: "name",
rules: [{ required: true, message: "请输入数据源名称" }],
spanCount: 12,
},
......@@ -191,6 +188,15 @@ export default {
},
spanCount: 12,
},
{
type: "input",
label: "库表前缀",
placeholder: "请输入库表前缀",
prop: "prefix",
rules: [{ required: true, message: "请输入库表前缀" }],
spanCount: 12,
},
{
type: "select",
label: "数据源类型",
......
<template>
<div class="container">
<direct-search
ref="form"
:label-position="'right'"
:forms="searchList"
:style="{ textAlign: 'left' }"
@handleSearch="handleFormSearch"
/>
<el-table-self
ref="table"
:table-data="tableData"
:columns="columns"
:list-loading="listLoading"
/>
<el-drawer
:title="widgetFormSelect.id ? '编辑' : '新增'"
:visible.sync="widgetVisible"
:size="500"
:wrapperClosable="false"
>
<div class="drawer__container">
<div class="drawer__content">
<widget-config
:data="widgetFormSelect"
:propNotEdit="propNotEdit"
layout-hidden
>
<template v-slot:dbtable>
<el-collapse-item
name="4"
title="数据库属性与命名标准"
v-if="!['group', 'title'].includes(widgetFormSelect.type)"
>
<el-form-item label="数据类型">
<el-select
v-model="widgetFormSelect.fieldType"
placeholder="字段存储类型"
style="width: 100%"
clearable
>
<el-option
:label="item.label"
:value="item.value"
v-for="item in dictMap['data_type']"
:key="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据宽度">
<el-input
style="width: 100%"
v-model="widgetFormSelect.fieldLength"
:controls="false"
clearable
placeholder="数据宽度"
></el-input>
</el-form-item>
<el-form-item label="数据元标识">
<el-input
v-model="widgetFormSelect.hisElementIdent"
clearable
placeholder="数据元标识"
></el-input>
</el-form-item>
<el-form-item label="数据元值类型">
<el-input
v-model="widgetFormSelect.hisDataType"
clearable
placeholder="数据元值类型"
></el-input>
</el-form-item>
<el-form-item label="表达格式">
<el-input
v-model="widgetFormSelect.hisRepresentFormat"
clearable
placeholder="表达格式"
></el-input>
</el-form-item>
<el-form-item label="允许值">
<el-input
v-model="widgetFormSelect.hisAllowance"
clearable
placeholder="允许值"
></el-input>
</el-form-item>
</el-collapse-item>
</template>
</widget-config>
</div>
<div class="footer">
<el-button @click="widgetVisible = false" size="large"
>取 消</el-button
>
<el-button
size="large"
type="primary"
:loading="loading"
@click="handleConfirm(widgetFormSelect)"
>确 定</el-button
>
</div>
</div>
</el-drawer>
</div>
</template>
<script>
import WidgetConfig from "packages/WidgetConfig.vue"
import { getFieldList, addField, delField } from "@/api/field.js"
// 新增所需字段
const fields = [
"id",
"fieldType",
"label",
"prop",
"fieldLength",
"hisElementIdent",
"hisDataType",
"hisRepresentFormat",
"hisAllowance",
]
// 字段关系映射
const fieldMap = {
label: "fieldName",
prop: "fieldCode",
}
export default {
name: "FieldList",
props: {
tableCode: {},
tableId: {},
dbId: {},
},
components: {
WidgetConfig,
},
data() {
return {
propNotEdit: false,
loading: false,
widgetVisible: false,
widgetFormSelect: {},
listLoading: false,
// 查询列表
searchList: [
{
label: "字段名",
type: "input",
prop: "fieldName",
placeholder: "请输入字段名",
},
{
label: "属性值",
type: "input",
prop: "fieldCode",
placeholder: "请输入属性值",
},
{
type: "button",
value: "查询",
icon: "el-icon-search",
},
{
type: "button",
color: "primary",
icon: "el-icon-plus",
hasForm: true,
value: "添加",
func: this.handleAdd,
},
],
columns: [
{
label: "字段名",
minWidth: 120,
value: "fieldName",
},
{
label: "属性值",
minWidth: 120,
value: "fieldCode",
},
{
label: "数据库存储表名称",
minWidth: 120,
value: "tableName",
},
{
label: "数据库存字段类型",
minWidth: 120,
value: "fieldType",
formatter: (row) => {
return this.$handle.formatDicList(
this.dictMap["data_type"],
row.fieldType
)
},
},
{
label: "数据宽度",
minWidth: 100,
value: "fieldLength",
},
{
label: "操作",
width: 200,
fixed: "right",
operType: "button",
operations: [
{
func: this.handleAdd,
formatter({ isDefault }) {
return {
disabled: isDefault === 1,
label: "编辑",
type: "primary",
}
},
},
{
func: this.handleDel,
formatter({ isDefault }) {
return {
disabled: isDefault === 1,
label: "删除",
type: "warning",
}
},
},
],
},
],
tableData: [],
cacheForm: {},
}
},
watch: {
tableCode(val) {
if (val) {
this.handleFormSearch()
} else {
this.tableData = []
}
},
},
methods: {
handleAdd({ id, jsonStr, tableCode }) {
if (!this.tableCode) {
this.$message.error("未选择数据表")
return
}
const fields = jsonStr ? JSON.parse(jsonStr) : {}
const form = id ? { id, ...fields } : { tableCode, importantField: true }
this.propNotEdit = Boolean(id)
this.widgetFormSelect = Object.assign(
{ type: "input", display: true },
form
)
this.widgetVisible = true
},
handleConfirm(form) {
if (!/^[a-z]+([a-z0-9]*([_]?[a-z]+)*)*$/.test(form.prop)) {
this.$message.error(
"只能包含字母、数字、下划线。必须以字母开始,下划线不可连续重复,下划线后不可紧跟着数字,不能以数字、下划线结束"
)
return
}
const data = {
jsonStr: JSON.stringify(form),
dbId: this.dbId,
tableId: this.tableId,
}
Object.keys(form).forEach((key) => {
if (fields.includes(key)) {
if (fieldMap[key]) {
data[fieldMap[key]] = form[key]
} else {
data[key] = form[key]
}
}
})
const msg = data.id ? "编辑成功" : "新增成功"
this.loading = true
addField(data)
.then((res) => {
if (res.code === 1) {
this.$message.success(msg)
this.handleSearch()
// this.widgetVisible = false
this.loading = false
}
})
.catch((e) => {
this.loading = false
})
},
handleDel(row) {
this.$confirm(`是否删除【${row.fieldName}】?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
delField(row.id).then((res) => {
if (res.code === 1) {
this.$message({
type: "success",
message: "删除成功!",
})
this.handleSearch()
}
})
})
.catch(() => {})
},
// 查询
handleFormSearch(form) {
this.pageIndex = 1
this.handleSearch(form)
},
handleSearch(form) {
this.cacheForm = Object.assign(this.cacheForm, form)
this.listLoading = true
const params = Object.assign(
{
tableCode: this.tableCode,
},
this.cacheForm
)
for (let key in params) {
if (params[key] === "") {
delete params[key]
}
}
getFieldList(params).then((res) => {
this.listLoading = false
this.tableData = res.data || []
})
},
},
}
</script>
<style lang="scss" scoped>
.drawer__container {
padding: 0 20px;
.drawer__content {
height: calc(100vh - #{"160px"});
overflow-y: auto;
::v-deep .el-input-number {
width: 100%;
}
&::-webkit-scrollbar {
width: 0px;
height: 0px;
}
&::-webkit-scrollbar-thumb {
background-color: #fff;
}
}
.footer {
margin-top: 20px;
display: flex;
button {
flex: 1;
}
}
}
</style>
<template>
<div class="container">
<direct-search
ref="form"
:label-position="'right'"
:forms="searchList"
:style="{ textAlign: 'left' }"
@handleSearch="handleFormSearch"
/>
<el-table-self
ref="table"
:table-data="tableData"
:columns="columns"
:list-loading="listLoading"
:current-page="pageIndex"
:total-count="total"
:page-sizes="pageSizes"
:page-size="pageSize"
@pageSizeChange="handleSizeChange"
@currentPageChange="handleCurrentChange"
/>
<el-drawer
:title="widgetFormSelect.id ? '编辑' : '新增'"
:visible.sync="widgetVisible"
:size="500"
:wrapperClosable="false"
>
<div class="drawer__container">
<div class="drawer__content">
<widget-config
:data="widgetFormSelect"
:propNotEdit="propNotEdit"
layout-hidden
>
<template v-slot:dbtable>
<el-collapse-item
name="4"
title="数据库属性与命名标准"
v-if="!['group', 'title'].includes(widgetFormSelect.type)"
>
<el-form-item label="数据库表">
<el-select
v-model="widgetFormSelect.tableCode"
placeholder="数据库表"
style="width: 100%"
<el-row class="page-container dict">
<el-tabs v-model="activeName" @tab-click="handleTabClick">
<el-tab-pane
:label="item.name"
:name="'index' + index"
v-for="(item, index) in dbList"
:key="item.id"
>{{
}}</el-tab-pane>
</el-tabs>
<el-container class="page-main" :gutter="20">
<el-aside width="220px" class="left-content">
<el-col :span="24" class="left-title">
<span>数据库表</span>
<span class="left-add" @click="handleAdd()" title="新增"
><i class="el-icon-circle-plus-outline"></i
></span>
</el-col>
<el-col :span="24" class="left-search">
<el-input
v-model.trim="searchVal"
clearable
:placeholder="placeholder"
>
<el-option
:label="item.label"
:value="item.value"
v-for="item in dictMap['table']"
:key="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据类型">
<el-select
v-model="widgetFormSelect.fieldType"
placeholder="字段存储类型"
style="width: 100%"
clearable
</el-input>
</el-col>
<el-col
class="dict-list"
ref="dict"
style="height: calc(100vh - 280px)"
>
<el-option
:label="item.label"
:value="item.value"
v-for="item in dictMap['data_type']"
:key="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据宽度">
<el-input
style="width: 100%"
v-model="widgetFormSelect.fieldLength"
:controls="false"
clearable
placeholder="数据宽度"
></el-input>
</el-form-item>
<el-form-item label="数据元标识">
<el-input
v-model="widgetFormSelect.hisElementIdent"
clearable
placeholder="数据元标识"
></el-input>
</el-form-item>
<el-form-item label="数据元值类型">
<el-input
v-model="widgetFormSelect.hisDataType"
clearable
placeholder="数据元值类型"
></el-input>
</el-form-item>
<el-form-item label="表达格式">
<el-input
v-model="widgetFormSelect.hisRepresentFormat"
clearable
placeholder="表达格式"
></el-input>
</el-form-item>
<el-form-item label="允许值">
<el-input
v-model="widgetFormSelect.hisAllowance"
clearable
placeholder="允许值"
></el-input>
</el-form-item>
</el-collapse-item>
</template>
</widget-config>
</div>
<div class="footer">
<el-button @click="widgetVisible = false" size="large"
>取 消</el-button
<el-col
v-for="(item, index) in tableData"
:key="item.id"
class="dict-item"
>
<el-button
size="large"
type="primary"
:loading="loading"
@click="handleConfirm(widgetFormSelect)"
>确 定</el-button
<span
@click="handClick(index, item)"
:class="{ active: index == isActive }"
style="cursor: pointer"
>
</div>
</div>
</el-drawer>
</div>
{{ item.name }} | {{ item.code }}
</span>
<span class="item-del">
<i class="el-icon-edit-outline" @click="handleAdd(item)"></i>
</span>
</el-col>
</el-col>
</el-aside>
<el-main>
<FieldList
:table-code="tableCode"
:tableId="tableId"
:dbId="dbId"
></FieldList>
</el-main>
</el-container>
<dialog-form
ref="dialog"
:width="'450px'"
:title="formEdit.id ? '编辑' : '新增'"
:form-data="formData"
:form-edit="formEdit"
@handleConfirm="handleConfirm"
/>
</el-row>
</template>
<script>
import WidgetConfig from "packages/WidgetConfig.vue"
import paginationMixin from "@/components/TabComponents/mixin"
import { getFieldPage, addField, delField } from "@/api/field.js"
// 新增所需字段
const fields = [
"id",
"fieldType",
"label",
"prop",
"tableCode",
"tableName",
"fieldLength",
"hisElementIdent",
"hisDataType",
"hisRepresentFormat",
"hisAllowance",
]
// 字段关系映射
const fieldMap = {
label: "fieldName",
prop: "fieldCode",
}
import { getDbList, getTableList, addDbTable } from "@/api/database"
import FieldList from "./FieldList.vue"
export default {
name: "FieldConfig",
components: {
WidgetConfig,
},
mixins: [paginationMixin],
components: { FieldList },
data() {
return {
propNotEdit: false,
loading: false,
widgetVisible: false,
widgetFormSelect: {},
dbId: null,
activeName: "index0",
dbList: [],
tableList: [],
tableCode: null,
isActive: -1,
tableId: "",
searchVal: "",
placeholder: "请输入关键字",
listLoading: false,
// 查询列表
searchList: [
formEdit: {},
formData: [
{
label: "字段名",
type: "input",
prop: "fieldName",
placeholder: "请输入字段名",
label: "表名称",
prop: "name",
rules: [{ required: true, message: "表名称必填" }],
},
{
label: "数据库存储表",
type: "select",
prop: "tableCode",
optsFormatter: () => {
return this.dictMap && this.dictMap["table"]
},
},
{
type: "button",
value: "查询",
icon: "el-icon-search",
type: "input",
label: "表code",
rules: [{ required: true, message: "表code必填" }],
prop: "code",
slot: "prepend",
unit: "",
},
{
type: "button",
color: "primary",
icon: "el-icon-plus",
hasForm: true,
value: "添加",
func: this.handleAdd,
type: "input",
label: "说明",
prop: "note",
},
],
columns: [
{
label: "字段名",
minWidth: 120,
value: "fieldName",
},
{
label: "属性值",
minWidth: 120,
value: "fieldCode",
},
{
label: "数据库存储表名称",
minWidth: 120,
value: "tableName",
},
{
label: "数据库存字段类型",
minWidth: 120,
value: "fieldType",
formatter: (row) => {
return this.$handle.formatDicList(
this.dictMap["data_type"],
row.fieldType
)
},
},
{
label: "数据宽度",
minWidth: 100,
value: "fieldLength",
},
{
label: "操作",
width: 200,
fixed: "right",
operType: "button",
operations: [
{
func: this.handleAdd,
formatter(row) {
return {
label: "编辑",
type: "primary",
}
},
computed: {
tableData() {
const list = this.tableList.filter(
(_) => !this.searchVal || _.name.includes(this.searchVal)
)
this.isActive = this.getListIdx(list, this.tableId)
return list
},
{
func: this.handleDel,
formatter(row) {
return {
label: "删除",
type: "warning",
}
},
filterTableData() {
return this.tabData.filter(
(_) => !this.cacheForm.name || _.name.includes(this.cacheForm.name)
)
},
],
},
],
tableData: [],
cacheForm: {},
}
},
methods: {
handleAdd({ id, jsonStr, tableCode }) {
const fields = jsonStr ? JSON.parse(jsonStr) : {}
const form = id ? { id, ...fields } : { tableCode, importantField: true }
this.propNotEdit = Boolean(id)
this.widgetFormSelect = Object.assign(
{ type: "input", display: true },
form
)
this.widgetVisible = true
},
handleConfirm(form) {
if (!/^[a-z]+([a-z0-9]*([_]?[a-z]+)*)*$/.test(form.prop)) {
this.$message.error(
"只能包含字母、数字、下划线。必须以字母开始,下划线不可连续重复,下划线后不可紧跟着数字,不能以数字、下划线结束"
)
handleAdd(row = {}) {
if (!this.dbId) {
this.$message.error("未选择数据库")
return
}
form.tableName = this.$handle.formatDicList(
this.dictMap["table"],
form.tableCode
)
const db = this.dbList.find((_) => _.id === this.dbId)
this.formData[1].unit = db.prefix + "_"
this.formEdit = { ...row }
this.$refs.dialog.open()
},
const data = { jsonStr: JSON.stringify(form) }
Object.keys(form).forEach((key) => {
if (fields.includes(key)) {
if (fieldMap[key]) {
data[fieldMap[key]] = form[key]
} else {
data[key] = form[key]
}
}
})
const msg = data.id ? "编辑成功" : "新增成功"
this.loading = true
addField(data)
handleConfirm(form) {
addDbTable({ ...form, dbId: this.dbId })
.then((res) => {
if (res.code === 1) {
this.$message.success(msg)
this.handleSearch()
// this.widgetVisible = false
this.loading = false
}
this.$message.success(res.msg)
this.getTableList()
this.$refs.dialog.close()
})
.catch((e) => {
this.loading = false
.finally(() => {
this.$refs.dialog.loading = false
})
},
handleDel(row) {
this.$confirm(`是否删除【${row.fieldName}】?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
delField(row.id).then((res) => {
if (res.code === 1) {
this.$message({
type: "success",
message: "删除成功!",
})
this.handleSearch()
}
})
handleTabClick({ index }) {
this.dbId = this.dbList[index].id
this.tableCode = null
this.tableId = null
this.getTableList()
},
getTableList() {
if (!this.dbId) return
getTableList(this.dbId).then((res) => {
this.tableList = res.data
})
.catch(() => {})
},
// 查询
handleFormSearch(form) {
this.pageIndex = 1
this.handleSearch(form)
// 点击左侧列表
handClick(index, { code, name, id }) {
this.name = name
this.isActive = index
this.tableCode = code
this.tableId = id
},
handleSearch(form) {
this.cacheForm = Object.assign(this.cacheForm, form)
this.listLoading = true
const params = Object.assign({}, this.cacheForm)
for (let key in params) {
if (params[key] === "") {
delete params[key]
getDbList() {
getDbList().then((res) => {
this.dbList = res.data
if (this.dbList[0]) {
this.dbId = this.dbList[0].id
this.getTableList()
}
})
},
getListIdx(list, id) {
let listIdx = -1
for (var i = 0; i < list.length; i++) {
if (list[i].id === id) {
listIdx = i
break
}
params.current = this.pageIndex
params.size = this.pageSize
getFieldPage(params).then((res) => {
this.listLoading = false
if (res.code === 1) {
const d = res.data
this.tableData = d.records || []
this.total = Number(d.total)
}
})
return listIdx
},
},
created() {
this.handleFormSearch()
mounted() {
this.getDbList()
},
}
</script>
<style lang="scss" scoped>
.drawer__container {
.el-main {
padding: 0 20px;
.drawer__content {
height: calc(100vh - #{"160px"});
overflow-y: auto;
}
::v-deep .el-input-number {
width: 100%;
}
&::-webkit-scrollbar {
width: 0px;
height: 0px;
}
&::-webkit-scrollbar-thumb {
background-color: #fff;
}
}
.footer {
margin-top: 20px;
display: flex;
button {
flex: 1;
}
}
.page-main {
align-items: flex-start;
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment