😎1、增加生成种子提示 2、调整文件上传

This commit is contained in:
zuohuaijun 2024-07-05 22:06:46 +08:00
parent 63ad79b527
commit ef08b47b8a
8 changed files with 88 additions and 76 deletions

View File

@ -37,7 +37,7 @@
<PackageReference Include="SqlSugarCore" Version="5.1.4.160" /> <PackageReference Include="SqlSugarCore" Version="5.1.4.160" />
<PackageReference Include="SSH.NET" Version="2024.1.0" /> <PackageReference Include="SSH.NET" Version="2024.1.0" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.4.3" /> <PackageReference Include="System.Linq.Dynamic.Core" Version="1.4.3" />
<PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1040" /> <PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1041" />
<PackageReference Include="UAParser" Version="3.1.47" /> <PackageReference Include="UAParser" Version="3.1.47" />
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" /> <PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
</ItemGroup> </ItemGroup>

View File

@ -0,0 +1,28 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 校验集合不能为空
/// </summary>
[SuppressSniffer]
public class NotEmptyAttribute : ValidationAttribute
{
/// <summary>
/// 校验集合不能为空
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public override bool IsValid(object value) => (value as IEnumerable)?.GetEnumerator().MoveNext() ?? false;
/// <summary>
/// 错误信息
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public override string FormatErrorMessage(string name) => base.FormatErrorMessage(name);
}

View File

@ -655,6 +655,12 @@ public enum ErrorCodeEnum
[ErrorCodeItemMetadata("不允许添加相同字段名")] [ErrorCodeItemMetadata("不允许添加相同字段名")]
db1002, db1002,
/// <summary>
/// 实体文件不存在或匹配不到。如果是刚刚生成的实体,请重启服务后再试
/// </summary>
[ErrorCodeItemMetadata("实体文件不存在或匹配不到。如果是刚刚生成的实体,请重启服务后再试")]
db1003,
/// <summary> /// <summary>
/// 父节点不存在 /// 父节点不存在
/// </summary> /// </summary>

View File

@ -316,7 +316,7 @@ public class SysDatabaseService : IDynamicApiController, ITransient
/// <param name="input"></param> /// <param name="input"></param>
[ApiDescriptionSettings(Name = "CreateSeedData"), HttpPost] [ApiDescriptionSettings(Name = "CreateSeedData"), HttpPost]
[DisplayName("创建种子数据")] [DisplayName("创建种子数据")]
public async void CreateSeedData(CreateSeedDataInput input) public async Task CreateSeedData(CreateSeedDataInput input)
{ {
var config = App.GetOptions<DbConnectionOptions>().ConnectionConfigs.FirstOrDefault(u => u.ConfigId.ToString() == input.ConfigId); var config = App.GetOptions<DbConnectionOptions>().ConnectionConfigs.FirstOrDefault(u => u.ConfigId.ToString() == input.ConfigId);
input.Position = string.IsNullOrWhiteSpace(input.Position) ? "Admin.NET.Core" : input.Position; input.Position = string.IsNullOrWhiteSpace(input.Position) ? "Admin.NET.Core" : input.Position;
@ -333,7 +333,7 @@ public class SysDatabaseService : IDynamicApiController, ITransient
entityType = item.Type; entityType = item.Type;
break; break;
} }
if (entityType == null) return; if (entityType == null) throw Oops.Oh(ErrorCodeEnum.db1003);
input.EntityName = entityType.Name; input.EntityName = entityType.Name;
input.SeedDataName = entityType.Name + "SeedData"; input.SeedDataName = entityType.Name + "SeedData";

View File

@ -168,7 +168,7 @@ public class SysDictTypeService : IDynamicApiController, ITransient
var ds = await _sysDictTypeRep.AsQueryable() var ds = await _sysDictTypeRep.AsQueryable()
.InnerJoin<SysDictData>((u, a) => u.Id == a.DictTypeId) .InnerJoin<SysDictData>((u, a) => u.Id == a.DictTypeId)
.Where((u, a) => u.IsDelete == false && a.IsDelete == false && a.Status == StatusEnum.Enable) .Where((u, a) => u.IsDelete == false && a.IsDelete == false && a.Status == StatusEnum.Enable)
.Select((u, a) => new { TypeCode = u.Code, a.Code, a.Name, a.Value, a.Remark, a.OrderNo, a.TagType }) .Select((u, a) => new { TypeCode = u.Code, a.Code, a.Name, a.Value, a.Remark, a.OrderNo, a.TagType, a.ExtData })
.ToListAsync(); .ToListAsync();
return ds.OrderBy(u => u.OrderNo).GroupBy(u => u.TypeCode).ToDictionary(u => u.Key, u => u); return ds.OrderBy(u => u.OrderNo).GroupBy(u => u.TypeCode).ToDictionary(u => u.Key, u => u);
} }

