This commit is contained in:
六如
2024-10-22 14:13:12 +08:00
parent 89304e8004
commit 483e3969be
18 changed files with 204 additions and 52 deletions

View File

@@ -85,7 +85,7 @@ public class PermGroupController {
*/ */
@PostMapping("/delete") @PostMapping("/delete")
public Result<Integer> delete(@Validated @RequestBody IdParam param) { public Result<Integer> delete(@Validated @RequestBody IdParam param) {
return Result.ok(permGroupService.deleteById(param.getId())); return Result.ok(permGroupService.delete(param.getId()));
} }

View File

@@ -25,7 +25,7 @@ public class ApiInfo {
private Long id; private Long id;
/** /**
* 应用名称 * 所属应用
*/ */
private String application; private String application;

View File

@@ -3,10 +3,14 @@ package com.gitee.sop.adminbackend.service.isv;
import com.gitee.fastmybatis.core.PageInfo; import com.gitee.fastmybatis.core.PageInfo;
import com.gitee.fastmybatis.core.query.LambdaQuery; import com.gitee.fastmybatis.core.query.LambdaQuery;
import com.gitee.fastmybatis.core.support.LambdaService; import com.gitee.fastmybatis.core.support.LambdaService;
import com.gitee.sop.adminbackend.common.exception.BizException;
import com.gitee.sop.adminbackend.dao.entity.PermGroup; import com.gitee.sop.adminbackend.dao.entity.PermGroup;
import com.gitee.sop.adminbackend.dao.entity.PermIsvGroup;
import com.gitee.sop.adminbackend.dao.mapper.PermGroupMapper; import com.gitee.sop.adminbackend.dao.mapper.PermGroupMapper;
import com.gitee.sop.adminbackend.dao.mapper.PermIsvGroupMapper;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
@@ -17,8 +21,11 @@ import java.util.Map;
@Service @Service
public class PermGroupService implements LambdaService<PermGroup, PermGroupMapper> { public class PermGroupService implements LambdaService<PermGroup, PermGroupMapper> {
public PageInfo<PermGroup> doPage(LambdaQuery<PermGroup> query) { @Resource
query.orderByDesc(PermGroup::getId); PermIsvGroupMapper permIsvGroupMapper;
public PageInfo<PermGroup> doPage(LambdaQuery<PermGroup> query) {
query.orderByDesc(PermGroup::getId);
PageInfo<PermGroup> page = this.page(query); PageInfo<PermGroup> page = this.page(query);
// 格式转换 // 格式转换
@@ -34,5 +41,15 @@ public class PermGroupService implements LambdaService<PermGroup, PermGroupMappe
.map(PermGroup::getId, PermGroup::getGroupName); .map(PermGroup::getId, PermGroup::getGroupName);
} }
public int delete(Long groupId) {
boolean used = permIsvGroupMapper.query()
.eq(PermIsvGroup::getGroupId, groupId)
.get() != null;
if (used) {
throw new BizException("无法删除:分组已被使用");
}
return this.deleteById(groupId);
}
} }

View File

@@ -82,7 +82,12 @@ public class PermIsvGroupService implements LambdaService<PermIsvGroup, PermIsvG
return new ArrayList<>(0); return new ArrayList<>(0);
} }
return list.stream().map(PermIsvGroup::getGroupId).distinct().collect(Collectors.toList()); return list.stream().map(PermIsvGroup::getGroupId).distinct().collect(Collectors.toList());
}
public boolean isUsed(Long groupId) {
return this.query()
.eq(PermIsvGroup::getGroupId, groupId)
.get() != null;
} }
} }

View File

@@ -1,5 +1,7 @@
# SOP Admin 前端实现 # SOP Admin 前端实现
> 采用 ECMAScript 模块ESM规范来编写和组织代码使用了最新的 Vue3、Vite、Element-Plus、TypeScript、Pinia、Tailwindcss 等主流技术
## 参考文档 ## 参考文档
- 模板:https://pure-admin.github.io/pure-admin-doc/ - 模板:https://pure-admin.github.io/pure-admin-doc/

View File

