Signed-off-by: 1iyc <5212514+liycone@user.noreply.gitee.com>
main
1iyc 3 days ago
parent 8092217e8a
commit 0b866ed102

@ -48,6 +48,7 @@
"js-beautify": "1.13.0",
"js-cookie": "3.0.1",
"jsencrypt": "3.0.0-rc.1",
"micromatch": "^4.0.8",
"nprogress": "0.2.0",
"quill": "2.0.2",
"screenfull": "5.0.2",

@ -0,0 +1,27 @@
import request from "@/utils/request";
export function getNav(query) {
return request({
url: '/gather/nav',
method: 'get',
params: query
})
}
export function getTasks(queryParams) {
return request({
url: '/gather/task/page/',
method: 'GET',
params: queryParams,
});
}
export function getDataList(dataSource, queryParams) {
return request({
url: '/kis/supplier/list/' + dataSource,
method: 'GET',
params: queryParams,
});
}

@ -1,81 +1,90 @@
<template>
<div class="container">
<div class="app-container">
<el-row :gutter="10">
<el-col :span="3">
<el-card class="full-height">
<el-card style="height: calc(100vh - 125px)">
<div slot="header">
<span> <el-button type="text" size="small" @click="showDialog('add')"></el-button></span>
<span><el-button type="text" size="small" @click="showDialog('add')"></el-button></span>
</div>
<el-menu
:default-active="activeTab"
@select="handleSelect"
default-active="2"
style="overflow:auto"
:default-active="active"
@select="onSelect"
mode="horizontal"
>
<el-menu-item v-for="(tab, index) in tabs" :key="index" :index="index.toString()">
<span>{{ tab.title }}</span>
<el-menu-item v-for="(tab, index) in tabs"
:key="index"
:index="index.toString()"
>
<span>{{ tab.title }}{{ index }}</span>
</el-menu-item>
</el-menu>
</el-card>
</el-col>
<!-- -->
<el-col :span="20">
<el-card class="full-height">
<el-tabs v-model="activeTab" type="card" closable @tab-remove="removeTab" size="small">
<el-tab-pane v-for="(tab, index) in tabs" :key="index" :label="tab.title" :name="index.toString()">
<el-card style="height: calc(100vh - 125px)">
<el-tabs v-model="active"
type="card"
closable
@tab-remove="removeTab"
size="small"
@tab-click="onClick"
>
<el-tab-pane v-for="(tab, index) in tabs"
:key="index"
:label="tab.title"
:name="index.toString()"
>
<el-button type="text" @click.stop="showDialog('edit', index)">修改</el-button>
<el-button type="text" @click.stop="disconnectTab(index)">断开</el-button>
<el-button type="text" @click.stop="disconnectTab(index)">打开</el-button>
<el-table v-loading="false"
:data="tableList"
highlight-current-row
style="width: 100%"
<el-table
:data="tableData"
highlight-current-row
style="width: 100%"
v-loading="loading"
>
<el-table-column type="selection" align="center" width="55"></el-table-column>
<el-table-column label="序号" type="index" width="50" align="center">
<el-table-column label="序号" type="index" width="80" align="center">
<template slot-scope="scope">
<span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}</span>
</template>
</el-table-column>
<el-table-column
label="表名称"
align="center"
prop="ffullName"
:show-overflow-tooltip="true"
width="120"
/>
<el-table-column
label="表名称"
align="center"
prop="fname"
:show-overflow-tooltip="true"
width="120"
/>
<el-table-column
label="表描述"
align="center"
prop="fhelpCode"
:show-overflow-tooltip="true"
width="120"
/>
</el-table>
v-for="(column, index) in columns"
:prop="column.key"
:label="column.title"
:width="column.width"
:align="column.align"
:show-overflow-tooltip="column.tooltip"
>
<pagination
v-show="true"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
<pagination
v-show="true"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
:page-sizes="[2,5,10]"
@pagination="getList"
/>
</el-card>
</el-col>
</el-row>
<el-dialog
:visible.sync="dialogVisible"
:title="dialogTitle"
@ -118,36 +127,41 @@
<script>
import request from "@/utils/request";
export default {
props: {
name: 'TabComponent',
initialTabs: {
initMenuItem: {
type: Array,
default: () => []
},
reqFun: {
callBackSelect: {
type: Function,
default: () => ({})
},
initColumns: {
type: Array,
default: () => []
},
initTableData: {
type: Array,
default: () => []
},
initActive: {
type: String,
default: '0'
}
},
}
,
data() {
return {
activeTab: '0',
tabs: this.initialTabs.map(tab => ({
title: tab.title || '',
name: tab.name || '',
dbType: tab.dbType || '',
url: tab.url || '',
username: tab.username || '',
password: tab.password || '',
driverClassName: tab.driverClassName || ''
})),
requestFun: this.reqFun,
active: this.initActive,
tabs: this.initMenuItem,
columns: this.initColumns,
tableData: this.initTableData,
loading: false,
dialogVisible: false,
dialogTitle: '',
activeTabData: {},
currentTabData: {
title: '',
name: '',
@ -158,15 +172,47 @@ export default {
driverClassName: ''
},
currentTabIndex: null,
tableList: [],
total: 0,
queryParams: {
pageNum: 1,
pageSize: 10
},
}
},
}
,
mounted() {
// console.log(JSON.stringify(this.initMenuItem))
// console.log(JSON.stringify(this.columns))
}
,
methods: {
/* 选中菜单 */
onSelect(index) {
this.active = index
this.loading = true
this.callBackSelect(this.active, this.queryParams)
this.loading = false
},
/* tabs 单击实践 */
onClick(tab) {
this.active = tab.name;
this.loading = true
this.callBackSelect(this.active, this.queryParams)
this.loading = false
},
/* 加载表格数据*/
loadTableData(tableData, total) {
this.tableData = tableData;
this.total = total;
},
getList() {
this.callBackSelect(this.active, this.queryParams)
},
showDialog(mode, index = null) {
this.dialogTitle = mode === 'add' ? '新建标签页' : '修改标签页';
this.currentTabIndex = index;
@ -174,19 +220,20 @@ export default {
this.currentTabData = {...this.tabs[index]};
} else {
this.currentTabData = {
title: '1',
name: '1',
dbType: '1',
url: '1',
username: '1',
password: '1',
driverClassName: '1'
title: '',
name: '',
dbType: '',
url: '',
username: '',
password: '',
driverClassName: ''
};
}
this.dialogVisible = true;
},
}
,
submit() {
this.$refs.form.validate((valid) => {
/*this.$refs.form.validate((valid) => {
if (valid) {
if (this.currentTabIndex !== null) {
this.tabs[this.currentTabIndex] = {...this.currentTabData};
@ -202,24 +249,28 @@ export default {
this.$message.error(errors.join(''));
return false;
}
});
},
});*/
}
,
cancel() {
this.dialogVisible = false;
this.$refs.form.resetFields();
},
}
,
removeTab(index) {
this.tabs.splice(index, 1);
if (this.activeTab === index.toString()) {
this.activeTab = Math.max(0, index - 1).toString();
}
},
handleSelect(index) {
this.activeTab = index;
},
}
,
disconnectTab(index) {
console.log(`断开标签页 ${index}`);
},
}
,
handleClose(done, event) {
if (typeof done === 'function') {
this.$confirm('确认关闭?')
@ -232,41 +283,10 @@ export default {
} else {
this.dialogVisible = false;
}
},
getActiveTab() {
const currentTabIndex = parseInt(this.activeTab);
this.activeTabData = this.tabs[currentTabIndex];
},
getList() {
request({
url: '/kis/supplier/list/' + this.activeTabData.name,
method: 'GET',
params: this.queryParams,
}).then(response => {
this.tableList = response.rows;
this.total = response.total;
})
}
},
created() {
this.getActiveTab();
},
mounted() {
this.getList();
}
};
</script>
,
<style scoped>
.container {
padding: 20px;
}
.full-height {
height: calc(100vh - 125px);
display: flex;
flex-direction: column;
}
}
</style>
</script>

