├── .gitignore ├── README.md ├── excel ├── 用户.xls └── 股票涨幅信息表.xlsx ├── pom.xml ├── sql ├── stock_db.sql └── test.sql ├── stock_backend ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── lt │ │ │ └── stock │ │ │ ├── StockApplication.java │ │ │ ├── common │ │ │ ├── PageResult.java │ │ │ ├── Response.java │ │ │ └── enums │ │ │ │ ├── Number.java │ │ │ │ └── ResponseCode.java │ │ │ ├── config │ │ │ ├── CommonConfig.java │ │ │ ├── HttpClientConfig.java │ │ │ ├── RedisConfig.java │ │ │ ├── TaskExecutePoolConfig.java │ │ │ └── job │ │ │ │ ├── StockJob.java │ │ │ │ └── XxlJobConfig.java │ │ │ ├── controller │ │ │ ├── HelloController.java │ │ │ ├── StockController.java │ │ │ └── UserController.java │ │ │ ├── mapper │ │ │ ├── StockBlockRtInfoMapper.java │ │ │ ├── StockBusinessMapper.java │ │ │ ├── StockMarketIndexInfoMapper.java │ │ │ ├── StockMarketLogPriceMapper.java │ │ │ ├── StockRtInfoMapper.java │ │ │ ├── SysLogMapper.java │ │ │ ├── SysPermissionMapper.java │ │ │ ├── SysRoleMapper.java │ │ │ ├── SysRolePermissionMapper.java │ │ │ ├── SysUserMapper.java │ │ │ └── SysUserRoleMapper.java │ │ │ ├── pojo │ │ │ ├── HttpPoolConfig.java │ │ │ ├── StockInfoConfig.java │ │ │ ├── TaskThreadPoolConfig.java │ │ │ ├── dto │ │ │ │ └── LoginRequestDto.java │ │ │ ├── entity │ │ │ │ ├── StockBlockRtInfo.java │ │ │ │ ├── StockBusiness.java │ │ │ │ ├── StockMarketIndexInfo.java │ │ │ │ ├── StockMarketLogPrice.java │ │ │ │ ├── StockRtInfo.java │ │ │ │ ├── SysLog.java │ │ │ │ ├── SysPermission.java │ │ │ │ ├── SysRole.java │ │ │ │ ├── SysRolePermission.java │ │ │ │ ├── SysUser.java │ │ │ │ └── SysUserRole.java │ │ │ └── vo │ │ │ │ ├── InnerMarketResponseVo.java │ │ │ │ ├── LoginResponseVo.java │ │ │ │ ├── OuterMarketResponseVo.java │ │ │ │ ├── PermissionRespNodeVo.java │ │ │ │ ├── StockBlockResponseVo.java │ │ │ │ ├── StockDayResponseVo.java │ │ │ │ ├── StockExcelResponseVo.java │ │ │ │ ├── StockMinuteResponseVo.java │ │ │ │ ├── StockSearchResponseVo.java │ │ │ │ └── StockUpDownResponseVo.java │ │ │ ├── security │ │ │ ├── config │ │ │ │ └── SecurityConfig.java │ │ │ ├── filter │ │ │ │ ├── JwtAuthorizationFilter.java │ │ │ │ └── JwtLoginAuthenticationFilter.java │ │ │ ├── handler │ │ │ │ ├── AccessAnonymousEntryPoint.java │ │ │ │ └── StockAccessDeniedHandler.java │ │ │ └── service │ │ │ │ └── LoginUserDetailService.java │ │ │ ├── service │ │ │ ├── PermissionService.java │ │ │ ├── StockService.java │ │ │ ├── StockTimerTaskService.java │ │ │ ├── UserService.java │ │ │ └── impl │ │ │ │ ├── PermissionServiceImpl.java │ │ │ │ ├── StockServiceImpl.java │ │ │ │ ├── StockTimerTaskServiceImpl.java │ │ │ │ └── UserServiceImpl.java │ │ │ └── utils │ │ │ ├── DateTimeUtil.java │ │ │ ├── IdWorker.java │ │ │ ├── JwtTokenUtil.java │ │ │ └── ParserStockInfoUtil.java │ └── resources │ │ ├── application.yml │ │ └── mapper │ │ ├── StockBlockRtInfoMapper.xml │ │ ├── StockBusinessMapper.xml │ │ ├── StockMarketIndexInfoMapper.xml │ │ ├── StockMarketLogPriceMapper.xml │ │ ├── StockRtInfoMapper.xml │ │ ├── SysLogMapper.xml │ │ ├── SysPermissionMapper.xml │ │ ├── SysRoleMapper.xml │ │ ├── SysRolePermissionMapper.xml │ │ ├── SysUserMapper.xml │ │ └── SysUserRoleMapper.xml │ └── test │ └── java │ └── com │ └── lt │ └── stock │ ├── TestEasyExcel.java │ ├── TestJodeDate.java │ ├── TestPwd.java │ ├── TestRedis.java │ ├── TestRep.java │ ├── TestRestTemplate.java │ ├── TestStockCollection.java │ ├── ThreadPoolTest.java │ ├── config │ ├── MyStockRunnable.java │ └── StockTaskRejectedExecutionHandler.java │ ├── controller │ └── UserControllerTest.java │ ├── pojo │ └── User.java │ └── service │ └── StockTimerService.java ├── stock_front_admin ├── .babelrc ├── README.md ├── dist_back │ ├── css │ │ ├── 401.css │ │ ├── 404.css │ │ ├── font-awesome.css │ │ ├── font-awesome.min.css │ │ ├── login.css │ │ ├── main.css │ │ ├── styles.css │ │ ├── views-components-jobAdmin.css │ │ ├── views-components-menus.css │ │ ├── views-components-roles-components-edit.css │ │ ├── views-components-roles.css │ │ ├── views-components-sql.css │ │ ├── views-components-swagger.css │ │ ├── views-components-user-components-auth.css │ │ ├── views-components-user-components-edit.css │ │ └── views-components-user.css │ ├── fonts │ │ ├── 535877f5-element-icons.woff │ │ ├── 732389de-element-icons.ttf │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ ├── images │ │ ├── 0026ea27-401.gif │ │ ├── 2f24f1a4-timg.jpg │ │ ├── 9a0a216e-b1.png │ │ ├── a91de005-logo3.png │ │ └── ab6bf1bd-404.jpg │ ├── index.html │ ├── js │ │ ├── 401.js │ │ ├── 404.js │ │ ├── login.js │ │ ├── main.js │ │ ├── manifest.js │ │ ├── styles.js │ │ ├── test.js │ │ ├── views-captcha.js │ │ ├── views-components-jobAdmin.js │ │ ├── views-components-logs.js │ │ ├── views-components-menus-components-add.js │ │ ├── views-components-menus-components-edit.js │ │ ├── views-components-menus.js │ │ ├── views-components-roles-components-add.js │ │ ├── views-components-roles-components-edit.js │ │ ├── views-components-roles.js │ │ ├── views-components-sql.js │ │ ├── views-components-stock-componment-details.js │ │ ├── views-components-stock-componment-home.js │ │ ├── views-components-swagger.js │ │ ├── views-components-user-components-add.js │ │ ├── views-components-user-components-auth.js │ │ ├── views-components-user-components-edit.js │ │ └── views-components-user.js │ └── logo-0.png ├── package-lock.json ├── package.json ├── src │ ├── App.vue │ ├── api │ │ ├── excel │ │ │ └── index.js │ │ ├── index.js │ │ ├── log │ │ │ └── index.js │ │ ├── login │ │ │ └── index.js │ │ ├── menus │ │ │ └── index.js │ │ ├── personal │ │ │ └── index.js │ │ ├── roles │ │ │ └── index.js │ │ ├── stock │ │ │ ├── details.js │ │ │ ├── home.js │ │ │ └── list.js │ │ └── user │ │ │ └── index.js │ ├── assets │ │ ├── favicon.ico │ │ ├── fonts │ │ │ ├── css │ │ │ │ ├── font-awesome.css │ │ │ │ └── font-awesome.min.css │ │ │ └── fonts │ │ │ │ ├── FontAwesome.otf │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ ├── fontawesome-webfont.svg │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ ├── fontawesome-webfont.woff │ │ │ │ └── fontawesome-webfont.woff2 │ │ ├── images │ │ │ ├── 401.gif │ │ │ ├── 404.gif │ │ │ ├── 404.jpg │ │ │ ├── avatar.png │ │ │ ├── b1.png │ │ │ ├── b2.png │ │ │ ├── bg.jpg │ │ │ ├── logo-0.png │ │ │ ├── logo.png │ │ │ ├── logo1.png │ │ │ ├── logo3.png │ │ │ ├── timg.jpg │ │ │ └── touxiang.jpg │ │ ├── js │ │ │ ├── jquery.js │ │ │ └── toastr.js │ │ └── style │ │ │ ├── .gitkeep │ │ │ ├── common │ │ │ └── common.css │ │ │ ├── globalstyle.css │ │ │ └── varibles.styl │ ├── common │ │ ├── common.js │ │ └── env.js │ ├── components │ │ ├── fadeIn │ │ │ └── fadeIn.vue │ │ └── layout │ │ │ ├── index.vue │ │ │ ├── mixin │ │ │ └── ResizeHandler.js │ │ │ └── slider │ │ │ ├── Logo.vue │ │ │ └── slider.vue │ ├── config │ │ ├── index.js │ │ └── router.config.js │ ├── directives │ │ ├── index.js │ │ └── permission.js │ ├── index.html │ ├── lib │ │ └── HttpRequest.js │ ├── main.js │ ├── router │ │ ├── index.js │ │ ├── routers │ │ │ ├── index.js │ │ │ └── router_map.js │ │ └── routes.js │ ├── settings.js │ ├── store │ │ ├── actions.js │ │ ├── getters.js │ │ ├── index.js │ │ ├── module │ │ │ ├── auth.js │ │ │ └── index.js │ │ ├── mutations.js │ │ ├── state.js │ │ └── types.js │ └── views │ │ ├── captcha │ │ └── index.vue │ │ ├── components │ │ ├── jobAdmin │ │ │ └── index.vue │ │ ├── logs │ │ │ └── index.vue │ │ ├── menus │ │ │ ├── components │ │ │ │ ├── add.vue │ │ │ │ └── edit.vue │ │ │ └── index.vue │ │ ├── personal │ │ │ ├── components │ │ │ │ ├── details.vue │ │ │ │ └── edit.vue │ │ │ └── index.vue │ │ ├── roles │ │ │ ├── components │ │ │ │ ├── add.vue │ │ │ │ └── edit.vue │ │ │ └── index.vue │ │ ├── sql │ │ │ └── index.vue │ │ ├── stock │ │ │ ├── componment │ │ │ │ ├── details.vue │ │ │ │ ├── home.vue │ │ │ │ ├── list.vue │ │ │ │ └── table.vue │ │ │ └── index.vue │ │ ├── swagger │ │ │ └── index.vue │ │ └── user │ │ │ ├── components │ │ │ ├── add.vue │ │ │ ├── auth.vue │ │ │ └── edit.vue │ │ │ └── index.vue │ │ ├── error │ │ ├── 401.vue │ │ └── 404.vue │ │ └── login.vue └── webpack.config.js └── stock_xxljob_admin ├── pom.xml └── src └── main ├── java └── com │ └── lt │ └── job │ └── admin │ ├── XxlJobAdminApplication.java │ ├── controller │ ├── IndexController.java │ ├── JobApiController.java │ ├── JobCodeController.java │ ├── JobGroupController.java │ ├── JobInfoController.java │ ├── JobLogController.java │ ├── UserController.java │ ├── annotation │ │ └── PermissionLimit.java │ ├── interceptor │ │ ├── CookieInterceptor.java │ │ ├── PermissionInterceptor.java │ │ └── WebMvcConfig.java │ └── resolver │ │ └── WebExceptionResolver.java │ ├── core │ ├── alarm │ │ ├── JobAlarm.java │ │ ├── JobAlarmer.java │ │ └── impl │ │ │ └── EmailJobAlarm.java │ ├── complete │ │ └── XxlJobCompleter.java │ ├── conf │ │ └── XxlJobAdminConfig.java │ ├── cron │ │ └── CronExpression.java │ ├── exception │ │ └── XxlJobException.java │ ├── model │ │ ├── XxlJobGroup.java │ │ ├── XxlJobInfo.java │ │ ├── XxlJobLog.java │ │ ├── XxlJobLogGlue.java │ │ ├── XxlJobLogReport.java │ │ ├── XxlJobRegistry.java │ │ └── XxlJobUser.java │ ├── old │ │ ├── RemoteHttpJobBean.java │ │ ├── XxlJobDynamicScheduler.java │ │ └── XxlJobThreadPool.java │ ├── route │ │ ├── ExecutorRouteStrategyEnum.java │ │ ├── ExecutorRouter.java │ │ └── strategy │ │ │ ├── ExecutorRouteBusyover.java │ │ │ ├── ExecutorRouteConsistentHash.java │ │ │ ├── ExecutorRouteFailover.java │ │ │ ├── ExecutorRouteFirst.java │ │ │ ├── ExecutorRouteLFU.java │ │ │ ├── ExecutorRouteLRU.java │ │ │ ├── ExecutorRouteLast.java │ │ │ ├── ExecutorRouteRandom.java │ │ │ └── ExecutorRouteRound.java │ ├── scheduler │ │ ├── MisfireStrategyEnum.java │ │ ├── ScheduleTypeEnum.java │ │ └── XxlJobScheduler.java │ ├── thread │ │ ├── JobCompleteHelper.java │ │ ├── JobFailMonitorHelper.java │ │ ├── JobLogReportHelper.java │ │ ├── JobRegistryHelper.java │ │ ├── JobScheduleHelper.java │ │ └── JobTriggerPoolHelper.java │ ├── trigger │ │ ├── TriggerTypeEnum.java │ │ └── XxlJobTrigger.java │ └── util │ │ ├── CookieUtil.java │ │ ├── FtlUtil.java │ │ ├── I18nUtil.java │ │ ├── JacksonUtil.java │ │ └── LocalCacheUtil.java │ ├── dao │ ├── XxlJobGroupDao.java │ ├── XxlJobInfoDao.java │ ├── XxlJobLogDao.java │ ├── XxlJobLogGlueDao.java │ ├── XxlJobLogReportDao.java │ ├── XxlJobRegistryDao.java │ └── XxlJobUserDao.java │ └── service │ ├── LoginService.java │ ├── XxlJobService.java │ └── impl │ ├── AdminBizImpl.java │ └── XxlJobServiceImpl.java └── resources ├── application.properties ├── i18n ├── message_en.properties ├── message_zh_CN.properties └── message_zh_TC.properties ├── logback.xml ├── mybatis-mapper ├── XxlJobGroupMapper.xml ├── XxlJobInfoMapper.xml ├── XxlJobLogGlueMapper.xml ├── XxlJobLogMapper.xml ├── XxlJobLogReportMapper.xml ├── XxlJobRegistryMapper.xml └── XxlJobUserMapper.xml ├── static ├── adminlte │ ├── dist │ │ ├── css │ │ │ ├── AdminLTE.min.css │ │ │ └── skins │ │ │ │ └── _all-skins.min.css │ │ └── js │ │ │ └── adminlte.min.js │ └── plugins │ │ └── iCheck │ │ ├── icheck.min.js │ │ └── square │ │ ├── blue.css │ │ ├── blue.png │ │ └── blue@2x.png ├── favicon.ico ├── js │ ├── common.1.js │ ├── index.js │ ├── jobcode.index.1.js │ ├── jobgroup.index.1.js │ ├── jobinfo.index.1.js │ ├── joblog.detail.1.js │ ├── joblog.index.1.js │ ├── login.1.js │ └── user.index.1.js └── plugins │ ├── codemirror │ ├── addon │ │ └── hint │ │ │ ├── anyword-hint.js │ │ │ ├── show-hint.css │ │ │ └── show-hint.js │ ├── lib │ │ ├── codemirror.css │ │ └── codemirror.js │ └── mode │ │ ├── clike │ │ └── clike.js │ │ ├── javascript │ │ └── javascript.js │ │ ├── php │ │ └── php.js │ │ ├── powershell │ │ └── powershell.js │ │ ├── python │ │ └── python.js │ │ └── shell │ │ └── shell.js │ ├── cronGen │ ├── cronGen.js │ └── cronGen_en.js │ ├── echarts │ └── echarts.common.min.js │ ├── jquery │ ├── jquery.cookie.js │ └── jquery.validate.min.js │ └── layer │ ├── layer.js │ └── theme │ └── default │ ├── icon-ext.png │ ├── icon.png │ ├── layer.css │ ├── loading-0.gif │ ├── loading-1.gif │ └── loading-2.gif └── templates ├── common ├── common.exception.ftl └── common.macro.ftl ├── help.ftl ├── index.ftl ├── jobcode └── jobcode.index.ftl ├── jobgroup └── jobgroup.index.ftl ├── jobinfo └── jobinfo.index.ftl ├── joblog ├── joblog.detail.ftl └── joblog.index.ftl ├── login.ftl └── user └── user.index.ftl /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # stockIndex 2 | ### 1. 项目介绍 3 | **一个基于股票实时交易产生的数据分析产品,旨在为特定用户和机构提供定制化的股票数据分析和展示服务** 4 | 5 | **项目的核心功能以数据分析和展示为主,主要包含了沪深指数、沪深板块、沪深个股和K线的实时行情查询等功能,内容包含了国内实时指数、涨幅榜、个股涨跌、个股秒级行情、实时日K线行情等** 6 | 7 | ### 2. 技术选型 8 | **前端技术栈** 9 | | 名称 | 技术 | 场景 | 10 | | -------- | ------------------------- | ---- | 11 | | 基本骨架 | vue-cli+vue+element+axios | | 12 | | 报表 | echartsjs | | 13 | | 前端支持 | node webpack 等 | | 14 | 15 | **后端技术栈** 16 | | 名称 | 技术 | 场景 | 17 | | ------------- | ------------------------------------------------------------ | ------------ | 18 | | 基础框架 | springboot、mybatis-springboot、springMVC | 项目基础骨架 | 19 | | 安全框架 | boot-security+jwt | 认证与授权 | 20 | | 缓存 | redis | 缓存 | 21 | | excel表格导出 | easyexcel | | 22 | | 小组件 | jode-date 、gson 、guava 、httpClient \| restTemplate 、线程池 | | 23 | | 定时任务 | xxljob | | 24 | | 文档框架 | swagger | | 25 | | 分库分表 | sharding-JDBC | | 26 | | 部署 | nginx | | 27 | 28 | **整体概况** 29 | ![image](https://user-images.githubusercontent.com/82208902/211144849-5d174ede-a7a5-4ed5-b263-ccefb34476ca.png) 30 | **** 31 | ### 3. 核心业务 32 | **业务结构预览** 33 | ![image](https://user-images.githubusercontent.com/82208902/211144893-614b2a38-0eba-4b3d-b550-5c1251babe5e.png) 34 | **业务功能简介** 35 | ``` 36 | 1.定时任务调度服务 37 | XXL-JOB通过RestTemplate+多线程动态拉去股票接口数据,刷入数据库; 38 | 2.国内指数服务 39 | 3.板块指数服务 40 | 4.涨幅榜展示功能 41 | 5.涨停跌停数展示功能 42 | 6.成交量对比展示功能 43 | 7.个股涨停服务展示功能 44 | 8.个股详情展示功能 45 | 包含分时行情、日k线、周K线图等 46 | 9.个股描述服务; 47 | 10.报表导出服务 48 | ``` 49 | -------------------------------------------------------------------------------- /excel/用户.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/excel/用户.xls -------------------------------------------------------------------------------- /excel/股票涨幅信息表.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/excel/股票涨幅信息表.xlsx -------------------------------------------------------------------------------- /sql/stock_db.sql: -------------------------------------------------------------------------------- 1 | create table sys_user 2 | ( 3 | id varchar(64) not null comment '用户id' 4 | primary key, 5 | username varchar(50) not null comment '账户', 6 | password varchar(200) not null comment '用户密码密文', 7 | phone varchar(20) null comment '手机号码', 8 | real_name varchar(60) null comment '真实名称', 9 | nick_name varchar(60) null comment '昵称', 10 | email varchar(50) null comment '邮箱(唯一)', 11 | status tinyint default 1 null comment '账户状态(1.正常 2.锁定 )', 12 | sex tinyint default 1 null comment '性别(1.男 2.女)', 13 | deleted tinyint default 1 null comment '是否删除(1未删除;0已删除)', 14 | create_id varchar(64) null comment '创建人', 15 | update_id varchar(64) null comment '更新人', 16 | create_where tinyint default 1 null comment '创建来源(1.web 2.android 3.ios )', 17 | create_time datetime null comment '创建时间', 18 | update_time datetime null comment '更新时间', 19 | constraint unique_username 20 | unique (username) comment '用户名唯一' 21 | ) 22 | comment '用户表' charset = utf8mb3; 23 | 24 | create table stock_market_index_info 25 | ( 26 | id varchar(20) not null comment '主键字段(无业务意义)' 27 | primary key, 28 | mark_Id char(12) not null comment '大盘ID', 29 | cur_time datetime not null comment '当前时间', 30 | mark_name varchar(20) null comment '指数名称', 31 | cur_point decimal(18, 2) null comment '当前点数', 32 | current_price decimal(18, 2) null comment '当前价格', 33 | updown_rate decimal(18, 3) null comment '涨跌率', 34 | trade_account bigint null comment '成交量(多少手)', 35 | trade_volume bigint null comment '成交额(万元)', 36 | constraint unique_id_time 37 | unique (mark_Id, cur_time) 38 | ) 39 | comment '股票大盘数据详情表' charset = utf8mb3; 40 | 41 | create table stock_market_log_price 42 | ( 43 | id varchar(20) not null comment '主键ID' 44 | primary key, 45 | market_code char(12) not null comment '大盘编码', 46 | cur_date date not null comment '当前日期', 47 | pre_close_price decimal(10, 2) null comment '前收盘价格', 48 | open_price decimal(10, 2) null comment '开盘价格', 49 | constraint unique_mcode_date 50 | unique (market_code, cur_date) comment '大盘id与日期组成唯一索引' 51 | ) 52 | comment '股票大盘 开盘价与前收盘价流水表' collate = utf8mb4_general_ci; -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/StockApplication.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock; 2 | 3 | import com.lt.stock.pojo.HttpPoolConfig; 4 | import com.lt.stock.pojo.StockInfoConfig; 5 | import com.lt.stock.pojo.TaskThreadPoolConfig; 6 | import org.mybatis.spring.annotation.MapperScan; 7 | import org.springframework.boot.SpringApplication; 8 | import org.springframework.boot.autoconfigure.SpringBootApplication; 9 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 10 | 11 | /** 12 | * @description: 13 | * @author: ~Teng~ 14 | * @date: 2023/1/6 18:08 15 | */ 16 | @SpringBootApplication 17 | @MapperScan("com.lt.stock.mapper") 18 | @EnableConfigurationProperties({StockInfoConfig.class, TaskThreadPoolConfig.class, HttpPoolConfig.class}) 19 | public class StockApplication { 20 | public static void main(String[] args) { 21 | SpringApplication.run(StockApplication.class, args); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/common/PageResult.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.common; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | import java.util.List; 8 | 9 | /** 10 | * @description: 分页结果 11 | * @author: ~Teng~ 12 | * @date: 2023/1/7 18:38 13 | */ 14 | @Data 15 | public class PageResult implements Serializable { 16 | /** 17 | * 总记录数 18 | */ 19 | private Long totalRows; 20 | 21 | /** 22 | * 总页数 23 | */ 24 | private Integer totalPages; 25 | 26 | /** 27 | * 当前第几页 28 | */ 29 | private Integer pageNum; 30 | 31 | /** 32 | * 每页记录数 33 | */ 34 | private Integer pageSize; 35 | 36 | /** 37 | * 当前页记录数 38 | */ 39 | private Integer size; 40 | 41 | /** 42 | * 结果集 43 | */ 44 | private List rows; 45 | 46 | /** 47 | * 分页数据组装 48 | */ 49 | public PageResult(PageInfo pageInfo) { 50 | totalRows = pageInfo.getTotal(); 51 | totalPages = pageInfo.getPages(); 52 | pageNum = pageInfo.getPageNum(); 53 | pageSize = pageInfo.getPageSize(); 54 | size = pageInfo.getSize(); 55 | rows = pageInfo.getList(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/common/Response.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.common; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * @description: 返回数据类 9 | * @author: ~Teng~ 10 | * @date: 2023/1/6 18:43 11 | */ 12 | //保证序列化json的时候,如果是null的对象,key也会消失 13 | @JsonInclude(JsonInclude.Include.NON_NULL) 14 | public class Response implements Serializable { 15 | private static final long serialVersionUID = 7735505903525411467L; 16 | 17 | // 成功值 18 | private static final int SUCCESS_CODE = 1; 19 | 20 | // 失败值 21 | private static final int ERROR_CODE = 0; 22 | 23 | /** 24 | * 状态码 25 | */ 26 | private int code; 27 | 28 | /** 29 | * 消息 30 | */ 31 | private String msg; 32 | 33 | /** 34 | * 返回数据 35 | */ 36 | private T data; 37 | 38 | private Response(int code) { 39 | this.code = code; 40 | } 41 | 42 | private Response(int code, T data) { 43 | this.code = code; 44 | this.data = data; 45 | } 46 | 47 | private Response(int code, String msg) { 48 | this.code = code; 49 | this.msg = msg; 50 | } 51 | 52 | private Response(int code, String msg, T data) { 53 | this.code = code; 54 | this.msg = msg; 55 | this.data = data; 56 | } 57 | 58 | public static Response ok() { 59 | return new Response(SUCCESS_CODE, "success"); 60 | } 61 | 62 | public static Response ok(String msg) { 63 | return new Response(SUCCESS_CODE, msg); 64 | } 65 | 66 | public static Response ok(T data) { 67 | return new Response(SUCCESS_CODE, data); 68 | } 69 | 70 | public static Response ok(String msg, T data) { 71 | return new Response(SUCCESS_CODE, msg, data); 72 | } 73 | 74 | public static Response error() { 75 | return new Response(ERROR_CODE, "error"); 76 | } 77 | 78 | public static Response error(String msg) { 79 | return new Response(ERROR_CODE, msg); 80 | } 81 | 82 | public static Response error(int code, String msg) { 83 | return new Response(code, msg); 84 | } 85 | 86 | public int getCode() { 87 | return code; 88 | } 89 | 90 | public String getMsg() { 91 | return msg; 92 | } 93 | 94 | public T getData() { 95 | return data; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/common/enums/Number.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.common.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @description: 9 | * @author: ~Teng~ 10 | * @date: 2023/1/6 20:44 11 | */ 12 | @AllArgsConstructor 13 | @Getter 14 | @NoArgsConstructor 15 | public enum Number { 16 | /** 17 | * 数字 18 | */ 19 | One(1), Two(2), Three(3); 20 | 21 | int number; 22 | } 23 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/common/enums/ResponseCode.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.common.enums; 2 | 3 | /** 4 | * @description: 5 | * @author: ~Teng~ 6 | * @date: 2023/1/6 18:47 7 | */ 8 | public enum ResponseCode { 9 | /** 10 | * 状态码,消息 11 | */ 12 | ERROR(0, "操作失败"), 13 | SUCCESS(1, "操作成功"), 14 | DATA_ERROR(0, "参数异常"), 15 | NO_RESPONSE_DATA(0, "无响应数据"), 16 | NO_CHINESE_DATA(0, "只能输入相关代码"), 17 | SYSTEM_VERIFY_CODE_NOT_EMPTY(0, "验证码不能为空"), 18 | SYSTEM_VERIFY_CODE_ERROR(0, "验证码错误"), 19 | SYSTEM_VERIFY_CODE_EXPIRED(0, "验证码已过期"), 20 | SYSTEM_USERNAME_NOT_EMPTY(0, "账号不能为空"), 21 | SYSTEM_USERNAME_NOT_EXISTS(0, "账号不存在"), 22 | SYSTEM_USERNAME_EXPIRED(0, "账户过期"), 23 | SYSTEM_USERNAME_LOCKED(0, "账户被锁"), 24 | SYSTEM_USERNAME_DISABLED(0, "账户被禁用"), 25 | SYSTEM_PASSWORD_ERROR(0, "账号或密码错误"), 26 | SYSTEM_PASSWORD_EXPIRED(0, "密码过期"), 27 | SYSTEM_USERNAME_OFFLINE(0, "已下线,请重新登录"), 28 | SYSTEM_ERROR(0, "系统异常请稍后再试"), 29 | ACCOUNT_EXISTS_ERROR(0, "该账号已存在"), 30 | TOKEN_ERROR(2, "用户未登录,请先登录"), 31 | NOT_PERMISSION(3, "没有权限访问该资源"), 32 | TOKEN_NOT_NULL(-1, "token 不能为空"), 33 | TOKEN_NO_AVAIL(-1, "token无效或过期"), 34 | TOKEN_PAST_DUE(-1, "登录失效,请重新登录"), 35 | TOKEN_EXISTS(-1, "账号异地登录,你已被迫退出"), 36 | OPERATION_MENU_PERMISSION_CATALOG_ERROR(0, "操作后的菜单类型是目录,所属菜单必须为默认顶级菜单或者目录"), 37 | OPERATION_MENU_PERMISSION_MENU_ERROR(0, "操作后的菜单类型是菜单,所属菜单必须为目录类型"), 38 | OPERATION_MENU_PERMISSION_BTN_ERROR(0, "操作后的菜单类型是按钮,所属菜单必须为菜单类型"), 39 | OPERATION_MENU_PERMISSION_URL_NOT_NULL(0, "菜单权限的url不能为空"), 40 | OPERATION_MENU_PERMISSION_URL_PERMS_NULL(0, "菜单权限的标识符不能为空"), 41 | OPERATION_MENU_PERMISSION_URL_METHOD_NULL(0, "菜单权限的请求方式不能为空"), 42 | OPERATION_MENU_PERMISSION_URL_CODE_NULL(0, "菜单权限的按钮标识不能为空"), 43 | OPERATION_MENU_PERMISSION_UPDATE(0, "操作的菜单权限存在子集关联不允许变更"), 44 | ROLE_PERMISSION_RELATION(0, "该菜单权限存在子集关联,不允许删除"), 45 | OLD_PASSWORD_ERROR(0, "旧密码不匹配"); 46 | private int code; 47 | private String message; 48 | 49 | ResponseCode(int code, String message) { 50 | this.code = code; 51 | this.message = message; 52 | } 53 | 54 | public int getCode() { 55 | return this.code; 56 | } 57 | 58 | public String getMessage() { 59 | return this.message; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/config/CommonConfig.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.config; 2 | 3 | import com.lt.stock.utils.IdWorker; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 7 | import org.springframework.security.crypto.password.PasswordEncoder; 8 | 9 | /** 10 | * @description: 公共配置类 11 | * @author: ~Teng~ 12 | * @date: 2023/1/6 18:48 13 | */ 14 | @Configuration 15 | public class CommonConfig { 16 | 17 | /** 18 | * 密码加密器---BCryptPasswordEncoder方法采用SHA-256对密码进行加密 19 | */ 20 | @Bean 21 | public PasswordEncoder passwordEncoder() { 22 | return new BCryptPasswordEncoder(); 23 | } 24 | 25 | /** 26 | * 基于雪花算法生成的全局唯一id 27 | */ 28 | @Bean 29 | public IdWorker idWorker() { 30 | // 指定当前为 1 号机房的 2 号机器生成 31 | return new IdWorker(2L, 1L); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/config/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.config; 2 | 3 | import org.springframework.cache.annotation.CachingConfigurerSupport; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.data.redis.connection.RedisConnectionFactory; 6 | import org.springframework.data.redis.core.RedisTemplate; 7 | import org.springframework.data.redis.serializer.StringRedisSerializer; 8 | 9 | /** 10 | * @description: 11 | * @author: ~Teng~ 12 | * @date: 2023/2/14 20:19 13 | */ 14 | @Configuration 15 | public class RedisConfig extends CachingConfigurerSupport { 16 | // 获取RedisTemplate 需要导入Redis的连接工厂 对象 17 | public RedisTemplate getRedisTemplate(RedisConnectionFactory redisConnectionFactory) { 18 | // 获取RedisTemplate对象 19 | RedisTemplate redisTemplate = new RedisTemplate<>(); 20 | // 进行序列化设置 (默认的序列化 是jdk格式的 我们在Linux中使用的是String/hash/list/set/zset格式的) 21 | // 更改序列化设置 支持String格式 22 | redisTemplate.setKeySerializer(new StringRedisSerializer()); 23 | // 更改序列化设置 支持Hash结构 24 | redisTemplate.setHashKeySerializer(new StringRedisSerializer()); 25 | redisTemplate.setConnectionFactory(redisConnectionFactory); 26 | return redisTemplate; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/config/TaskExecutePoolConfig.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.config; 2 | 3 | import com.lt.stock.pojo.TaskThreadPoolConfig; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 8 | 9 | import java.util.concurrent.RejectedExecutionHandler; 10 | 11 | /** 12 | * @description: 配置线程池 13 | * @author: ~Teng~ 14 | * @date: 2023/1/9 23:03 15 | */ 16 | @Configuration 17 | @Slf4j 18 | public class TaskExecutePoolConfig { 19 | 20 | private TaskThreadPoolConfig taskThreadPoolConfig; 21 | 22 | public TaskExecutePoolConfig(TaskThreadPoolConfig taskThreadPoolConfig) { 23 | this.taskThreadPoolConfig = taskThreadPoolConfig; 24 | } 25 | 26 | @Bean(name = "threadPoolTaskExecutor", destroyMethod = "shutdown") 27 | public ThreadPoolTaskExecutor threadPoolTaskExecutor() { 28 | // 构建线程池对象 29 | ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); 30 | // 核心线程数:核心线程数(获取硬件):线程池创建时候初始化的线程数 31 | taskExecutor.setCorePoolSize(taskThreadPoolConfig.getCorePoolSize()); 32 | // 最大线程数:只有在缓冲队列满了之后才会申请超过核心线程数的线程 33 | taskExecutor.setMaxPoolSize(taskThreadPoolConfig.getMaxPoolSize()); 34 | // 缓冲队列:用来缓冲执行任务的队列 35 | taskExecutor.setQueueCapacity(taskThreadPoolConfig.getQueueCapacity()); 36 | // 允许线程的空闲时间:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁 37 | taskExecutor.setKeepAliveSeconds(taskThreadPoolConfig.getKeepAliveSeconds()); 38 | // 线程名称前缀 39 | taskExecutor.setThreadNamePrefix("StockThread-"); 40 | // 设置拒绝策略 41 | taskExecutor.setRejectedExecutionHandler(rejectedExecutionHandler()); 42 | // 参数初始化 43 | taskExecutor.initialize(); 44 | return taskExecutor; 45 | } 46 | 47 | /** 48 | * 自定义线程拒绝策略 49 | */ 50 | @Bean 51 | public RejectedExecutionHandler rejectedExecutionHandler() { 52 | return (runnable, executor) -> { 53 | // TODO 可自定义Runable实现类,传入参数,做到不同任务,不同处理 54 | log.info("股票任务出现异常:发送邮件"); 55 | }; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/config/job/StockJob.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.config.job; 2 | 3 | import com.lt.stock.service.StockTimerTaskService; 4 | import com.xxl.job.core.handler.annotation.XxlJob; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Component; 9 | 10 | /** 11 | * @description: 定义股票相关数据的定时任务 12 | * @author: ~Teng~ 13 | * @date: 2023/1/9 21:45 14 | */ 15 | @Component 16 | public class StockJob { 17 | private static Logger logger = LoggerFactory.getLogger(StockJob.class); 18 | 19 | @Autowired 20 | private StockTimerTaskService stockTimerTaskService; 21 | 22 | /** 23 | * 采集国内大盘数据 24 | */ 25 | @XxlJob("collectionInnerMarketInfo") 26 | public void collectionInnerMarketInfo() { 27 | stockTimerTaskService.collectInnerMarketInfo(); 28 | } 29 | 30 | /** 31 | * 采集股票数据 32 | */ 33 | @XxlJob("collectAShareInfo") 34 | public void collectAShareInfo() { 35 | stockTimerTaskService.collectAShareInfo(); 36 | } 37 | 38 | /** 39 | * 采集板块数据 40 | */ 41 | @XxlJob("collectStockSectorRtIndex") 42 | public void collectStockSectorRtIndex() { 43 | stockTimerTaskService.collectStockSectorRtIndex(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/config/job/XxlJobConfig.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.config.job; 2 | 3 | import com.xxl.job.core.executor.impl.XxlJobSpringExecutor; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | /** 11 | * @description: xxl-job config 12 | * @author: ~Teng~ 13 | * @date: 2023/1/9 21:43 14 | */ 15 | @Configuration 16 | public class XxlJobConfig { 17 | private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class); 18 | 19 | @Value("${xxl.job.admin.addresses}") 20 | private String adminAddresses; 21 | 22 | @Value("${xxl.job.accessToken}") 23 | private String accessToken; 24 | 25 | @Value("${xxl.job.executor.appname}") 26 | private String appname; 27 | 28 | @Value("${xxl.job.executor.address}") 29 | private String address; 30 | 31 | @Value("${xxl.job.executor.ip}") 32 | private String ip; 33 | 34 | @Value("${xxl.job.executor.port}") 35 | private int port; 36 | 37 | @Value("${xxl.job.executor.logpath}") 38 | private String logPath; 39 | 40 | @Value("${xxl.job.executor.logretentiondays}") 41 | private int logRetentionDays; 42 | 43 | @Bean 44 | public XxlJobSpringExecutor xxlJobExecutor() { 45 | logger.info(">>>>>>>>>>> xxl-job config init."); 46 | XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); 47 | xxlJobSpringExecutor.setAdminAddresses(adminAddresses); 48 | xxlJobSpringExecutor.setAppname(appname); 49 | xxlJobSpringExecutor.setAddress(address); 50 | xxlJobSpringExecutor.setIp(ip); 51 | xxlJobSpringExecutor.setPort(port); 52 | xxlJobSpringExecutor.setAccessToken(accessToken); 53 | xxlJobSpringExecutor.setLogPath(logPath); 54 | xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays); 55 | return xxlJobSpringExecutor; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/controller/HelloController.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.controller; 2 | 3 | import org.springframework.security.access.prepost.PreAuthorize; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import javax.annotation.security.PermitAll; 8 | 9 | @RestController 10 | public class HelloController { 11 | @PreAuthorize("hasAuthority('sys:user:list')") // .antMatchers("/hello").hasAuthority("ROLE_ADMIN") 12 | @GetMapping("/hello") 13 | public String hello() { 14 | return "Hello World!!!"; 15 | } 16 | 17 | @PreAuthorize("hasAuthority('P6')") // .antMatchers("/say").hasAuthority("P6") 18 | @GetMapping("/say") 19 | public String say() { 20 | return "say Security!"; 21 | } 22 | 23 | @PermitAll // .antMatchers("/register").permitAll() 24 | @GetMapping("/register") 25 | public String register(){ 26 | return "register security"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.controller; 2 | 3 | import com.lt.stock.common.Response; 4 | import com.lt.stock.pojo.dto.LoginRequestDto; 5 | import com.lt.stock.pojo.vo.LoginResponseVo; 6 | import com.lt.stock.service.UserService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.security.access.prepost.PreAuthorize; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | import java.util.Map; 12 | 13 | /** 14 | * @description: 15 | * @author: ~Teng~ 16 | * @date: 2023/1/6 18:10 17 | */ 18 | @RestController 19 | @RequestMapping("/api") 20 | @CrossOrigin 21 | public class UserController { 22 | @Autowired 23 | private UserService userService; 24 | 25 | /** 26 | * 用户登录 27 | */ 28 | // @PostMapping("/login") 29 | // public Response login(@RequestBody LoginRequestDto loginRequestDto) { 30 | // return userService.login(loginRequestDto); 31 | // } 32 | 33 | /** 34 | * 生成验证码 35 | * 36 | * @return map:{code: xxx, rkey: xxx} 37 | */ 38 | @GetMapping("/captcha") 39 | public Response> generateCaptcha() { 40 | return userService.generateCaptcha(); 41 | } 42 | 43 | @GetMapping("/user") 44 | @PreAuthorize("hasAuthority('sys:user:update')") 45 | public Response getUser() { 46 | return Response.ok("hello"); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/mapper/StockBusinessMapper.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.mapper; 2 | 3 | import com.lt.stock.pojo.entity.StockBusiness; 4 | import org.springframework.stereotype.Repository; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @author teng 10 | * @description 针对表【stock_business(主营业务表)】的数据库操作Mapper 11 | * @createDate 2023-01-06 18:23:05 12 | * @Entity com.lt.stock.pojo.entity.StockBusiness 13 | */ 14 | @Repository 15 | public interface StockBusinessMapper { 16 | 17 | int deleteByPrimaryKey(Long id); 18 | 19 | int insert(StockBusiness record); 20 | 21 | int insertSelective(StockBusiness record); 22 | 23 | StockBusiness selectByPrimaryKey(Long id); 24 | 25 | int updateByPrimaryKeySelective(StockBusiness record); 26 | 27 | int updateByPrimaryKey(StockBusiness record); 28 | 29 | /** 30 | * 获取所有股票的code 31 | */ 32 | List getAllStockCode(); 33 | } 34 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/mapper/StockMarketIndexInfoMapper.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.mapper; 2 | 3 | import com.lt.stock.pojo.entity.StockMarketIndexInfo; 4 | import com.lt.stock.pojo.vo.InnerMarketResponseVo; 5 | import com.lt.stock.pojo.vo.OuterMarketResponseVo; 6 | import org.apache.ibatis.annotations.Param; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import java.util.Date; 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | /** 14 | * @author teng 15 | * @description 针对表【stock_market_index_info(股票大盘数据详情表)】的数据库操作Mapper 16 | * @createDate 2023-01-06 18:23:05 17 | * @Entity com.lt.stock.pojo.entity.StockMarketIndexInfo 18 | */ 19 | @Repository 20 | public interface StockMarketIndexInfoMapper { 21 | 22 | int deleteByPrimaryKey(Long id); 23 | 24 | int insert(StockMarketIndexInfo record); 25 | 26 | int insertSelective(StockMarketIndexInfo record); 27 | 28 | StockMarketIndexInfo selectByPrimaryKey(Long id); 29 | 30 | int updateByPrimaryKeySelective(StockMarketIndexInfo record); 31 | 32 | int updateByPrimaryKey(StockMarketIndexInfo record); 33 | 34 | /** 35 | * 根据大盘 id 和时间查询大盘信息 36 | * 37 | * @param marketIds 大盘id集合 38 | * @param timePoint 时间点 39 | * @return 大盘信息 40 | */ 41 | List getMarketInfo(@Param("marketIds") List marketIds, @Param("timePoint") Date timePoint); 42 | 43 | /** 44 | * 根据时间范围和指定的大盘id统计每分钟的交易量 45 | * 46 | * @param marketIds 股票大盘的编码code集合 47 | * @param startTime 开始时间 48 | * @param endTime 结束时间 49 | */ 50 | List getStockTradeAccountCount(@Param("marketIds") List marketIds, @Param("startTime") Date startTime, @Param("endTime") Date endTime); 51 | 52 | /** 53 | * 批量插入股票大盘数据 54 | * 55 | * @param infos 股票数据 56 | */ 57 | int insertBatch(@Param("infos") List infos); 58 | 59 | /** 60 | * 外盘指数行情数据查询,根据时间和大盘点数降序排序取前4 61 | */ 62 | List getOuterMarket(@Param("marketIds") List marketIds, @Param("timePoint") Date timePoint); 63 | } 64 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/mapper/StockMarketLogPriceMapper.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.mapper; 2 | 3 | import com.lt.stock.pojo.entity.StockMarketLogPrice; 4 | import org.springframework.stereotype.Repository; 5 | 6 | /** 7 | * @author teng 8 | * @description 针对表【stock_market_log_price(股票大盘 开盘价与前收盘价流水表)】的数据库操作Mapper 9 | * @createDate 2023-01-06 18:23:05 10 | * @Entity com.lt.stock.pojo.entity.StockMarketLogPrice 11 | */ 12 | @Repository 13 | public interface StockMarketLogPriceMapper { 14 | 15 | int deleteByPrimaryKey(Long id); 16 | 17 | int insert(StockMarketLogPrice record); 18 | 19 | int insertSelective(StockMarketLogPrice record); 20 | 21 | StockMarketLogPrice selectByPrimaryKey(Long id); 22 | 23 | int updateByPrimaryKeySelective(StockMarketLogPrice record); 24 | 25 | int updateByPrimaryKey(StockMarketLogPrice record); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/mapper/StockRtInfoMapper.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.mapper; 2 | 3 | import com.lt.stock.pojo.entity.StockRtInfo; 4 | import com.lt.stock.pojo.vo.StockSearchResponseVo; 5 | import com.lt.stock.pojo.vo.StockUpDownResponseVo; 6 | import org.apache.ibatis.annotations.Param; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import java.util.Date; 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | /** 14 | * @author teng 15 | * @description 针对表【stock_rt_info(个股详情信息表)】的数据库操作Mapper 16 | * @createDate 2023-01-06 18:23:05 17 | * @Entity com.lt.stock.pojo.entity.StockRtInfo 18 | */ 19 | @Repository 20 | public interface StockRtInfoMapper { 21 | 22 | int deleteByPrimaryKey(Long id); 23 | 24 | int insert(StockRtInfo record); 25 | 26 | int insertSelective(StockRtInfo record); 27 | 28 | StockRtInfo selectByPrimaryKey(Long id); 29 | 30 | int updateByPrimaryKeySelective(StockRtInfo record); 31 | 32 | int updateByPrimaryKey(StockRtInfo record); 33 | 34 | List getStockUpDownAllLimit(@Param("curTime") Date curTime); 35 | 36 | List getStockUpDownAll(); 37 | 38 | /** 39 | * 沪深两市涨跌停分时行情数据查询,查询T日每分钟的涨跌停数据(T:当前股票交易日) 40 | * 41 | * @param startTime 开始时间 42 | * @param endTime 结束时间 43 | * @param flag 标志 1-涨停 2-跌停 44 | */ 45 | List getStockUpDownCount(@Param("startTime") Date startTime, @Param("endTime") Date endTime, @Param("flag") int flag); 46 | 47 | /** 48 | * 批量插入功能 49 | */ 50 | int insertBatch(List stockRtInfoList); 51 | 52 | /** 53 | * 根据输入的个股代码,进行模糊查询,返回证券代码和证券名称 54 | * 55 | * @param code 只接受代码模糊查询,不支持文字查询 56 | */ 57 | List getStockSearch(@Param("code") String code); 58 | } 59 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/mapper/SysLogMapper.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.mapper; 2 | 3 | import com.lt.stock.pojo.entity.SysLog; 4 | 5 | /** 6 | * @author teng 7 | * @description 针对表【sys_log(系统日志)】的数据库操作Mapper 8 | * @createDate 2023-01-06 18:23:05 9 | * @Entity com.lt.stock.pojo.entity.SysLog 10 | */ 11 | public interface SysLogMapper { 12 | 13 | int deleteByPrimaryKey(Long id); 14 | 15 | int insert(SysLog record); 16 | 17 | int insertSelective(SysLog record); 18 | 19 | SysLog selectByPrimaryKey(Long id); 20 | 21 | int updateByPrimaryKeySelective(SysLog record); 22 | 23 | int updateByPrimaryKey(SysLog record); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/mapper/SysPermissionMapper.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.mapper; 2 | 3 | import com.lt.stock.pojo.entity.SysPermission; 4 | import org.apache.ibatis.annotations.Param; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author teng 11 | * @description 针对表【sys_permission(权限表(菜单))】的数据库操作Mapper 12 | * @createDate 2023-01-06 18:23:05 13 | * @Entity com.lt.stock.pojo.entity.SysPermission 14 | */ 15 | @Repository 16 | public interface SysPermissionMapper { 17 | 18 | int deleteByPrimaryKey(Long id); 19 | 20 | int insert(SysPermission record); 21 | 22 | int insertSelective(SysPermission record); 23 | 24 | SysPermission selectByPrimaryKey(Long id); 25 | 26 | int updateByPrimaryKeySelective(SysPermission record); 27 | 28 | int updateByPrimaryKey(SysPermission record); 29 | 30 | /** 31 | * 根据用户id查询用户信息 32 | */ 33 | List getPermissionByUserId(@Param("userId") String userId); 34 | } 35 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/mapper/SysRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.mapper; 2 | 3 | import com.lt.stock.pojo.entity.SysRole; 4 | import org.apache.ibatis.annotations.Param; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author teng 11 | * @description 针对表【sys_role(角色表)】的数据库操作Mapper 12 | * @createDate 2023-01-06 18:23:05 13 | * @Entity com.lt.stock.pojo.entity.SysRole 14 | */ 15 | @Repository 16 | public interface SysRoleMapper { 17 | 18 | int deleteByPrimaryKey(Long id); 19 | 20 | int insert(SysRole record); 21 | 22 | int insertSelective(SysRole record); 23 | 24 | SysRole selectByPrimaryKey(Long id); 25 | 26 | int updateByPrimaryKeySelective(SysRole record); 27 | 28 | int updateByPrimaryKey(SysRole record); 29 | 30 | /** 31 | * 根据用户id查询角色信息 32 | */ 33 | List getRoleByUserId(@Param("userId") String userId); 34 | } 35 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/mapper/SysRolePermissionMapper.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.mapper; 2 | 3 | import com.lt.stock.pojo.entity.SysRolePermission; 4 | 5 | /** 6 | * @author teng 7 | * @description 针对表【sys_role_permission(角色权限表)】的数据库操作Mapper 8 | * @createDate 2023-01-06 18:23:05 9 | * @Entity com.lt.stock.pojo.entity.SysRolePermission 10 | */ 11 | public interface SysRolePermissionMapper { 12 | 13 | int deleteByPrimaryKey(Long id); 14 | 15 | int insert(SysRolePermission record); 16 | 17 | int insertSelective(SysRolePermission record); 18 | 19 | SysRolePermission selectByPrimaryKey(Long id); 20 | 21 | int updateByPrimaryKeySelective(SysRolePermission record); 22 | 23 | int updateByPrimaryKey(SysRolePermission record); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/mapper/SysUserMapper.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.mapper; 2 | 3 | import com.lt.stock.pojo.entity.SysUser; 4 | import org.apache.ibatis.annotations.Param; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * @author teng 9 | * @description 针对表【sys_user(用户表)】的数据库操作Mapper 10 | * @createDate 2023-01-06 18:23:05 11 | * @Entity com.lt.stock.pojo.entity.SysUser 12 | */ 13 | @Repository 14 | public interface SysUserMapper { 15 | 16 | int deleteByPrimaryKey(Long id); 17 | 18 | int insert(SysUser record); 19 | 20 | int insertSelective(SysUser record); 21 | 22 | SysUser selectByPrimaryKey(Long id); 23 | 24 | int updateByPrimaryKeySelective(SysUser record); 25 | 26 | int updateByPrimaryKey(SysUser record); 27 | 28 | /** 29 | * 根据用户名查询用户信息 30 | */ 31 | SysUser findByUserName(@Param("username") String username); 32 | } 33 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/mapper/SysUserRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.mapper; 2 | 3 | import com.lt.stock.pojo.entity.SysUserRole; 4 | 5 | /** 6 | * @author teng 7 | * @description 针对表【sys_user_role(用户角色表)】的数据库操作Mapper 8 | * @createDate 2023-01-06 18:23:05 9 | * @Entity com.lt.stock.pojo.entity.SysUserRole 10 | */ 11 | public interface SysUserRoleMapper { 12 | 13 | int deleteByPrimaryKey(Long id); 14 | 15 | int insert(SysUserRole record); 16 | 17 | int insertSelective(SysUserRole record); 18 | 19 | SysUserRole selectByPrimaryKey(Long id); 20 | 21 | int updateByPrimaryKeySelective(SysUserRole record); 22 | 23 | int updateByPrimaryKey(SysUserRole record); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/HttpPoolConfig.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | /** 7 | * @description: http连接池常规参数的配置实体类 8 | * @author: ~Teng~ 9 | * @date: 2023/1/11 18:14 10 | */ 11 | @Data 12 | @ConfigurationProperties(prefix = "http.pool") 13 | public class HttpPoolConfig { 14 | /** 15 | * 最大连接数 16 | */ 17 | private Integer maxConnectionTotal; 18 | 19 | /** 20 | * 指定服务每次能并行接收的请求数量 21 | */ 22 | private Integer routeMaxCount; 23 | 24 | /** 25 | * 空闲连接超时时间超时后小于连接会被回收 26 | */ 27 | private Integer connectionIdleTimeOut; 28 | 29 | /** 30 | * 请求失败重试次数 31 | */ 32 | private Integer retryCount; 33 | 34 | /** 35 | * 连接超时时间 36 | */ 37 | private Integer connectionTimeOut; 38 | 39 | /** 40 | * 读取数据超时时间 41 | */ 42 | private Integer readTimeOut; 43 | 44 | /** 45 | * 连接池不够用时,等待超时时间 46 | */ 47 | private Integer connectionRequestTimeOut; 48 | } 49 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/StockInfoConfig.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @description: 10 | * @author: ~Teng~ 11 | * @date: 2023/1/7 12:51 12 | */ 13 | @ConfigurationProperties(prefix = "stock") 14 | @Data 15 | public class StockInfoConfig { 16 | /** 17 | * A股大盘ID集合 18 | */ 19 | private List inner; 20 | 21 | /** 22 | * 外盘ID集合 23 | */ 24 | private List outer; 25 | 26 | /** 27 | * 股票区间 28 | */ 29 | private List upDownRange; 30 | 31 | /** 32 | * 大盘参数获取url 33 | */ 34 | private String marketUrl; 35 | 36 | /** 37 | * 板块参数获取url 38 | */ 39 | private String blockUrl; 40 | } 41 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/TaskThreadPoolConfig.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | /** 7 | * @description: 8 | * @author: ~Teng~ 9 | * @date: 2023/1/9 23:00 10 | */ 11 | @ConfigurationProperties(prefix = "task.pool") 12 | @Data 13 | public class TaskThreadPoolConfig { 14 | private Integer corePoolSize; 15 | private Integer maxPoolSize; 16 | private Integer keepAliveSeconds; 17 | private Integer queueCapacity; 18 | } 19 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/dto/LoginRequestDto.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.dto; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @description: 登录请求 DTO 7 | * @author: ~Teng~ 8 | * @date: 2023/1/6 18:41 9 | */ 10 | @Data 11 | public class LoginRequestDto { 12 | /** 13 | * 用户名 14 | */ 15 | private String username; 16 | 17 | /** 18 | * 密码 19 | */ 20 | private String password; 21 | 22 | /** 23 | * 保存redis随机码的key 24 | */ 25 | private String rkey; 26 | 27 | /** 28 | * 验证码 29 | */ 30 | private String code; 31 | } 32 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/entity/StockBlockRtInfo.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.entity; 2 | 3 | import java.io.Serializable; 4 | import java.math.BigDecimal; 5 | import java.util.Date; 6 | 7 | import lombok.AllArgsConstructor; 8 | import lombok.Builder; 9 | import lombok.Data; 10 | import lombok.NoArgsConstructor; 11 | 12 | /** 13 | * 股票板块详情信息表 14 | * 15 | * @author teng 16 | * @TableName stock_block_rt_info 17 | */ 18 | @Data 19 | @AllArgsConstructor 20 | @NoArgsConstructor 21 | @Builder 22 | public class StockBlockRtInfo implements Serializable { 23 | /** 24 | * 板块主键ID(业务无关) 25 | */ 26 | private String id; 27 | 28 | /** 29 | * 表示,如:new_blhy-玻璃行业 30 | */ 31 | private String label; 32 | 33 | /** 34 | * 板块名称 35 | */ 36 | private String blockName; 37 | 38 | /** 39 | * 公司数量 40 | */ 41 | private Integer companyNum; 42 | 43 | /** 44 | * 平均价格 45 | */ 46 | private BigDecimal avgPrice; 47 | 48 | /** 49 | * 涨跌幅 50 | */ 51 | private BigDecimal updownRate; 52 | 53 | /** 54 | * 交易量 55 | */ 56 | private Long tradeAmount; 57 | 58 | /** 59 | * 交易金额 60 | */ 61 | private BigDecimal tradeVolume; 62 | 63 | /** 64 | * 当前日期(精确到秒) 65 | */ 66 | private Date curTime; 67 | 68 | private static final long serialVersionUID = 1L; 69 | } -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/entity/StockBusiness.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.entity; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | import lombok.Data; 6 | 7 | /** 8 | * 主营业务表 9 | * @TableName stock_business 10 | */ 11 | @Data 12 | public class StockBusiness implements Serializable { 13 | /** 14 | * 股票编码 15 | */ 16 | private String secCode; 17 | 18 | /** 19 | * 股票名称 20 | */ 21 | private String secName; 22 | 23 | /** 24 | * 行业板块代码 25 | */ 26 | private String sectorCode; 27 | 28 | /** 29 | * 行业板块名称 30 | */ 31 | private String sectorName; 32 | 33 | /** 34 | * 主营业务 35 | */ 36 | private String business; 37 | 38 | /** 39 | * 更新时间 40 | */ 41 | private Date updateTime; 42 | 43 | private static final long serialVersionUID = 1L; 44 | } -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/entity/StockMarketIndexInfo.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.entity; 2 | 3 | import java.io.Serializable; 4 | import java.math.BigDecimal; 5 | import java.util.Date; 6 | 7 | import lombok.AllArgsConstructor; 8 | import lombok.Builder; 9 | import lombok.Data; 10 | import lombok.NoArgsConstructor; 11 | 12 | /** 13 | * 股票大盘数据详情表 14 | * 15 | * @author teng 16 | * @TableName stock_market_index_info 17 | */ 18 | @Data 19 | @AllArgsConstructor 20 | @NoArgsConstructor 21 | @Builder 22 | public class StockMarketIndexInfo implements Serializable { 23 | /** 24 | * 主键字段(无业务意义) 25 | */ 26 | private String id; 27 | 28 | /** 29 | * 大盘ID 30 | */ 31 | private String markId; 32 | 33 | /** 34 | * 当前时间 35 | */ 36 | private Date curTime; 37 | 38 | /** 39 | * 指数名称 40 | */ 41 | private String markName; 42 | 43 | /** 44 | * 当前点数 45 | */ 46 | private BigDecimal curPoint; 47 | 48 | /** 49 | * 当前价格 50 | */ 51 | private BigDecimal currentPrice; 52 | 53 | /** 54 | * 涨跌率 55 | */ 56 | private BigDecimal updownRate; 57 | 58 | /** 59 | * 成交量(多少手) 60 | */ 61 | private Long tradeAccount; 62 | 63 | /** 64 | * 成交额(万元) 65 | */ 66 | private Long tradeVolume; 67 | 68 | private static final long serialVersionUID = 1L; 69 | } -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/entity/StockMarketLogPrice.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.entity; 2 | 3 | import java.io.Serializable; 4 | import java.math.BigDecimal; 5 | import java.util.Date; 6 | 7 | import lombok.Data; 8 | 9 | /** 10 | * 股票大盘 开盘价与前收盘价流水表 11 | * 12 | * @author teng 13 | * @TableName stock_market_log_price 14 | */ 15 | @Data 16 | public class StockMarketLogPrice implements Serializable { 17 | /** 18 | * 主键ID 19 | */ 20 | private String id; 21 | 22 | /** 23 | * 大盘编码 24 | */ 25 | private String marketCode; 26 | 27 | /** 28 | * 当前日期 29 | */ 30 | private Date curDate; 31 | 32 | /** 33 | * 前收盘价格 34 | */ 35 | private BigDecimal preClosePrice; 36 | 37 | /** 38 | * 开盘价格 39 | */ 40 | private BigDecimal openPrice; 41 | 42 | private static final long serialVersionUID = 1L; 43 | } -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/entity/StockRtInfo.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.entity; 2 | 3 | import java.io.Serializable; 4 | import java.math.BigDecimal; 5 | import java.util.Date; 6 | 7 | import lombok.AllArgsConstructor; 8 | import lombok.Builder; 9 | import lombok.Data; 10 | import lombok.NoArgsConstructor; 11 | 12 | /** 13 | * 个股详情信息表 14 | * 15 | * @author teng 16 | * @TableName stock_rt_info 17 | */ 18 | @Data 19 | @AllArgsConstructor 20 | @NoArgsConstructor 21 | @Builder 22 | public class StockRtInfo implements Serializable { 23 | /** 24 | * 主键字段(无业务意义) 25 | */ 26 | private String id; 27 | 28 | /** 29 | * 股票代码 30 | */ 31 | private String stockCode; 32 | 33 | /** 34 | * 当前时间 35 | */ 36 | private Date curTime; 37 | 38 | /** 39 | * 股票名称 40 | */ 41 | private String stockName; 42 | 43 | /** 44 | * 开盘价 45 | */ 46 | private BigDecimal openPrice; 47 | 48 | /** 49 | * 前收盘价| 昨日收盘价 50 | */ 51 | private BigDecimal preClosePrice; 52 | 53 | /** 54 | * 当前价格 55 | */ 56 | private BigDecimal curPrice; 57 | 58 | /** 59 | * 今日最高价 60 | */ 61 | private BigDecimal maxPrice; 62 | 63 | /** 64 | * 今日最低价 65 | */ 66 | private BigDecimal minPrice; 67 | 68 | /** 69 | * 成交量 70 | */ 71 | private Long tradeAmount; 72 | 73 | /** 74 | * 成交总金额(单位元) 75 | */ 76 | private BigDecimal tradeVolume; 77 | 78 | private static final long serialVersionUID = 1L; 79 | } -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/entity/SysLog.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.entity; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | import lombok.Data; 6 | 7 | /** 8 | * 系统日志 9 | * @TableName sys_log 10 | */ 11 | @Data 12 | public class SysLog implements Serializable { 13 | /** 14 | * 主键 15 | */ 16 | private String id; 17 | 18 | /** 19 | * 用户id 20 | */ 21 | private String userId; 22 | 23 | /** 24 | * 用户名 25 | */ 26 | private String username; 27 | 28 | /** 29 | * 用户操作 30 | */ 31 | private String operation; 32 | 33 | /** 34 | * 响应时间 35 | */ 36 | private Integer time; 37 | 38 | /** 39 | * 请求方法 40 | */ 41 | private String method; 42 | 43 | /** 44 | * 请求参数 45 | */ 46 | private String params; 47 | 48 | /** 49 | * IP地址 50 | */ 51 | private String ip; 52 | 53 | /** 54 | * 创建时间 55 | */ 56 | private Date createTime; 57 | 58 | private static final long serialVersionUID = 1L; 59 | } -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/entity/SysPermission.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.entity; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | import lombok.Data; 6 | 7 | /** 8 | * 权限表(菜单) 9 | * @TableName sys_permission 10 | */ 11 | @Data 12 | public class SysPermission implements Serializable { 13 | /** 14 | * 主键 15 | */ 16 | private String id; 17 | 18 | /** 19 | * 菜单权限编码(前端按钮权限标识) 20 | */ 21 | private String code; 22 | 23 | /** 24 | * 菜单权限名称 25 | */ 26 | private String title; 27 | 28 | /** 29 | * 菜单图标(侧边导航栏图标) 30 | */ 31 | private String icon; 32 | 33 | /** 34 | * 授权(如:sys:user:add) 35 | */ 36 | private String perms; 37 | 38 | /** 39 | * 访问地址URL 40 | */ 41 | private String url; 42 | 43 | /** 44 | * 资源请求类型 45 | */ 46 | private String method; 47 | 48 | /** 49 | * name与前端vue路由name约定一致 50 | */ 51 | private String name; 52 | 53 | /** 54 | * 父级菜单权限id 55 | */ 56 | private String pid; 57 | 58 | /** 59 | * 排序 60 | */ 61 | private Integer orderNum; 62 | 63 | /** 64 | * 菜单权限类型(1:目录;2:菜单;3:按钮) 65 | */ 66 | private Integer type; 67 | 68 | /** 69 | * 状态1:正常 0:禁用 70 | */ 71 | private Integer status; 72 | 73 | /** 74 | * 创建时间 75 | */ 76 | private Date createTime; 77 | 78 | /** 79 | * 更新时间 80 | */ 81 | private Date updateTime; 82 | 83 | /** 84 | * 是否删除(1未删除;0已删除) 85 | */ 86 | private Integer deleted; 87 | 88 | private static final long serialVersionUID = 1L; 89 | } -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/entity/SysRole.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.entity; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | import lombok.Data; 6 | 7 | /** 8 | * 角色表 9 | * @TableName sys_role 10 | */ 11 | @Data 12 | public class SysRole implements Serializable { 13 | /** 14 | * 主键 15 | */ 16 | private String id; 17 | 18 | /** 19 | * 角色名称 20 | */ 21 | private String name; 22 | 23 | /** 24 | * 描述 25 | */ 26 | private String description; 27 | 28 | /** 29 | * 状态(1:正常0:弃用) 30 | */ 31 | private Integer status; 32 | 33 | /** 34 | * 创建时间 35 | */ 36 | private Date createTime; 37 | 38 | /** 39 | * 更新时间 40 | */ 41 | private Date updateTime; 42 | 43 | /** 44 | * 是否删除(1未删除;0已删除) 45 | */ 46 | private Integer deleted; 47 | 48 | private static final long serialVersionUID = 1L; 49 | } -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/entity/SysRolePermission.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.entity; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | import lombok.Data; 6 | 7 | /** 8 | * 角色权限表 9 | * @TableName sys_role_permission 10 | */ 11 | @Data 12 | public class SysRolePermission implements Serializable { 13 | /** 14 | * 主键 15 | */ 16 | private String id; 17 | 18 | /** 19 | * 角色id 20 | */ 21 | private String roleId; 22 | 23 | /** 24 | * 菜单权限id 25 | */ 26 | private String permissionId; 27 | 28 | /** 29 | * 创建时间 30 | */ 31 | private Date createTime; 32 | 33 | private static final long serialVersionUID = 1L; 34 | } -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/entity/SysUserRole.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.entity; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | import lombok.Data; 6 | 7 | /** 8 | * 用户角色表 9 | * @TableName sys_user_role 10 | */ 11 | @Data 12 | public class SysUserRole implements Serializable { 13 | /** 14 | * 主键 15 | */ 16 | private String id; 17 | 18 | /** 19 | * 用户id 20 | */ 21 | private String userId; 22 | 23 | /** 24 | * 角色id 25 | */ 26 | private String roleId; 27 | 28 | /** 29 | * 创建时间 30 | */ 31 | private Date createTime; 32 | 33 | private static final long serialVersionUID = 1L; 34 | } -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/vo/InnerMarketResponseVo.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.math.BigDecimal; 6 | 7 | /** 8 | * @description: 国内大盘指数数据的Vo 9 | * @author: ~Teng~ 10 | * @date: 2023/1/7 12:48 11 | */ 12 | @Data 13 | public class InnerMarketResponseVo { 14 | /** 15 | * 交易量 16 | */ 17 | private Long tradeAmt; 18 | 19 | /** 20 | * 前收盘价格 21 | */ 22 | private BigDecimal preClosePrice; 23 | 24 | /** 25 | * 大盘编码 26 | */ 27 | private String code; 28 | 29 | /** 30 | * 大盘名称 31 | */ 32 | private String name; 33 | 34 | /** 35 | * 当前日期 36 | */ 37 | private String curDate; 38 | 39 | /** 40 | * 开盘价 41 | */ 42 | private BigDecimal openPrice; 43 | 44 | /** 45 | * 交易金额 46 | */ 47 | private Long tradeVol; 48 | 49 | /** 50 | * 涨幅 51 | */ 52 | private BigDecimal upDown; 53 | 54 | /** 55 | * 当前价格 56 | */ 57 | private BigDecimal tradePrice; 58 | } 59 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/vo/LoginResponseVo.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * @description: 登录后响应前端的vo 12 | * @author: ~Teng~ 13 | * @date: 2023/1/6 18:42 14 | */ 15 | @Data 16 | @Builder 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | public class LoginResponseVo { 20 | /** 21 | * 用户ID 22 | */ 23 | private String id; 24 | 25 | /** 26 | * 电话 27 | */ 28 | private String phone; 29 | 30 | /** 31 | * 用户名 32 | */ 33 | private String username; 34 | 35 | /** 36 | * 昵称 37 | */ 38 | private String nickName; 39 | 40 | /** 41 | * 组装的是用户拥有的权限对应的前端的侧边菜单栏(不包含按钮)实现动态加载 42 | */ 43 | private List menus; 44 | 45 | /** 46 | * 前端按钮权限表示 47 | */ 48 | private List permissions; 49 | 50 | /** 51 | * 认证成功后响应的 jwt token 52 | */ 53 | private String accessToken; 54 | } 55 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/vo/OuterMarketResponseVo.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.math.BigDecimal; 8 | 9 | /** 10 | * @description: 外盘指数实体 11 | * @author: ~Teng~ 12 | * @date: 2023/1/11 18:35 13 | */ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | public class OuterMarketResponseVo { 18 | /** 19 | * 大盘名称 20 | */ 21 | private String name; 22 | 23 | /** 24 | * 当前日期 25 | */ 26 | private String curTime; 27 | 28 | /** 29 | * 涨幅 30 | */ 31 | private BigDecimal updownRate; 32 | 33 | /** 34 | * 当前价格 35 | */ 36 | private BigDecimal tradePrice; 37 | 38 | /** 39 | * 当前大盘点 40 | */ 41 | private BigDecimal curPoint; 42 | } 43 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/vo/PermissionRespNodeVo.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @description: 9 | * @author: ~Teng~ 10 | * @date: 2023/2/14 19:20 11 | */ 12 | @Data 13 | public class PermissionRespNodeVo { 14 | /** 15 | * 主键 16 | */ 17 | private String id; 18 | 19 | /** 20 | * 菜单权限名称 21 | */ 22 | private String title; 23 | 24 | /** 25 | * 菜单图标(侧边导航栏图标) 26 | */ 27 | private String icon; 28 | 29 | /** 30 | * 访问地址URL 31 | */ 32 | private String path; 33 | 34 | /** 35 | * name与前端vue路由name约定一致 36 | */ 37 | private String name; 38 | 39 | /** 40 | * 菜单数据结构 41 | */ 42 | private List children; 43 | } 44 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/vo/StockBlockResponseVo.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.math.BigDecimal; 6 | 7 | /** 8 | * @description: 股票板块返回数据 9 | * @author: ~Teng~ 10 | * @date: 2023/1/7 16:58 11 | */ 12 | @Data 13 | public class StockBlockResponseVo { 14 | /** 15 | * 表示如:new_blhy-玻璃行业 16 | */ 17 | private String code; 18 | 19 | /** 20 | * 板块名称 21 | */ 22 | private String name; 23 | 24 | /** 25 | * 公司数量 26 | */ 27 | private Integer companyNum; 28 | 29 | /** 30 | * 平均价格 31 | */ 32 | private BigDecimal avgPrice; 33 | 34 | /** 35 | * 涨跌幅 36 | */ 37 | private BigDecimal updownRate; 38 | 39 | /** 40 | * 交易量 41 | */ 42 | private Long tradeAmt; 43 | 44 | /** 45 | * 交易金额 46 | */ 47 | private BigDecimal tradeVol; 48 | 49 | /** 50 | * 当前日期(精确到秒) 51 | */ 52 | private String curDate; 53 | } 54 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/vo/StockDayResponseVo.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.math.BigDecimal; 8 | 9 | /** 10 | * @description: 个股日K数据封装 11 | * @author: ~Teng~ 12 | * @date: 2023/1/8 21:31 13 | */ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | public class StockDayResponseVo { 18 | /** 19 | * 日期,eg:202201280809 20 | */ 21 | private String date; 22 | 23 | /** 24 | * 交易量 25 | */ 26 | private Long tradeAmt; 27 | 28 | /** 29 | * 股票编码 30 | */ 31 | private String code; 32 | 33 | /** 34 | * 最低价 35 | */ 36 | private BigDecimal lowPrice; 37 | 38 | /** 39 | * 股票名称 40 | */ 41 | private String name; 42 | 43 | /** 44 | * 最高价 45 | */ 46 | private BigDecimal highPrice; 47 | 48 | /** 49 | * 开盘价 50 | */ 51 | private BigDecimal openPrice; 52 | 53 | /** 54 | * 当前交易总金额 55 | */ 56 | private BigDecimal tradeVol; 57 | 58 | /** 59 | * 当前收盘价格指收盘时的价格,如果当天未收盘,则显示最新cur_price) 60 | */ 61 | private BigDecimal closePrice; 62 | 63 | /** 64 | * 前收盘价 65 | */ 66 | private BigDecimal preClosePrice; 67 | } 68 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/vo/StockExcelResponseVo.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.vo; 2 | 3 | import com.alibaba.excel.annotation.ExcelProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.math.BigDecimal; 9 | 10 | /** 11 | * @description: 导出股票信息的实体类对象 12 | * @author: ~Teng~ 13 | * @date: 2023/1/7 19:14 14 | */ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class StockExcelResponseVo { 19 | @ExcelProperty(value = {"股票涨幅信息统计表", "股票编码"}, index = 0) 20 | private String code; 21 | 22 | @ExcelProperty(value = {"股票涨幅信息统计表", "股票名称"}, index = 1) 23 | private String name; 24 | 25 | @ExcelProperty(value = {"股票涨幅信息统计表", "前收盘价格"}, index = 2) 26 | private BigDecimal preClosePrice; 27 | 28 | @ExcelProperty(value = {"股票涨幅信息统计表", "当前价格"}, index = 3) 29 | private BigDecimal tradePrice; 30 | 31 | @ExcelProperty(value = {"股票涨幅信息统计表", "涨跌"}, index = 4) 32 | private BigDecimal increase; 33 | 34 | @ExcelProperty(value = {"股票涨幅信息统计表", "涨幅"}, index = 5) 35 | private BigDecimal upDown; 36 | 37 | @ExcelProperty(value = {"股票涨幅信息统计表", "振幅"}, index = 6) 38 | private BigDecimal amplitude; 39 | 40 | @ExcelProperty(value = {"股票涨幅信息统计表", "交易总量"}, index = 7) 41 | private BigDecimal tradeAmt; 42 | 43 | @ExcelProperty(value = {"股票涨幅信息统计表", "交易总金额"}, index = 8) 44 | private BigDecimal tradeVol; 45 | 46 | @ExcelProperty(value = {"股票涨幅信息统计表", "日期"}, index = 9) 47 | private String curDate; 48 | } 49 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/vo/StockMinuteResponseVo.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.math.BigDecimal; 8 | 9 | /** 10 | * @description: 个股分时数据封装 11 | * @author: ~Teng~ 12 | * @date: 2023/1/8 21:05 13 | */ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | public class StockMinuteResponseVo { 18 | /** 19 | * 日期,eg:202201280809 20 | */ 21 | private String date; 22 | /** 23 | * 交易量 24 | */ 25 | private Long tradeAmt; 26 | /** 27 | * 股票编码 28 | */ 29 | private String code; 30 | /** 31 | * 最低价 32 | */ 33 | private BigDecimal lowPrice; 34 | /** 35 | * 前收盘价 36 | */ 37 | private BigDecimal preClosePrice; 38 | /** 39 | * 股票名称 40 | */ 41 | private String name; 42 | /** 43 | * 最高价 44 | */ 45 | private BigDecimal highPrice; 46 | /** 47 | * 开盘价 48 | */ 49 | private BigDecimal openPrice; 50 | 51 | /** 52 | * 当前交易总金额 53 | */ 54 | private BigDecimal tradeVol; 55 | /** 56 | * 当前价格 57 | */ 58 | private BigDecimal tradePrice; 59 | } 60 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/vo/StockSearchResponseVo.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.vo; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @description: 股票搜索实体类 7 | * @author: ~Teng~ 8 | * @date: 2023/1/11 18:57 9 | */ 10 | @Data 11 | public class StockSearchResponseVo { 12 | 13 | private String code; 14 | 15 | private String name; 16 | } 17 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/pojo/vo/StockUpDownResponseVo.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.math.BigDecimal; 6 | 7 | /** 8 | * @description: 股票涨跌信息 9 | * @author: ~Teng~ 10 | * @date: 2023/1/7 18:11 11 | */ 12 | @Data 13 | public class StockUpDownResponseVo { 14 | /** 15 | * 交易量 16 | */ 17 | private Long tradeAmt; 18 | /** 19 | * 前收盘价 20 | */ 21 | private BigDecimal preClosePrice; 22 | /** 23 | * 振幅 24 | */ 25 | private BigDecimal amplitude; 26 | /** 27 | * 股票编码 28 | */ 29 | private String code; 30 | /** 31 | * 名称 32 | */ 33 | private String name; 34 | /** 35 | * 日期 36 | */ 37 | private String curDate; 38 | /** 39 | * 交易金额 40 | */ 41 | private BigDecimal tradeVol; 42 | /** 43 | * 张涨跌 44 | */ 45 | private BigDecimal increase; 46 | 47 | /** 48 | * 涨幅 49 | */ 50 | private BigDecimal upDown; 51 | /** 52 | * 当前价格 53 | */ 54 | private BigDecimal tradePrice; 55 | } 56 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/security/handler/AccessAnonymousEntryPoint.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.security.handler; 2 | 3 | import com.google.gson.Gson; 4 | import com.lt.stock.common.Response; 5 | import com.lt.stock.common.enums.ResponseCode; 6 | import org.springframework.http.MediaType; 7 | import org.springframework.security.core.AuthenticationException; 8 | import org.springframework.security.web.AuthenticationEntryPoint; 9 | 10 | import javax.servlet.ServletException; 11 | import javax.servlet.http.HttpServletRequest; 12 | import javax.servlet.http.HttpServletResponse; 13 | import java.io.IOException; 14 | 15 | /** 16 | * @description: 匿名用户(即未登录时访问资源为匿名访问)无权限处理器 17 | * @author: ~Teng~ 18 | * @date: 2023/2/14 18:53 19 | */ 20 | public class AccessAnonymousEntryPoint implements AuthenticationEntryPoint { 21 | /** 22 | * 当用户请求了一个受保护的资源,但是用户没有通过认证,那么抛出异常, 23 | * AuthenticationEntryPoint. Commence(..)就会被调用。 24 | */ 25 | @Override 26 | public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { 27 | //设置响应数据格式 28 | response.setContentType(MediaType.APPLICATION_JSON_VALUE); 29 | //构建结果 30 | Response result = Response.error(ResponseCode.NOT_PERMISSION.getCode(), ResponseCode.NOT_PERMISSION.getMessage()); 31 | //将对象序列化为json字符串响应前台 32 | response.getWriter().write(new Gson().toJson(result)); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/security/handler/StockAccessDeniedHandler.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.security.handler; 2 | 3 | import com.google.gson.Gson; 4 | import com.lt.stock.common.Response; 5 | import com.lt.stock.common.enums.ResponseCode; 6 | import org.springframework.http.MediaType; 7 | import org.springframework.security.access.AccessDeniedException; 8 | import org.springframework.security.web.access.AccessDeniedHandler; 9 | 10 | import javax.servlet.ServletException; 11 | import javax.servlet.http.HttpServletRequest; 12 | import javax.servlet.http.HttpServletResponse; 13 | import java.io.IOException; 14 | 15 | /** 16 | * @description: 认证用户无权限访问资源时处理器 17 | * @author: ~Teng~ 18 | * @date: 2023/2/14 18:52 19 | */ 20 | public class StockAccessDeniedHandler implements AccessDeniedHandler { 21 | @Override 22 | public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { 23 | //设置响应数据格式 24 | response.setContentType(MediaType.APPLICATION_JSON_VALUE); 25 | //构建结果 26 | Response result = Response.error(ResponseCode.NOT_PERMISSION.getCode(), ResponseCode.NOT_PERMISSION.getMessage()); 27 | //将对象序列化为json字符串响应前台 28 | response.getWriter().write(new Gson().toJson(result)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/service/PermissionService.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.service; 2 | 3 | import com.lt.stock.pojo.entity.SysPermission; 4 | import com.lt.stock.pojo.vo.PermissionRespNodeVo; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @description: 10 | * @author: ~Teng~ 11 | * @date: 2023/2/14 18:46 12 | */ 13 | public interface PermissionService { 14 | List getTree(List permissionList, String pid, boolean isOnlyMenuType); 15 | } 16 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/service/StockTimerTaskService.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.service; 2 | 3 | /** 4 | * @description: 定义采集股票数据的定时任务的服务接口 5 | * @author: ~Teng~ 6 | * @date: 2023/1/9 16:42 7 | */ 8 | public interface StockTimerTaskService { 9 | 10 | /** 11 | * 定义采集国内大盘的实时数据信息 12 | */ 13 | void collectInnerMarketInfo(); 14 | 15 | /** 16 | * 采集股票数据 17 | */ 18 | void collectAShareInfo(); 19 | 20 | /** 21 | * 采集板块数据 22 | */ 23 | void collectStockSectorRtIndex(); 24 | } 25 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.service; 2 | 3 | import com.lt.stock.common.Response; 4 | import com.lt.stock.pojo.dto.LoginRequestDto; 5 | import com.lt.stock.pojo.vo.LoginResponseVo; 6 | 7 | import java.util.Map; 8 | 9 | /** 10 | * @description: 11 | * @author: ~Teng~ 12 | * @date: 2023/1/6 19:11 13 | */ 14 | public interface UserService { 15 | Response login(LoginRequestDto loginRequestDto); 16 | 17 | Response> generateCaptcha(); 18 | } 19 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/service/impl/PermissionServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.service.impl; 2 | 3 | import com.google.common.collect.Lists; 4 | import com.lt.stock.pojo.entity.SysPermission; 5 | import com.lt.stock.pojo.vo.PermissionRespNodeVo; 6 | import com.lt.stock.service.PermissionService; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.util.CollectionUtils; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | /** 14 | * @description: 15 | * @author: ~Teng~ 16 | * @date: 2023/2/14 18:46 17 | */ 18 | @Service 19 | public class PermissionServiceImpl implements PermissionService { 20 | @Override 21 | public List getTree(List permissions, String pid, boolean isOnlyMenuType) { 22 | ArrayList list = Lists.newArrayList(); 23 | if (CollectionUtils.isEmpty(permissions)) { 24 | return list; 25 | } 26 | for (SysPermission permission : permissions) { 27 | if (permission.getPid().equals(pid)) { 28 | if (permission.getType().intValue() != 3 || !isOnlyMenuType) { 29 | PermissionRespNodeVo permissionRespNodeVo = new PermissionRespNodeVo(); 30 | permissionRespNodeVo.setId(permission.getId()); 31 | permissionRespNodeVo.setTitle(permission.getTitle()); 32 | permissionRespNodeVo.setIcon(permission.getIcon()); 33 | permissionRespNodeVo.setPath(permission.getUrl()); 34 | permissionRespNodeVo.setName(permission.getName()); 35 | permissionRespNodeVo.setChildren(getTree(permissions, permission.getId(), isOnlyMenuType)); 36 | list.add(permissionRespNodeVo); 37 | } 38 | } 39 | } 40 | return list; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /stock_backend/src/main/java/com/lt/stock/utils/JwtTokenUtil.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.utils; 2 | 3 | import io.jsonwebtoken.*; 4 | 5 | import java.util.Date; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | /** 10 | * @description: 11 | * @author: ~Teng~ 12 | * @date: 2023/2/14 17:04 13 | */ 14 | public class JwtTokenUtil { 15 | /** 16 | * Token 请求头 17 | */ 18 | public static final String TOKEN_HEADER = "authorization"; 19 | 20 | /** 21 | * Token 前缀 22 | */ 23 | public static final String TOKEN_PREFIX = "Bearer "; 24 | 25 | /** 26 | * 签名主题 27 | */ 28 | public static final String SUBJECT = "SYSTEM"; 29 | 30 | /** 31 | * 过期时间 默认1天 32 | */ 33 | public static final long EXPIRATION = 1000 * 60 * 60 * 24L; 34 | 35 | /** 36 | * 应用密钥 37 | */ 38 | public static final String APP_SECRET_KEY = "muziteng"; 39 | 40 | /** 41 | * 生成 token 42 | */ 43 | public static String createToken(String username, String role) { 44 | Map map = new HashMap<>(2); 45 | map.put("username", username); 46 | map.put("role", role); 47 | return Jwts.builder() 48 | .setSubject(SUBJECT) 49 | .addClaims(map) 50 | .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION)) 51 | .setIssuedAt(new Date()) 52 | .signWith(SignatureAlgorithm.HS256, APP_SECRET_KEY) 53 | .compact(); 54 | } 55 | 56 | /** 57 | * 校验 token 58 | */ 59 | public static Claims checkJWT(String token) { 60 | try { 61 | Claims claims = Jwts.parser().setSigningKey(APP_SECRET_KEY).parseClaimsJws(token).getBody(); 62 | return claims; 63 | } catch (Exception e) { 64 | e.printStackTrace(); 65 | return null; 66 | } 67 | } 68 | 69 | /** 70 | * 从 token 中获取用户名 71 | */ 72 | public static String getUsername(String token) { 73 | return checkJWT(token).get("username").toString(); 74 | } 75 | 76 | /** 77 | * 校验Token是否过期 78 | */ 79 | public static String getUserRole(String token) { 80 | return checkJWT(token).get("role").toString(); 81 | } 82 | 83 | /** 84 | * 校验Token是否过期 85 | */ 86 | public static boolean isExpiration(String token) { 87 | return checkJWT(token).getExpiration().before(new Date()); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /stock_backend/src/test/java/com/lt/stock/TestEasyExcel.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock; 2 | 3 | import com.alibaba.excel.EasyExcel; 4 | import com.alibaba.excel.context.AnalysisContext; 5 | import com.alibaba.excel.event.AnalysisEventListener; 6 | import com.lt.stock.pojo.User; 7 | import org.junit.jupiter.api.Test; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Date; 11 | import java.util.List; 12 | 13 | /** 14 | * @description: 15 | * @author: ~Teng~ 16 | * @date: 2023/1/7 19:00 17 | */ 18 | public class TestEasyExcel { 19 | public List init() { 20 | //组装数据 21 | ArrayList users = new ArrayList<>(); 22 | for (int i = 0; i < 10; i++) { 23 | User user = new User(); 24 | user.setAddress("上海" + i); 25 | user.setUserName("张三" + i); 26 | user.setBirthday(new Date()); 27 | user.setAge(10 + i); 28 | users.add(user); 29 | } 30 | return users; 31 | } 32 | 33 | @Test 34 | public void testWriteExcel() { 35 | List users = init(); 36 | EasyExcel.write("D:\\MyCode\\JavaProjects\\web\\todayIndex\\stock_parent\\excel\\用户.xls", User.class).sheet("用户信息").doWrite(users); 37 | } 38 | 39 | @Test 40 | public void testReadExcel() { 41 | ArrayList users = new ArrayList<>(); 42 | EasyExcel.read("D:\\MyCode\\JavaProjects\\web\\todayIndex\\stock_parent\\excel\\用户.xls", User.class, new AnalysisEventListener() { 43 | @Override 44 | public void invoke(User user, AnalysisContext analysisContext) { 45 | System.out.println(user); 46 | users.add(user); 47 | } 48 | 49 | @Override 50 | public void doAfterAllAnalysed(AnalysisContext analysisContext) { 51 | System.out.println("完成。。。。"); 52 | } 53 | }).sheet().doRead(); 54 | System.out.println(users); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /stock_backend/src/test/java/com/lt/stock/TestJodeDate.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock; 2 | 3 | import com.lt.stock.utils.DateTimeUtil; 4 | import org.joda.time.DateTime; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.util.Date; 8 | 9 | /** 10 | * @description: 11 | * @author: ~Teng~ 12 | * @date: 2023/1/7 12:19 13 | */ 14 | public class TestJodeDate { 15 | 16 | @Test 17 | public void testJode() { 18 | Date date = DateTime.now().toDate(); 19 | // Sat Jan 07 12:20:27 CST 2023 20 | System.out.println(date); 21 | DateTime dateTime = DateTime.now().withDate(2023, 1, 9); 22 | // 2023-01-09 12:22:11 23 | System.out.println(dateTime.toString("yyyy-MM-dd HH:mm:ss")); 24 | dateTime = DateTime.now().withDate(2023, 1, 9).withHourOfDay(12).withMinuteOfHour(0).withSecondOfMinute(0).withMillisOfSecond(0); 25 | // 2023-01-09 12:00:00 26 | System.out.println(dateTime.toString("yyyy-MM-dd HH:mm:ss")); 27 | String lastDateString4Stock = DateTimeUtil.getLastDateString4Stock(DateTime.now()); 28 | System.out.println(lastDateString4Stock); 29 | } 30 | 31 | @Test 32 | public void testApi() { 33 | // 获取jode下的当前时间 34 | DateTime now = DateTime.now(); 35 | // 日期后退指定的时间 36 | DateTime plusDays = now.plusDays(1); 37 | // 2023-01-08T12:25:53.584+08:00 38 | System.out.println(plusDays); 39 | // 前推指定的时间 40 | DateTime minusDays = now.minusDays(7); 41 | // 2022-12-31T12:25:53.584+08:00 42 | System.out.println(minusDays); 43 | // 随意指定日期 44 | DateTime dateTime = now.withMonthOfYear(8); 45 | // 2023-08-07T12:25:53.584+08:00 46 | System.out.println(dateTime); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /stock_backend/src/test/java/com/lt/stock/TestPwd.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.security.crypto.password.PasswordEncoder; 7 | 8 | /** 9 | * @description: 10 | * @author: ~Teng~ 11 | * @date: 2023/1/6 19:06 12 | */ 13 | @SpringBootTest 14 | public class TestPwd { 15 | 16 | @Autowired 17 | private PasswordEncoder passwordEncoder; 18 | 19 | @Test 20 | public void testPwd() { 21 | String pwd = "1234"; 22 | String encode = passwordEncoder.encode(pwd); 23 | // $2a$10$W864RVedOz/eRc7U2KQozOSK3m9fgnwaYnnC/Cj0QEaYq.qDgs/nO 24 | System.out.println(encode); 25 | boolean flag = passwordEncoder.matches(pwd, "$2a$10$W864RVedOz/eRc7U2KQozOSK3m9fgnwaYnnC/Cj0QEaYq.qDgs/nO"); 26 | System.out.println(flag); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /stock_backend/src/test/java/com/lt/stock/TestRedis.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.data.redis.core.StringRedisTemplate; 7 | 8 | /** 9 | * @description: 10 | * @author: ~Teng~ 11 | * @date: 2023/1/7 10:15 12 | */ 13 | @SpringBootTest 14 | public class TestRedis { 15 | 16 | @Autowired 17 | private StringRedisTemplate stringRedisTemplate; 18 | 19 | @Test 20 | public void test1() { 21 | stringRedisTemplate.opsForValue().set("myname", "zhangsan"); 22 | String myname = stringRedisTemplate.opsForValue().get("myname"); 23 | System.out.println(myname); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /stock_backend/src/test/java/com/lt/stock/TestRep.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.regex.Matcher; 6 | import java.util.regex.Pattern; 7 | 8 | /** 9 | * @description: 10 | * @author: ~Teng~ 11 | * @date: 2023/1/9 16:17 12 | */ 13 | public class TestRep { 14 | 15 | @Test 16 | public void testRep1() { 17 | // 按指定模式在字符串查找 18 | String line = "This order was placed for QT3000! OK?"; 19 | String regex = "(\\D*)(\\d+)(.*)"; 20 | // 创建 Pattern 对象 21 | Pattern p = Pattern.compile(regex); 22 | // 创建 matcher 对象 23 | Matcher matcher = p.matcher(line); 24 | if (matcher.find()) { 25 | System.out.println("Found value: " + matcher.group(0)); 26 | System.out.println("Found value: " + matcher.group(1)); 27 | System.out.println("Found value: " + matcher.group(2)); 28 | System.out.println("Found value: " + matcher.group(3)); 29 | } else { 30 | System.out.println("NO MATCH"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /stock_backend/src/test/java/com/lt/stock/TestStockCollection.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock; 2 | 3 | import com.lt.stock.service.StockTimerTaskService; 4 | import org.junit.jupiter.api.Test; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | 8 | /** 9 | * @description: 10 | * @author: ~Teng~ 11 | * @date: 2023/1/9 16:51 12 | */ 13 | @SpringBootTest 14 | public class TestStockCollection { 15 | 16 | @Autowired 17 | private StockTimerTaskService stockTimerTaskService; 18 | 19 | @Test 20 | public void testCollectionInner() { 21 | stockTimerTaskService.collectInnerMarketInfo(); 22 | } 23 | 24 | @Test 25 | public void testCollectAShareInfo() { 26 | stockTimerTaskService.collectAShareInfo(); 27 | } 28 | 29 | @Test 30 | public void testCollectStockSectorRtIndex() { 31 | stockTimerTaskService.collectStockSectorRtIndex(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /stock_backend/src/test/java/com/lt/stock/config/MyStockRunnable.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.config; 2 | 3 | import com.lt.stock.service.StockTimerService; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | * @description: 自定义线程任务对象 9 | * @author: ~Teng~ 10 | * @date: 2023/1/11 17:49 11 | */ 12 | public class MyStockRunnable implements Runnable { 13 | 14 | /** 15 | * 携带的任务信息,任务拒绝时,使用 16 | */ 17 | private Map infos; 18 | 19 | private StockTimerService stockTimerService; 20 | 21 | public MyStockRunnable(Map infos, StockTimerService stockTimerService) { 22 | this.infos = infos; 23 | this.stockTimerService = stockTimerService; 24 | } 25 | 26 | @Override 27 | public void run() { 28 | stockTimerService.stockRtInto(); 29 | } 30 | 31 | public Map getInfos() { 32 | return infos; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /stock_backend/src/test/java/com/lt/stock/config/StockTaskRejectedExecutionHandler.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.config; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | 5 | import java.util.Map; 6 | import java.util.concurrent.RejectedExecutionHandler; 7 | import java.util.concurrent.ThreadPoolExecutor; 8 | 9 | /** 10 | * @description: 自定义拒绝策略 11 | * @author: ~Teng~ 12 | * @date: 2023/1/11 17:48 13 | */ 14 | 15 | @Slf4j 16 | public class StockTaskRejectedExecutionHandler implements RejectedExecutionHandler { 17 | /** 18 | * 具体执行拒绝策略的方法 19 | * 20 | * @param r 当前封装的任务对象 21 | * @param executor 线程池对象 22 | */ 23 | @Override 24 | public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { 25 | if (r instanceof MyStockRunnable) { 26 | MyStockRunnable r2 = ((MyStockRunnable) r); 27 | Map infos = r2.getInfos(); 28 | log.info("出现的异常的任务信息:{}", infos); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /stock_backend/src/test/java/com/lt/stock/controller/UserControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.controller; 2 | 3 | 4 | /** 5 | * @description: 6 | * @author: ~Teng~ 7 | * @date: 2023/1/6 18:11 8 | */ 9 | public class UserControllerTest { 10 | 11 | } -------------------------------------------------------------------------------- /stock_backend/src/test/java/com/lt/stock/pojo/User.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.pojo; 2 | 3 | import com.alibaba.excel.annotation.ExcelIgnore; 4 | import com.alibaba.excel.annotation.ExcelProperty; 5 | import com.alibaba.excel.annotation.format.DateTimeFormat; 6 | import com.alibaba.excel.annotation.write.style.ColumnWidth; 7 | import com.alibaba.excel.annotation.write.style.ContentRowHeight; 8 | import com.alibaba.excel.annotation.write.style.HeadRowHeight; 9 | import lombok.AllArgsConstructor; 10 | import lombok.Data; 11 | import lombok.NoArgsConstructor; 12 | 13 | import java.io.Serializable; 14 | import java.util.Date; 15 | 16 | /** 17 | * @description: 18 | * @author: ~Teng~ 19 | * @date: 2023/1/7 19:00 20 | */ 21 | @Data 22 | @AllArgsConstructor 23 | @NoArgsConstructor 24 | @HeadRowHeight(value = 35) // 表头行高 25 | @ContentRowHeight(value = 25) // 内容行高 26 | @ColumnWidth(value = 50) // 列宽 27 | public class User implements Serializable { 28 | @ExcelProperty(value = {"用户基本信息", "用户名"}, index = 1) 29 | // @ExcelIgnore 30 | private String userName; 31 | @ExcelProperty(value = {"用户基本信息", "年龄"}, index = 2) 32 | private Integer age; 33 | @ExcelProperty(value = {"用户基本信息", "地址"}, index = 4) 34 | private String address; 35 | 36 | /** 37 | * 注意:日期格式注解由alibaba.excel提供 38 | */ 39 | @ExcelProperty(value = {"用户基本信息", "生日"}, index = 3) 40 | @DateTimeFormat("yyyy/MM/dd HH:mm") 41 | private Date birthday; 42 | } 43 | -------------------------------------------------------------------------------- /stock_backend/src/test/java/com/lt/stock/service/StockTimerService.java: -------------------------------------------------------------------------------- 1 | package com.lt.stock.service; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.stereotype.Service; 5 | 6 | import java.util.concurrent.TimeUnit; 7 | 8 | /** 9 | * @description: 10 | * @author: ~Teng~ 11 | * @date: 2023/1/11 17:46 12 | */ 13 | @Service 14 | @Slf4j 15 | public class StockTimerService { 16 | /** 17 | * 拉取股票服务 18 | */ 19 | public void stockRtInto() { 20 | // 模拟网络I/O 1000毫秒 21 | try { 22 | TimeUnit.MILLISECONDS.sleep(1000); 23 | } catch (InterruptedException e) { 24 | e.printStackTrace(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /stock_front_admin/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["env", "stage-0"], 3 | "plugins": ["transform-runtime","transform-vue-jsx"] 4 | } -------------------------------------------------------------------------------- /stock_front_admin/README.md: -------------------------------------------------------------------------------- 1 | ## 1.目录结构 2 | 目录 3 | ``` 4 | │──dist 5 | │──src 6 | │ │──api 接口请求目录 7 | │ │──assets 静态资源目录 8 | │ │──common 公共目录(如:公共函数,可直接修改,不影响打包后的文件) 9 | │ │──components 组件目录 10 | │ │──config 配置目录 11 | │ │──lib 核心库目录 12 | │ │──router 路由目录 13 | │ │──store vuex目录 14 | │ │──views 视图目录 15 | │ │──App.vue 根组件 16 | │ │──index.html 模板文件 17 | │ │──main.js 入口文件 18 | │ └──settings.js 配置文件 19 | │ ... 20 | ``` 21 | 22 | ## 2.Build 23 | ``` 24 | # install dependency 25 | npm install 26 | 27 | # test development dev 28 | npm run dev 29 | 30 | # build 31 | npm run build 32 | 33 | # build test 34 | npm run build:test 35 | 36 | # watch 37 | npm run watch 38 | ``` 39 | 常见打包错误: 40 | 运行 npm run build,报错: 41 | Module build failed (from ./node_modules/image-webpack-loader/index.js) 42 | 解决方案: 43 | 44 | ~~~js 45 | 先卸载 46 | npm uninstall image-webpack-loader 47 | 然后使用 48 | cnpm install image-webpack-loader --save-dev 49 | ~~~ 50 | -------------------------------------------------------------------------------- /stock_front_admin/dist_back/css/401.css: -------------------------------------------------------------------------------- 1 | .notAuth[data-v-1d0f0583]{padding-top:5%;padding-bottom:8%;background:#fff}.notAuth>h1[data-v-1d0f0583]{padding:32px;font-size:32px;text-align:center} -------------------------------------------------------------------------------- /stock_front_admin/dist_back/css/404.css: -------------------------------------------------------------------------------- 1 | .error-page[data-v-1206f264]{padding-top:10%;padding-bottom:10%;width:100%;height:100%;display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex;overflow:hidden;-webkit-box-pack:center;-webkit-justify-content:center;-moz-box-pack:center;-ms-flex-pack:center;justify-content:center}.error-page>.pic-404[data-v-1206f264]{width:30%;padding-top:50px;padding-bottom:50px}.error-page img.pic-404__parent[data-v-1206f264]{width:100%;height:100%}.error-page .notFound[data-v-1206f264]{padding:150px 0;overflow:hidden}.error-page .notFound span[data-v-1206f264]{display:block;line-height:60px;font-size:18px;color:#8b7b8b}.error-page .notFound span .link[data-v-1206f264]{color:#5cacee;font-size:20px;cursor:pointer} -------------------------------------------------------------------------------- /stock_front_admin/dist_back/css/login.css: -------------------------------------------------------------------------------- 1 | .login[data-v-0609c202]{position:relative;width:100%;height:100%;overflow:hidden;text-align:center;background:url(/images/9a0a216e-b1.png) 50% fixed no-repeat;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover}.mask[data-v-0609c202]{display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-webkit-justify-content:center;-moz-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-webkit-align-items:center;-moz-box-align:center;-ms-flex-align:center;align-items:center;width:100%;height:100%}.login-container[data-v-0609c202]{overflow:hidden;position:relative;width:430px;max-width:100%;padding-bottom:16px;margin:0 auto;background:#fff;-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px;-webkit-box-shadow:0 0 6px #cac6c6;-moz-box-shadow:0 0 6px #cac6c6;box-shadow:0 0 6px #cac6c6}.login-container .title[data-v-0609c202]{margin-top:32px;font-size:26px;color:#666}.login-container .login-form[data-v-0609c202]{width:60%;margin:0 auto;padding-bottom:10px} -------------------------------------------------------------------------------- /stock_front_admin/dist_back/css/views-components-jobAdmin.css: -------------------------------------------------------------------------------- 1 | .sql[data-v-10aa1fd6]{position:relative;margin-left:-10px;margin-right:-10px;padding-top:25%;padding-bottom:25%;width:100%;font-size:12px;overflow:hidden}#iframe[data-v-10aa1fd6]{position:absolute;left:0;right:0;top:0;bottom:0;width:100%;height:100%;background:#fff;overflow-y:hidden} -------------------------------------------------------------------------------- /stock_front_admin/dist_back/css/views-components-menus.css: -------------------------------------------------------------------------------- 1 | .menu .fa-icon[data-v-1aa9f8ea]{vertical-align:middle;margin-right:5px;width:24px;text-align:center;font-size:18px} -------------------------------------------------------------------------------- /stock_front_admin/dist_back/css/views-components-roles-components-edit.css: -------------------------------------------------------------------------------- 1 | .custom-tree-node[data-v-ab4695ec]{-webkit-box-flex:1;-webkit-flex:1;-moz-box-flex:1;-ms-flex:1;flex:1;font-size:14px;padding-right:8px} -------------------------------------------------------------------------------- /stock_front_admin/dist_back/css/views-components-roles.css: -------------------------------------------------------------------------------- 1 | .custom-tree-node[data-v-ab4695ec]{-webkit-box-flex:1;-webkit-flex:1;-moz-box-flex:1;-ms-flex:1;flex:1;font-size:14px;padding-right:8px} -------------------------------------------------------------------------------- /stock_front_admin/dist_back/css/views-components-sql.css: -------------------------------------------------------------------------------- 1 | .sql[data-v-758b1676]{position:relative;margin-left:-10px;margin-right:-10px;padding-top:25%;padding-bottom:25%;width:100%;font-size:12px;overflow:hidden}#iframe[data-v-758b1676]{position:absolute;left:0;right:0;top:0;bottom:0;width:100%;height:100%;background:#fff;overflow-y:hidden} -------------------------------------------------------------------------------- /stock_front_admin/dist_back/css/views-components-swagger.css: -------------------------------------------------------------------------------- 1 | .swagger[data-v-659693d3]{position:relative;margin-left:-10px;margin-right:-10px;padding-top:25%;padding-bottom:25%;width:100%;font-size:12px;overflow:hidden}#iframe[data-v-659693d3]{position:absolute;left:0;right:0;top:0;bottom:0;width:100%;height:100%;background:#fff;overflow-y:hidden} -------------------------------------------------------------------------------- /stock_front_admin/dist_back/css/views-components-user-components-auth.css: -------------------------------------------------------------------------------- 1 | .user-auth[data-v-37965faa]{overflow:hidden}.user-auth .transfer[data-v-37965faa]{display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-webkit-justify-content:center;-moz-box-pack:center;-ms-flex-pack:center;justify-content:center}.user-auth .footer[data-v-37965faa]{text-align:center;padding-top:20px} -------------------------------------------------------------------------------- /stock_front_admin/dist_back/css/views-components-user-components-edit.css: -------------------------------------------------------------------------------- 1 | .custom-tree-node[data-v-93e89ed8]{-webkit-box-flex:1;-webkit-flex:1;-moz-box-flex:1;-ms-flex:1;flex:1;font-size:14px;padding-right:8px} -------------------------------------------------------------------------------- /stock_front_admin/dist_back/css/views-components-user.css: -------------------------------------------------------------------------------- 1 | .custom-tree-node[data-v-93e89ed8]{-webkit-box-flex:1;-webkit-flex:1;-moz-box-flex:1;-ms-flex:1;flex:1;font-size:14px;padding-right:8px}.user-auth[data-v-37965faa]{overflow:hidden}.user-auth .transfer[data-v-37965faa]{display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-webkit-justify-content:center;-moz-box-pack:center;-ms-flex-pack:center;justify-content:center}.user-auth .footer[data-v-37965faa]{text-align:center;padding-top:20px} -------------------------------------------------------------------------------- /stock_front_admin/dist_back/fonts/535877f5-element-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/dist_back/fonts/535877f5-element-icons.woff -------------------------------------------------------------------------------- /stock_front_admin/dist_back/fonts/732389de-element-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/dist_back/fonts/732389de-element-icons.ttf -------------------------------------------------------------------------------- /stock_front_admin/dist_back/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/dist_back/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /stock_front_admin/dist_back/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/dist_back/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /stock_front_admin/dist_back/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/dist_back/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /stock_front_admin/dist_back/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/dist_back/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /stock_front_admin/dist_back/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/dist_back/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /stock_front_admin/dist_back/images/0026ea27-401.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/dist_back/images/0026ea27-401.gif -------------------------------------------------------------------------------- /stock_front_admin/dist_back/images/2f24f1a4-timg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/dist_back/images/2f24f1a4-timg.jpg -------------------------------------------------------------------------------- /stock_front_admin/dist_back/images/9a0a216e-b1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/dist_back/images/9a0a216e-b1.png -------------------------------------------------------------------------------- /stock_front_admin/dist_back/images/a91de005-logo3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/dist_back/images/a91de005-logo3.png -------------------------------------------------------------------------------- /stock_front_admin/dist_back/images/ab6bf1bd-404.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/dist_back/images/ab6bf1bd-404.jpg -------------------------------------------------------------------------------- /stock_front_admin/dist_back/index.html: -------------------------------------------------------------------------------- 1 | 股票大屏展示系统
-------------------------------------------------------------------------------- /stock_front_admin/dist_back/js/401.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[2],{"/DX3":function(t,n,e){},"2ja0":function(t,n,e){"use strict";e.r(n);var i=e("3M85"),r=e.n(i);for(var u in i)"default"!==u&&function(t){e.d(n,t,function(){return i[t]})}(u);n.default=r.a},"3M85":function(t,n,e){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default={name:"NotAuth"}},"7FXn":function(t,n,e){"use strict";e.r(n);var i=e("Nz4G"),r=e("2ja0");for(var u in r)"default"!==u&&function(t){e.d(n,t,function(){return r[t]})}(u);e("Y9d3");var a=e("KHd+"),s=Object(a.a)(r.default,i.a,i.b,!1,null,"1d0f0583",null);n.default=s.exports},Nz4G:function(t,n,e){"use strict";var i=function(){var t=this.$createElement;this._self._c;return this._m(0)},r=[function(){var t=this.$createElement,n=this._self._c||t;return n("div",{staticClass:"notAuth"},[n("h1",[this._v("401,抱歉,你没有权限访问")]),this._v(" "),n("div",{staticClass:"img",attrs:{align:"center"}},[n("img",{attrs:{src:e("OXsn"),alt:""}})])])}];e.d(n,"a",function(){return i}),e.d(n,"b",function(){return r})},OXsn:function(t,n,e){t.exports=e.p+"images/0026ea27-401.gif"},Y9d3:function(t,n,e){"use strict";var i=e("/DX3");e.n(i).a}}]); -------------------------------------------------------------------------------- /stock_front_admin/dist_back/js/404.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[3],{J1RP:function(t,n,e){"use strict";e.r(n);var r=e("Q1R/"),a=e("nTvW");for(var i in a)"default"!==i&&function(t){e.d(n,t,function(){return a[t]})}(i);e("qtZT");var u=e("KHd+"),s=Object(u.a)(a.default,r.a,r.b,!1,null,"1206f264",null);n.default=s.exports},LmDw:function(t,n,e){t.exports=e.p+"images/ab6bf1bd-404.jpg"},"Q1R/":function(t,n,e){"use strict";var r=function(){var t=this,n=t.$createElement,e=t._self._c||n;return e("div",{staticClass:"error-page"},[t._m(0),t._v(" "),e("div",{staticClass:"notFound"},[e("span",[t._v("啊哦~~~你访问的页面不存在哦")]),t._v(" "),e("span",[t._v("你可以尝试"),e("a",{staticClass:"link",on:{click:function(n){return t.$router.go(-1)}}},[t._v("返回上一页")])])])])},a=[function(){var t=this.$createElement,n=this._self._c||t;return n("div",{staticClass:"pic-404"},[n("img",{staticClass:"pic-404__parent",attrs:{src:e("LmDw"),alt:""}})])}];e.d(n,"a",function(){return r}),e.d(n,"b",function(){return a})},QfSq:function(t,n,e){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default={name:"Notfound",data:function(){return{}}}},"V6+e":function(t,n,e){},nTvW:function(t,n,e){"use strict";e.r(n);var r=e("QfSq"),a=e.n(r);for(var i in r)"default"!==i&&function(t){e.d(n,t,function(){return r[t]})}(i);n.default=a.a},qtZT:function(t,n,e){"use strict";var r=e("V6+e");e.n(r).a}}]); -------------------------------------------------------------------------------- /stock_front_admin/dist_back/js/styles.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[0],{"9d8Q":function(n,o,i){},D66Q:function(n,o,i){},FLGV:function(n,o,i){},fGVW:function(n,o,i){},pdi6:function(n,o,i){}}]); -------------------------------------------------------------------------------- /stock_front_admin/dist_back/js/views-components-jobAdmin.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[6],{"/aDp":function(n,t,r){"use strict";var u=r("GQP8");r.n(u).a},"4WuE":function(n,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var u=r("Kqrf");t.default={name:"xxjobAdmin",data:function(){return{url:u.xxjobAdminUrl+"/heima-job-admin/"}}}},GQP8:function(n,t,r){},hxJu:function(n,t,r){"use strict";r.r(t);var u=r("4WuE"),a=r.n(u);for(var e in u)"default"!==e&&function(n){r.d(t,n,function(){return u[n]})}(e);t.default=a.a},"k+SM":function(n,t,r){"use strict";r.r(t);var u=r("yiVZ"),a=r("hxJu");for(var e in a)"default"!==e&&function(n){r.d(t,n,function(){return a[n]})}(e);r("/aDp");var i=r("KHd+"),f=Object(i.a)(a.default,u.a,u.b,!1,null,"10aa1fd6",null);t.default=f.exports},yiVZ:function(n,t,r){"use strict";var u=function(){var n=this.$createElement,t=this._self._c||n;return t("div",{staticClass:"sql"},[t("iframe",{attrs:{id:"iframe",src:this.url,scrolling:"auto",frameborder:"0"}})])},a=[];r.d(t,"a",function(){return u}),r.d(t,"b",function(){return a})}}]); -------------------------------------------------------------------------------- /stock_front_admin/dist_back/js/views-components-sql.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[10],{"+RKR":function(t,n,r){"use strict";var u=function(){var t=this.$createElement,n=this._self._c||t;return n("div",{staticClass:"sql"},[n("iframe",{attrs:{id:"iframe",src:this.url,scrolling:"auto",frameborder:"0"}})])},e=[];r.d(n,"a",function(){return u}),r.d(n,"b",function(){return e})},XeAk:function(t,n,r){"use strict";var u=r("uoY7");r.n(u).a},iGmq:function(t,n,r){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var u=r("Kqrf");n.default={name:"component-sql",data:function(){return{url:u.ip+"/druid/sql.html"}}}},luJO:function(t,n,r){"use strict";r.r(n);var u=r("+RKR"),e=r("wtTZ");for(var i in e)"default"!==i&&function(t){r.d(n,t,function(){return e[t]})}(i);r("XeAk");var a=r("KHd+"),o=Object(a.a)(e.default,u.a,u.b,!1,null,"758b1676",null);n.default=o.exports},uoY7:function(t,n,r){},wtTZ:function(t,n,r){"use strict";r.r(n);var u=r("iGmq"),e=r.n(u);for(var i in u)"default"!==i&&function(t){r.d(n,t,function(){return u[t]})}(i);n.default=e.a}}]); -------------------------------------------------------------------------------- /stock_front_admin/dist_back/js/views-components-swagger.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[13],{"E+nl":function(t,n,r){"use strict";r.r(n);var e=r("ugY+"),u=r("Ndb7");for(var a in u)"default"!==a&&function(t){r.d(n,t,function(){return u[t]})}(a);r("zRK/");var i=r("KHd+"),c=Object(i.a)(u.default,e.a,e.b,!1,null,"659693d3",null);n.default=c.exports},Ndb7:function(t,n,r){"use strict";r.r(n);var e=r("OS6h"),u=r.n(e);for(var a in e)"default"!==a&&function(t){r.d(n,t,function(){return e[t]})}(a);n.default=u.a},OS6h:function(t,n,r){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var e=r("Kqrf");n.default={name:"component-swagger",data:function(){return{url:e.ip+"/swagger-ui.html"}}}},rcXl:function(t,n,r){},"ugY+":function(t,n,r){"use strict";var e=function(){var t=this.$createElement,n=this._self._c||t;return n("div",{staticClass:"swagger"},[n("iframe",{attrs:{id:"iframe",src:this.url,scrolling:"auto",frameborder:"0"}})])},u=[];r.d(n,"a",function(){return e}),r.d(n,"b",function(){return u})},"zRK/":function(t,n,r){"use strict";var e=r("rcXl");r.n(e).a}}]); -------------------------------------------------------------------------------- /stock_front_admin/dist_back/logo-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/dist_back/logo-0.png -------------------------------------------------------------------------------- /stock_front_admin/src/App.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /stock_front_admin/src/api/excel/index.js: -------------------------------------------------------------------------------- 1 | // import http from '../../request/http.js'; 2 | import axios from '@/api'; 3 | 4 | //个股描述 5 | export function exportStockExcel(params) { 6 | return axios.request({ 7 | url: '/quot/stock/export', 8 | method: 'get', 9 | params, 10 | responseType: 'blob'//表名返回数据库类型 11 | }); 12 | } -------------------------------------------------------------------------------- /stock_front_admin/src/api/index.js: -------------------------------------------------------------------------------- 1 | import HttpRequest from '@/lib/HttpRequest.js' 2 | const axios = new HttpRequest(); 3 | export default axios -------------------------------------------------------------------------------- /stock_front_admin/src/api/log/index.js: -------------------------------------------------------------------------------- 1 | import axios from '@/api' 2 | 3 | /******************* 列表 *******************/ 4 | export const getTableData = (data) => { 5 | return axios.request({ 6 | url:'/logs', 7 | method:'post', 8 | data:data 9 | }); 10 | }; 11 | 12 | /******************* 删除 *******************/ 13 | export const del = (data) => { 14 | return axios.request({ 15 | url:'/log', 16 | method:'delete', 17 | data:data 18 | }); 19 | }; -------------------------------------------------------------------------------- /stock_front_admin/src/api/login/index.js: -------------------------------------------------------------------------------- 1 | import axios from '@/api' 2 | 3 | /******************* 登陆 *******************/ 4 | export const login = (data) => { 5 | // debugger; 6 | return axios.request({ 7 | url:'/login', 8 | method:'post', 9 | data:data 10 | }); 11 | }; 12 | 13 | /******************* 退出登陆 *******************/ 14 | export const logout = () => { 15 | return axios.request({ 16 | url:'/logout', 17 | method:'get', 18 | }); 19 | }; 20 | 21 | /******************* 获取验证码 *******************/ 22 | export const captcha = () => { 23 | return axios.request({ 24 | url:'/captcha', 25 | method:'get' 26 | }); 27 | }; 28 | 29 | // export const test = () => { 30 | // return axios.request({ 31 | // method: 'get', 32 | // url: '/test' 33 | // }) 34 | // } -------------------------------------------------------------------------------- /stock_front_admin/src/api/menus/index.js: -------------------------------------------------------------------------------- 1 | import axios from '@/api' 2 | 3 | /******************* 列表 *******************/ 4 | export const getTableData = () => { 5 | return axios.request({ 6 | url:'/permissions', 7 | method:'get', 8 | }); 9 | }; 10 | 11 | /******************* 添加/编辑菜单树 *******************/ 12 | export const getDataTree = () => { 13 | return axios.request({ 14 | url:'/permissions/tree', 15 | method:'get', 16 | }); 17 | }; 18 | 19 | 20 | /******************* 添加 *******************/ 21 | export const add = (data) => { 22 | return axios.request({ 23 | url:'/permission', 24 | method:'post', 25 | data:data 26 | }); 27 | }; 28 | 29 | /******************* 编辑 *******************/ 30 | export const edit = (data) => { 31 | return axios.request({ 32 | url:'/permission', 33 | method:'put', 34 | data:data 35 | }); 36 | }; 37 | 38 | /******************* 删除 *******************/ 39 | export const del = (id) => { 40 | return axios.request({ 41 | url:'/permission/' + id, 42 | method:'delete', 43 | }); 44 | }; 45 | 46 | 47 | /******************* 权限树形结构数据(角色添加/编辑) *******************/ 48 | export const getPermissionsTree = () => { 49 | return axios.request({ 50 | url:'/permissions/tree/all', 51 | method:'get', 52 | }); 53 | }; -------------------------------------------------------------------------------- /stock_front_admin/src/api/personal/index.js: -------------------------------------------------------------------------------- 1 | import axios from '@/api' 2 | 3 | /******************* 个人资料 *******************/ 4 | export const getPersonal = (data) => { 5 | console.log(data,"用户id....") 6 | return axios.request({ 7 | url:'/user/info/'+data, 8 | method:'get' 9 | }); 10 | }; 11 | 12 | /******************* 密码修改 *******************/ 13 | export const editPassword = (data) => { 14 | return axios.request({ 15 | url:'/user/password', 16 | method:'put', 17 | data:data 18 | }); 19 | }; -------------------------------------------------------------------------------- /stock_front_admin/src/api/roles/index.js: -------------------------------------------------------------------------------- 1 | import axios from '@/api' 2 | import da from "element-ui/src/locale/lang/da"; 3 | 4 | /******************* 列表 *******************/ 5 | export const getTableData = (data={}) => { 6 | return axios.request({ 7 | url:'/roles', 8 | method:'post', 9 | data:data 10 | }); 11 | }; 12 | 13 | 14 | /******************* 添加 *******************/ 15 | export const add = (data) => { 16 | return axios.request({ 17 | url:'/role', 18 | method:'post', 19 | data:data 20 | }); 21 | }; 22 | 23 | /******************* 获取拥有的权限ids *******************/ 24 | export const getPermissionsIds = (id) => { 25 | return axios.request({ 26 | url:'/role/' + id, 27 | method:'get', 28 | }); 29 | }; 30 | 31 | /******************* 编辑 *******************/ 32 | export const edit = (data) => { 33 | return axios.request({ 34 | url:'/role', 35 | method:'put', 36 | data:data 37 | }); 38 | }; 39 | 40 | /******************* 更新角色状态 *******************/ 41 | export const updateStatus = (data) => { 42 | return axios.request({ 43 | url:'/role/' + data[0] + '/' + data[1], 44 | method:'post', 45 | }); 46 | }; 47 | 48 | /******************* 删除 *******************/ 49 | export const del = (id) => { 50 | return axios.request({ 51 | url:'/role/'+id, 52 | method:'delete', 53 | }); 54 | }; -------------------------------------------------------------------------------- /stock_front_admin/src/api/stock/details.js: -------------------------------------------------------------------------------- 1 | // import http from '../../request/http.js'; 2 | import axios from '@/api'; 3 | 4 | //个股描述 5 | export function quotStockDescribe(params) { 6 | return axios.request({ 7 | url: '/quot/stock/describe', 8 | method: 'get', 9 | params, 10 | }); 11 | } 12 | 13 | //个股秒级行情数据查询 14 | export function quotStockScreenSecond(params) { 15 | return axios.request({ 16 | url: '/quot/stock/screen/second', 17 | method: 'get', 18 | params, 19 | }); 20 | } 21 | 22 | //个股秒级行情数据查询 23 | export function quotSecondDetail(params) { 24 | return axios.request({ 25 | url: '/quot/stock/screen/second/detail', 26 | method: 'get', 27 | params, 28 | }); 29 | } 30 | 31 | //个股分时行情 32 | export function timeSharing(params) { 33 | return axios.request({ 34 | url: '/quot/stock/screen/time-sharing', 35 | method: 'get', 36 | params, 37 | }); 38 | } 39 | 40 | //个股日K线数据查询 41 | export function dkline(params) { 42 | return axios.request({ 43 | url: '/quot/stock/screen/dkline', 44 | method: 'get', 45 | params, 46 | }); 47 | } 48 | 49 | //个股周K线数据查询 50 | export function weekKline(params) { 51 | return axios.request({ 52 | url: '/quot/stock/screen/weekkline', 53 | method: 'get', 54 | params, 55 | }); 56 | } 57 | -------------------------------------------------------------------------------- /stock_front_admin/src/api/stock/home.js: -------------------------------------------------------------------------------- 1 | // import http from '../../request/http.js'; 2 | import axios from '@/api'; 3 | 4 | //国内指数 5 | export function quotIndexAll(params) { 6 | return axios.request({ 7 | url: '/quot/index/all', 8 | method: 'get', 9 | params, 10 | }); 11 | } 12 | 13 | //板块指数 14 | export function quotSectorAll(params) { 15 | return axios.request({ 16 | url: '/quot/sector/all', 17 | method: 'get', 18 | params, 19 | }); 20 | } 21 | 22 | //外盘指数 23 | export function quotExternalIndex(params) { 24 | return axios.request({ 25 | url: '/quot/external/index', 26 | method: 'get', 27 | params, 28 | }); 29 | } 30 | 31 | //涨幅榜 32 | export function quotStockIncrease(params) { 33 | return axios.request({ 34 | url: '/quot/stock/increase', 35 | method: 'get', 36 | params, 37 | }); 38 | } 39 | 40 | //涨停跌停数 41 | export function quotStockUpdownCount(params) { 42 | return axios.request({ 43 | url: '/quot/stock/updown/count', 44 | method: 'get', 45 | params, 46 | }); 47 | } 48 | 49 | //个股涨跌 50 | export function quotStockUpdown(params) { 51 | return axios.request({ 52 | url: '/quot/stock/updown', 53 | method: 'get', 54 | params, 55 | }); 56 | } 57 | 58 | //成交量对比 59 | export function quotStockTradevol(params) { 60 | return axios.request({ 61 | url: '/quot/stock/tradevol', 62 | method: 'get', 63 | params, 64 | }); 65 | } 66 | 67 | 68 | //股票搜索 69 | export function quotStockSearch(params) { 70 | return axios.request({ 71 | url: '/quot/stock/search', 72 | method: 'get', 73 | params, 74 | }); 75 | } -------------------------------------------------------------------------------- /stock_front_admin/src/api/stock/list.js: -------------------------------------------------------------------------------- 1 | // import http from '../../request/http.js'; 2 | import axios from '@/api'; 3 | //列表页 4 | export function quotStockAll(params) { 5 | console.log(params); 6 | return axios.request({ 7 | url: '/quot/stock/all', 8 | method: 'get', 9 | params, 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /stock_front_admin/src/api/user/index.js: -------------------------------------------------------------------------------- 1 | import axios from '@/api' 2 | 3 | /******************* 列表 *******************/ 4 | export const getTableData = (data) => { 5 | console.log("P-userPage",data); 6 | return axios.request({ 7 | url:'/users', 8 | method:'post', 9 | data:data 10 | }); 11 | }; 12 | 13 | 14 | /******************* 添加 *******************/ 15 | export const add = (data) => { 16 | return axios.request({ 17 | url:'/user', 18 | method:'post', 19 | data:data 20 | }); 21 | }; 22 | 23 | /******************* 编辑 *******************/ 24 | export const edit = (data) => { 25 | return axios.request({ 26 | url:'/user', 27 | method:'put', 28 | data:data 29 | }); 30 | }; 31 | 32 | /******************* 重置密码 *******************/ 33 | export const resetPassword = (id) => { 34 | return axios.request({ 35 | url:'/user/password/' + id, 36 | method:'get', 37 | }); 38 | }; 39 | 40 | /******************* 删除 *******************/ 41 | export const del = (data) => { 42 | return axios.request({ 43 | url:'/user', 44 | method:'delete', 45 | data:data 46 | }); 47 | }; 48 | 49 | /******************* 获取拥有的权限ids *******************/ 50 | export const getPermissionsIds = (id) => { 51 | return axios.request({ 52 | url:'/user/roles/' + id, 53 | method:'get', 54 | }); 55 | }; 56 | 57 | /******************* 更新拥有的权限ids *******************/ 58 | export const updatePermissionsIds = (data) => { 59 | return axios.request({ 60 | url:'/user/roles', 61 | method:'put', 62 | data:data 63 | }); 64 | }; -------------------------------------------------------------------------------- /stock_front_admin/src/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/favicon.ico -------------------------------------------------------------------------------- /stock_front_admin/src/assets/fonts/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/fonts/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /stock_front_admin/src/assets/fonts/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/fonts/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /stock_front_admin/src/assets/fonts/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/fonts/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /stock_front_admin/src/assets/fonts/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/fonts/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /stock_front_admin/src/assets/fonts/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/fonts/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /stock_front_admin/src/assets/images/401.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/images/401.gif -------------------------------------------------------------------------------- /stock_front_admin/src/assets/images/404.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/images/404.gif -------------------------------------------------------------------------------- /stock_front_admin/src/assets/images/404.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/images/404.jpg -------------------------------------------------------------------------------- /stock_front_admin/src/assets/images/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/images/avatar.png -------------------------------------------------------------------------------- /stock_front_admin/src/assets/images/b1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/images/b1.png -------------------------------------------------------------------------------- /stock_front_admin/src/assets/images/b2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/images/b2.png -------------------------------------------------------------------------------- /stock_front_admin/src/assets/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/images/bg.jpg -------------------------------------------------------------------------------- /stock_front_admin/src/assets/images/logo-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/images/logo-0.png -------------------------------------------------------------------------------- /stock_front_admin/src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/images/logo.png -------------------------------------------------------------------------------- /stock_front_admin/src/assets/images/logo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/images/logo1.png -------------------------------------------------------------------------------- /stock_front_admin/src/assets/images/logo3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/images/logo3.png -------------------------------------------------------------------------------- /stock_front_admin/src/assets/images/timg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/images/timg.jpg -------------------------------------------------------------------------------- /stock_front_admin/src/assets/images/touxiang.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/images/touxiang.jpg -------------------------------------------------------------------------------- /stock_front_admin/src/assets/style/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_front_admin/src/assets/style/.gitkeep -------------------------------------------------------------------------------- /stock_front_admin/src/assets/style/globalstyle.css: -------------------------------------------------------------------------------- 1 | /************************* 全局样式 *************************/ 2 | .el-button+.el-button{ 3 | margin-left: 0; 4 | } 5 | #nprogress .bar { 6 | background: #52bea6 !important; /* 进度条自定义颜色 */ 7 | } -------------------------------------------------------------------------------- /stock_front_admin/src/assets/style/varibles.styl: -------------------------------------------------------------------------------- 1 | $bgImgLogin='~@/assets/images/bg.jpg' -------------------------------------------------------------------------------- /stock_front_admin/src/common/env.js: -------------------------------------------------------------------------------- 1 | /************************* 变量文件 *************************/ 2 | const ip = '';// api接口请求域名 3 | const host = 'http://192.168.5.100:8003';// 资源服务器 4 | const xxjobAdminUrl='http://127.0.0.1:8082';// xxjob-admin管理后台地址 5 | // const baseUrl = 'http://mock-api.com/WNnQarnY.mock'; 6 | const baseUrl = ip + '/api';// api接口请求域名 7 | 8 | /********************* 图片上传管理 ***********************/ 9 | const delUploadImageUrl = host + '/uploads/del';// 删除已上传图片地址 10 | const upload = ip + '/upload/'; 11 | const uploadIdCardUrl = host + '/upload/zn_IdCard';// 身份证上传 12 | const uploadBankCardUrl = host + '/upload/zn_bankCard';// 银行卡图片上传 13 | // 注意:删除图片,只需要改地址,然后引入组件即可使用 14 | module.exports = { 15 | ip, 16 | baseUrl, 17 | delUploadImageUrl, 18 | upload, 19 | uploadIdCardUrl, 20 | uploadBankCardUrl, 21 | xxjobAdminUrl 22 | }; 23 | 24 | -------------------------------------------------------------------------------- /stock_front_admin/src/components/fadeIn/fadeIn.vue: -------------------------------------------------------------------------------- 1 | 6 | 11 | -------------------------------------------------------------------------------- /stock_front_admin/src/components/layout/mixin/ResizeHandler.js: -------------------------------------------------------------------------------- 1 | import store from '@/store' 2 | 3 | const {body} = document; 4 | const WIDTH = 720; // refer to Bootstrap's responsive design 5 | 6 | export default { 7 | watch: { 8 | $route(route) { 9 | this.$_isMobile() && this.$_hiddenSiderBar(); 10 | /*if (this.$_isMobile()){ 11 | this.$_hiddenSiderBar(); 12 | }*/ 13 | } 14 | }, 15 | beforeMount() { 16 | window.addEventListener('resize', this.$_resizeHandler) 17 | }, 18 | beforeDestroy() { 19 | window.removeEventListener('resize', this.$_resizeHandler) 20 | }, 21 | created(){ 22 | store.dispatch('setToggleDevice', this.$_isMobile() ? 'mobile' : 'desktop'); 23 | }, 24 | mounted() { 25 | this.$_hiddenSiderBar(); 26 | }, 27 | methods: { 28 | // use $_ for mixins properties 29 | // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential 30 | $_hiddenSiderBar() { 31 | var className = document.getElementById('sider').className; 32 | if (this.$_isMobile()){ 33 | document.getElementById('sider').classList.add('hiddenSiderBar'); 34 | document.getElementById('siderBarMask').classList.remove('siderBarMask'); 35 | }else{ 36 | if (className.includes('hiddenSiderBar')){ 37 | document.getElementById('sider').classList.remove('hiddenSiderBar'); 38 | document.getElementById('sider').classList.remove('moblieSider'); 39 | } 40 | } 41 | }, 42 | $_isMobile() { 43 | const rect = body.getBoundingClientRect(); 44 | return rect.width - 1 < WIDTH; 45 | }, 46 | $_resizeHandler() { 47 | this.$_hiddenSiderBar(); 48 | if (!document.hidden) { 49 | const isMobile = this.$_isMobile(); 50 | store.dispatch('setToggleDevice', isMobile ? 'mobile' : 'desktop'); 51 | // if (isMobile) { 52 | // store.dispatch('app/closeSideBar', { withoutAnimation: true }) 53 | // } 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /stock_front_admin/src/components/layout/slider/Logo.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 36 | 37 | 85 | -------------------------------------------------------------------------------- /stock_front_admin/src/config/index.js: -------------------------------------------------------------------------------- 1 | import config from './router.config.js' 2 | 3 | export default config -------------------------------------------------------------------------------- /stock_front_admin/src/config/router.config.js: -------------------------------------------------------------------------------- 1 | /************************ axios请求 ************************/ 2 | import { baseUrl } from '@/common/env.js'; 3 | 4 | const config = { 5 | // baseUrl:'http://localhost:8080/api' 6 | baseUrl:baseUrl, 7 | headers:{}, 8 | withCredentials:false // 跨域配置 9 | }; 10 | export default config; -------------------------------------------------------------------------------- /stock_front_admin/src/directives/index.js: -------------------------------------------------------------------------------- 1 | import directives from './permission' 2 | import common from '../common/common' 3 | 4 | export default { 5 | install(Vue, options) { 6 | Vue.directive('has',directives); 7 | for (var key in common){ 8 | Vue.prototype[key] = common[key]; 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /stock_front_admin/src/directives/permission.js: -------------------------------------------------------------------------------- 1 | import store from '@/store' 2 | 3 | export default { 4 | inserted:(el,binding,vnode) => { 5 | // debugger; 6 | let permissions = store.getters.userInfo && store.getters.userInfo.permissions; 7 | permissions && !permissions.some(item => item==binding.value)&&(el.parentNode.removeChild(el)); 8 | } 9 | } -------------------------------------------------------------------------------- /stock_front_admin/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%= htmlWebpackPlugin.options.title %> 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | -------------------------------------------------------------------------------- /stock_front_admin/src/lib/HttpRequest.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import config from '@/config' 3 | import store from '@/store' 4 | const settings = require('@/settings.js'); 5 | // axios.defaults.withCredentials = true; 6 | class HttpRequest{ 7 | constructor(baseUrl = config.baseUrl){ 8 | this.baseUrl = baseUrl; 9 | this.queue = {}; 10 | } 11 | getInsideConfig(){ 12 | return Object.assign({baseURL:this.baseUrl,headers:{}},config); 13 | } 14 | interceptors(instance,url){ 15 | instance.interceptors.request.use(config => { 16 | if (Object.keys(this.queue).length) { 17 | this.queue[url] = true; 18 | } 19 | return config; 20 | },error => { 21 | delete this.queue[url]; 22 | return Promise.reject(error); 23 | }); 24 | instance.interceptors.response.use(response => { 25 | delete this.queue[url]; 26 | const { data, status } = response; 27 | return { data, status }; 28 | },error => { 29 | delete this.queue[url]; 30 | return Promise.reject(error); 31 | }); 32 | } 33 | request(options){ 34 | options = Object.assign(this.getInsideConfig(),options); 35 | const userInfo = (store.getters.userInfo && store.getters.userInfo.accessToken) ? store.getters.userInfo : (sessionStorage.getItem('userInfo') ? JSON.parse(sessionStorage.getItem('userInfo')).value : ''); 36 | if (userInfo && userInfo.accessToken) { 37 | options.headers[settings.authorization] = userInfo.accessToken; 38 | } 39 | const instance = axios.create(); 40 | this.interceptors(instance,options.url); 41 | return instance(options); 42 | } 43 | } 44 | 45 | export default HttpRequest -------------------------------------------------------------------------------- /stock_front_admin/src/main.js: -------------------------------------------------------------------------------- 1 | // 入口文件 2 | // 引入包 3 | import Vue from 'vue' 4 | import store from './store' 5 | import App from './App.vue' 6 | import router from './router' 7 | import directives from './directives' 8 | import ElementComponent from 'element-component' 9 | 10 | // import 'font-awesome/css/font-awesome.min.css' // https://www.thinkcmf.com/font/font_awesome/icons.html 11 | import 'normalize.css' 12 | import './assets/style/globalstyle.css' 13 | import ElementUI from 'element-ui'; 14 | import 'element-ui/lib/theme-chalk/index.css'; 15 | 16 | import echarts from 'echarts' 17 | Vue.prototype.$echarts = echarts 18 | 19 | Vue.use(ElementUI); 20 | 21 | Vue.config.productionTip = false 22 | 23 | // Vue.use(common); 24 | Vue.use(directives); 25 | Vue.use(ElementComponent); 26 | 27 | Vue.config.productionTip = false; 28 | const vm = new Vue({ 29 | el:'#app', 30 | store, 31 | router, 32 | render:c => c(App), 33 | }); 34 | -------------------------------------------------------------------------------- /stock_front_admin/src/router/routers/index.js: -------------------------------------------------------------------------------- 1 | import Layout from '@/components/layout' 2 | import {routes} from "../routes.js" 3 | //查看子路由,收集到集合下 4 | function findChild(data){ 5 | let children = []; 6 | if (!data){ 7 | return children; 8 | } 9 | for (let i = 0,leng = data.length; i < leng; i++) { 10 | if (!data[i].component || data[i].children && data[i].children.length > 0){ 11 | children.push(...findChild(data[i].children)); 12 | }else { 13 | children.push(data[i]); 14 | } 15 | } 16 | return children; 17 | } 18 | //找出根路径,也就是/默认路径 19 | let rootRoute = null; 20 | //找出权限中没有子路由的路由配置 21 | const notChildren = []; 22 | //找出路由配置中所有的子路由 23 | const child = []; 24 | routes && routes.map(item => { 25 | // debugger; 26 | if (item.path != "/"){ 27 | if (item.children && item.children.length > 0){ 28 | //item.children.map(router => child.push(router)); 29 | child.push(...findChild(item.children)); 30 | }else{ 31 | notChildren.push(item); 32 | } 33 | }else { 34 | rootRoute = item; 35 | } 36 | return item; 37 | }); 38 | let index = -1; 39 | let defaultRouter = []; 40 | notChildren.length>0 && routes.some(router => { 41 | index = notChildren.findIndex(item => item.path == router.path); 42 | return index != -1; 43 | }) && (index != -1) && (defaultRouter=notChildren.splice(index,1)); 44 | 45 | const children = { 46 | path:rootRoute.path, 47 | name:rootRoute.name, 48 | component: Layout, 49 | redirect:rootRoute.redirect, 50 | isMenu:rootRoute.isMenu!==false, 51 | children:[rootRoute.children[0],...child,...notChildren] 52 | }; 53 | const startRouter = [...defaultRouter,children]; 54 | export default startRouter; -------------------------------------------------------------------------------- /stock_front_admin/src/router/routers/router_map.js: -------------------------------------------------------------------------------- 1 | import {routesMap} from "../routes.js" 2 | 3 | const handleRoutesMap = []; 4 | routesMap && routesMap.map(item => { 5 | if (item.children && item.children.length > 0){ 6 | item.children.map(child => handleRoutesMap.push(child)); 7 | }else{ 8 | handleRoutesMap.push(item); 9 | } 10 | return item; 11 | }); 12 | export {handleRoutesMap,routesMap}; -------------------------------------------------------------------------------- /stock_front_admin/src/settings.js: -------------------------------------------------------------------------------- 1 | /************************* 配置 *************************/ 2 | module.exports = { 3 | components: '/components',// 指定views下组件所在目录,动态路由组件必须放在该目录下,且路径名称为组件名称 4 | affix: true,// 是否显示图钉 5 | isRefrushBack: true,// 刷新后是否停在当前页,默认回到首页 6 | authorization: 'authorization',// 请求头 token key 7 | title: '今日指数', // 标题 8 | // footer:'权限管理系统',// 底部文字,注释掉默认没有底部 9 | iconPath: './assets/images/logo-0.png',// 网页 icon 图标路径 10 | publicPath: '/',// 网站根目录,打包时用到 11 | devServer: { 12 | port: 8080, 13 | host: '127.0.0.1',// 开发host 14 | open: true,// 是否启动时打开浏览器 15 | disableHostCheck: true, // 映射外网时,需要设置为true 16 | /** 17 | * 域名,他将会基于 window.location来链接服务器,需要使用public配置 18 | * dev-server被代理到nginx中配置的 itheima.com 19 | */ 20 | public: "127.0.0.1:8080", 21 | publicPath: '/', 22 | compress: true, 23 | overlay: {// 是否在浏览器全屏显示错误与警告 24 | warnings: false, 25 | errors: true 26 | }, 27 | proxy: {// 跨域请求配置 28 | "/api": { 29 | secure: false,// 关闭安全检测,默认请求 https 30 | // target: "http://192.168.188.131:8081", 31 | target: "http://localhost:8081", 32 | changeOrigin: true, 33 | // pathRewrite: {"^/api" : ""}, 34 | } 35 | }, 36 | }, 37 | alias: { 38 | // 如:jquery 39 | //"$": 'jquery.js' 40 | }, 41 | //TODO 页面按钮操作权限先写死,后续 删除,从数据库动态获取 42 | permissoins: ['btn-user-delete', 'btn-log-delete', 'btn-user-add', 'btn-role-update', 43 | 'btn-permission-delete', 'btn-permission-list', 'btn-user-list', 'btn-role-delete', 44 | 'btn-role-add', 'btn-role-detail', 'btn-permission-update', 'btn-user-update-role', 45 | 'btn-user-update', 'btn-role-add', 'btn-permission-add', 'btn-role-list', 'btn-log-list' 46 | ] 47 | }; 48 | -------------------------------------------------------------------------------- /stock_front_admin/src/store/getters.js: -------------------------------------------------------------------------------- 1 | const getters = { 2 | device: state => state.device, 3 | isAuthToken: state => state.isAuthToken, 4 | userInfo: state => state.userInfo, 5 | siderList: state => state.siderList, 6 | routes:state => state.routes, 7 | // rules:state => state.rules 8 | }; 9 | 10 | export default getters; -------------------------------------------------------------------------------- /stock_front_admin/src/store/index.js: -------------------------------------------------------------------------------- 1 | // import Vue from 'Vue' 2 | import Vue from 'vue' 3 | import Vuex from 'vuex' 4 | import state from './state.js' 5 | import mutations from './mutations.js' 6 | import actions from './actions.js' 7 | import getters from './getters.js' 8 | import modules from './module/index.js' 9 | 10 | Vue.use(Vuex); 11 | 12 | export default new Vuex.Store({ 13 | state, 14 | mutations, 15 | actions, 16 | getters, 17 | modules 18 | }); 19 | -------------------------------------------------------------------------------- /stock_front_admin/src/store/module/auth.js: -------------------------------------------------------------------------------- 1 | import types from '../types.js' 2 | 3 | const modules = { 4 | state: {}, 5 | mutations: { 6 | [types.SET_CONCATROUTES] (state,newRoutes) { 7 | state.routes = newRoutes.concat(routes); 8 | state.isAuthToken = true; 9 | } 10 | }, 11 | actions: {}, 12 | getters: {} 13 | }; 14 | 15 | export default modules; -------------------------------------------------------------------------------- /stock_front_admin/src/store/module/index.js: -------------------------------------------------------------------------------- 1 | import auth from './auth.js' 2 | 3 | export default { 4 | auth 5 | } -------------------------------------------------------------------------------- /stock_front_admin/src/store/mutations.js: -------------------------------------------------------------------------------- 1 | import types from './types.js' 2 | 3 | // 后台直接请求回来菜单,帅选左侧导航菜单需要的属性 4 | const getMenuList = (routesList) => { 5 | let siderList = []; 6 | for (let key in routesList) { 7 | let item = routesList[key]; 8 | if (item.isMenu == false) { 9 | continue; 10 | } 11 | let sider = {name:'', icon:'', path:''}; 12 | if (item.meta && item.meta.title && item.path){ 13 | sider.name = item.meta.title; 14 | sider.icon = item.meta.icon; 15 | sider.path = item.path; 16 | } 17 | if (item.title && item.path){ 18 | sider.name = item.title; 19 | sider.icon = item.icon || ''; 20 | sider.path = item.path; 21 | } 22 | if (item.children && item.children.length > 0) { 23 | sider.children = getMenuList(item.children); 24 | } 25 | sider.name && sider.path && siderList.push(sider); 26 | } 27 | return siderList; 28 | }; 29 | 30 | const mutations = { 31 | [types.TOGGLE_DEVICE] (state,device) { 32 | state.device = device; 33 | }, 34 | [types.SET_TOKEN] (state,isAuthToken) { 35 | state.isAuthToken = isAuthToken; 36 | }, 37 | [types.SET_USER] (state,userInfo) { 38 | if (userInfo){ 39 | state.userInfo = userInfo; 40 | }else{ 41 | state.userInfo = {}; 42 | } 43 | }, 44 | [types.SET_NEWROUTES] (state,newRoutes) { 45 | state.routes = newRoutes; 46 | state.isAuthToken = true; 47 | }, 48 | [types.SET_SIDERLIST] (state,siderList) { 49 | if(!siderList){ 50 | return state.siderList = siderList; 51 | } 52 | //siderList = getMenuList(siderList,state.userInfo.roles); 53 | siderList = getMenuList(siderList); 54 | if (Array.isArray(siderList) && siderList.length > 0) { 55 | state.siderList = siderList; 56 | }else { 57 | state.siderList = []; 58 | } 59 | } 60 | }; 61 | 62 | export default mutations 63 | -------------------------------------------------------------------------------- /stock_front_admin/src/store/state.js: -------------------------------------------------------------------------------- 1 | // import {routes} from '@/router/routes.js' 2 | 3 | const state = { 4 | device:'desktop', 5 | isAuthToken:false, 6 | userInfo:{}, 7 | siderList:[], 8 | permissionList:[], 9 | routes:[] 10 | }; 11 | 12 | export default state -------------------------------------------------------------------------------- /stock_front_admin/src/store/types.js: -------------------------------------------------------------------------------- 1 | const types = { 2 | TOGGLE_DEVICE:'toggleDevice', 3 | SET_TOKEN:'token', 4 | SET_USER:'userInfo', 5 | SET_NEWROUTES:'newRoutes', 6 | SET_SIDERLIST:'siderList' 7 | }; 8 | 9 | export default types -------------------------------------------------------------------------------- /stock_front_admin/src/views/components/jobAdmin/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | 20 | -------------------------------------------------------------------------------- /stock_front_admin/src/views/components/sql/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | 20 | -------------------------------------------------------------------------------- /stock_front_admin/src/views/components/swagger/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | 20 | -------------------------------------------------------------------------------- /stock_front_admin/src/views/components/user/components/auth.vue: -------------------------------------------------------------------------------- 1 | 15 | 43 | -------------------------------------------------------------------------------- /stock_front_admin/src/views/error/401.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /stock_front_admin/src/views/error/404.vue: -------------------------------------------------------------------------------- 1 | 12 | 18 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/XxlJobAdminApplication.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | 7 | /** 8 | * @author teng 9 | */ 10 | @SpringBootApplication 11 | public class XxlJobAdminApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(XxlJobAdminApplication.class, args); 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/controller/annotation/PermissionLimit.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.controller.annotation; 2 | 3 | 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | /** 10 | * 权限限制 11 | * @author xuxueli 2015-12-12 18:29:02 12 | */ 13 | @Target(ElementType.METHOD) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface PermissionLimit { 16 | 17 | /** 18 | * 登录拦截 (默认拦截) 19 | */ 20 | boolean limit() default true; 21 | 22 | /** 23 | * 要求管理员权限 24 | * 25 | * @return 26 | */ 27 | boolean adminuser() default false; 28 | 29 | } -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/controller/interceptor/CookieInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.controller.interceptor; 2 | 3 | import com.lt.job.admin.core.util.FtlUtil; 4 | import com.lt.job.admin.core.util.I18nUtil; 5 | import org.springframework.stereotype.Component; 6 | import org.springframework.web.servlet.ModelAndView; 7 | import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 8 | 9 | import javax.servlet.http.Cookie; 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | import java.util.HashMap; 13 | 14 | /** 15 | * push cookies to model as cookieMap 16 | * 17 | * @author xuxueli 2015-12-12 18:09:04 18 | */ 19 | @Component 20 | public class CookieInterceptor extends HandlerInterceptorAdapter { 21 | 22 | @Override 23 | public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 24 | ModelAndView modelAndView) throws Exception { 25 | 26 | // cookie 27 | if (modelAndView!=null && request.getCookies()!=null && request.getCookies().length>0) { 28 | HashMap cookieMap = new HashMap(); 29 | for (Cookie ck : request.getCookies()) { 30 | cookieMap.put(ck.getName(), ck); 31 | } 32 | modelAndView.addObject("cookieMap", cookieMap); 33 | } 34 | 35 | // static method 36 | if (modelAndView != null) { 37 | modelAndView.addObject("I18nUtil", FtlUtil.generateStaticModel(I18nUtil.class.getName())); 38 | } 39 | 40 | super.postHandle(request, response, handler, modelAndView); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/controller/interceptor/PermissionInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.controller.interceptor; 2 | 3 | import com.lt.job.admin.controller.annotation.PermissionLimit; 4 | import com.lt.job.admin.core.model.XxlJobUser; 5 | import com.lt.job.admin.core.util.I18nUtil; 6 | import com.lt.job.admin.service.LoginService; 7 | import org.springframework.stereotype.Component; 8 | import org.springframework.web.method.HandlerMethod; 9 | import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 10 | 11 | import javax.annotation.Resource; 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpServletResponse; 14 | 15 | /** 16 | * 权限拦截 17 | * 18 | * @author xuxueli 2015-12-12 18:09:04 19 | */ 20 | @Component 21 | public class PermissionInterceptor extends HandlerInterceptorAdapter { 22 | 23 | @Resource 24 | private LoginService loginService; 25 | 26 | @Override 27 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 28 | 29 | if (!(handler instanceof HandlerMethod)) { 30 | return super.preHandle(request, response, handler); 31 | } 32 | 33 | // if need login 34 | boolean needLogin = true; 35 | boolean needAdminuser = false; 36 | HandlerMethod method = (HandlerMethod)handler; 37 | PermissionLimit permission = method.getMethodAnnotation(PermissionLimit.class); 38 | if (permission!=null) { 39 | needLogin = permission.limit(); 40 | needAdminuser = permission.adminuser(); 41 | } 42 | 43 | if (needLogin) { 44 | XxlJobUser loginUser = loginService.ifLogin(request, response); 45 | if (loginUser == null) { 46 | response.setStatus(302); 47 | response.setHeader("location", request.getContextPath()+"/toLogin"); 48 | return false; 49 | } 50 | if (needAdminuser && loginUser.getRole()!=1) { 51 | throw new RuntimeException(I18nUtil.getString("system_permission_limit")); 52 | } 53 | request.setAttribute(LoginService.LOGIN_IDENTITY_KEY, loginUser); 54 | } 55 | 56 | return super.preHandle(request, response, handler); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/controller/interceptor/WebMvcConfig.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.controller.interceptor; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 6 | 7 | import javax.annotation.Resource; 8 | 9 | /** 10 | * web mvc config 11 | * 12 | * @author xuxueli 2018-04-02 20:48:20 13 | */ 14 | @Configuration 15 | public class WebMvcConfig implements WebMvcConfigurer { 16 | 17 | @Resource 18 | private PermissionInterceptor permissionInterceptor; 19 | @Resource 20 | private CookieInterceptor cookieInterceptor; 21 | 22 | @Override 23 | public void addInterceptors(InterceptorRegistry registry) { 24 | registry.addInterceptor(permissionInterceptor).addPathPatterns("/**"); 25 | registry.addInterceptor(cookieInterceptor).addPathPatterns("/**"); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/controller/resolver/WebExceptionResolver.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.controller.resolver; 2 | 3 | import com.lt.job.admin.core.exception.XxlJobException; 4 | import com.lt.job.admin.core.util.JacksonUtil; 5 | import com.xxl.job.core.biz.model.ReturnT; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.web.bind.annotation.ResponseBody; 10 | import org.springframework.web.method.HandlerMethod; 11 | import org.springframework.web.servlet.HandlerExceptionResolver; 12 | import org.springframework.web.servlet.ModelAndView; 13 | 14 | import javax.servlet.http.HttpServletRequest; 15 | import javax.servlet.http.HttpServletResponse; 16 | import java.io.IOException; 17 | 18 | /** 19 | * common exception resolver 20 | * 21 | * @author xuxueli 2016-1-6 19:22:18 22 | */ 23 | @Component 24 | public class WebExceptionResolver implements HandlerExceptionResolver { 25 | private static transient Logger logger = LoggerFactory.getLogger(WebExceptionResolver.class); 26 | 27 | @Override 28 | public ModelAndView resolveException(HttpServletRequest request, 29 | HttpServletResponse response, Object handler, Exception ex) { 30 | 31 | if (!(ex instanceof XxlJobException)) { 32 | logger.error("WebExceptionResolver:{}", ex); 33 | } 34 | 35 | // if json 36 | boolean isJson = false; 37 | if (handler instanceof HandlerMethod) { 38 | HandlerMethod method = (HandlerMethod)handler; 39 | ResponseBody responseBody = method.getMethodAnnotation(ResponseBody.class); 40 | if (responseBody != null) { 41 | isJson = true; 42 | } 43 | } 44 | 45 | // error result 46 | ReturnT errorResult = new ReturnT(ReturnT.FAIL_CODE, ex.toString().replaceAll("\n", "
")); 47 | 48 | // response 49 | ModelAndView mv = new ModelAndView(); 50 | if (isJson) { 51 | try { 52 | response.setContentType("application/json;charset=utf-8"); 53 | response.getWriter().print(JacksonUtil.writeValueAsString(errorResult)); 54 | } catch (IOException e) { 55 | logger.error(e.getMessage(), e); 56 | } 57 | return mv; 58 | } else { 59 | 60 | mv.addObject("exceptionMsg", errorResult.getMsg()); 61 | mv.setViewName("/common/common.exception"); 62 | return mv; 63 | } 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/alarm/JobAlarm.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.alarm; 2 | 3 | import com.lt.job.admin.core.model.XxlJobInfo; 4 | import com.lt.job.admin.core.model.XxlJobLog; 5 | 6 | /** 7 | * @author xuxueli 2020-01-19 8 | */ 9 | public interface JobAlarm { 10 | 11 | /** 12 | * job alarm 13 | * 14 | * @param info 15 | * @param jobLog 16 | * @return 17 | */ 18 | public boolean doAlarm(XxlJobInfo info, XxlJobLog jobLog); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/alarm/JobAlarmer.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.alarm; 2 | 3 | import com.lt.job.admin.core.model.XxlJobInfo; 4 | import com.lt.job.admin.core.model.XxlJobLog; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.BeansException; 8 | import org.springframework.beans.factory.InitializingBean; 9 | import org.springframework.context.ApplicationContext; 10 | import org.springframework.context.ApplicationContextAware; 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | import java.util.Map; 16 | 17 | @Component 18 | public class JobAlarmer implements ApplicationContextAware, InitializingBean { 19 | private static Logger logger = LoggerFactory.getLogger(JobAlarmer.class); 20 | 21 | private ApplicationContext applicationContext; 22 | private List jobAlarmList; 23 | 24 | @Override 25 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 26 | this.applicationContext = applicationContext; 27 | } 28 | 29 | @Override 30 | public void afterPropertiesSet() throws Exception { 31 | Map serviceBeanMap = applicationContext.getBeansOfType(JobAlarm.class); 32 | if (serviceBeanMap != null && serviceBeanMap.size() > 0) { 33 | jobAlarmList = new ArrayList(serviceBeanMap.values()); 34 | } 35 | } 36 | 37 | /** 38 | * job alarm 39 | * 40 | * @param info 41 | * @param jobLog 42 | * @return 43 | */ 44 | public boolean alarm(XxlJobInfo info, XxlJobLog jobLog) { 45 | 46 | boolean result = false; 47 | if (jobAlarmList!=null && jobAlarmList.size()>0) { 48 | result = true; // success means all-success 49 | for (JobAlarm alarm: jobAlarmList) { 50 | boolean resultItem = false; 51 | try { 52 | resultItem = alarm.doAlarm(info, jobLog); 53 | } catch (Exception e) { 54 | logger.error(e.getMessage(), e); 55 | } 56 | if (!resultItem) { 57 | result = false; 58 | } 59 | } 60 | } 61 | 62 | return result; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/exception/XxlJobException.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.exception; 2 | 3 | /** 4 | * @author xuxueli 2019-05-04 23:19:29 5 | */ 6 | public class XxlJobException extends RuntimeException { 7 | 8 | public XxlJobException() { 9 | } 10 | public XxlJobException(String message) { 11 | super(message); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/model/XxlJobGroup.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Date; 6 | import java.util.List; 7 | 8 | /** 9 | * Created by xuxueli on 16/9/30. 10 | */ 11 | public class XxlJobGroup { 12 | 13 | private int id; 14 | private String appname; 15 | private String title; 16 | private int addressType; // 执行器地址类型:0=自动注册、1=手动录入 17 | private String addressList; // 执行器地址列表,多地址逗号分隔(手动录入) 18 | private Date updateTime; 19 | 20 | // registry list 21 | private List registryList; // 执行器地址列表(系统注册) 22 | public List getRegistryList() { 23 | if (addressList!=null && addressList.trim().length()>0) { 24 | registryList = new ArrayList(Arrays.asList(addressList.split(","))); 25 | } 26 | return registryList; 27 | } 28 | 29 | public int getId() { 30 | return id; 31 | } 32 | 33 | public void setId(int id) { 34 | this.id = id; 35 | } 36 | 37 | public String getAppname() { 38 | return appname; 39 | } 40 | 41 | public void setAppname(String appname) { 42 | this.appname = appname; 43 | } 44 | 45 | public String getTitle() { 46 | return title; 47 | } 48 | 49 | public void setTitle(String title) { 50 | this.title = title; 51 | } 52 | 53 | public int getAddressType() { 54 | return addressType; 55 | } 56 | 57 | public void setAddressType(int addressType) { 58 | this.addressType = addressType; 59 | } 60 | 61 | public String getAddressList() { 62 | return addressList; 63 | } 64 | 65 | public Date getUpdateTime() { 66 | return updateTime; 67 | } 68 | 69 | public void setUpdateTime(Date updateTime) { 70 | this.updateTime = updateTime; 71 | } 72 | 73 | public void setAddressList(String addressList) { 74 | this.addressList = addressList; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/model/XxlJobLogGlue.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.model; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * xxl-job log for glue, used to track job code process 7 | * @author xuxueli 2016-5-19 17:57:46 8 | */ 9 | public class XxlJobLogGlue { 10 | 11 | private int id; 12 | private int jobId; // 任务主键ID 13 | private String glueType; // GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum 14 | private String glueSource; 15 | private String glueRemark; 16 | private Date addTime; 17 | private Date updateTime; 18 | 19 | public int getId() { 20 | return id; 21 | } 22 | 23 | public void setId(int id) { 24 | this.id = id; 25 | } 26 | 27 | public int getJobId() { 28 | return jobId; 29 | } 30 | 31 | public void setJobId(int jobId) { 32 | this.jobId = jobId; 33 | } 34 | 35 | public String getGlueType() { 36 | return glueType; 37 | } 38 | 39 | public void setGlueType(String glueType) { 40 | this.glueType = glueType; 41 | } 42 | 43 | public String getGlueSource() { 44 | return glueSource; 45 | } 46 | 47 | public void setGlueSource(String glueSource) { 48 | this.glueSource = glueSource; 49 | } 50 | 51 | public String getGlueRemark() { 52 | return glueRemark; 53 | } 54 | 55 | public void setGlueRemark(String glueRemark) { 56 | this.glueRemark = glueRemark; 57 | } 58 | 59 | public Date getAddTime() { 60 | return addTime; 61 | } 62 | 63 | public void setAddTime(Date addTime) { 64 | this.addTime = addTime; 65 | } 66 | 67 | public Date getUpdateTime() { 68 | return updateTime; 69 | } 70 | 71 | public void setUpdateTime(Date updateTime) { 72 | this.updateTime = updateTime; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/model/XxlJobLogReport.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.model; 2 | 3 | import java.util.Date; 4 | 5 | public class XxlJobLogReport { 6 | 7 | private int id; 8 | 9 | private Date triggerDay; 10 | 11 | private int runningCount; 12 | private int sucCount; 13 | private int failCount; 14 | 15 | public int getId() { 16 | return id; 17 | } 18 | 19 | public void setId(int id) { 20 | this.id = id; 21 | } 22 | 23 | public Date getTriggerDay() { 24 | return triggerDay; 25 | } 26 | 27 | public void setTriggerDay(Date triggerDay) { 28 | this.triggerDay = triggerDay; 29 | } 30 | 31 | public int getRunningCount() { 32 | return runningCount; 33 | } 34 | 35 | public void setRunningCount(int runningCount) { 36 | this.runningCount = runningCount; 37 | } 38 | 39 | public int getSucCount() { 40 | return sucCount; 41 | } 42 | 43 | public void setSucCount(int sucCount) { 44 | this.sucCount = sucCount; 45 | } 46 | 47 | public int getFailCount() { 48 | return failCount; 49 | } 50 | 51 | public void setFailCount(int failCount) { 52 | this.failCount = failCount; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/model/XxlJobRegistry.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.model; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * Created by xuxueli on 16/9/30. 7 | */ 8 | public class XxlJobRegistry { 9 | 10 | private int id; 11 | private String registryGroup; 12 | private String registryKey; 13 | private String registryValue; 14 | private Date updateTime; 15 | 16 | public int getId() { 17 | return id; 18 | } 19 | 20 | public void setId(int id) { 21 | this.id = id; 22 | } 23 | 24 | public String getRegistryGroup() { 25 | return registryGroup; 26 | } 27 | 28 | public void setRegistryGroup(String registryGroup) { 29 | this.registryGroup = registryGroup; 30 | } 31 | 32 | public String getRegistryKey() { 33 | return registryKey; 34 | } 35 | 36 | public void setRegistryKey(String registryKey) { 37 | this.registryKey = registryKey; 38 | } 39 | 40 | public String getRegistryValue() { 41 | return registryValue; 42 | } 43 | 44 | public void setRegistryValue(String registryValue) { 45 | this.registryValue = registryValue; 46 | } 47 | 48 | public Date getUpdateTime() { 49 | return updateTime; 50 | } 51 | 52 | public void setUpdateTime(Date updateTime) { 53 | this.updateTime = updateTime; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/model/XxlJobUser.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.model; 2 | 3 | import org.springframework.util.StringUtils; 4 | 5 | /** 6 | * @author xuxueli 2019-05-04 16:43:12 7 | */ 8 | public class XxlJobUser { 9 | 10 | private int id; 11 | private String username; // 账号 12 | private String password; // 密码 13 | private int role; // 角色:0-普通用户、1-管理员 14 | private String permission; // 权限:执行器ID列表,多个逗号分割 15 | 16 | public int getId() { 17 | return id; 18 | } 19 | 20 | public void setId(int id) { 21 | this.id = id; 22 | } 23 | 24 | public String getUsername() { 25 | return username; 26 | } 27 | 28 | public void setUsername(String username) { 29 | this.username = username; 30 | } 31 | 32 | public String getPassword() { 33 | return password; 34 | } 35 | 36 | public void setPassword(String password) { 37 | this.password = password; 38 | } 39 | 40 | public int getRole() { 41 | return role; 42 | } 43 | 44 | public void setRole(int role) { 45 | this.role = role; 46 | } 47 | 48 | public String getPermission() { 49 | return permission; 50 | } 51 | 52 | public void setPermission(String permission) { 53 | this.permission = permission; 54 | } 55 | 56 | // plugin 57 | public boolean validPermission(int jobGroup){ 58 | if (this.role == 1) { 59 | return true; 60 | } else { 61 | if (StringUtils.hasText(this.permission)) { 62 | for (String permissionItem : this.permission.split(",")) { 63 | if (String.valueOf(jobGroup).equals(permissionItem)) { 64 | return true; 65 | } 66 | } 67 | } 68 | return false; 69 | } 70 | 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/old/RemoteHttpJobBean.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.old;//package com.xxl.job.admin.core.jobbean; 2 | // 3 | //import com.xxl.job.admin.core.thread.JobTriggerPoolHelper; 4 | //import com.xxl.job.admin.core.trigger.TriggerTypeEnum; 5 | //import org.quartz.JobExecutionContext; 6 | //import org.quartz.JobExecutionException; 7 | //import org.quartz.JobKey; 8 | //import org.slf4j.Logger; 9 | //import org.slf4j.LoggerFactory; 10 | //import org.springframework.scheduling.quartz.QuartzJobBean; 11 | // 12 | ///** 13 | // * http job bean 14 | // * “@DisallowConcurrentExecution” disable concurrent, thread size can not be only one, better given more 15 | // * @author xuxueli 2015-12-17 18:20:34 16 | // */ 17 | ////@DisallowConcurrentExecution 18 | //public class RemoteHttpJobBean extends QuartzJobBean { 19 | // private static Logger logger = LoggerFactory.getLogger(RemoteHttpJobBean.class); 20 | // 21 | // @Override 22 | // protected void executeInternal(JobExecutionContext context) 23 | // throws JobExecutionException { 24 | // 25 | // // load jobId 26 | // JobKey jobKey = context.getTrigger().getJobKey(); 27 | // Integer jobId = Integer.valueOf(jobKey.getName()); 28 | // 29 | // 30 | // } 31 | // 32 | //} -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/old/XxlJobThreadPool.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.old;//package com.xxl.job.admin.core.quartz; 2 | // 3 | //import org.quartz.SchedulerConfigException; 4 | //import org.quartz.spi.ThreadPool; 5 | // 6 | ///** 7 | // * single thread pool, for async trigger 8 | // * 9 | // * @author xuxueli 2019-03-06 10 | // */ 11 | //public class XxlJobThreadPool implements ThreadPool { 12 | // 13 | // @Override 14 | // public boolean runInThread(Runnable runnable) { 15 | // 16 | // // async run 17 | // runnable.run(); 18 | // return true; 19 | // 20 | // //return false; 21 | // } 22 | // 23 | // @Override 24 | // public int blockForAvailableThreads() { 25 | // return 1; 26 | // } 27 | // 28 | // @Override 29 | // public void initialize() throws SchedulerConfigException { 30 | // 31 | // } 32 | // 33 | // @Override 34 | // public void shutdown(boolean waitForJobsToComplete) { 35 | // 36 | // } 37 | // 38 | // @Override 39 | // public int getPoolSize() { 40 | // return 1; 41 | // } 42 | // 43 | // @Override 44 | // public void setInstanceId(String schedInstId) { 45 | // 46 | // } 47 | // 48 | // @Override 49 | // public void setInstanceName(String schedName) { 50 | // 51 | // } 52 | // 53 | // // support 54 | // public void setThreadCount(int count) { 55 | // // 56 | // } 57 | // 58 | //} 59 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/route/ExecutorRouteStrategyEnum.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.route; 2 | 3 | import com.lt.job.admin.core.util.I18nUtil; 4 | import com.lt.job.admin.core.route.strategy.*; 5 | 6 | /** 7 | * Created by xuxueli on 17/3/10. 8 | */ 9 | public enum ExecutorRouteStrategyEnum { 10 | 11 | FIRST(I18nUtil.getString("jobconf_route_first"), new ExecutorRouteFirst()), 12 | LAST(I18nUtil.getString("jobconf_route_last"), new ExecutorRouteLast()), 13 | ROUND(I18nUtil.getString("jobconf_route_round"), new ExecutorRouteRound()), 14 | RANDOM(I18nUtil.getString("jobconf_route_random"), new ExecutorRouteRandom()), 15 | CONSISTENT_HASH(I18nUtil.getString("jobconf_route_consistenthash"), new ExecutorRouteConsistentHash()), 16 | LEAST_FREQUENTLY_USED(I18nUtil.getString("jobconf_route_lfu"), new ExecutorRouteLFU()), 17 | LEAST_RECENTLY_USED(I18nUtil.getString("jobconf_route_lru"), new ExecutorRouteLRU()), 18 | FAILOVER(I18nUtil.getString("jobconf_route_failover"), new ExecutorRouteFailover()), 19 | BUSYOVER(I18nUtil.getString("jobconf_route_busyover"), new ExecutorRouteBusyover()), 20 | SHARDING_BROADCAST(I18nUtil.getString("jobconf_route_shard"), null); 21 | 22 | ExecutorRouteStrategyEnum(String title, ExecutorRouter router) { 23 | this.title = title; 24 | this.router = router; 25 | } 26 | 27 | private String title; 28 | private ExecutorRouter router; 29 | 30 | public String getTitle() { 31 | return title; 32 | } 33 | public ExecutorRouter getRouter() { 34 | return router; 35 | } 36 | 37 | public static ExecutorRouteStrategyEnum match(String name, ExecutorRouteStrategyEnum defaultItem){ 38 | if (name != null) { 39 | for (ExecutorRouteStrategyEnum item: ExecutorRouteStrategyEnum.values()) { 40 | if (item.name().equals(name)) { 41 | return item; 42 | } 43 | } 44 | } 45 | return defaultItem; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/route/ExecutorRouter.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.route; 2 | 3 | import com.xxl.job.core.biz.model.ReturnT; 4 | import com.xxl.job.core.biz.model.TriggerParam; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Created by xuxueli on 17/3/10. 12 | */ 13 | public abstract class ExecutorRouter { 14 | protected static Logger logger = LoggerFactory.getLogger(ExecutorRouter.class); 15 | 16 | /** 17 | * route address 18 | * 19 | * @param addressList 20 | * @return ReturnT.content=address 21 | */ 22 | public abstract ReturnT route(TriggerParam triggerParam, List addressList); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/route/strategy/ExecutorRouteBusyover.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.route.strategy; 2 | 3 | import com.lt.job.admin.core.scheduler.XxlJobScheduler; 4 | import com.lt.job.admin.core.route.ExecutorRouter; 5 | import com.lt.job.admin.core.util.I18nUtil; 6 | import com.xxl.job.core.biz.ExecutorBiz; 7 | import com.xxl.job.core.biz.model.IdleBeatParam; 8 | import com.xxl.job.core.biz.model.ReturnT; 9 | import com.xxl.job.core.biz.model.TriggerParam; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * Created by xuxueli on 17/3/10. 15 | */ 16 | public class ExecutorRouteBusyover extends ExecutorRouter { 17 | 18 | @Override 19 | public ReturnT route(TriggerParam triggerParam, List addressList) { 20 | StringBuffer idleBeatResultSB = new StringBuffer(); 21 | for (String address : addressList) { 22 | // beat 23 | ReturnT idleBeatResult = null; 24 | try { 25 | ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(address); 26 | idleBeatResult = executorBiz.idleBeat(new IdleBeatParam(triggerParam.getJobId())); 27 | } catch (Exception e) { 28 | logger.error(e.getMessage(), e); 29 | idleBeatResult = new ReturnT(ReturnT.FAIL_CODE, ""+e ); 30 | } 31 | idleBeatResultSB.append( (idleBeatResultSB.length()>0)?"

