Beta:发布v2.7.5测试版本 (#1896)
* 生产环境时移除console * 更新第三方库道最新版本,修正导致的兼容问题 * feat: 版本号变更,修复自动化历史的结构体描述 * feat: 放弃element的按需引用,增加自定义表单组件,替换原始的iframe引入模式。 * feat: 放开表单生成器的key输入 * feat: 自动化代码关联属性支持跨数据库关联 * fixed: 修复跨库关联模板 * feat: 允许清空跨数据关联的业务库选项 * feat: 增加用户搜索功能 * feat: 允许单条API同步 --------- Co-authored-by: task <121913992@qq.com> Co-authored-by: task <ms.yangdan@gmail.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gin-vue-admin",
|
||||
"version": "2.7.4",
|
||||
"version": "2.7.5",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "node openDocument.js && vite --host --mode development",
|
||||
@@ -11,6 +11,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@form-create/designer": "^3.2.6",
|
||||
"@form-create/element-ui": "^3.2.10",
|
||||
"@vue-office/docx": "^1.6.2",
|
||||
"@vue-office/excel": "^1.7.11",
|
||||
"@vue-office/pdf": "^2.0.2",
|
||||
@@ -22,7 +24,7 @@
|
||||
"core-js": "^3.38.1",
|
||||
"default-passive-events": "^2.0.0",
|
||||
"echarts": "5.5.1",
|
||||
"element-plus": "^2.8.1",
|
||||
"element-plus": "^2.8.4",
|
||||
"highlight.js": "^11.10.0",
|
||||
"js-cookie": "^3.0.5",
|
||||
"marked": "14.1.1",
|
||||
@@ -36,6 +38,7 @@
|
||||
"sortablejs": "^1.15.3",
|
||||
"spark-md5": "^3.0.2",
|
||||
"tailwindcss": "^3.4.10",
|
||||
"vform3-builds": "^3.0.10",
|
||||
"vite-auto-import-svg": "^1.1.0",
|
||||
"vue": "^3.5.7",
|
||||
"vue-echarts": "^7.0.3",
|
||||
@@ -59,8 +62,6 @@
|
||||
"eslint-plugin-vue": "^9.28.0",
|
||||
"sass": "^1.78.0",
|
||||
"terser": "^5.31.6",
|
||||
"unplugin-auto-import": "^0.18.2",
|
||||
"unplugin-vue-components": "^0.27.4",
|
||||
"vite": "^5.4.3",
|
||||
"vite-plugin-banner": "^0.8.0",
|
||||
"vite-plugin-importer": "^0.2.5",
|
||||
|
@@ -8,8 +8,6 @@
|
||||
|
||||
<script setup>
|
||||
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
|
||||
// element 2.3.8之前使用下面的语句
|
||||
// import zhCn from 'element-plus/lib/locale/lang/zh-cn'
|
||||
import {useAppStore} from "@/pinia";
|
||||
useAppStore()
|
||||
defineOptions({
|
||||
|
@@ -13,7 +13,7 @@ const config = {
|
||||
export const viteLogo = (env) => {
|
||||
if (config.showViteLogo) {
|
||||
console.log(greenText(`> 欢迎使用Gin-Vue-Admin,开源地址:https://github.com/flipped-aurora/gin-vue-admin`));
|
||||
console.log(greenText(`> 当前版本:v2.7.4`));
|
||||
console.log(greenText(`> 当前版本:v2.7.5`));
|
||||
console.log(greenText(`> 加群方式:微信:shouzi_1994 QQ群:470239250`));
|
||||
console.log(greenText(`> 项目地址:https://github.com/flipped-aurora/gin-vue-admin`));
|
||||
console.log(greenText(`> 插件市场:https://plugin.gin-vue-admin.com`));
|
||||
|
@@ -10,7 +10,7 @@ export default {
|
||||
register(app)
|
||||
console.log(`
|
||||
欢迎使用 Gin-Vue-Admin
|
||||
当前版本:v2.7.4
|
||||
当前版本:v2.7.5
|
||||
加群方式:微信:shouzi_1994 QQ群:622360840
|
||||
项目地址:https://github.com/flipped-aurora/gin-vue-admin
|
||||
插件市场:https://plugin.gin-vue-admin.com
|
||||
|
@@ -1,11 +1,8 @@
|
||||
import 'element-plus/es/components/message/style/css'
|
||||
import 'element-plus/es/components/loading/style/css'
|
||||
import 'element-plus/es/components/notification/style/css'
|
||||
import 'element-plus/es/components/message-box/style/css'
|
||||
import 'element-plus/theme-chalk/dark/css-vars.css'
|
||||
import './style/element_visiable.scss'
|
||||
|
||||
import { createApp } from 'vue'
|
||||
import ElementPlus from 'element-plus'
|
||||
|
||||
import 'element-plus/dist/index.css'
|
||||
// 引入gin-vue-admin前端初始化相关内容
|
||||
import './core/gin-vue-admin'
|
||||
// 引入封装的router
|
||||
@@ -23,6 +20,7 @@ app.config.productionTip = false
|
||||
|
||||
app
|
||||
.use(run)
|
||||
.use(ElementPlus)
|
||||
.use(store)
|
||||
.use(auth)
|
||||
.use(router)
|
||||
|
@@ -163,7 +163,6 @@
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="edit"
|
||||
|
||||
type="primary"
|
||||
link
|
||||
@click="editApiFunc(scope.row)"
|
||||
@@ -172,7 +171,6 @@
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="delete"
|
||||
|
||||
type="primary"
|
||||
link
|
||||
@click="deleteApiFunc(scope.row)"
|
||||
@@ -282,7 +280,10 @@
|
||||
fixed="right"
|
||||
>
|
||||
<template #default="{row}">
|
||||
<el-button type="primary" text @click="ignoreApiFunc(row,true)">
|
||||
<el-button icon="plus" type="primary" link @click="addApiFunc(row)">
|
||||
单条新增
|
||||
</el-button>
|
||||
<el-button icon="sunrise" type="primary" link @click="ignoreApiFunc(row,true)">
|
||||
忽略
|
||||
</el-button>
|
||||
</template>
|
||||
@@ -365,7 +366,7 @@
|
||||
fixed="right"
|
||||
>
|
||||
<template #default="{row}">
|
||||
<el-button type="primary" text @click="ignoreApiFunc(row,false)">
|
||||
<el-button icon="sunny" type="primary" link @click="ignoreApiFunc(row,false)">
|
||||
取消忽略
|
||||
</el-button>
|
||||
</template>
|
||||
@@ -568,14 +569,49 @@ const ignoreApiFunc = async (row,flag) =>{
|
||||
}
|
||||
}
|
||||
|
||||
const addApiFunc = async(row)=>{
|
||||
if(!row.apiGroup){
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '请先选择API分组'
|
||||
})
|
||||
return
|
||||
}
|
||||
if(!row.description){
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '请先填写API描述'
|
||||
})
|
||||
return
|
||||
}
|
||||
const res = await createApi(row)
|
||||
if (res.code === 0) {
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '添加成功',
|
||||
showClose: true
|
||||
})
|
||||
syncApiData.value.newApis = syncApiData.value.newApis.filter(item => !(item.path === row.path && item.method === row.method))
|
||||
}
|
||||
getTableData()
|
||||
getGroup()
|
||||
}
|
||||
|
||||
const closeSyncDialog = () => {
|
||||
syncApiFlag.value = false
|
||||
}
|
||||
|
||||
const syncing = ref(false)
|
||||
|
||||
|
||||
const enterSyncDialog = async() => {
|
||||
if( syncApiData.value.newApis.some(item => !item.apiGroup || !item.description)){
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '存在API未分组或未填写描述'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
syncing.value = true
|
||||
const res = await enterSyncApi(syncApiData.value)
|
||||
syncing.value = false
|
||||
|
@@ -1,6 +1,53 @@
|
||||
<template>
|
||||
<div>
|
||||
<warning-bar title="注:右上角头像下拉可切换角色" />
|
||||
<div class="gva-search-box">
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:inline="true"
|
||||
:model="searchInfo"
|
||||
>
|
||||
<el-form-item label="用户名">
|
||||
<el-input
|
||||
v-model="searchInfo.username"
|
||||
placeholder="用户名"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="昵称">
|
||||
<el-input
|
||||
v-model="searchInfo.nickname"
|
||||
placeholder="昵称"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号">
|
||||
<el-input
|
||||
v-model="searchInfo.phone"
|
||||
placeholder="手机号"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱">
|
||||
<el-input
|
||||
v-model="searchInfo.email"
|
||||
placeholder="邮箱"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="search"
|
||||
@click="onSubmit"
|
||||
>
|
||||
查询
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="refresh"
|
||||
@click="onReset"
|
||||
>
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="gva-table-box">
|
||||
<div class="gva-btn-list">
|
||||
<el-button
|
||||
@@ -246,7 +293,27 @@ defineOptions({
|
||||
name: 'User',
|
||||
})
|
||||
|
||||
const path = ref(import.meta.env.VITE_BASE_API + '/')
|
||||
const searchInfo = ref({
|
||||
username: '',
|
||||
nickname: '',
|
||||
phone: '',
|
||||
email: ''
|
||||
})
|
||||
|
||||
const onSubmit = () => {
|
||||
page.value = 1
|
||||
getTableData()
|
||||
}
|
||||
|
||||
const onReset = () => {
|
||||
searchInfo.value = {
|
||||
username: '',
|
||||
nickname: '',
|
||||
phone: '',
|
||||
email: ''
|
||||
}
|
||||
getTableData()
|
||||
}
|
||||
// 初始化相关
|
||||
const setAuthorityOptions = (AuthorityData, optionsData) => {
|
||||
AuthorityData &&
|
||||
@@ -286,7 +353,7 @@ const handleCurrentChange = (val) => {
|
||||
|
||||
// 查询
|
||||
const getTableData = async() => {
|
||||
const table = await getUserList({ page: page.value, pageSize: pageSize.value })
|
||||
const table = await getUserList({ page: page.value, pageSize: pageSize.value, ...searchInfo.value })
|
||||
if (table.code === 0) {
|
||||
tableData.value = table.data.list
|
||||
total.value = table.data.total
|
||||
@@ -341,11 +408,6 @@ const setAuthorityIds = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const chooseImg = ref(null)
|
||||
const openHeaderChange = () => {
|
||||
chooseImg.value.open()
|
||||
}
|
||||
|
||||
const authOptions = ref([])
|
||||
const setOptions = (authData) => {
|
||||
authOptions.value = []
|
||||
|
@@ -193,7 +193,30 @@
|
||||
>
|
||||
<el-row :gutter="8">
|
||||
<el-col
|
||||
:span="3"
|
||||
:span="4"
|
||||
>
|
||||
<el-select
|
||||
v-model="middleDate.dataSource.dbName"
|
||||
placeholder="数据库【不填则为GVA库】"
|
||||
@change="dbNameChange"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in dbList"
|
||||
:key="item.aliasName"
|
||||
:value="item.aliasName"
|
||||
:label="item.aliasName"
|
||||
:disabled="item.disable"
|
||||
>
|
||||
<div>
|
||||
<span>{{ item.aliasName }}</span>
|
||||
<span style="float:right;color:#8492a6;font-size:13px">{{ item.dbName }}</span>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="4"
|
||||
>
|
||||
<el-select
|
||||
v-model="middleDate.dataSource.association"
|
||||
@@ -210,8 +233,7 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="7">
|
||||
<el-col :span="5">
|
||||
<el-select
|
||||
v-model="middleDate.dataSource.table" placeholder="请选择数据源表"
|
||||
filterable allow-create @focus="getDBTableList" @change="selectDB"
|
||||
@@ -221,9 +243,8 @@
|
||||
:value="item.tableName"
|
||||
/>
|
||||
</el-select>
|
||||
<!-- <el-input v-model="middleDate.dataSource.table" placeholder="数据源表" /> -->
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-col :span="5">
|
||||
<el-select v-model="middleDate.dataSource.value" placeholder="请先选择需要存储的数据">
|
||||
<template #label="{ value }">
|
||||
<span>存储: </span>
|
||||
@@ -245,9 +266,8 @@
|
||||
</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<!-- <el-input v-model="middleDate.dataSource.value" placeholder="存储用字段" /> -->
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-col :span="5">
|
||||
<el-select v-model="middleDate.dataSource.label" placeholder="请先选择需要展示的数据">
|
||||
<template #label="{ value }">
|
||||
<span>展示: </span>
|
||||
@@ -283,7 +303,7 @@ import { getSysDictionaryList } from '@/api/sysDictionary'
|
||||
import WarningBar from '@/components/warningBar/warningBar.vue'
|
||||
import { ref,onMounted } from 'vue'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import {getColumn, getTable} from "@/api/autoCode";
|
||||
import {getColumn, getDB, getTable} from "@/api/autoCode";
|
||||
|
||||
defineOptions({
|
||||
name: 'FieldDialog'
|
||||
@@ -321,6 +341,15 @@ const activeNames = ref([])
|
||||
const middleDate = ref({})
|
||||
const dictOptions = ref([])
|
||||
|
||||
const dbList = ref([])
|
||||
|
||||
const getDbFunc = async() => {
|
||||
const res = await getDB()
|
||||
if (res.code === 0) {
|
||||
dbList.value = res.data.dbList
|
||||
}
|
||||
}
|
||||
|
||||
const validateDataTypeLong = (rule, value, callback) => {
|
||||
const regex = /^('([^']*)'(?:,'([^']+)'*)*)$/;
|
||||
if (middleDate.value.fieldType == "enum" && !regex.test(value)) {
|
||||
@@ -403,11 +432,18 @@ const associationChange = (val) => {
|
||||
}
|
||||
|
||||
|
||||
const dbNameChange = () => {
|
||||
getDBTableList()
|
||||
middleDate.value.dataSource.table = ''
|
||||
middleDate.value.dataSource.value = ''
|
||||
middleDate.value.dataSource.label = ''
|
||||
}
|
||||
|
||||
|
||||
const dbTableList = ref([])
|
||||
|
||||
const getDBTableList = async () => {
|
||||
const res = await getTable()
|
||||
console.log(res);
|
||||
const res = await getTable({ businessDB: middleDate.value.dataSource.dbName })
|
||||
if (res.code === 0) {
|
||||
let list = res.data.tables; // 确保这里正确获取到 tables 数组
|
||||
dbTableList.value = list.map(item => ({
|
||||
@@ -415,12 +451,15 @@ const getDBTableList = async () => {
|
||||
value: item.tableName // 这里假设 value 也是 tableName,如果不同请调整
|
||||
}));
|
||||
}
|
||||
middleDate.value.dataSource.value = ''
|
||||
middleDate.value.dataSource.label = ''
|
||||
}
|
||||
|
||||
const dbColumnList = ref([])
|
||||
const selectDB = async (val) => {
|
||||
middleDate.value.dataSource.table = val
|
||||
const res = await getColumn({
|
||||
businessDB: middleDate.value.dataSource.dbName,
|
||||
tableName: val
|
||||
})
|
||||
|
||||
@@ -445,6 +484,7 @@ const fieldDialogForm = ref(null)
|
||||
defineExpose({ fieldDialogForm })
|
||||
|
||||
onMounted(()=>{
|
||||
getDbFunc()
|
||||
if(middleDate.value.dataSource.table){
|
||||
selectDB(middleDate.value.dataSource.table)
|
||||
}
|
||||
|
@@ -26,7 +26,7 @@
|
||||
align="left"
|
||||
label="结构体描述"
|
||||
min-width="150"
|
||||
prop="structCNName"
|
||||
prop="description"
|
||||
/>
|
||||
<el-table-column
|
||||
align="left"
|
||||
|
@@ -1,19 +1,20 @@
|
||||
<template>
|
||||
<div style="height:80vh">
|
||||
<iframe
|
||||
width="100%"
|
||||
height="100%"
|
||||
:src="`${basePath}:${basePort}/form-generator/#/`"
|
||||
frameborder="0"
|
||||
/>
|
||||
</div>
|
||||
<fc-designer ref="designer" :config="config" height="calc(100vh - 160px)" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
const basePath = ref(import.meta.env.VITE_BASE_PATH)
|
||||
const basePort = ref(import.meta.env.VITE_SERVER_PORT)
|
||||
|
||||
import {ref} from "vue";
|
||||
import FcDesigner from '@form-create/designer'
|
||||
|
||||
defineOptions({
|
||||
name: 'FormGenerator'
|
||||
})
|
||||
|
||||
const designer = ref(null)
|
||||
|
||||
const config = {
|
||||
fieldReadonly: false
|
||||
}
|
||||
|
||||
</script>
|
||||
|
@@ -1,7 +1,4 @@
|
||||
import legacyPlugin from '@vitejs/plugin-legacy'
|
||||
import AutoImport from 'unplugin-auto-import/vite'
|
||||
import Components from 'unplugin-vue-components/vite'
|
||||
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
|
||||
import { viteLogo } from './src/core/config'
|
||||
import Banner from 'vite-plugin-banner'
|
||||
import * as path from 'path'
|
||||
@@ -9,7 +6,6 @@ import * as dotenv from 'dotenv'
|
||||
import * as fs from 'fs'
|
||||
import vuePlugin from '@vitejs/plugin-vue'
|
||||
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||
import fullImportPlugin from './vitePlugin/fullImport/fullImport.js'
|
||||
import VueFilePathPlugin from './vitePlugin/componentName/index.js'
|
||||
import { svgBuilder } from 'vite-auto-import-svg'
|
||||
import { AddSecret } from './vitePlugin/secret'
|
||||
@@ -101,28 +97,6 @@ export default ({
|
||||
[Banner(`\n Build based on gin-vue-admin \n Time : ${timestamp}`)],
|
||||
VueFilePathPlugin("./src/pathInfo.json")
|
||||
],
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
additionalData: `@use "@/style/element/index.scss" as *;`,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
if (NODE_ENV === 'development') {
|
||||
config.plugins.push(
|
||||
fullImportPlugin()
|
||||
)
|
||||
} else {
|
||||
config.plugins.push(AutoImport({
|
||||
resolvers: [ElementPlusResolver()]
|
||||
}),
|
||||
Components({
|
||||
resolvers: [ElementPlusResolver({
|
||||
importStyle: 'sass'
|
||||
})]
|
||||
}))
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
@@ -1,23 +0,0 @@
|
||||
import * as path from 'path'
|
||||
export default function fullImportPlugin() {
|
||||
let config
|
||||
return {
|
||||
name: 'fullImportElementPlus',
|
||||
async configResolved(conf) {
|
||||
config = conf
|
||||
},
|
||||
transform(code, id) {
|
||||
const sourcePath = path.join(config.root, 'src/main.js').split(path.sep).join('/')
|
||||
const targetPath = id.split(path.sep).join('/')
|
||||
if (sourcePath === targetPath) {
|
||||
const name = 'ElementPlus'
|
||||
// 引入 ElementPlus 和 样式
|
||||
code = code.replace(/import\s*{\s*createApp\s*}\s*from\s*['"]vue['"]/, ($1) => $1 + `\nimport ${name} from 'element-plus'`)
|
||||
code = code.replace(/import\s*['"]\.\/style\/element_visiable\.scss['"]/, ($1) => $1 + `\nimport 'element-plus/theme-chalk/src/index.scss'`)
|
||||
code = code.replace(/\.mount\(/, ($1) => `.use(${name})` + $1)
|
||||
return code
|
||||
}
|
||||
return code
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user