@ -0,0 +1,22 @@
import micromatch from "micromatch";
/**
* 全局配置文件
*/
export default {
// 白名单
whitelist(url) {
const excludeUrl = [
"/login",
"/getInfo",
"/getRouters",
"/getUploadLogoUrl",
"/register",
"/*/page",
"/*/list",
"/release/download/*",
];
const result = micromatch(url, excludeUrl, {}).length > 0;
return result;
},
};

@ -12,13 +12,13 @@ import store from './store'
import router from './router'
import directive from './directive' // directive
import plugins from './plugins' // plugins
import { download } from '@/utils/request'
import {download} from '@/utils/request'
import './assets/icons' // icon
import './permission' // permission control
import { getDicts } from "@/api/system/dict/data";
import { getConfigKey } from "@/api/system/config";
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi";
import {getDicts} from "@/api/system/dict/data";
import {getConfigKey} from "@/api/system/config";
import {addDateRange, handleTree, parseTime, resetForm, selectDictLabel, selectDictLabels} from "@/utils/ruoyi";
// 分页组件
import Pagination from "@/components/Pagination";
// 自定义表格工具组件
@ -39,8 +39,11 @@ import VueMeta from 'vue-meta'
import DictData from '@/components/DictData'
// tab组件
import TabComponent from '@/components/TabComponent'
//
import webSite from "@/config/website";
// 全局方法挂载
Vue.prototype.website = webSite;
Vue.prototype.getDicts = getDicts
Vue.prototype.getConfigKey = getConfigKey
Vue.prototype.parseTime = parseTime