@@ -0,0 +1,84 @@
import { ref } from "vue";
import { type PlusColumn } from "plus-pro-components";
import { withInstall } from "@pureadmin/utils";
import apiSelect from "./index.vue";
import { StatusEnum } from "@/model/enums";
export const dlgApiSelectShow = ref(false);
export const dlgWidth = ref(1100);
// ========= table =========
// 表格字段定义
export const tableColumns: PlusColumn[] = [
{
label: "所属应用",
prop: "application",
tableColumnProps: {
showOverflowTooltip: true
}
},
{
label: "接口名称",
prop: "apiName",
tableColumnProps: {
showOverflowTooltip: true
}
},
{
label: "版本号",
prop: "apiVersion",
width: 80
},
{
label: "接口描述",
prop: "description",
tableColumnProps: {
showOverflowTooltip: true
}
},
{
label: "注册来源",
prop: "regSource",
width: 100,
valueType: "select",
options: [
{
label: "系统",
value: 1,
color: "blue"
},
{
label: "手动",
value: 2,
color: "green"
}
]
},
{
label: "状态",
prop: "status",
width: 80,
valueType: "select",
options: [
{
label: "启用",
value: StatusEnum.ENABLE,
color: "green"
},
{
label: "禁用",
value: StatusEnum.DISABLE,
color: "red"
}
]
}
];
export const handleConfirm = () => {
console.log(1);
};
const ApiSelect = withInstall(apiSelect);
export { ApiSelect };

View File

@@ -0,0 +1,53 @@
<script setup lang="ts">
import {
handleConfirm,
dlgApiSelectShow,
tableColumns,
dlgWidth
} from "@/components/ApiSelect/index";
import {
handlePaginationChange,
handleSearch,
pageInfo,
searchFormColumns,
searchFormData,
total,
tableData
} from "@/views/serve/api/index";
</script>
<template>
<PlusDialog
v-model="dlgApiSelectShow"
header="选择接口"
:width="dlgWidth"
cancel-text="取消"
confirm-text="确定"
@confirm="handleConfirm"
>
<el-card shadow="never">
<template #header>
<PlusSearch
v-model="searchFormData"
:columns="searchFormColumns"
:show-number="2"
label-position="right"
:has-reset="false"
@search="handleSearch"
/>
</template>
<PlusTable
:columns="tableColumns"
:table-data="tableData"
:pagination="{
total,
modelValue: pageInfo,
pageSizeList: [10, 20, 50, 100],
align: 'right'
}"
adaptive
@paginationChange="handlePaginationChange"
/>
</el-card>
</PlusDialog>
</template>

View File

