├── .gitignore ├── README.md ├── admin-server ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── xm │ │ └── admin │ │ ├── AdminApplication.java │ │ ├── common │ │ ├── annotation │ │ │ └── SystemLog.java │ │ ├── aop │ │ │ └── SystemLogAspect.java │ │ ├── constant │ │ │ └── SecurityConstant.java │ │ ├── handler │ │ │ └── MyMetaObjectHandler.java │ │ └── utils │ │ │ ├── ImageUtil.java │ │ │ ├── IpInfoUtil.java │ │ │ ├── JwtUtil.java │ │ │ ├── ObjectUtil.java │ │ │ ├── ResponseUtil.java │ │ │ ├── SecurityUtil.java │ │ │ └── ThreadPoolUtil.java │ │ ├── config │ │ ├── auth │ │ │ ├── WebMvcConfig.java │ │ │ ├── jwt │ │ │ │ ├── JwtAuthenticationFilter.java │ │ │ │ └── JwtConfig.java │ │ │ └── security │ │ │ │ ├── AuthConfig.java │ │ │ │ ├── CustomUserDetailsService.java │ │ │ │ ├── IgnoreConfig.java │ │ │ │ ├── MySecurityException.java │ │ │ │ ├── RbacAuthorityService.java │ │ │ │ ├── SecurityConfig.java │ │ │ │ ├── SecurityHandlerConfig.java │ │ │ │ └── UserPrincipal.java │ │ ├── exception │ │ │ ├── BaseException.java │ │ │ └── RestCtrlExceptionHandler.java │ │ └── mybatisplus │ │ │ └── MybatisPlusConfig.java │ │ └── module │ │ ├── content │ │ ├── controller │ │ │ ├── ConArticleCategoryController.java │ │ │ └── ConArticleInfoController.java │ │ ├── entity │ │ │ ├── ConArticleCategory.java │ │ │ └── ConArticleInfo.java │ │ ├── mapper │ │ │ ├── ConArticleCategoryMapper.java │ │ │ └── ConArticleInfoMapper.java │ │ ├── payload │ │ │ └── ArticleCategoryAddEditRequest.java │ │ └── service │ │ │ ├── IConArticleCategoryService.java │ │ │ ├── IConArticleInfoService.java │ │ │ └── impl │ │ │ ├── ConArticleCategoryServiceImpl.java │ │ │ └── ConArticleInfoServiceImpl.java │ │ ├── storage │ │ ├── controller │ │ │ └── FileController.java │ │ └── service │ │ │ ├── IStorage.java │ │ │ ├── StorageFactory.java │ │ │ └── impl │ │ │ ├── LocalStorageImpl.java │ │ │ └── aliOssStorageImpl.java │ │ └── sys │ │ ├── controller │ │ ├── AccountController.java │ │ ├── AdminLogController.java │ │ ├── AuthController.java │ │ ├── CaptchaController.java │ │ ├── SysAdminController.java │ │ ├── SysDepartmentController.java │ │ ├── SysPermissionController.java │ │ └── SysRoleController.java │ │ ├── entity │ │ ├── SysAdmin.java │ │ ├── SysAdminLog.java │ │ ├── SysDepartment.java │ │ ├── SysPermission.java │ │ ├── SysRole.java │ │ └── SysRolePermission.java │ │ ├── mapper │ │ ├── SysAdminLogMapper.java │ │ ├── SysAdminMapper.java │ │ ├── SysDepartmentMapper.java │ │ ├── SysPermissionMapper.java │ │ ├── SysRoleMapper.java │ │ └── SysRolePermissionMapper.java │ │ ├── payload │ │ ├── AccountEditRequest.java │ │ ├── AdminAddRequest.java │ │ ├── AdminEditRequest.java │ │ ├── DepartmentAddEditRequest.java │ │ ├── LoginRequest.java │ │ ├── MenuAddEditRequest.java │ │ ├── ModifyPasswordRequest.java │ │ ├── RoleAddEditRequest.java │ │ └── UnlockRequest.java │ │ └── service │ │ ├── ISysAdminLogService.java │ │ ├── ISysAdminService.java │ │ ├── ISysDepartmentService.java │ │ ├── ISysPermissionService.java │ │ ├── ISysRolePermissionService.java │ │ ├── ISysRoleService.java │ │ └── impl │ │ ├── SysAdminLogServiceImpl.java │ │ ├── SysAdminServiceImpl.java │ │ ├── SysDepartmentServiceImpl.java │ │ ├── SysPermissionServiceImpl.java │ │ ├── SysRolePermissionServiceImpl.java │ │ └── SysRoleServiceImpl.java │ └── resources │ ├── application-dev.yml │ ├── application.yml │ ├── banner.txt │ ├── mapper │ ├── content │ │ ├── ConArticleCategoryMapper.xml │ │ └── ConArticleInfoMapper.xml │ └── sys │ │ ├── SysAdminLogMapper.xml │ │ ├── SysAdminMapper.xml │ │ ├── SysDepartmentMapper.xml │ │ ├── SysPermissionMapper.xml │ │ ├── SysRoleMapper.xml │ │ └── SysRolePermissionMapper.xml │ └── static │ ├── _app.config.js │ ├── assets │ ├── AccountDetail.984f65a6.js │ ├── AccountModal.058c039b.js │ ├── ArticleAddOrEdit.37728884.js │ ├── ArticleCategoryModal.5350b910.js │ ├── ArticleDetail.c5669fcb.js │ ├── BaseSetting.1b473720.css │ ├── BaseSetting.e577605c.js │ ├── Breadcrumb.3f26edbd.js │ ├── Breadcrumb.45a81991.css │ ├── CategoryTree.8cc65905.js │ ├── DeptModal.72ed0467.js │ ├── DeptTree.e05362dd.js │ ├── DetailModal.12e96179.js │ ├── DetailModal.vue_vue&type=script&setup=true&lang.a637f957.css │ ├── DetailModal.vue_vue&type=script&setup=true&lang.a6c65b40.js │ ├── DropMenuItem.f170c93a.js │ ├── ErrorAction.6e17c42b.js │ ├── Exception.1646ace5.css │ ├── Exception.74066454.js │ ├── FrameBlank.9b579f4b.js │ ├── GrowCard.511387e6.js │ ├── GrowCard.vue_vue&type=script&setup=true&lang.c91a4575.js │ ├── InputNumberItem.3c9011c4.js │ ├── InputNumberItem.5677bd64.css │ ├── LockModal.0068f88c.css │ ├── LockModal.bb45babe.js │ ├── LockPage.801c6251.js │ ├── LockPage.a757c476.css │ ├── Login.47363f68.js │ ├── Login.ede6bba2.css │ ├── LoginForm.3ed32c4a.js │ ├── LoginFormTitle.a551ed0c.js │ ├── MenuDrawer.005571a5.js │ ├── RoleDrawer.924f06c2.js │ ├── SalesProductPie.10cc1bf2.js │ ├── SalesProductPie.vue_vue&type=script&setup=true&lang.bbaf9b94.js │ ├── SecureSetting.3d063fe8.js │ ├── SecureSetting.7b2149bf.css │ ├── SelectItem.3b3b269f.css │ ├── SelectItem.f56d58cf.js │ ├── SessionTimeoutLogin.14f69a36.js │ ├── SessionTimeoutLogin.69dc390d.css │ ├── SettingFooter.82157ad7.js │ ├── SettingFooter.b4008314.css │ ├── SiderTrigger.ede96a0d.js │ ├── SiteAnalysis.447a5d4d.js │ ├── SiteAnalysis.vue_vue&type=script&setup=true&lang.27cd1c31.js │ ├── SwitchItem.24688c5a.css │ ├── SwitchItem.b4b07e3d.js │ ├── ThemeColorPicker.4d941433.js │ ├── ThemeColorPicker.8eb61909.css │ ├── Tree.vue_vue&type=style&index=0&lang.200156f7.js │ ├── Tree.vue_vue&type=style&index=0&lang.4ab73e60.css │ ├── TypePicker.25c7ab2c.js │ ├── TypePicker.8747a11f.css │ ├── VisitAnalysis.d8fd8bbd.js │ ├── VisitAnalysis.vue_vue&type=script&setup=true&lang.d605ffa3.js │ ├── VisitAnalysisBar.35857a6a.js │ ├── VisitAnalysisBar.vue_vue&type=script&setup=true&lang.3ad8168a.js │ ├── VisitRadar.131b66db.js │ ├── VisitRadar.vue_vue&type=script&setup=true&lang.a4354064.js │ ├── VisitSource.224fe732.js │ ├── VisitSource.vue_vue&type=script&setup=true&lang.3b4d463f.js │ ├── app-antd-dark-theme-style.e3b0c442.css │ ├── app-theme-style.e3b0c442.css │ ├── article.563832c8.js │ ├── article.data.1868c4de.css │ ├── article.data.953a6c4c.js │ ├── data.3fa8ee9d.js │ ├── data.63adca46.js │ ├── en.a6412278.js │ ├── header.1b5fa5f8.jpg │ ├── header.d801b988.js │ ├── index.028f2289.css │ ├── index.039140af.js │ ├── index.0cd4441b.css │ ├── index.1bb9cac4.css │ ├── index.29cb9d1e.js │ ├── index.2d880448.js │ ├── index.317f90e2.css │ ├── index.32fb0083.css │ ├── index.35b5cf30.css │ ├── index.4114577a.css │ ├── index.43ba843e.css │ ├── index.45857338.css │ ├── index.553174f4.css │ ├── index.55e05163.css │ ├── index.5895bef3.js │ ├── index.5c7227e9.css │ ├── index.5c85c39a.js │ ├── index.65674215.css │ ├── index.669628f2.js │ ├── index.75b04f83.css │ ├── index.83a5ac4f.js │ ├── index.858880e5.js │ ├── index.8798174a.js │ ├── index.87cbc01e.css │ ├── index.8a75b316.js │ ├── index.8c033639.js │ ├── index.96fb498a.js │ ├── index.97dd7f2c.js │ ├── index.9981dd62.js │ ├── index.9d7e575d.js │ ├── index.a2505068.css │ ├── index.a5d2a860.css │ ├── index.ae6b460e.js │ ├── index.b0cce37f.js │ ├── index.b3b32c91.css │ ├── index.c4896195.css │ ├── index.cc9dad28.css │ ├── index.ccc15a38.css │ ├── index.ce94be82.css │ ├── index.dd601831.js │ ├── index.dde333d5.js │ ├── index.e5a92ddb.js │ ├── index.e7586e6f.css │ ├── index.eadf116e.js │ ├── index.f3a22dc9.js │ ├── index.fc649792.js │ ├── lock.fb37e799.js │ ├── login-bg-dark.424130e3.svg │ ├── login-bg.b265811a.svg │ ├── login-box-bg.9027741f.svg │ ├── logo.63028018.png │ ├── net-error.61b7e6df.svg │ ├── no-data.f7e550cc.svg │ ├── onMountedOrActivated.fcde6c3c.js │ ├── props.0a93851a.js │ ├── sortable.esm.b519ac50.js │ ├── system.194fce67.js │ ├── upload.79b9af6d.js │ ├── useContentViewHeight.e2ebf036.js │ ├── useECharts.a0aee6e9.js │ ├── useForm.91b099eb.js │ ├── useForm.db8a3c82.css │ ├── useSortable.15816348.js │ ├── useTable.5e4f4153.css │ ├── useTable.e6b840ff.js │ ├── useWindowSizeFn.51649442.js │ ├── vendor.54f9b785.js │ ├── vendor.bd035476.css │ └── zh_CN.f54ce4d0.js │ ├── favicon.ico │ ├── index.html │ └── resource │ ├── img │ ├── logo.png │ ├── pwa-192x192.png │ └── pwa-512x512.png │ └── tinymce │ ├── langs │ ├── en.js │ └── zh_CN.js │ └── skins │ └── ui │ ├── oxide-dark │ ├── content.inline.min.css │ ├── content.min.css │ ├── content.mobile.min.css │ ├── skin.min.css │ └── skin.mobile.min.css │ └── oxide │ ├── content.inline.min.css │ ├── content.min.css │ ├── content.mobile.min.css │ ├── fonts │ └── tinymce-mobile.woff │ ├── skin.min.css │ └── skin.mobile.min.css ├── api-server ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── xm │ │ └── api │ │ ├── CloudApplication.java │ │ ├── authorization │ │ ├── annotation │ │ │ ├── CurrentControlUser.java │ │ │ └── CurrentTerminalUser.java │ │ ├── config │ │ │ └── MvcConfig.java │ │ ├── constant │ │ │ └── TokenConstant.java │ │ ├── manager │ │ │ ├── TokenManager.java │ │ │ └── impl │ │ │ │ └── RedisTokenManager.java │ │ ├── resolvers │ │ │ ├── CurrentControlUserMethodArgumentResolver.java │ │ │ └── CurrentTerminalUserMethodArgumentResolver.java │ │ └── vo │ │ │ └── Token.java │ │ ├── config │ │ └── mybatisplus │ │ │ └── MybatisPlusConfig.java │ │ ├── enums │ │ └── VerifyCodeEnum.java │ │ ├── exception │ │ ├── RestErrorFilter.java │ │ └── RestExceptionHandler.java │ │ └── handler │ │ └── MyMetaObjectHandler.java │ └── resources │ ├── application-dev.yml │ ├── application-prod.yml │ ├── application-test.yml │ ├── application.yml │ ├── banner.txt │ └── mapper │ ├── article │ ├── ArticleCategoryMapper.xml │ └── ArticleInfoMapper.xml │ ├── control │ └── EnterpriseUserInfoMapper.xml │ └── terminal │ └── TerminalUserInfoMapper.xml ├── common-lib ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── xm │ └── common │ ├── entity │ ├── BaseEntity.java │ ├── BaseLogEntity.java │ └── BaseSimpleEntity.java │ ├── enums │ ├── CommonStatus.java │ └── ResultCodeEnums.java │ ├── utils │ ├── CaptchaUtil.java │ ├── CommonPageUtil.java │ └── ResultUtil.java │ └── vo │ ├── Captcha.java │ ├── ExtraVo.java │ └── Result.java ├── doc ├── accountList.jpg ├── articleList.jpg ├── contact.jpg ├── demo_menu.json ├── home.jpg ├── lock.jpg ├── login.jpg ├── roleAssign.jpg ├── skeleton.sql └── tinymce.jpg ├── generator ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── xm │ │ └── generator │ │ └── Generator.java │ └── resources │ └── templates │ ├── controller.java.btl │ ├── entity.java.btl │ ├── mapper.java.btl │ ├── mapper.xml.btl │ ├── service.java.btl │ └── serviceImpl.java.btl └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | target -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Vben Admin Java 2 | =================================== 3 | 这是一个Spring Boot的基础项目,前后端分离,前端修改自开源项目 https://github.com/anncwb/vue-vben-admin Vue3 + ts 4 | 5 | 管理后台: http://127.0.0.1:20004 (账号:admin, 密码:Aa000000) 6 | 7 | Api端服务: http://127.0.0.1:20001 (/api/user/login /api/user/register /api/user/info) 8 | 9 | 管理后台的模板项目 [vue-vben-admin](https://github.com/xiaomalover/vue-vben-admin "Vue Vben Admin"). 采用vue3 + ts编写 10 | 11 | 目录结构 12 | -------- 13 | 14 | ``` 15 | admin-server 管理后台服务 16 | api-server 接口服务 17 | common-lib 公共资源 18 | generator 基于Mybatis-plus的生成工具 19 | ``` 20 | 21 | 运行 22 | -------- 23 | 1, 先导入根目录下的数据库 24 | 25 | 2, 启动管理后台,API服务 26 | 27 | 3, Api服务测试请用postman 导入要目录下的 xm_boot.postman_collection.json 28 | 29 | 功能 30 | ------- 31 | 32 | 1. 完整的后台管理基础功能,包含权限管理RBAC(JWT + Security),文章管理(tinymce编辑器),图片上传(支持本地和oss,只需修改配置文件就能简单切换) 33 | 2. 简单的Api服务,用户注册,登录,token存储redis 34 | 3. 代码自动生成,可自己指定生成模块,基于Mybatis-Plus实现 35 | 36 | ... 37 | 38 | 开发注意 39 | --------- 40 | 开发后台模板,请先安装nodeJS和yarn到你的系统,然后进入vue-vben-admin目录中依次执行(这里是模板项目vue-vben-admin) 41 | ``` 42 | $ yarn install 43 | $ yarn serve 44 | ``` 45 | 如果开发完成了,请执行以下命令, 然后把dist目录里生成的资源文件拷贝到后台项目(vben admin java)对应的admin-server的resources的static目录下。 46 | ``` 47 | $ yarn build 48 | ``` 49 | 50 | 项目截屏 51 | --------- 52 | 53 | ![doc](doc/login.jpg) 54 | 55 | ![doc](doc/lock.jpg) 56 | 57 | ![doc](doc/home.jpg) 58 | 59 | ![doc](doc/articleList.jpg) 60 | 61 | ![doc](doc/accountList.jpg) 62 | 63 | ![doc](doc/roleAssign.jpg) 64 | 65 | ![doc](doc/tinymce.jpg) 66 | 67 | 68 | 联系作者 69 | --------- 70 | 如果有任何安装问题,请加我微信,如果你觉得对你有用,请帮忙star, 让更多人看到此项目,希望能帮到大家。 71 | 72 | ![doc](doc/contact.jpg) 73 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/AdminApplication.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cache.annotation.EnableCaching; 6 | import org.springframework.scheduling.annotation.EnableAsync; 7 | import org.springframework.scheduling.annotation.EnableScheduling; 8 | 9 | /** 10 | * @author xiaomalover 11 | */ 12 | @SpringBootApplication 13 | //启用缓存 14 | @EnableCaching 15 | //启用异步 16 | @EnableAsync 17 | //启用自带定时任务 18 | @EnableScheduling 19 | 20 | public class AdminApplication { 21 | 22 | public static void main(String[] args) { 23 | SpringApplication.run(AdminApplication.class, args); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/common/annotation/SystemLog.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.common.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 系统日志自定义注解 7 | * 8 | * @author xiaomalover 9 | */ 10 | @Target({ElementType.PARAMETER, ElementType.METHOD})//作用于参数或方法上 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Documented 13 | public @interface SystemLog { 14 | String description() default ""; 15 | } 16 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/common/constant/SecurityConstant.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.common.constant; 2 | 3 | /** 4 | * @author xiaomalover 5 | */ 6 | public interface SecurityConstant { 7 | 8 | /** 9 | * JWT 在 Redis 中保存的key前缀 10 | */ 11 | String REDIS_JWT_KEY_PREFIX = "security:jwt:"; 12 | 13 | /** 14 | * 匿名用户 用户名 15 | */ 16 | String ANONYMOUS_NAME = "匿名用户"; 17 | } 18 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/common/handler/MyMetaObjectHandler.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.common.handler; 2 | 3 | import cn.hutool.core.util.ObjectUtil; 4 | import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; 5 | import org.apache.ibatis.reflection.MetaObject; 6 | import org.springframework.security.core.context.SecurityContextHolder; 7 | import org.springframework.security.core.userdetails.UserDetails; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.util.ObjectUtils; 10 | 11 | /** 12 | * 填充器, 新增和修改时自动填充时间 13 | * 配合实体中的 @TableField(fill= FieldFill.INSERT) 和 @TableField(fill= FieldFill.INSERT_UPDATE) 使用 14 | * 15 | * @author xiaomalover 16 | */ 17 | @Component 18 | public class MyMetaObjectHandler implements MetaObjectHandler { 19 | 20 | @Override 21 | public void insertFill(MetaObject metaObject) { 22 | Long now = getTimestamp(); 23 | String user = getUser(); 24 | setFieldValByName("createdAt", now, metaObject); 25 | setFieldValByName("updatedAt", now, metaObject); 26 | setFieldValByName("createdBy", user, metaObject); 27 | setFieldValByName("updatedBy", user, metaObject); 28 | } 29 | 30 | @Override 31 | public void updateFill(MetaObject metaObject) { 32 | setFieldValByName("updatedAt", getTimestamp(), metaObject); 33 | setFieldValByName("updatedBy", getUser(), metaObject); 34 | } 35 | 36 | private Long getTimestamp() { 37 | return System.currentTimeMillis() / 1000; 38 | } 39 | 40 | private String getUser() { 41 | if (!ObjectUtils.isEmpty(SecurityContextHolder.getContext())) { 42 | if (!ObjectUtils.isEmpty(SecurityContextHolder.getContext().getAuthentication())) { 43 | 44 | if( SecurityContextHolder.getContext().getAuthentication().getPrincipal() instanceof UserDetails ) { 45 | UserDetails user = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 46 | if (ObjectUtil.isNotNull(user)) { 47 | return user.getUsername(); 48 | } 49 | } 50 | } 51 | } 52 | return "admin"; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/common/utils/ImageUtil.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.common.utils; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.File; 5 | import java.io.FileOutputStream; 6 | import java.io.InputStream; 7 | import java.net.HttpURLConnection; 8 | import java.net.URL; 9 | 10 | /** 11 | * 图片工具 12 | * 13 | * @author xiaomalover 14 | */ 15 | public class ImageUtil { 16 | 17 | public static void saveImageFromUrl(String imgUrl, String path) throws Exception { 18 | //new一个URL对象 19 | URL url = new URL(imgUrl); 20 | //打开链接 21 | HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 22 | //设置请求方式为"GET" 23 | conn.setRequestMethod("GET"); 24 | //超时响应时间为5秒 25 | conn.setConnectTimeout(5 * 1000); 26 | //通过输入流获取图片数据 27 | InputStream inStream = conn.getInputStream(); 28 | //得到图片的二进制数据,以二进制封装得到数据,具有通用性 29 | byte[] data = readInputStream(inStream); 30 | //new一个文件对象用来保存图片,默认保存当前工程根目录 31 | File imageFile = new File(path); 32 | 33 | //创建输出流 34 | FileOutputStream outStream = new FileOutputStream(imageFile); 35 | //写入数据 36 | outStream.write(data); 37 | //关闭输出流 38 | outStream.close(); 39 | } 40 | 41 | /** 42 | * 初始化目录,只创建一层 43 | * 44 | * @param dir 目录 45 | * @return 结果 46 | */ 47 | public static boolean initDir(String dir) { 48 | File file = new File(dir); 49 | if (!file.exists() && !file.isDirectory()) { 50 | return file.mkdirs(); 51 | } 52 | return true; 53 | } 54 | 55 | private static byte[] readInputStream(InputStream inStream) throws Exception { 56 | ByteArrayOutputStream outStream = new ByteArrayOutputStream(); 57 | //创建一个Buffer字符串 58 | byte[] buffer = new byte[1024]; 59 | //每次读取的字符串长度,如果为-1,代表全部读取完毕 60 | int len; 61 | //使用一个输入流从buffer里把数据读取出来 62 | while ((len = inStream.read(buffer)) != -1) { 63 | //用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度 64 | outStream.write(buffer, 0, len); 65 | } 66 | //关闭输入流 67 | inStream.close(); 68 | //把outStream里的数据写入内存 69 | return outStream.toByteArray(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/common/utils/IpInfoUtil.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.common.utils; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.stereotype.Component; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import java.net.InetAddress; 8 | import java.net.UnknownHostException; 9 | 10 | /** 11 | * IP地址工具类 12 | * 13 | * @author xiaomalover 14 | */ 15 | @Slf4j 16 | @Component 17 | public class IpInfoUtil { 18 | 19 | private static final String LOCAL_IP_V4 = "127.0.0.1"; 20 | 21 | private static final String LOCAL_IP_V6 = "0:0:0:0:0:0:0:1"; 22 | 23 | private static final String UNKNOWN = "0:0:0:0:0:0:0:1"; 24 | 25 | private static final String IP_SEPARATOR = ","; 26 | 27 | private static final int IP_MAX_LEGHTH = 15; 28 | 29 | /** 30 | * 获取客户端IP地址 31 | * 32 | * @param request 请求 33 | * @return ip地址 34 | */ 35 | public String getIpAddr(HttpServletRequest request) { 36 | 37 | String ip = request.getHeader("x-forwarded-for"); 38 | if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { 39 | ip = request.getHeader("Proxy-Client-IP"); 40 | } 41 | if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { 42 | ip = request.getHeader("WL-Proxy-Client-IP"); 43 | } 44 | if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { 45 | ip = request.getRemoteAddr(); 46 | if (LOCAL_IP_V4.equals(ip)) { 47 | //根据网卡取本机配置的IP 48 | InetAddress inetAddress = null; 49 | try { 50 | inetAddress = InetAddress.getLocalHost(); 51 | } catch (UnknownHostException e) { 52 | e.printStackTrace(); 53 | } 54 | if (inetAddress != null) { 55 | ip = inetAddress.getHostAddress(); 56 | } 57 | } 58 | } 59 | // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割 60 | if (ip != null && ip.length() > IP_MAX_LEGHTH) { 61 | if (ip.indexOf(IP_SEPARATOR) > 0) { 62 | ip = ip.substring(0, ip.indexOf(",")); 63 | } 64 | } 65 | if (LOCAL_IP_V6.equals(ip)) { 66 | ip = LOCAL_IP_V4; 67 | } 68 | return ip; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/common/utils/ObjectUtil.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.common.utils; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import com.google.gson.Gson; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | /** 10 | * 对象工具类 11 | * 12 | * @author xiaomalover 13 | */ 14 | public class ObjectUtil { 15 | 16 | public static String mapToString(Map paramMap) { 17 | 18 | if (paramMap == null) { 19 | return ""; 20 | } 21 | Map params = new HashMap<>(16); 22 | for (Map.Entry param : paramMap.entrySet()) { 23 | 24 | String key = param.getKey(); 25 | String paramValue = (param.getValue() != null && param.getValue().length > 0 ? param.getValue()[0] : ""); 26 | String obj; 27 | if (StrUtil.endWithIgnoreCase(param.getKey(), "password") || StrUtil.endWithIgnoreCase(param.getKey(), "pwd")) { 28 | obj = "******"; 29 | } else { 30 | obj = paramValue; 31 | } 32 | params.put(key, obj); 33 | } 34 | return new Gson().toJson(params); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/common/utils/SecurityUtil.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.common.utils; 2 | 3 | import cn.hutool.core.util.ObjectUtil; 4 | import com.xm.admin.common.constant.SecurityConstant; 5 | import com.xm.admin.config.auth.security.UserPrincipal; 6 | import org.springframework.security.core.context.SecurityContextHolder; 7 | import org.springframework.security.core.userdetails.UserDetails; 8 | 9 | /** 10 | *

11 | * Spring Security工具类 12 | *

