This commit is contained in:
六如
2024-10-05 21:13:29 +08:00
parent c08fec74c9
commit d9fb25dc0a
31 changed files with 695 additions and 226 deletions

View File

@@ -0,0 +1,14 @@
package com.gitee.sop.adminbackend.common;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* @author 六如
*/
@Data
public class IdParam {
@NotNull(message = "id不能为空")
private Long id;
}

View File

@@ -0,0 +1,33 @@
package com.gitee.sop.adminbackend.common;
import lombok.Getter;
import java.util.Objects;
/**
* @author 六如
*/
@Getter
public enum StatusEnum {
DISABLED((byte)0),
ENABLE((byte)1),
SET_PWD((byte)2),
;
private final int status;
public static StatusEnum of(Integer value) {
for (StatusEnum statusEnum : StatusEnum.values()) {
if (Objects.equals(statusEnum.status, value)) {
return statusEnum;
}
}
return DISABLED;
}
StatusEnum(byte style) {
this.status = style;
}
}

View File

@@ -0,0 +1,80 @@
package com.gitee.sop.adminbackend.controller.serve;
import com.gitee.fastmybatis.core.PageInfo;
import com.gitee.fastmybatis.core.query.Query;
import com.gitee.sop.adminbackend.common.IdParam;
import com.gitee.sop.adminbackend.common.Result;
import com.gitee.sop.adminbackend.controller.serve.req.ApiInfoParam;
import com.gitee.sop.adminbackend.dao.entity.ApiInfo;
import com.gitee.sop.adminbackend.service.serve.ApiInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 接口管理
*
* @author 六如
*/
@RestController
@RequestMapping("serve/api")
public class ApiInfoController {
@Autowired
private ApiInfoService apiInfoService;
/**
* 分页查询
*
* @param param
* @return
*/
@GetMapping("/page")
public Result<PageInfo<ApiInfo>> page(ApiInfoParam param) {
Query query = param.toQuery();
query.orderByDesc("id");
PageInfo<ApiInfo> pageInfo = apiInfoService.page(query);
return Result.ok(pageInfo);
}
/**
* 新增记录
*
* @param user
* @return 返回添加后的主键值
*/
@PostMapping("/add")
public Result<Long> add(@Validated @RequestBody ApiInfo user) {
apiInfoService.save(user);
// 返回添加后的主键值
return Result.ok(user.getId());
}
/**
* 修改记录
*
* @param user 表单数据
* @return 返回影响行数
*/
@PostMapping("/update")
public Result<Integer> update(@Validated @RequestBody ApiInfo user) {
return Result.ok(apiInfoService.update(user));
}
/**
* 删除记录
*
* @param param 主键id
* @return 返回影响行数
*/
@PostMapping("/delete")
public Result<Integer> delete(@Validated @RequestBody IdParam param) {
return Result.ok(apiInfoService.deleteById(param.getId()));
}
}

View File

@@ -0,0 +1,18 @@
package com.gitee.sop.adminbackend.controller.serve.req;
import com.gitee.fastmybatis.core.query.Operator;
import com.gitee.fastmybatis.core.query.annotation.Condition;
import com.gitee.fastmybatis.core.query.param.PageParam;
import lombok.Data;
/**
* @author 六如
*/
@Data
public class ApiInfoParam extends PageParam {
@Condition(operator = Operator.like)
private String apiName;
}

View File