@ -1,15 +1,18 @@
import axios from 'axios'
import { Notification, MessageBox, Message, Loading } from 'element-ui'
import {Loading, Message, MessageBox, Notification} from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import {getToken} from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from "@/utils/ruoyi";
import {blobValidate, tansParams} from "@/utils/ruoyi";
import cache from '@/plugins/cache'
import { saveAs } from 'file-saver'
import {saveAs} from 'file-saver'
import Website from "@/config/website";
let downloadLoadingInstance;
let globalLoadingInstance;
// 是否显示重新登录
export let isRelogin = { show: false };
export let isRelogin = {show: false};
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
@ -22,6 +25,15 @@ const service = axios.create({
// request拦截器
service.interceptors.request.use(config => {
const whitelist = Website.whitelist(config.url);
// 开启全局加载指示器
if (!whitelist && config.method !== "get") {
globalLoadingInstance = Loading.service({
text: "Loading",
spinner: "el-icon-loading",
background: "hsla(0,0%,100%,.9)",
});
}
// 是否需要设置 token
const isToken = (config.headers || {}).isToken === false
// 是否需要防止数据重复提交
@ -67,49 +79,64 @@ service.interceptors.request.use(config => {
}
return config
}, error => {
console.log(error)
Promise.reject(error)
console.log(error)
if (globalLoadingInstance) {
globalLoadingInstance.close();
}
Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {
if (globalLoadingInstance) {
globalLoadingInstance.close();
}
// 未设置状态码则默认成功状态
const code = res.data.code || 200;
// 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default']
// 二进制数据则直接返回
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
return res.data
}
if (code === 401) {
if (!isRelogin.show) {
isRelogin.show = true;
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
isRelogin.show = false;
store.dispatch('LogOut').then(() => {
location.href = '/index';
})
}).catch(() => {
isRelogin.show = false;
});
}
}).catch(() => {
isRelogin.show = false;
});
}
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
} else if (code === 500) {
Message({ message: msg, type: 'error' })
Message({message: msg, type: 'error'})
return Promise.reject(new Error(msg))
} else if (code === 601) {
Message({ message: msg, type: 'warning' })
Message({message: msg, type: 'warning'})
return Promise.reject('error')
} else if (code !== 200) {
Notification.error({ title: msg })
Notification.error({title: msg})
return Promise.reject('error')
} else {
return res.data
}
},
error => {
if (globalLoadingInstance) {
globalLoadingInstance.close();
}
console.log('err' + error)
let { message } = error;
let {message} = error;
if (message == "Network Error") {
message = "后端接口连接异常";
} else if (message.includes("timeout")) {
@ -117,17 +144,23 @@ service.interceptors.response.use(res => {
} else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常";
}
Message({ message: message, type: 'error', duration: 5 * 1000 })
Message({message: message, type: 'error', duration: 5 * 1000})
return Promise.reject(error)
}
)
// 通用下载方法
export function download(url, params, filename, config) {
downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
downloadLoadingInstance = Loading.service({
text: "正在下载数据,请稍候",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
})
return service.post(url, params, {
transformRequest: [(params) => { return tansParams(params) }],
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
transformRequest: [(params) => {
return tansParams(params)
}],
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
responseType: 'blob',
...config
}).then(async (data) => {

@ -1,57 +1,113 @@
<template>
<div id="app">
<TabComponent
v-if="tabs.length > 0"
ref="tabComponent"
:initial-tabs="tabs"
:req-fun="openDB"
/>
:init-menu-item.sync="tabs"
:init-columns="column"
:call-back-select="backSelect"
>
</TabComponent>
</div>
</template>
<script>
import {getNav, getTasks} from "@/api/gather/pool/pool";
export default {
name: 'App',
data() {
return {
tabs: [
addTabDialogVisible: false,
tabs: [],
currentActiveTab: {},
column: [
{
type: 'id',
width: 55,
align: 'center'
},
{
"title": "开发KIS",
"name": "kisMssql",
"dbType": "mssql",
"url": "jdbc:sqlserver://192.168.3.28:1433;DatabaseName=KIS;encrypt=true;trustServerCertificate=true;",
"username": "sa",
"password": "mssql_whdZeB",
"driverClassName": "com.microsoft.sqlserver.jdbc.SQLServerDriver"
title: '表名称',
key: 'tableName',
align: 'center'
},
{
"title": "本地KIS",
"name": "localKis",
"dbType": "mssql",
"url": "jdbc:sqlserver://192.168.3.252:1433;DatabaseName=KIS_Sample;trustServerCertificate=true;sslProtocol=TLSv1.2;",
"username": "sa",
"password": "abc123456.",
"driverClassName": "com.microsoft.sqlserver.jdbc.SQLServerDriver"
title: '描述',
key: 'tableDescription',
align: 'center'
},
{
title: '表注',
key: 'tableNote',
align: 'center'
},
{
title: '启用',
key: 'enable',
align: 'center'
},
{
title: 'cron (定时)',
key: 'cron',
align: 'center'
},
{
title: '操作',
key: 'oper',
align: 'center'
}
],
addTabDialogVisible: false,
activeTab: null
total: 0,
rows: [],
initActiveTab: "0",
queryParams: {
pageNum: 1,
pageSize: 10
}
};
},
mounted() {
this.getNav();
},
methods: {
async openDB(data) {
await this.closeDialog();
getNav() {
getNav().then(response => {
this.tabs = response.data.map(item => ({
title: item.alias,
name: item.name,
dbType: item.dbType,
url: item.url,
username: item.username,
driverClassName: item.driverClassName
}));
if (this.tabs.length > 0) {
this.currentActiveTab = this.tabs[0];
this.getDataList(this.queryParams);
}
}).catch(error => {
console.error('Failed to fetch navigation data:', error);
});
},
async closeDialog() {
if (this.$refs.tabComponent) {
this.$refs.tabComponent.handleClose();
} else {
console.error('TabComponent ref is not defined');
}
backSelect(index, queryParams) {
this.currentActiveTab = this.tabs[index];
this.getDataList(queryParams);
},
getDataList(queryParams) {
getTasks(queryParams)
.then(response => {
this.rows = response.rows;
this.total = response.total;
this.$refs.tabComponent.loadTableData(this.rows, this.total);
})
.catch(error => {
console.error('Failed to fetch data list:', error);
});
}
},
mounted() {
// console.log('App mounted', this.$refs.tabComponent);
}
};
</script>

@ -118,19 +118,20 @@
type="text"
icon="el-icon-refresh-right"
@click="handleClearCacheAll()"
>清理全部</el-button
>清理全部
</el-button
>
</div>
<el-form :model="cacheForm">
<el-row :gutter="32">
<el-col :offset="1" :span="22">
<el-form-item label="缓存名称:" prop="cacheName">
<el-input v-model="cacheForm.cacheName" :readOnly="true" />
<el-input v-model="cacheForm.cacheName" :readOnly="true"/>
</el-form-item>
</el-col>
<el-col :offset="1" :span="22">
<el-form-item label="缓存键名:" prop="cacheKey">
<el-input v-model="cacheForm.cacheKey" :readOnly="true" />
<el-input v-model="cacheForm.cacheKey" :readOnly="true"/>
</el-form-item>
</el-col>
<el-col :offset="1" :span="22">
@ -152,7 +153,14 @@
</template>
<script>
import { listCacheName, listCacheKey, getCacheValue, clearCacheName, clearCacheKey, clearCacheAll } from "@/api/monitor/cache";
import {
clearCacheAll,
clearCacheKey,
clearCacheName,
getCacheValue,
listCacheKey,
listCacheName
} from "@/api/monitor/cache";
export default {
name: "CacheList",

Loading…
Cancel
Save