13 | * 14 | */ 15 | public class SecurityUtil { 16 | /** 17 | * 获取当前登录用户用户名 18 | * 19 | * @return 当前登录用户用户名 20 | */ 21 | public static String getCurrentUsername() { 22 | UserPrincipal currentUser = getCurrentUser(); 23 | return ObjectUtil.isNull(currentUser) ? SecurityConstant.ANONYMOUS_NAME : currentUser.getUsername(); 24 | } 25 | 26 | /** 27 | * 获取当前登录用户信息 28 | * 29 | * @return 当前登录用户信息,匿名登录时,为null 30 | */ 31 | public static UserPrincipal getCurrentUser() { 32 | Object userInfo = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 33 | if (userInfo instanceof UserDetails) { 34 | return (UserPrincipal) userInfo; 35 | } 36 | return null; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/common/utils/ThreadPoolUtil.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.common.utils; 2 | 3 | import java.util.concurrent.ArrayBlockingQueue; 4 | import java.util.concurrent.BlockingQueue; 5 | import java.util.concurrent.ThreadPoolExecutor; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | /** 9 | * 线程池工具类 10 | * 11 | * @author xiaomalover 12 | */ 13 | public class ThreadPoolUtil { 14 | 15 | /** 16 | * 线程缓冲队列 17 | */ 18 | private static BlockingQueue bqueue = new ArrayBlockingQueue<>(100); 19 | 20 | /** 21 | * 核心线程数,会一直存活,即使没有任务,线程池也会维护线程的最少数量 22 | */ 23 | private static final int SIZE_CORE_POOL = 5; 24 | 25 | /** 26 | * 线程池维护线程的最大数量 27 | */ 28 | private static final int SIZE_MAX_POOL = 10; 29 | 30 | /** 31 | * 线程池维护线程所允许的空闲时间 32 | */ 33 | private static final long ALIVE_TIME = 2000; 34 | 35 | /** 36 | * 创建线程池 37 | * 拒绝策略 AbortPolicy(): 拒绝执行并抛出 RejectedExecutionException. 38 | * 拒绝策略 CallerRunsPolicy(): 用于被拒绝任务的处理程序,它直接在 execute 方法的调用线程中运行被拒绝的任务, 39 | * 如果执行程序已关闭,则会丢弃该任务。 40 | * 拒绝策略 DiscardPolicy() : 丢弃当前将要加入队列的任务本身。 41 | * 拒绝策略 DiscardOldestPolicy() : 丢弃任务队列中最旧任务。 42 | */ 43 | private static ThreadPoolExecutor pool = new ThreadPoolExecutor( 44 | SIZE_CORE_POOL, 45 | SIZE_MAX_POOL, 46 | ALIVE_TIME, 47 | TimeUnit.MILLISECONDS, 48 | bqueue, 49 | new ThreadPoolExecutor.CallerRunsPolicy() 50 | ); 51 | 52 | //静态代码块,启动时主动执行,只执行一次 53 | //不同于静态方法,静态属性,是通过访问类被动调用的 54 | static { 55 | //启动时开启核心线程 56 | pool.prestartAllCoreThreads(); 57 | } 58 | 59 | /** 60 | * 获取线程池 61 | * 62 | * @return 线程池 63 | */ 64 | public static ThreadPoolExecutor getPool() { 65 | return pool; 66 | } 67 | 68 | /** 69 | * 测试 70 | * 71 | * @param args 参数 72 | */ 73 | public static void main(String[] args) { 74 | System.out.println(pool.getPoolSize()); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/config/auth/WebMvcConfig.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.config.auth; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 6 | 7 | /** 8 | *

9 | * MVC配置 10 | *

11 | * 12 | */ 13 | @Configuration 14 | public class WebMvcConfig implements WebMvcConfigurer { 15 | 16 | private static final long MAX_AGE_SECS = 3600; 17 | 18 | @Override 19 | public void addCorsMappings(CorsRegistry registry) { 20 | registry.addMapping("/**").allowedOrigins("*").allowedMethods("HEAD", "OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE").maxAge(MAX_AGE_SECS); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/config/auth/jwt/JwtConfig.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.config.auth.jwt; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | /** 8 | *

9 | * JWT 配置 10 | *

11 | * 12 | */ 13 | @Configuration 14 | @ConfigurationProperties(prefix = "jwt.config") 15 | @Data 16 | public class JwtConfig { 17 | /** 18 | * jwt 加密 key,默认值:xkcoding. 19 | */ 20 | private String key = "xkcoding"; 21 | 22 | /** 23 | * jwt 过期时间,默认值:600000 {@code 10 分钟}. 24 | */ 25 | private Long ttl = 600000L; 26 | 27 | /** 28 | * 开启 记住我 之后 jwt 过期时间,默认值 604800000 {@code 7 天} 29 | */ 30 | private Long remember = 604800000L; 31 | } 32 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/config/auth/security/AuthConfig.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.config.auth.security; 2 | 3 | import com.xm.admin.config.auth.security.IgnoreConfig; 4 | import lombok.Data; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | *

10 | * 自定义配置 11 | *

12 | * 13 | */ 14 | @Configuration 15 | @ConfigurationProperties(prefix = "auth.config") 16 | @Data 17 | public class AuthConfig { 18 | /** 19 | * 不需要拦截的地址 20 | */ 21 | private IgnoreConfig ignores; 22 | } 23 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/config/auth/security/IgnoreConfig.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.config.auth.security; 2 | 3 | import com.google.common.collect.Lists; 4 | import lombok.Data; 5 | import java.util.List; 6 | 7 | /** 8 | *

9 | * 忽略配置 10 | *

11 | * 12 | */ 13 | @Data 14 | public class IgnoreConfig { 15 | /** 16 | * 需要忽略的 URL 格式,不考虑请求方法 17 | */ 18 | private List pattern = Lists.newArrayList(); 19 | 20 | /** 21 | * 需要忽略的 GET 请求 22 | */ 23 | private List get = Lists.newArrayList(); 24 | 25 | /** 26 | * 需要忽略的 POST 请求 27 | */ 28 | private List post = Lists.newArrayList(); 29 | 30 | /** 31 | * 需要忽略的 DELETE 请求 32 | */ 33 | private List delete = Lists.newArrayList(); 34 | 35 | /** 36 | * 需要忽略的 PUT 请求 37 | */ 38 | private List put = Lists.newArrayList(); 39 | 40 | /** 41 | * 需要忽略的 HEAD 请求 42 | */ 43 | private List head = Lists.newArrayList(); 44 | 45 | /** 46 | * 需要忽略的 PATCH 请求 47 | */ 48 | private List patch = Lists.newArrayList(); 49 | 50 | /** 51 | * 需要忽略的 OPTIONS 请求 52 | */ 53 | private List options = Lists.newArrayList(); 54 | 55 | /** 56 | * 需要忽略的 TRACE 请求 57 | */ 58 | private List trace = Lists.newArrayList(); 59 | } 60 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/config/auth/security/MySecurityException.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.config.auth.security; 2 | 3 | import com.xm.admin.config.exception.BaseException; 4 | import com.xm.common.enums.ResultCodeEnums; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | 8 | /** 9 | *

10 | * 全局异常 11 | *

12 | * 13 | */ 14 | @EqualsAndHashCode(callSuper = true) 15 | @Data 16 | public class MySecurityException extends BaseException { 17 | 18 | public MySecurityException(ResultCodeEnums resultCode) { 19 | super(resultCode); 20 | } 21 | 22 | public MySecurityException(ResultCodeEnums resultCode, Object data) { 23 | super(resultCode, data); 24 | } 25 | 26 | public MySecurityException(Integer code, String message) { 27 | super(code, message); 28 | } 29 | 30 | public MySecurityException(Integer code, String message, Object data) { 31 | super(code, message, data); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/config/auth/security/SecurityHandlerConfig.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.config.auth.security; 2 | 3 | import com.xm.admin.common.utils.ResponseUtil; 4 | import com.xm.common.enums.ResultCodeEnums; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.security.web.access.AccessDeniedHandler; 8 | 9 | /** 10 | *

11 | * Security 结果处理配置 12 | *

13 | * 14 | */ 15 | @Configuration 16 | public class SecurityHandlerConfig { 17 | 18 | @Bean 19 | public AccessDeniedHandler accessDeniedHandler() { 20 | return (request, response, accessDeniedException) -> ResponseUtil.renderJson(response, ResultCodeEnums.ACCESS_DENIED, null); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/config/exception/BaseException.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.config.exception; 2 | 3 | import com.xm.common.enums.ResultCodeEnums; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | *

10 | * 异常基类 11 | *

12 | * 13 | */ 14 | @NoArgsConstructor 15 | @EqualsAndHashCode(callSuper = true) 16 | @Data 17 | public class BaseException extends RuntimeException { 18 | private Integer code; 19 | private String message; 20 | private Object data; 21 | 22 | public BaseException(ResultCodeEnums resultCode) { 23 | super(resultCode.getMessage()); 24 | this.code = resultCode.getCode(); 25 | this.message = resultCode.getMessage(); 26 | } 27 | 28 | public BaseException(ResultCodeEnums resultCode, Object data) { 29 | this(resultCode); 30 | this.data = data; 31 | } 32 | 33 | public BaseException(Integer code, String message) { 34 | super(message); 35 | this.code = code; 36 | this.message = message; 37 | } 38 | 39 | public BaseException(Integer code, String message, Object data) { 40 | this(code, message); 41 | this.data = data; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/config/mybatisplus/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.config.mybatisplus; 2 | 3 | import com.baomidou.mybatisplus.annotation.DbType; 4 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 5 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 6 | import org.mybatis.spring.annotation.MapperScan; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | /** 11 | * Mybatis-plus 配置类 12 | * 13 | * @author xiaomalover 14 | */ 15 | @Configuration 16 | @MapperScan("com.xm.admin.module.*.mapper") 17 | public class MybatisPlusConfig { 18 | 19 | @Bean 20 | public MybatisPlusInterceptor mybatisPlusInterceptor() { 21 | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); 22 | interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2)); 23 | return interceptor; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/content/entity/ConArticleCategory.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.content.entity; 2 | 3 | import java.math.BigDecimal; 4 | import com.xm.common.entity.BaseEntity; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.experimental.Accessors; 8 | 9 | /** 10 | *

11 | * 12 | *

13 | * 14 | * @author xiaomalover 15 | * @since 2021-09-26 16 | */ 17 | @Data 18 | @EqualsAndHashCode(callSuper = true) 19 | @Accessors(chain = true) 20 | public class ConArticleCategory extends BaseEntity{ 21 | 22 | private static final long serialVersionUID = 1L; 23 | 24 | /** 25 | * 上级分类 26 | */ 27 | private Integer parentId; 28 | 29 | /** 30 | * 分类名称 31 | */ 32 | private String name; 33 | 34 | /** 35 | * 描述 36 | */ 37 | private String description; 38 | 39 | /** 40 | * 排序 41 | */ 42 | private BigDecimal sortOrder; 43 | 44 | /** 45 | * 状态(0无效;1有效) 46 | */ 47 | private Integer status; 48 | } 49 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/content/entity/ConArticleInfo.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.content.entity; 2 | 3 | import com.xm.common.entity.BaseEntity; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.experimental.Accessors; 7 | 8 | /** 9 | *

10 | * 文章表 11 | *

12 | * 13 | * @author xiaomalover 14 | * @since 2021-09-26 15 | */ 16 | @Data 17 | @EqualsAndHashCode(callSuper = true) 18 | @Accessors(chain = true) 19 | public class ConArticleInfo extends BaseEntity{ 20 | 21 | private static final long serialVersionUID = 1L; 22 | 23 | /** 24 | * 文章分类ID 25 | */ 26 | private String categoryId; 27 | 28 | /** 29 | * 文章标题 30 | */ 31 | private String title; 32 | 33 | /** 34 | * 文章封面图 35 | */ 36 | private String thumb; 37 | 38 | /** 39 | * 文章简介 40 | */ 41 | private String summary; 42 | 43 | /** 44 | * 文章内容 45 | */ 46 | private String content; 47 | 48 | /** 49 | * 作者 50 | */ 51 | private String author; 52 | 53 | /** 54 | * 状态(0无效;1有效) 55 | */ 56 | private Integer status; 57 | } 58 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/content/mapper/ConArticleCategoryMapper.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.content.mapper; 2 | 3 | import com.xm.admin.module.content.entity.ConArticleCategory; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | *

11 | * Mapper 接口 12 | *

13 | * 14 | * @author xiaomalover 15 | * @since 2021-09-26 16 | */ 17 | public interface ConArticleCategoryMapper extends BaseMapper { 18 | 19 | /** 20 | * 获取分类树 21 | * 22 | * @param categoryName 分类名 23 | * @param status 状态 24 | * @return 分类分树 25 | */ 26 | List> selectAllCategoryListMap(String categoryName, Integer status); 27 | } 28 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/content/mapper/ConArticleInfoMapper.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.content.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.xm.admin.module.content.entity.ConArticleInfo; 5 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 6 | import com.xm.common.vo.ExtraVo; 7 | import org.apache.ibatis.annotations.Param; 8 | import org.springframework.stereotype.Repository; 9 | 10 | import java.util.Map; 11 | 12 | /** 13 | *

14 | * 文章表 Mapper 接口 15 | *

16 | * 17 | * @author xiaomalover 18 | * @since 2021-09-26 19 | */ 20 | @Repository 21 | public interface ConArticleInfoMapper extends BaseMapper { 22 | 23 | /** 24 | * 获取文章列表 25 | * 26 | * @param page 分页 27 | * @param articleInfo 搜索参数 28 | * @param extraVo 额外参数 29 | * @return 文章列表 30 | */ 31 | IPage> selectArticleList(IPage> page, @Param("articleInfo") ConArticleInfo articleInfo, ExtraVo extraVo); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/content/payload/ArticleCategoryAddEditRequest.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.content.payload; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.NotEmpty; 6 | import java.io.Serializable; 7 | import java.math.BigDecimal; 8 | 9 | @Data 10 | public class ArticleCategoryAddEditRequest implements Serializable { 11 | 12 | private static final long serialVersionUID = 120759823816854783L; 13 | private Integer id; 14 | 15 | @NotEmpty(message = "请输入分类名称") 16 | private String categoryName; 17 | 18 | private Integer parentCategory; 19 | 20 | private BigDecimal orderNo; 21 | 22 | private Integer status; 23 | 24 | private String remark; 25 | } 26 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/content/service/IConArticleCategoryService.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.content.service; 2 | 3 | import com.xm.admin.module.content.entity.ConArticleCategory; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | *

11 | * 服务类 12 | *

13 | * 14 | * @author xiaomalover 15 | * @since 2021-09-26 16 | */ 17 | public interface IConArticleCategoryService extends IService { 18 | /** 19 | * 获取分类树 20 | * 21 | * @param categoryName 分类名 22 | * @param status 状态 23 | * @return 分类分树 24 | */ 25 | List> getCategoryTree(String categoryName, Integer status); 26 | } 27 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/content/service/IConArticleInfoService.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.content.service; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.xm.admin.module.content.entity.ConArticleInfo; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | import com.xm.common.vo.ExtraVo; 7 | 8 | import java.util.Map; 9 | 10 | /** 11 | *

12 | * 文章表 服务类 13 | *

14 | * 15 | * @author xiaomalover 16 | * @since 2021-09-26 17 | */ 18 | public interface IConArticleInfoService extends IService { 19 | 20 | /** 21 | * 获取文章列表 22 | * 23 | * @param page 分页 24 | * @param articleInfo 搜索参数 25 | * @param extraVo 额外参数 26 | * @return 文章列表 27 | */ 28 | IPage> getArticleList(IPage> page, ConArticleInfo articleInfo, ExtraVo extraVo); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/content/service/impl/ConArticleInfoServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.content.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.xm.admin.module.content.entity.ConArticleInfo; 5 | import com.xm.admin.module.content.mapper.ConArticleInfoMapper; 6 | import com.xm.admin.module.content.service.IConArticleInfoService; 7 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 8 | import com.xm.common.vo.ExtraVo; 9 | import org.springframework.stereotype.Service; 10 | 11 | import java.util.Map; 12 | 13 | /** 14 | *

15 | * 文章表 服务实现类 16 | *

17 | * 18 | * @author xiaomalover 19 | * @since 2021-09-26 20 | */ 21 | @Service 22 | public class ConArticleInfoServiceImpl extends ServiceImpl implements IConArticleInfoService { 23 | 24 | final ConArticleInfoMapper articleInfoMapper; 25 | 26 | public ConArticleInfoServiceImpl(ConArticleInfoMapper articleInfoMapper) { 27 | this.articleInfoMapper = articleInfoMapper; 28 | } 29 | 30 | @Override 31 | public IPage> getArticleList(IPage> page, ConArticleInfo articleInfo, ExtraVo extraVo) { 32 | return articleInfoMapper.selectArticleList(page, articleInfo, extraVo); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/storage/controller/FileController.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.storage.controller; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import com.xm.admin.module.storage.service.IStorage; 5 | import com.xm.admin.module.storage.service.StorageFactory; 6 | import com.xm.common.vo.Result; 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.web.bind.annotation.PostMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | import org.springframework.web.bind.annotation.RestController; 12 | import org.springframework.web.multipart.MultipartFile; 13 | 14 | @RestController 15 | @RequestMapping("/file") 16 | public class FileController { 17 | 18 | final private IStorage storage; 19 | 20 | public FileController(StorageFactory factoryForStrategy, @Value("${storage.type}") String storageType) { 21 | this.storage = factoryForStrategy.getStorage(storageType + "Impl"); 22 | } 23 | 24 | @PostMapping("/upload") 25 | public Result upload( 26 | @RequestParam MultipartFile file, 27 | @RequestParam(required = false) String folder) 28 | { 29 | if (StrUtil.isBlank(folder)) { 30 | folder = "localDefault"; 31 | } 32 | return storage.upload(file, folder); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/storage/service/IStorage.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.storage.service; 2 | 3 | import com.xm.common.vo.Result; 4 | import org.springframework.web.multipart.MultipartFile; 5 | 6 | public interface IStorage { 7 | 8 | /** 9 | * 上传文件 10 | * @param file 文件 11 | * @param folder 上传路径 12 | * @return 返回url地址 13 | */ 14 | Result upload(MultipartFile file, String folder); 15 | } 16 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/storage/service/StorageFactory.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.storage.service; 2 | 3 | import org.springframework.stereotype.Service; 4 | import java.util.Map; 5 | 6 | @Service 7 | public class StorageFactory { 8 | 9 | Map storageMap; 10 | 11 | public StorageFactory(Map storageMap) { 12 | this.storageMap = storageMap; 13 | } 14 | 15 | public IStorage getStorage(String name) throws RuntimeException{ 16 | IStorage strategy = storageMap.get(name); 17 | if(strategy == null) { 18 | throw new RuntimeException("Storage type not found."); 19 | } 20 | return strategy; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/controller/CaptchaController.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.controller; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import com.xm.common.utils.CaptchaUtil; 5 | import com.xm.common.utils.ResultUtil; 6 | import com.xm.common.vo.Captcha; 7 | import com.xm.common.vo.Result; 8 | import org.springframework.data.redis.core.StringRedisTemplate; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | import java.util.UUID; 14 | import java.util.concurrent.TimeUnit; 15 | 16 | /** 17 | * @author xiaomalover 18 | */ 19 | @RequestMapping("/captcha") 20 | @RestController 21 | public class CaptchaController { 22 | 23 | private final StringRedisTemplate redisTemplate; 24 | 25 | public CaptchaController(StringRedisTemplate redisTemplate) { 26 | this.redisTemplate = redisTemplate; 27 | } 28 | 29 | @GetMapping("/getCaptcha") 30 | public Result getCaptcha() { 31 | 32 | //生成验证码,并缓存 33 | String captchaId = UUID.randomUUID().toString().replace("-", ""); 34 | String code = new CaptchaUtil().randomStr(4); 35 | redisTemplate.opsForValue().set(captchaId, code, 3L, TimeUnit.MINUTES); 36 | 37 | //验证码生成图片 38 | CaptchaUtil vCode = new CaptchaUtil(108, 40, 4, 10, code); 39 | String codeBae64 = vCode.getBase64Captcha(); 40 | 41 | if (StrUtil.isBlank(codeBae64)) { 42 | return new ResultUtil<>().error("获取验证码失败"); 43 | } 44 | 45 | Captcha captcha = new Captcha(); 46 | captcha.setCaptchaId(captchaId); 47 | captcha.setImgBase64(codeBae64); 48 | 49 | return new ResultUtil<>().success(captcha); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/entity/SysAdmin.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableField; 4 | import com.xm.common.entity.BaseEntity; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.experimental.Accessors; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | *

13 | * 管理员表 14 | *

15 | * 16 | * @author xiaomalover 17 | * @since 2021-08-08 18 | */ 19 | @Data 20 | @EqualsAndHashCode(callSuper = true) 21 | @Accessors(chain = true) 22 | public class SysAdmin extends BaseEntity{ 23 | 24 | private static final long serialVersionUID = 1L; 25 | 26 | /** 27 | * 用户名 28 | */ 29 | private String username; 30 | 31 | /** 32 | * 密码 33 | */ 34 | private String password; 35 | 36 | /** 37 | * 头像 38 | */ 39 | private String avatar; 40 | 41 | /** 42 | * 描述 43 | */ 44 | private String description; 45 | 46 | /** 47 | * 邮箱 48 | */ 49 | private String email; 50 | 51 | /** 52 | * 手机号 53 | */ 54 | private String mobile; 55 | 56 | /** 57 | * 昵称 58 | */ 59 | private String nickname; 60 | 61 | /** 62 | * 性别:0男;1女 63 | */ 64 | private Integer sex; 65 | 66 | /** 67 | * 状态(0无效;1有效) 68 | */ 69 | private Integer status; 70 | 71 | /** 72 | * 角色ID 73 | */ 74 | private Integer roleId; 75 | 76 | /** 77 | * 部门ID 78 | */ 79 | private Integer departmentId; 80 | 81 | @TableField(exist = false) 82 | private String departmentTitle; 83 | 84 | @TableField(exist = false) 85 | private SysRole role; 86 | 87 | @TableField(exist = false) 88 | private List permissions; 89 | } 90 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/entity/SysAdminLog.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.entity; 2 | 3 | import com.xm.admin.common.utils.ObjectUtil; 4 | import com.xm.common.entity.BaseLogEntity; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.experimental.Accessors; 8 | 9 | import java.util.Map; 10 | 11 | /** 12 | *

13 | * 请求日志 14 | *

15 | * 16 | * @author xiaomalover 17 | * @since 2021-08-08 18 | */ 19 | @Data 20 | @EqualsAndHashCode(callSuper = true) 21 | @Accessors(chain = true) 22 | public class SysAdminLog extends BaseLogEntity { 23 | 24 | private static final long serialVersionUID = 1L; 25 | 26 | /** 27 | * 请求处理时长 28 | */ 29 | private Integer costTime; 30 | 31 | /** 32 | * 请求ip地址 33 | */ 34 | private String ip; 35 | 36 | /** 37 | * 请求ip信息 38 | */ 39 | private String ipInfo; 40 | 41 | /** 42 | * 日志名称 43 | */ 44 | private String name; 45 | 46 | /** 47 | * 请求参数 48 | */ 49 | private String requestParam; 50 | 51 | /** 52 | * 请求类型 53 | */ 54 | private String requestType; 55 | 56 | /** 57 | * 请求地址 58 | */ 59 | private String requestUrl; 60 | 61 | /** 62 | * 操作人 63 | */ 64 | private String username; 65 | 66 | /** 67 | * 转换请求参数为Json 68 | * 69 | * @param paramMap 参数 70 | */ 71 | public void setMapToParams(Map paramMap) { 72 | this.requestParam = ObjectUtil.mapToString(paramMap); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/entity/SysDepartment.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.entity; 2 | 3 | import java.math.BigDecimal; 4 | import com.xm.common.entity.BaseEntity; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.experimental.Accessors; 8 | 9 | /** 10 | *

11 | * 12 | *

13 | * 14 | * @author xiaomalover 15 | * @since 2021-08-08 16 | */ 17 | @Data 18 | @EqualsAndHashCode(callSuper = true) 19 | @Accessors(chain = true) 20 | public class SysDepartment extends BaseEntity{ 21 | 22 | private static final long serialVersionUID = 1L; 23 | 24 | /** 25 | * 上级部门 26 | */ 27 | private Integer parentId; 28 | 29 | /** 30 | * 部门名称 31 | */ 32 | private String name; 33 | 34 | /** 35 | * 描述 36 | */ 37 | private String description; 38 | 39 | /** 40 | * 排序 41 | */ 42 | private BigDecimal sortOrder; 43 | 44 | /** 45 | * 状态(0无效;1有效) 46 | */ 47 | private Integer status; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/entity/SysPermission.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.entity; 2 | 3 | import java.math.BigDecimal; 4 | import com.xm.common.entity.BaseEntity; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.experimental.Accessors; 8 | 9 | /** 10 | *

11 | * 菜单权限表 12 | *

13 | * 14 | * @author xiaomalover 15 | * @since 2021-08-08 16 | */ 17 | @Data 18 | @EqualsAndHashCode(callSuper = true) 19 | @Accessors(chain = true) 20 | public class SysPermission extends BaseEntity{ 21 | 22 | private static final long serialVersionUID = 1L; 23 | 24 | /** 类型 - 目录 */ 25 | public static final Integer TYPE_DIR = 0; 26 | 27 | /** 类型 - 菜单 */ 28 | public static final Integer TYPE_MENU = 1; 29 | 30 | /** 类型 - 按钮 */ 31 | public static final Integer TYPE_BTN = 2; 32 | 33 | /** 34 | * 类型:0目录;1菜单;按钮 35 | */ 36 | private Integer type; 37 | 38 | /** 39 | * 名称 40 | */ 41 | private String name; 42 | 43 | /** 44 | * 父类ID 45 | */ 46 | private Integer parentId; 47 | 48 | /** 49 | * 关系路径 50 | */ 51 | private String path; 52 | 53 | /** 54 | * 请求方式 55 | */ 56 | private String method; 57 | 58 | /** 59 | * 排序 60 | */ 61 | private BigDecimal sortOrder; 62 | 63 | /** 64 | * 图标 65 | */ 66 | private String icon; 67 | 68 | /** 69 | * 路由地址 70 | */ 71 | private String url; 72 | 73 | /** 74 | * 组件路径 75 | */ 76 | private String component; 77 | 78 | /** 79 | * 权限标识 80 | */ 81 | private String permisionCode; 82 | 83 | /** 84 | * 状态(0无效;1有效) 85 | */ 86 | private Integer status; 87 | 88 | /** 89 | * 是否显示 90 | */ 91 | private Integer isDisplay; 92 | 93 | /** 94 | * 当前激活菜单(类型为隐藏菜单时有效) 95 | */ 96 | private String currentActiveMenu; 97 | 98 | /** 99 | * 是否外链 100 | */ 101 | private Integer isExternalLink; 102 | 103 | /** 104 | * 是否缓存 105 | */ 106 | private Integer isCache; 107 | 108 | } 109 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/entity/SysRole.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.entity; 2 | 3 | import com.xm.common.entity.BaseEntity; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.experimental.Accessors; 7 | 8 | /** 9 | *

10 | * 角色表 11 | *

12 | * 13 | * @author xiaomalover 14 | * @since 2021-08-08 15 | */ 16 | @Data 17 | @EqualsAndHashCode(callSuper = true) 18 | @Accessors(chain = true) 19 | public class SysRole extends BaseEntity{ 20 | 21 | private static final long serialVersionUID = 1L; 22 | 23 | /** 24 | * 角色名称 25 | */ 26 | private String name; 27 | 28 | /** 29 | * 角色值 30 | */ 31 | private String code; 32 | 33 | /** 34 | * 角色描述 35 | */ 36 | private String description; 37 | 38 | /** 39 | * 状态:0停用;1启用 40 | */ 41 | private Integer status; 42 | } 43 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/entity/SysRolePermission.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.entity; 2 | 3 | import com.xm.common.entity.BaseEntity; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.experimental.Accessors; 7 | 8 | /** 9 | *

10 | * 角色权限关联表 11 | *

12 | * 13 | * @author xiaomalover 14 | * @since 2021-08-08 15 | */ 16 | @Data 17 | @EqualsAndHashCode(callSuper = true) 18 | @Accessors(chain = true) 19 | public class SysRolePermission extends BaseEntity{ 20 | 21 | private static final long serialVersionUID = 1L; 22 | 23 | /** 24 | * 权限ID 25 | */ 26 | private Integer permissionId; 27 | 28 | /** 29 | * 角色ID 30 | */ 31 | private Integer roleId; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/mapper/SysAdminLogMapper.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.mapper; 2 | 3 | import com.xm.admin.module.sys.entity.SysAdminLog; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | 6 | /** 7 | *

8 | * 请求日志 Mapper 接口 9 | *

10 | * 11 | * @author xiaomalover 12 | * @since 2021-08-08 13 | */ 14 | public interface SysAdminLogMapper extends BaseMapper { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/mapper/SysAdminMapper.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.xm.admin.module.sys.entity.SysAdmin; 5 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 6 | import com.xm.common.vo.ExtraVo; 7 | import org.apache.ibatis.annotations.Param; 8 | import org.springframework.stereotype.Repository; 9 | 10 | import java.util.Map; 11 | 12 | /** 13 | *

14 | * 管理员表 Mapper 接口 15 | *

16 | * 17 | * @author xiaomalover 18 | * @since 2021-08-08 19 | */ 20 | @Repository 21 | public interface SysAdminMapper extends BaseMapper { 22 | 23 | /** 24 | * 获取管理页列表 25 | * 26 | * @param page 分业相关 27 | * @param extraVo 附加参数 28 | * @param conditionMap 搜索条件 29 | * @return 管理页列表 30 | */ 31 | IPage selectAdminList(IPage page, @Param("extraVo") ExtraVo extraVo, @Param("conditionMap") Map conditionMap); 32 | 33 | SysAdmin loadUserByUsername(@Param("username") String username); 34 | } 35 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/mapper/SysDepartmentMapper.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.mapper; 2 | 3 | import com.xm.admin.module.sys.entity.SysDepartment; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | /** 12 | *

13 | * Mapper 接口 14 | *

15 | * 16 | * @author xiaomalover 17 | * @since 2021-08-08 18 | */ 19 | @Repository 20 | public interface SysDepartmentMapper extends BaseMapper { 21 | 22 | /** 23 | * 获取所有的部分信息 24 | * @param deptName 部门名 25 | * @param status 状态 26 | * @return 部门信息 27 | */ 28 | List> selectAllDepartmentListMap(@Param("deptName") String deptName, @Param("status") Integer status); 29 | } 30 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/mapper/SysPermissionMapper.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.mapper; 2 | 3 | import com.xm.admin.module.sys.entity.SysPermission; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | /** 12 | *

13 | * 菜单权限表 Mapper 接口 14 | *

15 | * 16 | * @author xiaomalover 17 | * @since 2021-08-08 18 | */ 19 | @Repository 20 | public interface SysPermissionMapper extends BaseMapper { 21 | 22 | /** 23 | * 获取菜单(权限)树 24 | * 25 | * @param menuName 菜单名 26 | * @param status 状态 27 | * @param show 展示状态 28 | * @return 菜单(权限)树 29 | */ 30 | List> selectAllPermissionListMap(String menuName, Integer status, Integer show); 31 | 32 | /** 33 | * 获取菜单树 34 | * 35 | * @param userId 用户ID 36 | * @return 菜单树 37 | */ 38 | List> selectUserPermissionListMap(Integer userId); 39 | 40 | /** 41 | * 通过用户id获取 42 | * 43 | * @param userId 用户主键 44 | * @return 权限列表 45 | */ 46 | List findPermissionCodeByUserId(@Param("userId") Integer userId); 47 | } 48 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/mapper/SysRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.xm.admin.module.sys.entity.SysRole; 5 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 6 | import com.xm.common.vo.ExtraVo; 7 | import org.apache.ibatis.annotations.Param; 8 | import org.springframework.stereotype.Repository; 9 | 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | /** 14 | *

15 | * 角色表 Mapper 接口 16 | *

17 | * 18 | * @author xiaomalover 19 | * @since 2021-08-08 20 | */ 21 | @Repository 22 | public interface SysRoleMapper extends BaseMapper { 23 | 24 | /** 25 | * 获取角色列表 26 | * 27 | * @param page 分业相关 28 | * @param extraVo 附加参数 29 | * @param conditionMap 搜索条件 30 | * @return 角色列表 31 | */ 32 | IPage> selectRoleList(IPage> page, @Param("extraVo") ExtraVo extraVo, @Param("conditionMap") Map conditionMap); 33 | 34 | /** 35 | * 获取所有角色列表 36 | * 37 | * @return 角色列表 38 | */ 39 | List> selectAllRoleList(); 40 | } 41 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/mapper/SysRolePermissionMapper.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.mapper; 2 | 3 | import com.xm.admin.module.sys.entity.SysRolePermission; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | 6 | /** 7 | *

8 | * 角色权限关联表 Mapper 接口 9 | *

10 | * 11 | * @author xiaomalover 12 | * @since 2021-08-08 13 | */ 14 | public interface SysRolePermissionMapper extends BaseMapper { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/payload/AccountEditRequest.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.payload; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.NotEmpty; 6 | import javax.validation.constraints.Pattern; 7 | import java.io.Serializable; 8 | 9 | @Data 10 | public class AccountEditRequest implements Serializable { 11 | 12 | private static final long serialVersionUID = 8648914193037396878L; 13 | 14 | @NotEmpty(message = "请输入手机号") 15 | @Pattern(regexp="^1[3456789]\\d{9}$",message="手机号格式不正确") 16 | private String mobile; 17 | 18 | @NotEmpty(message = "请输入邮箱") 19 | @Pattern(regexp="^[a-zA-Z0-9]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+$", message="邮箱格式不正确") 20 | private String email; 21 | 22 | @NotEmpty(message = "请输入昵称") 23 | private String nickname; 24 | 25 | private String description; 26 | 27 | private String avatar; 28 | } 29 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/payload/AdminAddRequest.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.payload; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.NotEmpty; 6 | import javax.validation.constraints.NotNull; 7 | import javax.validation.constraints.Pattern; 8 | import java.io.Serializable; 9 | 10 | @Data 11 | public class AdminAddRequest implements Serializable { 12 | 13 | private static final long serialVersionUID = 8648914193037396878L; 14 | 15 | @NotEmpty(message = "请输入用户名") 16 | private String account; 17 | 18 | @NotEmpty(message = "请输入昵称") 19 | private String nickname; 20 | 21 | @NotEmpty(message = "请输入密码") 22 | @Pattern(regexp="^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,18}$", message="密码必须6-18位字母和数字组合") 23 | private String pwd; 24 | 25 | @NotEmpty(message = "请输入邮箱") 26 | @Pattern(regexp="^[a-zA-Z0-9]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+$", message="邮箱格式不正确") 27 | private String email; 28 | 29 | @NotNull(message = "请选择部门") 30 | private Integer dept; 31 | 32 | @NotNull(message = "请选择角色") 33 | private Integer role; 34 | 35 | private Integer status; 36 | 37 | private String remark; 38 | } 39 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/payload/AdminEditRequest.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.payload; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.NotEmpty; 6 | import javax.validation.constraints.NotNull; 7 | import javax.validation.constraints.Pattern; 8 | import java.io.Serializable; 9 | 10 | @Data 11 | public class AdminEditRequest implements Serializable { 12 | 13 | private static final long serialVersionUID = 8648914193037396878L; 14 | 15 | @NotNull(message = "参数缺失") 16 | private Integer id; 17 | 18 | @NotEmpty(message = "请输入用户名") 19 | private String account; 20 | 21 | @NotEmpty(message = "请输入昵称") 22 | private String nickname; 23 | 24 | @Pattern(regexp="^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,18}$", message="密码必须6-18位字母和数字组合") 25 | private String pwd; 26 | 27 | @NotEmpty(message = "请输入邮箱") 28 | @Pattern(regexp="^[a-zA-Z0-9]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+$", message="邮箱格式不正确") 29 | private String email; 30 | 31 | @NotNull(message = "请选择部门") 32 | private Integer dept; 33 | 34 | @NotNull(message = "请选择角色") 35 | private Integer role; 36 | 37 | private Integer status; 38 | 39 | private String remark; 40 | } 41 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/payload/DepartmentAddEditRequest.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.payload; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.NotEmpty; 6 | import java.io.Serializable; 7 | import java.math.BigDecimal; 8 | 9 | @Data 10 | public class DepartmentAddEditRequest implements Serializable { 11 | 12 | private static final long serialVersionUID = 5943426068162487167L; 13 | 14 | private Integer id; 15 | 16 | @NotEmpty(message = "请输入部门名称") 17 | private String deptName; 18 | 19 | private Integer parentDept; 20 | 21 | private BigDecimal orderNo; 22 | 23 | private Integer status; 24 | 25 | private String remark; 26 | } 27 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/payload/LoginRequest.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.payload; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.NotBlank; 6 | 7 | /** 8 | *

9 | * 登录请求参数 10 | *

11 | * 12 | */ 13 | @Data 14 | public class LoginRequest { 15 | 16 | /** 17 | * 用户名或邮箱或手机号 18 | */ 19 | @NotBlank(message = "用户名不能为空") 20 | private String username; 21 | 22 | /** 23 | * 密码 24 | */ 25 | @NotBlank(message = "密码不能为空") 26 | private String password; 27 | 28 | @NotBlank(message = "请输入验证码") 29 | String captcha; 30 | 31 | @NotBlank(message = "请输入验证码") 32 | String captchaId; 33 | 34 | /** 35 | * 记住我 36 | */ 37 | private Boolean rememberMe = false; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/payload/MenuAddEditRequest.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.payload; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.NotEmpty; 6 | import javax.validation.constraints.NotNull; 7 | import java.io.Serializable; 8 | import java.math.BigDecimal; 9 | 10 | @Data 11 | public class MenuAddEditRequest implements Serializable { 12 | 13 | private static final long serialVersionUID = 5943426068162487167L; 14 | 15 | private Integer id; 16 | 17 | @NotNull(message = "类型不能为空") 18 | private Integer type; 19 | 20 | @NotEmpty(message = "请输入名称") 21 | private String menuName; 22 | 23 | private Integer parentMenu; 24 | 25 | private BigDecimal orderNo; 26 | 27 | private Integer status; 28 | 29 | private String icon; 30 | 31 | private Integer isExt; 32 | 33 | private String routePath; 34 | 35 | private Integer show; 36 | 37 | private String method; 38 | 39 | private String component; 40 | 41 | private Integer keepalive; 42 | 43 | private String permission; 44 | 45 | private String currentActiveMenu; 46 | } 47 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/payload/ModifyPasswordRequest.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.payload; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.NotEmpty; 6 | import javax.validation.constraints.Pattern; 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @author fil 11 | */ 12 | @Data 13 | public class ModifyPasswordRequest implements Serializable { 14 | 15 | private static final long serialVersionUID = -7506638385507428250L; 16 | 17 | @NotEmpty(message = "请输入原密码") 18 | private String oldPassword; 19 | 20 | @NotEmpty(message = "请输入新密码") 21 | @Pattern(regexp="^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,18}$", message="密码必须6-18位字母和数字组合") 22 | private String password; 23 | } 24 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/payload/RoleAddEditRequest.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.payload; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.NotEmpty; 6 | import java.io.Serializable; 7 | import java.util.List; 8 | 9 | @Data 10 | public class RoleAddEditRequest implements Serializable { 11 | 12 | private static final long serialVersionUID = 5943426068162487167L; 13 | 14 | private Integer id; 15 | 16 | @NotEmpty(message = "请输入角色名") 17 | private String roleName; 18 | 19 | @NotEmpty(message = "请输入角色值") 20 | private String roleValue; 21 | 22 | private String remark; 23 | 24 | private Integer status; 25 | 26 | private List menu; 27 | } 28 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/payload/UnlockRequest.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.payload; 2 | 3 | import lombok.Data; 4 | import javax.validation.constraints.NotBlank; 5 | 6 | /** 7 | *

8 | * 解锁请求参数 9 | *

10 | * 11 | */ 12 | @Data 13 | public class UnlockRequest { 14 | 15 | /** 16 | * 用户名或邮箱或手机号 17 | */ 18 | @NotBlank(message = "用户名不能为空") 19 | private String username; 20 | 21 | /** 22 | * 密码 23 | */ 24 | @NotBlank(message = "密码不能为空") 25 | private String password; 26 | } 27 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/service/ISysAdminLogService.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.service; 2 | 3 | import com.xm.admin.module.sys.entity.SysAdminLog; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | /** 7 | *

8 | * 请求日志 服务类 9 | *

10 | * 11 | * @author xiaomalover 12 | * @since 2021-08-08 13 | */ 14 | public interface ISysAdminLogService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/service/ISysAdminService.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.service; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.xm.admin.module.sys.entity.SysAdmin; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | import com.xm.common.vo.ExtraVo; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | /** 12 | *

13 | * 管理员表 服务类 14 | *

15 | * 16 | * @author xiaomalover 17 | * @since 2021-08-08 18 | */ 19 | public interface ISysAdminService extends IService { 20 | 21 | /** 22 | * 获取用户详情 23 | * @param username 用户名 24 | * @return 用户详细信息 25 | */ 26 | SysAdmin findUserDetailInfo(String username); 27 | 28 | /** 29 | * 获取管理页列表 30 | * 31 | * @param page 分业相关 32 | * @param extraVo 附加参数 33 | * @param conditionMap 搜索条件 34 | * @return 管理页列表 35 | */ 36 | IPage getAdminList(IPage page, ExtraVo extraVo, MapconditionMap); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/service/ISysDepartmentService.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.xm.admin.module.sys.entity.SysDepartment; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | *

11 | * 服务类 12 | *

13 | * 14 | * @author xiaomalover 15 | * @since 2021-08-08 16 | */ 17 | public interface ISysDepartmentService extends IService { 18 | 19 | /** 20 | * 获取部门树 21 | * 22 | * @param deptName 部门名 23 | * @param status 状态 24 | * @return 部分树 25 | */ 26 | List> getDepartmentTree(String deptName, Integer status); 27 | } 28 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/service/ISysPermissionService.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.service; 2 | 3 | import com.xm.admin.module.sys.entity.SysPermission; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | *

11 | * 菜单权限表 服务类 12 | *

13 | * 14 | * @author xiaomalover 15 | * @since 2021-08-08 16 | */ 17 | public interface ISysPermissionService extends IService { 18 | 19 | /** 20 | * 获取菜单(权限)树 21 | * 22 | * @param menuName 菜单名 23 | * @param status 状态 24 | * @param show 展示状态 25 | * @return 菜单(权限)树 26 | */ 27 | List> getAllPermission(String menuName, Integer status, Integer show); 28 | 29 | /** 30 | * 获取菜单树 31 | * @return 菜单树 32 | */ 33 | List> getUserPermission(Integer userId); 34 | 35 | /** 36 | * 获取所有权限码, 操作类型的菜单 37 | * @return 权限码 38 | */ 39 | List getAllPermissionCodes(); 40 | 41 | /** 42 | * 获取用户权限码 43 | * @return 权限码 44 | */ 45 | List getUserPermissionCodes(Integer userId); 46 | } 47 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/service/ISysRolePermissionService.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.service; 2 | 3 | import com.xm.admin.module.sys.entity.SysRolePermission; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | /** 7 | *

8 | * 角色权限关联表 服务类 9 | *

10 | * 11 | * @author xiaomalover 12 | * @since 2021-08-08 13 | */ 14 | public interface ISysRolePermissionService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/service/ISysRoleService.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.service; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.xm.admin.module.sys.entity.SysRole; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | import com.xm.common.vo.ExtraVo; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | /** 12 | *

13 | * 角色表 服务类 14 | *

15 | * 16 | * @author xiaomalover 17 | * @since 2021-08-08 18 | */ 19 | public interface ISysRoleService extends IService { 20 | 21 | /** 22 | * 获取角色列表 23 | * 24 | * @param page 分业相关 25 | * @param extraVo 附加参数 26 | * @param conditionMap 搜索条件 27 | * @return 角色列表 28 | */ 29 | IPage> getRoleList(IPage> page, ExtraVo extraVo, Map conditionMap); 30 | 31 | /** 32 | * 获取所有角色列表 33 | * 34 | * @return 角色列表 35 | */ 36 | List> getAllRoleList(); 37 | } 38 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/service/impl/SysAdminLogServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.service.impl; 2 | 3 | import com.xm.admin.module.sys.entity.SysAdminLog; 4 | import com.xm.admin.module.sys.mapper.SysAdminLogMapper; 5 | import com.xm.admin.module.sys.service.ISysAdminLogService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | *

11 | * 请求日志 服务实现类 12 | *

13 | * 14 | * @author xiaomalover 15 | * @since 2021-08-08 16 | */ 17 | @Service 18 | public class SysAdminLogServiceImpl extends ServiceImpl implements ISysAdminLogService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/service/impl/SysRolePermissionServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.service.impl; 2 | 3 | import com.xm.admin.module.sys.entity.SysRolePermission; 4 | import com.xm.admin.module.sys.mapper.SysRolePermissionMapper; 5 | import com.xm.admin.module.sys.service.ISysRolePermissionService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | *

11 | * 角色权限关联表 服务实现类 12 | *

13 | * 14 | * @author xiaomalover 15 | * @since 2021-08-08 16 | */ 17 | @Service 18 | public class SysRolePermissionServiceImpl extends ServiceImpl implements ISysRolePermissionService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /admin-server/src/main/java/com/xm/admin/module/sys/service/impl/SysRoleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.xm.admin.module.sys.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.xm.admin.module.sys.entity.SysRole; 5 | import com.xm.admin.module.sys.mapper.SysRoleMapper; 6 | import com.xm.admin.module.sys.service.ISysRoleService; 7 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 8 | import com.xm.common.vo.ExtraVo; 9 | import org.springframework.stereotype.Service; 10 | 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | /** 15 | *

16 | * 角色表 服务实现类 17 | *

18 | * 19 | * @author xiaomalover 20 | * @since 2021-08-08 21 | */ 22 | @Service 23 | public class SysRoleServiceImpl extends ServiceImpl implements ISysRoleService { 24 | 25 | private final SysRoleMapper roleMapper; 26 | 27 | public SysRoleServiceImpl(SysRoleMapper roleMapper) { 28 | this.roleMapper = roleMapper; 29 | } 30 | 31 | @Override 32 | public IPage> getRoleList(IPage> page, ExtraVo extraVo, Map conditionMap) { 33 | return roleMapper.selectRoleList(page, extraVo, conditionMap); 34 | } 35 | 36 | @Override 37 | public List> getAllRoleList() { 38 | return roleMapper.selectAllRoleList(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | profiles: 3 | active: dev 4 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | _(\_/) 2 | ,((((^`\ 3 | (((( (6 \ 4 | ,((((( , \ 5 | ,,,_ ,((((( /"._ ,`, 6 | ((((\\ ,... ,(((( / `-.-' 7 | ))) ;' `"'"'""(((( ( 8 | ((( / ((( \ 9 | )) | @admin-server | 10 | (( | . ' | 11 | )) \ _ ' `t ,.') 12 | ( | y;- -,-""'"-.\ \/ 13 | ) / ./ ) / `\ \ 14 | |./ ( ( / /' 15 | || \\ //'| 16 | || \\ _//'|| 17 | || )) |_/ || 18 | \_\ |_/ || 19 | `'" \_\ 20 | `'" -------------------------------------------------------------------------------- /admin-server/src/main/resources/mapper/content/ConArticleCategoryMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 19 | 20 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/mapper/content/ConArticleInfoMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/mapper/sys/SysAdminLogMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/mapper/sys/SysAdminMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 25 | 26 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/mapper/sys/SysDepartmentMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 19 | 20 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/mapper/sys/SysPermissionMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 24 | 25 | 40 | 41 | 49 | 50 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/mapper/sys/SysRoleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/mapper/sys/SysRolePermissionMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/_app.config.js: -------------------------------------------------------------------------------- 1 | window.__PRODUCTION__VUE_VBEN_ADMIN__CONF__={"VITE_GLOB_APP_TITLE":"VbenAdmin","VITE_GLOB_APP_SHORT_NAME":"vue_vben_admin","VITE_GLOB_API_URL":"http://localhost:20004","VITE_GLOB_UPLOAD_URL":"http://localhost:20004/file/upload","VITE_GLOB_API_URL_PREFIX":""};Object.freeze(window.__PRODUCTION__VUE_VBEN_ADMIN__CONF__);Object.defineProperty(window,"__PRODUCTION__VUE_VBEN_ADMIN__CONF__",{configurable:false,writable:false,}); -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/AccountDetail.984f65a6.js: -------------------------------------------------------------------------------- 1 | import{D as e,bf as a,b1 as t,r,a0 as s,F as n,a1 as o,a5 as i,w as c,K as d,G as u,ar as p,L as l,aa as y,ac as m,ad as b}from"./vendor.54f9b785.js";import{a as f}from"./index.8c033639.js";import{j as k,a2 as v}from"./index.29cb9d1e.js";/* empty css *//* empty css *//* empty css */import"./onMountedOrActivated.fcde6c3c.js";import"./useWindowSizeFn.51649442.js";import"./useContentViewHeight.e2ebf036.js";const j=e({name:"AccountDetail",components:{PageWrapper:f,ATabs:a,ATabPane:a.TabPane},setup(){var e;const a=t(),s=k(),n=r(null==(e=a.params)?void 0:e.id),o=r("detail"),{setTitle:i}=v();return i("详情:用户"+n.value),{userId:n,currentKey:o,goBack:function(){s("/system/account")}}}}),g=b(" 禁用账号 "),K=b(" 修改密码 "),x={class:"pt-4 m-4 desc-wrap"};j.render=function(e,a,t,r,b,f){const k=s("a-button"),v=s("a-tab-pane"),j=s("a-tabs"),T=s("PageWrapper");return n(),o(T,{title:"用户"+e.userId+"的资料",content:"这是用户资料详情页面。本页面仅用于演示相同路由在tab中打开多个页面并且显示不同的数据",contentBackground:"",onBack:e.goBack},{extra:i((()=>[c(k,{type:"primary",danger:""},{default:i((()=>[g])),_:1}),c(k,{type:"primary"},{default:i((()=>[K])),_:1})])),footer:i((()=>[c(j,{"default-active-key":"detail",activeKey:e.currentKey,"onUpdate:activeKey":a[0]||(a[0]=a=>e.currentKey=a)},{default:i((()=>[c(v,{key:"detail",tab:"用户资料"}),c(v,{key:"logs",tab:"操作日志"})])),_:1},8,["activeKey"])])),default:i((()=>[d("div",x,["detail"==e.currentKey?(n(),u(y,{key:0},p(10,(a=>d("div",{key:a},"这是用户"+l(e.userId)+"资料Tab",1))),64)):m("",!0),"logs"==e.currentKey?(n(),u(y,{key:1},p(10,(a=>d("div",{key:a},"这是用户"+l(e.userId)+"操作日志Tab",1))),64)):m("",!0)])])),_:1},8,["title","onBack"])};export{j as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/ArticleAddOrEdit.37728884.js: -------------------------------------------------------------------------------- 1 | "undefined"!=typeof require&&require;var e=(e,t,i)=>new Promise(((s,r)=>{var o=e=>{try{n(i.next(e))}catch(t){r(t)}},a=e=>{try{n(i.throw(e))}catch(t){r(t)}},n=e=>e.done?s(e.value):Promise.resolve(e.value).then(o,a);n((i=i.apply(e,t)).next())}));import{g as t,h as i}from"./useForm.91b099eb.js";import{a as s}from"./article.data.953a6c4c.js";import{g as r,c as o,A as a,d as n}from"./article.563832c8.js";import{D as d,b1 as l,a as c,_ as m,a0 as u,F as p,G as f,w as y}from"./vendor.54f9b785.js";import{a2 as h}from"./index.29cb9d1e.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import"./index.9981dd62.js";import"./useWindowSizeFn.51649442.js";import"./onMountedOrActivated.fcde6c3c.js";import"./upload.79b9af6d.js";var b=d({name:"DeptModal",components:{BasicForm:t},emits:["success","register"],setup(){var t;const[d,{updateSchema:u,validate:p,setFieldsValue:f,resetFields:y}]=i({labelWidth:100,schemas:s,showSubmitButton:!0,submitButtonOptions:{text:"提交"}}),b=l(),j=c(),x=null==(t=b.query)?void 0:t.id,{closeCurrent:v}=h();return m((()=>e(this,null,(function*(){const e=yield r({status:1});if(yield u({field:"categoryId",componentProps:{treeData:e}}),yield y(),x){const e=yield o(Number(x));yield f(e)}})))),{registerForm:d,handleSubmit:function(){return e(this,null,(function*(){try{const e=yield p();if(x){e.id=x,(yield a(e))&&(yield v(),yield j.push({path:"/content/article/info"}))}else{(yield n(e))&&(yield v(),yield j.push({path:"/content/article/info"}))}}finally{}}))}}}});const j={style:{padding:"50px"}};b.render=function(e,t,i,s,r,o){const a=u("BasicForm");return p(),f("div",j,[y(a,{onRegister:e.registerForm,onSubmit:e.handleSubmit},null,8,["onRegister","onSubmit"])])};export{b as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/ArticleDetail.c5669fcb.js: -------------------------------------------------------------------------------- 1 | "undefined"!=typeof require&&require;import{D as e,b1 as t,a,r as n,_ as r,a0 as i,F as o,a1 as c,a5 as s,w as l,K as p,L as u,ad as d}from"./vendor.54f9b785.js";import{a as f}from"./index.8c033639.js";import{j as m,a2 as v}from"./index.29cb9d1e.js";import{c as x}from"./article.563832c8.js";/* empty css *//* empty css */import"./onMountedOrActivated.fcde6c3c.js";import"./useWindowSizeFn.51649442.js";import"./useContentViewHeight.e2ebf036.js";const j=e({name:"ArticleDetail",components:{PageWrapper:f},setup(){var e;const i=t(),o=a(),c=m(),s=n(null==(e=i.params)?void 0:e.id),{setTitle:l,closeCurrent:p}=v(),u=n({});function d(){return e=this,t=null,a=function*(){u.value=yield x(s.value),l("文章详情:"+u.value.title)},new Promise(((n,r)=>{var i=e=>{try{c(a.next(e))}catch(t){r(t)}},o=e=>{try{c(a.throw(e))}catch(t){r(t)}},c=e=>e.done?n(e.value):Promise.resolve(e.value).then(i,o);c((a=a.apply(e,t)).next())}));var e,t,a}return r((()=>{d()})),{articleId:s,goBack:function(){c("/content/article/info")},articleInfo:u,editArticle:function(){p(),o.push({path:"/content/article/article_edit",query:{id:s.value}})}}}}),y=d(" 编辑文章 "),g={class:"pt-4 m-4 desc-wrap"},h={style:{"text-align":"center"}},k={style:{padding:"100px 200px"}},b=["innerHTML"];j.render=function(e,t,a,n,r,d){const f=i("a-button"),m=i("PageWrapper");return o(),c(m,{title:"文章详情:"+e.articleInfo.title,content:"",contentBackground:"",onBack:e.goBack},{extra:s((()=>[l(f,{type:"primary",onClick:e.editArticle},{default:s((()=>[y])),_:1},8,["onClick"])])),default:s((()=>[p("div",g,[p("p",h,u(e.articleInfo.title),1),p("p",k,[p("span",{innerHTML:e.articleInfo.content},null,8,b)])])])),_:1},8,["title","onBack"])};export{j as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/Breadcrumb.45a81991.css: -------------------------------------------------------------------------------- 1 | .vben-layout-breadcrumb{display:flex;padding:0 8px;align-items:center}.vben-layout-breadcrumb .ant-breadcrumb-link .anticon{margin-right:4px;margin-bottom:2px}.vben-layout-breadcrumb--light .ant-breadcrumb-link{color:#999}.vben-layout-breadcrumb--light .ant-breadcrumb-link a{color:#000000a6}.vben-layout-breadcrumb--light .ant-breadcrumb-link a:hover{color:#0960bd}.vben-layout-breadcrumb--light .ant-breadcrumb-separator{color:#999}.vben-layout-breadcrumb--dark .ant-breadcrumb-link{color:#fff9}.vben-layout-breadcrumb--dark .ant-breadcrumb-link a{color:#fffc}.vben-layout-breadcrumb--dark .ant-breadcrumb-link a:hover{color:#fff}.vben-layout-breadcrumb--dark .ant-breadcrumb-separator,.vben-layout-breadcrumb--dark .anticon{color:#fffc} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/CategoryTree.8cc65905.js: -------------------------------------------------------------------------------- 1 | "undefined"!=typeof require&&require;import{_ as e}from"./Tree.vue_vue&type=style&index=0&lang.200156f7.js";import{g as t}from"./article.563832c8.js";import{D as r,r as a,_ as n,a0 as o,F as s,G as i,w as l}from"./vendor.54f9b785.js";import"./index.29cb9d1e.js";/* empty css */var c=r({name:"CategoryTree",components:{BasicTree:e},emits:["select"],setup(e,{emit:r}){const o=a([]);function s(){return e=this,r=null,a=function*(){o.value=yield t()},new Promise(((t,n)=>{var o=e=>{try{i(a.next(e))}catch(t){n(t)}},s=e=>{try{i(a.throw(e))}catch(t){n(t)}},i=e=>e.done?t(e.value):Promise.resolve(e.value).then(o,s);i((a=a.apply(e,r)).next())}));var e,r,a}return n((()=>{s()})),{treeData:o,handleSelect:function(e){r("select",e[0])}}}});const d={class:"bg-white m-4 mr-0 overflow-hidden"};c.render=function(e,t,r,a,n,c){const u=o("BasicTree");return s(),i("div",d,[l(u,{title:"分类列表",toolbar:"",search:"",clickRowToExpand:!1,treeData:e.treeData,replaceFields:{key:"id",title:"categoryName"},onSelect:e.handleSelect},null,8,["treeData","onSelect"])])};export{c as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/DeptTree.e05362dd.js: -------------------------------------------------------------------------------- 1 | "undefined"!=typeof require&&require;import{_ as e}from"./Tree.vue_vue&type=style&index=0&lang.200156f7.js";import{c as t}from"./system.194fce67.js";import{D as r,r as a,_ as n,a0 as s,F as o,G as i,w as l}from"./vendor.54f9b785.js";import"./index.29cb9d1e.js";/* empty css */var c=r({name:"DeptTree",components:{BasicTree:e},emits:["select"],setup(e,{emit:r}){const s=a([]);function o(){return e=this,r=null,a=function*(){s.value=yield t()},new Promise(((t,n)=>{var s=e=>{try{i(a.next(e))}catch(t){n(t)}},o=e=>{try{i(a.throw(e))}catch(t){n(t)}},i=e=>e.done?t(e.value):Promise.resolve(e.value).then(s,o);i((a=a.apply(e,r)).next())}));var e,r,a}return n((()=>{o()})),{treeData:s,handleSelect:function(e){r("select",e[0])}}}});const d={class:"bg-white m-4 mr-0 overflow-hidden"};c.render=function(e,t,r,a,n,c){const u=s("BasicTree");return o(),i("div",d,[l(u,{title:"部门列表",toolbar:"",search:"",clickRowToExpand:!1,treeData:e.treeData,replaceFields:{key:"id",title:"deptName"},onSelect:e.handleSelect},null,8,["treeData","onSelect"])])};export{c as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/DetailModal.12e96179.js: -------------------------------------------------------------------------------- 1 | import{_ as e}from"./DetailModal.vue_vue&type=script&setup=true&lang.a6c65b40.js";export{_ as default}from"./DetailModal.vue_vue&type=script&setup=true&lang.a6c65b40.js";import"./index.9981dd62.js";import"./index.29cb9d1e.js";import"./vendor.54f9b785.js";import"./useWindowSizeFn.51649442.js";import"./data.3fa8ee9d.js";/* empty css */ -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/DropMenuItem.f170c93a.js: -------------------------------------------------------------------------------- 1 | import{D as e,aA as n,j as s,ah as t,a0 as a,F as o,a1 as r,a5 as i,K as c,w as l,L as u}from"./vendor.54f9b785.js";import{_ as m,p}from"./index.29cb9d1e.js";var d=e({name:"DropdownMenuItem",components:{MenuItem:n.Item,Icon:m},props:{key:p.string,text:p.string,icon:p.string},setup(e){const n=t();return{itemKey:s((()=>{var s,t;return e.key||(null==(t=null==(s=null==n?void 0:n.vnode)?void 0:s.props)?void 0:t.key)}))}}});const f={class:"flex items-center"};d.render=function(e,n,s,t,m,p){const d=a("Icon"),v=a("MenuItem");return o(),r(v,{key:e.itemKey},{default:i((()=>[c("span",f,[l(d,{icon:e.icon,class:"mr-1"},null,8,["icon"]),c("span",null,u(e.text),1)])])),_:1})};export{d as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/ErrorAction.6e17c42b.js: -------------------------------------------------------------------------------- 1 | import{D as o,a8 as t,bB as e,a,j as n,a0 as r,F as s,a1 as i,a5 as u,w as l}from"./vendor.54f9b785.js";/* empty css */import{_ as c,aa as d,d as f,P as m}from"./index.29cb9d1e.js";var p=o({name:"ErrorAction",components:{Icon:c,Tooltip:t,Badge:e},setup(){const{t:o}=f(),{push:t}=a(),e=d();return{t:o,getCount:n((()=>e.getErrorLogListCount)),handleToErrorList:function(){t(m.ERROR_LOG_PAGE).then((()=>{e.setErrorLogListCount(0)}))}}}});p.render=function(o,t,e,a,n,c){const d=r("Icon"),f=r("Badge"),m=r("Tooltip");return s(),i(m,{title:o.t("layout.header.tooltipErrorLog"),placement:"bottom",mouseEnterDelay:.5,onClick:o.handleToErrorList},{default:u((()=>[l(f,{count:o.getCount,offset:[0,10],overflowCount:99},{default:u((()=>[l(d,{icon:"ion:bug-outline"})])),_:1},8,["count"])])),_:1},8,["title","mouseEnterDelay","onClick"])};export{p as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/Exception.1646ace5.css: -------------------------------------------------------------------------------- 1 | .ant-result{padding:48px 32px}.ant-result-success .ant-result-icon>.anticon{color:#55d187}.ant-result-error .ant-result-icon>.anticon{color:#ed6f6f}.ant-result-info .ant-result-icon>.anticon{color:#0960bd}.ant-result-warning .ant-result-icon>.anticon{color:#efbd47}.ant-result-image{width:250px;height:295px;margin:auto}.ant-result-icon{margin-bottom:24px;text-align:center}.ant-result-icon>.anticon{font-size:72px}.ant-result-title{color:#000000d9;font-size:24px;line-height:1.8;text-align:center}.ant-result-subtitle{color:#00000073;font-size:14px;line-height:1.6;text-align:center}.ant-result-extra{margin:24px 0 0;text-align:center}.ant-result-extra>*{margin-right:8px}.ant-result-extra>*:last-child{margin-right:0}.ant-result-content{margin-top:24px;padding:24px 40px;background-color:#fafafa}.ant-result-rtl{direction:rtl}.ant-result-rtl .ant-result-extra>*{margin-right:0;margin-left:8px}.ant-result-rtl .ant-result-extra>*:last-child{margin-left:0}.vben-app-exception-page{display:flex;align-items:center;flex-direction:column}.vben-app-exception-page .ant-result-icon img{max-width:400px;max-height:300px} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/Exception.74066454.js: -------------------------------------------------------------------------------- 1 | import{D as t,r as e,b1 as s,j as a,u as l,w as n,aS as i,b2 as r}from"./vendor.54f9b785.js";import{E as o,j as u,k as b,d as T,c,P as p}from"./index.29cb9d1e.js";var d=t({name:"ErrorPage",props:{status:{type:Number,default:o.PAGE_NOT_FOUND},title:{type:String,default:""},subTitle:{type:String,default:""},full:{type:Boolean,default:!1}},setup(t){const d=e(new Map),{query:x}=s(),E=u(),f=b(),{t:_}=T(),{prefixCls:y}=c("app-exception-page"),O=a((()=>{const{status:e}=x,{status:s}=t;return Number(e)||s})),m=a((()=>l(d).get(l(O)))),N=_("sys.exception.backLogin"),A=_("sys.exception.backHome");return l(d).set(o.PAGE_NOT_ACCESS,{title:"403",status:`${o.PAGE_NOT_ACCESS}`,subTitle:_("sys.exception.subTitle403"),btnText:t.full?N:A,handler:()=>t.full?E(p.BASE_LOGIN):E()}),l(d).set(o.PAGE_NOT_FOUND,{title:"404",status:`${o.PAGE_NOT_FOUND}`,subTitle:_("sys.exception.subTitle404"),btnText:t.full?N:A,handler:()=>t.full?E(p.BASE_LOGIN):E()}),l(d).set(o.ERROR,{title:"500",status:`${o.ERROR}`,subTitle:_("sys.exception.subTitle500"),btnText:A,handler:()=>E()}),l(d).set(o.PAGE_NOT_DATA,{title:_("sys.exception.noDataTitle"),subTitle:"",btnText:_("common.redo"),handler:()=>f(),icon:"/assets/no-data.f7e550cc.svg"}),l(d).set(o.NET_WORK_ERROR,{title:_("sys.exception.networkErrorTitle"),subTitle:_("sys.exception.networkErrorSubTitle"),btnText:_("common.redo"),handler:()=>f(),icon:"/assets/net-error.61b7e6df.svg"}),()=>{const{title:e,subTitle:s,btnText:a,icon:o,handler:u,status:b}=l(m)||{};return n(r,{class:y,status:b,title:t.title||e,"sub-title":t.subTitle||s},{extra:()=>a&&n(i,{type:"primary",onClick:u},{default:()=>a}),icon:()=>o?n("img",{src:o},null):null})}}});export{d as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/FrameBlank.9b579f4b.js: -------------------------------------------------------------------------------- 1 | import{D as r,F as a,G as e}from"./vendor.54f9b785.js";var n=r({name:"FrameBlank"});n.render=function(r,n,o,s,t,d){return a(),e("div")};export{n as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/GrowCard.511387e6.js: -------------------------------------------------------------------------------- 1 | import{_ as e}from"./GrowCard.vue_vue&type=script&setup=true&lang.c91a4575.js";export{_ as default}from"./GrowCard.vue_vue&type=script&setup=true&lang.c91a4575.js";import"./index.29cb9d1e.js";import"./vendor.54f9b785.js";/* empty css *//* empty css *//* empty css *//* empty css */ -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/InputNumberItem.3c9011c4.js: -------------------------------------------------------------------------------- 1 | import{D as e,bn as s,a0 as n,F as t,G as i,K as r,L as a,w as o,a4 as p,N as m}from"./vendor.54f9b785.js";/* empty css */import{c as d}from"./index.29cb9d1e.js";import{b as u}from"./index.5895bef3.js";import"./index.5c85c39a.js";/* empty css *//* empty css */import"./index.83a5ac4f.js";import"./index.fc649792.js";import"./useWindowSizeFn.51649442.js";import"./useContentViewHeight.e2ebf036.js";/* empty css */import"./useSortable.15816348.js";import"./lock.fb37e799.js";var l=e({name:"InputNumberItem",components:{InputNumber:s},props:{event:{type:Number},title:{type:String}},setup(e){const{prefixCls:s}=d("setting-input-number-item");return{prefixCls:s,handleChange:function(s){e.event&&u(e.event,s)}}}});l.render=function(e,s,d,u,l,f){const c=n("InputNumber");return t(),i("div",{class:m(e.prefixCls)},[r("span",null,a(e.title),1),o(c,p(e.$attrs,{size:"small",class:`${e.prefixCls}-input-number`,onChange:e.handleChange}),null,16,["class","onChange"])],2)},l.__scopeId="data-v-19883dde";export{l as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/InputNumberItem.5677bd64.css: -------------------------------------------------------------------------------- 1 | .vben-setting-input-number-item[data-v-19883dde]{display:flex;justify-content:space-between;margin:16px 0}.vben-setting-input-number-item-input-number[data-v-19883dde]{width:126px} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/LockModal.0068f88c.css: -------------------------------------------------------------------------------- 1 | .vben-header-lock-modal__entry{position:relative;padding:130px 30px 30px;border-radius:10px}.vben-header-lock-modal__header{position:absolute;top:0;left:calc(50% - 45px);width:auto;text-align:center}.vben-header-lock-modal__header-img{width:70px;border-radius:50%}.vben-header-lock-modal__header-name{margin-top:5px}.vben-header-lock-modal__footer{text-align:center} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/LockModal.bb45babe.js: -------------------------------------------------------------------------------- 1 | "undefined"!=typeof require&&require;import{c as e,h as s,d as r}from"./index.29cb9d1e.js";import{B as a,b as o}from"./index.9981dd62.js";import{g as t,h as i}from"./useForm.91b099eb.js";import{u as n}from"./lock.fb37e799.js";import{h as l}from"./header.d801b988.js";import{D as d,j as c,a0 as m,F as p,a1 as u,a5 as f,K as h,N as x,L as v,w as g,ad as j,a4 as k}from"./vendor.54f9b785.js";import"./useWindowSizeFn.51649442.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */var y=d({name:"LockModal",components:{BasicModal:a,BasicForm:t},setup(){const{t:a}=r(),{prefixCls:t}=e("header-lock-modal"),d=s(),m=n(),p=c((()=>{var e;return null==(e=d.getUserInfo)?void 0:e.realName})),[u,{closeModal:f}]=o(),[h,{validateFields:x,resetFields:v}]=i({showActionButtonGroup:!1,schemas:[{field:"password",label:a("layout.header.lockScreenPassword"),component:"InputPassword",required:!0}]});return{t:a,prefixCls:t,getRealName:p,register:u,registerForm:h,handleLock:function(){return e=this,s=null,r=function*(){const e=(yield x()).password;f(),m.setLockInfo({isLock:!0,pwd:e}),yield v()},new Promise(((a,o)=>{var t=e=>{try{n(r.next(e))}catch(s){o(s)}},i=e=>{try{n(r.throw(e))}catch(s){o(s)}},n=e=>e.done?a(e.value):Promise.resolve(e.value).then(t,i);n((r=r.apply(e,s)).next())}));var e,s,r},avatar:c((()=>{const{avatar:e}=d.getUserInfo;return e||l}))}}});const _=["src"];y.render=function(e,s,r,a,o,t){const i=m("BasicForm"),n=m("a-button"),l=m("BasicModal");return p(),u(l,k({footer:null,title:e.t("layout.header.lockScreen")},e.$attrs,{class:e.prefixCls,onRegister:e.register}),{default:f((()=>[h("div",{class:x(`${e.prefixCls}__entry`)},[h("div",{class:x(`${e.prefixCls}__header`)},[h("img",{src:e.avatar,class:x(`${e.prefixCls}__header-img`)},null,10,_),h("p",{class:x(`${e.prefixCls}__header-name`)},v(e.getRealName),3)],2),g(i,{onRegister:e.registerForm},null,8,["onRegister"]),h("div",{class:x(`${e.prefixCls}__footer`)},[g(n,{type:"primary",block:"",class:"mt-2",onClick:e.handleLock},{default:f((()=>[j(v(e.t("layout.header.lockScreenBtn")),1)])),_:1},8,["onClick"])],2)],2)])),_:1},16,["title","class","onRegister"])};export{y as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/LockPage.a757c476.css: -------------------------------------------------------------------------------- 1 | .vben-lock-page[data-v-39f73246]{z-index:3000}.vben-lock-page__unlock[data-v-39f73246]{transform:translate(-50%)}.vben-lock-page__hour[data-v-39f73246],.vben-lock-page__minute[data-v-39f73246]{display:flex;font-weight:700;color:#bababa;background-color:#141313;border-radius:30px;justify-content:center;align-items:center}@media screen and (max-width: 768px){.vben-lock-page__hour span[data-v-39f73246]:not(.meridiem),.vben-lock-page__minute span[data-v-39f73246]:not(.meridiem){font-size:160px}}@media screen and (min-width: 768px){.vben-lock-page__hour span[data-v-39f73246]:not(.meridiem),.vben-lock-page__minute span[data-v-39f73246]:not(.meridiem){font-size:160px}}@media screen and (max-width: 576px){.vben-lock-page__hour span[data-v-39f73246]:not(.meridiem),.vben-lock-page__minute span[data-v-39f73246]:not(.meridiem){font-size:90px}}@media screen and (min-width: 992px){.vben-lock-page__hour span[data-v-39f73246]:not(.meridiem),.vben-lock-page__minute span[data-v-39f73246]:not(.meridiem){font-size:220px}}@media screen and (min-width: 1200px){.vben-lock-page__hour span[data-v-39f73246]:not(.meridiem),.vben-lock-page__minute span[data-v-39f73246]:not(.meridiem){font-size:260px}}@media screen and (min-width: 1600px){.vben-lock-page__hour span[data-v-39f73246]:not(.meridiem),.vben-lock-page__minute span[data-v-39f73246]:not(.meridiem){font-size:320px}}.vben-lock-page-entry[data-v-39f73246]{position:absolute;top:0;left:0;display:flex;width:100%;height:100%;background-color:#00000080;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);justify-content:center;align-items:center}.vben-lock-page-entry-content[data-v-39f73246]{width:260px}.vben-lock-page-entry__header[data-v-39f73246]{text-align:center}.vben-lock-page-entry__header-img[data-v-39f73246]{width:70px;margin:0 auto;border-radius:50%}.vben-lock-page-entry__header-name[data-v-39f73246]{margin-top:5px;font-weight:500;color:#bababa}.vben-lock-page-entry__err-msg[data-v-39f73246]{display:inline-block;margin-top:10px;color:#ed6f6f}.vben-lock-page-entry__footer[data-v-39f73246]{display:flex;justify-content:space-between} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/Login.47363f68.js: -------------------------------------------------------------------------------- 1 | import{A as s,a as l,b as e,u as t,c as a,d as o,e as i}from"./index.29cb9d1e.js";import n from"./LoginForm.3ed32c4a.js";import{D as r,j as x,a0 as m,F as p,G as d,a1 as c,ac as u,K as f,w as g,L as w,N as v}from"./vendor.54f9b785.js";/* empty css *//* empty css */import"./LoginFormTitle.a551ed0c.js";var h=r({name:"Login",components:{AppLogo:s,LoginForm:n,AppLocalePicker:l,AppDarkModeToggle:e},props:{sessionTimeout:{type:Boolean}},setup(){const s=t(),{prefixCls:l}=a("login"),{t:e}=o(),n=i();return{t:e,prefixCls:l,title:x((()=>{var l;return null!=(l=null==s?void 0:s.title)?l:""})),showLocale:n.getShowPicker}}});const y={class:"-enter-x xl:hidden"},L={class:"container relative h-full py-2 mx-auto sm:px-10"},b={class:"flex h-full"},j={class:"hidden min-h-full pl-4 mr-4 xl:flex xl:flex-col xl:w-6/12"},k={class:"my-auto"},T=["alt"],A={class:"mt-10 font-medium text-white -enter-x"},F={class:"inline-block mt-4 text-3xl"},C={class:"mt-5 font-normal text-white text-md dark:text-gray-500 -enter-x"},D={class:"flex w-full h-full py-5 xl:h-auto xl:py-0 xl:my-0 xl:w-6/12"};h.render=function(s,l,e,t,a,o){const i=m("AppDarkModeToggle"),n=m("AppLogo"),r=m("LoginForm");return p(),d("div",{class:v([s.prefixCls,"relative w-full h-full px-4"])},[s.sessionTimeout?u("",!0):(p(),c(i,{key:0,class:"absolute top-3 right-7 enter-x"})),f("span",y,[g(n,{alwaysShowTitle:!0})]),f("div",L,[f("div",b,[f("div",j,[g(n,{class:"-enter-x"}),f("div",k,[f("img",{alt:s.title,src:"/assets/login-box-bg.9027741f.svg",class:"w-1/2 -mt-16 -enter-x"},null,8,T),f("div",A,[f("span",F,w(s.t("sys.login.signInTitle")),1)]),f("div",C,w(s.t("sys.login.signInDesc")),1)])]),f("div",D,[f("div",{class:v([`${s.prefixCls}-form`,"relative w-full px-5 py-8 mx-auto my-auto rounded-md shadow-md xl:ml-16 xl:bg-transparent sm:px-8 xl:p-4 xl:shadow-none sm:w-3/4 lg:w-2/4 xl:w-auto enter-x"])},[g(r)],2)])])])],2)};export{h as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/Login.ede6bba2.css: -------------------------------------------------------------------------------- 1 | html[data-theme=dark] .vben-login{background-color:#293146}html[data-theme=dark] .vben-login:before{background-image:url(/assets/login-bg-dark.424130e3.svg)}html[data-theme=dark] .vben-login .ant-input,html[data-theme=dark] .vben-login .ant-input-password{background-color:#232a3b}html[data-theme=dark] .vben-login .ant-btn:not(.ant-btn-link):not(.ant-btn-primary){border:1px solid #4a5569}html[data-theme=dark] .vben-login-form{background:transparent!important}html[data-theme=dark] .vben-login .app-iconify{color:#fff}html[data-theme=dark] input.fix-auto-fill,html[data-theme=dark] .fix-auto-fill input{-webkit-text-fill-color:#c9d1d9!important;box-shadow:inherit!important}.vben-login{min-height:100%;overflow:hidden}@media (max-width: 1200px){.vben-login{background-color:#293146}.vben-login .vben-login-form{background-color:#fff}}.vben-login:before{position:absolute;top:0;left:0;width:100%;height:100%;margin-left:-48%;background-image:url(/assets/login-bg.b265811a.svg);background-position:100%;background-repeat:no-repeat;background-size:auto 100%;content:""}@media (max-width: 1200px){.vben-login:before{display:none}}.vben-login .vben-app-logo{position:absolute;top:12px;height:30px}.vben-login .vben-app-logo__title{font-size:16px;color:#fff}.vben-login .vben-app-logo img{width:32px}.vben-login .container .vben-app-logo{display:flex;width:60%;height:80px}.vben-login .container .vben-app-logo__title{font-size:24px;color:#fff}.vben-login .container .vben-app-logo img{width:48px}.vben-login-sign-in-way .anticon{font-size:22px;color:#888;cursor:pointer}.vben-login-sign-in-way .anticon:hover{color:#0960bd}.vben-login input:not([type="checkbox"]){min-width:360px}@media (max-width: 1200px){.vben-login input:not([type="checkbox"]){min-width:320px}}@media (max-width: 992px){.vben-login input:not([type="checkbox"]){min-width:260px}}@media (max-width: 768px){.vben-login input:not([type="checkbox"]){min-width:240px}}@media (max-width: 576px){.vben-login input:not([type="checkbox"]){min-width:160px}}.vben-login .vben-countdown-input input{min-width:unset}.vben-login .ant-divider-inner-text{font-size:12px;color:#00000073} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/LoginFormTitle.a551ed0c.js: -------------------------------------------------------------------------------- 1 | var e,t;"undefined"!=typeof require&&require;import{d as n}from"./index.29cb9d1e.js";import{r,j as o,u as a,D as s,F as i,G as l,L as c}from"./vendor.54f9b785.js";(t=e||(e={}))[t.LOGIN=0]="LOGIN",t[t.REGISTER=1]="REGISTER",t[t.RESET_PASSWORD=2]="RESET_PASSWORD",t[t.MOBILE=3]="MOBILE",t[t.QR_CODE=4]="QR_CODE";const u=r(0);function d(){function e(e){u.value=e}return{setLoginState:e,getLoginState:o((()=>u.value)),handleBackLogin:function(){e(0)}}}function g(e){return{validForm:function(){return t=this,n=null,r=function*(){const t=a(e);if(t)return yield t.validate()},new Promise(((e,o)=>{var a=e=>{try{i(r.next(e))}catch(t){o(t)}},s=e=>{try{i(r.throw(e))}catch(t){o(t)}},i=t=>t.done?e(t.value):Promise.resolve(t.value).then(a,s);i((r=r.apply(t,n)).next())}));var t,n,r}}}function f(){const{t:e}=n(),t=o((()=>m(e("sys.login.accountPlaceholder")))),r=o((()=>m(e("sys.login.passwordPlaceholder")))),s=o((()=>m(e("sys.login.captchaPlaceholder"))));return{getFormRules:o((()=>{const e=a(t),n=a(r),o=a(s);return a(u),{account:e,password:n,captcha:o}}))}}function m(e){return[{required:!0,message:e,trigger:"change"}]}var h=s({name:"LoginFormTitle",setup(){const{t:t}=n(),{getLoginState:r}=d();return{getFormTitle:o((()=>({[e.LOGIN]:t("sys.login.signInFormTitle")}[a(r)])))}}});const v={class:"mb-3 text-2xl font-bold text-center xl:text-3xl enter-x xl:text-left"};h.render=function(e,t,n,r,o,a){return i(),l("h2",v,c(e.getFormTitle),1)};var x=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",default:h});export{e as L,h as _,f as a,g as b,x as c,d as u}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/SalesProductPie.10cc1bf2.js: -------------------------------------------------------------------------------- 1 | import{_ as e}from"./SalesProductPie.vue_vue&type=script&setup=true&lang.bbaf9b94.js";export{_ as default}from"./SalesProductPie.vue_vue&type=script&setup=true&lang.bbaf9b94.js";import"./vendor.54f9b785.js";/* empty css *//* empty css *//* empty css */import"./useECharts.a0aee6e9.js";import"./index.29cb9d1e.js"; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/SalesProductPie.vue_vue&type=script&setup=true&lang.bbaf9b94.js: -------------------------------------------------------------------------------- 1 | import{D as e,r as a,S as t,F as i,a1 as n,a5 as o,K as r,X as s,u as l,bV as d}from"./vendor.54f9b785.js";/* empty css *//* empty css *//* empty css */import{u}from"./useECharts.a0aee6e9.js";var m=e({props:{loading:Boolean,width:{type:String,default:"100%"},height:{type:String,default:"300px"}},setup(e){const m=e,p=a(null),{setOptions:g}=u(p);return t((()=>m.loading),(()=>{m.loading||g({tooltip:{trigger:"item"},series:[{name:"访问来源",type:"pie",radius:"80%",center:["50%","50%"],color:["#5ab1ef","#b6a2de","#67e0e3","#2ec7c9"],data:[{value:500,name:"电子产品"},{value:310,name:"服装"},{value:274,name:"化妆品"},{value:400,name:"家居"}].sort((function(e,a){return e.value-a.value})),roseType:"radius",animationType:"scale",animationEasing:"exponentialInOut",animationDelay:function(){return 400*Math.random()}}]})}),{immediate:!0}),(a,t)=>(i(),n(l(d),{title:"成交占比",loading:e.loading},{default:o((()=>[r("div",{ref:(e,a)=>{a.chartRef=e,p.value=e},style:s({width:e.width,height:e.height})},null,4)])),_:1},8,["loading"]))}});export{m as _}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/SecureSetting.3d063fe8.js: -------------------------------------------------------------------------------- 1 | "undefined"!=typeof require&&require;import{D as e,aS as a,aZ as t,aY as s,A as r,B as o,a0 as i,bc as n,F as d,a1 as l,a5 as c,w as u,H as p,ad as m}from"./vendor.54f9b785.js";/* empty css */import{g as f,h as b}from"./useForm.91b099eb.js";import{ad as h,i as j}from"./index.29cb9d1e.js";import{p as x,d as y}from"./data.63adca46.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import"./index.9981dd62.js";import"./useWindowSizeFn.51649442.js";var v=e({components:{BasicForm:f,CollapseContainer:h,Button:a,ARow:t,ACol:s},setup(){const{createMessage:e}=j(),[a,{validate:t,resetFields:s}]=b({labelWidth:120,schemas:x,showActionButtonGroup:!1});return{register:a,handleSubmit:function(){return a=this,r=null,o=function*(){try{let a=yield t();yield y(a),e.success("更新成功!"),yield s()}finally{}},new Promise(((e,t)=>{var s=e=>{try{n(o.next(e))}catch(a){t(a)}},i=e=>{try{n(o.throw(e))}catch(a){t(a)}},n=a=>a.done?e(a.value):Promise.resolve(a.value).then(s,i);n((o=o.apply(a,r)).next())}));var a,r,o}}}});r("data-v-47cccb67");const g=m(" 修改密码 ");o(),v.render=function(e,a,t,s,r,o){const m=i("BasicForm"),f=i("a-col"),b=i("a-row"),h=i("Button"),j=i("CollapseContainer"),x=n("auth");return d(),l(j,{title:"修改密码",canExpan:!1},{default:c((()=>[u(b,{gutter:24},{default:c((()=>[u(f,null,{default:c((()=>[u(m,{onRegister:e.register},null,8,["onRegister"])])),_:1})])),_:1}),p(u(h,{type:"primary",onClick:e.handleSubmit},{default:c((()=>[g])),_:1},8,["onClick"]),[[x,"setting:btn:password"]])])),_:1})},v.__scopeId="data-v-47cccb67";export{v as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/SecureSetting.7b2149bf.css: -------------------------------------------------------------------------------- 1 | .change-avatar img[data-v-47cccb67]{display:block;margin-bottom:15px;border-radius:50%} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/SelectItem.3b3b269f.css: -------------------------------------------------------------------------------- 1 | .vben-setting-select-item[data-v-2dba4940]{display:flex;justify-content:space-between;margin:16px 0}.vben-setting-select-item-select[data-v-2dba4940]{width:126px} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/SelectItem.f56d58cf.js: -------------------------------------------------------------------------------- 1 | import{D as e,bo as t,j as s,a0 as i,F as a,G as n,K as o,L as r,w as l,a4 as d,N as p}from"./vendor.54f9b785.js";import{c as f}from"./index.29cb9d1e.js";import{b as m}from"./index.5895bef3.js";import"./index.5c85c39a.js";/* empty css *//* empty css */import"./index.83a5ac4f.js";import"./index.fc649792.js";import"./useWindowSizeFn.51649442.js";import"./useContentViewHeight.e2ebf036.js";/* empty css */import"./useSortable.15816348.js";import"./lock.fb37e799.js";var u=e({name:"SelectItem",components:{Select:t},props:{event:{type:Number},disabled:{type:Boolean},title:{type:String},def:{type:[String,Number]},initValue:{type:[String,Number]},options:{type:Array,default:()=>[]}},setup(e){const{prefixCls:t}=f("setting-select-item");return{prefixCls:t,handleChange:function(t){e.event&&m(e.event,t)},getBindValue:s((()=>e.def?{value:e.def,defaultValue:e.initValue||e.def}:{}))}}});u.render=function(e,t,s,f,m,u){const c=i("Select");return a(),n("div",{class:p(e.prefixCls)},[o("span",null,r(e.title),1),l(c,d(e.getBindValue,{class:`${e.prefixCls}-select`,onChange:e.handleChange,disabled:e.disabled,size:"small",options:e.options}),null,16,["class","onChange","disabled","options"])],2)},u.__scopeId="data-v-2dba4940";export{u as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/SessionTimeoutLogin.14f69a36.js: -------------------------------------------------------------------------------- 1 | import{D as a,r as s,_ as e,aj as o,a0 as r,F as t,a1 as n,a5 as u,K as d,w as i,N as l,a2 as f}from"./vendor.54f9b785.js";import{h as c,H as v,Q as m,aO as p}from"./index.29cb9d1e.js";var g=a({setup(a){const g=c(),I=v(),j=m(),_=s(0);return e((()=>{var a;_.value=null==(a=g.getUserInfo)?void 0:a.userId})),o((()=>{(_.value&&_.value!==g.getUserInfo.userId||j.getProjectConfig.permissionMode===p.BACK&&0===I.getLastBuildMenuTime)&&document.location.reload()})),(a,s)=>{const e=r("Login");return t(),n(f,null,{default:u((()=>[d("div",{class:l(a.prefixCls)},[i(e,{sessionTimeout:""})],2)])),_:1})}}});g.__scopeId="data-v-6fc11378";export{g as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/SessionTimeoutLogin.69dc390d.css: -------------------------------------------------------------------------------- 1 | .vben-st-login[data-v-6fc11378]{position:fixed;z-index:9999999;width:100%;height:100%;background:#fff} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/SettingFooter.82157ad7.js: -------------------------------------------------------------------------------- 1 | import{H as e,c as t,X as a,h as s,Q as o,d as n,b1 as l,a5 as r,aW as c,aX as i,i as d}from"./index.29cb9d1e.js";import{D as u,ca as f,be as g,u as p,a0 as C,F as y,G as m,w as S,a5 as k,ad as b,L as h,N as R}from"./vendor.54f9b785.js";var x=u({name:"SettingFooter",components:{CopyOutlined:f,RedoOutlined:g},setup(){const u=e(),{prefixCls:f}=t("setting-footer"),{t:g}=n(),{createSuccessModal:C,createMessage:y}=d(),m=a(),S=s(),k=o();return{prefixCls:f,t:g,handleCopy:function(){const{isSuccessRef:e}=l(JSON.stringify(p(k.getProjectConfig),null,2));p(e)&&C({title:g("layout.setting.operatingTitle"),content:g("layout.setting.operatingContent")})},handleResetSetting:function(){try{k.setProjectConfig(r);const{colorWeak:e,grayMode:t}=r;c(e),i(t),y.success(g("layout.setting.resetSuccess"))}catch(e){y.error(e)}},handleClearAndRedo:function(){localStorage.clear(),k.resetAllState(),u.resetState(),m.resetState(),S.resetState(),location.reload()}}}});x.render=function(e,t,a,s,o,n){const l=C("CopyOutlined"),r=C("a-button"),c=C("RedoOutlined");return y(),m("div",{class:R(e.prefixCls)},[S(r,{type:"primary",block:"",onClick:e.handleCopy},{default:k((()=>[S(l,{class:"mr-2"}),b(" "+h(e.t("layout.setting.copyBtn")),1)])),_:1},8,["onClick"]),S(r,{color:"warning",block:"",onClick:e.handleResetSetting,class:"my-3"},{default:k((()=>[S(c,{class:"mr-2"}),b(" "+h(e.t("common.resetText")),1)])),_:1},8,["onClick"]),S(r,{color:"error",block:"",onClick:e.handleClearAndRedo},{default:k((()=>[S(c,{class:"mr-2"}),b(" "+h(e.t("layout.setting.clearBtn")),1)])),_:1},8,["onClick"])],2)},x.__scopeId="data-v-b4529210";export{x as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/SettingFooter.b4008314.css: -------------------------------------------------------------------------------- 1 | .vben-setting-footer[data-v-b4529210]{display:flex;flex-direction:column;align-items:center} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/SiderTrigger.ede96a0d.js: -------------------------------------------------------------------------------- 1 | import{m as e}from"./index.29cb9d1e.js";import{D as l,c8 as o,c9 as t,a0 as s,F as a,G as d,a1 as n,ay as r}from"./vendor.54f9b785.js";var g=l({name:"SiderTrigger",components:{DoubleRightOutlined:o,DoubleLeftOutlined:t},setup(){const{getCollapsed:l,toggleCollapsed:o}=e();return{getCollapsed:l,toggleCollapsed:o}}});g.render=function(e,l,o,t,g,i){const p=s("DoubleRightOutlined"),u=s("DoubleLeftOutlined");return a(),d("div",{onClick:l[0]||(l[0]=r(((...l)=>e.toggleCollapsed&&e.toggleCollapsed(...l)),["stop"]))},[e.getCollapsed?(a(),n(p,{key:0})):(a(),n(u,{key:1}))])};export{g as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/SiteAnalysis.447a5d4d.js: -------------------------------------------------------------------------------- 1 | import{_ as e}from"./SiteAnalysis.vue_vue&type=script&setup=true&lang.27cd1c31.js";export{_ as default}from"./SiteAnalysis.vue_vue&type=script&setup=true&lang.27cd1c31.js";import"./vendor.54f9b785.js";/* empty css *//* empty css *//* empty css */import"./VisitAnalysis.vue_vue&type=script&setup=true&lang.d605ffa3.js";import"./useECharts.a0aee6e9.js";import"./index.29cb9d1e.js";import"./props.0a93851a.js";import"./VisitAnalysisBar.vue_vue&type=script&setup=true&lang.3ad8168a.js"; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/SiteAnalysis.vue_vue&type=script&setup=true&lang.27cd1c31.js: -------------------------------------------------------------------------------- 1 | import{D as a,r as t,F as s,a1 as e,a5 as i,G as r,w as u,ac as p,a4 as n,u as o,bV as b}from"./vendor.54f9b785.js";/* empty css *//* empty css *//* empty css */import{_ as v}from"./VisitAnalysis.vue_vue&type=script&setup=true&lang.d605ffa3.js";import{_ as l}from"./VisitAnalysisBar.vue_vue&type=script&setup=true&lang.3ad8168a.js";const y={key:0},d={key:1};var f=a({setup(a){const f=t("tab1"),m=[{key:"tab1",tab:"流量趋势"},{key:"tab2",tab:"访问量"}];function c(a){f.value=a}return(a,t)=>(s(),e(o(b),n({"tab-list":m},a.$attrs,{"active-tab-key":f.value,onTabChange:c}),{default:i((()=>["tab1"===f.value?(s(),r("p",y,[u(v)])):p("",!0),"tab2"===f.value?(s(),r("p",d,[u(l)])):p("",!0)])),_:1},16,["active-tab-key"]))}});export{f as _}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/SwitchItem.24688c5a.css: -------------------------------------------------------------------------------- 1 | .vben-setting-switch-item[data-v-fd7354e2]{display:flex;justify-content:space-between;margin:16px 0} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/SwitchItem.b4b07e3d.js: -------------------------------------------------------------------------------- 1 | import{D as e,bp as t,j as n,a0 as i,F as s,G as a,K as d,L as o,w as r,a4 as l,N as p}from"./vendor.54f9b785.js";/* empty css */import{c,d as f}from"./index.29cb9d1e.js";import{b as m}from"./index.5895bef3.js";import"./index.5c85c39a.js";/* empty css *//* empty css */import"./index.83a5ac4f.js";import"./index.fc649792.js";import"./useWindowSizeFn.51649442.js";import"./useContentViewHeight.e2ebf036.js";/* empty css */import"./useSortable.15816348.js";import"./lock.fb37e799.js";var h=e({name:"SwitchItem",components:{Switch:t},props:{event:{type:Number},disabled:{type:Boolean},title:{type:String},def:{type:Boolean}},setup(e){const{prefixCls:t}=c("setting-switch-item"),{t:i}=f();return{prefixCls:t,t:i,handleChange:function(t){e.event&&m(e.event,t)},getBindValue:n((()=>e.def?{checked:e.def}:{}))}}});h.render=function(e,t,n,c,f,m){const h=i("Switch");return s(),a("div",{class:p(e.prefixCls)},[d("span",null,o(e.title),1),r(h,l(e.getBindValue,{onChange:e.handleChange,disabled:e.disabled,checkedChildren:e.t("layout.setting.on"),unCheckedChildren:e.t("layout.setting.off")}),null,16,["onChange","disabled","checkedChildren","unCheckedChildren"])],2)},h.__scopeId="data-v-fd7354e2";export{h as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/ThemeColorPicker.4d941433.js: -------------------------------------------------------------------------------- 1 | import{c as e}from"./index.29cb9d1e.js";import{b as s}from"./index.5895bef3.js";import{D as i,bt as t,a0 as r,F as n,G as o,aa as a,ar as p,N as c,X as l,w as d}from"./vendor.54f9b785.js";import"./index.5c85c39a.js";/* empty css *//* empty css */import"./index.83a5ac4f.js";import"./index.fc649792.js";import"./useWindowSizeFn.51649442.js";import"./useContentViewHeight.e2ebf036.js";/* empty css */import"./useSortable.15816348.js";import"./lock.fb37e799.js";var m=i({name:"ThemeColorPicker",components:{CheckOutlined:t},props:{colorList:{type:Array,defualt:[]},event:{type:Number},def:{type:String}},setup(i){const{prefixCls:t}=e("setting-theme-picker");return{prefixCls:t,handleClick:function(e){i.event&&s(i.event,e)}}}});const f=["onClick"];m.render=function(e,s,i,t,m,u){const x=r("CheckOutlined");return n(),o("div",{class:c(e.prefixCls)},[(n(!0),o(a,null,p(e.colorList||[],(s=>(n(),o("span",{key:s,onClick:i=>e.handleClick(s),class:c([`${e.prefixCls}__item`,{[`${e.prefixCls}__item--active`]:e.def===s}]),style:l({background:s})},[d(x)],14,f)))),128))],2)};export{m as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/ThemeColorPicker.8eb61909.css: -------------------------------------------------------------------------------- 1 | .vben-setting-theme-picker{display:flex;flex-wrap:wrap;margin:16px 0;justify-content:space-around}.vben-setting-theme-picker__item{width:20px;height:20px;cursor:pointer;border:1px solid #ddd;border-radius:2px}.vben-setting-theme-picker__item svg{display:none}.vben-setting-theme-picker__item--active{border:1px solid #0b79ee}.vben-setting-theme-picker__item--active svg{display:inline-block;margin:0 0 3px 3px;font-size:12px;fill:#fff!important} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/TypePicker.25c7ab2c.js: -------------------------------------------------------------------------------- 1 | import{D as e,a8 as t,A as a,B as s,a0 as i,F as l,G as r,aa as n,ar as p,a1 as o,a5 as d,K as c,N as f}from"./vendor.54f9b785.js";import{c as u}from"./index.29cb9d1e.js";var m=e({name:"MenuTypePicker",components:{Tooltip:t},props:{menuTypeList:{type:Array,defualt:()=>[]},handler:{type:Function,default:()=>({})},def:{type:String,default:""}},setup(){const{prefixCls:e}=u("setting-menu-type-picker");return{prefixCls:e}}});a("data-v-7e211634");const y=["onClick"],x=[c("div",{class:"mix-sidebar"},null,-1)];s(),m.render=function(e,t,a,s,u,m){const _=i("Tooltip");return l(),r("div",{class:f(e.prefixCls)},[(l(!0),r(n,null,p(e.menuTypeList||[],(t=>(l(),o(_,{key:t.title,title:t.title,placement:"bottom"},{default:d((()=>[c("div",{onClick:a=>e.handler(t),class:f([`${e.prefixCls}__item`,`${e.prefixCls}__item--${t.type}`,{[`${e.prefixCls}__item--active`]:e.def===t.type}])},x,10,y)])),_:2},1032,["title"])))),128))],2)},m.__scopeId="data-v-7e211634";export{m as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/TypePicker.8747a11f.css: -------------------------------------------------------------------------------- 1 | .vben-setting-menu-type-picker[data-v-7e211634]{display:flex}.vben-setting-menu-type-picker__item[data-v-7e211634]{position:relative;width:56px;height:48px;margin-right:16px;overflow:hidden;cursor:pointer;background-color:#f0f2f5;border-radius:4px;box-shadow:0 1px 2.5px #0000002e}.vben-setting-menu-type-picker__item[data-v-7e211634]:before,.vben-setting-menu-type-picker__item[data-v-7e211634]:after{position:absolute;content:""}.vben-setting-menu-type-picker__item--sidebar[data-v-7e211634]:before,.vben-setting-menu-type-picker__item--light[data-v-7e211634]:before{top:0;left:0;z-index:1;width:33%;height:100%;background-color:#273352;border-radius:4px 0 0 4px}.vben-setting-menu-type-picker__item--sidebar[data-v-7e211634]:after,.vben-setting-menu-type-picker__item--light[data-v-7e211634]:after{top:0;left:0;width:100%;height:25%;background-color:#fff}.vben-setting-menu-type-picker__item--mix[data-v-7e211634]:before{top:0;left:0;width:33%;height:100%;background-color:#fff;border-radius:4px 0 0 4px}.vben-setting-menu-type-picker__item--mix[data-v-7e211634]:after{top:0;left:0;z-index:1;width:100%;height:25%;background-color:#273352}.vben-setting-menu-type-picker__item--top-menu[data-v-7e211634]:after{top:0;left:0;width:100%;height:25%;background-color:#273352}.vben-setting-menu-type-picker__item--dark[data-v-7e211634]{background-color:#273352}.vben-setting-menu-type-picker__item--mix-sidebar[data-v-7e211634]:before{top:0;left:0;z-index:1;width:25%;height:100%;background-color:#273352;border-radius:4px 0 0 4px}.vben-setting-menu-type-picker__item--mix-sidebar[data-v-7e211634]:after{top:0;left:0;width:100%;height:25%;background-color:#fff}.vben-setting-menu-type-picker__item--mix-sidebar .mix-sidebar[data-v-7e211634]{position:absolute;left:25%;width:15%;height:100%;background-color:#fff}.vben-setting-menu-type-picker__item[data-v-7e211634]:hover,.vben-setting-menu-type-picker__item--active[data-v-7e211634]{padding:12px;border:2px solid #0960bd}.vben-setting-menu-type-picker__item[data-v-7e211634]:hover:before,.vben-setting-menu-type-picker__item--active[data-v-7e211634]:before,.vben-setting-menu-type-picker__item[data-v-7e211634]:hover:after,.vben-setting-menu-type-picker__item--active[data-v-7e211634]:after{border-radius:0}.vben-setting-menu-type-picker img[data-v-7e211634]{width:100%;height:100%;cursor:pointer} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/VisitAnalysis.d8fd8bbd.js: -------------------------------------------------------------------------------- 1 | import{_ as s}from"./VisitAnalysis.vue_vue&type=script&setup=true&lang.d605ffa3.js";export{_ as default}from"./VisitAnalysis.vue_vue&type=script&setup=true&lang.d605ffa3.js";import"./useECharts.a0aee6e9.js";import"./index.29cb9d1e.js";import"./vendor.54f9b785.js";import"./props.0a93851a.js"; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/VisitAnalysis.vue_vue&type=script&setup=true&lang.d605ffa3.js: -------------------------------------------------------------------------------- 1 | var e=Object.defineProperty,t=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,o=(t,r,a)=>r in t?e(t,r,{enumerable:!0,configurable:!0,writable:!0,value:a}):t[r]=a;"undefined"!=typeof require&&require;import{u as i}from"./useECharts.a0aee6e9.js";import{b as s}from"./props.0a93851a.js";import{D as l,r as p,_ as n,F as y,G as b,X as c}from"./vendor.54f9b785.js";var h=l({props:((e,i)=>{for(var s in i||(i={}))r.call(i,s)&&o(e,s,i[s]);if(t)for(var s of t(i))a.call(i,s)&&o(e,s,i[s]);return e})({},s),setup(e){const t=p(null),{setOptions:r}=i(t);return n((()=>{r({tooltip:{trigger:"axis",axisPointer:{lineStyle:{width:1,color:"#019680"}}},xAxis:{type:"category",boundaryGap:!1,data:["6:00","7:00","8:00","9:00","10:00","11:00","12:00","13:00","14:00","15:00","16:00","17:00","18:00","19:00","20:00","21:00","22:00","23:00"],splitLine:{show:!0,lineStyle:{width:1,type:"solid",color:"rgba(226,226,226,0.5)"}},axisTick:{show:!1}},yAxis:[{type:"value",max:8e4,splitNumber:4,axisTick:{show:!1},splitArea:{show:!0,areaStyle:{color:["rgba(255,255,255,0.2)","rgba(226,226,226,0.2)"]}}}],grid:{left:"1%",right:"1%",top:"2 %",bottom:0,containLabel:!0},series:[{smooth:!0,data:[111,222,4e3,18e3,33333,55555,66666,33333,14e3,36e3,66666,44444,22222,11111,4e3,2e3,500,333,222,111],type:"line",areaStyle:{},itemStyle:{color:"#5ab1ef"}},{smooth:!0,data:[33,66,88,333,3333,5e3,18e3,3e3,1200,13e3,22e3,11e3,2221,1201,390,198,60,30,22,11],type:"line",areaStyle:{},itemStyle:{color:"#019680"}}]})})),(e,r)=>(y(),b("div",{ref:(e,r)=>{r.chartRef=e,t.value=e},style:c({height:e.height,width:e.width})},null,4))}});export{h as _}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/VisitAnalysisBar.35857a6a.js: -------------------------------------------------------------------------------- 1 | import{_ as s}from"./VisitAnalysisBar.vue_vue&type=script&setup=true&lang.3ad8168a.js";export{_ as default}from"./VisitAnalysisBar.vue_vue&type=script&setup=true&lang.3ad8168a.js";import"./useECharts.a0aee6e9.js";import"./index.29cb9d1e.js";import"./vendor.54f9b785.js";import"./props.0a93851a.js"; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/VisitAnalysisBar.vue_vue&type=script&setup=true&lang.3ad8168a.js: -------------------------------------------------------------------------------- 1 | var e=Object.defineProperty,r=Object.getOwnPropertySymbols,t=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,o=(r,t,a)=>t in r?e(r,t,{enumerable:!0,configurable:!0,writable:!0,value:a}):r[t]=a;"undefined"!=typeof require&&require;import{u as i}from"./useECharts.a0aee6e9.js";import{b as s}from"./props.0a93851a.js";import{D as p,r as l,_ as n,F as u,G as b,X as f}from"./vendor.54f9b785.js";var y=p({props:((e,i)=>{for(var s in i||(i={}))t.call(i,s)&&o(e,s,i[s]);if(r)for(var s of r(i))a.call(i,s)&&o(e,s,i[s]);return e})({},s),setup(e){const r=l(null),{setOptions:t}=i(r);return n((()=>{t({tooltip:{trigger:"axis",axisPointer:{lineStyle:{width:1,color:"#019680"}}},grid:{left:"1%",right:"1%",top:"2 %",bottom:0,containLabel:!0},xAxis:{type:"category",data:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"]},yAxis:{type:"value",max:8e3,splitNumber:4},series:[{data:[3e3,2e3,3333,5e3,3200,4200,3200,2100,3e3,5100,6e3,3200,4800],type:"bar",barMaxWidth:80}]})})),(e,t)=>(u(),b("div",{ref:(e,t)=>{t.chartRef=e,r.value=e},style:f({height:e.height,width:e.width})},null,4))}});export{y as _}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/VisitRadar.131b66db.js: -------------------------------------------------------------------------------- 1 | import{_ as e}from"./VisitRadar.vue_vue&type=script&setup=true&lang.a4354064.js";export{_ as default}from"./VisitRadar.vue_vue&type=script&setup=true&lang.a4354064.js";import"./vendor.54f9b785.js";/* empty css *//* empty css *//* empty css */import"./useECharts.a0aee6e9.js";import"./index.29cb9d1e.js"; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/VisitRadar.vue_vue&type=script&setup=true&lang.a4354064.js: -------------------------------------------------------------------------------- 1 | import{D as a,r as t,S as e,F as i,a1 as o,a5 as s,K as d,X as r,u as l,bV as m}from"./vendor.54f9b785.js";/* empty css *//* empty css *//* empty css */import{u as n}from"./useECharts.a0aee6e9.js";var p=a({props:{loading:Boolean,width:{type:String,default:"100%"},height:{type:String,default:"300px"}},setup(a){const p=a,x=t(null),{setOptions:u}=n(x);return e((()=>p.loading),(()=>{p.loading||u({legend:{bottom:0,data:["访问","购买"]},tooltip:{},radar:{radius:"60%",splitNumber:8,indicator:[{text:"电脑",max:100},{text:"充电器",max:100},{text:"耳机",max:100},{text:"手机",max:100},{text:"Ipad",max:100},{text:"耳机",max:100}]},series:[{type:"radar",symbolSize:0,areaStyle:{shadowBlur:0,shadowColor:"rgba(0,0,0,.2)",shadowOffsetX:0,shadowOffsetY:10,opacity:1},data:[{value:[90,50,86,40,50,20],name:"访问",itemStyle:{color:"#b6a2de"}},{value:[70,75,70,76,20,85],name:"购买",itemStyle:{color:"#5ab1ef"}}]}]})}),{immediate:!0}),(t,e)=>(i(),o(l(m),{title:"转化率",loading:a.loading},{default:s((()=>[d("div",{ref:(a,t)=>{t.chartRef=a,x.value=a},style:r({width:a.width,height:a.height})},null,4)])),_:1},8,["loading"]))}});export{p as _}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/VisitSource.224fe732.js: -------------------------------------------------------------------------------- 1 | import{_ as e}from"./VisitSource.vue_vue&type=script&setup=true&lang.3b4d463f.js";export{_ as default}from"./VisitSource.vue_vue&type=script&setup=true&lang.3b4d463f.js";import"./vendor.54f9b785.js";/* empty css *//* empty css *//* empty css */import"./useECharts.a0aee6e9.js";import"./index.29cb9d1e.js"; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/VisitSource.vue_vue&type=script&setup=true&lang.3b4d463f.js: -------------------------------------------------------------------------------- 1 | import{D as e,r as a,S as t,F as i,a1 as o,a5 as n,K as l,X as r,u as s,bV as d}from"./vendor.54f9b785.js";/* empty css *//* empty css *//* empty css */import{u as m}from"./useECharts.a0aee6e9.js";var p=e({props:{loading:Boolean,width:{type:String,default:"100%"},height:{type:String,default:"300px"}},setup(e){const p=e,u=a(null),{setOptions:h}=m(u);return t((()=>p.loading),(()=>{p.loading||h({tooltip:{trigger:"item"},legend:{bottom:"1%",left:"center"},series:[{color:["#5ab1ef","#b6a2de","#67e0e3","#2ec7c9"],name:"访问来源",type:"pie",radius:["40%","70%"],avoidLabelOverlap:!1,itemStyle:{borderRadius:10,borderColor:"#fff",borderWidth:2},label:{show:!1,position:"center"},emphasis:{label:{show:!0,fontSize:"12",fontWeight:"bold"}},labelLine:{show:!1},data:[{value:1048,name:"搜索引擎"},{value:735,name:"直接访问"},{value:580,name:"邮件营销"},{value:484,name:"联盟广告"}],animationType:"scale",animationEasing:"exponentialInOut",animationDelay:function(){return 100*Math.random()}}]})}),{immediate:!0}),(a,t)=>(i(),o(s(d),{title:"访问来源",loading:e.loading},{default:n((()=>[l("div",{ref:(e,a)=>{a.chartRef=e,u.value=e},style:r({width:e.width,height:e.height})},null,4)])),_:1},8,["loading"]))}});export{p as _}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/article.563832c8.js: -------------------------------------------------------------------------------- 1 | import{f as e}from"./index.29cb9d1e.js";var t,r;(r=t||(t={})).CategoryList="/article/category/getCategoryTree",r.CategoryAdd="/article/category/add",r.CategoryEdit="/article/category/edit",r.CategoryDelete="/article/category/delete",r.ArticleList="/article/getByCondition",r.ArticleInfo="/article/detail",r.ArticleAdd="/article/add",r.ArticleEdit="/article/edit",r.ArticleDelete="/article/delete";const a=r=>e.get({url:t.CategoryList,params:r}),l=r=>e.post({url:t.CategoryAdd,params:r}),i=r=>e.post({url:t.CategoryEdit,params:r}),d=r=>e.delete({url:t.CategoryDelete+"/"+r}),c=r=>e.get({url:t.ArticleList,params:r}),s=r=>e.get({url:t.ArticleInfo+"/"+r}),o=r=>e.post({url:t.ArticleAdd,params:r}),g=r=>e.post({url:t.ArticleEdit,params:r}),A=r=>e.delete({url:t.ArticleDelete+"/"+r});export{g as A,i as C,l as a,d as b,s as c,o as d,c as e,A as f,a as g}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/article.data.1868c4de.css: -------------------------------------------------------------------------------- 1 | .vben-tinymce-img-upload[data-v-0e4ebbfe]{position:absolute;top:4px;right:10px;z-index:20}.vben-tinymce-img-upload.fullscreen[data-v-0e4ebbfe]{position:fixed;z-index:10000}.vben-tinymce-container{position:relative;line-height:normal}.vben-tinymce-container textarea{z-index:-1;visibility:hidden} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/data.3fa8ee9d.js: -------------------------------------------------------------------------------- 1 | import{w as t,bH as e}from"./vendor.54f9b785.js";/* empty css */import{aI as a,d as r}from"./index.29cb9d1e.js";const{t:d}=r();function n(){return[{dataIndex:"type",title:d("sys.errorLog.tableColumnType"),width:80,customRender:({text:r})=>{const d=r===a.VUE?"green":r===a.RESOURCE?"cyan":r===a.PROMISE?"blue":a.AJAX?"red":"purple";return t(e,{color:d},{default:()=>r})}},{dataIndex:"url",title:"URL",width:200},{dataIndex:"time",title:d("sys.errorLog.tableColumnDate"),width:160},{dataIndex:"file",title:d("sys.errorLog.tableColumnFile"),width:200},{dataIndex:"name",title:"Name",width:200},{dataIndex:"message",title:d("sys.errorLog.tableColumnMsg"),width:300},{dataIndex:"stack",title:d("sys.errorLog.tableColumnStackMsg")}]}function o(){return n().map((t=>({field:t.dataIndex,label:t.title})))}export{n as getColumns,o as getDescSchema}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/data.63adca46.js: -------------------------------------------------------------------------------- 1 | import{f as e}from"./index.29cb9d1e.js";var o,n;(n=o||(o={})).ACCOUNT_INFO="/account/info",n.SESSION_TIMEOUT="/user/sessionTimeout",n.TOKEN_EXPIRED="/user/tokenExpired",n.CHANGE_PASSWORD="/account/changePassword",n.ACCOUNT_EDIT="/account/edit";const s=()=>e.get({url:o.ACCOUNT_INFO}),a=n=>e.post({url:o.CHANGE_PASSWORD,params:n}),r=n=>e.post({url:o.ACCOUNT_EDIT,params:n}),p=[{key:"1",name:"基本设置",component:"BaseSetting"},{key:"2",name:"修改密码",component:"SecureSetting"}],l=[{field:"username",component:"Input",componentProps:{readonly:!0},label:"用户名",colProps:{span:18}},{field:"mobile",component:"Input",label:"手机号",colProps:{span:18}},{field:"email",component:"Input",label:"邮箱",colProps:{span:18}},{field:"nickname",component:"Input",label:"昵称",colProps:{span:18}},{field:"description",component:"InputTextArea",label:"个人简介",colProps:{span:18}}],t=[{field:"oldPassword",label:"当前密码",component:"InputPassword",required:!0},{field:"password",label:"新密码",component:"InputPassword",required:!0},{field:"confirmPassword",label:"确认密码",component:"InputPassword",dynamicRules:({values:e})=>[{required:!0,validator:(o,n)=>n?n!==e.password?Promise.reject("两次输入的密码不一致!"):Promise.resolve():Promise.reject("确认密码不能为空")}]}];export{s as a,l as b,r as c,a as d,t as p,p as s}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/header.1b5fa5f8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaomalover/vben-admin-java/5766a8953360a206d604876c812b240e7f84dd6f/admin-server/src/main/resources/static/assets/header.1b5fa5f8.jpg -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/header.d801b988.js: -------------------------------------------------------------------------------- 1 | var a="/assets/header.1b5fa5f8.jpg";export{a as h}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.039140af.js: -------------------------------------------------------------------------------- 1 | import{D as o,aT as e,c3 as t,a as s,r as a,j as n,u as i,A as r,B as l,a0 as u,F as d,a1 as c,a5 as f,K as p,L as v,w as b,N as h,ac as m}from"./vendor.54f9b785.js";import{N as F,c as _,F as w,d as C}from"./index.29cb9d1e.js";import{a as L}from"./useContentViewHeight.e2ebf036.js";import"./useWindowSizeFn.51649442.js";var g=o({name:"LayoutFooter",components:{Footer:e.Footer,GithubFilled:t},setup(){const{t:o}=C(),{getShowFooter:e}=F(),{currentRoute:t}=s(),{prefixCls:r}=_("layout-footer"),l=a(null),{setFooterHeight:u}=L();return{getShowLayoutFooter:n((()=>{var o,s;if(i(e)){const e=null==(o=i(l))?void 0:o.$el;u((null==e?void 0:e.offsetHeight)||0)}else u(0);return i(e)&&!(null==(s=i(t).meta)?void 0:s.hiddenFooter)})),prefixCls:r,t:o,DOC_URL:"https://vvbin.cn/doc-next/",GITHUB_URL:"https://github.com/anncwb/vue-vben-admin",SITE_URL:"https://vvbin.cn/next/",openWindow:w,footerRef:l}}});r("data-v-0bf7ba29");const x=p("div",null,"Copyright ©2020 Vben Admin",-1);l(),g.render=function(o,e,t,s,a,n){const i=u("GithubFilled"),r=u("Footer");return o.getShowLayoutFooter?(d(),c(r,{key:0,class:h(o.prefixCls),ref:"footerRef"},{default:f((()=>[p("div",{class:h(`${o.prefixCls}__links`)},[p("a",{onClick:e[0]||(e[0]=e=>o.openWindow(o.SITE_URL))},v(o.t("layout.footer.onlinePreview")),1),b(i,{onClick:e[1]||(e[1]=e=>o.openWindow(o.GITHUB_URL)),class:h(`${o.prefixCls}__github`)},null,8,["class"]),p("a",{onClick:e[2]||(e[2]=e=>o.openWindow(o.DOC_URL))},v(o.t("layout.footer.onlineDocument")),1)],2),x])),_:1},8,["class"])):m("",!0)},g.__scopeId="data-v-0bf7ba29";export{g as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.32fb0083.css: -------------------------------------------------------------------------------- 1 | .ant-back-top{box-sizing:border-box;margin:0;padding:0;color:#000000d9;font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:tnum;position:fixed;right:100px;bottom:50px;z-index:10;width:40px;height:40px;cursor:pointer}.ant-back-top:empty{display:none}.ant-back-top-rtl{right:auto;left:100px;direction:rtl}.ant-back-top-content{width:40px;height:40px;overflow:hidden;color:#fff;text-align:center;background-color:#00000073;border-radius:20px;transition:all .3s}.ant-back-top-content:hover{background-color:#000000d9;transition:all .3s}.ant-back-top-icon{font-size:24px;line-height:40px}@media screen and (max-width: 768px){.ant-back-top{right:60px}}@media screen and (max-width: 480px){.ant-back-top{right:20px}}.vben-setting-drawer-fearure{position:absolute;top:45%;right:0;z-index:10;display:flex;padding:10px;color:#fff;cursor:pointer;background-color:#0960bd;border-radius:6px 0 0 6px;justify-content:center;align-items:center}.vben-setting-drawer-fearure svg{width:1em;height:1em} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.35b5cf30.css: -------------------------------------------------------------------------------- 1 | .ant-divider{box-sizing:border-box;margin:0;padding:0;color:#000000d9;font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:tnum;border-top:1px solid rgba(0,0,0,.06)}.ant-divider-vertical{position:relative;top:-.06em;display:inline-block;height:.9em;margin:0 8px;vertical-align:middle;border-top:0;border-left:1px solid rgba(0,0,0,.06)}.ant-divider-horizontal{display:flex;clear:both;width:100%;min-width:100%;margin:24px 0}.ant-divider-horizontal.ant-divider-with-text{display:flex;margin:16px 0;color:#000000d9;font-weight:500;font-size:16px;white-space:nowrap;text-align:center;border-top:0;border-top-color:#0000000f}.ant-divider-horizontal.ant-divider-with-text:before,.ant-divider-horizontal.ant-divider-with-text:after{position:relative;top:50%;width:50%;border-top:1px solid transparent;border-top-color:inherit;border-bottom:0;transform:translateY(50%);content:""}.ant-divider-horizontal.ant-divider-with-text-left:before{top:50%;width:5%}.ant-divider-horizontal.ant-divider-with-text-left:after{top:50%;width:95%}.ant-divider-horizontal.ant-divider-with-text-right:before{top:50%;width:95%}.ant-divider-horizontal.ant-divider-with-text-right:after{top:50%;width:5%}.ant-divider-inner-text{display:inline-block;padding:0 1em}.ant-divider-dashed{background:none;border-color:#0000000f;border-style:dashed;border-width:1px 0 0}.ant-divider-horizontal.ant-divider-with-text.ant-divider-dashed{border-top:0}.ant-divider-horizontal.ant-divider-with-text.ant-divider-dashed:before,.ant-divider-horizontal.ant-divider-with-text.ant-divider-dashed:after{border-style:dashed none none}.ant-divider-vertical.ant-divider-dashed{border-width:0 0 0 1px}.ant-divider-plain.ant-divider-with-text{color:#000000d9;font-weight:normal;font-size:14px}.ant-divider-rtl{direction:rtl}.ant-divider-rtl.ant-divider-horizontal.ant-divider-with-text-left:before{width:95%}.ant-divider-rtl.ant-divider-horizontal.ant-divider-with-text-left:after{width:5%}.ant-divider-rtl.ant-divider-horizontal.ant-divider-with-text-right:before{width:5%}.ant-divider-rtl.ant-divider-horizontal.ant-divider-with-text-right:after{width:95%} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.4114577a.css: -------------------------------------------------------------------------------- 1 | .vben-layout-footer[data-v-0bf7ba29]{color:#d9d9d9;text-align:center}.vben-layout-footer__links[data-v-0bf7ba29]{margin-bottom:8px}.vben-layout-footer__links a[data-v-0bf7ba29]{color:#d9d9d9}.vben-layout-footer__links a[data-v-0bf7ba29]:hover{color:#000000d9}.vben-layout-footer__github[data-v-0bf7ba29]{margin:0 30px}.vben-layout-footer__github[data-v-0bf7ba29]:hover{color:#000000d9} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.43ba843e.css: -------------------------------------------------------------------------------- 1 | .ant-avatar{box-sizing:border-box;margin:0;padding:0;color:#000000d9;font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:tnum;position:relative;display:inline-block;overflow:hidden;color:#fff;white-space:nowrap;text-align:center;vertical-align:middle;background:#ccc;width:32px;height:32px;line-height:32px;border-radius:50%}.ant-avatar-image{background:transparent}.ant-avatar .ant-image-img{display:block}.ant-avatar-string{position:absolute;left:50%;transform-origin:0 center}.ant-avatar.ant-avatar-icon{font-size:18px}.ant-avatar.ant-avatar-icon>.anticon{margin:0}.ant-avatar-lg{width:40px;height:40px;line-height:40px;border-radius:50%}.ant-avatar-lg-string{position:absolute;left:50%;transform-origin:0 center}.ant-avatar-lg.ant-avatar-icon{font-size:24px}.ant-avatar-lg.ant-avatar-icon>.anticon{margin:0}.ant-avatar-sm{width:24px;height:24px;line-height:24px;border-radius:50%}.ant-avatar-sm-string{position:absolute;left:50%;transform-origin:0 center}.ant-avatar-sm.ant-avatar-icon{font-size:14px}.ant-avatar-sm.ant-avatar-icon>.anticon{margin:0}.ant-avatar-square{border-radius:2px}.ant-avatar>img{display:block;width:100%;height:100%;-o-object-fit:cover;object-fit:cover}.ant-avatar-group{display:inline-flex}.ant-avatar-group .ant-avatar{border:1px solid #fff}.ant-avatar-group .ant-avatar:not(:first-child){margin-left:-8px}.ant-avatar-group-popover .ant-avatar+.ant-avatar{margin-left:3px}.ant-avatar-group-rtl .ant-avatar:not(:first-child){margin-right:-8px;margin-left:0}.ant-avatar-group-popover.ant-popover-rtl .ant-avatar+.ant-avatar{margin-right:3px;margin-left:0} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.5c7227e9.css: -------------------------------------------------------------------------------- 1 | .vben-basic-drawer-footer{position:absolute;bottom:0;width:100%;padding:0 12px 0 20px;text-align:right;background-color:#fff;border-top:1px solid #d9d9d9}.vben-basic-drawer-footer>*{margin-right:8px}.vben-basic-drawer-header{display:flex;height:100%;align-items:center}.vben-basic-drawer-header__back{padding:0 12px;cursor:pointer}.vben-basic-drawer-header__back:hover{color:#0960bd}.vben-basic-drawer-header__twrap{flex:1}.vben-basic-drawer-header__toolbar{padding-right:50px}.vben-basic-drawer .ant-drawer-wrapper-body{overflow:hidden}.vben-basic-drawer .ant-drawer-close:hover{color:#ed6f6f}.vben-basic-drawer .ant-drawer-body{height:calc(100% - 48px);padding:0;background-color:#fff}.vben-basic-drawer .ant-drawer-body .scrollbar__wrap{padding:16px!important;margin-bottom:0!important}.vben-basic-drawer .ant-drawer-body>.scrollbar>.scrollbar__bar.is-horizontal{display:none}.vben-basic-drawer__detail{position:absolute}.vben-basic-drawer__detail .ant-drawer-header{width:100%;height:40px;padding:0;border-top:1px solid #d9d9d9;box-sizing:border-box}.vben-basic-drawer__detail .ant-drawer-title{height:100%}.vben-basic-drawer__detail .ant-drawer-close{height:40px;line-height:40px}.vben-basic-drawer__detail .scrollbar__wrap{padding:0!important}.vben-basic-drawer__detail .ant-drawer-body{height:calc(100% - 40px)} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.75b04f83.css: -------------------------------------------------------------------------------- 1 | .account-setting{margin:12px;background-color:#fff}.account-setting .base-title{padding-left:0}.account-setting .ant-tabs-tab-active{background-color:#e3f4fc} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.858880e5.js: -------------------------------------------------------------------------------- 1 | "undefined"!=typeof require&&require;import{_ as e,u as t}from"./useTable.e6b840ff.js";import{_ as n}from"./useForm.91b099eb.js";import{c as i,i as o}from"./system.194fce67.js";import{u as a}from"./index.9981dd62.js";import{_ as s,c as r,s as d}from"./DeptModal.72ed0467.js";import{D as l,a0 as c,bc as u,F as m,G as p,w as f,a5 as b,H as h,ad as j}from"./vendor.54f9b785.js";/* empty css */import"./index.8c033639.js";import"./index.29cb9d1e.js";/* empty css *//* empty css */import"./onMountedOrActivated.fcde6c3c.js";import"./useWindowSizeFn.51649442.js";import"./useContentViewHeight.e2ebf036.js";/* empty css *//* empty css *//* empty css *//* empty css */import"./useSortable.15816348.js";/* empty css *//* empty css */var x=l({name:"DeptManagement",components:{BasicTable:e,DeptModal:s,TableAction:n},setup(){const[e,{openModal:n}]=a(),[s,{reload:l}]=t({title:"部门列表",api:i,columns:r,formConfig:{labelWidth:120,schemas:d},pagination:!1,striped:!1,useSearchForm:!0,showTableSetting:!0,bordered:!0,showIndexColumn:!1,canResize:!1,actionColumn:{width:80,title:"操作",dataIndex:"action",slots:{customRender:"action"},fixed:void 0}});function c(){l()}return{registerTable:s,registerModal:e,handleCreate:function(){n(!0,{isUpdate:!1})},handleEdit:function(e){n(!0,{record:e,isUpdate:!0})},handleDelete:function(e){return t=this,n=null,i=function*(){(yield o(e.id))&&c()},new Promise(((e,o)=>{var a=e=>{try{r(i.next(e))}catch(t){o(t)}},s=e=>{try{r(i.throw(e))}catch(t){o(t)}},r=t=>t.done?e(t.value):Promise.resolve(t.value).then(a,s);r((i=i.apply(t,n)).next())}));var t,n,i},handleSuccess:c}}});const g=j(" 新增部门 ");x.render=function(e,t,n,i,o,a){const s=c("a-button"),r=c("TableAction"),d=c("BasicTable"),l=c("DeptModal"),j=u("auth");return m(),p("div",null,[f(d,{onRegister:e.registerTable},{toolbar:b((()=>[h(f(s,{type:"primary",onClick:e.handleCreate},{default:b((()=>[g])),_:1},8,["onClick"]),[[j,"dept:btn:add"]])])),action:b((({record:t})=>[f(r,{actions:[{icon:"clarity:note-edit-line",onClick:e.handleEdit.bind(null,t),auth:["dept:btn:edit"]},{icon:"ant-design:delete-outlined",color:"error",auth:["dept:btn:delete"],popConfirm:{title:"是否确认删除",confirm:e.handleDelete.bind(null,t)}}]},null,8,["actions"])])),_:1},8,["onRegister"]),f(l,{onRegister:e.registerModal,onSuccess:e.handleSuccess},null,8,["onRegister","onSuccess"])])};export{x as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.96fb498a.js: -------------------------------------------------------------------------------- 1 | import{D as a,bf as e,a0 as t,F as s,a1 as i,a5 as r,K as n,w as o,G as d,ar as p,ak as m,aa as f,N as l}from"./vendor.54f9b785.js";/* empty css */import{S as b}from"./index.29cb9d1e.js";import{s as j}from"./data.63adca46.js";import c from"./BaseSetting.e577605c.js";import u from"./SecureSetting.3d063fe8.js";/* empty css */import"./useForm.91b099eb.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import"./index.9981dd62.js";import"./useWindowSizeFn.51649442.js";/* empty css */import"./header.d801b988.js";import"./upload.79b9af6d.js";var x=a({components:{ScrollContainer:b,Tabs:e,TabPane:e.TabPane,BaseSetting:c,SecureSetting:u},setup:()=>({prefixCls:"account-setting",settingList:j,tabBarStyle:{width:"220px"}})});x.render=function(a,e,b,j,c,u){const x=t("TabPane"),S=t("Tabs"),g=t("ScrollContainer");return s(),i(g,null,{default:r((()=>[n("div",{ref:"wrapperRef",class:l(a.prefixCls)},[o(S,{"tab-position":"left",tabBarStyle:a.tabBarStyle},{default:r((()=>[(s(!0),d(f,null,p(a.settingList,(a=>(s(),i(x,{key:a.key,tab:a.name},{default:r((()=>[(s(),i(m(a.component)))])),_:2},1032,["tab"])))),128))])),_:1},8,["tabBarStyle"])],2)])),_:1})};export{x as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.9d7e575d.js: -------------------------------------------------------------------------------- 1 | var e;"undefined"!=typeof require&&require;import{D as r,r as o,S as t,$ as s,n as a,a0 as i,F as n,G as l,aa as u,ar as d,H as c,J as m,w as p,u as f,a5 as j,ad as b,L as y}from"./vendor.54f9b785.js";import{_ as g}from"./DetailModal.vue_vue&type=script&setup=true&lang.a6c65b40.js";import{u as v,_ as x}from"./useTable.e6b840ff.js";import{_ as h}from"./useForm.91b099eb.js";import{u as w}from"./index.9981dd62.js";import{f as L,d as _,aa as E}from"./index.29cb9d1e.js";import{getColumns as C}from"./data.3fa8ee9d.js";/* empty css */import"./index.8c033639.js";/* empty css *//* empty css */import"./onMountedOrActivated.fcde6c3c.js";import"./useWindowSizeFn.51649442.js";import"./useContentViewHeight.e2ebf036.js";/* empty css *//* empty css *//* empty css *//* empty css */import"./useSortable.15816348.js";/* empty css *//* empty css */(e||(e={})).Error="/error";const R={class:"p-4"},k=["src"];var D=r({setup(r){const D=o(),A=o([]),{t:T}=_(),F=E(),[M,{setTableData:S}]=v({title:T("sys.errorLog.tableTitle"),columns:C(),actionColumn:{width:80,title:"Action",dataIndex:"action",slots:{customRender:"action"}}}),[q,{openModal:H}]=w();function I(e){D.value=e,H(!0)}function P(){throw new Error("fire vue error!")}function V(){A.value.push(`${(new Date).getTime()}.png`)}function $(){return r=this,o=null,t=function*(){yield L.get({url:e.Error})},new Promise(((e,s)=>{var a=e=>{try{n(t.next(e))}catch(r){s(r)}},i=e=>{try{n(t.throw(e))}catch(r){s(r)}},n=r=>r.done?e(r.value):Promise.resolve(r.value).then(a,i);n((t=t.apply(r,o)).next())}));var r,o,t}return t((()=>F.getErrorLogInfoList),(e=>{s((()=>{S(a(e))}))}),{immediate:!0}),(e,r)=>{const o=i("a-button");return n(),l("div",R,[(n(!0),l(u,null,d(A.value,(e=>c((n(),l("img",{key:e,src:e},null,8,k)),[[m,!1]]))),128)),p(g,{info:D.value,onRegister:f(q)},null,8,["info","onRegister"]),p(f(x),{onRegister:f(M),class:"error-handle-table"},{toolbar:j((()=>[p(o,{onClick:P,type:"primary"},{default:j((()=>[b(y(f(T)("sys.errorLog.fireVueError")),1)])),_:1}),p(o,{onClick:V,type:"primary"},{default:j((()=>[b(y(f(T)("sys.errorLog.fireResourceError")),1)])),_:1}),p(o,{onClick:$,type:"primary"},{default:j((()=>[b(y(f(T)("sys.errorLog.fireAjaxError")),1)])),_:1})])),action:j((({record:e})=>[p(f(h),{actions:[{label:f(T)("sys.errorLog.tableActionDesc"),onClick:I.bind(null,e)}]},null,8,["actions"])])),_:1},8,["onRegister"])])}}});export{D as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.a2505068.css: -------------------------------------------------------------------------------- 1 | .ant-breadcrumb{box-sizing:border-box;margin:0;padding:0;color:#000000d9;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:tnum;color:#00000073;font-size:14px}.ant-breadcrumb .anticon{font-size:14px}.ant-breadcrumb a{color:#00000073;transition:color .3s}.ant-breadcrumb a:hover{color:#2a7dc9}.ant-breadcrumb>span:last-child{color:#000000d9}.ant-breadcrumb>span:last-child a{color:#000000d9}.ant-breadcrumb>span:last-child .ant-breadcrumb-separator{display:none}.ant-breadcrumb-separator{margin:0 8px;color:#00000073}.ant-breadcrumb-link>.anticon+span,.ant-breadcrumb-link>.anticon+a{margin-left:4px}.ant-breadcrumb-overlay-link>.anticon{margin-left:4px}.ant-breadcrumb-rtl{direction:rtl}.ant-breadcrumb-rtl:before,.ant-breadcrumb-rtl:after{display:table;content:""}.ant-breadcrumb-rtl:after{clear:both}.ant-breadcrumb-rtl>span{float:right}.ant-breadcrumb-rtl .ant-breadcrumb-link>.anticon+span,.ant-breadcrumb-rtl .ant-breadcrumb-link>.anticon+a{margin-right:4px;margin-left:0}.ant-breadcrumb-rtl .ant-breadcrumb-overlay-link>.anticon{margin-right:4px;margin-left:0} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.b3b32c91.css: -------------------------------------------------------------------------------- 1 | .fullscreen-modal{overflow:hidden}.fullscreen-modal .ant-modal{top:0!important;right:0!important;bottom:0!important;left:0!important;width:100%!important;height:100%}.fullscreen-modal .ant-modal-content{height:100%}.ant-modal{width:520px;padding-bottom:0}.ant-modal .ant-modal-body>.scrollbar{padding:14px}.ant-modal-title{font-size:16px;font-weight:bold;line-height:16px}.ant-modal-title .base-title{cursor:move!important}.ant-modal .ant-modal-body{padding:0}.ant-modal .ant-modal-body>.scrollbar>.scrollbar__bar.is-horizontal{display:none}.ant-modal-large{top:60px}.ant-modal-large--mini{top:16px}.ant-modal-header{padding:16px}.ant-modal-content{box-shadow:0 4px 8px #0003,0 6px 20px #00000030}.ant-modal-footer button+button{margin-left:10px}.ant-modal-close{font-weight:normal;outline:none}.ant-modal-close-x{display:inline-block;width:96px;height:56px;line-height:56px}.ant-modal-confirm-body .ant-modal-confirm-content>*{color:#909399}.ant-modal-confirm-confirm.error .ant-modal-confirm-body>.anticon{color:#ed6f6f}.ant-modal-confirm-btns .ant-btn:last-child{margin-right:0}.ant-modal-confirm-info .ant-modal-confirm-body>.anticon{color:#efbd47}.ant-modal-confirm-confirm.success .ant-modal-confirm-body>.anticon{color:#55d187}.ant-modal-confirm .ant-modal-body{padding:24px!important}@media screen and (max-height: 600px){.ant-modal{top:60px}}@media screen and (max-height: 540px){.ant-modal{top:30px}}@media screen and (max-height: 480px){.ant-modal{top:10px}}.vben-basic-modal-close{display:flex;height:95%;align-items:center}.vben-basic-modal-close>span{margin-left:48px;font-size:16px}.vben-basic-modal-close--can-full>span{margin-left:12px}.vben-basic-modal-close:not(.vben-basic-modal-close--can-full)>span:nth-child(1):hover{font-weight:700}.vben-basic-modal-close span:nth-child(1){display:inline-block;padding:10px}.vben-basic-modal-close span:nth-child(1):hover{color:#0960bd}.vben-basic-modal-close span:nth-child(2):hover{color:#ed6f6f} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.ce94be82.css: -------------------------------------------------------------------------------- 1 | .vben-iframe-page .ant-spin-nested-loading[data-v-6703bdae]{position:relative;height:100%}.vben-iframe-page .ant-spin-nested-loading .ant-spin-container[data-v-6703bdae]{width:100%;height:100%;padding:10px}.vben-iframe-page__mask[data-v-6703bdae]{position:absolute;top:0;left:0;width:100%;height:100%}.vben-iframe-page__main[data-v-6703bdae]{width:100%;height:100%;overflow:hidden;background-color:#fff;border:0;box-sizing:border-box} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.dde333d5.js: -------------------------------------------------------------------------------- 1 | import{_ as s}from"./GrowCard.vue_vue&type=script&setup=true&lang.c91a4575.js";import{_ as e}from"./SiteAnalysis.vue_vue&type=script&setup=true&lang.27cd1c31.js";import{_ as a}from"./VisitSource.vue_vue&type=script&setup=true&lang.3b4d463f.js";import{_ as t}from"./VisitRadar.vue_vue&type=script&setup=true&lang.a4354064.js";import{_ as i}from"./SalesProductPie.vue_vue&type=script&setup=true&lang.bbaf9b94.js";import{D as l,r,F as u,G as p,w as o,K as n}from"./vendor.54f9b785.js";import"./index.29cb9d1e.js";/* empty css *//* empty css *//* empty css *//* empty css */import"./VisitAnalysis.vue_vue&type=script&setup=true&lang.d605ffa3.js";import"./useECharts.a0aee6e9.js";import"./props.0a93851a.js";import"./VisitAnalysisBar.vue_vue&type=script&setup=true&lang.3ad8168a.js";const d={class:"p-4"},m={class:"md:flex enter-y"};var v=l({setup(l){const v=r(!0);return setTimeout((()=>{v.value=!1}),1500),(l,r)=>(u(),p("div",d,[o(s,{loading:v.value,class:"enter-y"},null,8,["loading"]),o(e,{class:"!my-4 enter-y",loading:v.value},null,8,["loading"]),n("div",m,[o(t,{class:"md:w-1/3 w-full",loading:v.value},null,8,["loading"]),o(a,{class:"md:w-1/3 !md:mx-4 !md:my-0 !my-4 w-full",loading:v.value},null,8,["loading"]),o(i,{class:"md:w-1/3 w-full",loading:v.value},null,8,["loading"])])]))}});export{v as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.e5a92ddb.js: -------------------------------------------------------------------------------- 1 | import{C as e,N as t,aP as s,c as o,W as a}from"./index.29cb9d1e.js";import{D as i,c2 as n,j as r,u,a0 as g,F as p,G as m,w as c,a1 as f,ac as d,N as l,aa as S}from"./vendor.54f9b785.js";import{c as T,u as j}from"./index.83a5ac4f.js";import x from"./SessionTimeoutLogin.14f69a36.js";import"./index.fc649792.js";import"./useWindowSizeFn.51649442.js";import"./useContentViewHeight.e2ebf036.js";/* empty css *//* empty css */import"./useSortable.15816348.js";import"./lock.fb37e799.js";var k=i({name:"LayoutFeatures",components:{BackTop:n,LayoutLockPage:T((()=>e((()=>import("./index.f3a22dc9.js")),["assets/index.f3a22dc9.js","assets/vendor.54f9b785.js","assets/vendor.bd035476.css","assets/LockPage.801c6251.js","assets/LockPage.a757c476.css","assets/index.29cb9d1e.js","assets/index.87cbc01e.css","assets/lock.fb37e799.js","assets/header.d801b988.js"]))),SettingDrawer:T((()=>e((()=>import("./index.5895bef3.js").then((function(e){return e.i}))),["assets/index.5895bef3.js","assets/index.35b5cf30.css","assets/index.5c85c39a.js","assets/index.5c7227e9.css","assets/index.1bb9cac4.css","assets/index.29cb9d1e.js","assets/index.87cbc01e.css","assets/vendor.54f9b785.js","assets/vendor.bd035476.css","assets/index.83a5ac4f.js","assets/index.45857338.css","assets/index.65674215.css","assets/index.fc649792.js","assets/index.ce94be82.css","assets/useWindowSizeFn.51649442.js","assets/useContentViewHeight.e2ebf036.js","assets/useSortable.15816348.js","assets/lock.fb37e799.js"]))),SessionTimeoutLogin:x},setup(){const{getUseOpenBackTop:e,getShowSettingButton:i,getSettingButtonPosition:n,getFullContent:g}=t(),p=s(),{prefixCls:m}=o("setting-drawer-fearure"),{getShowHeader:c}=j(),f=r((()=>p.getSessionTimeout));return{getTarget:()=>document.body,getUseOpenBackTop:e,getIsFixedSettingDrawer:r((()=>{if(!u(i))return!1;const e=u(n);return e===a.AUTO?!u(c)||u(g):e===a.FIXED})),prefixCls:m,getIsSessionTimeout:f}}});k.render=function(e,t,s,o,a,i){const n=g("LayoutLockPage"),r=g("BackTop"),u=g("SettingDrawer"),T=g("SessionTimeoutLogin");return p(),m(S,null,[c(n),e.getUseOpenBackTop?(p(),f(r,{key:0,target:e.getTarget},null,8,["target"])):d("",!0),e.getIsFixedSettingDrawer?(p(),f(u,{key:1,class:l(e.prefixCls)},null,8,["class"])):d("",!0),e.getIsSessionTimeout?(p(),f(T,{key:2})):d("",!0)],64)};export{k as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.e7586e6f.css: -------------------------------------------------------------------------------- 1 | .vben-header-user-dropdown{height:48px;padding:0 10px;overflow:hidden;font-size:12px;cursor:pointer;align-items:center}.vben-header-user-dropdown img{width:24px;height:24px;margin-right:12px}.vben-header-user-dropdown__header{border-radius:50%}.vben-header-user-dropdown__name{font-size:14px}.vben-header-user-dropdown--dark:hover{background-color:var(--header-bg-hover-color)}.vben-header-user-dropdown--light:hover{background-color:#f6f6f6}.vben-header-user-dropdown--light .vben-header-user-dropdown__name{color:#000000d9}.vben-header-user-dropdown--light .vben-header-user-dropdown__desc{color:#7c8087}.vben-header-user-dropdown-dropdown-overlay .ant-dropdown-menu-item{min-width:160px} 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.eadf116e.js: -------------------------------------------------------------------------------- 1 | import{D as e,a as r,u as t,F as a,G as s}from"./vendor.54f9b785.js";var p=e({setup(e){const{currentRoute:p,replace:o}=r(),{params:u,query:y}=t(p),{path:c,_redirect_type:n="path"}=u;Reflect.deleteProperty(u,"_redirect_type"),Reflect.deleteProperty(u,"path");const d=Array.isArray(c)?c.join("/"):c;return o("name"===n?{name:d,query:y,params:u}:{path:d.startsWith("/")?d:"/"+d,query:y}),(e,r)=>(a(),s("div"))}});export{p as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.f3a22dc9.js: -------------------------------------------------------------------------------- 1 | import{D as a,j as o,F as e,a1 as s,a5 as r,u as t,ac as d,a2 as m}from"./vendor.54f9b785.js";import n from"./LockPage.801c6251.js";import{u}from"./lock.fb37e799.js";import"./index.29cb9d1e.js";import"./header.d801b988.js";var i=a({setup(a){const i=u(),f=o((()=>{var a,o;return null!=(o=null==(a=null==i?void 0:i.getLockInfo)?void 0:a.isLock)&&o}));return(a,o)=>(e(),s(m,{name:"fade-bottom",mode:"out-in"},{default:r((()=>[t(f)?(e(),s(n,{key:0})):d("",!0)])),_:1}))}});export{i as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/index.fc649792.js: -------------------------------------------------------------------------------- 1 | import{D as e,r as a,j as s,u as t,F as n,G as i,w as r,a5 as o,K as f,N as c,X as d,aO as l,A as u,B as m}from"./vendor.54f9b785.js";import{u as p}from"./useWindowSizeFn.51649442.js";import{p as g,c as v}from"./index.29cb9d1e.js";import{a as h}from"./useContentViewHeight.e2ebf036.js";u("data-v-6703bdae");const w=["src"];m();var b=e({props:{frameSrc:g.string.def("")},setup(e){const u=a(!0),m=a(50),g=a(window.innerHeight),b=a(),{headerHeightRef:j}=h(),{prefixCls:x}=v("iframe-page");p(_,150,{immediate:!0});const H=s((()=>({height:`${t(g)}px`})));function _(){const e=t(b);if(!e)return;const a=j.value;m.value=a,g.value=window.innerHeight-a;const s=document.documentElement.clientHeight-a;e.style.height=`${s}px`}function y(){u.value=!1,_()}return(a,s)=>(n(),i("div",{class:c(t(x)),style:d(t(H))},[r(t(l),{spinning:u.value,size:"large",style:d(t(H))},{default:o((()=>[f("iframe",{src:e.frameSrc,class:c(`${t(x)}__main`),ref:(e,a)=>{a.frameRef=e,b.value=e},onLoad:y},null,42,w)])),_:1},8,["spinning","style"])],6))}});b.__scopeId="data-v-6703bdae";export{b as default}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/lock.fb37e799.js: -------------------------------------------------------------------------------- 1 | "undefined"!=typeof require&&require;var e=(e,o,t)=>new Promise(((n,r)=>{var s=e=>{try{a(t.next(e))}catch(o){r(o)}},c=e=>{try{a(t.throw(e))}catch(o){r(o)}},a=e=>e.done?n(e.value):Promise.resolve(e.value).then(s,c);a((t=t.apply(e,o)).next())}));import{f as o}from"./vendor.54f9b785.js";import{a7 as t,a8 as n,h as r,a9 as s}from"./index.29cb9d1e.js";const c=o({id:"app-lock",state:()=>({lockInfo:t.getLocal(n)}),getters:{getLockInfo(){return this.lockInfo}},actions:{setLockInfo(e){this.lockInfo=Object.assign({},this.lockInfo,e),t.setLocal(n,this.lockInfo,!0)},resetLockInfo(){t.removeLocal(n,!0),this.lockInfo=null},unLock(o){return e(this,null,(function*(){var t;const n=r();if((null==(t=this.lockInfo)?void 0:t.pwd)===o)return this.resetLockInfo(),!0;return yield(()=>e(this,null,(function*(){var e;try{const t=null==(e=n.getUserInfo)?void 0:e.username,r=yield s({username:t,password:o});return r&&this.resetLockInfo(),r}catch(t){return!1}})))()}))}}});export{c as u}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/login-bg-dark.424130e3.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/login-bg.b265811a.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/logo.63028018.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaomalover/vben-admin-java/5766a8953360a206d604876c812b240e7f84dd6f/admin-server/src/main/resources/static/assets/logo.63028018.png -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/onMountedOrActivated.fcde6c3c.js: -------------------------------------------------------------------------------- 1 | import{_ as o,$ as s,bS as a}from"./vendor.54f9b785.js";function r(r){let t;o((()=>{r(),s((()=>{t=!0}))})),a((()=>{t&&r()}))}export{r as o}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/props.0a93851a.js: -------------------------------------------------------------------------------- 1 | const t={width:{type:String,default:"100%"},height:{type:String,default:"280px"}};export{t as b}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/system.194fce67.js: -------------------------------------------------------------------------------- 1 | import{f as e}from"./index.29cb9d1e.js";var t,s;(s=t||(t={})).AccountList="/admin/getAccountList",s.AccountAdd="/admin/add",s.AccountEdit="/admin/edit",s.AccountDelete="/admin/delete",s.IsAccountExist="/system/accountExist",s.DeptList="/department/getDepartmentTree",s.DeptAdd="/department/add",s.DeptEdit="/department/edit",s.DeptDelete="/department/delete",s.setRoleStatus="/role/setStatus",s.MenuList="/permission/getMenuTree",s.MenuAdd="/permission/add",s.MenuEdit="/permission/edit",s.MenuDelete="/permission/delete",s.RolePageList="/role/getRoleList",s.GetAllRoleList="/role/getAllRoleList",s.RoleAdd="/role/add",s.RoleEdit="/role/edit",s.RoleDelete="/role/delete",s.LogList="/log/page",s.LogDelete="/log/delByIds",s.LogClear="/log/delAll";const a=s=>e.get({url:t.AccountList,params:s}),l=s=>e.post({url:t.AccountAdd,params:s}),d=s=>e.post({url:t.AccountEdit,params:s}),r=s=>e.delete({url:t.AccountDelete+"/"+s}),o=s=>e.get({url:t.DeptList,params:s}),i=s=>e.post({url:t.DeptAdd,params:s}),u=s=>e.post({url:t.DeptEdit,params:s}),p=s=>e.delete({url:t.DeptDelete+"/"+s}),n=s=>e.get({url:t.MenuList,params:s}),m=s=>e.post({url:t.MenuAdd,params:s}),c=s=>e.post({url:t.MenuEdit,params:s}),g=s=>e.delete({url:t.MenuDelete+"/"+s}),A=s=>e.get({url:t.RolePageList,params:s}),L=s=>e.get({url:t.GetAllRoleList,params:s}),D=s=>e.post({url:t.RoleAdd,params:s}),R=s=>e.post({url:t.RoleEdit,params:s}),E=s=>e.delete({url:t.RoleDelete+"/"+s}),M=(s,a)=>e.post({url:t.setRoleStatus,params:{id:s,status:a}}),x=s=>e.get({url:t.LogList,params:s}),f=s=>e.delete({url:t.LogDelete+"/"+s}),S=()=>e.delete({url:t.LogClear});export{d as A,u as D,f as L,g as M,E as R,S as a,L as b,o as c,l as d,a as e,r as f,x as g,i as h,p as i,n as j,c as k,m as l,A as m,R as n,D as o,M as s}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/upload.79b9af6d.js: -------------------------------------------------------------------------------- 1 | import{u as o,f as r}from"./index.29cb9d1e.js";const{uploadUrl:s=""}=o();function u(o,u){return r.uploadFile({url:s,onUploadProgress:u},o)}export{u}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/useContentViewHeight.e2ebf036.js: -------------------------------------------------------------------------------- 1 | "undefined"!=typeof require&&require;import{v as e}from"./index.29cb9d1e.js";import{u as t}from"./useWindowSizeFn.51649442.js";import{r as n,j as i,u as o}from"./vendor.54f9b785.js";const r=Symbol();const a=n(0),u=n(0);function s(){return{headerHeightRef:a,footerHeightRef:u,setHeaderHeight:function(e){a.value=e},setFooterHeight:function(e){u.value=e}}}function h(){const s=n(window.innerHeight),h=n(window.innerHeight),c=i((()=>o(s)-o(a)-o(u)||0));t((()=>{s.value=window.innerHeight}),100,{immediate:!0}),e({contentHeight:c,setPageHeight:function(e){return t=this,n=null,i=function*(){h.value=e},new Promise(((e,o)=>{var r=e=>{try{u(i.next(e))}catch(t){o(t)}},a=e=>{try{u(i.throw(e))}catch(t){o(t)}},u=t=>t.done?e(t.value):Promise.resolve(t.value).then(r,a);u((i=i.apply(t,n)).next())}));var t,n,i},pageHeight:h},r,{native:!0})}export{s as a,h as u}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/useSortable.15816348.js: -------------------------------------------------------------------------------- 1 | var e=Object.defineProperty,r=Object.getOwnPropertySymbols,t=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable,n=(r,t,o)=>t in r?e(r,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):r[t]=o;"undefined"!=typeof require&&require;import{C as a}from"./index.29cb9d1e.js";import{$ as i,u as l}from"./vendor.54f9b785.js";function u(e,u){return{initSortable:function(){i((()=>{return i=this,c=null,p=function*(){e&&(yield a((()=>import("./sortable.esm.b519ac50.js")),[])).default.create(l(e),((e,a)=>{for(var i in a||(a={}))t.call(a,i)&&n(e,i,a[i]);if(r)for(var i of r(a))o.call(a,i)&&n(e,i,a[i]);return e})({animation:500,delay:400,delayOnTouchOnly:!0},u))},new Promise(((e,r)=>{var t=e=>{try{n(p.next(e))}catch(t){r(t)}},o=e=>{try{n(p.throw(e))}catch(t){r(t)}},n=r=>r.done?e(r.value):Promise.resolve(r.value).then(t,o);n((p=p.apply(i,c)).next())}));var i,c,p}))}}}export{u}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/assets/useWindowSizeFn.51649442.js: -------------------------------------------------------------------------------- 1 | import{bg as e,af as n,T as t}from"./vendor.54f9b785.js";function r(r,s=150,i){let o=()=>{r()};const a=t(o,s);o=a;const d=()=>{i&&i.immediate&&o(),window.addEventListener("resize",o)},m=()=>{window.removeEventListener("resize",o)};return e((()=>{d()})),n((()=>{m()})),[d,m]}export{r as u}; 2 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaomalover/vben-admin-java/5766a8953360a206d604876c812b240e7f84dd6f/admin-server/src/main/resources/static/favicon.ico -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/resource/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaomalover/vben-admin-java/5766a8953360a206d604876c812b240e7f84dd6f/admin-server/src/main/resources/static/resource/img/logo.png -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/resource/img/pwa-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaomalover/vben-admin-java/5766a8953360a206d604876c812b240e7f84dd6f/admin-server/src/main/resources/static/resource/img/pwa-192x192.png -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/resource/img/pwa-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaomalover/vben-admin-java/5766a8953360a206d604876c812b240e7f84dd6f/admin-server/src/main/resources/static/resource/img/pwa-512x512.png -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/resource/tinymce/skins/ui/oxide-dark/content.mobile.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Tiny Technologies, Inc. All rights reserved. 3 | * Licensed under the LGPL or a commercial license. 4 | * For LGPL see License.txt in the project root for license information. 5 | * For commercial licenses see https://www.tiny.cloud/ 6 | */ 7 | .tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection{position: absolute;display: inline-block;background-color: green;opacity: .5;} 8 | 9 | body{-webkit-text-size-adjust: none;} 10 | 11 | body img{max-width: 96vw;} 12 | 13 | body table img{max-width: 95%;} 14 | 15 | body{font-family: sans-serif;} 16 | 17 | table{border-collapse: collapse;} 18 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/resource/tinymce/skins/ui/oxide/content.mobile.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Tiny Technologies, Inc. All rights reserved. 3 | * Licensed under the LGPL or a commercial license. 4 | * For LGPL see License.txt in the project root for license information. 5 | * For commercial licenses see https://www.tiny.cloud/ 6 | */ 7 | .tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection{position: absolute;display: inline-block;background-color: green;opacity: .5;} 8 | 9 | body{-webkit-text-size-adjust: none;} 10 | 11 | body img{max-width: 96vw;} 12 | 13 | body table img{max-width: 95%;} 14 | 15 | body{font-family: sans-serif;} 16 | 17 | table{border-collapse: collapse;} 18 | -------------------------------------------------------------------------------- /admin-server/src/main/resources/static/resource/tinymce/skins/ui/oxide/fonts/tinymce-mobile.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaomalover/vben-admin-java/5766a8953360a206d604876c812b240e7f84dd6f/admin-server/src/main/resources/static/resource/tinymce/skins/ui/oxide/fonts/tinymce-mobile.woff -------------------------------------------------------------------------------- /api-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | api-server 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | api-server 11 | 接口服务 12 | 13 | 14 | com.xm 15 | boot 16 | 0.0.1-SNAPSHOT 17 | 18 | 19 | 20 | 21 | 22 | com.xm 23 | common-lib 24 | 0.0.1-SNAPSHOT 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-web 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-actuator 35 | 36 | 37 | 38 | 39 | com.alibaba 40 | druid-spring-boot-starter 41 | 42 | 43 | 44 | 45 | mysql 46 | mysql-connector-java 47 | 48 | 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-starter-data-redis 53 | 54 | 55 | 56 | cn.hutool 57 | hutool-all 58 | 59 | 60 | org.springframework.security 61 | spring-security-core 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | org.springframework.boot 70 | spring-boot-maven-plugin 71 | 2.2.6.RELEASE 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /api-server/src/main/java/com/xm/api/CloudApplication.java: -------------------------------------------------------------------------------- 1 | package com.xm.api; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * Api 服务 8 | * @author xiaomalover 9 | */ 10 | @SpringBootApplication 11 | public class CloudApplication { 12 | public static void main(String[] args) { 13 | SpringApplication.run(CloudApplication.class, args); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /api-server/src/main/java/com/xm/api/authorization/annotation/CurrentControlUser.java: -------------------------------------------------------------------------------- 1 | package com.xm.api.authorization.annotation; 2 | 3 | import com.xm.api.authorization.resolvers.CurrentControlUserMethodArgumentResolver; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * 在Controller的方法参数中使用此注解,该方法在映射时会注入当前登录的User对象 12 | * @see CurrentControlUserMethodArgumentResolver 13 | * @author xiaomalover 14 | */ 15 | @Target(ElementType.PARAMETER) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | public @interface CurrentControlUser { 18 | } 19 | -------------------------------------------------------------------------------- /api-server/src/main/java/com/xm/api/authorization/annotation/CurrentTerminalUser.java: -------------------------------------------------------------------------------- 1 | package com.xm.api.authorization.annotation; 2 | 3 | import com.xm.api.authorization.resolvers.CurrentControlUserMethodArgumentResolver; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * 在Controller的方法参数中使用此注解,该方法在映射时会注入当前登录的User对象 12 | * @see CurrentControlUserMethodArgumentResolver 13 | * @author xiaomalover 14 | */ 15 | @Target(ElementType.PARAMETER) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | public @interface CurrentTerminalUser { 18 | } 19 | -------------------------------------------------------------------------------- /api-server/src/main/java/com/xm/api/authorization/config/MvcConfig.java: -------------------------------------------------------------------------------- 1 | package com.xm.api.authorization.config; 2 | 3 | import com.xm.api.authorization.resolvers.CurrentControlUserMethodArgumentResolver; 4 | import com.xm.api.authorization.resolvers.CurrentTerminalUserMethodArgumentResolver; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.web.method.support.HandlerMethodArgumentResolver; 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; 9 | import java.util.List; 10 | 11 | /** 12 | * 配置类,增加自定义拦截器和解析器 13 | * @see CurrentControlUserMethodArgumentResolver 14 | * @author xiaomalover 15 | */ 16 | @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") 17 | @Configuration 18 | public class MvcConfig extends WebMvcConfigurationSupport { 19 | 20 | @Autowired 21 | private CurrentControlUserMethodArgumentResolver currentControlUserMethodArgumentResolver; 22 | 23 | @Autowired 24 | private CurrentTerminalUserMethodArgumentResolver currentTerminalUserMethodArgumentResolver; 25 | 26 | @Override 27 | public void addArgumentResolvers(List argumentResolvers) { 28 | argumentResolvers.add(currentControlUserMethodArgumentResolver); 29 | argumentResolvers.add(currentTerminalUserMethodArgumentResolver); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /api-server/src/main/java/com/xm/api/authorization/constant/TokenConstant.java: -------------------------------------------------------------------------------- 1 | package com.xm.api.authorization.constant; 2 | 3 | /** 4 | * Token相关常量 5 | * 6 | * @author xiaomalover 7 | */ 8 | public class TokenConstant { 9 | 10 | /** 11 | * 控制端TOKEN 12 | */ 13 | public final static int TOKEN_TYPE_CONTROL = 1; 14 | 15 | /** 16 | * 设备端TOKEN 17 | */ 18 | public final static int TOKEN_TYPE_TERMINAL = 2; 19 | 20 | /** 21 | * 控制端TOKEN过期时间常量 22 | */ 23 | public final static int CONTROL_TOKEN_EXPIRED = 15 * 3600; 24 | 25 | /** 26 | * 设备端TOKEN过过期时间常量 27 | */ 28 | public final static int TERMINAL_TOKEN_EXPIRED = 15 * 3600; 29 | 30 | /** 31 | * 控制端用户Token前缀常量 32 | */ 33 | public final static String CONTROL_TOKEN_KEY_PREFIX = "control_token_"; 34 | 35 | /** 36 | * 设备端用户Token前缀常量 37 | */ 38 | public final static String TERMINAL_TOKEN_KEY_PREFIX = "terminal_token_"; 39 | 40 | /** 41 | * 控制端用户id与token映射缓存常量 42 | */ 43 | public final static String CONTROL_TOKEN_HASH_KEY_PREFIX = "control_token_hash_"; 44 | 45 | /** 46 | * 设备端用户id与token映射缓存常量 47 | */ 48 | public final static String TERMINAL_TOKEN_HASH_KEY_PREFIX = "terminal_token_hash_"; 49 | 50 | /** 51 | * 校验参数名常量 52 | */ 53 | public final static String CONTROL_TOKEN_PARAM_NAME = "control_token"; 54 | 55 | /** 56 | * 校验参数名常量 57 | */ 58 | public final static String TERMINAL_TOKEN_PARAM_NAME = "terminal_token"; 59 | } 60 | -------------------------------------------------------------------------------- /api-server/src/main/java/com/xm/api/authorization/manager/TokenManager.java: -------------------------------------------------------------------------------- 1 | package com.xm.api.authorization.manager; 2 | 3 | import com.xm.api.authorization.vo.Token; 4 | 5 | /** 6 | * 对Token进行操作的接口 7 | * @author xiaomalover 8 | */ 9 | public interface TokenManager { 10 | 11 | /** 12 | * 创建一个token关联上指定用户 13 | * @param userId 指定用户的id 14 | * @param tokenType TOKEN的类型,是设备端还是控制端 15 | * @return 生成的token 16 | */ 17 | Token createToken(String userId, int tokenType); 18 | 19 | /** 20 | * 刷新token 21 | * @param token token 22 | * @param tokenType TOKEN的类型,是设备端还是控制端 23 | */ 24 | void refreshToken(String token, int tokenType); 25 | 26 | /** 27 | * 通过token拿userId 28 | * @param token token 29 | * @param tokenType TOKEN的类型,是设备端还是控制端 30 | * @return 用户id 31 | */ 32 | String getUserIdByToken(String token, int tokenType); 33 | } 34 | -------------------------------------------------------------------------------- /api-server/src/main/java/com/xm/api/authorization/vo/Token.java: -------------------------------------------------------------------------------- 1 | package com.xm.api.authorization.vo; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * Token的Model类,可以增加字段提高安全性,例如时间戳、url签名 7 | * 8 | * @author xiaomalover 9 | */ 10 | @Data 11 | public class Token { 12 | 13 | /** 14 | * 用户id 15 | */ 16 | private String userId; 17 | 18 | /** 19 | * 随机生成的uuid 20 | */ 21 | private String token; 22 | 23 | /** 24 | * 过期时间 25 | */ 26 | private int ttl; 27 | 28 | public Token(String userId, String token, int ttl) { 29 | this.userId = userId; 30 | this.token = token; 31 | this.ttl = ttl; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /api-server/src/main/java/com/xm/api/config/mybatisplus/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.xm.api.config.mybatisplus; 2 | 3 | import com.baomidou.mybatisplus.annotation.DbType; 4 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 5 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 6 | import org.mybatis.spring.annotation.MapperScan; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | /** 11 | * Mybatis-plus 配置类 12 | * 13 | * @author xiaomalover 14 | */ 15 | @Configuration 16 | @MapperScan("com.xm.admin.module.*.mapper") 17 | public class MybatisPlusConfig { 18 | 19 | @Bean 20 | public MybatisPlusInterceptor mybatisPlusInterceptor() { 21 | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); 22 | interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2)); 23 | return interceptor; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /api-server/src/main/java/com/xm/api/enums/VerifyCodeEnum.java: -------------------------------------------------------------------------------- 1 | package com.xm.api.enums; 2 | 3 | /** 4 | * 短信验证码枚举 5 | */ 6 | public enum VerifyCodeEnum { 7 | 8 | TYPE_REGISTER(1, "注册验证码", ""), 9 | TYPE_CHANGE_PASSWORD(2, "修改密码", "") 10 | ; 11 | 12 | /** 13 | * 类型 14 | */ 15 | private int type; 16 | 17 | /** 18 | * 类型描述 19 | */ 20 | private String description; 21 | 22 | /** 23 | * 短信模板 24 | */ 25 | private String template; 26 | 27 | VerifyCodeEnum(int type, String description, String template) { 28 | this.type = type; 29 | this.description = description; 30 | this.template = template; 31 | } 32 | 33 | public int getType() { 34 | return type; 35 | } 36 | 37 | public void setType(int type) { 38 | this.type = type; 39 | } 40 | 41 | public String getDescription() { 42 | return description; 43 | } 44 | 45 | public void setDescription(String description) { 46 | this.description = description; 47 | } 48 | 49 | public String getTemplate() { 50 | return template; 51 | } 52 | 53 | public void setTemplate(String template) { 54 | this.template = template; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /api-server/src/main/java/com/xm/api/exception/RestErrorFilter.java: -------------------------------------------------------------------------------- 1 | package com.xm.api.exception; 2 | 3 | import com.xm.common.utils.ResultUtil; 4 | import org.springframework.boot.web.servlet.error.ErrorController; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | import javax.servlet.http.HttpServletResponse; 9 | 10 | /** 11 | * @author xiaomalover 12 | * 错误捕获 13 | */ 14 | @RestController 15 | public class RestErrorFilter implements ErrorController { 16 | 17 | private static final String ERROR_PATH = "/error"; 18 | 19 | @RequestMapping(value = ERROR_PATH) 20 | public Object handleError(HttpServletResponse response) { 21 | int code = response.getStatus(); 22 | if (code == HttpStatus.NOT_FOUND.value()) { 23 | return new ResultUtil<>().error(HttpStatus.NOT_FOUND.value(), HttpStatus.NOT_FOUND.getReasonPhrase()); 24 | } else if (code == HttpStatus.METHOD_NOT_ALLOWED.value()) { 25 | return new ResultUtil<>().error(HttpStatus.METHOD_NOT_ALLOWED.value(), HttpStatus.METHOD_NOT_ALLOWED.getReasonPhrase()); 26 | } else { 27 | return new ResultUtil<>().error(HttpStatus.INTERNAL_SERVER_ERROR.value(), HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()); 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /api-server/src/main/java/com/xm/api/exception/RestExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.xm.api.exception; 2 | 3 | import com.xm.common.utils.ResultUtil; 4 | import com.xm.common.vo.Result; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.validation.BindException; 7 | import org.springframework.validation.ObjectError; 8 | import org.springframework.web.bind.annotation.ExceptionHandler; 9 | import org.springframework.web.bind.annotation.ResponseBody; 10 | import org.springframework.web.bind.annotation.ResponseStatus; 11 | import org.springframework.web.bind.annotation.RestControllerAdvice; 12 | import java.util.List; 13 | 14 | /** 15 | * @author xiaomalover 16 | * 异常捕获处理 17 | */ 18 | @RestControllerAdvice 19 | public class RestExceptionHandler { 20 | 21 | /** 22 | * 参数异常处理 23 | * 24 | * @param e 参数校验异常 25 | * @return 结果 26 | */ 27 | @ExceptionHandler(BindException.class) 28 | @ResponseStatus(HttpStatus.OK) 29 | public Result error(BindException e) { 30 | List allErrors = e.getAllErrors(); // 拿到异常信息 31 | String errMessage = getErrMessage(allErrors); // 拼接, 返回前端 32 | return new ResultUtil<>().error(errMessage); 33 | } 34 | 35 | /** 36 | * 自定义异常 37 | */ 38 | @ExceptionHandler(Exception.class) 39 | @ResponseBody 40 | public Object requestNotReadable(Exception e) { 41 | return new ResultUtil<>().error(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage()); 42 | } 43 | 44 | /** 45 | * 获取异常信息, 拼成String 46 | * 47 | * @param errors 错误消息集合 48 | * @return 错误消息字符串 49 | */ 50 | private String getErrMessage(List errors) { 51 | StringBuilder errorMsg = new StringBuilder(); 52 | errors.forEach((err) -> { 53 | if (errorMsg.length() > 0) { 54 | errorMsg.append(";"); 55 | } 56 | errorMsg.append(err.getDefaultMessage()); 57 | }); 58 | return errorMsg.toString(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /api-server/src/main/java/com/xm/api/handler/MyMetaObjectHandler.java: -------------------------------------------------------------------------------- 1 | package com.xm.api.handler; 2 | 3 | import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; 4 | import org.apache.ibatis.reflection.MetaObject; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * 填充器, 新增和修改时自动填充时间 9 | * 配合实体中的 @TableField(fill= FieldFill.INSERT) 和 @TableField(fill= FieldFill.INSERT_UPDATE) 使用 10 | * 11 | * @author xiaomalover 12 | */ 13 | @Component 14 | public class MyMetaObjectHandler implements MetaObjectHandler { 15 | 16 | @Override 17 | public void insertFill(MetaObject metaObject) { 18 | Long now = getTimestamp(); 19 | setFieldValByName("createdAt", now, metaObject); 20 | setFieldValByName("updatedAt", now, metaObject); 21 | } 22 | 23 | @Override 24 | public void updateFill(MetaObject metaObject) { 25 | setFieldValByName("updatedAt", getTimestamp(), metaObject); 26 | } 27 | 28 | private Long getTimestamp() { 29 | return System.currentTimeMillis() / 1000; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /api-server/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 20001 3 | servlet: 4 | context-path: /cloud 5 | 6 | spring: 7 | application: 8 | name: cloud-server 9 | datasource: 10 | url: jdbc:mysql://mysql.xm.me:3306/skeleton?useUnicode=true&characterEncoding=utf-8&useSSL=false&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true 11 | username: root 12 | password: root 13 | type: com.alibaba.druid.pool.DruidDataSource 14 | driverClassName: com.mysql.jdbc.Driver 15 | logSlowSql: true 16 | # Druid StatViewServlet配置 17 | druid: 18 | stat-view-servlet: 19 | # 默认true 内置监控页面首页/druid/index.html 20 | enabled: true 21 | url-pattern: /druid/* 22 | # 允许清空统计数据 23 | reset-enable: true 24 | login-username: root 25 | login-password: root 26 | # IP白名单 多个逗号分隔 27 | allow: 28 | # IP黑名单 29 | deny: 30 | 31 | # Redis 32 | redis: 33 | host: redis.xm.me 34 | #password: xiaomalover 35 | # 数据库索引 默认0 36 | database: 0 37 | port: 6379 38 | timeout: 3000s 39 | #password: 69F0ef5dd1d62ab48b13834286403A 40 | 41 | # Mybatis-plus 42 | mybatis-plus: 43 | # 放在resource目录 classpath:/mapper/**/*Mapper.xml 44 | mapper-locations: classpath:/mapper/**/*Mapper.xml 45 | #实体扫描,多个package用逗号或者分号分隔 46 | typeAliasesPackage: com.xm.api.*.*.entity 47 | typeEnumsPackage: com.xm.api.*.*.entity 48 | global-config: 49 | #主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID"; 50 | id-type: 2 51 | #字段策略 0:"忽略判断",1:"非 NULL 判断",2:"非空判断" 52 | field-strategy: 2 53 | #驼峰下划线转换 54 | db-column-underline: true 55 | #刷新mapper 调试神器 56 | refresh-mapper: true 57 | #数据库大写下划线转换 58 | #capital-mode: true 59 | #逻辑删除配置(下面3个配置) 60 | logic-delete-value: 0 61 | logic-not-delete-value: 1 62 | # SQL 解析缓存,开启后多租户 @SqlParser 注解生效 63 | sql-parser-cache: true 64 | configuration: 65 | map-underscore-to-camel-case: true 66 | cache-enabled: false -------------------------------------------------------------------------------- /api-server/src/main/resources/application-prod.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 20001 3 | servlet: 4 | context-path: /api 5 | 6 | spring: 7 | application: 8 | name: api-server 9 | datasource: 10 | url: jdbc:mysql://127.0.0.1:3306/skeleton?useUnicode=true&characterEncoding=utf-8&useSSL=false&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true 11 | username: root 12 | password: root 13 | type: com.alibaba.druid.pool.DruidDataSource 14 | driverClassName: com.mysql.jdbc.Driver 15 | logSlowSql: true 16 | # Druid StatViewServlet配置 17 | druid: 18 | stat-view-servlet: 19 | # 默认true 内置监控页面首页/druid/index.html 20 | enabled: true 21 | url-pattern: /druid/* 22 | # 允许清空统计数据 23 | reset-enable: true 24 | login-username: root 25 | login-password: root 26 | # IP白名单 多个逗号分隔 27 | allow: 28 | # IP黑名单 29 | deny: 30 | 31 | # Mybatis-plus 32 | mybatis-plus: 33 | # 放在resource目录 classpath:/mapper/**/*Mapper.xml 34 | mapper-locations: classpath:/mapper/**/*Mapper.xml 35 | #实体扫描,多个package用逗号或者分号分隔 36 | typeAliasesPackage: com.xm.api.*.*.entity 37 | typeEnumsPackage: com.xm.api.*.*.entity 38 | global-config: 39 | #主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID"; 40 | id-type: 2 41 | #字段策略 0:"忽略判断",1:"非 NULL 判断",2:"非空判断" 42 | field-strategy: 2 43 | #驼峰下划线转换 44 | db-column-underline: true 45 | #刷新mapper 调试神器 46 | refresh-mapper: true 47 | #数据库大写下划线转换 48 | #capital-mode: true 49 | #逻辑删除配置(下面3个配置) 50 | logic-delete-value: 0 51 | logic-not-delete-value: 1 52 | # SQL 解析缓存,开启后多租户 @SqlParser 注解生效 53 | sql-parser-cache: true 54 | configuration: 55 | map-underscore-to-camel-case: true 56 | cache-enabled: false -------------------------------------------------------------------------------- /api-server/src/main/resources/application-test.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 20001 3 | servlet: 4 | context-path: /api 5 | 6 | spring: 7 | application: 8 | name: api-server 9 | datasource: 10 | url: jdbc:mysql://127.0.0.1:3306/skeleton?useUnicode=true&characterEncoding=utf-8&useSSL=false&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true 11 | username: root 12 | password: root 13 | type: com.alibaba.druid.pool.DruidDataSource 14 | driverClassName: com.mysql.jdbc.Driver 15 | logSlowSql: true 16 | # Druid StatViewServlet配置 17 | druid: 18 | stat-view-servlet: 19 | # 默认true 内置监控页面首页/druid/index.html 20 | enabled: true 21 | url-pattern: /druid/* 22 | # 允许清空统计数据 23 | reset-enable: true 24 | login-username: root 25 | login-password: root 26 | # IP白名单 多个逗号分隔 27 | allow: 28 | # IP黑名单 29 | deny: 30 | 31 | # Mybatis-plus 32 | mybatis-plus: 33 | # 放在resource目录 classpath:/mapper/**/*Mapper.xml 34 | mapper-locations: classpath:/mapper/**/*Mapper.xml 35 | #实体扫描,多个package用逗号或者分号分隔 36 | typeAliasesPackage: com.xm.api.*.*.entity 37 | typeEnumsPackage: com.xm.api.*.*.entity 38 | global-config: 39 | #主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID"; 40 | id-type: 2 41 | #字段策略 0:"忽略判断",1:"非 NULL 判断",2:"非空判断" 42 | field-strategy: 2 43 | #驼峰下划线转换 44 | db-column-underline: true 45 | #刷新mapper 调试神器 46 | refresh-mapper: true 47 | #数据库大写下划线转换 48 | #capital-mode: true 49 | #逻辑删除配置(下面3个配置) 50 | logic-delete-value: 0 51 | logic-not-delete-value: 1 52 | # SQL 解析缓存,开启后多租户 @SqlParser 注解生效 53 | sql-parser-cache: true 54 | configuration: 55 | map-underscore-to-camel-case: true 56 | cache-enabled: false -------------------------------------------------------------------------------- /api-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | profiles: 3 | active: dev 4 | -------------------------------------------------------------------------------- /api-server/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | _(\_/) 2 | ,((((^`\ 3 | (((( (6 \ 4 | ,((((( , \ 5 | ,,,_ ,((((( /"._ ,`, 6 | ((((\\ ,... ,(((( / `-.-' 7 | ))) ;' `"'"'""(((( ( 8 | ((( / ((( \ 9 | )) | @cloud-server | 10 | (( | . ' | 11 | )) \ _ ' `t ,.') 12 | ( | y;- -,-""'"-.\ \/ 13 | ) / ./ ) / `\ \ 14 | |./ ( ( / /' 15 | || \\ //'| 16 | || \\ _//'|| 17 | || )) |_/ || 18 | \_\ |_/ || 19 | `'" \_\ 20 | `'" -------------------------------------------------------------------------------- /api-server/src/main/resources/mapper/article/ArticleCategoryMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /api-server/src/main/resources/mapper/article/ArticleInfoMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /api-server/src/main/resources/mapper/control/EnterpriseUserInfoMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /api-server/src/main/resources/mapper/terminal/TerminalUserInfoMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /common-lib/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | common-lib 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | common-lib 11 | common libs 12 | 13 | 14 | com.xm 15 | boot 16 | 0.0.1-SNAPSHOT 17 | 18 | 19 | 20 | 21 | 22 | 23 | org.projectlombok 24 | lombok 25 | 26 | 27 | 28 | 29 | com.baomidou 30 | mybatis-plus-boot-starter 31 | 32 | 33 | 34 | 35 | com.alibaba 36 | fastjson 37 | 38 | 39 | 40 | cn.hutool 41 | hutool-all 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-maven-plugin 51 | 52 | true 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /common-lib/src/main/java/com/xm/common/entity/BaseEntity.java: -------------------------------------------------------------------------------- 1 | package com.xm.common.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.IdType; 5 | import com.baomidou.mybatisplus.annotation.TableField; 6 | import com.baomidou.mybatisplus.annotation.TableId; 7 | import lombok.Data; 8 | import java.io.Serializable; 9 | 10 | /** 11 | * @author xiaomalover 12 | * 标准实体的其类,ID使用自增算法 13 | * 包含了添加、修改时间,添加、修改人 14 | */ 15 | @Data 16 | public abstract class BaseEntity implements Serializable { 17 | 18 | @TableId(type = IdType.AUTO) 19 | private Integer id; 20 | 21 | @TableField(fill = FieldFill.INSERT) 22 | private Long createdAt; 23 | 24 | @TableField(fill = FieldFill.INSERT) 25 | private String createdBy; 26 | 27 | @TableField(fill = FieldFill.INSERT_UPDATE) 28 | private Long updatedAt; 29 | 30 | @TableField(fill = FieldFill.INSERT_UPDATE) 31 | private String updatedBy; 32 | } 33 | -------------------------------------------------------------------------------- /common-lib/src/main/java/com/xm/common/entity/BaseLogEntity.java: -------------------------------------------------------------------------------- 1 | package com.xm.common.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.IdType; 5 | import com.baomidou.mybatisplus.annotation.TableField; 6 | import com.baomidou.mybatisplus.annotation.TableId; 7 | import lombok.Data; 8 | 9 | import java.io.Serializable; 10 | 11 | /** 12 | * @author xiaomalover 13 | * 标准实体的其类,ID使用自增算法 14 | * 只包含了添加时间 15 | */ 16 | @Data 17 | public abstract class BaseLogEntity implements Serializable { 18 | 19 | @TableId(type = IdType.AUTO) 20 | private Integer id; 21 | 22 | @TableField(fill = FieldFill.INSERT) 23 | private Long createdAt; 24 | } 25 | -------------------------------------------------------------------------------- /common-lib/src/main/java/com/xm/common/entity/BaseSimpleEntity.java: -------------------------------------------------------------------------------- 1 | package com.xm.common.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.IdType; 5 | import com.baomidou.mybatisplus.annotation.TableField; 6 | import com.baomidou.mybatisplus.annotation.TableId; 7 | import lombok.Data; 8 | 9 | import java.io.Serializable; 10 | 11 | /** 12 | * @author xiaomalover 13 | * 标准实体的其类,ID使用自增算法 14 | * 只包含了添加、修改时间 15 | */ 16 | @Data 17 | public abstract class BaseSimpleEntity implements Serializable { 18 | 19 | @TableId(type = IdType.AUTO) 20 | private Integer id; 21 | 22 | @TableField(fill = FieldFill.INSERT) 23 | private Long createdAt; 24 | 25 | @TableField(fill = FieldFill.INSERT_UPDATE) 26 | private Long updatedAt; 27 | } 28 | -------------------------------------------------------------------------------- /common-lib/src/main/java/com/xm/common/enums/CommonStatus.java: -------------------------------------------------------------------------------- 1 | package com.xm.common.enums; 2 | 3 | /** 4 | * 通用状态枚举 5 | * 6 | * @author xiaomalover 7 | */ 8 | public enum CommonStatus { 9 | /** 10 | * 状态 - 无效 11 | */ 12 | STATUS_DISABLED(0, "无效"), 13 | 14 | /** 15 | * 状态 - 无效 16 | */ 17 | STATUS_ENABLED(1, "有效"), 18 | 19 | /** 20 | * 状态 - 删除 21 | */ 22 | STATUS_DELETED(2, "删除"); 23 | 24 | /** 25 | * 状态 26 | */ 27 | private int status; 28 | 29 | /** 30 | * 描述 31 | */ 32 | private String description; 33 | 34 | CommonStatus(int status, String description) { 35 | this.status = status; 36 | this.description = description; 37 | } 38 | 39 | public int getStatus() { 40 | return status; 41 | } 42 | 43 | public void setStatus(int status) { 44 | this.status = status; 45 | } 46 | 47 | public String getDescription() { 48 | return description; 49 | } 50 | 51 | public void setDescription(String description) { 52 | this.description = description; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /common-lib/src/main/java/com/xm/common/utils/CommonPageUtil.java: -------------------------------------------------------------------------------- 1 | package com.xm.common.utils; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 5 | import com.xm.common.vo.ExtraVo; 6 | 7 | /** 8 | * @author xiaomalover 9 | */ 10 | public class CommonPageUtil { 11 | 12 | /** 13 | * 初始化分页抽象类 14 | * 15 | * @param page 页数 16 | * @param pageSize 每页条数 17 | * @return 分页抽象类 18 | */ 19 | public IPage initIPage(Integer page, Integer pageSize) { 20 | IPage iPage = new Page<>(); 21 | if (page == null || page < 1) { 22 | page = 1; 23 | } 24 | if (pageSize == null || pageSize < 1) { 25 | pageSize = 10; 26 | } 27 | iPage.setCurrent(page); 28 | iPage.setSize(pageSize); 29 | return iPage; 30 | } 31 | 32 | public IPage initIPage(ExtraVo extraVo) { 33 | 34 | IPage iPage = new Page<>(); 35 | int page = extraVo.getPage(); 36 | int pageSize = extraVo.getPageSize(); 37 | 38 | if (page < 1) { 39 | page = 1; 40 | } 41 | if (pageSize < 1) { 42 | pageSize = 10; 43 | } 44 | iPage.setCurrent(page); 45 | iPage.setSize(pageSize); 46 | return iPage; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /common-lib/src/main/java/com/xm/common/vo/Captcha.java: -------------------------------------------------------------------------------- 1 | package com.xm.common.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * @author xiaomalover 9 | */ 10 | @Data 11 | public class Captcha implements Serializable { 12 | 13 | private String captchaId; 14 | 15 | private String imgBase64; 16 | } 17 | -------------------------------------------------------------------------------- /common-lib/src/main/java/com/xm/common/vo/ExtraVo.java: -------------------------------------------------------------------------------- 1 | package com.xm.common.vo; 2 | 3 | import lombok.Data; 4 | import org.springframework.util.ObjectUtils; 5 | import java.io.Serializable; 6 | import java.sql.Timestamp; 7 | 8 | /** 9 | * 分页排序日期搜索前端收集VO 10 | * 11 | * @author xiaomalover 12 | */ 13 | @Data 14 | public class ExtraVo implements Serializable { 15 | 16 | private static final long serialVersionUID = 1L; 17 | 18 | private int page; 19 | 20 | private int pageSize; 21 | 22 | private String sort; 23 | 24 | private String order; 25 | 26 | private Long startDate; 27 | 28 | private Long endDate; 29 | 30 | public void setStartDate(String startDate) 31 | { 32 | if (!ObjectUtils.isEmpty(startDate)) { 33 | this.startDate = this.stringToTimestamp(startDate); 34 | } 35 | } 36 | 37 | public void setEndDate(String endDate) 38 | { 39 | if (!ObjectUtils.isEmpty(endDate)) { 40 | Long temp = this.stringToTimestamp(endDate); 41 | this.endDate = temp + 24 * 3600; 42 | } 43 | } 44 | 45 | private Long stringToTimestamp(String time) { 46 | 47 | //兼容带时间的 48 | if (time.length() > 10) { 49 | time = time.substring(0, 10); 50 | } 51 | 52 | time += " 00:00:00"; 53 | long timestamp = 0L; 54 | try { 55 | timestamp = ((Timestamp.valueOf(time).getTime()) / 1000); 56 | } catch (Exception e) { 57 | e.printStackTrace(); 58 | } 59 | return timestamp; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /common-lib/src/main/java/com/xm/common/vo/Result.java: -------------------------------------------------------------------------------- 1 | package com.xm.common.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * @author xiaomalover 9 | * 前后端交互数据标准 10 | */ 11 | @Data 12 | public class Result implements Serializable { 13 | 14 | private static final long serialVersionUID = 1L; 15 | 16 | /** 17 | * 成功标志 18 | */ 19 | private boolean success; 20 | 21 | /** 22 | * 消息 23 | */ 24 | private String message; 25 | 26 | /** 27 | * 返回代码 28 | */ 29 | private Integer code; 30 | 31 | /** 32 | * 时间戳 33 | */ 34 | private long timestamp = System.currentTimeMillis(); 35 | 36 | /** 37 | * 结果对象 38 | */ 39 | private T result; 40 | } 41 | -------------------------------------------------------------------------------- /doc/accountList.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaomalover/vben-admin-java/5766a8953360a206d604876c812b240e7f84dd6f/doc/accountList.jpg -------------------------------------------------------------------------------- /doc/articleList.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaomalover/vben-admin-java/5766a8953360a206d604876c812b240e7f84dd6f/doc/articleList.jpg -------------------------------------------------------------------------------- /doc/contact.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaomalover/vben-admin-java/5766a8953360a206d604876c812b240e7f84dd6f/doc/contact.jpg -------------------------------------------------------------------------------- /doc/home.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaomalover/vben-admin-java/5766a8953360a206d604876c812b240e7f84dd6f/doc/home.jpg -------------------------------------------------------------------------------- /doc/lock.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaomalover/vben-admin-java/5766a8953360a206d604876c812b240e7f84dd6f/doc/lock.jpg -------------------------------------------------------------------------------- /doc/login.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaomalover/vben-admin-java/5766a8953360a206d604876c812b240e7f84dd6f/doc/login.jpg -------------------------------------------------------------------------------- /doc/roleAssign.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaomalover/vben-admin-java/5766a8953360a206d604876c812b240e7f84dd6f/doc/roleAssign.jpg -------------------------------------------------------------------------------- /doc/tinymce.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaomalover/vben-admin-java/5766a8953360a206d604876c812b240e7f84dd6f/doc/tinymce.jpg -------------------------------------------------------------------------------- /generator/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | boot 7 | com.xm 8 | 0.0.1-SNAPSHOT 9 | 10 | 11 | 4.0.0 12 | 13 | generator 14 | 15 | 16 | 17 | 18 | com.xm 19 | common-lib 20 | 0.0.1-SNAPSHOT 21 | 22 | 23 | 24 | 25 | mysql 26 | mysql-connector-java 27 | 28 | 29 | 30 | com.baomidou 31 | mybatis-plus-generator 32 | 33 | 34 | 35 | com.ibeetl 36 | beetl 37 | 38 | 39 | 40 | cn.hutool 41 | hutool-all 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-maven-plugin 52 | 2.2.6.RELEASE 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | maven-compiler-plugin 61 | 62 | 1.8 63 | 1.8 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /generator/src/main/resources/templates/controller.java.btl: -------------------------------------------------------------------------------- 1 | package ${package.Controller}; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | <% if(restControllerStyle){ %> 5 | import org.springframework.web.bind.annotation.RestController; 6 | <% }else{ %> 7 | import org.springframework.stereotype.Controller; 8 | <% } %> 9 | <% if(isNotEmpty(superControllerClassPackage)){ %> 10 | import ${superControllerClassPackage}; 11 | <% } %> 12 | 13 | /** 14 | *

15 | * ${table.comment!} 前端控制器 16 | *

17 | * 18 | * @author ${author} 19 | * @since ${date} 20 | */ 21 | <% if(restControllerStyle){ %> 22 | @RestController 23 | <% }else{ %> 24 | @Controller 25 | <% } %> 26 | @RequestMapping("${cfg.requestMappingPrefix}/${table.entityPath}") 27 | <% if(kotlin){ %> 28 | class ${table.controllerName}<% if(isNotEmpty(superControllerClass)){ %> : ${superControllerClass}()<% } %> 29 | <% }else{ %> 30 | <% if(isNotEmpty(superControllerClass)){ %> 31 | public class ${table.controllerName} extends ${superControllerClass} { 32 | <% }else{ %> 33 | public class ${table.controllerName} { 34 | <% } %> 35 | 36 | } 37 | <% } %> 38 | -------------------------------------------------------------------------------- /generator/src/main/resources/templates/mapper.java.btl: -------------------------------------------------------------------------------- 1 | package ${package.Mapper}; 2 | 3 | import ${package.Entity}.${entity}; 4 | import ${superMapperClassPackage}; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | *

9 | * ${table.comment!} Mapper 接口 10 | *

11 | * 12 | * @author ${author} 13 | * @since ${date} 14 | */ 15 | @Repository 16 | <% if(kotlin){ %> 17 | interface ${table.mapperName} : ${superMapperClass}<${entity}> 18 | <% }else{ %> 19 | public interface ${table.mapperName} extends ${superMapperClass}<${entity}> { 20 | 21 | } 22 | <% } %> 23 | -------------------------------------------------------------------------------- /generator/src/main/resources/templates/mapper.xml.btl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <% if(enableCache){ %> 5 | 6 | 7 | <% } %> 8 | <% if(baseResultMap){ %> 9 | 10 | 11 | <% for(field in table.fields){ %> 12 | <% /** 生成主键排在第一位 **/ %> 13 | <% if(field.keyFlag){ %> 14 | 15 | <% } %> 16 | <% } %> 17 | <% for(field in table.commonFields){ %> 18 | <% /** 生成公共字段 **/ %> 19 | 20 | <% } %> 21 | <% for(field in table.fields){ %> 22 | <% /** 生成普通字段 **/ %> 23 | <% if(!field.keyFlag){ %> 24 | 25 | <% } %> 26 | <% } %> 27 | 28 | <% } %> 29 | <% if(baseColumnList){ %> 30 | 31 | 32 | <% for(field in table.commonFields){ %> 33 | ${field.name}, 34 | <% } %> 35 | ${table.fieldNames} 36 | 37 | <% } %> 38 | 39 | -------------------------------------------------------------------------------- /generator/src/main/resources/templates/service.java.btl: -------------------------------------------------------------------------------- 1 | package ${package.Service}; 2 | 3 | import ${package.Entity}.${entity}; 4 | import ${superServiceClassPackage}; 5 | 6 | /** 7 | *

8 | * ${table.comment!} 服务类 9 | *

10 | * 11 | * @author ${author} 12 | * @since ${date} 13 | */ 14 | <% if(kotlin){ %> 15 | interface ${table.serviceName} : ${superServiceClass}<${entity}> 16 | <% }else{ %> 17 | public interface ${table.serviceName} extends ${superServiceClass}<${entity}> { 18 | 19 | } 20 | <% } %> -------------------------------------------------------------------------------- /generator/src/main/resources/templates/serviceImpl.java.btl: -------------------------------------------------------------------------------- 1 | package ${package.ServiceImpl}; 2 | 3 | import ${package.Entity}.${entity}; 4 | import ${package.Mapper}.${table.mapperName}; 5 | import ${package.Service}.${table.serviceName}; 6 | import ${superServiceImplClassPackage}; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | *

11 | * ${table.comment!} 服务实现类 12 | *

13 | * 14 | * @author ${author} 15 | * @since ${date} 16 | */ 17 | @Service 18 | <% if(kotlin){ %> 19 | open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} { 20 | 21 | } 22 | <% }else{ %> 23 | public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} { 24 | 25 | } 26 | <% } %> --------------------------------------------------------------------------------