Commit 5ffbf3fd by guangyi.tan

调整readme

parent c60ce285
<h1 align="center">Welcome to spring-microservice-exam 👋</h1> <h1 align="center">Welcome to spring-microservice-exam 👋</h1>
<p> <p>
<img alt="Version" src="https://img.shields.io/badge/version-3.5.0-blue.svg?cacheSeconds=2592000" /> <img alt="Version" src="https://img.shields.io/badge/version-3.6.0-blue.svg?cacheSeconds=2592000" />
<a href="https://www.kancloud.cn/tangyi/spring-microservice-exam/1322864" target="_blank"> <a href="https://www.kancloud.cn/tangyi/spring-microservice-exam/1322864" target="_blank">
<img alt="Documentation" src="https://img.shields.io/badge/documentation-yes-brightgreen.svg" /> <img alt="Documentation" src="https://img.shields.io/badge/documentation-yes-brightgreen.svg" />
</a> </a>
...@@ -104,8 +104,8 @@ ...@@ -104,8 +104,8 @@
<table> <table>
<tr> <tr>
<td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_web_login.png" alt="登录"/></td> <td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_web_login.jpg" alt="登录"/></td>
<td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_web.png" alt="首页"/></td> <td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_web.jpg" alt="首页"/></td>
</tr> </tr>
<tr> <tr>
<td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_web_exams.png" alt="考试列表"/></td> <td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_web_exams.png" alt="考试列表"/></td>
...@@ -121,8 +121,8 @@ ...@@ -121,8 +121,8 @@
<table> <table>
<tr> <tr>
<td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_ui_login.png" alt="登录"/></td> <td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_ui_login.jpg" alt="登录"/></td>
<td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_ui_exam.png" alt="首页"/></td> <td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_ui_exam.jpg" alt="首页"/></td>
</tr> </tr>
<tr> <tr>
<td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_ui_menu.png" alt="菜单"/></td> <td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_ui_menu.png" alt="菜单"/></td>
...@@ -142,7 +142,20 @@ ...@@ -142,7 +142,20 @@
</tr> </tr>
<tr> <tr>
<td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_ui_log_manage.png" alt="日志监控"/></td> <td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_ui_log_manage.png" alt="日志监控"/></td>
<td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_ui_consul.png" alt="服务监控"/></td> <td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_ui_consul.png" alt="consul监控"/></td>
</tr>
</table>
### 系统监控(点击查看大图)
<table>
<tr>
<td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_ui_spring_boot_admin.jpg" alt="服务监控"/></td>
<td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_ui_spring_boot_admin01.jpg" alt="服务监控"/></td>
</tr>
<tr>
<td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_ui_swagger.png" alt="swagger文档"/></td>
<td><img src="https://gitee.com/wells2333/spring-microservice-exam/raw/master/docs/images/image_ui_elk.png" alt="elk日志"/></td>
</tr> </tr>
</table> </table>
...@@ -150,6 +163,8 @@ ...@@ -150,6 +163,8 @@
- [在线考试系统-部署文档](https://www.kancloud.cn/tangyi/spring-microservice-exam/1322870) - [在线考试系统-部署文档](https://www.kancloud.cn/tangyi/spring-microservice-exam/1322870)
- [部署视频教程](https://www.kancloud.cn/tangyi/spring-microservice-exam/1519487)
- [在线考试系统-部署文档(docker版)](https://www.kancloud.cn/tangyi/spring-microservice-exam/1322869) - [在线考试系统-部署文档(docker版)](https://www.kancloud.cn/tangyi/spring-microservice-exam/1322869)
- [在线考试系统-数据库设计](https://www.kancloud.cn/tangyi/spring-microservice-exam/1322868) - [在线考试系统-数据库设计](https://www.kancloud.cn/tangyi/spring-microservice-exam/1322868)
......
...@@ -13,6 +13,6 @@ import java.lang.annotation.*; ...@@ -13,6 +13,6 @@ import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE}) @Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Inherited @Inherited
@PreAuthorize("hasRole(T(com.github.tangyi.common.security.enums.Roles).ROLE_ADMIN) or hasRole(T(com.github.tangyi.common.security.enums.Roles).ROLE_TENANT_ADMIN) or hasRole(T(com.github.tangyi.common.security.enums.Roles).ROLE_TEACHER)") @PreAuthorize("hasRole(T(com.github.tangyi.common.security.enums.Roles).ROLE_ADMIN) or hasRole(T(com.github.tangyi.common.security.enums.Roles).ROLE_TENANT_ADMIN) or hasRole(T(com.github.tangyi.common.security.enums.Roles).ROLE_TEACHER) or hasRole(T(com.github.tangyi.common.security.enums.Roles).ROLE_PREVIEW)")
public @interface AdminTenantTeacherAuthorization { public @interface AdminTenantTeacherAuthorization {
} }
...@@ -27,7 +27,12 @@ public enum Roles implements GrantedAuthority { ...@@ -27,7 +27,12 @@ public enum Roles implements GrantedAuthority {
/** /**
* 老师 * 老师
*/ */
ROLE_TEACHER; ROLE_TEACHER,
/**
* 预览角色
*/
ROLE_PREVIEW;
@Override @Override
public String getAuthority() { public String getAuthority() {
......
...@@ -1301,7 +1301,7 @@ CREATE TABLE `sys_user_auths` ( ...@@ -1301,7 +1301,7 @@ CREATE TABLE `sys_user_auths` (
-- ---------------------------- -- ----------------------------
-- Records of sys_user_auths -- Records of sys_user_auths
-- ---------------------------- -- ----------------------------
INSERT INTO `sys_user_auths` VALUES (596329627606192128, 596078038307966976, 1, 'admin', '$2a$10$6rHs.Z/VLIM.DIfxHonuX.KYsMlOirIu75KBsyhqJsKI8.pN0eYZ2', 'admin', '2019-07-04 13:21:02', 'admin', '2019-07-04 13:21:02', 0, 'EXAM', 'gitee'); INSERT INTO `sys_user_auths` VALUES (596329627606192128, 596078038307966976, 1, 'admin', '$2a$10$mE.iDKH2pUr.vEIYhykpcuOjTnYmtjHrSevgbevfuVTDOf0Z33tL6', 'admin', '2019-07-04 13:21:02', 'admin', '2019-07-04 13:21:02', 0, 'EXAM', 'gitee');
INSERT INTO `sys_user_auths` VALUES (596329627648135168, 596307222997372928, 1, 'student', '$2a$10$czmVw4WF7Qt7RpwDJ4V4W.jkDKheEev63HlIsP31QnWHVOpSJz3au', 'admin', '2019-07-04 13:21:03', 'admin', '2019-07-04 13:21:03', 0, 'EXAM', 'gitee'); INSERT INTO `sys_user_auths` VALUES (596329627648135168, 596307222997372928, 1, 'student', '$2a$10$czmVw4WF7Qt7RpwDJ4V4W.jkDKheEev63HlIsP31QnWHVOpSJz3au', 'admin', '2019-07-04 13:21:03', 'admin', '2019-07-04 13:21:03', 0, 'EXAM', 'gitee');
INSERT INTO `sys_user_auths` VALUES (596332387693105152, 596332387600830464, 1, 'teacher', '$2a$10$4p0VfFRF969ltVakk6Qz9uQyuZXZSRZy4kA2Ur8pgazKQMqpvNAEy', 'admin', '2019-07-04 13:32:01', 'admin', '2019-07-04 13:32:01', 0, 'EXAM', 'gitee'); INSERT INTO `sys_user_auths` VALUES (596332387693105152, 596332387600830464, 1, 'teacher', '$2a$10$4p0VfFRF969ltVakk6Qz9uQyuZXZSRZy4kA2Ur8pgazKQMqpvNAEy', 'admin', '2019-07-04 13:32:01', 'admin', '2019-07-04 13:32:01', 0, 'EXAM', 'gitee');
INSERT INTO `sys_user_auths` VALUES (681167777872089088, 681167776798347264, 1, 'preview', '$2a$10$mE.iDKH2pUr.vEIYhykpcuOjTnYmtjHrSevgbevfuVTDOf0Z33tL6', 'admin', '2020-02-23 15:57:34', 'admin', '2020-02-23 15:57:34', 0, 'EXAM', 'gitee'); INSERT INTO `sys_user_auths` VALUES (681167777872089088, 681167776798347264, 1, 'preview', '$2a$10$mE.iDKH2pUr.vEIYhykpcuOjTnYmtjHrSevgbevfuVTDOf0Z33tL6', 'admin', '2020-02-23 15:57:34', 'admin', '2020-02-23 15:57:34', 0, 'EXAM', 'gitee');
......
...@@ -2,6 +2,8 @@ import request from '@/router/axios' ...@@ -2,6 +2,8 @@ import request from '@/router/axios'
const baseRouteUrl = '/api/route/v1/route/' const baseRouteUrl = '/api/route/v1/route/'
const previewSwitchUrl = '/api/preview/'
export function routeList () { export function routeList () {
return request({ return request({
url: baseRouteUrl + 'routeList', url: baseRouteUrl + 'routeList',
...@@ -61,3 +63,18 @@ export function refresh () { ...@@ -61,3 +63,18 @@ export function refresh () {
method: 'get' method: 'get'
}) })
} }
export function previewSwitch (query) {
return request({
url: previewSwitchUrl + 'enable',
method: 'get',
params: query
})
}
export function getPreviewSwitch () {
return request({
url: previewSwitchUrl + 'getPreview',
method: 'get'
})
}
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
:default-sort="{ prop: 'id', order: 'descending' }" :default-sort="{ prop: 'id', order: 'descending' }"
highlight-current-row highlight-current-row
style="width: 100%;" style="width: 100%;"
@row-dblclick="handleUpdate"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
@sort-change="sortChange"> @sort-change="sortChange">
<el-table-column type="selection" width="55"/> <el-table-column type="selection" width="55"/>
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
:default-sort="{ prop: 'id', order: 'descending' }" :default-sort="{ prop: 'id', order: 'descending' }"
highlight-current-row highlight-current-row
style="width: 100%;" style="width: 100%;"
@cell-dblclick="handleUpdate"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
@sort-change="sortChange"> @sort-change="sortChange">
<el-table-column type="selection" width="55"/> <el-table-column type="selection" width="55"/>
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
highlight-current-row highlight-current-row
style="width: 100%;" style="width: 100%;"
@selection-change="handleSubjectSelectionChange" @selection-change="handleSubjectSelectionChange"
@cell-dblclick="handleUpdateSubject"
@sort-change="sortSubjectChange"> @sort-change="sortSubjectChange">
<el-table-column type="selection" width="55"/> <el-table-column type="selection" width="55"/>
<el-table-column :label="$t('table.subjectName')" min-width="120"> <el-table-column :label="$t('table.subjectName')" min-width="120">
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
:default-sort="{ prop: 'id', order: 'descending' }" :default-sort="{ prop: 'id', order: 'descending' }"
highlight-current-row highlight-current-row
style="width: 100%;" style="width: 100%;"
@row-dblclick="handleUpdate"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
@sort-change="sortChange"> @sort-change="sortChange">
<el-table-column type="selection" width="55"/> <el-table-column type="selection" width="55"/>
......
...@@ -46,7 +46,6 @@ ...@@ -46,7 +46,6 @@
:data="list" :data="list"
highlight-current-row highlight-current-row
style="width: 100%;" style="width: 100%;"
@cell-dblclick="handleUpdateSubject"
@selection-change="handleSubjectSelectionChange" @selection-change="handleSubjectSelectionChange"
@sort-change="sortSubjectChange"> @sort-change="sortSubjectChange">
<el-table-column type="selection" width="55"/> <el-table-column type="selection" width="55"/>
......
...@@ -6,6 +6,17 @@ ...@@ -6,6 +6,17 @@
<div class="right-menu"> <div class="right-menu">
<template v-if="device!=='mobile'"> <template v-if="device!=='mobile'">
<div v-if="userInfo.identifier === 'admin'" class="preview-switch animated fadeIn">
<el-switch
v-model="previewSwitch"
active-text="开"
inactive-text="关"
active-color="#13ce66"
inactive-color="#ff4949"
@change="handlePreviewSwitch">
</el-switch>
</div>
<a class="animated fadeIn hi">{{ tip }},{{ userInfo.name }}</a> <a class="animated fadeIn hi">{{ tip }},{{ userInfo.name }}</a>
<el-tooltip :content="$t('navbar.lock')" effect="dark" placement="bottom"> <el-tooltip :content="$t('navbar.lock')" effect="dark" placement="bottom">
...@@ -59,6 +70,8 @@ import SizeSelect from '@/components/SizeSelect' ...@@ -59,6 +70,8 @@ import SizeSelect from '@/components/SizeSelect'
import LangSelect from '@/components/LangSelect' import LangSelect from '@/components/LangSelect'
import ThemePicker from '@/components/ThemePicker' import ThemePicker from '@/components/ThemePicker'
import Lock from '@/components/Lock' import Lock from '@/components/Lock'
import { messageSuccess, messageFail } from '@/utils/util'
import { previewSwitch, getPreviewSwitch } from '@/api/admin/route'
export default { export default {
components: { components: {
...@@ -73,12 +86,14 @@ export default { ...@@ -73,12 +86,14 @@ export default {
data () { data () {
return { return {
avatarUrl: '', avatarUrl: '',
tip: '' tip: '',
previewSwitch: true
} }
}, },
created () { created () {
this.userInfo.sex = parseInt(this.userInfo.sex) this.userInfo.sex = parseInt(this.userInfo.sex)
this.getTip() this.getTip()
this.getPreviewSwitch()
}, },
computed: { computed: {
...mapGetters([ ...mapGetters([
...@@ -110,6 +125,30 @@ export default { ...@@ -110,6 +125,30 @@ export default {
} else { } else {
self.tip = '晚上好' self.tip = '晚上好'
} }
},
handlePreviewSwitch () {
this.$prompt('请输入Secret', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(({ value }) => {
previewSwitch({ secret: value, enable: this.previewSwitch }).then(response => {
console.log(response.data)
messageSuccess(this, '操作成功')
}).catch(error => {
console.error(error)
this.previewSwitch = !this.previewSwitch
})
}).catch(() => {
this.previewSwitch = !this.previewSwitch
});
},
getPreviewSwitch () {
getPreviewSwitch().then(response => {
this.previewSwitch = response.data.data === 'true'
}).catch(error => {
console.error(error)
messageFail(this, '获取演示模式状态失败')
})
} }
} }
} }
...@@ -180,5 +219,10 @@ export default { ...@@ -180,5 +219,10 @@ export default {
margin-right: 30px; margin-right: 30px;
} }
} }
.preview-switch {
vertical-align: 15px;
margin-right: 30px;
display: inline-block;
}
} }
</style> </style>
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
:default-sort="{ prop: 'create_date', order: 'descending' }" :default-sort="{ prop: 'create_date', order: 'descending' }"
highlight-current-row highlight-current-row
style="width: 100%;" style="width: 100%;"
@cell-dblclick="handleUpdate"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
@sort-change="sortChange"> @sort-change="sortChange">
<el-table-column type="selection" width="55"/> <el-table-column type="selection" width="55"/>
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
:default-sort="{ prop: 'id', order: 'descending' }" :default-sort="{ prop: 'id', order: 'descending' }"
highlight-current-row highlight-current-row
style="width: 100%;" style="width: 100%;"
@cell-dblclick="handleUpdate"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
@sort-change="sortChange"> @sort-change="sortChange">
<el-table-column type="selection" width="55"/> <el-table-column type="selection" width="55"/>
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
:default-sort="{ prop: 'id', order: 'descending' }" :default-sort="{ prop: 'id', order: 'descending' }"
highlight-current-row highlight-current-row
style="width: 100%;" style="width: 100%;"
@cell-dblclick="handleUpdate"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
@sort-change="sortChange"> @sort-change="sortChange">
<el-table-column type="selection" width="55"/> <el-table-column type="selection" width="55"/>
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
:default-sort="{ prop: 'id', order: 'descending' }" :default-sort="{ prop: 'id', order: 'descending' }"
highlight-current-row highlight-current-row
style="width: 100%;" style="width: 100%;"
@cell-dblclick="handleUpdate"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
@sort-change="sortChange"> @sort-change="sortChange">
<el-table-column type="selection" width="55"/> <el-table-column type="selection" width="55"/>
...@@ -420,7 +419,6 @@ export default { ...@@ -420,7 +419,6 @@ export default {
}, },
getFilters (filters) { getFilters (filters) {
let result = filters.map(filter => { let result = filters.map(filter => {
debugger
const tempFilter = Object.assign(filter) const tempFilter = Object.assign(filter)
let tempArgs = Object.assign(tempFilter.args) let tempArgs = Object.assign(tempFilter.args)
const args = tempArgs.split(',') const args = tempArgs.split(',')
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
:data="list" :data="list"
highligidStringht-current-row highligidStringht-current-row
style="width: 100%;" style="width: 100%;"
@cell-dblclick="handleUpdate"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
@sort-change="sortChange"> @sort-change="sortChange">
<el-table-column type="selection" width="55"/> <el-table-column type="selection" width="55"/>
...@@ -173,8 +172,7 @@ ...@@ -173,8 +172,7 @@
highlight-current-row highlight-current-row
style="width: 100%;" style="width: 100%;"
@row-click = "handleSingleRoleSelection" @row-click = "handleSingleRoleSelection"
@current-change="handleSingleRoleCurrentChange" @current-change="handleSingleRoleCurrentChange">
@cell-dblclick="updateRoleData">
<el-table-column align="center" width="55" label="" > <el-table-column align="center" width="55" label="" >
<template slot-scope="scope"> <template slot-scope="scope">
<el-radio :label="scope.$index" v-model="tempRadio" @change.native="handleSingleRoleSelectionChange(scope.$index, scope.row)">&nbsp;</el-radio> <el-radio :label="scope.$index" v-model="tempRadio" @change.native="handleSingleRoleSelectionChange(scope.$index, scope.row)">&nbsp;</el-radio>
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
:default-sort="{ prop: 'id', order: 'descending' }" :default-sort="{ prop: 'id', order: 'descending' }"
highlight-current-row highlight-current-row
style="width: 100%;" style="width: 100%;"
@cell-dblclick="handleUpdate"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
@sort-change="sortChange"> @sort-change="sortChange">
<el-table-column type="selection" width="55"/> <el-table-column type="selection" width="55"/>
......
...@@ -21,7 +21,7 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -21,7 +21,7 @@ import org.springframework.web.bind.annotation.RestController;
@Slf4j @Slf4j
@AllArgsConstructor @AllArgsConstructor
@RestController @RestController
@RequestMapping(value = "/preview") @RequestMapping(value = "/api/preview")
public class PreviewController { public class PreviewController {
private final SysProperties sysProperties; private final SysProperties sysProperties;
...@@ -35,7 +35,8 @@ public class PreviewController { ...@@ -35,7 +35,8 @@ public class PreviewController {
* @date 2019/12/15 19:45 * @date 2019/12/15 19:45
*/ */
@GetMapping("/enable") @GetMapping("/enable")
public ResponseBean<Boolean> preview(@RequestParam String enable, @RequestParam String secret) { public ResponseBean<Boolean> preview(@RequestParam(required = false) String enable, @RequestParam String secret) {
if (StringUtils.isNotBlank(enable) && sysProperties.getGatewaySecret().equals(secret)) { if (StringUtils.isNotBlank(enable) && sysProperties.getGatewaySecret().equals(secret)) {
log.info("Preview enable: {}", enable); log.info("Preview enable: {}", enable);
RedisTemplate<String, String> redisTemplate = (RedisTemplate) SpringContextHolder.getApplicationContext().getBean("redisTemplate"); RedisTemplate<String, String> redisTemplate = (RedisTemplate) SpringContextHolder.getApplicationContext().getBean("redisTemplate");
...@@ -43,4 +44,17 @@ public class PreviewController { ...@@ -43,4 +44,17 @@ public class PreviewController {
} }
return new ResponseBean<>(Boolean.TRUE); return new ResponseBean<>(Boolean.TRUE);
} }
/**
* 获取演示模式开关
*
* @return ResponseBean
* @author tangyi
* @date 2019/12/15 19:45
*/
@GetMapping("/getPreview")
public ResponseBean<String> getPreview() {
RedisTemplate<String, String> redisTemplate = (RedisTemplate) SpringContextHolder.getApplicationContext().getBean("redisTemplate");
return new ResponseBean<>(redisTemplate.opsForValue().get(PreviewConfigLoader.PREVIEW_ENABLE));
}
} }
...@@ -37,12 +37,6 @@ public class PreviewFilter implements GlobalFilter, Ordered { ...@@ -37,12 +37,6 @@ public class PreviewFilter implements GlobalFilter, Ordered {
@Override @Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
if (shouldFilter(request)) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.LOCKED);
return response.setComplete();
}
return chain.filter(exchange); return chain.filter(exchange);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment