diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/controller/NamespaceController.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/controller/NamespaceController.java
index d1e86509..5d550a45 100644
--- a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/controller/NamespaceController.java
+++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/controller/NamespaceController.java
@@ -9,11 +9,7 @@ import com.aizuda.easy.retry.server.web.service.NamespaceService;
import com.aizuda.easy.retry.template.datasource.persistence.po.SystemUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
import java.util.List;
@@ -39,12 +35,17 @@ public class NamespaceController {
return namespaceService.updateNamespace(namespaceRequestVO);
}
- @PutMapping
+ @GetMapping("list")
public PageResult<List<NamespaceResponseVO>> getNamespacePage(NamespaceQueryVO queryVO) {
return namespaceService.getNamespacePage(queryVO);
}
- @PutMapping
+ @DeleteMapping("{id}")
+ public Boolean deleteNamespace(@PathVariable("id") Long id) {
+ return namespaceService.deleteNamespace(id);
+ }
+
+// @PutMapping
public List<NamespaceResponseVO> getNamespaceByUserId(@LoginUser SystemUser systemUser) {
return namespaceService.getNamespaceByUserId(systemUser);
}
diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/NamespaceService.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/NamespaceService.java
index 34454a32..e817c3aa 100644
--- a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/NamespaceService.java
+++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/NamespaceService.java
@@ -22,4 +22,6 @@ public interface NamespaceService {
PageResult<List<NamespaceResponseVO>> getNamespacePage(NamespaceQueryVO queryVO);
List<NamespaceResponseVO> getNamespaceByUserId(SystemUser systemUser);
+
+ Boolean deleteNamespace(Long id);
}
diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/convert/NamespaceResponseVOConverter.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/convert/NamespaceResponseVOConverter.java
index cddc1cc1..18ae86ec 100644
--- a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/convert/NamespaceResponseVOConverter.java
+++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/convert/NamespaceResponseVOConverter.java
@@ -2,6 +2,7 @@ package com.aizuda.easy.retry.server.web.service.convert;
import com.aizuda.easy.retry.server.web.model.response.NamespaceResponseVO;
import com.aizuda.easy.retry.template.datasource.persistence.po.Namespace;
+import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@@ -11,6 +12,7 @@ import java.util.List;
* @date : 2023-11-21 16:20
* @since : 2.5.0
*/
+@Mapper
public interface NamespaceResponseVOConverter {
NamespaceResponseVOConverter INSTANCE = Mappers.getMapper(NamespaceResponseVOConverter.class);
diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/NamespaceServiceImpl.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/NamespaceServiceImpl.java
index f05155a5..3f0f3dae 100644
--- a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/NamespaceServiceImpl.java
+++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/NamespaceServiceImpl.java
@@ -59,11 +59,11 @@ public class NamespaceServiceImpl implements NamespaceService {
LambdaQueryWrapper<Namespace> queryWrapper = new LambdaQueryWrapper<>();
if (StrUtil.isNotBlank(queryVO.getName())) {
- queryWrapper.like(Namespace::getName, "%" + queryVO.getName() + "%");
+ queryWrapper.like(Namespace::getName,queryVO.getName() + "%");
}
queryWrapper.eq(Namespace::getDeleted, StatusEnum.NO);
-
+ queryWrapper.orderByDesc(Namespace::getId);
PageDTO<Namespace> selectPage = namespaceMapper.selectPage(pageDTO, queryWrapper);
return new PageResult<>(pageDTO, NamespaceResponseVOConverter.INSTANCE.toNamespaceResponseVOs(selectPage.getRecords()));
}
@@ -72,4 +72,9 @@ public class NamespaceServiceImpl implements NamespaceService {
public List<NamespaceResponseVO> getNamespaceByUserId(final SystemUser systemUser) {
return null;
}
+
+ @Override
+ public Boolean deleteNamespace(Long id) {
+ return 1 == namespaceMapper.deleteById(id);
+ }
}
diff --git a/frontend/src/api/manage.js b/frontend/src/api/manage.js
index d622ca14..7ab1c6ed 100644
--- a/frontend/src/api/manage.js
+++ b/frontend/src/api/manage.js
@@ -45,11 +45,39 @@ const api = {
systemVersion: '/system/version',
pods: '/dashboard/pods',
consumerGroup: '/dashboard/consumer/group',
- updateGroupStatus: '/group/status'
+ updateGroupStatus: '/group/status',
+
+ addNamespace: '/namespace',
+ updateNamespace: '/namespace',
+ namespaceList: '/namespace/list',
+ delNamespace: '/namespace/'
}
export default api
+export function delNamespace (id) {
+ return request({
+ url: api.delNamespace + id,
+ method: 'delete'
+ })
+}
+
+export function addNamespace (data) {
+ return request({
+ url: api.addNamespace,
+ method: 'post',
+ data
+ })
+}
+
+export function namespaceList (parameter) {
+ return request({
+ url: api.namespaceList,
+ method: 'get',
+ params: parameter
+ })
+}
+
export function delUser (id) {
return request({
url: api.delUser + id,
diff --git a/frontend/src/components/GlobalHeader/RightContent.vue b/frontend/src/components/GlobalHeader/RightContent.vue
index 669b9340..ed73e0d3 100644
--- a/frontend/src/components/GlobalHeader/RightContent.vue
+++ b/frontend/src/components/GlobalHeader/RightContent.vue
@@ -1,9 +1,24 @@
<template>
<div :class="wrpCls">
+ <a-dropdown>
+ <span placement="bottomRight">
+ Default <a-icon type="down" />
+ </span>
+ <a-menu slot="overlay">
+ <a-menu-item>
+ <a href="javascript:;">Uat</a>
+ </a-menu-item>
+ <a-menu-item>
+ <a href="javascript:;">Dev</a>
+ </a-menu-item>
+ <a-menu-item>
+ <a href="javascript:;">Prod</a>
+ </a-menu-item>
+ </a-menu>
+ </a-dropdown>
<a href="https://www.easyretry.com" target="_blank" :class="prefixCls"><a-icon type="question-circle" :style="{ fontSize: '18px', color: '#08c' }"/></a>
<avatar-dropdown :menu="showMenu" :current-user="currentUser" :class="prefixCls"/>
<!-- <select-lang :class="prefixCls" />-->
-
</div>
</template>
diff --git a/frontend/src/config/router.config.js b/frontend/src/config/router.config.js
index dd82adea..1158b339 100644
--- a/frontend/src/config/router.config.js
+++ b/frontend/src/config/router.config.js
@@ -38,6 +38,13 @@ export const asyncRouterMap = [
]
},
// profile
+ {
+ path: '/namespace',
+ name: 'namespace',
+ component: () => import('@/views/namespace/NamespaceList'),
+ meta: { title: '命名空间', icon: 'team', permission: ['group'] }
+ },
+ // profile
{
path: '/basic-config-list',
name: 'basicConfigList',
diff --git a/frontend/src/views/namespace/NamespaceForm.vue b/frontend/src/views/namespace/NamespaceForm.vue
new file mode 100644
index 00000000..107fe754
--- /dev/null
+++ b/frontend/src/views/namespace/NamespaceForm.vue
@@ -0,0 +1,102 @@
+<template>
+ <a-modal :visible="visible" title="命名空间配置" @ok="handleOk" @cancel="visible = false" width="650px">
+ <a-form @submit="handleOk" :form="form" :body-style="{padding: '24px 32px'}" v-bind="formItemLayout" >
+ <a-form-item>
+ <a-input
+ hidden
+ v-decorator="['id']" />
+ </a-form-item>
+ <a-form-item
+ label="唯一标识"
+ v-if="isEdit">
+ <a-input
+ placeholder="唯一标识"
+ disabled
+ v-decorator="[
+ 'uniqueId',
+ {rules: [{ required: false, message: '请输入空间名称', whitespace: true}]}
+ ]" />
+ </a-form-item>
+ <a-form-item
+ label="空间名称">
+ <a-input
+ placeholder="请输入空间名称"
+ v-decorator="[
+ 'name',
+ {rules: [{ required: true, message: '请输入空间名称', whitespace: true}]}
+ ]" />
+ </a-form-item>
+ </a-form></a-modal>
+
+</template>
+
+<script>
+import { addNamespace, updateNamespace } from '@/api/manage'
+import pick from 'lodash.pick'
+
+export default {
+ name: 'NamespaceForm',
+ props: {
+ isEdit: {
+ type: Boolean,
+ default: false
+ }
+ },
+ data () {
+ return {
+ form: this.$form.createForm(this),
+ role: 0,
+ formType: 'create',
+ formItemLayout: {
+ labelCol: { lg: { span: 7 }, sm: { span: 7 } },
+ wrapperCol: { lg: { span: 10 }, sm: { span: 17 } }
+ },
+ visible: false
+ }
+ },
+ methods: {
+ isShow (record) {
+ this.formType = record ? 'edit' : 'create'
+ console.log(this.formType)
+ this.loadEditInfo(record)
+ this.visible = true
+ this.form.resetFields()
+ },
+ handleOk (e) {
+ e.preventDefault()
+ this.form.validateFields((err, values) => {
+ if (!err) {
+ if (this.formType === 'create') {
+ addNamespace(values).then(res => {
+ this.$message.success('操作成功')
+ this.$emit('refreshTable', 1)
+ this.visible = false
+ })
+ } else {
+ updateNamespace(values).then(res => {
+ this.$message.success('操作成功')
+ this.$emit('refreshTable', 1)
+ this.visible = false
+ })
+ }
+ }
+ })
+ },
+ loadEditInfo (data) {
+ this.formType = 'edit'
+ const { form } = this
+ // ajax
+ new Promise((resolve) => {
+ setTimeout(resolve, 100)
+ }).then(() => {
+ const formData = pick(data, ['id', 'name', 'uniqueId'])
+ form.setFieldsValue(formData)
+ })
+ }
+ }
+}
+</script>
+
+<style scoped>
+
+</style>
diff --git a/frontend/src/views/namespace/NamespaceList.vue b/frontend/src/views/namespace/NamespaceList.vue
new file mode 100644
index 00000000..9d2e8a8d
--- /dev/null
+++ b/frontend/src/views/namespace/NamespaceList.vue
@@ -0,0 +1,179 @@
+<template>
+ <div>
+ <a-card :bordered="false">
+
+ <div class="table-page-search-wrapper">
+ <a-form layout="inline">
+ <a-row :gutter="48">
+ <a-col :md="8" :sm="24">
+ <a-form-item label="用户名">
+ <a-input v-model="queryParam.name" placeholder="请输入空间名称" allowClear/>
+ </a-form-item>
+ </a-col>
+ <a-col :md="!advanced && 8 || 24" :sm="24">
+ <span class="table-page-search-submitButtons" :style="advanced && { float: 'right', overflow: 'hidden' } || {} ">
+ <a-button type="primary" @click="$refs.table.refresh(true)">查询</a-button>
+ <a-button style="margin-left: 8px" @click="() => queryParam = {}">重置</a-button>
+ </span>
+ </a-col>
+ </a-row>
+ </a-form>
+ </div>
+
+ <div class="table-operator">
+ <a-button type="primary" icon="plus" @click="handleNew()">新建</a-button>
+ </div>
+
+ <s-table
+ ref="table"
+ size="default"
+ :rowKey="record => record.id"
+ :columns="columns"
+ :data="loadData"
+ :alert="options.alert"
+ :rowSelection="options.rowSelection"
+ >
+ <span slot="serial" slot-scope="record">
+ {{ record.id }}
+ </span>
+ <!-- <span slot="groupNameList" slot-scope="text, record">-->
+ <!-- {{ record.role === 2 ? '所有组' : text.toString() }}-->
+ <!-- </span>-->
+ <!-- <span slot="role" slot-scope="text, record">-->
+ <!-- {{ record.role === 2 ? '管理员' : '普通用户' }}-->
+ <!-- </span>-->
+ <span slot="action" slot-scope="text, record">
+ <template>
+ <a @click="handleEdit(record)">编辑</a>
+ <a-divider type="vertical" />
+ <a-popconfirm
+ title="命名空间删除后不可恢复,请确认是否删除这个空间?"
+ ok-text="删除"
+ cancel-text="取消"
+ @confirm="handleDel(record)">
+ <a href="javascript:;">删除</a>
+ </a-popconfirm>
+
+ </template>
+ </span>
+ </s-table>
+ </a-card>
+
+ <NamespaceForm ref="namespaceFormRef" :isEdit="isEdit" @refreshTable="refreshTable"/>
+ </div>
+</template>
+<script>
+
+import AInput from 'ant-design-vue/lib/input/Input'
+import ATextarea from 'ant-design-vue/lib/input/TextArea'
+import { STable } from '@/components'
+import moment from 'moment/moment'
+import { namespaceList, delNamespace } from '@/api/manage'
+import NamespaceForm from '@/views/namespace/NamespaceForm.vue'
+
+export default {
+ name: 'NamespaceList',
+ components: {
+ AInput,
+ ATextarea,
+ STable,
+ NamespaceForm
+ },
+ data () {
+ return {
+ mdl: {},
+ // 高级搜索 展开/关闭
+ advanced: false,
+ // 查询参数
+ queryParam: {},
+ // 表头
+ columns: [
+ {
+ title: '#',
+ width: '5%',
+ scopedSlots: { customRender: 'serial' }
+ },
+ {
+ title: '名称',
+ dataIndex: 'name'
+ },
+ {
+ title: 'UniqueId',
+ dataIndex: 'uniqueId'
+ },
+ {
+ title: '创建时间',
+ dataIndex: 'updateDt',
+ customRender: (text) => moment(text).format('YYYY-MM-DD HH:mm:ss')
+ },
+ {
+ title: '更新时间',
+ dataIndex: 'createDt',
+ customRender: (text) => moment(text).format('YYYY-MM-DD HH:mm:ss')
+ },
+ {
+ title: '操作',
+ width: '10%',
+ dataIndex: 'action',
+ scopedSlots: { customRender: 'action' }
+ }
+ ],
+ // 加载数据方法 必须为 Promise 对象
+ loadData: parameter => {
+ return namespaceList(Object.assign(parameter, this.queryParam))
+ .then(res => {
+ return res
+ })
+ },
+ selectedRowKeys: [],
+ selectedRows: [],
+
+ // custom table alert & rowSelection
+ options: {
+ alert: { show: true, clear: () => { this.selectedRowKeys = [] } },
+ rowSelection: {
+ selectedRowKeys: this.selectedRowKeys,
+ onChange: this.onSelectChange
+ }
+ },
+ optionAlertShow: false,
+ isEdit: false
+ }
+ },
+ filters: {
+ },
+ methods: {
+ handleNew () {
+ this.isEdit = false
+ this.$refs.namespaceFormRef.isShow()
+ },
+ refreshTable (v) {
+ this.$refs.table.refresh()
+ },
+ handleEdit (record) {
+ this.isEdit = true
+ this.$refs.namespaceFormRef.isShow(record)
+ },
+ handleDel (record) {
+ delNamespace(record.id).then(res => {
+ this.$message.success('删除成功')
+ this.$refs.table.refresh()
+ })
+ },
+ handleGoBack () {
+ this.record = ''
+ this.currentComponet = 'List'
+ }
+ },
+ watch: {
+ '$route.path' () {
+ this.record = ''
+ this.currentComponet = 'List'
+ }
+ }
+}
+</script>
+
+<style scoped lang='less'>
+
+</style>