":"") 32 | .append(I18nUtil.getString("jobconf_idleBeat") + ":") 33 | .append("
address:").append(address) 34 | .append("
code:").append(idleBeatResult.getCode()) 35 | .append("
msg:").append(idleBeatResult.getMsg()); 36 | 37 | // beat success 38 | if (idleBeatResult.getCode() == ReturnT.SUCCESS_CODE) { 39 | idleBeatResult.setMsg(idleBeatResultSB.toString()); 40 | idleBeatResult.setContent(address); 41 | return idleBeatResult; 42 | } 43 | } 44 | 45 | return new ReturnT(ReturnT.FAIL_CODE, idleBeatResultSB.toString()); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/route/strategy/ExecutorRouteFailover.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.route.strategy; 2 | 3 | import com.lt.job.admin.core.scheduler.XxlJobScheduler; 4 | import com.lt.job.admin.core.route.ExecutorRouter; 5 | import com.lt.job.admin.core.util.I18nUtil; 6 | import com.xxl.job.core.biz.ExecutorBiz; 7 | import com.xxl.job.core.biz.model.ReturnT; 8 | import com.xxl.job.core.biz.model.TriggerParam; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * Created by xuxueli on 17/3/10. 14 | */ 15 | public class ExecutorRouteFailover extends ExecutorRouter { 16 | 17 | @Override 18 | public ReturnT route(TriggerParam triggerParam, List addressList) { 19 | 20 | StringBuffer beatResultSB = new StringBuffer(); 21 | for (String address : addressList) { 22 | // beat 23 | ReturnT beatResult = null; 24 | try { 25 | ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(address); 26 | beatResult = executorBiz.beat(); 27 | } catch (Exception e) { 28 | logger.error(e.getMessage(), e); 29 | beatResult = new ReturnT(ReturnT.FAIL_CODE, ""+e ); 30 | } 31 | beatResultSB.append( (beatResultSB.length()>0)?"