@@ -52,13 +52,6 @@ class PureHttp {
constructor() { constructor() {
this.httpInterceptorsRequest(); this.httpInterceptorsRequest();
this.httpInterceptorsResponse(); this.httpInterceptorsResponse();
PureHttp.initConfig.beforeResponseCallback = response => {
const resp = response.data || {};
if (resp.code && resp.code !== "0") {
console.log(resp);
ElMessage.error(resp.msg || "后台出错,请查看日志");
}
};
} }
/** `token`过期后,暂存待执行的请求 */ /** `token`过期后,暂存待执行的请求 */
@@ -189,8 +182,13 @@ class PureHttp {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
PureHttp.axiosInstance PureHttp.axiosInstance
.request(config) .request(config)
.then((response: undefined) => { .then((response: any) => {
resolve(response); if (response.code && response.code !== "0") {
const msg = response.msg || "后台出错,请查看日志";
ElMessage.error(msg);
} else {
resolve(response);
}
}) })
.catch(error => { .catch(error => {
reject(error); reject(error);

View File

@@ -172,10 +172,7 @@ actionButtons.value = [
: StatusEnum.ENABLE : StatusEnum.ENABLE
}; };
api.updateStatus(data).then(() => { api.updateStatus(data).then(() => {
ElMessage({ ElMessage.success("修改成功");
message: "修改成功",
type: "success"
});
dlgShow.value = false; dlgShow.value = false;
search(); search();
}); });
@@ -253,10 +250,7 @@ export const handleSave = () => {
const postData = editFormData.value; const postData = editFormData.value;
const pms = isAdd.value ? api.add(postData) : api.update(postData); const pms = isAdd.value ? api.add(postData) : api.update(postData);
pms.then(() => { pms.then(() => {
ElMessage({ ElMessage.success("保存成功");
message: "保存成功",
type: "success"
});
dlgShow.value = false; dlgShow.value = false;
search(); search();
}); });

View File

@@ -61,10 +61,7 @@ export const handleUpdateGroup = () => {
const data = settingGroupFormData.value; const data = settingGroupFormData.value;
api.updateGroup(data.isvId, data.groupIds).then(() => { api.updateGroup(data.isvId, data.groupIds).then(() => {
ElMessage({ ElMessage.success("保存成功");
message: "保存成功",
type: "success"
});
dlgGroupSetting.value = false; dlgGroupSetting.value = false;
search(); search();
}); });

View File

@@ -149,10 +149,7 @@ export const resetPlatformKeys = () => {
export const handleUpdateKeys = () => { export const handleUpdateKeys = () => {
api.updateKeys(settingKeysFormData.value).then(() => { api.updateKeys(settingKeysFormData.value).then(() => {
ElMessage({ ElMessage.success("保存成功");
message: "保存成功",
type: "success"
});
dlgKeysSetting.value = false; dlgKeysSetting.value = false;
search(); search();
}); });

View File

@@ -1,4 +1,4 @@
import { computed, ref } from "vue"; import { ref } from "vue";
import { import {
type ButtonsCallBackParams, type ButtonsCallBackParams,
type PageInfo, type PageInfo,
@@ -7,6 +7,8 @@ import {
} from "plus-pro-components"; } from "plus-pro-components";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { api } from "@/api/permGroup"; import { api } from "@/api/permGroup";
import { dlgApiSelectShow } from "@/components/ApiSelect";
import { search as searchApi } from "@/views/serve/api";
const isAdd = ref(false); const isAdd = ref(false);
@@ -58,6 +60,17 @@ export const tableColumns: PlusColumn[] = [
]; ];
// 表格按钮定义 // 表格按钮定义
actionButtons.value = [ actionButtons.value = [
{
text: "接口授权",
code: "edit",
props: {
type: "warning"
},
onClick() {
dlgApiSelectShow.value = true;
searchApi();
}
},
{ {
// 修改 // 修改
text: "修改", text: "修改",
@@ -65,7 +78,6 @@ actionButtons.value = [
props: { props: {
type: "primary" type: "primary"
}, },
show: computed(() => true),
onClick(params: ButtonsCallBackParams) { onClick(params: ButtonsCallBackParams) {
isAdd.value = false; isAdd.value = false;
editFormData.value = Object.assign({}, params.row); editFormData.value = Object.assign({}, params.row);
@@ -109,7 +121,7 @@ const editFormDataGen = () => {
}; };
export const editFormData = ref<any>(editFormDataGen()); export const editFormData = ref<any>(editFormDataGen());
export const editFormRules = { export const editFormRules = {
groupName: [{ required: true, message: "请输入分组描述" }] groupName: [{ required: true, message: "请输入分组名称" }]
}; };
// 表单内容 // 表单内容
@@ -136,10 +148,7 @@ export const handleSave = () => {
const postData = editFormData.value; const postData = editFormData.value;
const pms = isAdd.value ? api.add(postData) : api.update(postData); const pms = isAdd.value ? api.add(postData) : api.update(postData);
pms.then(() => { pms.then(() => {
ElMessage({ ElMessage.success("保存成功");
message: "保存成功",
type: "success"
});
dlgShow.value = false; dlgShow.value = false;
search(); search();
}); });

View File

@@ -17,6 +17,7 @@ import {
tableData, tableData,
total total
} from "./permGroup"; } from "./permGroup";
import { ApiSelect } from "@/components/ApiSelect/index";
</script> </script>
<template> <template>
<el-card shadow="never"> <el-card shadow="never">
@@ -33,7 +34,7 @@ import {
<PlusTable <PlusTable
:columns="tableColumns" :columns="tableColumns"
:table-data="tableData" :table-data="tableData"
:action-bar="{ buttons: actionButtons, width: 120 }" :action-bar="{ buttons: actionButtons, width: 200 }"
:pagination="{ :pagination="{
total, total,
modelValue: pageInfo, modelValue: pageInfo,
@@ -60,5 +61,6 @@ import {
:hasErrorTip="false" :hasErrorTip="false"
@confirm="handleSave" @confirm="handleSave"
/> />
<ApiSelect />
</el-card> </el-card>
</template> </template>

View File

@@ -62,7 +62,7 @@ pageInfo.value.pageSize = 10;
// 表格字段定义 // 表格字段定义
export const tableColumns: PlusColumn[] = [ export const tableColumns: PlusColumn[] = [
{ {
label: "应用名称", label: "所属应用",
prop: "application", prop: "application",
tableColumnProps: { tableColumnProps: {
showOverflowTooltip: true showOverflowTooltip: true
@@ -212,10 +212,7 @@ actionButtons.value = [
: StatusEnum.ENABLE : StatusEnum.ENABLE
}; };
api.updateStatus(data).then(() => { api.updateStatus(data).then(() => {
ElMessage({ ElMessage.success("修改成功");
message: "修改成功",
type: "success"
});
dlgShow.value = false; dlgShow.value = false;
search(); search();
}); });
@@ -256,7 +253,7 @@ export const isCustomRegSource = computed(() => {
// 表单内容 // 表单内容
export const editFormColumns: PlusColumn[] = [ export const editFormColumns: PlusColumn[] = [
{ {
label: "应用名称", label: "所属应用",
prop: "application", prop: "application",
valueType: "text" valueType: "text"
}, },
@@ -353,10 +350,7 @@ export const handleSave = () => {
const postData = editFormData.value; const postData = editFormData.value;
const pms = isAdd.value ? api.add(postData) : api.update(postData); const pms = isAdd.value ? api.add(postData) : api.update(postData);
pms.then(() => { pms.then(() => {
ElMessage({ ElMessage.success("保存成功");
message: "保存成功",
type: "success"
});
dlgShow.value = false; dlgShow.value = false;
search(); search();
}); });
@@ -375,7 +369,7 @@ export const handlePaginationChange = (_pageInfo: PageInfo): void => {
}; };
// 查询 // 查询
const search = async () => { export const search = async () => {
try { try {
const { data } = await doSearch(); const { data } = await doSearch();
tableData.value = data.list; tableData.value = data.list;

View File

@@ -12,7 +12,7 @@ public class ApiInfoDTO implements Serializable {
private static final long serialVersionUID = 2183251167679411550L; private static final long serialVersionUID = 2183251167679411550L;
/** /**
* 应用名称 * 所属应用
*/ */
private String application; private String application;

View File

@@ -22,7 +22,7 @@ public class ApiInfo {
private Long id; private Long id;
/** /**
* 应用名称 * 所属应用
*/ */
private String application; private String application;

View File

@@ -12,7 +12,7 @@ public class RegisterDTO implements Serializable {
private static final long serialVersionUID = 2183251167679411550L; private static final long serialVersionUID = 2183251167679411550L;
/** /**
* 应用名称 * 所属应用
*/ */
private String application; private String application;

View File

@@ -6,7 +6,7 @@ USE `sop`;
CREATE TABLE `api_info` ( CREATE TABLE `api_info` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`application` varchar(64) NOT NULL DEFAULT '' COMMENT '应用名称', `application` varchar(64) NOT NULL DEFAULT '' COMMENT '所属应用',
`api_name` varchar(128) NOT NULL DEFAULT '' COMMENT '接口名称', `api_name` varchar(128) NOT NULL DEFAULT '' COMMENT '接口名称',
`api_version` varchar(16) NOT NULL DEFAULT '1.0' COMMENT '版本号', `api_version` varchar(16) NOT NULL DEFAULT '1.0' COMMENT '版本号',
`interface_class_name` varchar(128) NOT NULL DEFAULT '' COMMENT '接口class', `interface_class_name` varchar(128) NOT NULL DEFAULT '' COMMENT '接口class',