View File

@ -5,7 +5,6 @@
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Aliyun.OSS.Util; using Aliyun.OSS.Util;
using Furion.VirtualFileServer;
using OnceMi.AspNetCore.OSS; using OnceMi.AspNetCore.OSS;
namespace Admin.NET.Core.Service; namespace Admin.NET.Core.Service;
@ -112,7 +111,7 @@ public class SysFileService : IDynamicApiController, ITransient
[DisplayName("根据文件Id或Url下载")] [DisplayName("根据文件Id或Url下载")]
public async Task<IActionResult> DownloadFile(FileInput input) public async Task<IActionResult> DownloadFile(FileInput input)
{ {
var file = input.Id > 0 ? await GetFile(input) : await _sysFileRep.GetFirstAsync(u => u.Url == input.Url); var file = input.Id > 0 ? await GetFile(input) : await _sysFileRep.CopyNew().GetFirstAsync(u => u.Url == input.Url);
var fileName = HttpUtility.UrlEncode(file.FileName, Encoding.GetEncoding("UTF-8")); var fileName = HttpUtility.UrlEncode(file.FileName, Encoding.GetEncoding("UTF-8"));
if (_OSSProviderOptions.IsEnable) if (_OSSProviderOptions.IsEnable)
@ -198,7 +197,7 @@ public class SysFileService : IDynamicApiController, ITransient
} }
else if (App.Configuration["SSHProvider:IsEnable"].ToBoolean()) else if (App.Configuration["SSHProvider:IsEnable"].ToBoolean())
{ {
var sysFile = await _sysFileRep.GetFirstAsync(u => u.Url == url) ?? throw Oops.Oh($"文件不存在"); var sysFile = await _sysFileRep.CopyNew().GetFirstAsync(u => u.Url == url) ?? throw Oops.Oh($"文件不存在");
using (SSHHelper helper = new SSHHelper(App.Configuration["SSHProvider:Host"], using (SSHHelper helper = new SSHHelper(App.Configuration["SSHProvider:Host"],
App.Configuration["SSHProvider:Port"].ToInt(), App.Configuration["SSHProvider:Username"], App.Configuration["SSHProvider:Password"])) App.Configuration["SSHProvider:Port"].ToInt(), App.Configuration["SSHProvider:Username"], App.Configuration["SSHProvider:Password"]))
{ {
@ -207,14 +206,17 @@ public class SysFileService : IDynamicApiController, ITransient
} }
else else
{ {
var sysFile = await _sysFileRep.GetFirstAsync(u => u.Url == url) ?? throw Oops.Oh($"文件不存在"); var sysFile = await _sysFileRep.CopyNew().GetFirstAsync(u => u.Url == url) ?? throw Oops.Oh($"文件不存在");
var filePath = Path.Combine(App.WebHostEnvironment.WebRootPath, sysFile.FilePath); var filePath = Path.Combine(App.WebHostEnvironment.WebRootPath, sysFile.FilePath);
if (!Directory.Exists(filePath)) if (!Directory.Exists(filePath))
Directory.CreateDirectory(filePath); Directory.CreateDirectory(filePath);
var realFile = Path.Combine(filePath, $"{sysFile.Id}{sysFile.Suffix}"); var realFile = Path.Combine(filePath, $"{sysFile.Id}{sysFile.Suffix}");
if (!File.Exists(realFile)) if (!File.Exists(realFile))
throw Oops.Oh($"文件[{realFile}]不在存"); {
Log.Error($"DownloadFileBase64:文件[{realFile}]不存在");
throw Oops.Oh($"文件[{sysFile.FilePath}]不存在");
}
byte[] fileBytes = File.ReadAllBytes(realFile); byte[] fileBytes = File.ReadAllBytes(realFile);
return Convert.ToBase64String(fileBytes); return Convert.ToBase64String(fileBytes);
} }
@ -278,7 +280,7 @@ public class SysFileService : IDynamicApiController, ITransient
/// <returns></returns> /// <returns></returns>
private async Task<SysFile> GetFile([FromQuery] FileInput input) private async Task<SysFile> GetFile([FromQuery] FileInput input)
{ {
var file = await _sysFileRep.GetFirstAsync(u => u.Id == input.Id); var file = await _sysFileRep.CopyNew().GetFirstAsync(u => u.Id == input.Id);
return file ?? throw Oops.Oh(ErrorCodeEnum.D8000); return file ?? throw Oops.Oh(ErrorCodeEnum.D8000);
} }
@ -321,6 +323,8 @@ public class SysFileService : IDynamicApiController, ITransient
// 获取文件后缀 // 获取文件后缀
var suffix = Path.GetExtension(file.FileName).ToLower(); // 后缀 var suffix = Path.GetExtension(file.FileName).ToLower(); // 后缀
if (string.IsNullOrWhiteSpace(suffix))
suffix = string.Concat(".", file.ContentType.AsSpan(file.ContentType.LastIndexOf('/') + 1));
if (!string.IsNullOrWhiteSpace(suffix)) if (!string.IsNullOrWhiteSpace(suffix))
{ {
//var contentTypeProvider = FS.GetFileExtensionContentTypeProvider(); //var contentTypeProvider = FS.GetFileExtensionContentTypeProvider();

View File

@ -4,7 +4,7 @@
<el-card :model="connection"> <el-card :model="connection">
<h1>连接参数(Configuration)</h1> <h1>连接参数(Configuration)</h1>
<el-form label-position="top" :model="connection"> <el-form label-position="top" :model="connection">
<el-row :gutter="20"> <el-row :gutter="6">
<el-col :span="8"> <el-col :span="8">
<el-form-item prop="host" label="协议|主机|端口"> <el-form-item prop="host" label="协议|主机|端口">
<el-input v-model="connection.host" :disabled="connSuccess" type="password" show-password> <el-input v-model="connection.host" :disabled="connSuccess" type="password" show-password>
@ -49,7 +49,6 @@
<el-button <el-button
type="primary" type="primary"
:icon="Setting" :icon="Setting"
size="default"
class="sub-btn" class="sub-btn"
:disabled="client.connected" :disabled="client.connected"
@click="createConnection" @click="createConnection"
@ -58,7 +57,7 @@
> >
{{ client.connected ? '已连接(Connected)' : '连接(Connect)' }} {{ client.connected ? '已连接(Connected)' : '连接(Connect)' }}
</el-button> </el-button>
<el-button v-if="client.connected" type="warning" size="default" :icon="Discount" @click="destroyConnection" :loading="btnLoadingType === 'disconnect'"> 断开(Disconnect) </el-button> <el-button v-if="client.connected" class="sub-btn" type="warning" :icon="Discount" @click="destroyConnection" :loading="btnLoadingType === 'disconnect'"> 断开(Disconnect) </el-button>
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
@ -67,7 +66,7 @@
<el-card shadow="hover"> <el-card shadow="hover">
<h1>订阅(Subscribe)</h1> <h1>订阅(Subscribe)</h1>
<el-form label-position="top" :model="subscription"> <el-form label-position="top" :model="subscription">
<el-row :gutter="20"> <el-row :gutter="6">
<el-col :span="12"> <el-col :span="12">
<el-form-item prop="topic" label="订阅主题(Topic)"> <el-form-item prop="topic" label="订阅主题(Topic)">
<el-input v-model="connection.subTopics" :disabled="subscribedSuccess" type="password" show-password></el-input> <el-input v-model="connection.subTopics" :disabled="subscribedSuccess" type="password" show-password></el-input>
@ -84,7 +83,6 @@
<el-button <el-button
type="primary" type="primary"
:icon="Connection" :icon="Connection"
size="default"
class="sub-btn" class="sub-btn"
:style="{ display: subscribedSuccess ? 'none' : '' }" :style="{ display: subscribedSuccess ? 'none' : '' }"
:loading="btnLoadingType === 'subscribe'" :loading="btnLoadingType === 'subscribe'"
@ -93,16 +91,7 @@
> >
{{ subscribedSuccess ? '已订阅(Subscribed)' : '订阅(Subscribe)' }} {{ subscribedSuccess ? '已订阅(Subscribed)' : '订阅(Subscribe)' }}
</el-button> </el-button>
<el-button <el-button v-if="subscribedSuccess" type="warning" :icon="Discount" class="sub-btn" :loading="btnLoadingType === 'unsubscribe'" :disabled="!client.connected" @click="doUnSubscribe">
v-if="subscribedSuccess"
type="warning"
:icon="Discount"
size="default"
class="sub-btn"
:loading="btnLoadingType === 'unsubscribe'"
:disabled="!client.connected"
@click="doUnSubscribe"
>
取消(Unsubscribe) 取消(Unsubscribe)
</el-button> </el-button>
</el-col> </el-col>
@ -113,7 +102,7 @@
<el-card shadow="hover"> <el-card shadow="hover">
<h1>发布(Publish)</h1> <h1>发布(Publish)</h1>
<el-form label-position="top" :model="publish"> <el-form label-position="top" :model="publish">
<el-row :gutter="30"> <el-row :gutter="6">
<el-col :span="8"> <el-col :span="8">
<el-form-item prop="topic" label="发布主题(Topic)"> <el-form-item prop="topic" label="发布主题(Topic)">
<el-input v-model="connection.pubTopic" type="password" show-password></el-input> <el-input v-model="connection.pubTopic" type="password" show-password></el-input>
@ -136,7 +125,7 @@
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="30"> <el-row :gutter="6">
<el-col :span="16"> <el-col :span="16">
<el-form-item prop="payload" label="操作指令(Payload)"> <el-form-item prop="payload" label="操作指令(Payload)">
<el-input v-model="publish.payload" clearable maxlength="64" show-word-limit> <el-input v-model="publish.payload" clearable maxlength="64" show-word-limit>
@ -158,15 +147,7 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8" class="text-right"> <el-col :span="8" class="text-right">
<el-button <el-button type="success" :icon="Position" class="sub-btn" :loading="btnLoadingType === 'publish'" :disabled="!client.connected" @click="doPublish(publish.payload, connection.pubTopic)">
type="success"
:icon="Position"
size="default"
class="sub-btn"
:loading="btnLoadingType === 'publish'"
:disabled="!client.connected"
@click="doPublish(publish.payload, connection.pubTopic)"
>
发布(Publish) 发布(Publish)
</el-button> </el-button>
</el-col> </el-col>
@ -176,113 +157,104 @@
<el-card shadow="hover"> <el-card shadow="hover">
<h1> <h1>
<el-button @click="clsmsg" type="Success" size="default" :icon="Delete" title="点击清空历史记录">接收(Receive)</el-button> <el-button @click="clsmsg" type="success" :icon="Delete" title="点击清空历史记录">接收(Receive)</el-button>
<el-tag size="default" title="接收次数"> {{ recvnum }}</el-tag> <el-tag title="接收次数"> {{ recvnum }}</el-tag>
<el-tag size="default" :title="dht_tm">{{ dht_wsd }}</el-tag> <el-tag :title="dht_tm">{{ dht_wsd }}</el-tag>
<el-tag size="default" title="设备已工作时长">{{ parseInt(runSeconds) }} </el-tag> <el-tag title="设备已工作时长">{{ parseInt(runSeconds) }} </el-tag>
<el-button <el-button
type="success" type="success"
title="关闭一路" title="关闭一路"
:disabled="!connection.onlineStatus | !client.connected" :disabled="!connection.onlineStatus || !client.connected"
v-if="connection.ch1_Status" v-if="connection.ch1_Status"
icon="ele-Check" icon="ele-Check"
size="default"
id="ch1" id="ch1"
v-preventReClick="2000" v-reclick="2000"
@click="switchLight('55 AA AA AA AA 81 01 00')" @click="switchLight('55 AA AA AA AA 81 01 00')"
>关闭</el-button >关闭</el-button
> >
<el-button <el-button
type="warning" type="warning"
title="打开一路" title="打开一路"
:disabled="!connection.onlineStatus | !client.connected" :disabled="!connection.onlineStatus || !client.connected"
v-else="!connection.ch1_Status" v-else="!connection.ch1_Status"
icon="ele-CloseBold" icon="ele-CloseBold"
size="default"
id="ch1" id="ch1"
v-preventReClick="2000" v-reclick="2000"
@click="switchLight('55 AA AA AA AA 81 01 01')" @click="switchLight('55 AA AA AA AA 81 01 01')"
>打开</el-button >打开</el-button
> >
<el-button <el-button
type="success" type="success"
title="关闭二路" title="关闭二路"
:disabled="!connection.onlineStatus | !client.connected" :disabled="!connection.onlineStatus || !client.connected"
v-if="connection.ch2_Status" v-if="connection.ch2_Status"
icon="ele-Check" icon="ele-Check"
size="default"
id="ch2" id="ch2"
v-preventReClick="2000" v-reclick="2000"
@click="switchLight('55 AA AA AA AA 81 02 00')" @click="switchLight('55 AA AA AA AA 81 02 00')"
>关闭</el-button >关闭</el-button
> >
<el-button <el-button
type="warning" type="warning"
title="打开二路" title="打开二路"
:disabled="!connection.onlineStatus | !client.connected" :disabled="!connection.onlineStatus || !client.connected"
v-else="!connection.ch2_Status" v-else="!connection.ch2_Status"
icon="ele-CloseBold" icon="ele-CloseBold"
size="default"
id="ch2" id="ch2"
v-preventReClick="2000" v-reclick="2000"
@click="switchLight('55 AA AA AA AA 81 02 01')" @click="switchLight('55 AA AA AA AA 81 02 01')"
>打开</el-button >打开</el-button
> >
<el-button <el-button
type="success" type="success"
title="关闭三路" title="关闭三路"
:disabled="!connection.onlineStatus | !client.connected" :disabled="!connection.onlineStatus || !client.connected"
v-if="connection.ch3_Status" v-if="connection.ch3_Status"
icon="ele-Check" icon="ele-Check"
size="default"
id="ch3" id="ch3"
v-preventReClick="2000" v-reclick="2000"
@click="switchLight('55 AA AA AA AA 81 03 00')" @click="switchLight('55 AA AA AA AA 81 03 00')"
>关闭</el-button >关闭</el-button
> >
<el-button <el-button
type="warning" type="warning"
title="打开三路" title="打开三路"
:disabled="!connection.onlineStatus | !client.connected" :disabled="!connection.onlineStatus || !client.connected"
v-else="!connection.ch3_Status" v-else="!connection.ch3_Status"
icon="ele-CloseBold" icon="ele-CloseBold"
size="default"
id="ch3" id="ch3"
v-preventReClick="2000" v-reclick="2000"
@click="switchLight('55 AA AA AA AA 81 03 01')" @click="switchLight('55 AA AA AA AA 81 03 01')"
>打开</el-button >打开</el-button
> >
<el-button <el-button
type="success" type="success"
title="关闭四路" title="关闭四路"
:disabled="!connection.onlineStatus | !client.connected" :disabled="!connection.onlineStatus || !client.connected"
v-if="connection.ch4_Status" v-if="connection.ch4_Status"
icon="ele-Check" icon="ele-Check"
size="default"
id="ch4" id="ch4"
v-preventReClick="2000" v-reclick="2000"
@click="switchLight('55 AA AA AA AA 81 04 00')" @click="switchLight('55 AA AA AA AA 81 04 00')"
>关闭</el-button >关闭</el-button
> >
<el-button <el-button
type="warning" type="warning"
title="打开四路" title="打开四路"
:disabled="!connection.onlineStatus | !client.connected" :disabled="!connection.onlineStatus || !client.connected"
v-else="!connection.ch4_Status" v-else="!connection.ch4_Status"
icon="ele-CloseBold" icon="ele-CloseBold"
size="default"
id="ch4" id="ch4"
v-preventReClick="2000" v-reclick="2000"
@click="switchLight('55 AA AA AA AA 81 04 01')" @click="switchLight('55 AA AA AA AA 81 04 01')"
>打开</el-button >打开</el-button
> >
<el-button <el-button
type="danger" type="danger"
title="四路全部关闭" title="四路全部关闭"
:disabled="!connection.onlineStatus | !client.connected" :disabled="!connection.onlineStatus || !client.connected"
v-if="connection.all_Status" v-if="connection.all_Status"
icon="ele-SwitchButton" icon="ele-SwitchButton"
size="default"
id="ch5" id="ch5"
@click="switchLight('55 AA AA AA AA 81 A4 00')" @click="switchLight('55 AA AA AA AA 81 A4 00')"
>全关</el-button >全关</el-button
@ -290,16 +262,15 @@
<el-button <el-button
type="success" type="success"
title="四路全部打开" title="四路全部打开"
:disabled="!connection.onlineStatus | !client.connected" :disabled="!connection.onlineStatus || !client.connected"
v-else="!connection.all_Status" v-else="!connection.all_Status"
icon="ele-Switch" icon="ele-Switch"
size="default"
id="ch5" id="ch5"
@click="switchLight('55 AA AA AA AA 81 A4 01')" @click="switchLight('55 AA AA AA AA 81 A4 01')"
>全开</el-button >全开</el-button
> >
<el-alert v-if="!client.connected || !connection.onlineStatus" title="网络服务断开或设备离线!" center type="warning" effect="light" /> <el-alert v-if="!client.connected || !connection.onlineStatus" title="网络服务断开或设备离线!" center type="warning" effect="light" style="margin-top: 4px" />
</h1> </h1>
<!-- 绑定接收日志只读 --> <!-- 绑定接收日志只读 -->
<el-col :span="24"> <el-col :span="24">
@ -347,7 +318,7 @@ const retryTimes = ref(0); //重连次数
* ws -> 8083; wss -> 8084 * ws -> 8083; wss -> 8084
* By default, EMQX allows clients to connect without authentication. * By default, EMQX allows clients to connect without authentication.
* https://docs.emqx.com/en/enterprise/v4.4/advanced/auth.html#anonymous-login * https://docs.emqx.com/en/enterprise/v4.4/advanced/auth.html#anonymous-login
* for more options and details, please refer to https://github.com/mqttjs/MQTT.js#mqttclientstreambuilder-options * for more options and details, please refer to https://github.com/mqttjs/MQTT.js#mqttclientstreambuilder-options
*/ */
const connection = reactive({ const connection = reactive({
@ -748,20 +719,19 @@ const clsmsg = () => {
<style lang="scss" scoped> <style lang="scss" scoped>
.mqtt-box { .mqtt-box {
max-width: 100%; max-width: 100%;
padding: 4px; margin: 0 auto;
margin: 10px auto 0 auto;
} }
.header { .header {
font-size: 24px; font-size: 24px;
font-weight: bold; font-weight: bold;
margin: -12px auto 8px auto; margin: -6px auto 0px auto;
} }
h1 { h1 {
font-size: 16px; font-size: 16px;
margin-top: 10px auto 20px auto; margin-top: 10px auto 20px auto;
padding: 5px 0px 5px 0; padding: 6px 0px 6px 0;
} }
.el-col { .el-col {
@ -772,7 +742,7 @@ h1 {
font-size: 13px; font-size: 13px;
} }
.el-card { .el-card {
margin-bottom: 12px; margin-bottom: 6px;
} }
.el-card__body { .el-card__body {
padding: 24px; padding: 24px;

View File

@ -32,7 +32,11 @@
<el-button-group style="padding-left: 12px; padding-right: 12px"> <el-button-group style="padding-left: 12px; padding-right: 12px">
<el-button icon="ele-Plus" @click="showAddColumn"> 增加列 </el-button> <el-button icon="ele-Plus" @click="showAddColumn"> 增加列 </el-button>
<el-button icon="ele-Plus" @click="showGenDialog"> 生成实体 </el-button> <el-button icon="ele-Plus" @click="showGenDialog"> 生成实体 </el-button>
<el-button icon="ele-Plus" @click="showGenSeedDataDialog"> 生成种子 </el-button> <el-popover placement="bottom" title="温馨提示" :width="200" trigger="hover" content="如果是刚刚生成的实体,请重启服务后再生成种子">
<template #reference>
<el-button icon="ele-Plus" @click="showGenSeedDataDialog"> 生成种子 </el-button>
</template>
</el-popover>
</el-button-group> </el-button-group>
<el-button icon="ele-View" type="primary" @click="visualTable" plain> 可视化 </el-button> <el-button icon="ele-View" type="primary" @click="visualTable" plain> 可视化 </el-button>
</template> </template>