":"") 32 | .append(I18nUtil.getString("jobconf_beat") + ":") 33 | .append("
address:").append(address) 34 | .append("
code:").append(beatResult.getCode()) 35 | .append("
msg:").append(beatResult.getMsg()); 36 | 37 | // beat success 38 | if (beatResult.getCode() == ReturnT.SUCCESS_CODE) { 39 | 40 | beatResult.setMsg(beatResultSB.toString()); 41 | beatResult.setContent(address); 42 | return beatResult; 43 | } 44 | } 45 | return new ReturnT(ReturnT.FAIL_CODE, beatResultSB.toString()); 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/route/strategy/ExecutorRouteFirst.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.route.strategy; 2 | 3 | import com.lt.job.admin.core.route.ExecutorRouter; 4 | import com.xxl.job.core.biz.model.ReturnT; 5 | import com.xxl.job.core.biz.model.TriggerParam; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created by xuxueli on 17/3/10. 11 | */ 12 | public class ExecutorRouteFirst extends ExecutorRouter { 13 | 14 | @Override 15 | public ReturnT route(TriggerParam triggerParam, List addressList){ 16 | return new ReturnT(addressList.get(0)); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/route/strategy/ExecutorRouteLast.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.route.strategy; 2 | 3 | import com.lt.job.admin.core.route.ExecutorRouter; 4 | import com.xxl.job.core.biz.model.ReturnT; 5 | import com.xxl.job.core.biz.model.TriggerParam; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created by xuxueli on 17/3/10. 11 | */ 12 | public class ExecutorRouteLast extends ExecutorRouter { 13 | 14 | @Override 15 | public ReturnT route(TriggerParam triggerParam, List addressList) { 16 | return new ReturnT(addressList.get(addressList.size()-1)); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/route/strategy/ExecutorRouteRandom.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.route.strategy; 2 | 3 | import com.lt.job.admin.core.route.ExecutorRouter; 4 | import com.xxl.job.core.biz.model.ReturnT; 5 | import com.xxl.job.core.biz.model.TriggerParam; 6 | 7 | import java.util.List; 8 | import java.util.Random; 9 | 10 | /** 11 | * Created by xuxueli on 17/3/10. 12 | */ 13 | public class ExecutorRouteRandom extends ExecutorRouter { 14 | 15 | private static Random localRandom = new Random(); 16 | 17 | @Override 18 | public ReturnT route(TriggerParam triggerParam, List addressList) { 19 | String address = addressList.get(localRandom.nextInt(addressList.size())); 20 | return new ReturnT(address); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/route/strategy/ExecutorRouteRound.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.route.strategy; 2 | 3 | import com.lt.job.admin.core.route.ExecutorRouter; 4 | import com.xxl.job.core.biz.model.ReturnT; 5 | import com.xxl.job.core.biz.model.TriggerParam; 6 | 7 | import java.util.List; 8 | import java.util.Random; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | import java.util.concurrent.ConcurrentMap; 11 | import java.util.concurrent.atomic.AtomicInteger; 12 | 13 | /** 14 | * Created by xuxueli on 17/3/10. 15 | */ 16 | public class ExecutorRouteRound extends ExecutorRouter { 17 | 18 | private static ConcurrentMap routeCountEachJob = new ConcurrentHashMap<>(); 19 | private static long CACHE_VALID_TIME = 0; 20 | 21 | private static int count(int jobId) { 22 | // cache clear 23 | if (System.currentTimeMillis() > CACHE_VALID_TIME) { 24 | routeCountEachJob.clear(); 25 | CACHE_VALID_TIME = System.currentTimeMillis() + 1000*60*60*24; 26 | } 27 | 28 | AtomicInteger count = routeCountEachJob.get(jobId); 29 | if (count == null || count.get() > 1000000) { 30 | // 初始化时主动Random一次,缓解首次压力 31 | count = new AtomicInteger(new Random().nextInt(100)); 32 | } else { 33 | // count++ 34 | count.addAndGet(1); 35 | } 36 | routeCountEachJob.put(jobId, count); 37 | return count.get(); 38 | } 39 | 40 | @Override 41 | public ReturnT route(TriggerParam triggerParam, List addressList) { 42 | String address = addressList.get(count(triggerParam.getJobId())%addressList.size()); 43 | return new ReturnT(address); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/scheduler/MisfireStrategyEnum.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.scheduler; 2 | 3 | import com.lt.job.admin.core.util.I18nUtil; 4 | 5 | /** 6 | * @author xuxueli 2020-10-29 21:11:23 7 | */ 8 | public enum MisfireStrategyEnum { 9 | 10 | /** 11 | * do nothing 12 | */ 13 | DO_NOTHING(I18nUtil.getString("misfire_strategy_do_nothing")), 14 | 15 | /** 16 | * fire once now 17 | */ 18 | FIRE_ONCE_NOW(I18nUtil.getString("misfire_strategy_fire_once_now")); 19 | 20 | private String title; 21 | 22 | MisfireStrategyEnum(String title) { 23 | this.title = title; 24 | } 25 | 26 | public String getTitle() { 27 | return title; 28 | } 29 | 30 | public static MisfireStrategyEnum match(String name, MisfireStrategyEnum defaultItem){ 31 | for (MisfireStrategyEnum item: MisfireStrategyEnum.values()) { 32 | if (item.name().equals(name)) { 33 | return item; 34 | } 35 | } 36 | return defaultItem; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/scheduler/ScheduleTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.scheduler; 2 | 3 | import com.lt.job.admin.core.util.I18nUtil; 4 | 5 | /** 6 | * @author xuxueli 2020-10-29 21:11:23 7 | */ 8 | public enum ScheduleTypeEnum { 9 | 10 | NONE(I18nUtil.getString("schedule_type_none")), 11 | 12 | /** 13 | * schedule by cron 14 | */ 15 | CRON(I18nUtil.getString("schedule_type_cron")), 16 | 17 | /** 18 | * schedule by fixed rate (in seconds) 19 | */ 20 | FIX_RATE(I18nUtil.getString("schedule_type_fix_rate")), 21 | 22 | /** 23 | * schedule by fix delay (in seconds), after the last time 24 | */ 25 | /*FIX_DELAY(I18nUtil.getString("schedule_type_fix_delay"))*/; 26 | 27 | private String title; 28 | 29 | ScheduleTypeEnum(String title) { 30 | this.title = title; 31 | } 32 | 33 | public String getTitle() { 34 | return title; 35 | } 36 | 37 | public static ScheduleTypeEnum match(String name, ScheduleTypeEnum defaultItem){ 38 | for (ScheduleTypeEnum item: ScheduleTypeEnum.values()) { 39 | if (item.name().equals(name)) { 40 | return item; 41 | } 42 | } 43 | return defaultItem; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/trigger/TriggerTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.trigger; 2 | 3 | import com.lt.job.admin.core.util.I18nUtil; 4 | 5 | /** 6 | * trigger type enum 7 | * 8 | * @author xuxueli 2018-09-16 04:56:41 9 | */ 10 | public enum TriggerTypeEnum { 11 | 12 | MANUAL(I18nUtil.getString("jobconf_trigger_type_manual")), 13 | CRON(I18nUtil.getString("jobconf_trigger_type_cron")), 14 | RETRY(I18nUtil.getString("jobconf_trigger_type_retry")), 15 | PARENT(I18nUtil.getString("jobconf_trigger_type_parent")), 16 | API(I18nUtil.getString("jobconf_trigger_type_api")), 17 | MISFIRE(I18nUtil.getString("jobconf_trigger_type_misfire")); 18 | 19 | private TriggerTypeEnum(String title){ 20 | this.title = title; 21 | } 22 | private String title; 23 | public String getTitle() { 24 | return title; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/core/util/FtlUtil.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.core.util; 2 | 3 | import freemarker.ext.beans.BeansWrapper; 4 | import freemarker.ext.beans.BeansWrapperBuilder; 5 | import freemarker.template.Configuration; 6 | import freemarker.template.TemplateHashModel; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | /** 11 | * ftl util 12 | * 13 | * @author xuxueli 2018-01-17 20:37:48 14 | */ 15 | public class FtlUtil { 16 | private static Logger logger = LoggerFactory.getLogger(FtlUtil.class); 17 | 18 | private static BeansWrapper wrapper = new BeansWrapperBuilder(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS).build(); //BeansWrapper.getDefaultInstance(); 19 | 20 | public static TemplateHashModel generateStaticModel(String packageName) { 21 | try { 22 | TemplateHashModel staticModels = wrapper.getStaticModels(); 23 | TemplateHashModel fileStatics = (TemplateHashModel) staticModels.get(packageName); 24 | return fileStatics; 25 | } catch (Exception e) { 26 | logger.error(e.getMessage(), e); 27 | } 28 | return null; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/dao/XxlJobGroupDao.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.dao; 2 | 3 | import com.lt.job.admin.core.model.XxlJobGroup; 4 | import org.apache.ibatis.annotations.Mapper; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | 10 | @Mapper 11 | public interface XxlJobGroupDao { 12 | 13 | public List findAll(); 14 | 15 | public List findByAddressType(@Param("addressType") int addressType); 16 | 17 | public int save(XxlJobGroup xxlJobGroup); 18 | 19 | public int update(XxlJobGroup xxlJobGroup); 20 | 21 | public int remove(@Param("id") int id); 22 | 23 | public XxlJobGroup load(@Param("id") int id); 24 | 25 | public List pageList(@Param("offset") int offset, 26 | @Param("pagesize") int pagesize, 27 | @Param("appname") String appname, 28 | @Param("title") String title); 29 | 30 | public int pageListCount(@Param("offset") int offset, 31 | @Param("pagesize") int pagesize, 32 | @Param("appname") String appname, 33 | @Param("title") String title); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/dao/XxlJobInfoDao.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.dao; 2 | 3 | import com.lt.job.admin.core.model.XxlJobInfo; 4 | import org.apache.ibatis.annotations.Mapper; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | 10 | @Mapper 11 | public interface XxlJobInfoDao { 12 | 13 | public List pageList(@Param("offset") int offset, 14 | @Param("pagesize") int pagesize, 15 | @Param("jobGroup") int jobGroup, 16 | @Param("triggerStatus") int triggerStatus, 17 | @Param("jobDesc") String jobDesc, 18 | @Param("executorHandler") String executorHandler, 19 | @Param("author") String author); 20 | 21 | public int pageListCount(@Param("offset") int offset, 22 | @Param("pagesize") int pagesize, 23 | @Param("jobGroup") int jobGroup, 24 | @Param("triggerStatus") int triggerStatus, 25 | @Param("jobDesc") String jobDesc, 26 | @Param("executorHandler") String executorHandler, 27 | @Param("author") String author); 28 | 29 | public int save(XxlJobInfo info); 30 | 31 | public XxlJobInfo loadById(@Param("id") int id); 32 | 33 | public int update(XxlJobInfo xxlJobInfo); 34 | 35 | public int delete(@Param("id") long id); 36 | 37 | public List getJobsByGroup(@Param("jobGroup") int jobGroup); 38 | 39 | public int findAllCount(); 40 | 41 | public List scheduleJobQuery(@Param("maxNextTime") long maxNextTime, @Param("pagesize") int pagesize); 42 | 43 | public int scheduleUpdate(XxlJobInfo xxlJobInfo); 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/dao/XxlJobLogGlueDao.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.dao; 2 | 3 | import com.lt.job.admin.core.model.XxlJobLogGlue; 4 | import org.apache.ibatis.annotations.Mapper; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | 10 | @Mapper 11 | public interface XxlJobLogGlueDao { 12 | 13 | public int save(XxlJobLogGlue xxlJobLogGlue); 14 | 15 | public List findByJobId(@Param("jobId") int jobId); 16 | 17 | public int removeOld(@Param("jobId") int jobId, @Param("limit") int limit); 18 | 19 | public int deleteByJobId(@Param("jobId") int jobId); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/dao/XxlJobLogReportDao.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.dao; 2 | 3 | import com.lt.job.admin.core.model.XxlJobLogReport; 4 | import org.apache.ibatis.annotations.Mapper; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.Date; 8 | import java.util.List; 9 | 10 | 11 | @Mapper 12 | public interface XxlJobLogReportDao { 13 | 14 | public int save(XxlJobLogReport xxlJobLogReport); 15 | 16 | public int update(XxlJobLogReport xxlJobLogReport); 17 | 18 | public List queryLogReport(@Param("triggerDayFrom") Date triggerDayFrom, 19 | @Param("triggerDayTo") Date triggerDayTo); 20 | 21 | public XxlJobLogReport queryLogReportTotal(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/dao/XxlJobRegistryDao.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.dao; 2 | 3 | import com.lt.job.admin.core.model.XxlJobRegistry; 4 | import org.apache.ibatis.annotations.Mapper; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.Date; 8 | import java.util.List; 9 | 10 | 11 | @Mapper 12 | public interface XxlJobRegistryDao { 13 | 14 | public List findDead(@Param("timeout") int timeout, 15 | @Param("nowTime") Date nowTime); 16 | 17 | public int removeDead(@Param("ids") List ids); 18 | 19 | public List findAll(@Param("timeout") int timeout, 20 | @Param("nowTime") Date nowTime); 21 | 22 | public int registryUpdate(@Param("registryGroup") String registryGroup, 23 | @Param("registryKey") String registryKey, 24 | @Param("registryValue") String registryValue, 25 | @Param("updateTime") Date updateTime); 26 | 27 | public int registrySave(@Param("registryGroup") String registryGroup, 28 | @Param("registryKey") String registryKey, 29 | @Param("registryValue") String registryValue, 30 | @Param("updateTime") Date updateTime); 31 | 32 | public int registryDelete(@Param("registryGroup") String registryGroup, 33 | @Param("registryKey") String registryKey, 34 | @Param("registryValue") String registryValue); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/dao/XxlJobUserDao.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.dao; 2 | 3 | import com.lt.job.admin.core.model.XxlJobUser; 4 | import org.apache.ibatis.annotations.Mapper; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | 10 | @Mapper 11 | public interface XxlJobUserDao { 12 | 13 | public List pageList(@Param("offset") int offset, 14 | @Param("pagesize") int pagesize, 15 | @Param("username") String username, 16 | @Param("role") int role); 17 | 18 | public int pageListCount(@Param("offset") int offset, 19 | @Param("pagesize") int pagesize, 20 | @Param("username") String username, 21 | @Param("role") int role); 22 | 23 | public XxlJobUser loadByUserName(@Param("username") String username); 24 | 25 | public int save(XxlJobUser xxlJobUser); 26 | 27 | public int update(XxlJobUser xxlJobUser); 28 | 29 | public int delete(@Param("id") int id); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/service/XxlJobService.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.service; 2 | 3 | 4 | import com.lt.job.admin.core.model.XxlJobInfo; 5 | import com.xxl.job.core.biz.model.ReturnT; 6 | 7 | import java.util.Date; 8 | import java.util.Map; 9 | 10 | 11 | public interface XxlJobService { 12 | 13 | /** 14 | * page list 15 | * 16 | * @param start 17 | * @param length 18 | * @param jobGroup 19 | * @param jobDesc 20 | * @param executorHandler 21 | * @param author 22 | * @return 23 | */ 24 | public Map pageList(int start, int length, int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author); 25 | 26 | /** 27 | * add job 28 | * 29 | * @param jobInfo 30 | * @return 31 | */ 32 | public ReturnT add(XxlJobInfo jobInfo); 33 | 34 | /** 35 | * update job 36 | * 37 | * @param jobInfo 38 | * @return 39 | */ 40 | public ReturnT update(XxlJobInfo jobInfo); 41 | 42 | /** 43 | * remove job 44 | * * 45 | * 46 | * @param id 47 | * @return 48 | */ 49 | public ReturnT remove(int id); 50 | 51 | /** 52 | * start job 53 | * 54 | * @param id 55 | * @return 56 | */ 57 | public ReturnT start(int id); 58 | 59 | /** 60 | * stop job 61 | * 62 | * @param id 63 | * @return 64 | */ 65 | public ReturnT stop(int id); 66 | 67 | /** 68 | * dashboard info 69 | * 70 | * @return 71 | */ 72 | public Map dashboardInfo(); 73 | 74 | /** 75 | * chart info 76 | * 77 | * @param startDate 78 | * @param endDate 79 | * @return 80 | */ 81 | public ReturnT> chartInfo(Date startDate, Date endDate); 82 | 83 | } 84 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/java/com/lt/job/admin/service/impl/AdminBizImpl.java: -------------------------------------------------------------------------------- 1 | package com.lt.job.admin.service.impl; 2 | 3 | import com.lt.job.admin.core.thread.JobCompleteHelper; 4 | import com.lt.job.admin.core.thread.JobRegistryHelper; 5 | import com.xxl.job.core.biz.AdminBiz; 6 | import com.xxl.job.core.biz.model.HandleCallbackParam; 7 | import com.xxl.job.core.biz.model.RegistryParam; 8 | import com.xxl.job.core.biz.model.ReturnT; 9 | import org.springframework.stereotype.Service; 10 | 11 | import java.util.List; 12 | 13 | 14 | @Service 15 | public class AdminBizImpl implements AdminBiz { 16 | 17 | 18 | @Override 19 | public ReturnT callback(List callbackParamList) { 20 | return JobCompleteHelper.getInstance().callback(callbackParamList); 21 | } 22 | 23 | @Override 24 | public ReturnT registry(RegistryParam registryParam) { 25 | return JobRegistryHelper.getInstance().registry(registryParam); 26 | } 27 | 28 | @Override 29 | public ReturnT registryRemove(RegistryParam registryParam) { 30 | return JobRegistryHelper.getInstance().registryRemove(registryParam); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | logback 5 | 6 | 7 | 8 | 9 | %d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n 10 | 11 | 12 | 13 | 14 | ${log.path} 15 | 16 | ${log.path}.%d{yyyy-MM-dd}.zip 17 | 18 | 19 | %date %level [%thread] %logger{36} [%file : %line] %msg%n 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/mybatis-mapper/XxlJobLogGlueMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | t.id, 18 | t.job_id, 19 | t.glue_type, 20 | t.glue_source, 21 | t.glue_remark, 22 | t.add_time, 23 | t.update_time 24 | 25 | 26 | 27 | INSERT INTO xxl_job_logglue ( 28 | `job_id`, 29 | `glue_type`, 30 | `glue_source`, 31 | `glue_remark`, 32 | `add_time`, 33 | `update_time` 34 | ) VALUES ( 35 | #{jobId}, 36 | #{glueType}, 37 | #{glueSource}, 38 | #{glueRemark}, 39 | #{addTime}, 40 | #{updateTime} 41 | ); 42 | 45 | 46 | 47 | 53 | 54 | 55 | DELETE FROM xxl_job_logglue 56 | WHERE id NOT in( 57 | SELECT id FROM( 58 | SELECT id FROM xxl_job_logglue 59 | WHERE `job_id` = #{jobId} 60 | ORDER BY update_time desc 61 | LIMIT 0, #{limit} 62 | ) t1 63 | ) AND `job_id` = #{jobId} 64 | 65 | 66 | 67 | DELETE FROM xxl_job_logglue 68 | WHERE `job_id` = #{jobId} 69 | 70 | 71 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/mybatis-mapper/XxlJobLogReportMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | t.id, 16 | t.trigger_day, 17 | t.running_count, 18 | t.suc_count, 19 | t.fail_count 20 | 21 | 22 | 23 | INSERT INTO xxl_job_log_report ( 24 | `trigger_day`, 25 | `running_count`, 26 | `suc_count`, 27 | `fail_count` 28 | ) VALUES ( 29 | #{triggerDay}, 30 | #{runningCount}, 31 | #{sucCount}, 32 | #{failCount} 33 | ); 34 | 37 | 38 | 39 | 40 | UPDATE xxl_job_log_report 41 | SET `running_count` = #{runningCount}, 42 | `suc_count` = #{sucCount}, 43 | `fail_count` = #{failCount} 44 | WHERE `trigger_day` = #{triggerDay} 45 | 46 | 47 | 53 | 54 | 61 | 62 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/mybatis-mapper/XxlJobRegistryMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | t.id, 16 | t.registry_group, 17 | t.registry_key, 18 | t.registry_value, 19 | t.update_time 20 | 21 | 22 | 27 | 28 | 29 | DELETE FROM xxl_job_registry 30 | WHERE id in 31 | 32 | #{item} 33 | 34 | 35 | 36 | 41 | 42 | 43 | UPDATE xxl_job_registry 44 | SET `update_time` = #{updateTime} 45 | WHERE `registry_group` = #{registryGroup} 46 | AND `registry_key` = #{registryKey} 47 | AND `registry_value` = #{registryValue} 48 | 49 | 50 | 51 | INSERT INTO xxl_job_registry( `registry_group` , `registry_key` , `registry_value`, `update_time`) 52 | VALUES( #{registryGroup} , #{registryKey} , #{registryValue}, #{updateTime}) 53 | 54 | 55 | 56 | DELETE FROM xxl_job_registry 57 | WHERE registry_group = #{registryGroup} 58 | AND registry_key = #{registryKey} 59 | AND registry_value = #{registryValue} 60 | 61 | 62 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/static/adminlte/plugins/iCheck/square/blue.css: -------------------------------------------------------------------------------- 1 | /* iCheck plugin Square skin, blue 2 | ----------------------------------- */ 3 | .icheckbox_square-blue, 4 | .iradio_square-blue { 5 | display: inline-block; 6 | *display: inline; 7 | vertical-align: middle; 8 | margin: 0; 9 | padding: 0; 10 | width: 22px; 11 | height: 22px; 12 | background: url(blue.png) no-repeat; 13 | border: none; 14 | cursor: pointer; 15 | } 16 | 17 | .icheckbox_square-blue { 18 | background-position: 0 0; 19 | } 20 | .icheckbox_square-blue.hover { 21 | background-position: -24px 0; 22 | } 23 | .icheckbox_square-blue.checked { 24 | background-position: -48px 0; 25 | } 26 | .icheckbox_square-blue.disabled { 27 | background-position: -72px 0; 28 | cursor: default; 29 | } 30 | .icheckbox_square-blue.checked.disabled { 31 | background-position: -96px 0; 32 | } 33 | 34 | .iradio_square-blue { 35 | background-position: -120px 0; 36 | } 37 | .iradio_square-blue.hover { 38 | background-position: -144px 0; 39 | } 40 | .iradio_square-blue.checked { 41 | background-position: -168px 0; 42 | } 43 | .iradio_square-blue.disabled { 44 | background-position: -192px 0; 45 | cursor: default; 46 | } 47 | .iradio_square-blue.checked.disabled { 48 | background-position: -216px 0; 49 | } 50 | 51 | /* Retina support */ 52 | @media only screen and (-webkit-min-device-pixel-ratio: 1.5), 53 | only screen and (-moz-min-device-pixel-ratio: 1.5), 54 | only screen and (-o-min-device-pixel-ratio: 3/2), 55 | only screen and (min-device-pixel-ratio: 1.5) { 56 | .icheckbox_square-blue, 57 | .iradio_square-blue { 58 | background-image: url(blue@2x.png); 59 | -webkit-background-size: 240px 24px; 60 | background-size: 240px 24px; 61 | } 62 | } -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/static/adminlte/plugins/iCheck/square/blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_xxljob_admin/src/main/resources/static/adminlte/plugins/iCheck/square/blue.png -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/static/adminlte/plugins/iCheck/square/blue@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_xxljob_admin/src/main/resources/static/adminlte/plugins/iCheck/square/blue@2x.png -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_xxljob_admin/src/main/resources/static/favicon.ico -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/static/js/login.1.js: -------------------------------------------------------------------------------- 1 | $(function(){ 2 | 3 | // input iCheck 4 | $('input').iCheck({ 5 | checkboxClass: 'icheckbox_square-blue', 6 | radioClass: 'iradio_square-blue', 7 | increaseArea: '20%' // optional 8 | }); 9 | 10 | // login Form Valid 11 | var loginFormValid = $("#loginForm").validate({ 12 | errorElement : 'span', 13 | errorClass : 'help-block', 14 | focusInvalid : true, 15 | rules : { 16 | userName : { 17 | required : true , 18 | minlength: 4, 19 | maxlength: 18 20 | }, 21 | password : { 22 | required : true , 23 | minlength: 4, 24 | maxlength: 18 25 | } 26 | }, 27 | messages : { 28 | userName : { 29 | required : I18n.login_username_empty, 30 | minlength : I18n.login_username_lt_4 31 | }, 32 | password : { 33 | required : I18n.login_password_empty , 34 | minlength : I18n.login_password_lt_4 35 | /*,maxlength:"登录密码不应超过18位"*/ 36 | } 37 | }, 38 | highlight : function(element) { 39 | $(element).closest('.form-group').addClass('has-error'); 40 | }, 41 | success : function(label) { 42 | label.closest('.form-group').removeClass('has-error'); 43 | label.remove(); 44 | }, 45 | errorPlacement : function(error, element) { 46 | element.parent('div').append(error); 47 | }, 48 | submitHandler : function(form) { 49 | $.post(base_url + "/login", $("#loginForm").serialize(), function(data, status) { 50 | if (data.code == "200") { 51 | layer.msg( I18n.login_success ); 52 | setTimeout(function(){ 53 | window.location.href = base_url + "/"; 54 | }, 500); 55 | } else { 56 | layer.open({ 57 | title: I18n.system_tips, 58 | btn: [ I18n.system_ok ], 59 | content: (data.msg || I18n.login_fail ), 60 | icon: '2' 61 | }); 62 | } 63 | }); 64 | } 65 | }); 66 | }); -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/static/plugins/codemirror/addon/hint/anyword-hint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | var WORD = /[\w$]+/, RANGE = 500; 15 | 16 | CodeMirror.registerHelper("hint", "anyword", function(editor, options) { 17 | var word = options && options.word || WORD; 18 | var range = options && options.range || RANGE; 19 | var cur = editor.getCursor(), curLine = editor.getLine(cur.line); 20 | var end = cur.ch, start = end; 21 | while (start && word.test(curLine.charAt(start - 1))) --start; 22 | var curWord = start != end && curLine.slice(start, end); 23 | 24 | var list = options && options.list || [], seen = {}; 25 | var re = new RegExp(word.source, "g"); 26 | for (var dir = -1; dir <= 1; dir += 2) { 27 | var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir; 28 | for (; line != endLine; line += dir) { 29 | var text = editor.getLine(line), m; 30 | while (m = re.exec(text)) { 31 | if (line == cur.line && m[0] === curWord) continue; 32 | if ((!curWord || m[0].lastIndexOf(curWord, 0) == 0) && !Object.prototype.hasOwnProperty.call(seen, m[0])) { 33 | seen[m[0]] = true; 34 | list.push(m[0]); 35 | } 36 | } 37 | } 38 | } 39 | return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)}; 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/static/plugins/codemirror/addon/hint/show-hint.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-hints { 2 | position: absolute; 3 | z-index: 10; 4 | overflow: hidden; 5 | list-style: none; 6 | 7 | margin: 0; 8 | padding: 2px; 9 | 10 | -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 11 | -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 12 | box-shadow: 2px 3px 5px rgba(0,0,0,.2); 13 | border-radius: 3px; 14 | border: 1px solid silver; 15 | 16 | background: white; 17 | font-size: 90%; 18 | font-family: monospace; 19 | 20 | max-height: 20em; 21 | overflow-y: auto; 22 | } 23 | 24 | .CodeMirror-hint { 25 | margin: 0; 26 | padding: 0 4px; 27 | border-radius: 2px; 28 | white-space: pre; 29 | color: black; 30 | cursor: pointer; 31 | } 32 | 33 | li.CodeMirror-hint-active { 34 | background: #08f; 35 | color: white; 36 | } 37 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/static/plugins/layer/theme/default/icon-ext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_xxljob_admin/src/main/resources/static/plugins/layer/theme/default/icon-ext.png -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/static/plugins/layer/theme/default/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_xxljob_admin/src/main/resources/static/plugins/layer/theme/default/icon.png -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/static/plugins/layer/theme/default/loading-0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_xxljob_admin/src/main/resources/static/plugins/layer/theme/default/loading-0.gif -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/static/plugins/layer/theme/default/loading-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_xxljob_admin/src/main/resources/static/plugins/layer/theme/default/loading-1.gif -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/static/plugins/layer/theme/default/loading-2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeTeng/stockIndex/272852b6467446024ab0c7ae09e47a0d6d6bd8c4/stock_xxljob_admin/src/main/resources/static/plugins/layer/theme/default/loading-2.gif -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/templates/common/common.exception.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Error 6 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |

