提交 4ed03d72 authored 作者: 刘旭's avatar 刘旭

新增执行计划、 产品管理页面

上级 782f20b5
File added
......@@ -5,7 +5,7 @@
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit --skipLibCheck && vite build",
"build": "vite build",
"preview": "vite preview",
"build-only": "vite build",
"type-check": "vue-tsc --build --force",
......
......@@ -58,11 +58,6 @@ class RequestHttp {
*/
this.service.interceptors.request.use(
(config: CustomAxiosRequestConfig) => {
// const globalStore = useGlobalStore()
// let globalStore: any
// if (config.headers && globalStore.token) {
// config.headers.set('Authorization', globalStore.token)
// }
return config
},
......
......@@ -67,6 +67,7 @@ export const cleanBatch = (data: any) => {
export const getJarList = () => {
return request.get('/admin/docker/jar/list')
}
export const jarRestart = (data: any) => {
return request.get('/admin/docker/jar/restart', data)
}
import request from './config'
let baseUrl = location.origin
// let baseUrl = 'http://192.168.1.67:8003'
let newPort = '8003'
baseUrl = baseUrl.replace(/:\d+/, ':' + newPort)
export const getExecuteList = () => {
return request.get(baseUrl + '/webApi/job/list')
}
export const setExecuteStats = (data: any) => {
return request.get(baseUrl + '/webApi/job/stats', data)
}
export const setExecuteCron = (data: any) => {
return request.get(baseUrl + '/webApi/job/cron', data)
}
export const getSyncConfigLog = (data: any) => {
return request.get(baseUrl + '/webApi/syncConfig/log', data)
}
export const setSyncConfigLog = (data: any) => {
return request.get(baseUrl + '/webApi/syncConfig/log/update', data)
}
export const getSyncConfigScene = (data: any) => {
return request.get(baseUrl + '/webApi/syncConfig/scene', data)
}
export const setSyncConfigScene = (data: any) => {
return request.get(baseUrl + '/webApi/syncConfig/scene/update', data)
}
......@@ -6,44 +6,23 @@
text-color="#fff"
router
>
<el-menu-item v-for="item in mentList" :index="item.index" :route="item.path">
<el-menu-item v-for="item in menuList" :index="item.index" :route="item.path">
<span>{{ item.name }}</span>
</el-menu-item>
</el-menu>
</template>
<script setup lang="ts">
import { menuList } from '../uilts/menuList'
const route = useRoute()
const active: any = ref(1)
const mentList = ref([
{
index: 1,
path: '/tenant',
name: '租户管理'
},
{
index: 2,
path: '/logs',
name: '日志管理'
},
{
index: 3,
path: '/imageManagement',
name: '容器管理'
},
{
index: 4,
path: '/jarManagement',
name: 'jar包管理'
}
])
watch(
() => route.path,
(newPath: string) => {
active.value = mentList.value.find((item: any) => newPath === item.path)?.index
active.value = menuList.find((item: any) => newPath === item.path)?.index
},
{ immediate: true }
)
......
......@@ -17,6 +17,19 @@
<script setup lang="ts">
import Aside from './components/aside.vue'
import Headers from './components/header.vue'
import { useTenantStore } from '@/stores/modules/tenant'
const router = useRouter()
const tenantStore = useTenantStore()
const tenantList = computed(() => tenantStore.getTenantList)
watch(
() => tenantList.value,
(list: any) => {
if (!list.length) return router.push('/')
},
{ immediate: true }
)
</script>
<style scoped>
......
export const menuList = [
{
index: 1,
path: '/tenant',
name: '租户管理'
},
{
index: 2,
path: '/logs',
name: '日志管理'
},
{
index: 3,
path: '/imageManagement',
name: '容器管理'
},
{
index: 4,
path: '/jarManagement',
name: 'jar包管理'
},
{
index: 5,
path: '/execute',
name: '执行计划'
},
{
index: 6,
path: '/syncConfig',
name: '产品管理'
}
]
......@@ -30,6 +30,14 @@ const router = createRouter({
{
path: '/jarManagement',
component: () => import('@/views/jarManagement/index.vue')
},
{
path: '/execute',
component: () => import('@/views/execute/index.vue')
},
{
path: '/syncConfig',
component: () => import('@/views/syncConfig/index.vue')
}
]
}
......
......@@ -14,6 +14,7 @@ declare module 'vue' {
ElContainer: typeof import('element-plus/es')['ElContainer']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDivider: typeof import('element-plus/es')['ElDivider']
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElHeader: typeof import('element-plus/es')['ElHeader']
......@@ -27,6 +28,7 @@ declare module 'vue' {
ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTag: typeof import('element-plus/es')['ElTag']
......
<template>
<el-dialog v-model="show" title="编辑" width="40%" @close="handleClose">
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
<el-form-item label="任务类名">
<el-input v-model="form.className" disabled />
</el-form-item>
<el-form-item prop="cronExpression" label="cron表达式">
<el-input v-model="form.cronExpression" />
</el-form-item>
<el-form-item label="状态">
<el-tag :type="form.status ? 'success' : 'error'" disable-transitions>{{
form.status ? '成功' : '失败'
}}</el-tag>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="onComfirm">确认</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
const emtis = defineEmits(['comfirm'])
const show = ref(false)
const form = ref()
const formRef = ref()
const rules = { cronExpression: [{ required: true, message: '请输入cron表达式', trigger: 'blur' }] }
const onComfirm = () => {
formRef.value?.validate((valid: Boolean, fields: any) => {
if (valid) {
emtis('comfirm', form.value)
handleClose()
} else {
console.log('error submit!', fields)
}
})
}
const handleClose = () => {
formRef.value?.resetFields()
show.value = false
}
defineExpose({
form,
show
})
</script>
<style scoped></style>
<template>
<div v-loading="loading">
<el-table :data="tableData" stripe border>
<el-table-column type="index" label="#" align="center" />
<el-table-column prop="className" label="任务类名" />
<el-table-column prop="cronExpression" label="cron表达式" width="150px" align="center" />
<el-table-column prop="status" label="状态" width="100px" align="center">
<template #default="scope">
<el-tag :type="scope.row.status ? 'success' : 'error'" disable-transitions>{{
scope.row.status ? '成功' : '失败'
}}</el-tag>
</template>
</el-table-column>
<el-table-column prop="operation" label="操作" align="center" width="150px">
<template #default="scope">
<span
v-if="!scope.row.status"
class="el-dropdown-link"
@click="handleStartNow(scope.row)"
style="color: #409eff; cursor: pointer; margin-top: 2px"
>启动</span
>
<span
v-else
class="el-dropdown-link"
@click="handleStopNow(scope.row)"
style="color: #409eff; cursor: pointer; margin-top: 2px"
>停用</span
>
<el-divider direction="vertical" />
<span
class="el-dropdown-link"
@click="handleEdit(scope.row)"
style="color: #409eff; cursor: pointer; margin-top: 2px"
>编辑</span
>
</template>
</el-table-column>
</el-table>
</div>
<executeDialog ref="executeRef" @comfirm="onConfirm" />
</template>
<script setup lang="ts">
import { getExecuteList, setExecuteStats, setExecuteCron } from '@/api/webApi'
import executeDialog from './components/executeDialog.vue'
const loading = ref(true)
const tableData = ref()
const executeRef = ref()
const handleStartNow = async (row: any) => {
const res: any = await setExecuteStats({ className: row.className, status: 1 })
if (res.code === 200) {
init()
}
}
const handleStopNow = async (row: any) => {
const res: any = await setExecuteStats({ className: row.className, status: 0 })
if (res.code === 200) {
init()
}
}
const handleEdit = (row: any) => {
executeRef.value.form = row
executeRef.value.show = true
}
const onConfirm = async (data: any) => {
const res: any = await setExecuteCron({
className: data.className,
cronExpression: data.cronExpression
})
if (res.code === 200) {
init()
}
}
const init = async () => {
loading.value = true
const res: any = await getExecuteList()
if (res.code === 200) {
tableData.value = res.data
loading.value = false
}
}
init()
</script>
<style scoped></style>
......@@ -56,15 +56,7 @@
</template>
<script setup lang="ts">
import {
getListAll,
getMessage,
restartOne,
startBatch,
updateBatch,
cleanBatch,
getLogs
} from '@/api'
import { getListAll, getMessage, restartOne, startBatch, updateBatch, cleanBatch } from '@/api'
import { useTenantStore } from '@/stores/modules/tenant'
import logs from '@/components/logs.vue'
......@@ -144,7 +136,7 @@ const onClean = () => {
const onMessages = async () => {
state.loading = true
await initListAll()
await initListAll(tenantId.value)
await initMessage().then(() => {
state.loading = false
})
......@@ -220,8 +212,7 @@ watch(
)
const init = async () => {
await initListAll()
await initMessage().then(() => {
initMessage().then(() => {
state.loading = false
})
}
......
......@@ -38,9 +38,11 @@ const loginForm = ref({
password: ''
})
const router = useRouter()
const login = () => {
tenantStore.initTenantList()
router.push('/tenant')
tenantStore.initTenantList().then(() => {
router.push('/tenant')
})
}
</script>
......
<template>
<div v-loading="loading" class="sync">
<div class="log-form">
<h3 class="title">产品日志</h3>
<el-form :model="state.logData" :label-width="100" label-position="left">
<el-form-item label="租户标识">
<el-input v-model="state.logData.tenantId" disabled />
</el-form-item>
<el-form-item label="是否同步">
<el-switch v-model="state.logData.isSync" />
</el-form-item>
<el-form-item label="开始时间过滤">
<el-input v-model="state.logData.dateFrom" />
</el-form-item>
<el-form-item label="结束时间过滤">
<el-input v-model="state.logData.dateTo" />
</el-form-item>
<el-form-item label="过滤参数">
<el-input v-model="state.logData.whereFilter" />
</el-form-item>
</el-form>
<el-button type="primary" @click="onUpdate('log')">日志更新</el-button>
</div>
<el-divider direction="vertical" />
<div class="scene-form">
<h3 class="title">产品场景</h3>
<el-form :model="state.sceneData" :label-width="100" label-position="left">
<el-form-item label="租户标识">
<el-input v-model="state.sceneData.tenantId" disabled />
</el-form-item>
<el-form-item label="是否同步">
<el-switch v-model="state.sceneData.isSync" />
</el-form-item>
</el-form>
<el-button type="primary" @click="onUpdate('scene')">场景更新</el-button>
</div>
</div>
</template>
<script setup lang="ts">
import {
getSyncConfigLog,
setSyncConfigLog,
getSyncConfigScene,
setSyncConfigScene
} from '@/api/webApi'
import { useTenantStore } from '@/stores/modules/tenant'
const tenantStore = useTenantStore()
const tenantId = computed(() => tenantStore.getTenantId)
const state = reactive({
logData: {
tenantId: '',
isSync: false,
dateFrom: '',
dateTo: '',
whereFilter: ''
},
sceneData: {
tenantId: '',
isSync: false
}
})
const loading = ref(true)
const onUpdate = async (type: string) => {
ElMessageBox.confirm(`确认${type === 'log' ? '日志' : '场景'}更新?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
const res: any =
type === 'log'
? await setSyncConfigLog(state.logData)
: await setSyncConfigScene(state.sceneData)
if (res.code === 200) {
init().finally(() => (loading.value = false))
}
})
}
const init = async () => {
loading.value = true
const res: any = await getSyncConfigLog({ tenantId: tenantId.value })
const res1: any = await getSyncConfigScene({ tenantId: tenantId.value })
if (res.code === 200) {
state.logData = res.data
}
if (res1.code === 200) {
state.sceneData = res1.data
}
}
watch(
() => tenantId.value,
() => {
init().finally(() => (loading.value = false))
},
{ immediate: true }
)
</script>
<style scoped>
.sync {
width: 100%;
height: 100%;
display: flex;
}
.log-form,
.scene-form {
width: 49%;
display: flex;
align-items: center;
flex-direction: column;
}
.el-form {
min-height: 300px;
}
.title {
font-weight: bolder;
margin-bottom: 20px;
}
.el-divider {
height: 100%;
}
</style>
......@@ -52,6 +52,9 @@ export default defineConfig({
proxy: {
'/admin': {
target: 'http://192.168.1.67:8080/'
},
'/webApi': {
target: 'http://192.168.1.67:8003/'
}
}
},
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论