Commit d13791ea by yuwei

2.0.0项目初始化

parent dc41b1a8
# 数据源配置
spring:
mail:
host: smtp.qq.com
username: 312075478@qq.com
password: ohxmhfsefapibjee
protocol: smtp
default-encoding: utf-8
properties.mail.smtp.auth: true
properties.mail.smtp.port: 465
properties.mail.display.sendmail: 312075478@qq.com
properties.mail.display.sendname: 测试
properties.mail.smtp.starttls.enable: true
properties.mail.smtp.starttls.required: true
properties.mail.smtp.ssl.enable: true
from: 测试1
datasource:
dynamic:
type: com.zaxxer.hikari.HikariDataSource
......
......@@ -64,8 +64,8 @@ public class DataApiDto implements Serializable {
private List<ReqParam> reqParams;
@ApiModelProperty(value = "返回参数")
@Valid
@NotEmpty(message = "返回参数不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
@Size(min = 1, message="返回参数长度不能少于{min}位")
@NotEmpty(message = "返回字段不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
@Size(min = 1, message="返回字段长度不能少于{min}位")
private List<ResParam> resParams;
@ApiModelProperty(value = "状态")
@NotNull(message = "状态不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
......
......@@ -87,7 +87,7 @@ public class DataApiEntity extends DataScopeBaseEntity {
private List<ReqParam> reqParams;
/**
* 返回参数
* 返回字段
*/
@TableField(value = "res_json", typeHandler = JacksonTypeHandler.class)
private List<ResParam> resParams;
......
......@@ -173,7 +173,7 @@ public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntit
List<ReqParam> reqParams = variables.stream().map(s -> {
ReqParam reqParam = new ReqParam();
reqParam.setParamName(s);
reqParam.setNullable(DataConstant.TrueOrFalse.TRUE.getKey());
reqParam.setNullable(DataConstant.TrueOrFalse.FALSE.getKey());
return reqParam;
}).collect(Collectors.toList());
sqlParseVo.setReqParams(reqParams);
......
......@@ -5,44 +5,18 @@ import cn.datax.service.email.service.EmailService;
import cn.datax.service.email.utils.EmailUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeUtility;
import java.io.UnsupportedEncodingException;
@Slf4j
@Service
public class EmailServiceImpl implements EmailService {
@Value("${spring.mail.from}")
private String fromNick;
@Value("${spring.mail.username}")
private String fromAddress;
@Autowired
private JavaMailSender mailSender;
private EmailUtil emailUtil;
@Override
public void sendEmail(EmailEntity emailEntity) {
log.info("实体类 {}", emailEntity);
InternetAddress from = null;
String alias = null;
try {
alias = MimeUtility.encodeText(fromNick);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
from = new InternetAddress(alias + " <" + fromAddress + ">");
} catch (AddressException e) {
e.printStackTrace();
}
EmailUtil emailUtil = new EmailUtil(from, mailSender);
try {
emailUtil.sendEmail(emailEntity);
} catch (Exception e) {
......
......@@ -2,27 +2,47 @@ package cn.datax.service.email.utils;
import cn.datax.service.email.api.entity.EmailEntity;
import cn.hutool.core.collection.CollUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.List;
@Component
public class EmailUtil {
private InternetAddress from;
private JavaMailSender mailSender;
@Value("${spring.mail.from}")
private String fromNick;
public EmailUtil(InternetAddress from, JavaMailSender mailSender) {
this.from = from;
this.mailSender = mailSender;
}
@Value("${spring.mail.username}")
private String fromAddress;
@Autowired
private JavaMailSender mailSender;
public void sendEmail(EmailEntity mailEntity) throws Exception {
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
InternetAddress from = null;
String alias = null;
try {
alias = MimeUtility.encodeText(fromNick);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
from = new InternetAddress(alias + " <" + fromAddress + ">");
} catch (AddressException e) {
e.printStackTrace();
}
helper.setFrom(from);
helper.setSubject(mailEntity.getSubject());
helper.setText(mailEntity.getText(),true);
......@@ -45,5 +65,4 @@ public class EmailUtil {
}
mailSender.send(mimeMessage);
}
}
......@@ -10,31 +10,45 @@
</div>
<div :style="classCardbody">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="数据源" prop="sourceId">
<el-select v-model="form.sourceId" placeholder="请选择数据源">
<el-form-item label="数据API" prop="apiId">
<el-select v-model="form.apiId" placeholder="请选择数据API" @change="apiSelectChanged">
<el-option
v-for="source in sourceOptions"
:key="source.id"
:label="source.sourceName"
:value="source.id"
:disabled="source.status === '0'"
v-for="api in apiOptions"
:key="api.id"
:label="api.apiName"
:value="api.id"
:disabled="api.status === '0'"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据集名称" prop="setName">
<el-input v-model="form.setName" placeholder="请输入数据集名称" />
<el-form-item label="脱敏名称" prop="maskName">
<el-input v-model="form.maskName" placeholder="请输入脱敏名称" />
</el-form-item>
<el-form-item label="数据集sql" prop="setSql">
<sql-editor
ref="sqleditor"
:value="form.setSql"
@changeTextarea="changeTextarea($event)"
style="height: 300px;"
></sql-editor>
</el-form-item>
<el-form-item>
<el-button size="mini" type="primary" @click="formaterSql">Sql格式化</el-button>
<el-button size="mini" type="primary" @click="dataPreview">预览</el-button>
<el-form-item label="脱敏字段规则配置" prop="rules">
<el-table :data="resParamList" stripe border
:max-height="300"
style="width: 100%; margin: 15px 0;">
<el-table-column label="序号" width="55" align="center">
<template slot-scope="scope">
<span>{{ scope.$index +1 }}</span>
</template>
</el-table-column>
<el-table-column prop="fieldName" label="字段名称" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-button type="text" @click="fieldRule(scope.row.fieldName)">{{scope.row.fieldName}}</el-button>
</template>
</el-table-column>
<el-table-column prop="remark" label="描述" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="dataType" label="数据类型" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="exampleValue" label="示例值" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="cipherType" label="脱敏类型" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="cryptType" label="规则类型" align="center" show-overflow-tooltip >
</el-table-column>
</el-table>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
......@@ -49,54 +63,50 @@
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<!-- 脱敏规则对话框 -->
<el-dialog :title="cipher.title" :visible.sync="cipher.open" width="400px" append-to-body>
<el-form ref="form2" :model="form2" :rules="rules2" label-width="80px">
<el-form-item label="字段名称" prop="fieldName">
<el-input v-model="form2.fieldName" placeholder="请输入字段名称" :disabled="true"/>
</el-form-item>
<el-form-item label="脱敏类型" prop="cipherType">
<el-select v-model="form2.cipherType" clearable placeholder="请选择脱敏类型" @change="cipherTypeSelectChanged">
<el-option
v-for="dict in cipherTypeOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="规则类型" prop="cryptType">
<el-select v-model="form2.cryptType" clearable placeholder="请选择规则类型">
<el-option
v-for="dict in cryptTypeOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
></el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFieldCipherForm">确 定</el-button>
<el-button @click="cipher.open = false">取 消</el-button>
</div>
</el-dialog>
</div>
<el-drawer
:visible.sync="drawer"
direction="btt"
:with-header="false">
<el-table :data="previewData.dataList" stripe border
:max-height="200"
style="width: 100%; margin: 15px 0;">
<el-table-column label="序号" width="55" align="center">
<template slot-scope="scope">
<span>{{ scope.$index + 1 }}</span>
</template>
</el-table-column>
<template v-for="(column, index) in previewData.columnList">
<el-table-column
:prop="column"
:label="column"
:key="index"
align="center"
show-overflow-tooltip
/>
</template>
</el-table>
<el-pagination
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="previewData.pageNum"
:page-size.sync="previewData.pageSize"
:total="previewData.dataTotal"
></el-pagination>
</el-drawer>
</el-card>
</div>
</template>
<script>
import { addDataSet } from '@/api/factory/dataset'
import { listDataSource, queryByPage } from '@/api/factory/datasource'
import sqlFormatter from 'sql-formatter'
import SqlEditor from '@/components/SqlEditor'
import { addApiMask } from '@/api/market/apimask'
import { listDataApi } from '@/api/market/dataapi'
export default {
name: 'ApiMaskAdd',
components: {
SqlEditor
},
props: {
data: {
type: Object,
......@@ -128,27 +138,50 @@ export default {
},
// 表单参数
form: {
id: undefined,
apiId: undefined,
maskName: undefined,
rules: [],
status: '1',
sourceId: undefined,
setSql: undefined
remark: undefined
},
// 表单校验
rules: {
setName: [
{ required: true, message: '数据集名称不能为空', trigger: 'blur' }
apiId: [
{ required: true, message: '数据API不能为空', trigger: 'blur' }
],
maskName: [
{ required: true, message: '脱敏名称不能为空', trigger: 'blur' }
]
},
form2: {
fieldName: undefined,
cipherType: undefined,
cryptType: undefined
},
rules2: {
fieldName: [
{ required: true, message: '字段名称不能为空', trigger: 'blur' }
]
},
// 状态数据字典
statusOptions: [],
// 数据源数据字典
sourceOptions: [],
drawer: false,
previewData: {
dataList: [],
columnList: [],
pageNum: 1,
pageSize: 20,
dataTotal: 0
// 数据API数据字典
apiOptions: [],
// 脱敏字段信息
resParamList: [],
// 脱敏类型数据字典
cipherTypeOptions: [],
cryptTypeOptions: [],
// 正则替换数据字典
regexCryptoOptions: [],
// 加密算法数据字典
algorithmCryptoOptions: [],
cipher: {
// 是否显示弹出层
open: false,
// 弹出层标题
title: "脱敏规则配置"
}
}
},
......@@ -158,73 +191,93 @@ export default {
this.statusOptions = response.data
}
})
this.getDataSourceList()
this.getDataApiList()
this.getDicts('data_cipher_type').then(response => {
if (response.success) {
this.cipherTypeOptions = response.data
}
})
this.getDicts('data_regex_crypto').then(response => {
if (response.success) {
this.regexCryptoOptions = response.data
}
})
this.getDicts('data_algorithm_crypto').then(response => {
if (response.success) {
this.algorithmCryptoOptions = response.data
}
})
},
methods: {
showCard () {
this.$emit('showCard', this.showOptions)
},
getDataSourceList () {
listDataSource().then(response => {
getDataApiList () {
listDataApi().then(response => {
if (response.success) {
this.sourceOptions = response.data
this.apiOptions = response.data
}
})
},
// 绑定编辑器value值的变化
changeTextarea (val) {
this.$set(this.form, 'setSql', val)
apiSelectChanged (val) {
this.resParamList = this.apiOptions.filter(item => item.id === val).map(function (item) {
return item.resParams
})
},
fieldRule (fieldName) {
this.cipher.open = true
this.form2.fieldName = fieldName
this.form2.cipherType = undefined
this.form2.cryptType = undefined
this.cryptTypeOptions = []
},
formaterSql () {
if (!this.form.setSql) {
return
cipherTypeSelectChanged (val) {
this.form2.cryptType = undefined
this.cryptTypeOptions = []
if (val === '1') {
// 正则替换
this.cryptTypeOptions = this.regexCryptoOptions
} else if (val === '2') {
// 加密算法
this.cryptTypeOptions = this.algorithmCryptoOptions
}
this.$refs.sqleditor.editor.setValue(sqlFormatter.format(this.$refs.sqleditor.editor.getValue()))
},
dataPreview () {
if (!this.form.sourceId) {
return
submitFieldCipherForm () {
let fieldRuleIndex = this.form.rules.findIndex((item) => {
return item.fieldName === this.form2.fieldName
})
if (fieldRuleIndex != -1) {
// 当返回-1时,则说明数组中没有
this.form.rules.splice(fieldRuleIndex, 1)
}
if (!this.form.setSql) {
return
if (this.form2.cipherType && this.form2.cryptType) {
this.form.rules.push(this.form2)
}
let data = {}
data.dataSourceId = this.form.sourceId
data.sql = this.form.setSql
data.pageNum = this.previewData.pageNum
data.pageSize = this.previewData.pageSize
queryByPage(data).then(response => {
if (response.success) {
const { data } = response
let dataList = data.data || []
let columnList = []
if (dataList.length > 0) {
columnList = Object.keys(dataList[0])
}
this.previewData.dataList = dataList
this.previewData.columnList = columnList
this.previewData.dataTotal = data.total
this.drawer = true
}
let cipher = this.cipherTypeOptions.find((item) => {
return item.itemText === this.form2.cipherType
})
},
handleSizeChange (val) {
this.previewData.pageNum = 1
this.previewData.pageSize = val
this.dataPreview()
},
handleCurrentChange (val) {
this.previewData.pageNum = val
this.dataPreview()
let crypt = this.cryptTypeOptions.find((item) => {
return item.itemText === this.form2.cryptType
})
let fieldParamIndex = this.resParamList.findIndex((item) => {
return item.fieldName === this.form2.fieldName
})
let resParam = Object.assign({}, this.resParamList[fieldParamIndex], { cipherType: (cipher && cipher.itemValue) || undefined, cryptType: (crypt && crypt.itemValue) || undefined })
this.$set(this.resParamList, fieldParamIndex, resParam)
this.cipher.open = false
},
/** 提交按钮 */
submitForm: function () {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.rules.length <= 0) {
this.$message.error('脱敏字段规则配置不能为空')
return
}
this.loadingOptions.loading = true
this.loadingOptions.loadingText = '保存中...'
this.loadingOptions.isDisabled = true
addDataSet(this.form).then(response => {
addApiMask(this.form).then(response => {
if (response.success) {
this.$message.success('保存成功')
setTimeout(() => {
......
......@@ -4,33 +4,47 @@
<div slot="header" class="clearfix">
<span>{{ title }}</span>
<el-button-group style="float: right;">
<el-button size="mini" icon="el-icon-s-data" round @click="dataPreview">数据预览</el-button>
<el-button size="mini" icon="el-icon-back" round @click="showCard">返回</el-button>
</el-button-group>
</div>
<div :style="classCardbody">
<el-form ref="form" :model="form" label-width="80px" disabled>
<el-form-item label="数据源" prop="sourceId">
<el-select v-model="form.sourceId" placeholder="请选择数据源">
<el-form ref="form" :model="form" :rules="rules" label-width="80px" disabled>
<el-form-item label="数据API" prop="apiId">
<el-select v-model="form.apiId" placeholder="请选择数据API">
<el-option
v-for="source in sourceOptions"
:key="source.id"
:label="source.sourceName"
:value="source.id"
:disabled="source.status === '0'"
v-for="api in apiOptions"
:key="api.id"
:label="api.apiName"
:value="api.id"
:disabled="api.status === '0'"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据集名称" prop="setName">
<el-input v-model="form.setName" placeholder="请输入数据集名称" />
<el-form-item label="脱敏名称" prop="maskName">
<el-input v-model="form.maskName" placeholder="请输入脱敏名称" />
</el-form-item>
<el-form-item label="数据集sql" prop="setSql">
<sql-editor
ref="sqleditor"
:value="form.setSql"
:readOnly="true"
style="height: 300px;"
></sql-editor>
<el-form-item label="脱敏字段规则配置" prop="rules">
<el-table :data="resParamList" stripe border
:max-height="300"
style="width: 100%; margin: 15px 0;">
<el-table-column label="序号" width="55" align="center">
<template slot-scope="scope">
<span>{{ scope.$index +1 }}</span>
</template>
</el-table-column>
<el-table-column prop="fieldName" label="字段名称" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="remark" label="描述" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="dataType" label="数据类型" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="exampleValue" label="示例值" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="cipherType" label="脱敏类型" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="cryptType" label="规则类型" align="center" show-overflow-tooltip >
</el-table-column>
</el-table>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
......@@ -45,53 +59,17 @@
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<el-drawer
:visible.sync="drawer"
direction="btt"
:with-header="false">
<el-table :data="previewData.dataList" stripe border
:max-height="200"
style="width: 100%; margin: 15px 0;">
<el-table-column label="序号" width="55" align="center">
<template slot-scope="scope">
<span>{{ scope.$index + 1 }}</span>
</template>
</el-table-column>
<template v-for="(column, index) in previewData.columnList">
<el-table-column
:prop="column"
:label="column"
:key="index"
align="center"
show-overflow-tooltip
/>
</template>
</el-table>
<el-pagination
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="previewData.pageNum"
:page-size.sync="previewData.pageSize"
:total="previewData.dataTotal"
></el-pagination>
</el-drawer>
</div>
</el-card>
</div>
</template>
<script>
import { getDataSet } from '@/api/factory/dataset'
import { listDataSource, queryByPage } from '@/api/factory/datasource'
import SqlEditor from '@/components/SqlEditor'
import { getApiMask } from '@/api/market/apimask'
import { listDataApi } from '@/api/market/dataapi'
export default {
name: 'ApiMaskDetail',
components: {
SqlEditor
},
props: {
data: {
type: Object,
......@@ -116,19 +94,26 @@ export default {
showDetail: false
},
// 表单参数
form: {},
form: {
id: undefined,
apiId: undefined,
maskName: undefined,
rules: [],
status: '1',
remark: undefined
},
// 状态数据字典
statusOptions: [],
// 数据数据字典
sourceOptions: [],
drawer: false,
previewData: {
dataList: [],
columnList: [],
pageNum: 1,
pageSize: 20,
dataTotal: 0
}
// 数据API数据字典
apiOptions: [],
// 脱敏字段信息
resParamList: [],
// 脱敏类型数据字典
cipherTypeOptions: [],
// 正则替换数据字典
regexCryptoOptions: [],
// 加密算法数据字典
algorithmCryptoOptions: []
}
},
created () {
......@@ -138,64 +123,60 @@ export default {
this.statusOptions = response.data
}
})
this.getDataSourceList()
this.getDataSet(this.data.id)
this.getDataApiList()
this.getDicts('data_cipher_type').then(response => {
if (response.success) {
this.cipherTypeOptions = response.data
}
})
this.getDicts('data_regex_crypto').then(response => {
if (response.success) {
this.regexCryptoOptions = response.data
}
})
this.getDicts('data_algorithm_crypto').then(response => {
if (response.success) {
this.algorithmCryptoOptions = response.data
}
})
this.getApiMask(this.data.id)
},
methods: {
showCard () {
this.$emit('showCard', this.showOptions)
},
getDataSourceList () {
listDataSource().then(response => {
getDataApiList () {
listDataApi().then(response => {
if (response.success) {
this.sourceOptions = response.data
this.apiOptions = response.data
}
})
},
/** 获取详情 */
getDataSet: function (id) {
getDataSet(id).then(response => {
getApiMask: function (id) {
getApiMask(id).then(response => {
if (response.success) {
this.form = response.data
this.$refs.sqleditor.editor.setValue(this.form.setSql)
}
})
},
dataPreview () {
if (!this.form.sourceId) {
return
}
if (!this.form.setSql) {
return
}
let data = {}
data.dataSourceId = this.form.sourceId
data.sql = this.form.setSql
data.pageNum = this.previewData.pageNum
data.pageSize = this.previewData.pageSize
queryByPage(data).then(response => {
if (response.success) {
const { data } = response
let dataList = data.data || []
let columnList = []
if (dataList.length > 0) {
columnList = Object.keys(dataList[0])
}
this.previewData.dataList = dataList
this.previewData.columnList = columnList
this.previewData.dataTotal = data.total
this.drawer = true
this.resParamList = this.apiOptions.filter(item => item.id === this.form.apiId).map(function (item) {
return item.resParams
})
this.form.rules.forEach(rule => {
let fieldParamIndex = this.resParamList.findIndex((param) => {
return param.fieldName === rule.fieldName
})
if (fieldParamIndex != -1) {
let cipher = this.cipherTypeOptions.find((item) => {
return item.itemText === rule.cipherType
})
let crypt = this.cryptTypeOptions.find((item) => {
return item.itemText === rule.cryptType
})
let resParam = Object.assign({}, this.resParamList[fieldParamIndex], { cipherType: (cipher && cipher.itemValue) || undefined, cryptType: (crypt && crypt.itemValue) || undefined })
this.$set(this.resParamList, fieldParamIndex, resParam)
}
})
}
})
},
handleSizeChange (val) {
this.previewData.pageNum = 1
this.previewData.pageSize = val
this.dataPreview()
},
handleCurrentChange (val) {
this.previewData.pageNum = val
this.dataPreview()
}
}
}
......
......@@ -10,31 +10,45 @@
</div>
<div :style="classCardbody">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="数据源" prop="sourceId">
<el-select v-model="form.sourceId" placeholder="请选择数据源">
<el-form-item label="数据API" prop="apiId">
<el-select v-model="form.apiId" placeholder="请选择数据API" @change="apiSelectChanged">
<el-option
v-for="source in sourceOptions"
:key="source.id"
:label="source.sourceName"
:value="source.id"
:disabled="source.status === '0'"
v-for="api in apiOptions"
:key="api.id"
:label="api.apiName"
:value="api.id"
:disabled="api.status === '0'"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据集名称" prop="setName">
<el-input v-model="form.setName" placeholder="请输入数据集名称" />
<el-form-item label="脱敏名称" prop="maskName">
<el-input v-model="form.maskName" placeholder="请输入脱敏名称" />
</el-form-item>
<el-form-item label="数据集sql" prop="setSql">
<sql-editor
ref="sqleditor"
:value="form.setSql"
@changeTextarea="changeTextarea($event)"
style="height: 300px;"
></sql-editor>
</el-form-item>
<el-form-item>
<el-button size="mini" type="primary" @click="formaterSql">Sql格式化</el-button>
<el-button size="mini" type="primary" @click="dataPreview">预览</el-button>
<el-form-item label="脱敏字段规则配置" prop="rules">
<el-table :data="resParamList" stripe border
:max-height="300"
style="width: 100%; margin: 15px 0;">
<el-table-column label="序号" width="55" align="center">
<template slot-scope="scope">
<span>{{ scope.$index +1 }}</span>
</template>
</el-table-column>
<el-table-column prop="fieldName" label="字段名称" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-button type="text" @click="fieldRule(scope.row.fieldName)">{{scope.row.fieldName}}</el-button>
</template>
</el-table-column>
<el-table-column prop="remark" label="描述" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="dataType" label="数据类型" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="exampleValue" label="示例值" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="cipherType" label="脱敏类型" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="cryptType" label="规则类型" align="center" show-overflow-tooltip >
</el-table-column>
</el-table>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
......@@ -49,54 +63,50 @@
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<el-drawer
:visible.sync="drawer"
direction="btt"
:with-header="false">
<el-table :data="previewData.dataList" stripe border
:max-height="200"
style="width: 100%; margin: 15px 0;">
<el-table-column label="序号" width="55" align="center">
<template slot-scope="scope">
<span>{{ scope.$index + 1 }}</span>
</template>
</el-table-column>
<template v-for="(column, index) in previewData.columnList">
<el-table-column
:prop="column"
:label="column"
:key="index"
align="center"
show-overflow-tooltip
/>
</template>
</el-table>
<el-pagination
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="previewData.pageNum"
:page-size.sync="previewData.pageSize"
:total="previewData.dataTotal"
></el-pagination>
</el-drawer>
<!-- 脱敏规则对话框 -->
<el-dialog :title="cipher.title" :visible.sync="cipher.open" width="400px" append-to-body>
<el-form ref="form2" :model="form2" :rules="rules2" label-width="80px">
<el-form-item label="字段名称" prop="fieldName">
<el-input v-model="form2.fieldName" placeholder="请输入字段名称" :disabled="true"/>
</el-form-item>
<el-form-item label="脱敏类型" prop="cipherType">
<el-select v-model="form2.cipherType" clearable placeholder="请选择脱敏类型" @change="cipherTypeSelectChanged">
<el-option
v-for="dict in cipherTypeOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="规则类型" prop="cryptType">
<el-select v-model="form2.cryptType" clearable placeholder="请选择规则类型">
<el-option
v-for="dict in cryptTypeOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
></el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFieldCipherForm">确 定</el-button>
<el-button @click="cipher.open = false">取 消</el-button>
</div>
</el-dialog>
</div>
</el-card>
</div>
</template>
<script>
import { getDataSet, updateDataSet } from '@/api/factory/dataset'
import { listDataSource, queryByPage } from '@/api/factory/datasource'
import sqlFormatter from 'sql-formatter'
import SqlEditor from '@/components/SqlEditor'
import { getApiMask, updateApiMask } from '@/api/market/apimask'
import { listDataApi } from '@/api/market/dataapi'
export default {
name: 'ApiMaskEdit',
components: {
SqlEditor
},
props: {
data: {
type: Object,
......@@ -127,24 +137,51 @@ export default {
isDisabled: false
},
// 表单参数
form: {},
form: {
id: undefined,
apiId: undefined,
maskName: undefined,
rules: [],
status: '1',
remark: undefined
},
// 表单校验
rules: {
setName: [
{ required: true, message: '数据集名称不能为空', trigger: 'blur' }
apiId: [
{ required: true, message: '数据API不能为空', trigger: 'blur' }
],
maskName: [
{ required: true, message: '脱敏名称不能为空', trigger: 'blur' }
]
},
form2: {
fieldName: undefined,
cipherType: undefined,
cryptType: undefined
},
rules2: {
fieldName: [
{ required: true, message: '字段名称不能为空', trigger: 'blur' }
]
},
// 状态数据字典
statusOptions: [],
// 数据源数据字典
sourceOptions: [],
drawer: false,
previewData: {
dataList: [],
columnList: [],
pageNum: 1,
pageSize: 20,
dataTotal: 0
// 数据API数据字典
apiOptions: [],
// 脱敏字段信息
resParamList: [],
// 脱敏类型数据字典
cipherTypeOptions: [],
cryptTypeOptions: [],
// 正则替换数据字典
regexCryptoOptions: [],
// 加密算法数据字典
algorithmCryptoOptions: [],
cipher: {
// 是否显示弹出层
open: false,
// 弹出层标题
title: "脱敏规则配置"
}
}
},
......@@ -155,80 +192,120 @@ export default {
this.statusOptions = response.data
}
})
this.getDataSourceList()
this.getDataSet(this.data.id)
this.getDataApiList()
this.getDicts('data_cipher_type').then(response => {
if (response.success) {
this.cipherTypeOptions = response.data
}
})
this.getDicts('data_regex_crypto').then(response => {
if (response.success) {
this.regexCryptoOptions = response.data
}
})
this.getDicts('data_algorithm_crypto').then(response => {
if (response.success) {
this.algorithmCryptoOptions = response.data
}
})
this.getApiMask(this.data.id)
},
methods: {
showCard () {
this.$emit('showCard', this.showOptions)
},
getDataSourceList () {
listDataSource().then(response => {
getDataApiList () {
listDataApi().then(response => {
if (response.success) {
this.sourceOptions = response.data
this.apiOptions = response.data
}
})
},
/** 获取详情 */
getDataSet: function (id) {
getDataSet(id).then(response => {
getApiMask: function (id) {
getApiMask(id).then(response => {
if (response.success) {
this.form = response.data
this.$refs.sqleditor.editor.setValue(this.form.setSql)
this.resParamList = this.apiOptions.filter(item => item.id === this.form.apiId).map(function (item) {
return item.resParams
})
this.form.rules.forEach(rule => {
let fieldParamIndex = this.resParamList.findIndex((param) => {
return param.fieldName === rule.fieldName
})
if (fieldParamIndex != -1) {
let cipher = this.cipherTypeOptions.find((item) => {
return item.itemText === rule.cipherType
})
let crypt = this.cryptTypeOptions.find((item) => {
return item.itemText === rule.cryptType
})
let resParam = Object.assign({}, this.resParamList[fieldParamIndex], { cipherType: (cipher && cipher.itemValue) || undefined, cryptType: (crypt && crypt.itemValue) || undefined })
this.$set(this.resParamList, fieldParamIndex, resParam)
}
})
}
})
},
// 绑定编辑器value值的变化
changeTextarea (val) {
this.$set(this.form, 'setSql', val)
apiSelectChanged (val) {
this.resParamList = this.apiOptions.filter(item => item.id === val).map(function (item) {
return item.resParams
})
},
formaterSql (val) {
this.$refs.sqleditor.editor.setValue(sqlFormatter.format(this.$refs.sqleditor.editor.getValue()))
fieldRule (fieldName) {
this.cipher.open = true
this.form2.fieldName = fieldName
this.form2.cipherType = undefined
this.form2.cryptType = undefined
this.cryptTypeOptions = []
},
dataPreview () {
if (!this.form.sourceId) {
return
cipherTypeSelectChanged (val) {
this.form2.cryptType = undefined
this.cryptTypeOptions = []
if (val === '1') {
// 正则替换
this.cryptTypeOptions = this.regexCryptoOptions
} else if (val === '2') {
// 加密算法
this.cryptTypeOptions = this.algorithmCryptoOptions
}
if (!this.form.setSql) {
return
},
submitFieldCipherForm () {
let fieldRuleIndex = this.form.rules.findIndex((item) => {
return item.fieldName === this.form2.fieldName
})
if (fieldRuleIndex != -1) {
// 当返回-1时,则说明数组中没有
this.form.rules.splice(fieldRuleIndex, 1)
}
let data = {}
data.dataSourceId = this.form.sourceId
data.sql = this.form.setSql
data.pageNum = this.previewData.pageNum
data.pageSize = this.previewData.pageSize
queryByPage(data).then(response => {
if (response.success) {
const { data } = response
let dataList = data.data || []
let columnList = []
if (dataList.length > 0) {
columnList = Object.keys(dataList[0])
}
this.previewData.dataList = dataList
this.previewData.columnList = columnList
this.previewData.dataTotal = data.total
this.drawer = true
}
if (this.form2.cipherType && this.form2.cryptType) {
this.form.rules.push(this.form2)
}
let cipher = this.cipherTypeOptions.find((item) => {
return item.itemText === this.form2.cipherType
})
},
handleSizeChange (val) {
this.previewData.pageNum = 1
this.previewData.pageSize = val
this.dataPreview()
},
handleCurrentChange (val) {
this.previewData.pageNum = val
this.dataPreview()
let crypt = this.cryptTypeOptions.find((item) => {
return item.itemText === this.form2.cryptType
})
let fieldParamIndex = this.resParamList.findIndex((item) => {
return item.fieldName === this.form2.fieldName
})
let resParam = Object.assign({}, this.resParamList[fieldParamIndex], { cipherType: (cipher && cipher.itemValue) || undefined, cryptType: (crypt && crypt.itemValue) || undefined })
this.$set(this.resParamList, fieldParamIndex, resParam)
this.cipher.open = false
},
/** 提交按钮 */
submitForm: function () {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.rules.length <= 0) {
this.$message.error('脱敏字段规则配置不能为空')
return
}
this.loadingOptions.loading = true
this.loadingOptions.loadingText = '保存中...'
this.loadingOptions.isDisabled = true
updateDataSet(this.form).then(response => {
updateApiMask(this.form).then(response => {
if (response.success) {
this.$message.success('保存成功')
setTimeout(() => {
......
......@@ -50,7 +50,7 @@
<el-form-item label="是否限流" prop="rateLimit">
<el-radio-group v-model="form1.rateLimit">
<el-radio
v-for="dict in rateLimitOptions"
v-for="dict in whetherOptions"
:key="dict.id"
:label="dict.itemText"
>{{dict.itemValue}}</el-radio>
......@@ -97,8 +97,8 @@
></el-option>
</el-select>
</el-form-item>
<el-form-item v-if="form2.configType === '1'">
<el-select v-model="form2.tableName" placeholder="请选择" @change="tableNameSelectChanged">
<el-form-item label="数据库表" prop="tableName" v-if="form2.configType === '1'">
<el-select v-model="form2.tableName" placeholder="请选择数据库表" @change="tableNameSelectChanged">
<el-option
v-for="item in tableNameOptions"
:key="item.tableName"
......@@ -107,7 +107,7 @@
</el-option>
</el-select>
</el-form-item>
<el-form-item v-if="form2.configType === '1'">
<el-form-item label="字段列表" v-if="form2.configType === '1'">
<el-table :data="fieldParamList" stripe border
:max-height="300"
style="width: 100%; margin: 15px 0;">
......@@ -166,6 +166,82 @@
</el-form-item>
</el-form>
<el-form ref="form3" :model="form3" :rules="rules3" label-width="80px" v-if="active == 3">
<el-form-item label="请求参数">
<el-table :data="form3.reqParams" stripe border
:max-height="300"
style="width: 100%; margin: 15px 0;">
<el-table-column label="序号" width="55" align="center">
<template slot-scope="scope">
<span>{{ scope.$index +1 }}</span>
</template>
</el-table-column>
<el-table-column prop="paramName" label="参数名称" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="nullable" label="是否必传" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-checkbox v-model="scope.row.nullable" true-label="1" false-label="0"></el-checkbox>
</template>
</el-table-column>
<el-table-column prop="remark" label="描述" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="whereType" label="操作符" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-select v-model="scope.row.whereType" placeholder="请选择操作符">
<el-option
v-for="dict in whereTypeOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="paramType" label="参数类型" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-select v-model="scope.row.paramType" placeholder="请选择参数类型">
<el-option
v-for="dict in paramTypeOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="exampleValue" label="示例值" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-input v-model="scope.row.exampleValue" placeholder="请输入示例值" />
</template>
</el-table-column>
<el-table-column prop="defaultValue" label="默认值" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-input v-model="scope.row.defaultValue" placeholder="请输入默认值" />
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item label="返回字段">
<el-table :data="form3.resParams" stripe border
:max-height="300"
style="width: 100%; margin: 15px 0;">
<el-table-column label="序号" width="55" align="center">
<template slot-scope="scope">
<span>{{ scope.$index +1 }}</span>
</template>
</el-table-column>
<el-table-column prop="fieldName" label="字段名称" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="remark" label="描述" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="dataType" label="数据类型" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="exampleValue" label="示例值" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-input v-model="scope.row.exampleValue" placeholder="请输入示例值" />
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
<el-button style="margin-top: 12px;" @click="handleNextStep" v-if="active < 3">下一步</el-button>
<el-button style="margin-top: 12px;" @click="handleLastStep" v-if="active > 1">上一步</el-button>
......@@ -274,8 +350,8 @@ export default {
reqMethodOptions: [],
// 返回格式数据字典
resTypeOptions: [],
// 是否限流数据字典
rateLimitOptions: [],
// 是否数据字典
whetherOptions: [],
// 状态数据字典
statusOptions: [],
// 数据源数据字典
......@@ -285,7 +361,11 @@ export default {
// 数据库表字段列表
fieldParamList: [],
// 配置方式数据字典
configTypeOptions: []
configTypeOptions: [],
// 操作符数据字典
whereTypeOptions: [],
// 参数类型数据字典
paramTypeOptions: []
}
},
created () {
......@@ -301,7 +381,7 @@ export default {
})
this.getDicts('sys_yes_no').then(response => {
if (response.success) {
this.rateLimitOptions = response.data
this.whetherOptions = response.data
}
})
this.getDicts('sys_common_status').then(response => {
......@@ -315,6 +395,16 @@ export default {
this.configTypeOptions = response.data
}
})
this.getDicts('data_where_type').then(response => {
if (response.success) {
this.whereTypeOptions = response.data
}
})
this.getDicts('data_param_type').then(response => {
if (response.success) {
this.paramTypeOptions = response.data
}
})
},
methods: {
showCard () {
......@@ -342,23 +432,22 @@ export default {
this.form3.reqParams = this.fieldParamList.filter(item => item.reqable).map(function (item) {
let json = {}
json.paramName = item.colName
json.nullable = false
json.remark = item.colComment
json.paramType = undefined
json.whereType = undefined
json.exampleValue = undefined
json.defaultValue = undefined
json.nullable = item.nullable || '0'
json.remark = item.remark || undefined
json.paramType = item.paramType || undefined
json.whereType = item.whereType || undefined
json.exampleValue = item.exampleValue || undefined
json.defaultValue = item.defaultValue || undefined
return json
})
this.form3.resParams = this.fieldParamList.filter(item => item.resable).map(function (item) {
let json = {}
json.fieldName = item.colName
json.remark = item.colComment
json.dataType = item.dataType
json.exampleValue = undefined
json.remark = item.colComment || undefined
json.dataType = item.dataType || undefined
json.exampleValue = item.exampleValue || undefined
return json
})
console.log(this.form3)
}
this.active++
}
......@@ -413,7 +502,28 @@ export default {
sqlParse(data).then(response => {
if (response.success) {
const { data } = response
console.log(data)
let reqParams = data.reqParams
let resParams = data.resParams
this.form3.reqParams = reqParams.map(function (item) {
let json = {}
json.paramName = item.paramName
json.nullable = item.nullable || '0'
json.remark = item.remark || undefined
json.paramType = item.paramType || undefined
json.whereType = item.whereType || undefined
json.exampleValue = item.exampleValue || undefined
json.defaultValue = item.defaultValue || undefined
return json
})
this.form3.resParams = resParams.map(function (item) {
let json = {}
json.fieldName = item.fieldName
json.remark = item.remark || undefined
json.dataType = item.dataType || undefined
json.exampleValue = item.exampleValue || undefined
return json
})
this.$message.success('解析成功,请进行下一步')
}
})
},
......@@ -421,10 +531,21 @@ export default {
submitForm: function () {
this.$refs['form3'].validate(valid => {
if (valid) {
if (this.form3.reqParams.length <= 0) {
this.$message.error('请求参数不能为空')
return
}
if (this.form3.resParams.length <= 0) {
this.$message.error('返回字段不能为空')
return
}
this.form1.executeConfig = this.form2
this.form1.reqParams = this.form3.reqParams
this.form1.resParams = this.form3.resParams
this.loadingOptions.loading = true
this.loadingOptions.loadingText = '保存中...'
this.loadingOptions.isDisabled = true
addDataApi(this.form).then(response => {
addDataApi(this.form1).then(response => {
if (response.success) {
this.$message.success('保存成功')
setTimeout(() => {
......
......@@ -4,36 +4,65 @@
<div slot="header" class="clearfix">
<span>{{ title }}</span>
<el-button-group style="float: right;">
<el-button size="mini" icon="el-icon-s-data" round @click="dataPreview">数据预览</el-button>
<el-button size="mini" icon="el-icon-back" round @click="showCard">返回</el-button>
</el-button-group>
</div>
<div :style="classCardbody">
<el-form ref="form" :model="form" label-width="80px" disabled>
<el-form-item label="数据源" prop="sourceId">
<el-select v-model="form.sourceId" placeholder="请选择数据源">
<el-steps :active="active" finish-status="success" align-center>
<el-step title="属性配置"></el-step>
<el-step title="执行配置"></el-step>
<el-step title="参数配置"></el-step>
</el-steps>
<el-form ref="form1" :model="form1" :rules="rules1" label-width="80px" v-if="active == 1" disabled>
<el-form-item label="API名称" prop="apiName">
<el-input v-model="form1.apiName" placeholder="请输入API名称" />
</el-form-item>
<el-form-item label="API版本" prop="apiVersion">
<el-input v-model="form1.apiVersion" placeholder="请输入API版本" />
</el-form-item>
<el-form-item label="API路径" prop="apiUrl">
<el-input v-model="form1.apiUrl" placeholder="请输入API路径" />
</el-form-item>
<el-form-item label="请求方式" prop="reqMethod">
<el-select v-model="form1.reqMethod" placeholder="请选择请求方式">
<el-option
v-for="source in sourceOptions"
:key="source.id"
:label="source.sourceName"
:value="source.id"
:disabled="source.status === '0'"
v-for="dict in reqMethodOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据集名称" prop="setName">
<el-input v-model="form.setName" placeholder="请输入数据集名称" />
<el-form-item label="返回格式" prop="resType">
<el-select v-model="form1.resType" placeholder="请选择返回格式">
<el-option
v-for="dict in resTypeOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据集sql" prop="setSql">
<sql-editor
ref="sqleditor"
:value="form.setSql"
:readOnly="true"
style="height: 300px;"
></sql-editor>
<el-form-item label="IP黑名单" prop="deny">
<el-input v-model="form1.deny" type="textarea" placeholder="请输入IP黑名单多个用,隔开" />
</el-form-item>
<el-form-item label="是否限流" prop="rateLimit">
<el-radio-group v-model="form1.rateLimit">
<el-radio
v-for="dict in whetherOptions"
:key="dict.id"
:label="dict.itemText"
>{{dict.itemValue}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="请求次数" prop="times" v-if="form1.rateLimit === '1'">
<el-input-number v-model="form1.times" controls-position="right" :min="1" />
</el-form-item>
<el-form-item label="请求时间范围" prop="seconds" v-if="form1.rateLimit === '1'">
<el-input-number v-model="form1.seconds" controls-position="right" :min="1"/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio-group v-model="form1.status">
<el-radio
v-for="dict in statusOptions"
:key="dict.id"
......@@ -42,49 +71,187 @@
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
<el-input v-model="form1.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<el-form ref="form2" :model="form2" :rules="rules2" label-width="80px" v-if="active == 2" disabled>
<el-form-item label="配置方式" prop="configType">
<el-select v-model="form2.configType" placeholder="请选择配置方式" @change="configTypeSelectChanged">
<el-option
v-for="dict in configTypeOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据源" prop="sourceId">
<el-select v-model="form2.sourceId" placeholder="请选择数据源" @change="sourceSelectChanged">
<el-option
v-for="source in sourceOptions"
:key="source.id"
:label="source.sourceName"
:value="source.id"
:disabled="source.status === '0'"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据库表" prop="tableName" v-if="form2.configType === '1'">
<el-select v-model="form2.tableName" placeholder="请选择数据库表" @change="tableNameSelectChanged">
<el-option
v-for="item in tableNameOptions"
:key="item.tableName"
:label="item.tableComment"
:value="item.tableName">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="字段列表" v-if="form2.configType === '1'">
<el-table :data="fieldParamList" stripe border
:max-height="300"
style="width: 100%; margin: 15px 0;">
<el-table-column prop="colPosition" label="序号" width="55" align="center" >
</el-table-column>
<el-table-column prop="colName" label="列名" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="dataType" label="数据类型" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="dataLength" label="数据长度" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="dataPrecision" label="数据精度" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="dataScale" label="数据小数位" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="colKey" label="是否主键" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<span v-if="scope.row.colKey === true"></span>
<span v-if="scope.row.colKey === false"></span>
</template>
</el-table-column>
<el-table-column prop="nullable" label="是否允许为空" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<span v-if="scope.row.nullable === true"></span>
<span v-if="scope.row.nullable === false"></span>
</template>
</el-table-column>
<el-table-column prop="dataDefault" label="列默认值" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="colComment" label="列注释" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="reqable" label="是否作为请求参数" align="center" width="50" >
<template slot-scope="scope">
<el-checkbox v-model="scope.row.reqable"></el-checkbox>
</template>
</el-table-column>
<el-table-column prop="resable" label="是否作为返回参数" align="center" width="50" >
<template slot-scope="scope">
<el-checkbox v-model="scope.row.resable"></el-checkbox>
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-row v-if="form2.configType === '2'">
<el-col :span="24">
<sql-editor
ref="sqleditor"
:value="form2.sqlText"
@changeTextarea="changeTextarea($event)"
style="height: 300px;margin: 10px 10px;"
></sql-editor>
</el-col>
</el-row>
<el-form-item v-if="form2.configType === '2'">
<el-button size="mini" type="primary" @click="sqlParse">SQL解析</el-button>
</el-form-item>
</el-form>
<el-form ref="form3" :model="form3" :rules="rules3" label-width="80px" v-if="active == 3" disabled>
<el-form-item label="请求参数">
<el-table :data="form3.reqParams" stripe border
:max-height="300"
style="width: 100%; margin: 15px 0;">
<el-table-column label="序号" width="55" align="center">
<template slot-scope="scope">
<span>{{ scope.$index +1 }}</span>
</template>
</el-table-column>
<el-table-column prop="paramName" label="参数名称" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="nullable" label="是否必传" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-checkbox v-model="scope.row.nullable" true-label="1" false-label="0"></el-checkbox>
</template>
</el-table-column>
<el-table-column prop="remark" label="描述" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="whereType" label="操作符" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-select v-model="scope.row.whereType" placeholder="请选择操作符">
<el-option
v-for="dict in whereTypeOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="paramType" label="参数类型" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-select v-model="scope.row.paramType" placeholder="请选择参数类型">
<el-option
v-for="dict in paramTypeOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="exampleValue" label="示例值" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-input v-model="scope.row.exampleValue" placeholder="请输入示例值" />
</template>
</el-table-column>
<el-table-column prop="defaultValue" label="默认值" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-input v-model="scope.row.defaultValue" placeholder="请输入默认值" />
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item label="返回字段">
<el-table :data="form3.resParams" stripe border
:max-height="300"
style="width: 100%; margin: 15px 0;">
<el-table-column label="序号" width="55" align="center">
<template slot-scope="scope">
<span>{{ scope.$index +1 }}</span>
</template>
</el-table-column>
<el-table-column prop="fieldName" label="字段名称" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="remark" label="描述" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="dataType" label="数据类型" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="exampleValue" label="示例值" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-input v-model="scope.row.exampleValue" placeholder="请输入示例值" />
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
<el-drawer
:visible.sync="drawer"
direction="btt"
:with-header="false">
<el-table :data="previewData.dataList" stripe border
:max-height="200"
style="width: 100%; margin: 15px 0;">
<el-table-column label="序号" width="55" align="center">
<template slot-scope="scope">
<span>{{ scope.$index + 1 }}</span>
</template>
</el-table-column>
<template v-for="(column, index) in previewData.columnList">
<el-table-column
:prop="column"
:label="column"
:key="index"
align="center"
show-overflow-tooltip
/>
</template>
</el-table>
<el-pagination
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="previewData.pageNum"
:page-size.sync="previewData.pageSize"
:total="previewData.dataTotal"
></el-pagination>
</el-drawer>
<el-button style="margin-top: 12px;" @click="handleNextStep" v-if="active < 3">下一步</el-button>
<el-button style="margin-top: 12px;" @click="handleLastStep" v-if="active > 1">上一步</el-button>
</div>
</el-card>
</div>
</template>
<script>
import { getDataSet } from '@/api/factory/dataset'
import { listDataSource, queryByPage } from '@/api/factory/datasource'
import { getDataApi, sqlParse } from '@/api/market/dataapi'
import { listDataSource, getDbTables, getDbTableColumns } from '@/api/factory/datasource'
import SqlEditor from '@/components/SqlEditor'
export default {
......@@ -115,31 +282,124 @@ export default {
showEdit: false,
showDetail: false
},
active: 1,
// 表单参数
form: {},
form1: {
id: undefined,
apiName: undefined,
apiVersion: undefined,
apiUrl: undefined,
reqMethod: undefined,
resType: undefined,
deny: undefined,
rateLimit: '1',
times: 5,
seconds: 60,
status: '1',
remark: undefined,
executeConfig: {},
reqParams: [],
resParams: []
},
// 表单校验
rules1: {
apiName: [
{ required: true, message: 'API名称不能为空', trigger: 'blur' }
],
apiVersion: [
{ required: true, message: 'API版本不能为空', trigger: 'blur' }
],
apiUrl: [
{ required: true, message: 'API路径不能为空', trigger: 'blur' }
],
reqMethod: [
{ required: true, message: '请求方式不能为空', trigger: 'blur' }
],
resType: [
{ required: true, message: '返回格式不能为空', trigger: 'blur' }
]
},
form2: {
configType: undefined,
sourceId: undefined,
tableName: undefined,
fieldParams: [],
sqlText: undefined
},
rules2: {
configType: [
{ required: true, message: '配置方式不能为空', trigger: 'blur' }
],
sourceId: [
{ required: true, message: '数据源不能为空', trigger: 'blur' }
]
},
form3: {
reqParams: [],
resParams: []
},
rules3: {},
// 请求方式数据字典
reqMethodOptions: [],
// 返回格式数据字典
resTypeOptions: [],
// 是否数据字典
whetherOptions: [],
// 状态数据字典
statusOptions: [],
// 数据源数据字典
sourceOptions: [],
drawer: false,
previewData: {
dataList: [],
columnList: [],
pageNum: 1,
pageSize: 20,
dataTotal: 0
}
// 数据库表数据字典
tableNameOptions: [],
// 数据库表字段列表
fieldParamList: [],
// 配置方式数据字典
configTypeOptions: [],
// 操作符数据字典
whereTypeOptions: [],
// 参数类型数据字典
paramTypeOptions: []
}
},
created () {
console.log('id:' + this.data.id)
this.getDicts('sys_job_status').then(response => {
this.getDicts('data_req_method').then(response => {
if (response.success) {
this.reqMethodOptions = response.data
}
})
this.getDicts('data_res_type').then(response => {
if (response.success) {
this.resTypeOptions = response.data
}
})
this.getDicts('sys_yes_no').then(response => {
if (response.success) {
this.whetherOptions = response.data
}
})
this.getDicts('sys_common_status').then(response => {
if (response.success) {
this.statusOptions = response.data
}
})
this.getDataSourceList()
this.getDataSet(this.data.id)
this.getDicts('data_config_type').then(response => {
if (response.success) {
this.configTypeOptions = response.data
}
})
this.getDicts('data_where_type').then(response => {
if (response.success) {
this.whereTypeOptions = response.data
}
})
this.getDicts('data_param_type').then(response => {
if (response.success) {
this.paramTypeOptions = response.data
}
})
this.getDataApi(this.data.id)
},
methods: {
showCard () {
......@@ -152,50 +412,141 @@ export default {
}
})
},
/** 获取详情 */
getDataSet: function (id) {
getDataSet(id).then(response => {
/** 步骤条下一步 */
handleNextStep () {
if (this.active === 1) {
this.$refs['form1'].validate(valid => {
if (valid) {
this.active++
}
})
} else if (this.active === 2) {
this.$refs['form2'].validate(valid => {
if (valid) {
if (this.form2.configType && this.form2.configType === '1') {
this.form3.reqParams = this.fieldParamList.filter(item => item.reqable).map(function (item) {
let json = {}
json.paramName = item.colName
json.nullable = item.nullable || '0'
json.remark = item.remark || undefined
json.paramType = item.paramType || undefined
json.whereType = item.whereType || undefined
json.exampleValue = item.exampleValue || undefined
json.defaultValue = item.defaultValue || undefined
return json
})
this.form3.resParams = this.fieldParamList.filter(item => item.resable).map(function (item) {
let json = {}
json.fieldName = item.colName
json.remark = item.colComment || undefined
json.dataType = item.dataType || undefined
json.exampleValue = item.exampleValue || undefined
return json
})
}
this.active++
}
})
}
},
/** 步骤条上一步 */
handleLastStep () {
this.active--
},
changeTextarea (val) {
this.form2.sqlText = val
},
configTypeSelectChanged (val) {
if (this.form2.configType === '1' && this.form2.sourceId && this.tableNameOptions.length <= 0) {
getDbTables(this.form2.sourceId).then(response => {
if (response.success) {
this.tableNameOptions = response.data
this.fieldParamList = []
}
})
}
},
sourceSelectChanged (val) {
if (this.form2.configType && this.form2.configType === '1') {
getDbTables(val).then(response => {
if (response.success) {
this.tableNameOptions = response.data
this.fieldParamList = []
}
})
}
},
tableNameSelectChanged (val) {
getDbTableColumns(this.form2.sourceId, val).then(response => {
if (response.success) {
this.form = response.data
this.$refs.sqleditor.editor.setValue(this.form.setSql)
this.fieldParamList = response.data
}
})
},
dataPreview () {
if (!this.form.sourceId) {
sqlParse () {
if (!this.form2.sourceId) {
this.$message.error('数据源不能为空')
return
}
if (!this.form.setSql) {
if (!this.form2.sqlText) {
this.$message.error('解析SQL不能为空')
return
}
let data = {}
data.dataSourceId = this.form.sourceId
data.sql = this.form.setSql
data.pageNum = this.previewData.pageNum
data.pageSize = this.previewData.pageSize
queryByPage(data).then(response => {
data.sqlText = this.form2.sqlText
sqlParse(data).then(response => {
if (response.success) {
const { data } = response
let dataList = data.data || []
let columnList = []
if (dataList.length > 0) {
columnList = Object.keys(dataList[0])
}
this.previewData.dataList = dataList
this.previewData.columnList = columnList
this.previewData.dataTotal = data.total
this.drawer = true
let reqParams = data.reqParams
let resParams = data.resParams
this.form3.reqParams = reqParams.map(function (item) {
let json = {}
json.paramName = item.paramName
json.nullable = item.nullable || '0'
json.remark = item.remark || undefined
json.paramType = item.paramType || undefined
json.whereType = item.whereType || undefined
json.exampleValue = item.exampleValue || undefined
json.defaultValue = item.defaultValue || undefined
return json
})
this.form3.resParams = resParams.map(function (item) {
let json = {}
json.fieldName = item.fieldName
json.remark = item.remark || undefined
json.dataType = item.dataType || undefined
json.exampleValue = item.exampleValue || undefined
return json
})
this.$message.success('解析成功,请进行下一步')
}
})
},
handleSizeChange (val) {
this.previewData.pageNum = 1
this.previewData.pageSize = val
this.dataPreview()
},
handleCurrentChange (val) {
this.previewData.pageNum = val
this.dataPreview()
/** 获取详情 */
getDataApi: function (id) {
getDataApi(id).then(response => {
if (response.success) {
this.form1 = response.data
this.form2 = this.form1.executeConfig
this.form3.reqParams = this.form1.reqParams
this.form3.resParams = this.form1.resParams
if (this.form2.configType === '1') {
getDbTables(this.form2.sourceId).then(response => {
if (response.success) {
this.tableNameOptions = response.data
getDbTableColumns(this.form2.sourceId, this.form2.tableName).then(response => {
if (response.success) {
this.fieldParamList = response.data
}
})
}
})
}
if (this.form2.configType === '2') {
this.$refs.sqleditor.editor.setValue(this.form2.sqlText)
}
}
})
}
}
}
......
......@@ -9,35 +9,61 @@
</el-button-group>
</div>
<div :style="classCardbody">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="数据源" prop="sourceId">
<el-select v-model="form.sourceId" placeholder="请选择数据源">
<el-steps :active="active" finish-status="success" align-center>
<el-step title="属性配置"></el-step>
<el-step title="执行配置"></el-step>
<el-step title="参数配置"></el-step>
</el-steps>
<el-form ref="form1" :model="form1" :rules="rules1" label-width="80px" v-if="active == 1">
<el-form-item label="API名称" prop="apiName">
<el-input v-model="form1.apiName" placeholder="请输入API名称" />
</el-form-item>
<el-form-item label="API版本" prop="apiVersion">
<el-input v-model="form1.apiVersion" placeholder="请输入API版本" />
</el-form-item>
<el-form-item label="API路径" prop="apiUrl">
<el-input v-model="form1.apiUrl" placeholder="请输入API路径" />
</el-form-item>
<el-form-item label="请求方式" prop="reqMethod">
<el-select v-model="form1.reqMethod" placeholder="请选择请求方式">
<el-option
v-for="source in sourceOptions"
:key="source.id"
:label="source.sourceName"
:value="source.id"
:disabled="source.status === '0'"
v-for="dict in reqMethodOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据集名称" prop="setName">
<el-input v-model="form.setName" placeholder="请输入数据集名称" />
<el-form-item label="返回格式" prop="resType">
<el-select v-model="form1.resType" placeholder="请选择返回格式">
<el-option
v-for="dict in resTypeOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="IP黑名单" prop="deny">
<el-input v-model="form1.deny" type="textarea" placeholder="请输入IP黑名单多个用,隔开" />
</el-form-item>
<el-form-item label="是否限流" prop="rateLimit">
<el-radio-group v-model="form1.rateLimit">
<el-radio
v-for="dict in whetherOptions"
:key="dict.id"
:label="dict.itemText"
>{{dict.itemValue}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="数据集sql" prop="setSql">
<sql-editor
ref="sqleditor"
:value="form.setSql"
@changeTextarea="changeTextarea($event)"
style="height: 300px;"
></sql-editor>
<el-form-item label="请求次数" prop="times" v-if="form1.rateLimit === '1'">
<el-input-number v-model="form1.times" controls-position="right" :min="1" />
</el-form-item>
<el-form-item>
<el-button size="mini" type="primary" @click="formaterSql">Sql格式化</el-button>
<el-button size="mini" type="primary" @click="dataPreview">预览</el-button>
<el-form-item label="请求时间范围" prop="seconds" v-if="form1.rateLimit === '1'">
<el-input-number v-model="form1.seconds" controls-position="right" :min="1"/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio-group v-model="form1.status">
<el-radio
v-for="dict in statusOptions"
:key="dict.id"
......@@ -46,50 +72,187 @@
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
<el-input v-model="form1.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<el-form ref="form2" :model="form2" :rules="rules2" label-width="80px" v-if="active == 2">
<el-form-item label="配置方式" prop="configType">
<el-select v-model="form2.configType" placeholder="请选择配置方式" @change="configTypeSelectChanged">
<el-option
v-for="dict in configTypeOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据源" prop="sourceId">
<el-select v-model="form2.sourceId" placeholder="请选择数据源" @change="sourceSelectChanged">
<el-option
v-for="source in sourceOptions"
:key="source.id"
:label="source.sourceName"
:value="source.id"
:disabled="source.status === '0'"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据库表" prop="tableName" v-if="form2.configType === '1'">
<el-select v-model="form2.tableName" placeholder="请选择数据库表" @change="tableNameSelectChanged">
<el-option
v-for="item in tableNameOptions"
:key="item.tableName"
:label="item.tableComment"
:value="item.tableName">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="字段列表" v-if="form2.configType === '1'">
<el-table :data="fieldParamList" stripe border
:max-height="300"
style="width: 100%; margin: 15px 0;">
<el-table-column prop="colPosition" label="序号" width="55" align="center" >
</el-table-column>
<el-table-column prop="colName" label="列名" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="dataType" label="数据类型" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="dataLength" label="数据长度" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="dataPrecision" label="数据精度" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="dataScale" label="数据小数位" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="colKey" label="是否主键" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<span v-if="scope.row.colKey === true"></span>
<span v-if="scope.row.colKey === false"></span>
</template>
</el-table-column>
<el-table-column prop="nullable" label="是否允许为空" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<span v-if="scope.row.nullable === true"></span>
<span v-if="scope.row.nullable === false"></span>
</template>
</el-table-column>
<el-table-column prop="dataDefault" label="列默认值" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="colComment" label="列注释" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="reqable" label="是否作为请求参数" align="center" width="50" >
<template slot-scope="scope">
<el-checkbox v-model="scope.row.reqable"></el-checkbox>
</template>
</el-table-column>
<el-table-column prop="resable" label="是否作为返回参数" align="center" width="50" >
<template slot-scope="scope">
<el-checkbox v-model="scope.row.resable"></el-checkbox>
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-row v-if="form2.configType === '2'">
<el-col :span="24">
<sql-editor
ref="sqleditor"
:value="form2.sqlText"
@changeTextarea="changeTextarea($event)"
style="height: 300px;margin: 10px 10px;"
></sql-editor>
</el-col>
</el-row>
<el-form-item v-if="form2.configType === '2'">
<el-button size="mini" type="primary" @click="sqlParse">SQL解析</el-button>
</el-form-item>
</el-form>
<el-form ref="form3" :model="form3" :rules="rules3" label-width="80px" v-if="active == 3">
<el-form-item label="请求参数">
<el-table :data="form3.reqParams" stripe border
:max-height="300"
style="width: 100%; margin: 15px 0;">
<el-table-column label="序号" width="55" align="center">
<template slot-scope="scope">
<span>{{ scope.$index +1 }}</span>
</template>
</el-table-column>
<el-table-column prop="paramName" label="参数名称" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="nullable" label="是否必传" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-checkbox v-model="scope.row.nullable" true-label="1" false-label="0"></el-checkbox>
</template>
</el-table-column>
<el-table-column prop="remark" label="描述" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="whereType" label="操作符" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-select v-model="scope.row.whereType" placeholder="请选择操作符">
<el-option
v-for="dict in whereTypeOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="paramType" label="参数类型" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-select v-model="scope.row.paramType" placeholder="请选择参数类型">
<el-option
v-for="dict in paramTypeOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="exampleValue" label="示例值" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-input v-model="scope.row.exampleValue" placeholder="请输入示例值" />
</template>
</el-table-column>
<el-table-column prop="defaultValue" label="默认值" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-input v-model="scope.row.defaultValue" placeholder="请输入默认值" />
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item label="返回字段">
<el-table :data="form3.resParams" stripe border
:max-height="300"
style="width: 100%; margin: 15px 0;">
<el-table-column label="序号" width="55" align="center">
<template slot-scope="scope">
<span>{{ scope.$index +1 }}</span>
</template>
</el-table-column>
<el-table-column prop="fieldName" label="字段名称" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="remark" label="描述" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="dataType" label="数据类型" align="center" show-overflow-tooltip >
</el-table-column>
<el-table-column prop="exampleValue" label="示例值" align="center" show-overflow-tooltip >
<template slot-scope="scope">
<el-input v-model="scope.row.exampleValue" placeholder="请输入示例值" />
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
<el-drawer
:visible.sync="drawer"
direction="btt"
:with-header="false">
<el-table :data="previewData.dataList" stripe border
:max-height="200"
style="width: 100%; margin: 15px 0;">
<el-table-column label="序号" width="55" align="center">
<template slot-scope="scope">
<span>{{ scope.$index + 1 }}</span>
</template>
</el-table-column>
<template v-for="(column, index) in previewData.columnList">
<el-table-column
:prop="column"
:label="column"
:key="index"
align="center"
show-overflow-tooltip
/>
</template>
</el-table>
<el-pagination
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="previewData.pageNum"
:page-size.sync="previewData.pageSize"
:total="previewData.dataTotal"
></el-pagination>
</el-drawer>
<el-button style="margin-top: 12px;" @click="handleNextStep" v-if="active < 3">下一步</el-button>
<el-button style="margin-top: 12px;" @click="handleLastStep" v-if="active > 1">上一步</el-button>
</div>
</el-card>
</div>
</template>
<script>
import { getDataSet, updateDataSet } from '@/api/factory/dataset'
import { listDataSource, queryByPage } from '@/api/factory/datasource'
import sqlFormatter from 'sql-formatter'
import { getDataApi, updateDataApi, sqlParse } from '@/api/market/dataapi'
import { listDataSource, getDbTables, getDbTableColumns } from '@/api/factory/datasource'
import SqlEditor from '@/components/SqlEditor'
export default {
......@@ -126,37 +289,124 @@ export default {
loadingText: '保存',
isDisabled: false
},
active: 1,
// 表单参数
form: {},
form1: {
id: undefined,
apiName: undefined,
apiVersion: undefined,
apiUrl: undefined,
reqMethod: undefined,
resType: undefined,
deny: undefined,
rateLimit: '1',
times: 5,
seconds: 60,
status: '1',
remark: undefined,
executeConfig: {},
reqParams: [],
resParams: []
},
// 表单校验
rules: {
setName: [
{ required: true, message: '数据集名称不能为空', trigger: 'blur' }
rules1: {
apiName: [
{ required: true, message: 'API名称不能为空', trigger: 'blur' }
],
apiVersion: [
{ required: true, message: 'API版本不能为空', trigger: 'blur' }
],
apiUrl: [
{ required: true, message: 'API路径不能为空', trigger: 'blur' }
],
reqMethod: [
{ required: true, message: '请求方式不能为空', trigger: 'blur' }
],
resType: [
{ required: true, message: '返回格式不能为空', trigger: 'blur' }
]
},
form2: {
configType: undefined,
sourceId: undefined,
tableName: undefined,
fieldParams: [],
sqlText: undefined
},
rules2: {
configType: [
{ required: true, message: '配置方式不能为空', trigger: 'blur' }
],
sourceId: [
{ required: true, message: '数据源不能为空', trigger: 'blur' }
]
},
form3: {
reqParams: [],
resParams: []
},
rules3: {},
// 请求方式数据字典
reqMethodOptions: [],
// 返回格式数据字典
resTypeOptions: [],
// 是否数据字典
whetherOptions: [],
// 状态数据字典
statusOptions: [],
// 数据源数据字典
sourceOptions: [],
drawer: false,
previewData: {
dataList: [],
columnList: [],
pageNum: 1,
pageSize: 20,
dataTotal: 0
}
// 数据库表数据字典
tableNameOptions: [],
// 数据库表字段列表
fieldParamList: [],
// 配置方式数据字典
configTypeOptions: [],
// 操作符数据字典
whereTypeOptions: [],
// 参数类型数据字典
paramTypeOptions: []
}
},
created () {
console.log('id:' + this.data.id)
this.getDicts('sys_job_status').then(response => {
this.getDicts('data_req_method').then(response => {
if (response.success) {
this.reqMethodOptions = response.data
}
})
this.getDicts('data_res_type').then(response => {
if (response.success) {
this.resTypeOptions = response.data
}
})
this.getDicts('sys_yes_no').then(response => {
if (response.success) {
this.whetherOptions = response.data
}
})
this.getDicts('sys_common_status').then(response => {
if (response.success) {
this.statusOptions = response.data
}
})
this.getDataSourceList()
this.getDataSet(this.data.id)
this.getDicts('data_config_type').then(response => {
if (response.success) {
this.configTypeOptions = response.data
}
})
this.getDicts('data_where_type').then(response => {
if (response.success) {
this.whereTypeOptions = response.data
}
})
this.getDicts('data_param_type').then(response => {
if (response.success) {
this.paramTypeOptions = response.data
}
})
this.getDataApi(this.data.id)
},
methods: {
showCard () {
......@@ -169,66 +419,161 @@ export default {
}
})
},
/** 获取详情 */
getDataSet: function (id) {
getDataSet(id).then(response => {
if (response.success) {
this.form = response.data
this.$refs.sqleditor.editor.setValue(this.form.setSql)
}
})
/** 步骤条下一步 */
handleNextStep () {
if (this.active === 1) {
this.$refs['form1'].validate(valid => {
if (valid) {
this.active++
}
})
} else if (this.active === 2) {
this.$refs['form2'].validate(valid => {
if (valid) {
if (this.form2.configType && this.form2.configType === '1') {
this.form3.reqParams = this.fieldParamList.filter(item => item.reqable).map(function (item) {
let json = {}
json.paramName = item.colName
json.nullable = item.nullable || '0'
json.remark = item.remark || undefined
json.paramType = item.paramType || undefined
json.whereType = item.whereType || undefined
json.exampleValue = item.exampleValue || undefined
json.defaultValue = item.defaultValue || undefined
return json
})
this.form3.resParams = this.fieldParamList.filter(item => item.resable).map(function (item) {
let json = {}
json.fieldName = item.colName
json.remark = item.colComment || undefined
json.dataType = item.dataType || undefined
json.exampleValue = item.exampleValue || undefined
return json
})
}
this.active++
}
})
}
},
/** 步骤条上一步 */
handleLastStep () {
this.active--
},
// 绑定编辑器value值的变化
changeTextarea (val) {
this.$set(this.form, 'setSql', val)
this.form2.sqlText = val
},
configTypeSelectChanged (val) {
if (this.form2.configType === '1' && this.form2.sourceId && this.tableNameOptions.length <= 0) {
getDbTables(this.form2.sourceId).then(response => {
if (response.success) {
this.tableNameOptions = response.data
this.fieldParamList = []
}
})
}
},
formaterSql (val) {
this.$refs.sqleditor.editor.setValue(sqlFormatter.format(this.$refs.sqleditor.editor.getValue()))
sourceSelectChanged (val) {
if (this.form2.configType && this.form2.configType === '1') {
getDbTables(val).then(response => {
if (response.success) {
this.tableNameOptions = response.data
this.fieldParamList = []
}
})
}
},
tableNameSelectChanged (val) {
getDbTableColumns(this.form2.sourceId, val).then(response => {
if (response.success) {
this.fieldParamList = response.data
}
})
},
dataPreview () {
if (!this.form.sourceId) {
sqlParse () {
if (!this.form2.sourceId) {
this.$message.error('数据源不能为空')
return
}
if (!this.form.setSql) {
if (!this.form2.sqlText) {
this.$message.error('解析SQL不能为空')
return
}
let data = {}
data.dataSourceId = this.form.sourceId
data.sql = this.form.setSql
data.pageNum = this.previewData.pageNum
data.pageSize = this.previewData.pageSize
queryByPage(data).then(response => {
data.sqlText = this.form2.sqlText
sqlParse(data).then(response => {
if (response.success) {
const { data } = response
let dataList = data.data || []
let columnList = []
if (dataList.length > 0) {
columnList = Object.keys(dataList[0])
}
this.previewData.dataList = dataList
this.previewData.columnList = columnList
this.previewData.dataTotal = data.total
this.drawer = true
let reqParams = data.reqParams
let resParams = data.resParams
this.form3.reqParams = reqParams.map(function (item) {
let json = {}
json.paramName = item.paramName
json.nullable = item.nullable || '0'
json.remark = item.remark || undefined
json.paramType = item.paramType || undefined
json.whereType = item.whereType || undefined
json.exampleValue = item.exampleValue || undefined
json.defaultValue = item.defaultValue || undefined
return json
})
this.form3.resParams = resParams.map(function (item) {
let json = {}
json.fieldName = item.fieldName
json.remark = item.remark || undefined
json.dataType = item.dataType || undefined
json.exampleValue = item.exampleValue || undefined
return json
})
this.$message.success('解析成功,请进行下一步')
}
})
},
handleSizeChange (val) {
this.previewData.pageNum = 1
this.previewData.pageSize = val
this.dataPreview()
},
handleCurrentChange (val) {
this.previewData.pageNum = val
this.dataPreview()
/** 获取详情 */
getDataApi: function (id) {
getDataApi(id).then(response => {
if (response.success) {
this.form1 = response.data
this.form2 = this.form1.executeConfig
this.form3.reqParams = this.form1.reqParams
this.form3.resParams = this.form1.resParams
if (this.form2.configType === '1') {
getDbTables(this.form2.sourceId).then(response => {
if (response.success) {
this.tableNameOptions = response.data
getDbTableColumns(this.form2.sourceId, this.form2.tableName).then(response => {
if (response.success) {
this.fieldParamList = response.data
}
})
}
})
}
if (this.form2.configType === '2') {
this.$refs.sqleditor.editor.setValue(this.form2.sqlText)
}
}
})
},
/** 提交按钮 */
submitForm: function () {
this.$refs['form'].validate(valid => {
this.$refs['form3'].validate(valid => {
if (valid) {
if (this.form3.reqParams.length <= 0) {
this.$message.error('请求参数不能为空')
return
}
if (this.form3.resParams.length <= 0) {
this.$message.error('返回字段不能为空')
return
}
this.form1.executeConfig = this.form2
this.form1.reqParams = this.form3.reqParams
this.form1.resParams = this.form3.resParams
this.loadingOptions.loading = true
this.loadingOptions.loadingText = '保存中...'
this.loadingOptions.isDisabled = true
updateDataSet(this.form).then(response => {
updateDataApi(this.form1).then(response => {
if (response.success) {
this.$message.success('保存成功')
setTimeout(() => {
......
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