System Error

25 |

${exceptionMsg}

26 | Back 27 |

28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/templates/help.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <#import "./common/common.macro.ftl" as netCommon> 5 | <@netCommon.commonStyle /> 6 | ${I18n.admin_name} 7 | 8 | sidebar-collapse "> 9 |
10 | 11 | <@netCommon.commonHeader /> 12 | 13 | <@netCommon.commonLeft "help" /> 14 | 15 | 16 |
17 | 18 |
19 |

${I18n.job_help}

20 |
21 | 22 | 23 |
24 |
25 |

${I18n.admin_name_full}

26 |
27 |

28 | Github     29 | 30 |

31 | ${I18n.job_help_document} 32 |

33 | 34 |

35 |

36 |
37 |
38 | 39 |
40 | 41 | 42 | 43 | <@netCommon.commonFooter /> 44 |
45 | <@netCommon.commonScript /> 46 | 47 | 48 | -------------------------------------------------------------------------------- /stock_xxljob_admin/src/main/resources/templates/login.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <#import "./common/common.macro.ftl" as netCommon> 5 | <@netCommon.commonStyle /> 6 | 7 | ${I18n.admin_name} 8 | 9 | 10 | 40 | <@netCommon.commonScript /> 41 | 42 | 43 | 44 | 45 | 46 | --------------------------------------------------------------------------------