@@ -1,11 +1,12 @@
package com.gitee.sop.adminbackend.dao.entity;
import java.time.LocalDateTime;
import com.gitee.fastmybatis.annotation.Pk;
import com.gitee.fastmybatis.annotation.PkStrategy;
import com.gitee.fastmybatis.annotation.Table;
import lombok.Data;
import java.time.LocalDateTime;
import lombok.Data;
/**
@@ -35,6 +36,16 @@ public class ApiInfo {
*/
private String apiVersion;
/**
* 接口描述
*/
private String description;
/**
* 备注
*/
private String remark;
/**
* 接口class
*/
@@ -61,7 +72,7 @@ public class ApiInfo {
private Integer isNeedToken;
/**
* 状态,1-启用,0-禁用
* 1启用2禁用
*/
private Integer status;

View File

@@ -0,0 +1,15 @@
package com.gitee.sop.adminbackend.service.serve;
import com.gitee.fastmybatis.core.support.LambdaService;
import com.gitee.sop.adminbackend.dao.entity.ApiInfo;
import com.gitee.sop.adminbackend.dao.mapper.ApiInfoMapper;
import org.springframework.stereotype.Service;
/**
* @author 六如
*/
@Service
public class ApiInfoService implements LambdaService<ApiInfo, ApiInfoMapper> {
}

View File

@@ -1,7 +1,6 @@
package com.gitee.sop.adminbackend.service.sys.login;
import com.alibaba.nacos.shaded.com.google.common.collect.Sets;
import com.gitee.fastmybatis.core.query.Query;
import com.gitee.sop.adminbackend.common.ConfigKeyEnum;
import com.gitee.sop.adminbackend.common.exception.BizException;
import com.gitee.sop.adminbackend.config.Configs;
@@ -11,7 +10,7 @@ import com.gitee.sop.adminbackend.service.sys.login.dto.LoginDTO;
import com.gitee.sop.adminbackend.service.sys.login.dto.LoginForm;
import com.gitee.sop.adminbackend.service.sys.login.dto.LoginResult;
import com.gitee.sop.adminbackend.service.sys.login.dto.LoginUser;
import com.gitee.sop.adminbackend.service.sys.login.enums.AdminUserStatusEnum;
import com.gitee.sop.adminbackend.common.StatusEnum;
import com.gitee.sop.adminbackend.service.sys.login.enums.RegTypeEnum;
import com.gitee.sop.adminbackend.util.CopyUtil;
import com.gitee.sop.adminbackend.util.GenerateUtil;
@@ -26,7 +25,6 @@ import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@@ -68,7 +66,7 @@ public class LoginService {
}
private LoginUser buildLoginUser(SysAdminUser userInfo) {
if (AdminUserStatusEnum.of(userInfo.getStatus()) == AdminUserStatusEnum.DISABLED) {
if (StatusEnum.of(userInfo.getStatus()) == StatusEnum.DISABLED) {
throw new BizException("账号已禁用,请联系管理员");
}
// 登录成功
@@ -125,7 +123,7 @@ public class LoginService {
userInfo.setPassword(GenerateUtil.getUUID());
userInfo.setNickname(loginResult.getNickname());
userInfo.setAvatar("");
userInfo.setStatus(AdminUserStatusEnum.ENABLE.getStatus());
userInfo.setStatus(StatusEnum.ENABLE.getStatus());
userInfo.setRegType(loginResult.getRegTypeEnum().getValue());
userInfo.setEmail(loginResult.getEmail());
sysAdminUserService.save(userInfo);

View File

@@ -1,34 +0,0 @@
package com.gitee.sop.adminbackend.service.sys.login.enums;
import java.util.Objects;
/**
* @author 六如
*/
public enum AdminUserStatusEnum {
DISABLED((byte)0),
ENABLE((byte)1),
SET_PWD((byte)2),
;
private final int status;
public static AdminUserStatusEnum of(Integer value) {
for (AdminUserStatusEnum adminUserStatusEnum : AdminUserStatusEnum.values()) {
if (Objects.equals(adminUserStatusEnum.status, value)) {
return adminUserStatusEnum;
}
}
return DISABLED;
}
AdminUserStatusEnum(byte style) {
this.status = style;
}
public int getStatus() {
return status;
}
}

View File

@@ -5,7 +5,7 @@ import com.gitee.sop.adminbackend.dao.entity.SysAdminUser;
import com.gitee.sop.adminbackend.service.sys.SysAdminUserService;
import com.gitee.sop.adminbackend.service.sys.login.UserCacheManager;
import com.gitee.sop.adminbackend.service.sys.login.dto.LoginUser;
import com.gitee.sop.adminbackend.service.sys.login.enums.AdminUserStatusEnum;
import com.gitee.sop.adminbackend.common.StatusEnum;
import com.gitee.sop.adminbackend.util.CopyUtil;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
@@ -75,7 +75,7 @@ public class DefaultUserCacheManager implements UserCacheManager, InitializingBe
log.warn("登录用户不存在userId{}", id);
return null;
}
if (userInfo.getStatus() == AdminUserStatusEnum.DISABLED.getStatus()) {
if (userInfo.getStatus() == StatusEnum.DISABLED.getStatus()) {
log.warn("用户被禁用, userId:{}, username:{}, nickname:{}", userInfo.getId(), userInfo.getUsername(), userInfo.getNickname());
return null;
}

View File

@@ -6,9 +6,7 @@ import gradientString from "gradient-string";
import boxen, { type Options as BoxenOptions } from "boxen";
dayjs.extend(duration);
const welcomeMessage = gradientString("cyan", "magenta").multiline(
`您好! 欢迎使用 pure-admin 开源项目\n我们为您精心准备了下面两个贴心的保姆级文档\nhttps://pure-admin.github.io/pure-admin-doc\nhttps://pure-admin-utils.netlify.app`
);
const welcomeMessage = gradientString("cyan", "magenta").multiline(`SOP Admin`);
const boxenOptions: BoxenOptions = {
padding: 0.5,

View File

@@ -93,7 +93,7 @@ export default defineFlatConfig([
"@typescript-eslint/prefer-as-const": "warn",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-import-type-side-effects": "error",
"@typescript-eslint/no-import-type-side-effects": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/consistent-type-imports": [
"error",

View File

@@ -8,7 +8,7 @@
name="viewport"
content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0"
/>
<title>pure-admin-thin</title>
<title>SOP Admin</title>
<link rel="icon" href="/favicon.ico" />
<script>
window.process = {};

View File

@@ -5,7 +5,7 @@ import { defineFakeRoute } from "vite-plugin-fake-server/client";
* 服务管理
*/
const apiRouter = {
path: "/serviceManage",
path: "/serve",
meta: {
title: "服务管理",
icon: "ri:server-line",
@@ -13,7 +13,7 @@ const apiRouter = {
},
children: [
{
path: "/serviceManage/apiManage/index",
path: "/serve/api/index",
name: "ApiManage",
meta: {
title: "接口管理",

View File

@@ -1,5 +1,5 @@
{
"name": "pure-admin-thin",
"name": "SOP Admin",
"version": "5.8.0",
"private": true,
"type": "module",
@@ -55,6 +55,7 @@
"@vueuse/motion": "2.2.3",
"animate.css": "4.1.1",
"axios": "1.7.4",
"crypto-js": "4.2.0",
"dayjs": "1.11.12",
"echarts": "5.5.1",
"element-plus": "2.8.0",

View File

@@ -29,6 +29,9 @@ importers:
axios:
specifier: 1.7.4
version: 1.7.4
crypto-js:
specifier: 4.2.0
version: 4.2.0
dayjs:
specifier: 1.11.12
version: 1.11.12
@@ -1605,6 +1608,9 @@ packages:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'}
crypto-js@4.2.0:
resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==}
css-declaration-sorter@6.4.1:
resolution: {integrity: sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==}
engines: {node: ^10 || ^12 || >=14}
@@ -5390,6 +5396,8 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
crypto-js@4.2.0: {}
css-declaration-sorter@6.4.1(postcss@8.4.41):
dependencies:
postcss: 8.4.41

View File

@@ -1,6 +1,6 @@
{
"Version": "5.8.0",
"Title": "PureAdmin",
"Title": "SOP Admin",
"FixedHeader": true,
"HiddenSideBar": false,
"MultiTagsCache": false,
@@ -12,8 +12,8 @@
"OverallStyle": "light",
"Grey": false,
"Weak": false,
"HideTabs": false,
"HideFooter": false,
"HideTabs": true,
"HideFooter": true,
"Stretch": false,
"SidebarStatus": true,
"EpThemeColor": "#409EFF",

View File

@@ -48,9 +48,10 @@ const { t, locale, translationCh, translationEn } = useTranslationLang();
<LayNavMix v-if="layout === 'mix'" />
<div v-if="layout === 'vertical'" class="vertical-header-right">
<!-- 菜单搜索 -->
<!-- 菜单搜索
<LaySearch id="header-search" />
<!-- 国际化 -->
-->
<!-- 国际化
<el-dropdown id="header-translation" trigger="click">
<GlobalizationIcon
class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-none"
@@ -82,14 +83,19 @@ const { t, locale, translationCh, translationEn } = useTranslationLang();
</el-dropdown-menu>
</template>
</el-dropdown>
<!-- 全屏 -->
-->
<!-- 全屏
<LaySidebarFullScreen id="full-screen" />
<!-- 消息通知 -->
-->
<!-- 消息通知
<LayNotice id="header-notice" />
-->
<!-- 退出登录 -->
<el-dropdown trigger="click">
<span class="el-dropdown-link navbar-bg-hover select-none">
<!-- 头像
<img :src="userAvatar" :style="avatarsStyle" />
-->
<p v-if="username" class="dark:text-white">{{ username }}</p>
</span>
<template #dropdown>
@@ -104,6 +110,7 @@ const { t, locale, translationCh, translationEn } = useTranslationLang();
</el-dropdown-menu>
</template>
</el-dropdown>
<!-- 设置
<span
class="set-icon navbar-bg-hover"
:title="t('buttons.pureOpenSystemSet')"
@@ -111,6 +118,7 @@ const { t, locale, translationCh, translationEn } = useTranslationLang();
>
<IconifyIconOffline :icon="Setting" />
</span>
-->
</div>
</div>
</template>

View File

@@ -0,0 +1,14 @@
export type Result = {
success: boolean;
data: object;
};
export type PageResult = {
success: boolean;
msg: "";
code: "";
data: {
total: 0;
list: Array<any>;
};
};

View File

@@ -37,7 +37,7 @@ import {
* 如何排除文件请看https://cn.vitejs.dev/guide/features.html#negative-patterns
*/
const modules: Record<string, any> = import.meta.glob(
["./modules/**/*.ts", "!./modules/**/remaining.ts"],
["./modules/**/*.ts", "!./modules/**/remaining.ts", "!./modules/**/error.ts"],
{
eager: true
}

View File

@@ -22,6 +22,7 @@ import globalization from "@/assets/svg/globalization.svg?component";
import Lock from "@iconify-icons/ri/lock-fill";
import Check from "@iconify-icons/ep/check";
import User from "@iconify-icons/ri/user-3-fill";
import CryptoJS from "crypto-js";
defineOptions({
name: "Login"
@@ -40,8 +41,8 @@ const { title, getDropdownItemStyle, getDropdownItemClass } = useNav();
const { locale, translationCh, translationEn } = useTranslationLang();
const ruleForm = reactive({
username: "admin",
password: "admin123"
username: "",
password: ""
});
const onLogin = async (formEl: FormInstance | undefined) => {
@@ -49,8 +50,10 @@ const onLogin = async (formEl: FormInstance | undefined) => {
await formEl.validate((valid, fields) => {
if (valid) {
loading.value = true;
const pwd = ruleForm.password;
const hash = CryptoJS.SHA256(pwd).toString();
useUserStoreHook()
.loginByUsername({ username: ruleForm.username, password: "admin123" })
.loginByUsername({ username: ruleForm.username, password: hash })
.then(res => {
if (res.success) {
// 获取后端路由

View File

@@ -3,8 +3,8 @@ import type { FormRules } from "element-plus";
import { $t, transformI18n } from "@/plugins/i18n";
/** 密码正则密码格式应为8-18位数字、字母、符号的任意两种组合 */
export const REGEXP_PWD =
/^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)]|[()])+$)(?!^.*[\u4E00-\u9FA5].*$)([^(0-9a-zA-Z)]|[()]|[a-z]|[A-Z]|[0-9]){8,18}$/;
// export const REGEXP_PWD =
// /^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)]|[()])+$)(?!^.*[\u4E00-\u9FA5].*$)([^(0-9a-zA-Z)]|[()]|[a-z]|[A-Z]|[0-9]){8,18}$/;
/** 登录校验 */
const loginRules = reactive(<FormRules>{
@@ -13,8 +13,6 @@ const loginRules = reactive(<FormRules>{
validator: (rule, value, callback) => {
if (value === "") {
callback(new Error(transformI18n($t("login.purePassWordReg"))));
} else if (!REGEXP_PWD.test(value)) {
callback(new Error(transformI18n($t("login.purePassWordRuleReg"))));
} else {
callback();
}

View File

@@ -0,0 +1,315 @@
import { computed, ref } from "vue";
import {
type PlusColumn,
useTable,
type PageInfo,
type FieldValues,
type ButtonsCallBackParams
} from "plus-pro-components";
import { type PageResult } from "@/model";
import { http } from "@/utils/http";
import { ElMessage } from "element-plus";
// 后端请求接口
const apiUrl = {
page: "/serve/api/page",
add: "/serve/api/add",
update: "/serve/api/update",
del: "/serve/api/delete"
};
// 查询表单对象
export const searchFormData = ref({
apiName: "",
pageIndex: 1,
pageSize: 10
});
// 表格对象
export const {
tableData,
total,
pageInfo,
buttons: actionButtons
} = useTable<any[]>();
// 默认每页条数,默认10
pageInfo.value.pageSize = 10;
// 查询表单字段定义
export const searchFormColumns: PlusColumn[] = [
{
label: "接口名称",
prop: "apiName"
}
];
// 表格字段定义
export const tableColumns: PlusColumn[] = [
{
label: "应用名称",
prop: "application"
},
{
label: "接口名称",
prop: "apiName"
},
{
label: "版本号",
prop: "apiVersion",
width: 80
},
{
label: "接口描述",
prop: "description"
},
{
label: "需要授权",
prop: "isPermission",
width: 100,
valueType: "select",
options: [
{
label: "否",
value: 0,
color: "red"
},
{
label: "是",
value: 1,
color: "green"
}
]
},
{
label: "需要token",
prop: "isNeedToken",
width: 100,
valueType: "select",
options: [
{
label: "否",
value: 0,
color: "red"
},
{
label: "是",
value: 1,
color: "green"
}
]
},
{
label: "状态",
prop: "status",
width: 80,
valueType: "select",
options: [
{
label: "禁用",
value: 0,
color: "red"
},
{
label: "启用",
value: 1,
color: "green"
}
]
},
{
label: "添加时间",
prop: "addTime"
}
];
actionButtons.value = [
{
// 修改
text: "修改",
code: "edit",
props: {
type: "primary"
},
show: computed(() => true),
onClick(params: ButtonsCallBackParams) {
if (params?.formRefs) {
// isEdit v0.1.8 新增
const isEdit = params.formRefs[0].isEdit.value;
isEdit
? params.formRefs[0]?.stopCellEdit()
: params.formRefs[0]?.startCellEdit();
}
}
},
{
// 删除
text: "删除",
code: "delete",
props: {
type: "danger"
},
confirm: {
options: { draggable: true }
},
onClick(params: ButtonsCallBackParams) {
console.log(params, "onClick");
},
onConfirm(params: ButtonsCallBackParams) {
console.log(params, "onConfirm");
},
onCancel(params: ButtonsCallBackParams) {
console.log(params, "onCancel");
}
}
];
// 弹窗表单
export const dlgShow = ref(false);
export const editFormData = ref<FieldValues>({
application: "",
status: 1,
isPermission: 0,
isNeedToken: 0
});
export const editFormRules = {
application: [{ required: true, message: "请输入应用名称" }],
apiName: [{ required: true, message: "请输入接口名称" }],
apiVersion: [{ required: true, message: "请输入版本号" }],
description: [{ required: true, message: "请输入接口描述" }]
};
export const handleDlgOpen = () => {
dlgShow.value = true;
};
export const handleSave = () => {
http
.post<PageResult, any>(apiUrl.add, { data: editFormData.value })
.then(resp => {
if (resp.success) {
ElMessage({
message: "保存成功",
type: "success"
});
dlgShow.value = false;
search();
} else {
console.log(resp);
ElMessage.error(`保存失败:${resp.msg}`);
}
});
};
export const editFormColumns: PlusColumn[] = [
{
label: "应用名称",
prop: "application",
valueType: "copy"
},
{
label: "接口名称",
prop: "apiName",
valueType: "copy"
},
{
label: "版本号",
prop: "apiVersion",
valueType: "copy"
},
{
label: "接口描述",
prop: "description",
valueType: "copy"
},
{
label: "备注",
prop: "remark",
valueType: "textarea",
fieldProps: {
maxlength: 10,
showWordLimit: true,
autosize: { minRows: 2, maxRows: 4 }
}
},
{
label: "需要授权",
prop: "isPermission",
valueType: "radio",
options: [
{
label: "否",
value: 0,
color: "red"
},
{
label: "是",
value: 1,
color: "green"
}
]
},
{
label: "需要token",
prop: "isNeedToken",
valueType: "radio",
options: [
{
label: "否",
value: 0,
color: "red"
},
{
label: "是",
value: 1,
color: "green"
}
]
},
{
label: "状态",
prop: "status",
valueType: "radio",
options: [
{
label: "禁用",
value: 0,
color: "red"
},
{
label: "启用",
value: 1,
color: "green"
}
]
}
];
// 点击查询按钮
export const handleSearch = () => {
pageInfo.value.page = 1;
search();
};
// 查询
const search = async () => {
try {
const { data } = await doSearch();
tableData.value = data.list;
total.value = data.total;
} catch (error) {}
};
// 请求接口
const doSearch = async () => {
// 查询参数
const data = searchFormData.value;
// 添加分页参数
data.pageIndex = pageInfo.value.page;
data.pageSize = pageInfo.value.pageSize;
return http.get<PageResult, any>(apiUrl.page, { params: data });
};
// 分页事件
export const handlePaginationChange = (_pageInfo: PageInfo): void => {
pageInfo.value = _pageInfo;
search();
};
// 页面加载
search();

View File

@@ -0,0 +1,61 @@
<script setup lang="ts">
import {
actionButtons,
dlgShow,
editFormColumns,
editFormData,
editFormRules,
handleDlgOpen,
handlePaginationChange,
handleSave,
handleSearch,
pageInfo,
searchFormColumns,
searchFormData,
tableColumns,
tableData,
total
} from "./index";
</script>
<template>
<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"
:action-bar="{ buttons: actionButtons, width: 120 }"
:pagination="{
total,
modelValue: pageInfo,
pageSizeList: [10, 20, 50, 100],
align: 'right'
}"
@paginationChange="handlePaginationChange"
>
<template #title>
<el-button type="primary" @click="handleDlgOpen">新增接口</el-button>
</template>
</PlusTable>
<PlusDialogForm
v-model:visible="dlgShow"
v-model="editFormData"
label-width="200px"
:form="{
columns: editFormColumns,
rules: editFormRules,
labelWidth: '100px',
labelPosition: 'right'
}"
@confirm="handleSave"
/>
</el-card>
</template>

View File

@@ -1,151 +0,0 @@
<script setup lang="ts">
import { ref } from "vue";
import { type PlusColumn, useTable, PageInfo } from "plus-pro-components";
const state = ref({
status: "0",
time: new Date().toString()
});
const columns: PlusColumn[] = [
{
label: "接口名称",
prop: "name"
}
];
const handleChange = (values: any) => {
console.log(values, "change");
};
const handleSearch = (values: any) => {
console.log(values, "search");
};
const handleRest = () => {
console.log("handleRest");
};
interface TableRow {
id: number;
name: string;
status: string;
tag: string;
time: Date;
}
const TestServe = {
getList: async () => {
const data = Array.from({ length: 3 }).map((item, index) => {
return {
id: index,
name: index + "name",
status: String(index % 3),
tag: "success",
time: new Date()
};
});
return {
data: data as TableRow[],
total: data.length
};
}
};
const { tableData, total, pageInfo } = useTable<TableRow[]>();
pageInfo.value.pageSize = 10;
const tableConfig: PlusColumn[] = [
{
label: "名称",
prop: "name",
disabledHeaderFilter: true,
tooltip: "名称",
tableColumnProps: {
align: "center",
showOverflowTooltip: true
}
},
{
label: "状态",
prop: "status",
valueType: "select",
options: [
{
label: "未解决",
value: "0",
color: "red"
},
{
label: "已解决",
value: "1",
color: "blue"
},
{
label: "解决中",
value: "2",
color: "yellow"
},
{
label: "失败",
value: "3",
color: "red"
}
]
},
{
label: "标签",
prop: "tag",
valueType: "tag",
fieldProps: (value: string) => {
return { type: value };
}
},
{
label: "时间",
prop: "time",
valueType: "date-picker"
}
];
const getList = async () => {
try {
const { data, total: dataTotal } = await TestServe.getList();
tableData.value = data;
total.value = dataTotal;
} catch (error) {}
};
const handlePaginationChange = (_pageInfo: PageInfo): void => {
pageInfo.value = _pageInfo;
getList();
};
getList();
</script>
<template>
<el-card>
<PlusSearch
v-model="state"
:columns="columns"
:show-number="2"
label-position="right"
:has-reset="false"
@change="handleChange"
@search="handleSearch"
@reset="handleRest"
/>
<el-divider />
<PlusTable
:columns="tableConfig"
:table-data="tableData"
:pagination="{
total,
modelValue: pageInfo,
pageSizeList: [10, 20, 50, 100],
align: 'right'
}"
>
<template #title>
<el-button type="primary">新增接口</el-button>
</template>
</PlusTable>
</el-card>
</template>

View File

@@ -5,5 +5,5 @@ defineOptions({
</script>
<template>
<h1>Pure-Admin-Thin国际化版本</h1>
<h1>欢迎使用SOP Admin</h1>
</template>

View File

@@ -24,7 +24,14 @@ export default ({ mode }: ConfigEnv): UserConfigExport => {
port: VITE_PORT,
host: "0.0.0.0",
// 本地跨域代理 https://cn.vitejs.dev/config/server-options.html#server-proxy
proxy: {},
proxy: {
"/api": {
// 这里填写后端地址
target: "http://127.0.0.1:8082",
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, "")
}
},
// 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布
warmup: {
clientFiles: ["./index.html", "./src/{views,components}/*"]

View File

@@ -11,20 +11,54 @@ import java.io.Serializable;
public class ApiInfoDTO implements Serializable {
private static final long serialVersionUID = 2183251167679411550L;
/**
* 应用名称
*/
private String application;
/**
* 接口名称
*/
private String apiName;
/**
* 版本号
*/
private String apiVersion;
/**
* 接口描述
*/
private String description;
/**
* 备注
*/
private String remark;
/**
* 接口class
*/
private String interfaceClassName;
/**
* 方法名称
*/
private String methodName;
/**
* 参数信息
*/
private String paramInfo;
/**
* 接口是否需要授权访问
*/
private Integer isPermission;
/**
* 是否需要appAuthToken
*/
private Integer isNeedToken;
private Integer status;

View File

@@ -10,7 +10,7 @@ import lombok.Getter;
@Getter
public enum StatusEnum {
ENABLE(1),
DISABLE(2);
DISABLE(0);
private final int value;

View File

@@ -1,7 +1,6 @@
package com.gitee.sop.index.dao.entity;
import java.time.LocalDateTime;
import java.util.Date;
import com.gitee.fastmybatis.annotation.Pk;
import com.gitee.fastmybatis.annotation.PkStrategy;
@@ -37,6 +36,16 @@ public class ApiInfo {
*/
private String apiVersion;
/**
* 接口描述
*/
private String description;
/**
* 备注
*/
private String remark;
/**
* 接口class
*/
@@ -63,7 +72,7 @@ public class ApiInfo {
private Integer isNeedToken;
/**
* 状态,1-启用,0-禁用
* 1启用2禁用
*/
private Integer status;

View File

@@ -11,25 +11,54 @@ import java.io.Serializable;
public class RegisterDTO implements Serializable {
private static final long serialVersionUID = 2183251167679411550L;
/**
* 应用名称
*/
private String application;
/**
* 接口名称
*/
private String apiName;
/**
* 版本号
*/
private String apiVersion;
/**
* 接口描述
*/
private String description;
/**
* 备注
*/
private String remark;
/**
* 接口class
*/
private String interfaceClassName;
/**
* 方法名称
*/
private String methodName;
/**
* 字段信息
*
* [{"name":"id": "type":"java.lang.Integer"}]
* 参数信息
*/
private String paramInfo;
/**
* 接口是否需要授权访问
*/
private Integer isPermission;
/**
* 是否需要appAuthToken
*/
private Integer isNeedToken;