Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
spring-microservice-exam
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
汪想
spring-microservice-exam
Commits
21f4f0c1
Commit
21f4f0c1
authored
Apr 06, 2020
by
tangyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
优化
parent
fd8c285d
Hide whitespace changes
Inline
Side-by-side
Showing
53 changed files
with
1337 additions
and
533 deletions
+1337
-533
CHANGELOG.md
CHANGELOG.md
+9
-1
README.md
README.md
+2
-2
SysConfigDto.java
...java/com/github/tangyi/common/basic/dto/SysConfigDto.java
+0
-5
SysProperties.java
.../github/tangyi/common/basic/properties/SysProperties.java
+15
-0
CustomGlobalExceptionHandler.java
...i/common/config/handler/CustomGlobalExceptionHandler.java
+58
-10
ApiMsg.java
...n/java/com/github/tangyi/common/core/constant/ApiMsg.java
+6
-0
FileUtil.java
...in/java/com/github/tangyi/common/core/utils/FileUtil.java
+109
-0
FastDfsService.java
...in/java/com/github/tangyi/oss/service/FastDfsService.java
+0
-1
QiNiuUtil.java
...rc/main/java/com/github/tangyi/oss/service/QiNiuUtil.java
+18
-16
user-service.yml
config-service/src/main/resources/config/user-service.yml
+4
-0
dev.env
docs/deploy/dev.env
+39
-0
docker-compose-base.yml
docs/deploy/docker-compose-base.yml
+2
-0
docker-compose-services.yml
docs/deploy/docker-compose-services.yml
+13
-0
docker-compose.env
docs/deploy/docker-compose.env
+5
-2
microservice_auth.sql
docs/deploy/mysql/init/microservice_auth.sql
+2
-1
microservice_exam.sql
docs/deploy/mysql/init/microservice_exam.sql
+121
-57
microservice_user.sql
docs/deploy/mysql/init/microservice_user.sql
+15
-12
update.sql
docs/deploy/mysql/update.sql
+6
-2
readme.md
frontend/spring-microservice-exam-miniprogram/readme.md
+0
-0
package.json
frontend/spring-microservice-exam-ui/package.json
+1
-1
attachment.js
...d/spring-microservice-exam-ui/src/api/admin/attachment.js
+2
-2
index.vue
...service-exam-ui/src/components/Subjects/Choices/index.vue
+22
-78
index.vue
...rvice-exam-ui/src/components/Subjects/Judgement/index.vue
+11
-66
index.vue
...exam-ui/src/components/Subjects/MultipleChoices/index.vue
+31
-99
index.vue
...ice-exam-ui/src/components/Subjects/ShortAnswer/index.vue
+7
-52
index.vue
...ing-microservice-exam-ui/src/components/Tinymce/index.vue
+3
-14
toolbar.js
...ng-microservice-exam-ui/src/components/Tinymce/toolbar.js
+1
-1
zh.js
frontend/spring-microservice-exam-ui/src/lang/zh.js
+1
-0
list.vue
...spring-microservice-exam-ui/src/views/attachment/list.vue
+90
-21
exam.vue
frontend/spring-microservice-exam-ui/src/views/exam/exam.vue
+3
-4
examSubjects.vue
...ring-microservice-exam-ui/src/views/exam/examSubjects.vue
+0
-1
subject.vue
...nd/spring-microservice-exam-ui/src/views/exam/subject.vue
+117
-3
message.vue
...pring-microservice-exam-ui/src/views/personal/message.vue
+1
-4
menu.vue
frontend/spring-microservice-exam-ui/src/views/sys/menu.vue
+3
-0
login_bg.jpeg
...tend/spring-microservice-exam-ui/static/img/login_bg.jpeg
+0
-0
package.json
frontend/spring-microservice-exam-web/package.json
+1
-1
Index.vue
frontend/spring-microservice-exam-web/src/views/Index.vue
+1
-1
header.vue
.../spring-microservice-exam-web/src/views/common/header.vue
+1
-1
account.vue
...ring-microservice-exam-web/src/views/personal/account.vue
+2
-5
CourseService.java
...in/java/com/github/tangyi/exam/service/CourseService.java
+2
-3
ExaminationService.java
...va/com/github/tangyi/exam/service/ExaminationService.java
+2
-1
AttachmentConstant.java
...m/github/tangyi/user/api/constant/AttachmentConstant.java
+5
-0
Attachment.java
...in/java/com/github/tangyi/user/api/module/Attachment.java
+17
-5
AttachmentController.java
...m/github/tangyi/user/controller/AttachmentController.java
+84
-14
AttachUploaderEnum.java
...java/com/github/tangyi/user/enums/AttachUploaderEnum.java
+36
-0
AttachmentService.java
...ava/com/github/tangyi/user/service/AttachmentService.java
+10
-47
AbstractUploader.java
...ava/com/github/tangyi/user/uploader/AbstractUploader.java
+61
-0
FastDfsUploader.java
...java/com/github/tangyi/user/uploader/FastDfsUploader.java
+57
-0
FileUploader.java
...in/java/com/github/tangyi/user/uploader/FileUploader.java
+82
-0
IUploader.java
.../main/java/com/github/tangyi/user/uploader/IUploader.java
+48
-0
QiNiuUploader.java
...n/java/com/github/tangyi/user/uploader/QiNiuUploader.java
+42
-0
UploadInvoker.java
...n/java/com/github/tangyi/user/uploader/UploadInvoker.java
+155
-0
AttachmentMapper.xml
...er-service/src/main/resources/mapper/AttachmentMapper.xml
+14
-0
No files found.
CHANGELOG.md
View file @
21f4f0c1
Version v3.7.0 (2020-03-39)
Version v3.7.0 (2020-04-05)
--------------------------
改进:
*
优化附件上传模块,支持存储方式支持本地、fastDfs、七牛云
*
优化题目编辑页面,统一采用富文本输入,支持数学公式
Version v3.7.0 (2020-03-31)
--------------------------
改进:
...
...
README.md
View file @
21f4f0c1
...
...
@@ -45,7 +45,7 @@
-
构建工具:
`Maven`
-
后台 API 文档:
`Swagger`
-
消息队列:
`RabbitMQ`
-
文件系统:
`七牛云`
、
`FastDfs`
-
文件系统:
`
本地目录`
、
`
七牛云`
、
`FastDfs`
-
缓存:
`Redis`
-
前端:
`vue`
-
小程序:
`wepy`
...
...
@@ -94,7 +94,7 @@
-
知识库:知识库增删改查、上传附件
附件管理:项目的所有附件存储在
`fastDfs`
里,提供统一的管理入口
-
附件列表:管理所有附件,如用户头像、考试附件、知识库附件等
。
-
附件列表:管理所有附件,如用户头像、考试附件、知识库附件等
,存储方式支持服务器本地目录、
`fastDfs`
,七牛云
个人管理:管理个人资料和修改密码
-
个人资料:姓名、头像等基本信息的修改
...
...
common/common-basic/src/main/java/com/github/tangyi/common/basic/dto/SysConfigDto.java
View file @
21f4f0c1
...
...
@@ -14,11 +14,6 @@ public class SysConfigDto implements Serializable {
private
static
final
long
serialVersionUID
=
1L
;
/**
* fastDfs服务器的HTTP地址
*/
private
String
fdfsHttpHost
;
/**
* 上传地址
*/
private
String
uploadUrl
;
...
...
common/common-basic/src/main/java/com/github/tangyi/common/basic/properties/SysProperties.java
View file @
21f4f0c1
...
...
@@ -54,4 +54,19 @@ public class SysProperties {
* 二维码生成链接
*/
private
String
qrCodeUrl
;
/**
* 上传类型,1:本地目录,2:fastDfs,3:七牛云
*/
private
String
attachUploadType
;
/**
* 附件上传目录
*/
private
String
attachPath
;
/**
* 支持预览的附件后缀名,多个用逗号隔开,如:png,jpeg
*/
private
String
canPreview
;
}
common/common-config/src/main/java/com/github/tangyi/common/config/handler/CustomGlobalExceptionHandler.java
View file @
21f4f0c1
...
...
@@ -3,17 +3,22 @@ package com.github.tangyi.common.config.handler;
import
com.github.tangyi.common.core.constant.ApiMsg
;
import
com.github.tangyi.common.core.exceptions.CommonException
;
import
com.github.tangyi.common.core.model.ResponseBean
;
import
com.github.tangyi.common.core.utils.JsonMapper
;
import
org.springframework.context.support.DefaultMessageSourceResolvable
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.http.converter.HttpMessageConversionException
;
import
org.springframework.validation.BindException
;
import
org.springframework.validation.BindingResult
;
import
org.springframework.validation.FieldError
;
import
org.springframework.web.bind.MethodArgumentNotValidException
;
import
org.springframework.web.bind.annotation.ControllerAdvice
;
import
org.springframework.web.bind.annotation.ExceptionHandler
;
import
org.springframework.web.context.request.WebRequest
;
import
org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler
;
import
org.springframework.web.bind.annotation.RestControllerAdvice
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
/**
...
...
@@ -22,8 +27,8 @@ import java.util.stream.Collectors;
* @author tangyi
* @date 2019/05/25 15:36
*/
@ControllerAdvice
public
class
CustomGlobalExceptionHandler
extends
ResponseEntityExceptionHandler
{
@
Rest
ControllerAdvice
public
class
CustomGlobalExceptionHandler
{
/**
* 处理参数校验异常
...
...
@@ -31,13 +36,12 @@ public class CustomGlobalExceptionHandler extends ResponseEntityExceptionHandler
* @param ex ex
* @param headers headers
* @param status status
* @param request request
* @return ResponseEntity
*/
@
Override
p
rotected
ResponseEntity
<
Object
>
handleMethodArgumentNotValid
(
MethodArgumentNotValidException
ex
,
HttpHeaders
headers
,
HttpStatus
status
,
WebRequest
request
)
{
@
ExceptionHandler
(
MethodArgumentNotValidException
.
class
)
p
ublic
ResponseEntity
<
Object
>
validationBodyException
(
MethodArgumentNotValidException
ex
,
HttpHeaders
headers
,
HttpStatus
status
)
{
// 获取所有异常信息
List
<
String
>
errors
=
ex
.
getBindingResult
()
.
getFieldErrors
()
...
...
@@ -49,6 +53,18 @@ public class CustomGlobalExceptionHandler extends ResponseEntityExceptionHandler
}
/**
* 参数类型转换错误
*
* @param exception 错误
* @return 错误信息
*/
@ExceptionHandler
(
HttpMessageConversionException
.
class
)
public
ResponseEntity
<
ResponseBean
<
String
>>
parameterTypeException
(
HttpMessageConversionException
exception
)
{
ResponseBean
<
String
>
responseBean
=
new
ResponseBean
<>(
exception
.
getMessage
(),
ApiMsg
.
KEY_PARAM_VALIDATE
,
ApiMsg
.
ERROR
);
return
new
ResponseEntity
<>(
responseBean
,
HttpStatus
.
OK
);
}
/**
* 处理CommonException
*
* @param e e
...
...
@@ -60,9 +76,40 @@ public class CustomGlobalExceptionHandler extends ResponseEntityExceptionHandler
return
new
ResponseEntity
<>(
responseBean
,
HttpStatus
.
OK
);
}
/**
* 捕获@Validate校验抛出的异常
*
* @param e e
* @return ResponseEntity
*/
@ExceptionHandler
(
BindException
.
class
)
public
ResponseEntity
<
Object
>
validExceptionHandler
(
BindException
e
)
{
Exception
ex
=
parseBindingResult
(
e
.
getBindingResult
());
ResponseBean
<
String
>
responseBean
=
new
ResponseBean
<>(
ex
.
getMessage
(),
ApiMsg
.
KEY_PARAM_VALIDATE
,
ApiMsg
.
ERROR
);
return
new
ResponseEntity
<>(
responseBean
,
HttpStatus
.
OK
);
}
@ExceptionHandler
(
Exception
.
class
)
public
ResponseEntity
<
ResponseBean
<
String
>>
handleException
(
Exception
e
)
{
ResponseBean
<
String
>
responseBean
=
new
ResponseBean
<>(
e
.
getMessage
(),
ApiMsg
.
KEY_ERROR
,
ApiMsg
.
ERROR
);
return
new
ResponseEntity
<>(
responseBean
,
HttpStatus
.
OK
);
}
/**
* 提取Validator产生的异常错误
*
* @param bindingResult bindingResult
* @return Exception
*/
private
Exception
parseBindingResult
(
BindingResult
bindingResult
)
{
Map
<
String
,
String
>
errorMsgs
=
new
HashMap
<>();
for
(
FieldError
error
:
bindingResult
.
getFieldErrors
())
{
errorMsgs
.
put
(
error
.
getField
(),
error
.
getDefaultMessage
());
}
if
(
errorMsgs
.
isEmpty
())
{
return
new
CommonException
(
ApiMsg
.
KEY_PARAM_VALIDATE
+
""
);
}
else
{
return
new
CommonException
(
JsonMapper
.
toJsonString
(
errorMsgs
));
}
}
}
\ No newline at end of file
common/common-core/src/main/java/com/github/tangyi/common/core/constant/ApiMsg.java
View file @
21f4f0c1
...
...
@@ -101,6 +101,11 @@ public class ApiMsg {
public
static
final
int
KEY_AUTHENTICATION
=
405
;
/**
* 参数校验
*/
public
static
final
int
KEY_PARAM_VALIDATE
=
406
;
/**
* code和提示内容的对应关系
*/
private
static
final
Map
<
Integer
,
String
>
CODE_MAP
=
new
HashMap
<>();
...
...
@@ -130,6 +135,7 @@ public class ApiMsg {
KEY_MAP
.
put
(
KEY_VALIDATE_CODE
,
"VALIDATE CODE"
);
KEY_MAP
.
put
(
KEY_TOKEN
,
"TOKEN"
);
KEY_MAP
.
put
(
KEY_ACCESS
,
"ACCESS"
);
KEY_MAP
.
put
(
KEY_PARAM_VALIDATE
,
"PARAM_VALIDATE"
);
}
public
static
String
code2Msg
(
int
codeKey
,
int
msgKey
)
{
...
...
common/common-core/src/main/java/com/github/tangyi/common/core/utils/FileUtil.java
View file @
21f4f0c1
package
com
.
github
.
tangyi
.
common
.
core
.
utils
;
import
lombok.extern.slf4j.Slf4j
;
import
java.io.File
;
/**
* 文件工具类
*
* @author tangyi
* @date 2018/10/30 22:05
*/
@Slf4j
public
class
FileUtil
{
/**
...
...
@@ -25,4 +30,108 @@ public class FileUtil {
}
return
""
;
}
/**
* 创建目录
*
* @param descDirName descDirName
* @return String
*/
public
static
boolean
createDirectory
(
String
descDirName
)
{
String
descDirNames
=
descDirName
;
if
(!
descDirNames
.
endsWith
(
File
.
separator
))
{
descDirNames
=
descDirNames
+
File
.
separator
;
}
File
descDir
=
new
File
(
descDirNames
);
if
(
descDir
.
exists
())
{
log
.
debug
(
"dir "
+
descDirNames
+
" already exits!"
);
return
false
;
}
if
(
descDir
.
mkdirs
())
{
log
.
debug
(
"dir "
+
descDirNames
+
" create success!"
);
return
true
;
}
else
{
log
.
debug
(
"dir "
+
descDirNames
+
" create failure!"
);
return
false
;
}
}
/**
*
* 删除目录及目录下的文件
*
* @param dirName 被删除的目录所在的文件路径
* @return 如果目录删除成功,则返回true,否则返回false
*/
public
static
boolean
deleteDirectory
(
String
dirName
)
{
String
dirNames
=
dirName
;
if
(!
dirNames
.
endsWith
(
File
.
separator
))
{
dirNames
=
dirNames
+
File
.
separator
;
}
File
dirFile
=
new
File
(
dirNames
);
if
(!
dirFile
.
exists
()
||
!
dirFile
.
isDirectory
())
{
log
.
debug
(
dirNames
+
" dir not exists!"
);
return
true
;
}
boolean
flag
=
true
;
// 列出全部文件及子目录
File
[]
files
=
dirFile
.
listFiles
();
if
(
files
!=
null
)
{
for
(
File
file
:
files
)
{
// 删除子文件
if
(
file
.
isFile
())
{
flag
=
FileUtil
.
deleteFile
(
file
.
getAbsolutePath
());
// 如果删除文件失败,则退出循环
if
(!
flag
)
{
break
;
}
}
// 删除子目录
else
if
(
file
.
isDirectory
())
{
flag
=
FileUtil
.
deleteDirectory
(
file
.
getAbsolutePath
());
// 如果删除子目录失败,则退出循环
if
(!
flag
)
{
break
;
}
}
}
}
if
(!
flag
)
{
log
.
debug
(
"delete dir failure!"
);
return
false
;
}
// 删除当前目录
if
(
dirFile
.
delete
())
{
log
.
debug
(
"delete dir "
+
dirName
+
" success!"
);
return
true
;
}
else
{
log
.
debug
(
"delete dir "
+
dirName
+
" failure!"
);
return
false
;
}
}
/**
*
* 删除单个文件
*
* @param fileName 被删除的文件名
* @return 如果删除成功,则返回true,否则返回false
*/
public
static
boolean
deleteFile
(
String
fileName
)
{
File
file
=
new
File
(
fileName
);
if
(
file
.
exists
()
&&
file
.
isFile
())
{
if
(
file
.
delete
())
{
log
.
debug
(
"delete file "
+
fileName
+
" success!"
);
return
true
;
}
else
{
log
.
debug
(
"delete file "
+
fileName
+
" failure!"
);
return
false
;
}
}
else
{
log
.
debug
(
fileName
+
" not exists!"
);
return
true
;
}
}
}
common/common-oss/src/main/java/com/github/tangyi/oss/service/FastDfsService.java
View file @
21f4f0c1
...
...
@@ -27,7 +27,6 @@ import java.util.Set;
* @author tangyi
* @date 2018-01-04 10:34
*/
@Deprecated
@Slf4j
@AllArgsConstructor
@Service
...
...
common/common-oss/src/main/java/com/github/tangyi/oss/service/QiNiu
Service
.java
→
common/common-oss/src/main/java/com/github/tangyi/oss/service/QiNiu
Util
.java
View file @
21f4f0c1
...
...
@@ -2,6 +2,7 @@ package com.github.tangyi.oss.service;
import
com.github.tangyi.common.core.constant.CommonConstant
;
import
com.github.tangyi.common.core.utils.JsonMapper
;
import
com.github.tangyi.common.core.utils.SpringContextHolder
;
import
com.github.tangyi.oss.config.QiNiuConfig
;
import
com.github.tangyi.oss.exceptions.OssException
;
import
com.qiniu.common.QiniuException
;
...
...
@@ -14,10 +15,7 @@ import com.qiniu.storage.model.DefaultPutRet;
import
com.qiniu.util.Auth
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.PostConstruct
;
import
java.io.UnsupportedEncodingException
;
import
java.net.URLEncoder
;
...
...
@@ -27,10 +25,7 @@ import java.net.URLEncoder;
* @date 2019/12/8 20:25
*/
@Slf4j
@Service
public
class
QiNiuService
{
private
final
QiNiuConfig
qiNiuConfig
;
public
class
QiNiuUtil
{
private
Auth
auth
;
...
...
@@ -38,18 +33,25 @@ public class QiNiuService {
private
BucketManager
bucketManager
;
@Autowired
public
QiNiuService
(
QiNiuConfig
qiNiuConfig
)
{
this
.
qiNiuConfig
=
qiNiuConfig
;
private
QiNiuConfig
qiNiuConfig
;
private
static
QiNiuUtil
instance
;
public
synchronized
static
QiNiuUtil
getInstance
()
{
if
(
instance
==
null
)
{
instance
=
new
QiNiuUtil
();
}
return
instance
;
}
@PostConstruct
public
void
init
()
{
public
QiNiuUtil
()
{
qiNiuConfig
=
SpringContextHolder
.
getApplicationContext
().
getBean
(
QiNiuConfig
.
class
);
if
(
StringUtils
.
isNotBlank
(
qiNiuConfig
.
getAccessKey
())
&&
StringUtils
.
isNotBlank
(
qiNiuConfig
.
getSecretKey
()))
{
auth
=
Auth
.
create
(
qiNiuConfig
.
getAccessKey
(),
qiNiuConfig
.
getSecretKey
());
instance
=
new
QiNiuUtil
();
instance
.
auth
=
Auth
.
create
(
qiNiuConfig
.
getAccessKey
(),
qiNiuConfig
.
getSecretKey
());
Configuration
config
=
new
Configuration
(
Region
.
region2
());
uploadManager
=
new
UploadManager
(
config
);
bucketManager
=
new
BucketManager
(
auth
,
config
);
instance
.
uploadManager
=
new
UploadManager
(
config
);
instance
.
bucketManager
=
new
BucketManager
(
instance
.
auth
,
config
);
}
}
...
...
@@ -59,7 +61,7 @@ public class QiNiuService {
* @return String
*/
public
String
getQiNiuToken
()
{
return
auth
.
uploadToken
(
qiNiuConfig
.
getBucket
());
return
auth
.
uploadToken
(
getInstance
().
qiNiuConfig
.
getBucket
());
}
/**
...
...
config-service/src/main/resources/config/user-service.yml
View file @
21f4f0c1
...
...
@@ -112,6 +112,9 @@ sys:
defaultAvatar
:
/static/img/avatar/
key
:
'
1234567887654321'
cacheExpire
:
86400
# 缓存失效时间,单位秒,默认一天
attachtUploadType
:
1
# 上传类型,1:本地目录,2:fastDfs,3:七牛云
attachPath
:
${ATTACH_PATH:C:/attach}
# 附件上传目录
canPreview
:
jpg,png,jpeg,gif
# 支持预览的格式
# feign相关配置
feign
:
...
...
@@ -158,6 +161,7 @@ ignore:
-
/v1/menu/anonymousUser/**
-
/v1/code/**
-
/v1/attachment/download
-
/v1/attachment/preview
-
/v1/log/**
-
/authentication/**
-
/v1/authentication/**
...
...
docs/deploy/dev.env
0 → 100644
View file @
21f4f0c1
DB_AUTH=dev_microservice_auth
DB_USER=dev_microservice_user
DB_EXAM=dev_microservice_exam
DB_GATEWAY=dev_microservice_gateway
# 租户标识,默认gitee
TENANT_CODE=gitee
# 网关token转换
GATEWAY_TOKEN_TRANSFER=false
# 网关secret
GATEWAY_SECRET=15521089185
# 环境配置
SPRING_PROFILES_ACTIVE=native
# consul配置
CONSUL_HOST=localhost
CONSUL_PORT=8500
# rabbitMq配置
RABBIT_HOST=localhost
RABBIT_PORT=5672
RABBITMQ_DEFAULT_USER=guest
RABBITMQ_DEFAULT_PASS=guest
# Redis配置
REDIS_HOST=localhost
# 数据库配置
MYSQL_HOST=118.25.138.130
MYSQL_USERNAME=root
MYSQL_PASSWORD=15521089185
# ID生成配置
CLUSTER_WORK_ID=1
CLUSTER_DATA_CENTER_ID=1
\ No newline at end of file
docs/deploy/docker-compose-base.yml
View file @
21f4f0c1
...
...
@@ -97,6 +97,8 @@ services:
-
redis
ports
:
-
"
9181:9181"
volumes
:
-
./logs/config-service:/logs/config-service
networks
:
-
net
...
...
docs/deploy/docker-compose-services.yml
View file @
21f4f0c1
...
...
@@ -10,6 +10,8 @@ services:
restart
:
always
ports
:
-
"
9180:9180"
volumes
:
-
./logs/gateway-service:/logs/gateway-service
networks
:
-
net
...
...
@@ -23,6 +25,8 @@ services:
restart
:
always
ports
:
-
"
9182:9182"
volumes
:
-
./logs/auth-service:/logs/auth-service
networks
:
-
net
...
...
@@ -36,6 +40,9 @@ services:
restart
:
always
ports
:
-
"
9183:9183"
volumes
:
-
./logs/user-service:/logs/user-service
-
./attach:/attach
networks
:
-
net
...
...
@@ -49,6 +56,8 @@ services:
restart
:
always
ports
:
-
"
9184:9184"
volumes
:
-
./logs/exam-service:/logs/exam-service
networks
:
-
net
...
...
@@ -62,6 +71,8 @@ services:
restart
:
always
ports
:
-
"
9185:9185"
volumes
:
-
./logs/msc-service:/logs/msc-service
networks
:
-
net
...
...
@@ -75,6 +86,8 @@ services:
restart
:
always
ports
:
-
"
9186:9186"
volumes
:
-
./logs/monitor-service:/logs/monitor-service
networks
:
-
net
...
...
docs/deploy/docker-compose.env
View file @
21f4f0c1
...
...
@@ -83,4 +83,7 @@ LOGSTASH_HOST=localhost:5044
# 微信配置
WX_APP_ID=test
WX_APP_SECRET=test
WX_GRANT_TYPE=authorization_code
\ No newline at end of file
WX_GRANT_TYPE=authorization_code
# 附件上传配置
ATTACH_PATH=/attach
\ No newline at end of file
docs/deploy/mysql/init/microservice_auth.sql
View file @
21f4f0c1
SET
NAMES
utf8mb4
;
SET
FOREIGN_KEY_CHECKS
=
0
;
...
...
@@ -32,6 +33,6 @@ CREATE TABLE `oauth_client_details` (
-- ----------------------------
-- Records of oauth_client_details
-- ----------------------------
INSERT
INTO
`oauth_client_details`
VALUES
(
607150228717572096
,
'web_app'
,
NULL
,
'spring-microservice-exam-secret'
,
'$2a$10$IWLD8r7e0rKMW.ZhGsGCUO./MZUNDKudIswSToa9puXJwty.h59.u'
,
'read,write'
,
'password,authorization_code,refresh_token,implicit'
,
NULL
,
NULL
,
'
3600'
,
'86400'
,
NULL
,
NULL
,
'admin'
,
'2019-03-30 23:43:07'
,
'admin'
,
'2019-12-24 21:56:19
'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`oauth_client_details`
VALUES
(
607150228717572096
,
'web_app'
,
NULL
,
'spring-microservice-exam-secret'
,
'$2a$10$IWLD8r7e0rKMW.ZhGsGCUO./MZUNDKudIswSToa9puXJwty.h59.u'
,
'read,write'
,
'password,authorization_code,refresh_token,implicit'
,
NULL
,
NULL
,
'
86400'
,
'86400'
,
NULL
,
NULL
,
'admin'
,
'2019-03-30 23:43:07'
,
'admin'
,
'2020-03-28 20:01:31
'
,
0
,
'EXAM'
,
'gitee'
);
SET
FOREIGN_KEY_CHECKS
=
1
;
docs/deploy/mysql/init/microservice_exam.sql
View file @
21f4f0c1
...
...
@@ -28,6 +28,31 @@ CREATE TABLE `exam_answer` (
)
ENGINE
=
InnoDB
CHARACTER
SET
=
utf8
COLLATE
=
utf8_general_ci
COMMENT
=
'答题表'
ROW_FORMAT
=
Compact
;
-- ----------------------------
-- Records of exam_answer
-- ----------------------------
INSERT
INTO
`exam_answer`
VALUES
(
691062093205606401
,
691062092169613312
,
679455142176755712
,
0
,
'A'
,
0
,
5
,
1
,
'2020-03-21 23:14:02'
,
'2020-03-21 23:14:08'
,
'anonymousUser'
,
'2020-03-21 23:25:43'
,
'anonymousUser'
,
'2020-03-21 23:14:08'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
691062191109050368
,
691062092169613312
,
679455223147794432
,
0
,
'B'
,
0
,
5
,
1
,
'2020-03-21 23:14:09'
,
'2020-03-21 23:14:26'
,
'anonymousUser'
,
'2020-03-21 23:25:43'
,
'anonymousUser'
,
'2020-03-21 23:14:26'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
691062249435041792
,
691062092169613312
,
679455353129275392
,
0
,
'C'
,
0
,
5
,
1
,
'2020-03-21 23:14:26'
,
'2020-03-21 23:14:40'
,
'anonymousUser'
,
'2020-03-21 23:25:43'
,
'anonymousUser'
,
'2020-03-21 23:14:40'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
691062295685632000
,
691062092169613312
,
679680049900818432
,
3
,
'A,C'
,
0
,
5
,
1
,
'2020-03-21 23:14:40'
,
'2020-03-21 23:14:51'
,
'anonymousUser'
,
'2020-03-21 23:25:43'
,
'anonymousUser'
,
'2020-03-21 23:14:51'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
691062305785516032
,
691062092169613312
,
679680687489552384
,
0
,
'A'
,
0
,
5
,
1
,
'2020-03-21 23:14:51'
,
'2020-03-21 23:20:32'
,
'anonymousUser'
,
'2020-03-21 23:31:15'
,
'anonymousUser'
,
'2020-03-21 23:20:32'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
691062329726603264
,
691062092169613312
,
680037906714333184
,
1
,
'<p>erer</p>'
,
1
,
0
,
1
,
'2020-03-21 23:14:53'
,
'2020-03-21 23:20:31'
,
'anonymousUser'
,
'2020-03-21 23:31:13'
,
'anonymousUser'
,
'2020-03-21 23:20:31'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
691062861052645376
,
691062092169613312
,
680772677350330368
,
2
,
'正确'
,
0
,
5
,
1
,
'2020-03-21 23:17:01'
,
'2020-03-21 23:20:27'
,
'anonymousUser'
,
'2020-03-21 23:31:10'
,
'anonymousUser'
,
'2020-03-21 23:20:27'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
691063101176549377
,
691063100123779072
,
679455142176755712
,
0
,
'A'
,
0
,
5
,
1
,
'2020-03-21 23:18:03'
,
'2020-03-21 23:18:06'
,
'admin'
,
'2020-03-21 23:29:17'
,
'admin'
,
'2020-03-21 23:18:06'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
691063138266779648
,
691063100123779072
,
679455223147794432
,
0
,
'B'
,
0
,
5
,
1
,
'2020-03-21 23:18:07'
,
'2020-03-21 23:18:11'
,
'admin'
,
'2020-03-21 23:29:17'
,
'admin'
,
'2020-03-21 23:18:11'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
691063154221912064
,
691063100123779072
,
679455353129275392
,
0
,
'C'
,
0
,
5
,
1
,
'2020-03-21 23:18:11'
,
'2020-03-21 23:18:15'
,
'admin'
,
'2020-03-21 23:29:17'
,
'admin'
,
'2020-03-21 23:18:15'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
691063166632857600
,
691063100123779072
,
679680049900818432
,
3
,
'A,C'
,
0
,
5
,
1
,
'2020-03-21 23:18:15'
,
'2020-03-21 23:18:18'
,
'admin'
,
'2020-03-21 23:29:17'
,
'admin'
,
'2020-03-21 23:18:18'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
691063179433873408
,
691063100123779072
,
679680687489552384
,
0
,
'A'
,
0
,
5
,
1
,
'2020-03-21 23:18:18'
,
'2020-03-21 23:18:21'
,
'admin'
,
'2020-03-21 23:29:17'
,
'admin'
,
'2020-03-21 23:18:21'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
691063208663977984
,
691063100123779072
,
680037906714333184
,
1
,
'<p>测试</p>'
,
1
,
0
,
1
,
'2020-03-21 23:18:22'
,
'2020-03-21 23:18:28'
,
'admin'
,
'2020-03-21 23:29:17'
,
'admin'
,
'2020-03-21 23:18:28'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
691063227982942208
,
691063100123779072
,
680772677350330368
,
2
,
'正确'
,
0
,
5
,
1
,
'2020-03-21 23:18:28'
,
'2020-03-21 23:18:33'
,
'admin'
,
'2020-03-21 23:29:17'
,
'admin'
,
'2020-03-21 23:18:33'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
696330635085746176
,
696330634376908800
,
696329099584606208
,
0
,
'A'
,
0
,
5
,
1
,
'2020-04-05 12:09:21'
,
'2020-04-05 12:09:24'
,
'student'
,
'2020-04-05 12:21:19'
,
'student'
,
'2020-04-05 12:09:24'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
696330659911831552
,
696330634376908800
,
696329220065988608
,
3
,
'B'
,
0
,
5
,
1
,
'2020-04-05 12:09:24'
,
'2020-04-05 12:09:27'
,
'student'
,
'2020-04-05 12:21:19'
,
'student'
,
'2020-04-05 12:09:27'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
696330669739085824
,
696330634376908800
,
696329277397929984
,
2
,
'正确'
,
0
,
5
,
1
,
'2020-04-05 12:09:27'
,
'2020-04-05 12:10:25'
,
'student'
,
'2020-04-05 12:21:19'
,
'student'
,
'2020-04-05 12:10:25'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
696330707735285760
,
696330634376908800
,
696329333312196608
,
1
,
'<p>测试 吃的啥</p>'
,
1
,
0
,
1
,
'2020-04-05 12:09:29'
,
'2020-04-05 12:10:24'
,
'student'
,
'2020-04-05 12:21:19'
,
'student'
,
'2020-04-05 12:10:24'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
696330724759965696
,
696330634376908800
,
696329371371311104
,
1
,
'<p>测试 </p>'
,
1
,
0
,
1
,
'2020-04-05 12:09:38'
,
'2020-04-05 12:10:01'
,
'student'
,
'2020-04-05 12:21:19'
,
'student'
,
'2020-04-05 12:10:01'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
696330749921595392
,
696330634376908800
,
696329435527385088
,
0
,
'B'
,
1
,
0
,
1
,
'2020-04-05 12:09:45'
,
'2020-04-05 12:09:56'
,
'student'
,
'2020-04-05 12:21:19'
,
'student'
,
'2020-04-05 12:09:56'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_answer`
VALUES
(
696330779109756928
,
696330634376908800
,
696329516385177600
,
0
,
'A'
,
0
,
5
,
1
,
'2020-04-05 12:09:48'
,
'2020-04-05 12:09:55'
,
'student'
,
'2020-04-05 12:21:19'
,
'student'
,
'2020-04-05 12:09:55'
,
0
,
'EXAM'
,
'gitee'
);
-- ----------------------------
-- Table structure for exam_course
-- ----------------------------
DROP
TABLE
IF
EXISTS
`exam_course`
;
...
...
@@ -51,8 +76,8 @@ CREATE TABLE `exam_course` (
-- ----------------------------
-- Records of exam_course
-- ----------------------------
INSERT
INTO
`exam_course`
VALUES
(
590968789617741824
,
'计算机基础'
,
'信息学院'
,
'软件工程'
,
''
,
'计算机基础'
,
'admin'
,
'20
19-10-07 15:28:03'
,
'admin'
,
'2019-10-07 15:19:36
'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_course`
VALUES
(
590968881187786752
,
'大学语文'
,
'信息学院'
,
'软件工程'
,
'陈老师'
,
'大学语文'
,
'admin'
,
'20
19-10-07 15:28:00'
,
'admin'
,
'2019-10-07 15:19:34
'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_course`
VALUES
(
590968789617741824
,
'计算机基础'
,
'信息学院'
,
'软件工程'
,
''
,
'计算机基础'
,
'admin'
,
'20
20-03-20 23:37:30'
,
'admin'
,
'2020-03-20 23:26:43
'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_course`
VALUES
(
590968881187786752
,
'大学语文'
,
'信息学院'
,
'软件工程'
,
'陈老师'
,
'大学语文'
,
'admin'
,
'20
20-03-20 23:37:23'
,
'admin'
,
'2020-03-20 23:26:37
'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_course`
VALUES
(
630786336084856832
,
'1'
,
'1'
,
'1'
,
'1'
,
'1'
,
'admin'
,
'2019-10-07 15:28:53'
,
'admin'
,
'2019-10-07 15:20:23'
,
1
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_course`
VALUES
(
630786555333709824
,
'1'
,
'1'
,
'1'
,
'1'
,
'1'
,
'admin'
,
'2019-10-07 15:29:06'
,
'admin'
,
'2019-10-07 15:20:37'
,
1
,
'EXAM'
,
'gitee'
);
...
...
@@ -85,13 +110,14 @@ CREATE TABLE `exam_examination` (
-- ----------------------------
-- Records of exam_examination
-- ----------------------------
INSERT
INTO
`exam_examination`
VALUES
(
590969316204220416
,
'全国计算机统考练习题10道'
,
2
,
'练习'
,
'2019-12-13 22:29:24'
,
'20
19-12-16 22:29:30'
,
50
,
0
,
NULL
,
590968789617741824
,
'全国计算机统考练习题10道'
,
'admin'
,
'2019-06-19 18:21:04'
,
'admin'
,
'2019-12-14 22:20:45
'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination`
VALUES
(
590969316204220416
,
'全国计算机统考练习题10道'
,
2
,
'练习'
,
'2019-12-13 22:29:24'
,
'20
20-03-12 22:24:49'
,
50
,
0
,
NULL
,
590968789617741824
,
'全国计算机统考练习题10道'
,
'admin'
,
'2019-06-19 18:21:04'
,
'admin'
,
'2020-03-09 22:24:52
'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination`
VALUES
(
590969514372501504
,
'四川省2016年普通高考文科综合能力测试-语文部分'
,
0
,
'注意事项:
\n
1.本试卷分第工卷(选择题)和第II卷(非选择题)两部分。答卷前,考生务必将白己的姓名、准考证号填写在答题卡上。
\n
2.回答第Ⅰ卷时,选出每小题答案后,用铅笔把答题卡上对应题目的答案标号涂黑。如需改动,用橡皮擦干净后,再选涂其它答案标号。写在本试卷上无效。
\n
3.回答第Ⅱ卷时,将答案写在答题卡上。写在本试卷上无效。
\n
4.考试结束后,将本试卷和答题卡一并交回。'
,
'2019-12-14 22:29:43'
,
'2019-12-17 22:29:46'
,
60
,
0
,
NULL
,
590968881187786752
,
'四川省2016年普通高考-文科综合能力测试'
,
'admin'
,
'2019-06-19 18:21:51'
,
'admin'
,
'2019-12-14 22:20:13'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination`
VALUES
(
625826218704506880
,
'12'
,
0
,
'1'
,
'2019-10-07 15:32:23'
,
'2019-10-09 15:32:25'
,
1
,
0
,
NULL
,
NULL
,
'1'
,
'admin'
,
'2019-09-23 22:49:58'
,
'admin'
,
'2019-10-07 15:32:30'
,
1
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination`
VALUES
(
630880779513237504
,
'2'
,
0
,
'2'
,
'2019-10-07 21:34:53'
,
'2019-10-15 00:00:00'
,
2
,
0
,
NULL
,
NULL
,
'22'
,
'admin'
,
'2019-10-07 21:34:59'
,
'admin'
,
'2019-10-11 22:20:47'
,
1
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination`
VALUES
(
636313595680002048
,
'1'
,
0
,
'1'
,
'2019-12-13 22:33:24'
,
'2019-12-17 22:33:31'
,
1
,
0
,
NULL
,
NULL
,
'1'
,
'admin'
,
'2019-10-22 21:23:03'
,
'admin'
,
'2019-12-14 22:23:58'
,
1
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination`
VALUES
(
672753150888906752
,
'测试考试1'
,
0
,
'测试考试1'
,
'2020-02-08 13:55:39'
,
'2020-02-20 13:55:41'
,
20
,
0
,
NULL
,
590968881187786752
,
'测试考试1'
,
'admin'
,
'2020-01-31 10:40:50'
,
'admin'
,
'2020-02-17 19:11:55'
,
1
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination`
VALUES
(
679446626552647680
,
'测试考试1'
,
0
,
'测试考试1'
,
'2020-02-21 21:58:09'
,
'2020-02-23 00:00:00'
,
50
,
0
,
NULL
,
590968881187786752
,
'测试考试1'
,
'admin'
,
'2020-02-18 21:58:19'
,
'admin'
,
'2020-02-22 13:26:17'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination`
VALUES
(
679446626552647680
,
'测试考试1'
,
0
,
'测试考试1'
,
'2020-03-21 17:08:28'
,
'2020-03-25 00:00:00'
,
50
,
0
,
696436243684265984
,
590968881187786752
,
'测试考试1'
,
'admin'
,
'2020-02-18 21:58:19'
,
'preview'
,
'2020-04-05 19:09:01'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination`
VALUES
(
696328959679401984
,
'测试考试2'
,
0
,
'发的发达'
,
'2020-04-04 12:13:21'
,
'2020-04-08 00:00:00'
,
49
,
0
,
696434412228841472
,
590968881187786752
,
'发达地方'
,
'preview'
,
'2020-04-05 12:02:41'
,
'preview'
,
'2020-04-05 19:01:44'
,
0
,
'EXAM'
,
'gitee'
);
-- ----------------------------
-- Table structure for exam_examination_record
...
...
@@ -118,6 +144,13 @@ CREATE TABLE `exam_examination_record` (
)
ENGINE
=
InnoDB
CHARACTER
SET
=
utf8
COLLATE
=
utf8_general_ci
COMMENT
=
'考试记录表'
ROW_FORMAT
=
Compact
;
-- ----------------------------
-- Records of exam_examination_record
-- ----------------------------
INSERT
INTO
`exam_examination_record`
VALUES
(
691062092169613312
,
596078038307966976
,
679446626552647680
,
'2020-03-21 23:14:02'
,
'2020-03-21 23:17:21'
,
30
,
6
,
1
,
3
,
'admin'
,
'2020-03-21 23:14:02'
,
'anonymousUser'
,
'2020-03-21 23:17:21'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_record`
VALUES
(
691063100123779072
,
596078038307966976
,
679446626552647680
,
'2020-03-21 23:18:02'
,
'2020-03-21 23:18:35'
,
30
,
6
,
1
,
3
,
'admin'
,
'2020-03-21 23:18:02'
,
'admin'
,
'2020-03-21 23:18:35'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_record`
VALUES
(
696330634376908800
,
596307222997372928
,
696328959679401984
,
'2020-04-05 12:09:20'
,
'2020-04-05 12:10:29'
,
20
,
4
,
3
,
3
,
'student'
,
'2020-04-05 12:09:20'
,
'student'
,
'2020-04-05 12:10:29'
,
0
,
'EXAM'
,
'gitee'
);
-- ----------------------------
-- Table structure for exam_examination_subject
-- ----------------------------
DROP
TABLE
IF
EXISTS
`exam_examination_subject`
;
...
...
@@ -168,11 +201,6 @@ INSERT INTO `exam_examination_subject` VALUES (635557908003819520, NULL, 6355558
INSERT
INTO
`exam_examination_subject`
VALUES
(
660248786156785664
,
NULL
,
0
,
660248785791881216
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
660573712369717248
,
NULL
,
0
,
660573712097087488
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
668114910588309504
,
NULL
,
0
,
668114909724282880
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
672815799131574272
,
NULL
,
602231546270846976
,
672815798720532480
,
3
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
672817386306539520
,
NULL
,
602231546270846976
,
672817385757085696
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
672818579904794624
,
NULL
,
602231546270846976
,
672818579560861696
,
3
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
672819333487005696
,
NULL
,
602231546270846976
,
672819333117906944
,
1
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
672824502287208448
,
NULL
,
602231546270846976
,
672824501133774848
,
3
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
679455142529077248
,
679446626552647680
,
NULL
,
679455142176755712
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
679455223491727360
,
679446626552647680
,
NULL
,
679455223147794432
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
679455353464819712
,
679446626552647680
,
NULL
,
679455353129275392
,
0
,
'EXAM'
,
'gitee'
);
...
...
@@ -180,6 +208,20 @@ INSERT INTO `exam_examination_subject` VALUES (679680050186031104, 6794466265526
INSERT
INTO
`exam_examination_subject`
VALUES
(
679680687841873920
,
679446626552647680
,
NULL
,
679680687489552384
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
680037907620302848
,
679446626552647680
,
NULL
,
680037906714333184
,
1
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
680772677467770880
,
679446626552647680
,
NULL
,
680772677350330368
,
2
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
696323940607463424
,
NULL
,
602231546270846976
,
696323940339027968
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
696324258783170560
,
NULL
,
602231546270846976
,
696324258506346496
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
696325065666596864
,
NULL
,
602231546270846976
,
696325065393967104
,
3
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
696325166040485888
,
NULL
,
602231546270846976
,
696325165767856128
,
2
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
696326076326088704
,
NULL
,
602231546270846976
,
696326076057653248
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
696326769229303808
,
NULL
,
602231546270846976
,
696326726975885312
,
1
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
696327229705162752
,
NULL
,
602231546270846976
,
696327229180874752
,
1
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
696329099844653056
,
696328959679401984
,
NULL
,
696329099584606208
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
696329220326035456
,
696328959679401984
,
NULL
,
696329220065988608
,
3
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
696329277674754048
,
696328959679401984
,
NULL
,
696329277397929984
,
2
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
696329333576437760
,
696328959679401984
,
NULL
,
696329333312196608
,
1
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
696329371618775040
,
696328959679401984
,
NULL
,
696329371371311104
,
1
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
696329435779043328
,
696328959679401984
,
602231546270846976
,
696329435527385088
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_examination_subject`
VALUES
(
696329516641030144
,
696328959679401984
,
602231546270846976
,
696329516385177600
,
0
,
'EXAM'
,
'gitee'
);
-- ----------------------------
-- Table structure for exam_knowledge
...
...
@@ -204,7 +246,7 @@ CREATE TABLE `exam_knowledge` (
-- ----------------------------
-- Records of exam_knowledge
-- ----------------------------
INSERT
INTO
`exam_knowledge`
VALUES
(
590978901526843392
,
'四川省2016年普通高考适应性测试'
,
'四川省2016年普通高考适应性测试'
,
590978944174526464
,
0
,
'admin'
,
'2020-02-22 13:26:59'
,
'admin'
,
'2020-02-22 13:16:16
'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_knowledge`
VALUES
(
590978901526843392
,
'四川省2016年普通高考适应性测试'
,
'四川省2016年普通高考适应性测试'
,
696432359691653120
,
1
,
'admin'
,
'2020-04-05 19:04:23'
,
'preview'
,
'2020-04-05 18:53:34
'
,
0
,
'EXAM'
,
'gitee'
);
-- ----------------------------
-- Table structure for exam_pictures
...
...
@@ -323,15 +365,19 @@ INSERT INTO `exam_subject_choices` VALUES (660248785791881216, 0, '1', 0, 'A', 5
INSERT
INTO
`exam_subject_choices`
VALUES
(
660573712097087488
,
0
,
'2'
,
0
,
''
,
5
,
''
,
2
,
'admin'
,
'2019-12-28 20:04:06'
,
'admin'
,
'2019-12-28 20:04:06'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
660944353132417024
,
0
,
'大苏打实打实的'
,
0
,
'A'
,
5
,
'<p>2323为</p>'
,
2
,
'admin'
,
'2019-12-29 20:36:54'
,
'admin'
,
'2019-12-29 20:36:54'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
668114909724282880
,
0
,
'1'
,
0
,
'A'
,
5
,
'555'
,
2
,
'admin'
,
'2020-01-18 15:30:07'
,
'admin'
,
'2020-01-18 15:30:07'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
672815798720532480
,
602231546270846976
,
'1'
,
3
,
',B'
,
5
,
'1'
,
2
,
'admin'
,
'2020-01-31 15:03:38'
,
'admin'
,
'2020-01-31 15:03:38'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
672817385757085696
,
602231546270846976
,
'2'
,
0
,
'B'
,
5
,
'2'
,
2
,
'admin'
,
'2020-01-31 14:56:05'
,
'admin'
,
'2020-01-31 14:56:05'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
672818579560861696
,
602231546270846976
,
'3'
,
3
,
',C'
,
5
,
'3'
,
2
,
'admin'
,
'2020-01-31 15:00:50'
,
'admin'
,
'2020-01-31 15:00:50'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
672824501133774848
,
602231546270846976
,
'1'
,
3
,
',B'
,
5
,
'1'
,
2
,
'admin'
,
'2020-01-31 15:24:22'
,
'admin'
,
'2020-01-31 15:24:22'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
679455142176755712
,
NULL
,
'选择题1'
,
0
,
'A'
,
5
,
'选择题1'
,
2
,
'admin'
,
'2020-02-18 22:32:10'
,
'admin'
,
'2020-02-18 22:32:10'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
679455223147794432
,
NULL
,
'选择题2'
,
0
,
'B'
,
5
,
'选择题2'
,
2
,
'admin'
,
'2020-02-18 22:32:29'
,
'admin'
,
'2020-02-18 22:32:29'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
679455353129275392
,
NULL
,
'选择题3'
,
0
,
'C'
,
5
,
'选择题3'
,
2
,
'admin'
,
'2020-02-18 22:33:00'
,
'admin'
,
'2020-02-18 22:33:00'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
679680049900818432
,
NULL
,
'多选题'
,
3
,
',A,C'
,
5
,
'多选题'
,
2
,
'admin'
,
'2020-02-19 13:25:52'
,
'admin'
,
'2020-02-19 13:25:52'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
679680687489552384
,
NULL
,
'测试两个选项'
,
0
,
'A'
,
5
,
'测试两个选项'
,
2
,
'admin'
,
'2020-02-19 22:08:02'
,
'admin'
,
'2020-02-19 22:08:02'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
679455142176755712
,
NULL
,
'<p>选择题1</p>'
,
0
,
'A'
,
5
,
'选择题1'
,
2
,
'admin'
,
'2020-03-09 22:27:39'
,
'admin'
,
'2020-03-09 22:16:44'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
679455223147794432
,
NULL
,
'<p>选择题2</p>'
,
0
,
'B'
,
5
,
'选择题2'
,
2
,
'admin'
,
'2020-03-09 22:26:16'
,
'admin'
,
'2020-03-09 22:15:20'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
679455353129275392
,
NULL
,
'<p>选择题3</p>'
,
0
,
'C'
,
5
,
'选择题3'
,
2
,
'admin'
,
'2020-03-09 22:26:29'
,
'admin'
,
'2020-03-09 22:15:34'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
679680049900818432
,
NULL
,
'<p>多选题</p>'
,
3
,
'A,C'
,
5
,
'多选题'
,
2
,
'admin'
,
'2020-03-09 22:27:10'
,
'admin'
,
'2020-03-09 22:16:15'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
679680687489552384
,
NULL
,
'<p>测试两个选项</p>'
,
0
,
'A'
,
5
,
'<p>测试两个选项</p>'
,
2
,
'admin'
,
'2020-04-05 11:37:59'
,
'preview'
,
'2020-04-05 11:27:08'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
696323940339027968
,
602231546270846976
,
'<p>单选题1</p>'
,
0
,
'A'
,
5
,
'<p>解析</p>'
,
2
,
'preview'
,
'2020-04-05 11:53:43'
,
'preview'
,
'2020-04-05 11:42:52'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
696324258506346496
,
602231546270846976
,
'<p>单选题2</p>'
,
0
,
'A'
,
5
,
''
,
2
,
'preview'
,
'2020-04-05 11:44:00'
,
'preview'
,
'2020-04-05 11:44:00'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
696325065393967104
,
602231546270846976
,
'<p>测试多选题1</p>'
,
3
,
',B,C'
,
5
,
'<p>测试多选题1</p>'
,
2
,
'preview'
,
'2020-04-05 11:47:13'
,
'preview'
,
'2020-04-05 11:47:13'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
696326076057653248
,
602231546270846976
,
'<p>测试判断题2</p>'
,
0
,
'正确'
,
5
,
'<p>测试判断题2</p>'
,
2
,
'preview'
,
'2020-04-05 11:51:14'
,
'preview'
,
'2020-04-05 11:51:14'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
696329099584606208
,
NULL
,
'<p>单选题</p>'
,
0
,
'A'
,
5
,
'<p>A</p>'
,
2
,
'preview'
,
'2020-04-05 12:03:15'
,
'preview'
,
'2020-04-05 12:03:15'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
696329220065988608
,
NULL
,
'<p>多选题</p>'
,
3
,
',B,C'
,
5
,
'<p>A</p>'
,
2
,
'preview'
,
'2020-04-05 12:03:43'
,
'preview'
,
'2020-04-05 12:03:43'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
696329435527385088
,
602231546270846976
,
'<p>单选题1</p>'
,
0
,
'A'
,
5
,
'<p>解析</p>'
,
2
,
'preview'
,
'2020-04-05 12:04:35'
,
'preview'
,
'2020-04-05 12:04:35'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_choices`
VALUES
(
696329516385177600
,
602231546270846976
,
'<p>打分</p>'
,
0
,
'A'
,
5
,
'<p>发达</p>'
,
2
,
'preview'
,
'2020-04-05 12:04:54'
,
'preview'
,
'2020-04-05 12:04:54'
,
0
,
'EXAM'
,
'gitee'
);
-- ----------------------------
-- Table structure for exam_subject_judgement
...
...
@@ -358,7 +404,9 @@ CREATE TABLE `exam_subject_judgement` (
-- ----------------------------
-- Records of exam_subject_judgement
-- ----------------------------
INSERT
INTO
`exam_subject_judgement`
VALUES
(
680772677350330368
,
NULL
,
'测试判断题'
,
'正确'
,
5
,
'测试判断题'
,
2
,
'admin'
,
'2020-02-22 13:47:34'
,
'admin'
,
'2020-02-22 13:47:34'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_judgement`
VALUES
(
680772677350330368
,
NULL
,
'<p>测试判断题</p>'
,
'正确'
,
5
,
'<p>这是解析</p>'
,
2
,
'admin'
,
'2020-04-03 22:49:02'
,
'preview'
,
'2020-04-03 22:38:06'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_judgement`
VALUES
(
696325165767856128
,
602231546270846976
,
'<p>测试判断题</p>'
,
'正确'
,
5
,
'<p>测试判断题</p>'
,
2
,
'preview'
,
'2020-04-05 12:01:48'
,
'preview'
,
'2020-04-05 11:50:58'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_judgement`
VALUES
(
696329277397929984
,
NULL
,
'<p>判断题</p>'
,
'正确'
,
5
,
'<p>A</p>'
,
2
,
'preview'
,
'2020-04-05 12:03:57'
,
'preview'
,
'2020-04-05 12:03:57'
,
0
,
'EXAM'
,
'gitee'
);
-- ----------------------------
-- Table structure for exam_subject_option
...
...
@@ -595,45 +643,58 @@ INSERT INTO `exam_subject_option` VALUES (672768816400437248, 672768816001978368
INSERT
INTO
`exam_subject_option`
VALUES
(
672768816400437249
,
672768816001978368
,
'B'
,
'选项2'
,
'admin'
,
'2020-01-31 11:43:05'
,
'admin'
,
'2020-01-31 11:43:05'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672768816400437250
,
672768816001978368
,
'C'
,
'选项3'
,
'admin'
,
'2020-01-31 11:43:05'
,
'admin'
,
'2020-01-31 11:43:05'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672768816400437251
,
672768816001978368
,
'D'
,
'选项4'
,
'admin'
,
'2020-01-31 11:43:05'
,
'admin'
,
'2020-01-31 11:43:05'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672815799890743296
,
672815798720532480
,
'A'
,
'1'
,
'admin'
,
'2020-01-31 14:49:47'
,
'admin'
,
'2020-01-31 15:03:38'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672815799890743297
,
672815798720532480
,
'B'
,
'1'
,
'admin'
,
'2020-01-31 14:49:47'
,
'admin'
,
'2020-01-31 15:03:38'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672815799890743298
,
672815798720532480
,
'C'
,
'1'
,
'admin'
,
'2020-01-31 14:49:47'
,
'admin'
,
'2020-01-31 15:03:38'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672815799890743299
,
672815798720532480
,
'D'
,
'1'
,
'admin'
,
'2020-01-31 14:49:47'
,
'admin'
,
'2020-01-31 15:03:38'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672817387019571200
,
672817385757085696
,
'A'
,
'2'
,
'admin'
,
'2020-01-31 14:56:05'
,
'admin'
,
'2020-01-31 14:56:05'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672817387019571201
,
672817385757085696
,
'B'
,
'2'
,
'admin'
,
'2020-01-31 14:56:05'
,
'admin'
,
'2020-01-31 14:56:05'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672817387019571202
,
672817385757085696
,
'C'
,
'2'
,
'admin'
,
'2020-01-31 14:56:05'
,
'admin'
,
'2020-01-31 14:56:05'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672817387019571203
,
672817385757085696
,
'D'
,
'22'
,
'admin'
,
'2020-01-31 14:56:05'
,
'admin'
,
'2020-01-31 14:56:05'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672818580617826304
,
672818579560861696
,
'A'
,
'3'
,
'admin'
,
'2020-01-31 15:00:50'
,
'admin'
,
'2020-01-31 15:00:50'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672818580617826305
,
672818579560861696
,
'B'
,
'3'
,
'admin'
,
'2020-01-31 15:00:50'
,
'admin'
,
'2020-01-31 15:00:50'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672818580617826306
,
672818579560861696
,
'C'
,
'3'
,
'admin'
,
'2020-01-31 15:00:50'
,
'admin'
,
'2020-01-31 15:00:50'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672818580617826307
,
672818579560861696
,
'D'
,
'3'
,
'admin'
,
'2020-01-31 15:00:50'
,
'admin'
,
'2020-01-31 15:00:50'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672824501511262208
,
672824501133774849
,
'A'
,
'1'
,
'admin'
,
'2020-01-31 15:24:22'
,
'admin'
,
'2020-01-31 15:24:22'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672824501511262209
,
672824501133774849
,
'B'
,
'1'
,
'admin'
,
'2020-01-31 15:24:22'
,
'admin'
,
'2020-01-31 15:24:22'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672824501511262210
,
672824501133774849
,
'C'
,
'1'
,
'admin'
,
'2020-01-31 15:24:22'
,
'admin'
,
'2020-01-31 15:24:22'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672824501511262211
,
672824501133774849
,
'D'
,
'1'
,
'admin'
,
'2020-01-31 15:24:22'
,
'admin'
,
'2020-01-31 15:24:22'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672824503025405952
,
672824501133774848
,
'A'
,
'1'
,
'admin'
,
'2020-01-31 15:24:22'
,
'admin'
,
'2020-01-31 15:24:22'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672824503025405953
,
672824501133774848
,
'B'
,
'1'
,
'admin'
,
'2020-01-31 15:24:22'
,
'admin'
,
'2020-01-31 15:24:22'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672824503025405954
,
672824501133774848
,
'C'
,
'1'
,
'admin'
,
'2020-01-31 15:24:22'
,
'admin'
,
'2020-01-31 15:24:22'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
672824503025405955
,
672824501133774848
,
'D'
,
'1'
,
'admin'
,
'2020-01-31 15:24:22'
,
'admin'
,
'2020-01-31 15:24:22'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455143225331712
,
679455142176755712
,
'A'
,
'选择题1'
,
'admin'
,
'2020-02-18 22:32:10'
,
'admin'
,
'2020-02-18 22:32:10'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455143225331713
,
679455142176755712
,
'B'
,
'选择题1'
,
'admin'
,
'2020-02-18 22:32:10'
,
'admin'
,
'2020-02-18 22:32:10'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455143225331714
,
679455142176755712
,
'C'
,
'选择题1'
,
'admin'
,
'2020-02-18 22:32:10'
,
'admin'
,
'2020-02-18 22:32:10'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455143225331715
,
679455142176755712
,
'D'
,
'选择题1'
,
'admin'
,
'2020-02-18 22:32:10'
,
'admin'
,
'2020-02-18 22:32:10'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455224125067264
,
679455223147794432
,
'A'
,
'选择题2'
,
'admin'
,
'2020-02-18 22:32:29'
,
'admin'
,
'2020-02-18 22:32:29'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455224125067265
,
679455223147794432
,
'B'
,
'选择题2'
,
'admin'
,
'2020-02-18 22:32:29'
,
'admin'
,
'2020-02-18 22:32:29'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455224125067266
,
679455223147794432
,
'C'
,
'选择题2'
,
'admin'
,
'2020-02-18 22:32:29'
,
'admin'
,
'2020-02-18 22:32:29'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455224129261568
,
679455223147794432
,
'D'
,
'选择题2'
,
'admin'
,
'2020-02-18 22:32:29'
,
'admin'
,
'2020-02-18 22:32:29'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455354119131136
,
679455353129275392
,
'A'
,
'选择题3'
,
'admin'
,
'2020-02-18 22:33:00'
,
'admin'
,
'2020-02-18 22:33:00'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455354119131137
,
679455353129275392
,
'B'
,
'选择题3'
,
'admin'
,
'2020-02-18 22:33:00'
,
'admin'
,
'2020-02-18 22:33:00'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455354119131138
,
679455353129275392
,
'C'
,
'选择题3'
,
'admin'
,
'2020-02-18 22:33:00'
,
'admin'
,
'2020-02-18 22:33:00'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455354119131139
,
679455353129275392
,
'D'
,
'选择题3'
,
'admin'
,
'2020-02-18 22:33:00'
,
'admin'
,
'2020-02-18 22:33:00'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679680050878091264
,
679680049900818432
,
'A'
,
'多选题'
,
'admin'
,
'2020-02-19 13:25:52'
,
'admin'
,
'2020-02-19 13:25:52'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679680050878091265
,
679680049900818432
,
'B'
,
'多选题'
,
'admin'
,
'2020-02-19 13:25:52'
,
'admin'
,
'2020-02-19 13:25:52'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679680050878091266
,
679680049900818432
,
'C'
,
'多选题'
,
'admin'
,
'2020-02-19 13:25:52'
,
'admin'
,
'2020-02-19 13:25:52'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679680050878091267
,
679680049900818432
,
'D'
,
'多选题'
,
'admin'
,
'2020-02-19 13:25:52'
,
'admin'
,
'2020-02-19 13:25:52'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679680050878091268
,
679680049900818432
,
'E'
,
'多选题'
,
'admin'
,
'2020-02-19 13:25:52'
,
'admin'
,
'2020-02-19 13:25:52'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679680688584265728
,
679680687489552384
,
'A'
,
'测试两个选项'
,
'admin'
,
'2020-02-19 13:28:24'
,
'admin'
,
'2020-02-19 22:08:02'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679680688584265729
,
679680687489552384
,
'B'
,
'测试两个选项'
,
'admin'
,
'2020-02-19 13:28:24'
,
'admin'
,
'2020-02-19 22:08:02'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455143225331712
,
679455142176755712
,
'A'
,
'<p>选择题1</p>'
,
'admin'
,
'2020-02-18 22:32:10'
,
'admin'
,
'2020-03-09 22:16:44'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455143225331713
,
679455142176755712
,
'B'
,
'<p>选择题1</p>'
,
'admin'
,
'2020-02-18 22:32:10'
,
'admin'
,
'2020-03-09 22:16:44'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455143225331714
,
679455142176755712
,
'C'
,
'<p>选择题1</p>'
,
'admin'
,
'2020-02-18 22:32:10'
,
'admin'
,
'2020-03-09 22:16:44'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455143225331715
,
679455142176755712
,
'D'
,
'<p>选择题1</p>'
,
'admin'
,
'2020-02-18 22:32:10'
,
'admin'
,
'2020-03-09 22:16:44'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455224125067264
,
679455223147794432
,
'A'
,
'<p>选择题2</p>'
,
'admin'
,
'2020-02-18 22:32:29'
,
'admin'
,
'2020-03-09 22:15:20'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455224125067265
,
679455223147794432
,
'B'
,
'<p>选择题2</p>'
,
'admin'
,
'2020-02-18 22:32:29'
,
'admin'
,
'2020-03-09 22:15:20'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455224125067266
,
679455223147794432
,
'C'
,
'<p>选择题2</p>'
,
'admin'
,
'2020-02-18 22:32:29'
,
'admin'
,
'2020-03-09 22:15:20'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455224129261568
,
679455223147794432
,
'D'
,
'<p>选择题2</p>'
,
'admin'
,
'2020-02-18 22:32:29'
,
'admin'
,
'2020-03-09 22:15:20'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455354119131136
,
679455353129275392
,
'A'
,
'<p>选择题3</p>'
,
'admin'
,
'2020-02-18 22:33:00'
,
'admin'
,
'2020-03-09 22:15:34'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455354119131137
,
679455353129275392
,
'B'
,
'<p>选择题3</p>'
,
'admin'
,
'2020-02-18 22:33:00'
,
'admin'
,
'2020-03-09 22:15:34'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455354119131138
,
679455353129275392
,
'C'
,
'<p>选择题3</p>'
,
'admin'
,
'2020-02-18 22:33:00'
,
'admin'
,
'2020-03-09 22:15:34'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679455354119131139
,
679455353129275392
,
'D'
,
'<p>选择题3</p>'
,
'admin'
,
'2020-02-18 22:33:00'
,
'admin'
,
'2020-03-09 22:15:34'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679680050878091264
,
679680049900818432
,
'A'
,
'<p>多选题</p>'
,
'admin'
,
'2020-02-19 13:25:52'
,
'admin'
,
'2020-03-09 22:16:15'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679680050878091265
,
679680049900818432
,
'B'
,
'<p>多选题</p>'
,
'admin'
,
'2020-02-19 13:25:52'
,
'admin'
,
'2020-03-09 22:16:15'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679680050878091266
,
679680049900818432
,
'C'
,
'<p>多选题</p>'
,
'admin'
,
'2020-02-19 13:25:52'
,
'admin'
,
'2020-03-09 22:16:15'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679680050878091267
,
679680049900818432
,
'D'
,
'<p>多选题</p>'
,
'admin'
,
'2020-02-19 13:25:52'
,
'admin'
,
'2020-03-09 22:16:15'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679680050878091268
,
679680049900818432
,
'E'
,
'<p>多选题</p>'
,
'admin'
,
'2020-02-19 13:25:52'
,
'admin'
,
'2020-03-09 22:16:15'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679680688584265728
,
679680687489552384
,
'A'
,
'测试两个选项'
,
'admin'
,
'2020-02-19 13:28:24'
,
'admin'
,
'2020-04-05 11:27:08'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
679680688584265729
,
679680687489552384
,
'B'
,
'<p>测试两个选项</p>'
,
'admin'
,
'2020-02-19 13:28:24'
,
'admin'
,
'2020-04-05 11:27:08'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696323941173694464
,
696323940339027968
,
'A'
,
'<p>测试1</p>'
,
'preview'
,
'2020-04-05 11:42:45'
,
'preview'
,
'2020-04-05 11:42:52'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696323941173694465
,
696323940339027968
,
'B'
,
'<p>测试2</p>'
,
'preview'
,
'2020-04-05 11:42:45'
,
'preview'
,
'2020-04-05 11:42:52'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696323941173694466
,
696323940339027968
,
'C'
,
'<p>测试3</p>'
,
'preview'
,
'2020-04-05 11:42:45'
,
'preview'
,
'2020-04-05 11:42:52'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696323941173694467
,
696323940339027968
,
'D'
,
'<p>测试4</p>'
,
'preview'
,
'2020-04-05 11:42:45'
,
'preview'
,
'2020-04-05 11:42:52'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696324259345207296
,
696324258506346496
,
'A'
,
'<p>测试1</p>'
,
'preview'
,
'2020-04-05 11:44:01'
,
'preview'
,
'2020-04-05 11:44:01'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696324259345207297
,
696324258506346496
,
'B'
,
'<p>测试2</p>'
,
'preview'
,
'2020-04-05 11:44:01'
,
'preview'
,
'2020-04-05 11:44:01'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696324259345207298
,
696324258506346496
,
'C'
,
'<p>测试3</p>'
,
'preview'
,
'2020-04-05 11:44:01'
,
'preview'
,
'2020-04-05 11:44:01'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696324259345207299
,
696324258506346496
,
'D'
,
'<p>测试4</p>'
,
'preview'
,
'2020-04-05 11:44:01'
,
'preview'
,
'2020-04-05 11:44:01'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696325066228633600
,
696325065393967104
,
'A'
,
'<p>测试多选题1</p>'
,
'preview'
,
'2020-04-05 11:47:13'
,
'preview'
,
'2020-04-05 11:47:13'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696325066228633601
,
696325065393967104
,
'B'
,
'<p>测试多选题1</p>'
,
'preview'
,
'2020-04-05 11:47:13'
,
'preview'
,
'2020-04-05 11:47:13'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696325066228633602
,
696325065393967104
,
'C'
,
'<p>测试多选题1</p>'
,
'preview'
,
'2020-04-05 11:47:13'
,
'preview'
,
'2020-04-05 11:47:13'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696325066228633603
,
696325065393967104
,
'D'
,
'<p>测试多选题1</p>'
,
'preview'
,
'2020-04-05 11:47:13'
,
'preview'
,
'2020-04-05 11:47:13'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696325066228633604
,
696325065393967104
,
'E'
,
'<p>测试多选题1</p>'
,
'preview'
,
'2020-04-05 11:47:13'
,
'preview'
,
'2020-04-05 11:47:13'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696329100368941056
,
696329099584606208
,
'A'
,
'<p>A</p>'
,
'preview'
,
'2020-04-05 12:03:15'
,
'preview'
,
'2020-04-05 12:03:15'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696329100368941057
,
696329099584606208
,
'B'
,
'<p>B</p>'
,
'preview'
,
'2020-04-05 12:03:15'
,
'preview'
,
'2020-04-05 12:03:15'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696329100368941058
,
696329099584606208
,
'C'
,
'<p>C</p>'
,
'preview'
,
'2020-04-05 12:03:15'
,
'preview'
,
'2020-04-05 12:03:15'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696329100368941059
,
696329099584606208
,
'D'
,
'<p>D</p>'
,
'preview'
,
'2020-04-05 12:03:15'
,
'preview'
,
'2020-04-05 12:03:15'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696329220858712064
,
696329220065988608
,
'A'
,
'<p>A</p>'
,
'preview'
,
'2020-04-05 12:03:43'
,
'preview'
,
'2020-04-05 12:03:43'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696329220858712065
,
696329220065988608
,
'B'
,
'<p>B</p>'
,
'preview'
,
'2020-04-05 12:03:43'
,
'preview'
,
'2020-04-05 12:03:43'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696329220858712066
,
696329220065988608
,
'C'
,
'<p>C</p>'
,
'preview'
,
'2020-04-05 12:03:43'
,
'preview'
,
'2020-04-05 12:03:43'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696329220858712067
,
696329220065988608
,
'D'
,
'<p>D</p>'
,
'preview'
,
'2020-04-05 12:03:43'
,
'preview'
,
'2020-04-05 12:03:43'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696329436286554112
,
696329435527385088
,
'A'
,
'<p>测试1</p>'
,
'preview'
,
'2020-04-05 12:04:35'
,
'preview'
,
'2020-04-05 12:04:35'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696329436286554113
,
696329435527385088
,
'B'
,
'<p>测试2</p>'
,
'preview'
,
'2020-04-05 12:04:35'
,
'preview'
,
'2020-04-05 12:04:35'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696329436286554114
,
696329435527385088
,
'C'
,
'<p>测试3</p>'
,
'preview'
,
'2020-04-05 12:04:35'
,
'preview'
,
'2020-04-05 12:04:35'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696329436286554115
,
696329435527385088
,
'D'
,
'<p>测试4</p>'
,
'preview'
,
'2020-04-05 12:04:35'
,
'preview'
,
'2020-04-05 12:04:35'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696329517161123840
,
696329516385177600
,
'A'
,
'<p>测试1</p>'
,
'preview'
,
'2020-04-05 12:04:54'
,
'preview'
,
'2020-04-05 12:04:54'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696329517161123841
,
696329516385177600
,
'B'
,
'<p>测试2</p>'
,
'preview'
,
'2020-04-05 12:04:54'
,
'preview'
,
'2020-04-05 12:04:54'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696329517161123842
,
696329516385177600
,
'C'
,
'<p>测试3</p>'
,
'preview'
,
'2020-04-05 12:04:54'
,
'preview'
,
'2020-04-05 12:04:54'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_option`
VALUES
(
696329517161123843
,
696329516385177600
,
'D'
,
'<p>测试4</p>'
,
'preview'
,
'2020-04-05 12:04:54'
,
'preview'
,
'2020-04-05 12:04:54'
,
0
,
'EXAM'
,
'gitee'
);
-- ----------------------------
-- Table structure for exam_subject_short_answer
...
...
@@ -660,7 +721,10 @@ CREATE TABLE `exam_subject_short_answer` (
-- ----------------------------
-- Records of exam_subject_short_answer
-- ----------------------------
INSERT
INTO
`exam_subject_short_answer`
VALUES
(
672819333117906944
,
NULL
,
'333'
,
'333'
,
5
,
'3333'
,
2
,
'admin'
,
'2020-01-31 15:03:49'
,
'admin'
,
'2020-01-31 15:03:49'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_short_answer`
VALUES
(
680037906714333184
,
NULL
,
'测试简答题'
,
'测试简答题'
,
5
,
'测试简答题'
,
2
,
'admin'
,
'2020-02-20 13:07:51'
,
'admin'
,
'2020-02-20 13:07:51'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_short_answer`
VALUES
(
680037906714333184
,
NULL
,
'<p>测试简答题</p>'
,
'<p>测试简答题</p>'
,
5
,
'<p>这是答案</p>'
,
4
,
'admin'
,
'2020-04-03 22:44:06'
,
'preview'
,
'2020-04-03 22:33:10'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_short_answer`
VALUES
(
696326726975885312
,
602231546270846976
,
'<p>测试简答题1</p>'
,
'<p>测试简答题1</p>'
,
5
,
'<p>测试简答题1</p>'
,
2
,
'preview'
,
'2020-04-05 12:06:21'
,
'preview'
,
'2020-04-05 11:55:31'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_short_answer`
VALUES
(
696327229180874752
,
602231546270846976
,
'<p>测试简答题2</p>'
,
'<p>测试简答题2</p>'
,
5
,
'<p>测试简答题2</p>'
,
2
,
'preview'
,
'2020-04-05 11:55:49'
,
'preview'
,
'2020-04-05 11:55:49'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_short_answer`
VALUES
(
696329333312196608
,
NULL
,
'<p>简答题</p>'
,
'<p>A</p>'
,
5
,
'<p>B</p>'
,
2
,
'preview'
,
'2020-04-05 12:04:10'
,
'preview'
,
'2020-04-05 12:04:10'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`exam_subject_short_answer`
VALUES
(
696329371371311104
,
NULL
,
'<p>简答题2</p>'
,
'<p>地方大</p>'
,
5
,
'<p>打单发</p>'
,
2
,
'preview'
,
'2020-04-05 12:04:19'
,
'preview'
,
'2020-04-05 12:04:19'
,
0
,
'EXAM'
,
'gitee'
);
SET
FOREIGN_KEY_CHECKS
=
1
;
docs/deploy/mysql/init/microservice_user.sql
View file @
21f4f0c1
SET
NAMES
utf8mb4
;
SET
FOREIGN_KEY_CHECKS
=
0
;
...
...
@@ -8,6 +9,7 @@ DROP TABLE IF EXISTS `sys_attachment`;
CREATE
TABLE
`sys_attachment`
(
`id`
bigint
(
20
)
NOT
NULL
,
`attach_name`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_general_ci
NULL
DEFAULT
NULL
COMMENT
'附件名称'
,
`attach_type`
varchar
(
128
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_general_ci
NULL
DEFAULT
NULL
COMMENT
'附件类型'
,
`attach_size`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_general_ci
NULL
DEFAULT
NULL
COMMENT
'附件大小'
,
`group_name`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_general_ci
NULL
DEFAULT
NULL
COMMENT
'组名称'
,
`fast_file_id`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_general_ci
NULL
DEFAULT
NULL
COMMENT
'文件ID'
,
...
...
@@ -15,6 +17,7 @@ CREATE TABLE `sys_attachment` (
`busi_module`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_general_ci
NULL
DEFAULT
NULL
COMMENT
'业务模块'
,
`busi_type`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_general_ci
NULL
DEFAULT
NULL
COMMENT
'业务类型 0-普通,1-头像'
,
`preview_url`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_general_ci
NULL
DEFAULT
NULL
COMMENT
'预览地址'
,
`upload_type`
tinyint
(
4
)
NULL
DEFAULT
NULL
COMMENT
'上传类型'
,
`creator`
varchar
(
128
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_general_ci
NULL
DEFAULT
NULL
COMMENT
'创建人'
,
`create_date`
timestamp
(
0
)
NOT
NULL
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
(
0
)
COMMENT
'创建时间'
,
`modifier`
varchar
(
128
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_general_ci
NULL
DEFAULT
NULL
COMMENT
'修改人'
,
...
...
@@ -146,7 +149,7 @@ INSERT INTO `sys_menu` VALUES ('571362994005610496', 'zipkin监控', 'monitor:li
INSERT
INTO
`sys_menu`
VALUES
(
'571363268497641472'
,
'服务监控'
,
'monitor:admin'
,
'/api/monitor/**'
,
'571361163502292992'
,
''
,
'33'
,
'0'
,
1
,
'admin'
,
'2019-04-26 15:53:38'
,
'admin'
,
'2020-02-23 16:20:24'
,
'0'
,
'EXAM'
,
NULL
,
'http://118.25.138.130:9186/admin'
,
NULL
,
NULL
,
'gitee'
);
INSERT
INTO
`sys_menu`
VALUES
(
'571363537549660160'
,
'接口文档'
,
'monitor:document'
,
'/api/monitor/**'
,
'571361163502292992'
,
''
,
'34'
,
'0'
,
1
,
'admin'
,
'2019-04-26 15:54:42'
,
'admin'
,
'2020-02-23 16:19:58'
,
'0'
,
'EXAM'
,
NULL
,
'http://118.25.138.130:9180/swagger-ui.html'
,
NULL
,
NULL
,
'gitee'
);
INSERT
INTO
`sys_menu`
VALUES
(
'571364115214372864'
,
'删除日志'
,
'monitor:log:del'
,
NULL
,
'571361526066319360'
,
''
,
'30'
,
'1'
,
1
,
'admin'
,
'2019-04-26 15:57:00'
,
'admin'
,
'2019-04-26 15:57:00'
,
'0'
,
'EXAM'
,
NULL
,
NULL
,
NULL
,
'删除日志'
,
'gitee'
);
INSERT
INTO
`sys_menu`
VALUES
(
'571365178965364736'
,
'首页'
,
'dashboard'
,
'/'
,
'-1'
,
'dashboard'
,
'0'
,
'0'
,
1
,
'admin'
,
'2019-04-26 16:01:14'
,
'admin'
,
'2020-0
2-23 16:17:59'
,
'0'
,
'EXAM'
,
'Layout'
,
'/
dashboard'
,
NULL
,
'首页'
,
'gitee'
);
INSERT
INTO
`sys_menu`
VALUES
(
'571365178965364736'
,
'首页'
,
'dashboard'
,
'/'
,
'-1'
,
'dashboard'
,
'0'
,
'0'
,
1
,
'admin'
,
'2019-04-26 16:01:14'
,
'admin'
,
'2020-0
4-05 19:47:03'
,
'0'
,
'EXAM'
,
'Layout'
,
'
dashboard'
,
NULL
,
'首页'
,
'gitee'
);
INSERT
INTO
`sys_menu`
VALUES
(
'571367565360762880'
,
'系统管理'
,
'sys'
,
'/api/user/v1/**'
,
'-1'
,
'component'
,
'1'
,
'0'
,
1
,
'admin'
,
'2019-04-26 16:10:43'
,
'admin'
,
'2019-05-23 21:52:26'
,
'0'
,
'EXAM'
,
'Layout'
,
'/sys'
,
NULL
,
'系统管理'
,
'gitee'
);
INSERT
INTO
`sys_menu`
VALUES
(
'571367969767165952'
,
'用户管理'
,
'sys:user'
,
'/api/user/v1/user/**'
,
'571367565360762880'
,
''
,
'2'
,
'0'
,
1
,
'admin'
,
'2019-04-26 16:12:19'
,
'admin'
,
'2019-04-26 16:12:19'
,
'0'
,
'EXAM'
,
'views/sys/user'
,
'user'
,
NULL
,
'用户管理'
,
'gitee'
);
INSERT
INTO
`sys_menu`
VALUES
(
'571368181252362240'
,
'部门管理'
,
'sys:dept'
,
'/api/user/v1/dept/**'
,
'571367565360762880'
,
''
,
'8'
,
'0'
,
1
,
'admin'
,
'2019-04-26 16:13:09'
,
'admin'
,
'2019-04-26 16:13:09'
,
'0'
,
'EXAM'
,
'views/sys/dept'
,
'dept'
,
NULL
,
'部门管理'
,
'gitee'
);
...
...
@@ -1243,6 +1246,7 @@ CREATE TABLE `sys_user` (
`login_time`
timestamp
(
0
)
NULL
DEFAULT
NULL
COMMENT
'最后登录时间'
,
`lock_time`
timestamp
(
0
)
NULL
DEFAULT
NULL
COMMENT
'锁定账号时间'
,
`wechat`
varchar
(
128
)
CHARACTER
SET
utf8
COLLATE
utf8_general_ci
NULL
DEFAULT
NULL
COMMENT
'微信号'
,
`signature`
varchar
(
255
)
CHARACTER
SET
utf8
COLLATE
utf8_general_ci
NULL
DEFAULT
NULL
COMMENT
'个性签名'
,
`family_role`
tinyint
(
4
)
NULL
DEFAULT
NULL
COMMENT
'家庭角色'
,
`creator`
varchar
(
255
)
CHARACTER
SET
utf8
COLLATE
utf8_general_ci
NOT
NULL
COMMENT
'创建人'
,
`create_date`
timestamp
(
0
)
NOT
NULL
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
(
0
)
COMMENT
'创建时间'
,
...
...
@@ -1257,10 +1261,10 @@ CREATE TABLE `sys_user` (
-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT
INTO
`sys_user`
VALUES
(
596078038307966976
,
'管理员'
,
'15521089123'
,
'0'
,
'1633736729@qq.com'
,
'
2019-07-01'
,
0
,
0
,
596290673729212416
,
'管理员'
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
'admin'
,
'2020-02-23 16:08:40'
,
'admin'
,
'2020-02-23 15:57:57
'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`sys_user`
VALUES
(
596307222997372928
,
'梁同学'
,
'15521089123'
,
NULL
,
'1633736729@qq.com'
,
'2019-07-01'
,
0
,
1
,
596290673729212416
,
'梁同学'
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
'admin'
,
'2020-02-23 16:08:36'
,
'admin'
,
'2020-02-23 15:57:53
'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`sys_user`
VALUES
(
596332387600830464
,
'林老师'
,
'15521089123'
,
NULL
,
'1633736729@qq.com'
,
'2019-07-03'
,
0
,
1
,
596290673729212416
,
'林老师'
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
'admin'
,
'2020-02-23 16:08:30'
,
'admin'
,
'2020-02-23 15:57:48
'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`sys_user`
VALUES
(
681167776798347264
,
'预览权限'
,
'15521089123'
,
NULL
,
NULL
,
'2020-02-23'
,
0
,
0
,
596290673729212416
,
''
,
596329627606192128
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
'admin'
,
'2020-02-23 16:10:08'
,
'preview'
,
'2020-02-23 15:59:25
'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`sys_user`
VALUES
(
596078038307966976
,
'管理员'
,
'15521089123'
,
'0'
,
'1633736729@qq.com'
,
'
1995-07-03'
,
0
,
0
,
596290673729212416
,
'管理员'
,
NULL
,
NULL
,
NULL
,
530100
,
530000
,
'2020-04-05 19:47:18'
,
NULL
,
NULL
,
'测试'
,
NULL
,
'admin'
,
'2020-04-05 19:58:07'
,
'admin'
,
'2020-04-05 19:47:18
'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`sys_user`
VALUES
(
596307222997372928
,
'梁同学'
,
'15521089123'
,
'0'
,
'1633736729@qq.com'
,
'2019-07-01'
,
0
,
1
,
596290673729212416
,
'梁同学'
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
'2020-04-05 19:36:13'
,
NULL
,
NULL
,
NULL
,
NULL
,
'admin'
,
'2020-04-05 19:56:36'
,
'student'
,
'2020-04-05 19:38:57
'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`sys_user`
VALUES
(
596332387600830464
,
'林老师'
,
'15521089123'
,
NULL
,
'1633736729@qq.com'
,
'2019-07-03'
,
0
,
1
,
596290673729212416
,
'林老师'
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
'admin'
,
'2020-03-05 22:17:01'
,
'admin'
,
'2020-03-05 22:06:27
'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`sys_user`
VALUES
(
681167776798347264
,
'预览权限'
,
'15521089123'
,
'0'
,
NULL
,
'2020-02-23'
,
0
,
0
,
596290673729212416
,
''
,
596329627606192128
,
NULL
,
NULL
,
NULL
,
NULL
,
'2020-04-05 19:30:45'
,
NULL
,
NULL
,
NULL
,
NULL
,
'admin'
,
'2020-04-05 19:56:38'
,
'preview'
,
'2020-04-05 19:30:59
'
,
0
,
'EXAM'
,
'gitee'
);
-- ----------------------------
-- Table structure for sys_user_auths
...
...
@@ -1285,10 +1289,10 @@ CREATE TABLE `sys_user_auths` (
-- ----------------------------
-- Records of sys_user_auths
-- ----------------------------
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
(
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
(
596329627606192128
,
596078038307966976
,
1
,
'admin'
,
'$2a$10$
fi16OaJpNVcMuhudn5pxf.0Um3OI0mOODA9Rx3.oLERDrry9RRCRe'
,
'admin'
,
'2020-02-29 16:13:29
'
,
'admin'
,
'2019-07-04 13:21:02'
,
0
,
'EXAM'
,
'gitee'
);
INSERT
INTO
`sys_user_auths`
VALUES
(
596329627648135168
,
596307222997372928
,
1
,
'student'
,
'$2a$10$
5XMiXaS3XbkZvcdFHFA6HeZGWAfzxQtLVXRZi8Oyic/rbRLExT5Na
'
,
'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$
8CNmKhP0UJm9WVeDRkowteGHtJEz77xUNaKoVQook6ESYemueK8sC
'
,
'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$
tzwo3TcjyyHnX85WlyO2Huq/gdR7gxhNBGrARAl9PctT6AFZ30Dnu
'
,
'admin'
,
'2020-02-23 15:57:34'
,
'admin'
,
'2020-02-23 15:57:34'
,
0
,
'EXAM'
,
'gitee'
);
-- ----------------------------
-- Table structure for sys_user_role
...
...
@@ -1304,11 +1308,10 @@ CREATE TABLE `sys_user_role` (
-- ----------------------------
-- Records of sys_user_role
-- ----------------------------
INSERT
INTO
`sys_user_role`
VALUES
(
681167777393938432
,
681167776798347264
,
681167029125910528
);
INSERT
INTO
`sys_user_role`
VALUES
(
681167778597703680
,
681167776798347264
,
596116511031169024
);
INSERT
INTO
`sys_user_role`
VALUES
(
681167836533624832
,
596332387600830464
,
596330074307956736
);
INSERT
INTO
`sys_user_role`
VALUES
(
681167857941352448
,
596307222997372928
,
596116511031169024
);
INSERT
INTO
`sys_user_role`
VALUES
(
681167874412384256
,
596078038307966976
,
596117256346406912
);
INSERT
INTO
`sys_user_role`
VALUES
(
685246878203383808
,
596332387600830464
,
596330074307956736
);
INSERT
INTO
`sys_user_role`
VALUES
(
686273423307051008
,
681167776798347264
,
681167029125910528
);
-- ----------------------------
-- Table structure for sys_user_student
...
...
docs/deploy/mysql/update.sql
View file @
21f4f0c1
ALTER
TABLE
`microservice-user`
.
`sys_user`
ADD
COLUMN
`signature`
varchar
(
255
)
NULL
COMMENT
'个性签名'
AFTER
`wechat`
;
\ No newline at end of file
ADD
COLUMN
`signature`
varchar
(
255
)
NULL
COMMENT
'个性签名'
AFTER
`wechat`
;
ALTER
TABLE
`microservice-user`
.
`sys_attachment`
ADD
COLUMN
`attach_type`
varchar
(
128
)
NULL
COMMENT
'附件类型'
AFTER
`attach_name`
,
ADD
COLUMN
`upload_type`
tinyint
(
4
)
NULL
COMMENT
'上传类型'
AFTER
`preview_url`
;
\ No newline at end of file
frontend/spring-microservice-exam-miniprogram/readme.md
deleted
100644 → 0
View file @
fd8c285d
frontend/spring-microservice-exam-ui/package.json
View file @
21f4f0c1
{
"name"
:
"spring-microservice-exam-ui"
,
"version"
:
"3.
5
.0"
,
"version"
:
"3.
7
.0"
,
"description"
:
"在线考试"
,
"author"
:
"tangyi <1633736729@qq.com>"
,
"private"
:
true
,
...
...
frontend/spring-microservice-exam-ui/src/api/admin/attachment.js
View file @
21f4f0c1
...
...
@@ -24,9 +24,9 @@ export function getObj (id) {
})
}
export
function
p
review
(
id
)
{
export
function
canP
review
(
id
)
{
return
request
({
url
:
baseAttachmentUrl
+
id
+
'/
p
review'
,
url
:
baseAttachmentUrl
+
id
+
'/
canP
review'
,
method
:
'get'
})
}
...
...
frontend/spring-microservice-exam-ui/src/components/Subjects/Choices/index.vue
View file @
21f4f0c1
<
template
>
<el-form
ref=
"dataSubjectForm"
:rules=
"subjectRules"
:model=
"subjectInfo"
:label-position=
"labelPosition"
label-width=
"100px"
>
<el-row>
<el-col
:span=
"
10
"
>
<el-col
:span=
"
20"
:offset=
"2
"
>
<div
class=
"subject-info"
>
<el-row>
<el-col
:span=
"12"
>
...
...
@@ -17,17 +17,17 @@
</el-row>
<el-row>
<el-col
:span=
"24"
>
<el-form-item
:label=
"$t('table.subjectName')"
prop=
"subjectName"
>
<el-input
v-model=
"subjectInfo.subjectName"
@
focus=
"updateTinymceContent(subjectInfo.subjectName, tinymceEdit.subjectName)"
/>
<el-form-item
:label=
"$t('table.subject.answer')"
prop=
"answer"
>
<el-radio-group
v-model=
"subjectInfo.answer.answer"
>
<el-radio
v-for=
"(option) in options"
:label=
"option.optionName"
:key=
"option.optionName"
>
{{
option
.
optionName
}}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"24"
>
<el-form-item
:label=
"$t('table.subject.answer')"
prop=
"answer"
>
<el-radio-group
v-model=
"subjectInfo.answer.answer"
>
<el-radio
v-for=
"(option) in options"
:label=
"option.optionName"
:key=
"option.optionName"
>
{{
option
.
optionName
}}
</el-radio>
</el-radio-group>
<el-form-item
:label=
"$t('table.subjectName')"
prop=
"subjectName"
>
<tinymce
ref=
"subjectNameEditor"
:height=
"60"
v-model=
"subjectInfo.subjectName"
/>
</el-form-item>
</el-col>
</el-row>
...
...
@@ -35,15 +35,20 @@
<el-col
:span=
"24"
>
<el-divider>
选项列表
</el-divider>
<el-form-item
v-for=
"(option, index) in options"
:label=
"option.optionName"
:key=
"option.optionName"
:prop=
"'options.' + index + '.optionContent'"
>
:prop=
"'options.' + index + '.optionContent'"
label-width=
"15px"
>
<el-row
:gutter=
"5"
>
<el-col
:span=
"
4
"
>
<el-col
:span=
"
2
"
>
<el-input
v-model=
"option.optionName"
/>
</el-col>
<el-col
:span=
"18"
>
<el-input
v-model=
"option.optionContent"
@
input=
"updateTinymceContent(option.optionContent, index, '1')"
>
<el-button
slot=
"append"
@
click
.
prevent=
"removeOption(option)"
>
删除
</el-button>
</el-input>
<el-col
:span=
"21"
>
<el-row
:gutter=
"5"
>
<el-col
:span=
"23"
>
<tinymce
:height=
"60"
v-model=
"option.optionContent"
/>
</el-col>
<el-col
:span=
"1"
>
<el-button
@
click
.
prevent=
"removeOption(option)"
>
删除
</el-button>
</el-col>
</el-row>
</el-col>
</el-row>
</el-form-item>
...
...
@@ -53,17 +58,12 @@
<el-row>
<el-col
:span=
"24"
>
<el-form-item
:label=
"$t('table.subject.analysis')"
prop=
"analysis"
class=
"analysis-form-item"
>
<
el-input
v-model=
"subjectInfo.analysis"
@
input=
"updateTinymceContent(subjectInfo.analysis, tinymceEdit.analysis)
"
/>
<
tinymce
ref=
"analysisEditor"
:height=
"60"
v-model=
"subjectInfo.analysis
"
/>
</el-form-item>
</el-col>
</el-row>
</div>
</el-col>
<el-col
:span=
"14"
>
<div
class=
"subject-tinymce"
>
<tinymce
ref=
"choicesEditor"
:height=
"350"
v-model=
"choicesContent"
@
hasClick=
"hasClick"
/>
</div>
</el-col>
</el-row>
</el-form>
</
template
>
...
...
@@ -124,36 +124,11 @@ export default {
score
:
[{
required
:
true
,
message
:
'请输入题目分值'
,
trigger
:
'change'
}],
answer
:
[{
required
:
true
,
message
:
'请输入答案'
,
trigger
:
'change'
}]
},
tinymce
:
{
type
:
1
,
// 类型 0:题目名称,1:选项
dialogTinymceVisible
:
false
,
tempValue
:
''
,
currentEdit
:
-
1
},
// 编辑对象
tinymceEdit
:
{
subjectName
:
-
1
,
answer
:
4
,
analysis
:
5
},
options
:
[],
optionCollapseActives
:
[
'1'
],
analysisCollapseActives
:
[
'2'
]
}
},
watch
:
{
// 监听富文本编辑器的输入
choicesContent
:
{
handler
:
function
(
choicesContent
)
{
if
(
isNotEmpty
(
this
.
$refs
.
choicesEditor
))
{
if
(
this
.
editType
===
1
&&
this
.
$refs
.
choicesEditor
.
getHasClick
())
{
this
.
saveTinymceContent
(
choicesContent
)
}
}
},
immediate
:
true
}
},
methods
:
{
initDefaultOptions
()
{
this
.
options
=
[
...
...
@@ -162,6 +137,7 @@ export default {
{
subjectChoicesId
:
''
,
optionName
:
'C'
,
optionContent
:
''
},
{
subjectChoicesId
:
''
,
optionName
:
'D'
,
optionContent
:
''
}
]
this
.
subjectInfo
.
answer
.
answer
=
'A'
},
setSubjectInfo
(
subject
)
{
this
.
subjectInfo
=
subject
...
...
@@ -181,36 +157,6 @@ export default {
getChoicesContent
()
{
return
this
.
choicesContent
},
// 绑定富文本的内容
updateTinymceContent
(
content
,
currentEdit
,
type
)
{
// 重置富文本
this
.
choicesContent
=
''
// 绑定当前编辑的对象
this
.
tinymce
.
currentEdit
=
currentEdit
this
.
tinymce
.
type
=
type
// 选择题
this
.
$refs
.
choicesEditor
.
setContent
(
content
||
''
)
this
.
editType
=
0
this
.
$refs
.
choicesEditor
.
setHashClick
(
false
)
},
// 保存题目时绑定富文本的内容到subjectInfo
saveTinymceContent
(
content
)
{
if
(
this
.
tinymce
.
type
!==
'1'
)
{
switch
(
this
.
tinymce
.
currentEdit
)
{
case
this
.
tinymceEdit
.
subjectName
:
this
.
subjectInfo
.
subjectName
=
content
break
case
this
.
tinymceEdit
.
answer
:
this
.
subjectInfo
.
answer
.
answer
=
content
break
case
this
.
tinymceEdit
.
analysis
:
this
.
subjectInfo
.
analysis
=
content
break
}
}
else
{
this
.
options
[
this
.
tinymce
.
currentEdit
].
optionContent
=
content
}
},
// 表单校验
validate
()
{
let
valid
=
false
...
...
@@ -251,6 +197,8 @@ export default {
this
.
subjectInfo
.
score
=
score
}
this
.
initDefaultOptions
()
this
.
$refs
[
'subjectNameEditor'
].
setContent
(
''
)
this
.
$refs
[
'analysisEditor'
].
setContent
(
''
)
},
addOption
()
{
// 校验
...
...
@@ -270,10 +218,6 @@ export default {
if
(
index
!==
-
1
)
{
this
.
options
.
splice
(
index
,
1
)
}
},
// 点击事件回调
hasClick
(
hasClick
)
{
this
.
editType
=
1
}
}
}
...
...
frontend/spring-microservice-exam-ui/src/components/Subjects/Judgement/index.vue
View file @
21f4f0c1
<
template
>
<el-form
ref=
"dataSubjectForm"
:rules=
"subjectRules"
:model=
"subjectInfo"
:label-position=
"labelPosition"
label-width=
"100px"
>
<el-row>
<el-col
:span=
"
10
"
>
<el-col
:span=
"
20"
:offset=
"2
"
>
<div
class=
"subject-info"
>
<el-row>
<el-col
:span=
"12"
>
...
...
@@ -17,34 +17,29 @@
</el-row>
<el-row>
<el-col
:span=
"24"
>
<el-form-item
:label=
"$t('table.subjectName')"
prop=
"subjectName"
>
<el-input
v-model=
"subjectInfo.subjectName"
@
focus=
"updateTinymceContent(subjectInfo.subjectName, tinymceEdit.subjectName)"
/>
<el-form-item
:label=
"$t('table.subject.answer')"
prop=
"answer"
>
<el-radio-group
v-model=
"subjectInfo.answer.answer"
>
<el-radio
v-for=
"(option) in options"
:label=
"option.optionName"
:key=
"option.optionName"
>
{{
option
.
optionName
}}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"24"
>
<el-form-item
:label=
"$t('table.subject.answer')"
prop=
"answer"
>
<el-radio-group
v-model=
"subjectInfo.answer.answer"
>
<el-radio
v-for=
"(option) in options"
:label=
"option.optionName"
:key=
"option.optionName"
>
{{
option
.
optionName
}}
</el-radio>
</el-radio-group>
<el-form-item
:label=
"$t('table.subjectName')"
prop=
"subjectName"
>
<tinymce
ref=
"subjectNameEditor"
:height=
"60"
v-model=
"subjectInfo.subjectName"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"24"
>
<el-form-item
:label=
"$t('table.subject.analysis')"
prop=
"analysis"
class=
"analysis-form-item"
>
<
el-input
v-model=
"subjectInfo.analysis"
@
input=
"updateTinymceContent(subjectInfo.analysis, tinymceEdit.analysis)
"
/>
<
tinymce
ref=
"analysisEditor"
:height=
"60"
v-model=
"subjectInfo.analysis
"
/>
</el-form-item>
</el-col>
</el-row>
</div>
</el-col>
<el-col
:span=
"14"
>
<div
class=
"subject-tinymce"
>
<tinymce
ref=
"choicesEditor"
:height=
"350"
v-model=
"choicesContent"
@
hasClick=
"hasClick"
/>
</div>
</el-col>
</el-row>
</el-form>
</
template
>
...
...
@@ -102,40 +97,16 @@ export default {
score
:
[{
required
:
true
,
message
:
'请输入题目分值'
,
trigger
:
'change'
}],
answer
:
[{
required
:
true
,
message
:
'请输入答案'
,
trigger
:
'change'
}]
},
tinymce
:
{
type
:
1
,
// 类型 0:题目名称,1:选项
dialogTinymceVisible
:
false
,
tempValue
:
''
,
currentEdit
:
-
1
},
// 编辑对象
tinymceEdit
:
{
subjectName
:
-
1
,
answer
:
4
,
analysis
:
5
},
options
:
[]
}
},
watch
:
{
// 监听富文本编辑器的输入
choicesContent
:
{
handler
:
function
(
choicesContent
)
{
if
(
isNotEmpty
(
this
.
$refs
.
choicesEditor
))
{
if
(
this
.
editType
===
1
&&
this
.
$refs
.
choicesEditor
.
getHasClick
())
{
this
.
saveTinymceContent
(
choicesContent
)
}
}
},
immediate
:
true
}
},
methods
:
{
initDefaultOptions
()
{
this
.
options
=
[
{
subjectChoicesId
:
''
,
optionName
:
'正确'
,
optionContent
:
'正确'
},
{
subjectChoicesId
:
''
,
optionName
:
'错误'
,
optionContent
:
'错误'
}
]
this
.
subjectInfo
.
answer
.
answer
=
'正确'
},
setSubjectInfo
(
subject
)
{
this
.
subjectInfo
=
subject
...
...
@@ -144,30 +115,6 @@ export default {
getSubjectInfo
()
{
return
this
.
subjectInfo
},
// 绑定富文本的内容
updateTinymceContent
(
content
,
currentEdit
,
type
)
{
// 重置富文本
this
.
choicesContent
=
''
// 绑定当前编辑的对象
this
.
tinymce
.
currentEdit
=
currentEdit
this
.
tinymce
.
type
=
type
this
.
$refs
.
choicesEditor
.
setContent
(
content
||
''
)
this
.
editType
=
0
this
.
$refs
.
choicesEditor
.
setHashClick
(
false
)
},
saveTinymceContent
(
content
)
{
switch
(
this
.
tinymce
.
currentEdit
)
{
case
this
.
tinymceEdit
.
subjectName
:
this
.
subjectInfo
.
subjectName
=
content
break
case
this
.
tinymceEdit
.
answer
:
this
.
subjectInfo
.
answer
.
answer
=
content
break
case
this
.
tinymceEdit
.
analysis
:
this
.
subjectInfo
.
analysis
=
content
break
}
},
// 表单校验
validate
()
{
let
valid
=
false
...
...
@@ -202,10 +149,8 @@ export default {
this
.
subjectInfo
.
score
=
score
}
this
.
initDefaultOptions
()
},
// 点击事件回调
hasClick
(
hasClick
)
{
this
.
editType
=
1
this
.
$refs
[
'subjectNameEditor'
].
setContent
(
''
)
this
.
$refs
[
'analysisEditor'
].
setContent
(
''
)
}
}
}
...
...
frontend/spring-microservice-exam-ui/src/components/Subjects/MultipleChoices/index.vue
View file @
21f4f0c1
<
template
>
<el-form
ref=
"dataSubjectForm"
:rules=
"subjectRules"
:model=
"subjectInfo"
:label-position=
"labelPosition"
label-width=
"100px"
>
<el-row>
<el-col
:span=
"
10
"
>
<el-col
:span=
"
20"
:offset=
"2
"
>
<div
class=
"subject-info"
v-if=
"subjectInfo.type === 3"
>
<el-row>
<el-col
:span=
"12"
>
...
...
@@ -18,64 +17,53 @@
</el-row>
<el-row>
<el-col
:span=
"24"
>
<el-form-item
:label=
"$t('table.subjectName')"
prop=
"subjectName"
>
<el-input
v-model=
"subjectInfo.subjectName"
/>
<el-form-item
:label=
"$t('table.subject.answer')"
prop=
"answer"
>
<el-checkbox-group
v-model=
"multipleAnswers"
>
<el-checkbox
v-for=
"(option) in options"
:label=
"option.optionName"
:key=
"option.optionName"
:name=
"option.optionName"
>
{{
option
.
optionName
}}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"24"
>
<el-form-item
:label=
"$t('table.subject.answer')"
prop=
"answer"
>
<el-checkbox-group
v-model=
"multipleAnswers"
>
<el-checkbox
v-for=
"(option) in options"
:label=
"option.optionName"
:key=
"option.optionName"
:name=
"option.optionName"
>
{{
option
.
optionName
}}
</el-checkbox>
</el-checkbox-group>
<el-form-item
:label=
"$t('table.subjectName')"
prop=
"subjectName"
>
<tinymce
ref=
"subjectNameEditor"
:height=
"60"
v-model=
"subjectInfo.subjectName"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"24"
>
<el-collapse
v-model=
"optionCollapseActives"
>
<el-collapse-item
title=
"选项列表"
name=
"1"
>
<el-row
class=
"collapse-top"
>
<el-col
:span=
"24"
>
<el-form-item
v-for=
"(option, index) in options"
:label=
"option.optionName"
:key=
"option.optionName"
:prop=
"'options.' + index + '.optionContent'"
>
<el-row
:gutter=
"5"
>
<el-col
:span=
"4"
>
<el-input
v-model=
"option.optionName"
/>
</el-col>
<el-col
:span=
"18"
>
<el-input
v-model=
"option.optionContent"
@
input=
"updateTinymceContent(option.optionContent, index, '1')"
>
<el-button
slot=
"append"
@
click
.
prevent=
"removeOption(option)"
>
删除
</el-button>
</el-input>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"24"
>
<el-button
type=
"success"
@
click
.
prevent=
"addOption()"
style=
"display:block;margin:0 auto"
>
新增选项
</el-button>
</el-col>
</el-row>
</el-collapse-item>
</el-collapse>
<el-divider>
选项列表
</el-divider>
<el-form-item
v-for=
"(option, index) in options"
:label=
"option.optionName"
:key=
"option.optionName"
:prop=
"'options.' + index + '.optionContent'"
label-width=
"15px"
>
<el-row
:gutter=
"5"
>
<el-col
:span=
"2"
>
<el-input
v-model=
"option.optionName"
/>
</el-col>
<el-col
:span=
"21"
>
<el-row
:gutter=
"5"
>
<el-col
:span=
"23"
>
<tinymce
:height=
"60"
v-model=
"option.optionContent"
/>
</el-col>
<el-col
:span=
"1"
>
<el-button
@
click
.
prevent=
"removeOption(option)"
>
删除
</el-button>
</el-col>
</el-row>
</el-col>
</el-row>
</el-form-item>
<el-button
type=
"success"
@
click
.
prevent=
"addOption()"
style=
"display:block;margin:0 auto"
>
新增选项
</el-button>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"24"
>
<el-form-item
:label=
"$t('table.subject.analysis')"
prop=
"analysis"
class=
"analysis-form-item"
>
<
el-input
v-model=
"subjectInfo.analysis"
@
input=
"updateTinymceContent(subjectInfo.analysis, tinymceEdit.analysis)
"
/>
<
tinymce
ref=
"analysisEditor"
:height=
"60"
v-model=
"subjectInfo.analysis
"
/>
</el-form-item>
</el-col>
</el-row>
</div>
</el-col>
<el-col
:span=
"14"
>
<div
class=
"subject-tinymce"
>
<tinymce
ref=
"choicesEditor"
:height=
"350"
v-model=
"choicesContent"
@
hasClick=
"hasClick"
/>
</div>
</el-col>
</el-row>
</el-form>
</
template
>
...
...
@@ -127,37 +115,12 @@ export default {
score
:
[{
required
:
true
,
message
:
'请输入题目分值'
,
trigger
:
'change'
}],
answer
:
[{
required
:
true
,
message
:
'请输入答案'
,
trigger
:
'change'
}]
},
tinymce
:
{
type
:
1
,
// 类型 0:题目名称,1:选项
dialogTinymceVisible
:
false
,
tempValue
:
''
,
currentEdit
:
-
1
},
// 编辑对象
tinymceEdit
:
{
subjectName
:
-
1
,
answer
:
4
,
analysis
:
5
},
options
:
[],
optionCollapseActives
:
[
'1'
],
analysisCollapseActives
:
[
'2'
],
multipleAnswers
:
[]
}
},
watch
:
{
// 监听富文本编辑器的输入
choicesContent
:
{
handler
:
function
(
choicesContent
)
{
if
(
isNotEmpty
(
this
.
$refs
.
choicesEditor
))
{
if
(
this
.
editType
===
1
&&
this
.
$refs
.
choicesEditor
.
getHasClick
())
{
this
.
saveTinymceContent
(
choicesContent
)
}
}
},
immediate
:
true
}
},
methods
:
{
initDefaultOptions
()
{
this
.
options
=
[
...
...
@@ -166,6 +129,7 @@ export default {
{
subjectChoicesId
:
''
,
optionName
:
'C'
,
optionContent
:
''
},
{
subjectChoicesId
:
''
,
optionName
:
'D'
,
optionContent
:
''
}
]
this
.
subjectInfo
.
answer
.
answer
=
'A'
},
setSubjectInfo
(
subject
)
{
this
.
subjectInfo
=
subject
...
...
@@ -187,36 +151,6 @@ export default {
getChoicesContent
()
{
return
this
.
choicesContent
},
// 绑定富文本的内容
updateTinymceContent
(
content
,
currentEdit
,
type
)
{
// 重置富文本
this
.
choicesContent
=
''
// 绑定当前编辑的对象
this
.
tinymce
.
currentEdit
=
currentEdit
this
.
tinymce
.
type
=
type
// 选择题
this
.
$refs
.
choicesEditor
.
setContent
(
content
||
''
)
this
.
editType
=
0
this
.
$refs
.
choicesEditor
.
setHashClick
(
false
)
},
// 保存题目时绑定富文本的内容到subjectInfo
saveTinymceContent
(
content
)
{
if
(
this
.
tinymce
.
type
!==
'1'
)
{
switch
(
this
.
tinymce
.
currentEdit
)
{
case
this
.
tinymceEdit
.
subjectName
:
this
.
subjectInfo
.
subjectName
=
content
break
case
this
.
tinymceEdit
.
answer
:
this
.
subjectInfo
.
answer
.
answer
=
content
break
case
this
.
tinymceEdit
.
analysis
:
this
.
subjectInfo
.
analysis
=
content
break
}
}
else
{
this
.
options
[
this
.
tinymce
.
currentEdit
].
optionContent
=
content
}
},
// 表单校验
validate
()
{
let
valid
=
false
...
...
@@ -257,6 +191,8 @@ export default {
this
.
subjectInfo
.
score
=
score
}
this
.
initDefaultOptions
()
this
.
$refs
[
'subjectNameEditor'
].
setContent
(
''
)
this
.
$refs
[
'analysisEditor'
].
setContent
(
''
)
},
addOption
()
{
// 校验
...
...
@@ -277,10 +213,6 @@ export default {
this
.
options
.
splice
(
index
,
1
)
}
},
// 点击事件回调
hasClick
(
hasClick
)
{
this
.
editType
=
1
},
initMultipleAnswers
()
{
if
(
isNotEmpty
(
this
.
subjectInfo
.
answer
))
{
this
.
multipleAnswers
=
this
.
subjectInfo
.
answer
.
answer
.
split
(
','
)
...
...
frontend/spring-microservice-exam-ui/src/components/Subjects/ShortAnswer/index.vue
View file @
21f4f0c1
<
template
>
<el-form
ref=
"dataSubjectForm"
:rules=
"subjectRules"
:model=
"subjectInfo"
:label-position=
"labelPosition"
label-width=
"100px"
>
<el-row>
<el-col
:span=
"
10
"
>
<el-col
:span=
"
20"
:offset=
"2
"
>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
:label=
"$t('table.subject.score')"
prop=
"score"
>
...
...
@@ -17,30 +17,25 @@
<el-row>
<el-col
:span=
"24"
>
<el-form-item
:label=
"$t('table.subjectName')"
prop=
"subjectName"
>
<
el-input
v-model=
"subjectInfo.subjectName"
@
focus=
"updateTinymceContent(subjectInfo.subjectName, tinymceEdit.subjectName)
"
/>
<
tinymce
ref=
"subjectNameEditor"
:height=
"60"
v-model=
"subjectInfo.subjectName
"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"24"
>
<el-form-item
:label=
"$t('table.subject.answer')"
prop=
"answer"
>
<
el-input
v-model=
"subjectInfo.answer.answer"
@
focus=
"updateTinymceContent(subjectInfo.answer.answer, tinymceEdit.answer)
"
/>
<
tinymce
ref=
"answerEditor"
:height=
"60"
v-model=
"subjectInfo.answer.answer
"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"24"
>
<el-form-item
:label=
"$t('table.subject.analysis')"
prop=
"analysis"
>
<
el-input
v-model=
"subjectInfo.analysis"
@
focus=
"updateTinymceContent(subjectInfo.analysis, tinymceEdit.analysis)
"
/>
<
tinymce
ref=
"analysisEditor"
:height=
"60"
v-model=
"subjectInfo.analysis
"
/>
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col
:span=
"14"
>
<div
class=
"subject-tinymce"
>
<tinymce
ref=
"shortAnswerEditor"
:height=
"350"
v-model=
"shortAnswerEditorContent"
/>
</div>
</el-col>
</el-row>
</el-form>
</
template
>
...
...
@@ -85,37 +80,15 @@ export default {
data
()
{
return
{
subjectInfo
:
this
.
subject
,
shortAnswerEditorContent
:
this
.
content
,
labelPosition
:
'right'
,
// 表单校验规则
subjectRules
:
{
subjectName
:
[{
required
:
true
,
message
:
'请输入题目名称'
,
trigger
:
'change'
}],
score
:
[{
required
:
true
,
message
:
'请输入题目分值'
,
trigger
:
'change'
}],
answer
:
[{
required
:
true
,
message
:
'请输入答案'
,
trigger
:
'change'
}]
},
tinymce
:
{
type
:
1
,
// 类型 0:题目名称,1:选项A,2:选择B,3:选项C,4:选项D
dialogTinymceVisible
:
false
,
tempValue
:
''
,
currentEdit
:
-
1
},
// 编辑对象
tinymceEdit
:
{
subjectName
:
-
1
,
answer
:
4
,
analysis
:
5
}
}
},
watch
:
{
// 监听富文本编辑器的输入
shortAnswerEditorContent
:
{
handler
:
function
(
shortAnswerEditorContent
)
{
this
.
saveTinymceContent
(
shortAnswerEditorContent
)
},
immediate
:
true
}
},
methods
:
{
setSubjectInfo
(
subject
)
{
this
.
subjectInfo
=
subject
...
...
@@ -123,27 +96,6 @@ export default {
getSubjectInfo
()
{
return
this
.
subjectInfo
},
// 绑定富文本的内容
updateTinymceContent
(
content
,
currentEdit
)
{
// 绑定当前编辑的对象
this
.
tinymce
.
currentEdit
=
currentEdit
// 选择题
this
.
$refs
.
shortAnswerEditor
.
setContent
(
content
||
''
)
},
// 保存题目时绑定富文本的内容到subjectInfo
saveTinymceContent
(
content
)
{
switch
(
this
.
tinymce
.
currentEdit
)
{
case
this
.
tinymceEdit
.
subjectName
:
this
.
subjectInfo
.
subjectName
=
content
break
case
this
.
tinymceEdit
.
answer
:
this
.
subjectInfo
.
answer
.
answer
=
content
break
case
this
.
tinymceEdit
.
analysis
:
this
.
subjectInfo
.
analysis
=
content
break
}
},
// 表单校验
validate
()
{
let
valid
=
false
...
...
@@ -177,6 +129,9 @@ export default {
if
(
isNotEmpty
(
score
))
{
this
.
subjectInfo
.
score
=
score
}
this
.
$refs
[
'subjectNameEditor'
].
setContent
(
''
)
this
.
$refs
[
'answerEditor'
].
setContent
(
''
)
this
.
$refs
[
'analysisEditor'
].
setContent
(
''
)
},
initDefaultOptions
()
{
...
...
frontend/spring-microservice-exam-ui/src/components/Tinymce/index.vue
View file @
21f4f0c1
...
...
@@ -32,7 +32,7 @@ export default {
},
menubar
:
{
type
:
String
,
default
:
'
file edit insert view format table
'
default
:
''
},
height
:
{
type
:
Number
,
...
...
@@ -42,8 +42,6 @@ export default {
},
data
()
{
return
{
hasChange
:
false
,
hasClick
:
false
,
hasInit
:
false
,
tinymceId
:
this
.
id
,
fullscreen
:
false
,
...
...
@@ -94,6 +92,7 @@ export default {
toolbar
:
this
.
toolbar
.
length
>
0
?
this
.
toolbar
:
toolbar
,
menubar
:
this
.
menubar
,
plugins
:
plugins
,
external_plugins
:
{
tiny_mce_wiris
:
'https://www.wiris.net/demo/plugins/tiny_mce/plugin.js'
},
end_container_on_empty_block
:
true
,
powerpaste_word_import
:
'clean'
,
code_dialog_height
:
450
,
...
...
@@ -103,6 +102,7 @@ export default {
imagetools_cors_hosts
:
[
'www.tinymce.com'
,
'codepen.io'
],
default_link_target
:
'_blank'
,
link_title
:
false
,
statusbar
:
false
,
nonbreaking_force_tab
:
true
,
// inserting nonbreaking space need Nonbreaking Space Plugin
init_instance_callback
:
editor
=>
{
if
(
_this
.
value
)
{
...
...
@@ -113,11 +113,6 @@ export default {
this
.
hasChange
=
true
this
.
$emit
(
'input'
,
editor
.
getContent
())
})
editor
.
on
(
'Click'
,
()
=>
{
this
.
hasClick
=
true
this
.
$emit
(
'hasClick'
,
this
.
hasClick
)
})
},
setup
(
editor
)
{
editor
.
on
(
'FullscreenStateChanged'
,
(
e
)
=>
{
...
...
@@ -136,12 +131,6 @@ export default {
},
getContent
()
{
return
window
.
tinymce
.
get
(
this
.
tinymceId
).
getContent
()
},
getHasClick
()
{
return
this
.
hasClick
},
setHashClick
(
click
)
{
this
.
hasClick
=
click
}
}
}
...
...
frontend/spring-microservice-exam-ui/src/components/Tinymce/toolbar.js
View file @
21f4f0c1
// Here is a list of the toolbar
// Detail list see https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols
const
toolbar
=
[
'
bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample'
,
'hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor
fullscreen'
]
const
toolbar
=
[
'
tiny_mce_wiris_formulaEditor tiny_mce_wiris_formulaEditorChemistry bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote superscript codesample bullist numlist link image charmap media table forecolor backcolor preview
fullscreen'
]
export
default
toolbar
frontend/spring-microservice-exam-ui/src/lang/zh.js
View file @
21f4f0c1
...
...
@@ -169,6 +169,7 @@ export default {
attachSize
:
'附件大小'
,
upload
:
'上传'
,
download
:
'下载'
,
downloadUrl
:
'复制下载链接'
,
uploader
:
'上传者'
,
uploadDate
:
'上传时间'
,
courseName
:
'课程名称'
,
...
...
frontend/spring-microservice-exam-ui/src/views/attachment/list.vue
View file @
21f4f0c1
...
...
@@ -15,10 +15,10 @@
:data=
"params"
class=
"upload-demo"
multiple
>
<el-button
v-waves
type=
"primary"
class=
"filter-item"
>
上传
<i
class=
"el-icon-upload el-icon--right"
style=
"margin-left: 10px;"
/></el-button>
<el-progress
v-if=
"uploading === true"
:percentage=
"percentage"
:text-inside=
"true"
:stroke-width=
"18"
status=
"success"
/>
<el-button
v-waves
type=
"success"
class=
"filter-item"
>
上传
<i
class=
"el-icon-upload el-icon--right"
style=
"margin-left: 10px;"
/></el-button>
</el-upload>
</div>
<el-progress
v-if=
"uploading === true"
:percentage=
"percentage"
:text-inside=
"true"
:stroke-width=
"18"
status=
"success"
/>
<spinner-loading
v-if=
"listLoading"
/>
<el-table
...
...
@@ -28,7 +28,7 @@
style=
"width: 100%;"
@
sort-change=
"sortChange"
>
<el-table-column
type=
"selection"
width=
"55"
/>
<el-table-column
prop=
"
id"
label=
"流水号
"
min-width=
"100"
>
<el-table-column
prop=
"
流水号"
label=
"id
"
min-width=
"100"
>
<template
slot-scope=
"scope"
>
<span>
{{
scope
.
row
.
id
}}
</span>
</
template
>
...
...
@@ -43,6 +43,11 @@
<span>
{{
scope
.
row
.
busiType
|
attachmentTypeFilter
}}
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"附件大小"
min-width=
"90"
>
<
template
slot-scope=
"scope"
>
<span>
{{
scope
.
row
.
attachSize
|
attachmentSizeFilter
}}
</span>
</
template
>
</el-table-column>
<el-table-column
:label=
"$t('table.uploader')"
min-width=
"50"
>
<
template
slot-scope=
"scope"
>
<span>
{{
scope
.
row
.
creator
}}
</span>
...
...
@@ -50,14 +55,38 @@
</el-table-column>
<el-table-column
:label=
"$t('table.uploadDate')"
min-width=
"70"
>
<
template
slot-scope=
"scope"
>
<span>
{{
scope
.
row
.
createDate
|
timeFilter
}}
</span>
<span>
{{
scope
.
row
.
createDate
|
fmtDate
(
'yyyy-MM-dd hh:mm'
)
}}
</span>
</
template
>
</el-table-column>
<el-table-column
:label=
"$t('table.actions')"
class-name=
"status-col"
width=
"
300px
"
>
<el-table-column
:label=
"$t('table.actions')"
class-name=
"status-col"
width=
"
100
"
>
<
template
slot-scope=
"scope"
>
<el-button
type=
"text"
@
click=
"handleDownload(scope.row)"
>
{{
$t
(
'table.download'
)
}}
</el-button>
<el-button
type=
"text"
@
click=
"handleDelete(scope.row)"
>
{{
$t
(
'table.delete'
)
}}
</el-button>
<el-dropdown>
<span
class=
"el-dropdown-link"
>
操作
<i
class=
"el-icon-caret-bottom el-icon--right"
></i>
</span>
<el-dropdown-menu
slot=
"dropdown"
>
<el-dropdown-item>
<a
@
click=
"handlePreview(scope.row)"
>
<span><i
class=
"el-icon-view"
></i>
{{
$t
(
'table.preview'
)
}}
</span>
</a>
</el-dropdown-item>
<el-dropdown-item>
<a
@
click=
"handleDownloadUrl(scope.row)"
>
<span><i
class=
"el-icon-document-copy"
></i>
{{
$t
(
'table.downloadUrl'
)
}}
</span>
</a>
</el-dropdown-item>
<el-dropdown-item>
<a
@
click=
"handleDownload(scope.row)"
>
<span><i
class=
"el-icon-download"
></i>
{{
$t
(
'table.download'
)
}}
</span>
</a>
</el-dropdown-item>
<el-dropdown-item>
<a
@
click=
"handleDelete(scope.row)"
>
<span><i
class=
"el-icon-delete"
></i>
{{
$t
(
'table.delete'
)
}}
</span>
</a>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</
template
>
</el-table-column>
</el-table>
...
...
@@ -65,14 +94,21 @@
<div
class=
"pagination-container"
>
<el-pagination
v-show=
"total>0"
:current-page=
"listQuery.pageNum"
:page-sizes=
"[10,20,30, 50]"
:page-size=
"listQuery.pageSize"
:total=
"total"
background
layout=
"total, sizes, prev, pager, next, jumper"
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
/>
</div>
<!-- 预览 -->
<el-dialog
:visible
.
sync=
"dialogPreviewVisible"
title=
"预览"
width=
"50%"
top=
"12vh"
>
<div
class=
"preview"
>
<img
:src=
"previewUrl"
alt=
"二维码"
>
</div>
</el-dialog>
</div>
</template>
<
script
>
import
{
fetchList
,
addObj
,
putObj
,
delAttachment
,
getDownloadUrl
}
from
'@/api/admin/attachment'
import
{
fetchList
,
addObj
,
putObj
,
delAttachment
,
canPreview
}
from
'@/api/admin/attachment'
import
waves
from
'@/directive/waves'
import
{
getToken
}
from
'@/utils/auth'
// getToken from cookie
import
{
notifySuccess
,
messageSuccess
,
isNotEmpty
,
formatDate
}
from
'@/utils/util'
import
{
getToken
}
from
'@/utils/auth'
import
{
messageSuccess
,
messageWarn
}
from
'@/utils/util'
import
SpinnerLoading
from
'@/components/SpinnerLoading'
export
default
{
...
...
@@ -105,8 +141,16 @@ export default {
}
return
attachType
},
timeFilter
(
time
)
{
return
formatDate
(
new
Date
(
time
),
'yyyy-MM-dd hh:mm'
)
attachmentSizeFilter
(
attachSize
)
{
let
fileSizeByte
=
attachSize
let
fileSizeMsg
=
''
if
(
fileSizeByte
<
1048576
)
fileSizeMsg
=
(
fileSizeByte
/
1024
).
toFixed
(
2
)
+
'KB'
else
if
(
fileSizeByte
===
1048576
)
fileSizeMsg
=
'1MB'
else
if
(
fileSizeByte
>
1048576
&&
fileSizeByte
<
1073741824
)
fileSizeMsg
=
(
fileSizeByte
/
(
1024
*
1024
)).
toFixed
(
2
)
+
'MB'
else
if
(
fileSizeByte
>
1048576
&&
fileSizeByte
===
1073741824
)
fileSizeMsg
=
'1GB'
else
if
(
fileSizeByte
>
1073741824
&&
fileSizeByte
<
1099511627776
)
fileSizeMsg
=
(
fileSizeByte
/
(
1024
*
1024
*
1024
)).
toFixed
(
2
)
+
'GB'
else
fileSizeMsg
=
'文件超过1TB'
return
fileSizeMsg
}
},
data
()
{
...
...
@@ -151,7 +195,9 @@ export default {
}
],
uploading
:
false
,
percentage
:
0
percentage
:
0
,
dialogPreviewVisible
:
false
,
previewUrl
:
''
}
},
created
()
{
...
...
@@ -204,25 +250,38 @@ export default {
addObj
(
this
.
temp
).
then
(()
=>
{
this
.
list
.
unshift
(
this
.
temp
)
this
.
getList
()
notify
Success
(
this
,
'创建成功'
)
message
Success
(
this
,
'创建成功'
)
})
}
})
},
handleDownload
(
row
)
{
getDownloadUrl
(
row
.
id
).
then
(
response
=>
{
if
(
isNotEmpty
(
response
.
data
))
{
window
.
open
(
'http://'
+
response
.
data
.
data
,
'_blank'
)
window
.
location
.
href
=
'/api/user/v1/attachment/download?id='
+
row
.
id
},
handlePreview
(
row
)
{
this
.
previewUrl
=
''
canPreview
(
row
.
id
).
then
(
response
=>
{
if
(
response
.
data
.
data
)
{
this
.
previewUrl
=
'/api/user/v1/attachment/preview?id='
+
row
.
id
this
.
dialogPreviewVisible
=
true
}
else
{
messageWarn
(
this
,
'暂不支持预览该格式的附件'
)
}
}).
catch
(
error
=>
{
console
.
error
(
error
)
})
},
handleDownloadUrl
(
row
)
{
const
url
=
'http://'
+
window
.
location
.
host
+
'/api/user/v1/attachment/download?id='
+
row
.
id
this
.
$alert
(
url
,
'下载链接'
,
{
confirmButtonText
:
'确定'
})
},
updateData
()
{
this
.
$refs
[
'dataForm'
].
validate
((
valid
)
=>
{
if
(
valid
)
{
const
tempData
=
Object
.
assign
({},
this
.
temp
)
putObj
(
tempData
).
then
(()
=>
{
this
.
getList
()
notify
Success
(
this
,
'更新成功'
)
message
Success
(
this
,
'更新成功'
)
})
}
})
...
...
@@ -236,14 +295,14 @@ export default {
}).
then
(()
=>
{
delAttachment
(
row
.
id
).
then
(()
=>
{
this
.
getList
()
notify
Success
(
this
,
'删除成功'
)
message
Success
(
this
,
'删除成功'
)
})
}).
catch
(()
=>
{})
},
handleUploadSuccess
()
{
this
.
uploading
=
false
this
.
getList
()
notify
Success
(
this
,
'上传成功'
)
message
Success
(
this
,
'上传成功'
)
},
handleUploadProgress
(
event
,
file
,
fileList
)
{
this
.
uploading
=
true
...
...
@@ -252,3 +311,13 @@ export default {
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.upload-demo
{
display
:
inline-block
;
}
.preview
{
text-align
:
center
;
overflow
:
hidden
;
}
</
style
>
frontend/spring-microservice-exam-ui/src/views/exam/exam.vue
View file @
21f4f0c1
...
...
@@ -234,7 +234,7 @@ import waves from '@/directive/waves'
import
{
mapGetters
,
mapState
}
from
'vuex'
import
{
getToken
}
from
'@/utils/auth'
import
{
checkMultipleSelect
,
isNotEmpty
,
notifySuccess
,
notifyFail
,
messageSuccess
}
from
'@/utils/util'
import
{
delAttachment
,
preview
}
from
'@/api/admin/attachment'
import
{
delAttachment
}
from
'@/api/admin/attachment'
import
Tinymce
from
'@/components/Tinymce'
import
SpinnerLoading
from
'@/components/SpinnerLoading'
import
Choices
from
'@/components/Subjects/Choices'
...
...
@@ -465,6 +465,7 @@ export default {
},
handleUpdate
(
row
)
{
this
.
temp
=
Object
.
assign
({},
row
)
this
.
avatar
=
''
if
(
!
isNotEmpty
(
this
.
temp
.
course
))
{
this
.
temp
.
course
=
{
id
:
''
,
...
...
@@ -473,9 +474,7 @@ export default {
}
// 获取图片的预览地址
if
(
isNotEmpty
(
this
.
temp
.
avatarId
))
{
preview
(
this
.
temp
.
avatarId
).
then
(
response
=>
{
this
.
avatar
=
response
.
data
.
data
})
this
.
avatar
=
'/api/user/v1/attachment/preview?id='
+
this
.
temp
.
avatarId
}
this
.
dialogStatus
=
'update'
this
.
dialogFormVisible
=
true
...
...
frontend/spring-microservice-exam-ui/src/views/exam/examSubjects.vue
View file @
21f4f0c1
...
...
@@ -394,7 +394,6 @@ export default {
</
script
>
<
style
lang=
"scss"
rel=
"stylesheet/scss"
scoped
>
/* 题目 */
.subject-title
{
font-size
:
18px
;
line-height
:
22px
;
...
...
frontend/spring-microservice-exam-ui/src/views/exam/subject.vue
View file @
21f4f0c1
...
...
@@ -86,6 +86,11 @@
<span><i
class=
"el-icon-edit"
></i>
{{
$t
(
'table.edit'
)
}}
</span>
</a>
</el-dropdown-item>
<el-dropdown-item>
<a
@
click=
"handleViewSubject(scope.row)"
>
<span><i
class=
"el-icon-view"
></i>
{{
$t
(
'table.preview'
)
}}
</span>
</a>
</el-dropdown-item>
<el-dropdown-item
v-if=
"subject_bank_btn_del"
>
<a
@
click=
"handleDeleteSubject(scope.row)"
>
<span><i
class=
"el-icon-delete"
></i>
{{
$t
(
'table.delete'
)
}}
</span>
...
...
@@ -183,12 +188,39 @@
</el-col>
</el-row>
</el-dialog>
<!-- 预览题目 -->
<el-dialog
title=
"预览题目"
:visible
.
sync=
"dialogViewVisible"
width=
"60%"
top=
"10vh"
>
<div
class=
"subject-title"
>
<span
class=
"subject-title-content"
v-html=
"tempSubject.subjectName"
/>
<span
class=
"subject-title-content"
>
({{tempSubject.score}})分
</span>
</div>
<ul
v-if=
"tempSubject.type === 0 || tempSubject.type === 3"
class=
"subject-options"
>
<li
class=
"subject-option"
v-for=
"(option) in tempSubject.options"
:key=
"option.id"
>
<input
class=
"toggle"
type=
"checkbox"
>
<label><span
class=
"subject-option-prefix"
>
{{option.optionName}}
</span><span
v-html=
"option.optionContent"
class=
"subject-option-prefix"
></span></label>
</li>
</ul>
<ul
v-if=
"tempSubject.type === 2"
class=
"subject-options"
>
<li
class=
"subject-option"
>
<input
class=
"toggle"
type=
"checkbox"
>
<label><span
class=
"subject-option-prefix"
>
正确
</span></label>
</li>
<li
class=
"subject-option"
>
<input
class=
"toggle"
type=
"checkbox"
>
<label><span
class=
"subject-option-prefix"
>
错误
</span></label>
</li>
</ul>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
type=
"primary"
@
click=
"dialogViewVisible = false"
>
{{ $t('table.confirm') }}
</el-button>
</div>
</el-dialog>
</div>
</template>
<
script
>
import
{
fetchCategoryTree
,
getCategory
,
addCategory
,
delCategory
,
putCategory
}
from
'@/api/exam/subjectCategory'
import
{
fetchSubjectList
,
addSubject
,
putSubject
,
delSubject
,
delAllSubject
,
exportSubject
}
from
'@/api/exam/subject'
import
{
fetchSubjectList
,
addSubject
,
getSubject
,
putSubject
,
delSubject
,
delAllSubject
,
exportSubject
}
from
'@/api/exam/subject'
import
{
mapGetters
}
from
'vuex'
import
{
getToken
}
from
'@/utils/auth'
import
{
checkMultipleSelect
,
exportExcel
,
notifySuccess
,
isNotEmpty
}
from
'@/utils/util'
...
...
@@ -308,6 +340,8 @@ export default {
dialogImportVisible
:
false
,
// 导出窗口状态
dialogExportVisible
:
false
,
// 预览窗口状态
dialogViewVisible
:
false
,
// 选择的菜单
multipleSelection
:
[],
importUrl
:
'/api/exam/v1/subject/import'
,
...
...
@@ -699,6 +733,14 @@ export default {
}).
catch
(()
=>
{})
}
},
// 查看题目
handleViewSubject
(
row
)
{
// 加载题目信息
getSubject
(
row
.
id
,
{
type
:
row
.
type
}).
then
(
response
=>
{
this
.
tempSubject
=
response
.
data
.
data
this
.
dialogViewVisible
=
true
})
},
// 点击排序按钮
sortSubjectChange
(
column
,
prop
,
order
)
{
this
.
listQuery
.
sort
=
column
.
prop
...
...
@@ -813,16 +855,88 @@ export default {
}
</
script
>
<
style
scoped
>
<
style
lang=
"scss"
rel=
"stylesheet/scss"
scoped
>
.category-header
{
margin
:
12px
;
}
.tree-container
{
.tree-container
{
padding-top
:
10px
;
}
.category-btn
{
margin
:
5px
;
padding
:
6px
13px
;
}
.filter-tree
{
overflow
:
hidden
;
}
.subject-title
{
font-size
:
18px
;
line-height
:
22px
;
.subject-title-number
{
display
:
inline-block
;
line-height
:
22px
;
}
.subject-title-content
{
display
:
inline-block
;
}
}
.subject-options
{
margin
:
0
;
padding
:
0
;
list-style
:
none
;
>
li
{
position
:
relative
;
font-size
:
24px
;
.toggle
{
opacity
:
0
;
text-align
:
center
;
width
:
35px
;
/* auto, since non-WebKit browsers doesn't support input styling */
height
:
auto
;
position
:
absolute
;
top
:
0
;
bottom
:
0
;
margin
:
auto
0
;
border
:
none
;
/* Mobile Safari */
-webkit-appearance
:
none
;
appearance
:
none
;
}
.toggle
+
label
{
background-image
:
url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E')
;
background-repeat
:
no-repeat
;
background-position
:
center
left
;
background-size
:
30px
;
}
.toggle
:checked
+
label
{
background-size
:
30px
;
background-image
:
url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E')
;
}
label
{
word-break
:
break-all
;
padding
:
10px
10px
10px
45px
;
display
:
block
;
line-height
:
1
.0
;
transition
:
color
0
.4s
;
}
/* 选项名称 */
.subject-option-prefix
{
font-size
:
16px
;
display
:
inline-block
}
}
}
</
style
>
frontend/spring-microservice-exam-ui/src/views/personal/message.vue
View file @
21f4f0c1
...
...
@@ -95,7 +95,6 @@
import
{
updateObjInfo
,
updateAvatar
}
from
'@/api/admin/user'
import
{
mapState
}
from
'vuex'
import
{
getToken
}
from
'@/utils/auth'
import
{
preview
}
from
'@/api/admin/attachment'
import
{
isNotEmpty
,
notifySuccess
,
notifyFail
}
from
'@/utils/util'
import
store
from
'@/store'
...
...
@@ -152,9 +151,7 @@ export default {
return
}
// 重新获取预览地址
preview
(
res
.
data
.
id
).
then
(
response
=>
{
this
.
userInfo
.
avatarUrl
=
response
.
data
.
data
})
this
.
userInfo
.
avatarUrl
=
'/api/user/v1/attachment/preview?id='
+
res
.
data
.
id
this
.
userInfo
.
avatarId
=
res
.
data
.
id
updateAvatar
(
this
.
userInfo
).
then
(
response
=>
{
notifySuccess
(
this
,
'头像上传成功'
)
...
...
frontend/spring-microservice-exam-ui/src/views/sys/menu.vue
View file @
21f4f0c1
...
...
@@ -428,4 +428,7 @@ export default {
.tab-container
{
margin
:
30px
;
}
.filter-tree
{
overflow
:
hidden
;
}
</
style
>
frontend/spring-microservice-exam-ui/static/img/login_bg.jpeg
0 → 100644
View file @
21f4f0c1
243 KB
frontend/spring-microservice-exam-web/package.json
View file @
21f4f0c1
{
"name"
:
"spring-microservice-exam-web"
,
"version"
:
"3.
5
.0"
,
"version"
:
"3.
7
.0"
,
"description"
:
"spring-microservice-exam-web"
,
"author"
:
"tangyi <1633736729@qq.com>"
,
"private"
:
true
,
...
...
frontend/spring-microservice-exam-web/src/views/Index.vue
View file @
21f4f0c1
...
...
@@ -45,7 +45,7 @@
</el-submenu>
<el-submenu
v-if=
"login"
index=
"/user-info"
>
<
template
slot=
"title"
>
<img
src=
"https://colorlib.com/preview/theme/clever/img/bg-img/t1.png
"
style=
"height: 30px;border-radius: 50%;margin-right: 6px;"
/>
<img
:src=
"userInfo.avatarUrl
"
style=
"height: 30px;border-radius: 50%;margin-right: 6px;"
/>
{{
userInfo
.
identifier
}}
</
template
>
<el-menu-item
index=
"account"
@
click=
"open('/account')"
>
个人中心
</el-menu-item>
...
...
frontend/spring-microservice-exam-web/src/views/common/header.vue
View file @
21f4f0c1
...
...
@@ -44,7 +44,7 @@
</el-submenu>
<el-submenu
v-if=
"login"
index=
"/user-info"
>
<
template
slot=
"title"
>
<img
src=
"https://colorlib.com/preview/theme/clever/img/bg-img/t1.png
"
style=
"height: 30px;border-radius: 50%;margin-right: 6px;"
/>
<img
:src=
"userInfo.avatarUrl
"
style=
"height: 30px;border-radius: 50%;margin-right: 6px;"
/>
{{
userInfo
.
identifier
}}
</
template
>
<el-menu-item
index=
"account"
@
click=
"open('/account')"
>
个人中心
</el-menu-item>
...
...
frontend/spring-microservice-exam-web/src/views/personal/account.vue
View file @
21f4f0c1
...
...
@@ -91,7 +91,6 @@ import { updateObjInfo, updateAvatar } from '@/api/admin/user'
import
OFooter
from
'../common/footer'
import
{
getToken
}
from
'@/utils/auth'
import
{
mapState
}
from
'vuex'
import
{
preview
}
from
'@/api/admin/attachment'
import
{
isNotEmpty
,
notifySuccess
,
notifyFail
}
from
'@/utils/util'
import
store
from
'@/store'
...
...
@@ -144,14 +143,12 @@ export default {
})
},
handleAvatarSuccess
(
res
,
file
)
{
if
(
!
isNotEmpty
(
res
.
data
)
||
!
isNotEmpty
(
res
.
data
.
fastFileId
)
)
{
if
(
!
isNotEmpty
(
res
.
data
))
{
notifyFail
(
this
,
'头像上传失败'
)
return
}
// 重新获取预览地址
preview
(
res
.
data
.
id
).
then
(
response
=>
{
this
.
userInfo
.
avatarUrl
=
response
.
data
.
data
})
this
.
userInfo
.
avatarUrl
=
'/api/user/v1/attachment/preview?id='
+
res
.
data
.
id
this
.
userInfo
.
avatarId
=
res
.
data
.
id
updateAvatar
(
this
.
userInfo
).
then
(
response
=>
{
notifySuccess
(
this
,
'头像上传成功'
)
...
...
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/service/CourseService.java
View file @
21f4f0c1
...
...
@@ -6,6 +6,7 @@ import com.github.tangyi.common.core.constant.CommonConstant;
import
com.github.tangyi.common.core.service.CrudService
;
import
com.github.tangyi.exam.api.module.Course
;
import
com.github.tangyi.exam.mapper.CourseMapper
;
import
com.github.tangyi.user.api.constant.AttachmentConstant
;
import
com.github.tangyi.user.api.module.Attachment
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
...
...
@@ -141,9 +142,7 @@ public class CourseService extends CrudService<CourseMapper, Course> {
courseList
.
forEach
(
course
->
{
// 获取配置默认头像地址
if
(
course
.
getLogoId
()
!=
null
&&
course
.
getLogoId
()
!=
0L
)
{
Attachment
attachment
=
new
Attachment
();
attachment
.
setId
(
course
.
getLogoId
());
course
.
setLogoUrl
(
sysProperties
.
getLogoUrl
()
+
course
.
getLogoId
()
+
sysProperties
.
getLogoSuffix
());
course
.
setLogoUrl
(
AttachmentConstant
.
ATTACHMENT_PREVIEW_URL
+
course
.
getLogoId
());
}
else
{
Long
index
=
new
Random
().
nextInt
(
sysProperties
.
getLogoCount
())
+
1L
;
course
.
setLogoUrl
(
sysProperties
.
getLogoUrl
()
+
index
+
sysProperties
.
getLogoSuffix
());
...
...
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/service/ExaminationService.java
View file @
21f4f0c1
...
...
@@ -14,6 +14,7 @@ import com.github.tangyi.exam.api.module.Examination;
import
com.github.tangyi.exam.api.module.ExaminationSubject
;
import
com.github.tangyi.exam.enums.ExaminationTypeEnum
;
import
com.github.tangyi.exam.mapper.ExaminationMapper
;
import
com.github.tangyi.user.api.constant.AttachmentConstant
;
import
com.github.tangyi.user.api.module.Attachment
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
...
...
@@ -297,7 +298,7 @@ public class ExaminationService extends CrudService<ExaminationMapper, Examinati
if
(
examinationDto
.
getAvatarId
()
!=
null
&&
examinationDto
.
getAvatarId
()
!=
0L
)
{
Attachment
attachment
=
new
Attachment
();
attachment
.
setId
(
examinationDto
.
getAvatarId
());
examinationDto
.
setLogoUrl
(
sysProperties
.
getLogoUrl
()
+
examinationDto
.
getAvatarId
()
+
sysProperties
.
getLogoSuffix
());
examinationDto
.
setLogoUrl
(
AttachmentConstant
.
ATTACHMENT_PREVIEW_URL
+
examinationDto
.
getAvatarId
());
}
else
{
Long
index
=
new
Random
().
nextInt
(
sysProperties
.
getLogoCount
())
+
1L
;
examinationDto
.
setLogoUrl
(
sysProperties
.
getLogoUrl
()
+
index
+
sysProperties
.
getLogoSuffix
());
...
...
modules/user-service-parent/user-service-api/src/main/java/com/github/tangyi/user/api/constant/AttachmentConstant.java
View file @
21f4f0c1
...
...
@@ -20,4 +20,9 @@ public class AttachmentConstant {
* 知识库附件
*/
public
static
final
String
BUSI_TYPE_KNOWLEDGE_ATTACHMENT
=
"2"
;
/**
* 附件预览地址
*/
public
static
final
String
ATTACHMENT_PREVIEW_URL
=
"/api/user/v1/attachment/preview?id="
;
}
modules/user-service-parent/user-service-api/src/main/java/com/github/tangyi/user/api/module/Attachment.java
View file @
21f4f0c1
package
com
.
github
.
tangyi
.
user
.
api
.
module
;
import
com.fasterxml.jackson.annotation.JsonIgnore
;
import
com.github.tangyi.common.core.persistence.BaseEntity
;
import
com.github.tangyi.user.api.constant.AttachmentConstant
;
import
lombok.Data
;
import
javax.validation.constraints.NotBlank
;
/**
* 附件信息
*
...
...
@@ -18,16 +17,19 @@ public class Attachment extends BaseEntity<Attachment> {
/**
* 附件名称
*/
@NotBlank
(
message
=
"附件名称不能为空"
)
private
String
attachName
;
/**
* 附件大小
*/
@NotBlank
(
message
=
"附件大小不能为空"
)
private
String
attachSize
;
/**
* 附件类型
*/
private
String
attachType
;
/**
* 组名称
*/
private
String
groupName
;
...
...
@@ -35,12 +37,12 @@ public class Attachment extends BaseEntity<Attachment> {
/**
* 文件ID
*/
@JsonIgnore
private
String
fastFileId
;
/**
* 业务流水号
*/
@NotBlank
(
message
=
"附件业务流水号不能为空"
)
private
String
busiId
;
/**
...
...
@@ -57,4 +59,14 @@ public class Attachment extends BaseEntity<Attachment> {
* 预览地址
*/
private
String
previewUrl
;
/**
* 上传类型,1:本地目录,2:fastDfs,3:七牛云
*/
private
Integer
uploadType
;
/**
* 上传结果
*/
private
String
uploadResult
;
}
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/controller/AttachmentController.java
View file @
21f4f0c1
package
com
.
github
.
tangyi
.
user
.
controller
;
import
com.github.pagehelper.PageInfo
;
import
com.github.tangyi.common.basic.properties.SysProperties
;
import
com.github.tangyi.common.basic.vo.AttachmentVo
;
import
com.github.tangyi.common.core.constant.CommonConstant
;
import
com.github.tangyi.common.core.exceptions.CommonException
;
import
com.github.tangyi.common.core.model.ResponseBean
;
import
com.github.tangyi.common.core.utils.FileUtil
;
import
com.github.tangyi.common.core.utils.PageUtil
;
import
com.github.tangyi.common.core.utils.Servlets
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.utils.SysUtil
;
import
com.github.tangyi.user.api.module.Attachment
;
import
com.github.tangyi.user.service.AttachmentService
;
import
com.github.tangyi.user.uploader.UploadInvoker
;
import
com.google.common.net.HttpHeaders
;
import
io.swagger.annotations.*
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.lang.ArrayUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.util.FileCopyUtils
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.validation.constraints.NotBlank
;
import
java.io.*
;
import
java.net.URLEncoder
;
import
java.util.List
;
import
java.util.stream.Collectors
;
...
...
@@ -39,6 +50,8 @@ public class AttachmentController extends BaseController {
private
final
AttachmentService
attachmentService
;
private
final
SysProperties
sysProperties
;
/**
* 根据ID获取
*
...
...
@@ -104,9 +117,19 @@ public class AttachmentController extends BaseController {
@Log
(
"上传文件"
)
public
ResponseBean
<
Attachment
>
upload
(
@ApiParam
(
value
=
"要上传的文件"
,
required
=
true
)
@RequestParam
(
"file"
)
MultipartFile
file
,
Attachment
attachment
)
{
if
(
file
.
isEmpty
())
return
new
ResponseBean
<>(
new
Attachment
());
return
new
ResponseBean
<>(
attachmentService
.
upload
(
file
,
attachment
));
if
(!
file
.
isEmpty
())
{
try
{
attachment
.
setCommonValue
(
SysUtil
.
getUser
(),
SysUtil
.
getSysCode
(),
SysUtil
.
getTenantCode
());
attachment
.
setAttachType
(
FileUtil
.
getFileNameEx
(
file
.
getOriginalFilename
()));
attachment
.
setAttachSize
(
String
.
valueOf
(
file
.
getSize
()));
attachment
.
setAttachName
(
file
.
getOriginalFilename
());
attachment
.
setBusiId
(
attachment
.
getId
().
toString
());
attachment
=
UploadInvoker
.
getInstance
().
upload
(
attachment
,
file
.
getBytes
());
}
catch
(
Exception
e
)
{
log
.
error
(
"upload attachment error: {}"
,
e
.
getMessage
(),
e
);
}
}
return
new
ResponseBean
<>(
attachment
);
}
/**
...
...
@@ -119,19 +142,36 @@ public class AttachmentController extends BaseController {
@GetMapping
(
"download"
)
@ApiOperation
(
value
=
"下载附件"
,
notes
=
"根据ID下载附件"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"附件ID"
,
required
=
true
,
dataType
=
"Long"
)
public
ResponseBean
<
String
>
download
(
@NotBlank
Long
id
)
{
String
downloadUrl
=
""
;
public
void
download
(
HttpServletRequest
request
,
HttpServletResponse
response
,
@NotBlank
Long
id
)
{
try
{
Attachment
attachment
=
new
Attachment
();
attachment
.
setId
(
id
);
attachment
=
attachmentService
.
get
(
attachment
);
if
(
attachment
==
null
)
throw
new
CommonException
(
"Attachment does not exist"
);
downloadUrl
=
attachmentService
.
download
(
attachment
);
InputStream
inputStream
=
UploadInvoker
.
getInstance
().
download
(
attachment
);
if
(
inputStream
==
null
)
{
log
.
info
(
"attachment is not exists"
);
return
;
}
OutputStream
outputStream
=
response
.
getOutputStream
();
response
.
setContentType
(
"application/zip"
);
response
.
setHeader
(
HttpHeaders
.
CACHE_CONTROL
,
"max-age=10"
);
// IE之外的浏览器使用编码输出名称
String
contentDisposition
=
""
;
String
httpUserAgent
=
request
.
getHeader
(
"User-Agent"
);
if
(
StringUtils
.
isNotEmpty
(
httpUserAgent
))
{
httpUserAgent
=
httpUserAgent
.
toLowerCase
();
String
fileName
=
attachment
.
getAttachName
();
contentDisposition
=
httpUserAgent
.
contains
(
"wps"
)
?
"attachment;filename="
+
URLEncoder
.
encode
(
fileName
,
"UTF-8"
)
:
Servlets
.
getDownName
(
request
,
fileName
);
}
response
.
setHeader
(
HttpHeaders
.
CONTENT_DISPOSITION
,
contentDisposition
);
response
.
setContentLength
(
inputStream
.
available
());
FileCopyUtils
.
copy
(
inputStream
,
outputStream
);
log
.
info
(
"download {} success"
,
attachment
.
getAttachName
());
}
catch
(
Exception
e
)
{
log
.
error
(
"Download attachment failed: {}"
,
e
.
getMessage
(),
e
);
}
return
new
ResponseBean
<>(
downloadUrl
);
}
/**
...
...
@@ -152,7 +192,7 @@ public class AttachmentController extends BaseController {
attachment
=
attachmentService
.
get
(
attachment
);
boolean
success
=
false
;
if
(
attachment
!=
null
)
success
=
attachmentService
.
delete
(
attachment
)
>
0
;
success
=
UploadInvoker
.
getInstance
().
delete
(
attachment
)
;
return
new
ResponseBean
<>(
success
);
}
...
...
@@ -172,7 +212,7 @@ public class AttachmentController extends BaseController {
boolean
success
=
false
;
try
{
if
(
ArrayUtils
.
isNotEmpty
(
ids
))
success
=
attachmentService
.
deleteAll
(
ids
)
>
0
;
success
=
UploadInvoker
.
getInstance
().
deleteAll
(
ids
)
;
}
catch
(
Exception
e
)
{
log
.
error
(
"Delete attachment failed"
,
e
);
}
...
...
@@ -205,19 +245,49 @@ public class AttachmentController extends BaseController {
}
/**
*
获取预览地址
*
是否支持预览
*
* @param id id
* @return ResponseBean
* @author tangyi
* @date 2019/06/19 15:47
*/
@GetMapping
(
"/{id}/
p
review"
)
@ApiOperation
(
value
=
"
获取预览地址"
,
notes
=
"根据附件ID获取预览地址
"
)
@GetMapping
(
"/{id}/
canP
review"
)
@ApiOperation
(
value
=
"
判断附件是否支持预览"
,
notes
=
"根据附件ID判断附件是否支持预览
"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"附件id"
,
required
=
true
,
dataType
=
"Long"
,
paramType
=
"path"
)
public
ResponseBean
<
String
>
getPreviewUrl
(
@PathVariable
Long
id
)
{
public
ResponseBean
<
Boolean
>
canPreview
(
@PathVariable
Long
id
)
{
Attachment
attachment
=
new
Attachment
();
attachment
.
setId
(
id
);
return
new
ResponseBean
<>(
attachmentService
.
getPreviewUrl
(
attachment
));
attachment
=
attachmentService
.
get
(
attachment
);
return
new
ResponseBean
<>(
attachment
!=
null
&&
ArrayUtils
.
contains
(
sysProperties
.
getCanPreview
().
split
(
","
),
attachment
.
getAttachType
()));
}
/**
* 预览附件
*
* @param response response
* @param id id
* @author tangyi
* @date 2019/06/19 15:47
*/
@GetMapping
(
"/preview"
)
@ApiOperation
(
value
=
"预览附件"
,
notes
=
"根据附件ID预览附件"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"附件id"
,
required
=
true
,
dataType
=
"Long"
)
public
void
preview
(
HttpServletResponse
response
,
@RequestParam
Long
id
)
throws
Exception
{
Attachment
attachment
=
new
Attachment
();
attachment
.
setId
(
id
);
attachment
=
attachmentService
.
get
(
attachment
);
FileInputStream
stream
=
new
FileInputStream
(
new
File
(
attachment
.
getFastFileId
()
+
File
.
separator
+
attachment
.
getAttachName
()));
ByteArrayOutputStream
out
=
new
ByteArrayOutputStream
(
1000
);
byte
[]
b
=
new
byte
[
1000
];
int
n
;
while
((
n
=
stream
.
read
(
b
))
!=
-
1
)
{
out
.
write
(
b
,
0
,
n
);
}
response
.
setHeader
(
"Content-Type"
,
"image/png"
);
response
.
getOutputStream
().
write
(
out
.
toByteArray
());
response
.
getOutputStream
().
flush
();
out
.
close
();
stream
.
close
();
}
}
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/enums/AttachUploaderEnum.java
0 → 100644
View file @
21f4f0c1
package
com
.
github
.
tangyi
.
user
.
enums
;
import
lombok.Getter
;
/**
* 附件存储类型
* @author tangyi
* @date 2020/04/05 14:01
*/
@Getter
public
enum
AttachUploaderEnum
{
FILE
(
1
,
"文件"
,
"com.github.tangyi.user.uploader.FileUploader"
),
FAST_DFS
(
2
,
"FastDfs"
,
"com.github.tangyi.user.uploader.FastDfsUploader"
),
QI_NIU
(
3
,
"七牛云"
,
"com.github.tangyi.user.uploader.QiNiuUploader"
);
private
Integer
value
;
private
String
desc
;
private
String
implClass
;
AttachUploaderEnum
(
int
value
,
String
desc
,
String
implClass
)
{
this
.
value
=
value
;
this
.
desc
=
desc
;
this
.
implClass
=
implClass
;
}
public
static
AttachUploaderEnum
matchByValue
(
Integer
value
)
{
for
(
AttachUploaderEnum
item
:
AttachUploaderEnum
.
values
())
{
if
(
item
.
value
.
equals
(
value
))
{
return
item
;
}
}
return
FILE
;
}
}
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/service/AttachmentService.java
View file @
21f4f0c1
package
com
.
github
.
tangyi
.
user
.
service
;
import
com.github.tangyi.common.core.constant.CommonConstant
;
import
com.github.tangyi.common.core.exceptions.CommonException
;
import
com.github.tangyi.common.core.service.CrudService
;
import
com.github.tangyi.common.security.utils.SysUtil
;
import
com.github.tangyi.oss.service.QiNiuService
;
import
com.github.tangyi.user.api.constant.AttachmentConstant
;
import
com.github.tangyi.user.api.module.Attachment
;
import
com.github.tangyi.user.mapper.AttachmentMapper
;
import
com.github.tangyi.user.uploader.UploadInvoker
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang
3
.StringUtils
;
import
org.apache.commons.lang.StringUtils
;
import
org.springframework.cache.annotation.CacheEvict
;
import
org.springframework.cache.annotation.Cacheable
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.web.multipart.MultipartFile
;
import
java.
nio.charset.StandardCharsets
;
import
java.
io.InputStream
;
/**
* @author tangyi
...
...
@@ -27,8 +25,6 @@ import java.nio.charset.StandardCharsets;
@Service
public
class
AttachmentService
extends
CrudService
<
AttachmentMapper
,
Attachment
>
{
private
final
QiNiuService
qiNiuService
;
/**
* 根据id查询
*
...
...
@@ -55,50 +51,14 @@ public class AttachmentService extends CrudService<AttachmentMapper, Attachment>
}
/**
* 上传
*
* @param file file
* @param attachment attachment
* @return int
*/
@Transactional
public
Attachment
upload
(
MultipartFile
file
,
Attachment
attachment
)
{
try
{
long
start
=
System
.
currentTimeMillis
();
long
attachSize
=
file
.
getSize
();
if
(
StringUtils
.
isNotBlank
(
file
.
getOriginalFilename
()))
{
String
fileName
=
new
String
(
file
.
getOriginalFilename
().
getBytes
(),
StandardCharsets
.
UTF_8
);
String
previewUrl
=
qiNiuService
.
upload
(
file
.
getBytes
(),
fileName
);
Attachment
newAttachment
=
new
Attachment
();
newAttachment
.
setCommonValue
(
SysUtil
.
getUser
(),
SysUtil
.
getSysCode
(),
SysUtil
.
getTenantCode
());
newAttachment
.
setPreviewUrl
(
previewUrl
);
newAttachment
.
setAttachName
(
fileName
);
newAttachment
.
setGroupName
(
qiNiuService
.
getDomainOfBucket
());
newAttachment
.
setFastFileId
(
fileName
);
newAttachment
.
setAttachSize
(
Long
.
toString
(
attachSize
));
newAttachment
.
setBusiId
(
attachment
.
getBusiId
());
newAttachment
.
setBusiModule
(
attachment
.
getBusiModule
());
newAttachment
.
setBusiType
(
attachment
.
getBusiType
());
super
.
insert
(
newAttachment
);
log
.
info
(
"Upload attachment success, fileName: {}, time: {}ms"
,
file
.
getName
(),
System
.
currentTimeMillis
()
-
start
);
return
newAttachment
;
}
return
null
;
}
catch
(
Exception
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
throw
new
CommonException
(
e
);
}
}
/**
* 下载
*
* @param attachment attachment
* @return InputStream
*/
public
String
download
(
Attachment
attachment
)
throws
Exception
{
public
InputStream
download
(
Attachment
attachment
)
throws
Exception
{
// 下载附件
return
qiNiuService
.
getDownloadUrl
(
attachment
.
getAttachName
()
);
return
UploadInvoker
.
getInstance
().
download
(
attachment
);
}
/**
...
...
@@ -140,8 +100,11 @@ public class AttachmentService extends CrudService<AttachmentMapper, Attachment>
attachment
=
this
.
get
(
attachment
);
if
(
attachment
!=
null
)
{
String
preview
=
attachment
.
getPreviewUrl
();
if
(
!
preview
.
startsWith
(
"http"
))
if
(
StringUtils
.
isNotBlank
(
preview
)
&&
!
preview
.
startsWith
(
"http"
))
{
preview
=
"http://"
+
preview
;
}
else
{
preview
=
AttachmentConstant
.
ATTACHMENT_PREVIEW_URL
+
attachment
.
getId
();
}
log
.
debug
(
"GetPreviewUrl id: {}, preview url: {}"
,
attachment
.
getId
(),
preview
);
return
preview
;
}
...
...
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/uploader/AbstractUploader.java
0 → 100644
View file @
21f4f0c1
package
com
.
github
.
tangyi
.
user
.
uploader
;
import
com.github.tangyi.common.basic.properties.SysProperties
;
import
com.github.tangyi.common.core.utils.SpringContextHolder
;
import
com.github.tangyi.common.security.utils.SysUtil
;
import
com.github.tangyi.user.api.module.Attachment
;
import
com.github.tangyi.user.service.AttachmentService
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
java.io.File
;
import
java.io.InputStream
;
/**
* @author tangyi
* @date 2020/04/05 13:37
*/
public
abstract
class
AbstractUploader
implements
IUploader
{
@Override
public
int
save
(
Attachment
attachment
)
{
return
SpringContextHolder
.
getApplicationContext
().
getBean
(
AttachmentService
.
class
).
insert
(
attachment
);
}
@Override
public
boolean
delete
(
Attachment
attachment
)
{
return
SpringContextHolder
.
getApplicationContext
().
getBean
(
AttachmentService
.
class
).
delete
(
attachment
)
>
0
;
}
@Override
public
abstract
Attachment
upload
(
Attachment
attachment
,
byte
[]
bytes
);
@Override
public
abstract
InputStream
download
(
Attachment
attachment
);
/**
* 获取附件存储目录
*
* @param attachment attachment
* @param id id
* @return String
*/
public
String
getFileRealDirectory
(
Attachment
attachment
,
String
id
)
{
String
applicationCode
=
attachment
.
getApplicationCode
();
String
busiId
=
attachment
.
getBusiId
();
String
fileName
=
attachment
.
getAttachName
();
String
fileRealDirectory
=
SpringContextHolder
.
getApplicationContext
().
getBean
(
SysProperties
.
class
).
getAttachPath
()
+
File
.
separator
+
applicationCode
+
File
.
separator
;
// 有分类就加上
if
(
StringUtils
.
isNotBlank
(
attachment
.
getBusiModule
()))
{
String
busiModule
=
attachment
.
getBusiModule
();
fileRealDirectory
=
fileRealDirectory
+
busiModule
+
File
.
separator
;
}
if
(
StringUtils
.
isNotBlank
(
attachment
.
getBusiType
()))
{
String
busiType
=
attachment
.
getBusiType
();
fileRealDirectory
=
fileRealDirectory
+
busiType
+
File
.
separator
;
}
fileRealDirectory
=
fileRealDirectory
+
busiId
;
return
fileRealDirectory
;
}
}
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/uploader/FastDfsUploader.java
0 → 100644
View file @
21f4f0c1
package
com
.
github
.
tangyi
.
user
.
uploader
;
import
com.github.tangyi.oss.service.FastDfsService
;
import
com.github.tangyi.user.api.module.Attachment
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.io.ByteArrayInputStream
;
import
java.io.InputStream
;
/**
* 上传到FastDfs
* @author tangyi
* @date 2020/04/05 13:36
*/
@Slf4j
@Service
public
class
FastDfsUploader
extends
AbstractUploader
{
@Autowired
private
FastDfsService
fastDfsService
;
@Override
public
Attachment
upload
(
Attachment
attachment
,
byte
[]
bytes
)
{
try
{
attachment
.
setAttachSize
(
String
.
valueOf
(
bytes
.
length
));
String
fastFileId
=
fastDfsService
.
uploadFile
(
new
ByteArrayInputStream
(
bytes
),
bytes
.
length
,
attachment
.
getAttachType
());
String
groupName
=
fastFileId
.
substring
(
0
,
fastFileId
.
indexOf
(
"/"
));
attachment
.
setFastFileId
(
fastFileId
);
attachment
.
setGroupName
(
groupName
);
return
attachment
;
}
catch
(
Exception
e
)
{
log
.
error
(
"上传附件至网盘失败:"
+
attachment
.
getAttachName
()
+
e
.
getMessage
());
return
null
;
}
}
@Override
public
InputStream
download
(
Attachment
attachment
)
{
return
fastDfsService
.
downloadStream
(
attachment
.
getGroupName
(),
attachment
.
getFastFileId
());
}
@Override
public
boolean
delete
(
Attachment
attachment
)
{
if
(
StringUtils
.
isNotEmpty
(
attachment
.
getGroupName
())
&&
StringUtils
.
isNotEmpty
(
attachment
.
getFastFileId
()))
{
fastDfsService
.
deleteFile
(
attachment
.
getGroupName
(),
attachment
.
getFastFileId
());
}
return
Boolean
.
TRUE
;
}
@Override
public
boolean
deleteAll
(
Attachment
attachment
)
{
return
false
;
}
}
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/uploader/FileUploader.java
0 → 100644
View file @
21f4f0c1
package
com
.
github
.
tangyi
.
user
.
uploader
;
import
com.github.tangyi.common.core.exceptions.CommonException
;
import
com.github.tangyi.common.core.utils.FileUtil
;
import
com.github.tangyi.user.api.module.Attachment
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.stereotype.Service
;
import
java.io.*
;
/**
* 上传到本地目录
*
* @author tangyi
* @date 2020/04/05 13:36
*/
@Slf4j
@Service
public
class
FileUploader
extends
AbstractUploader
{
@Override
public
Attachment
upload
(
Attachment
attachment
,
byte
[]
bytes
)
{
try
{
String
fileRealDirectory
=
getFileRealDirectory
(
attachment
,
attachment
.
getId
().
toString
());
fileRealDirectory
=
fileRealDirectory
.
replaceAll
(
"\\\\"
,
"/"
);
String
fileName
=
attachment
.
getAttachName
();
attachment
.
setAttachSize
(
String
.
valueOf
(
bytes
.
length
));
log
.
info
(
"file read directory: {}"
,
fileRealDirectory
);
FileUtil
.
createDirectory
(
fileRealDirectory
);
log
.
info
(
"start write file: {}"
,
fileName
);
saveFileFormByteArray
(
bytes
,
fileRealDirectory
,
fileName
);
log
.
info
(
"write file finished: {}"
,
fileName
);
attachment
.
setFastFileId
(
fileRealDirectory
);
return
attachment
;
}
catch
(
Exception
e
)
{
log
.
error
(
"FileUploader error:{}, {}"
,
attachment
.
getAttachName
(),
e
.
getMessage
(),
e
);
return
null
;
}
}
@Override
public
InputStream
download
(
Attachment
attachment
)
{
String
path
=
attachment
.
getFastFileId
()
+
File
.
separator
+
attachment
.
getAttachName
();
InputStream
input
=
null
;
try
{
String
fileRealDirectory
=
getFileRealDirectory
(
attachment
,
attachment
.
getId
().
toString
());
fileRealDirectory
=
fileRealDirectory
.
replaceAll
(
"\\\\"
,
"/"
);
if
(
StringUtils
.
isNotBlank
(
fileRealDirectory
)
&&
!
fileRealDirectory
.
equals
(
attachment
.
getFastFileId
()))
throw
new
CommonException
(
"attach path validate failure!attachPath:"
+
attachment
.
getFastFileId
()
+
", fileRealDirectory:"
+
fileRealDirectory
);
input
=
new
FileInputStream
(
new
File
(
path
));
}
catch
(
Exception
e
)
{
log
.
error
(
"download attachment failure: {}"
,
e
.
getMessage
(),
e
);
}
return
input
;
}
@Override
public
boolean
delete
(
Attachment
attachment
)
{
String
path
=
attachment
.
getFastFileId
()
+
File
.
separator
+
attachment
.
getAttachName
();
File
file
=
new
File
(
path
);
if
(
file
.
delete
())
{
FileUtil
.
deleteDirectory
(
attachment
.
getFastFileId
());
return
super
.
delete
(
attachment
);
}
return
Boolean
.
FALSE
;
}
@Override
public
boolean
deleteAll
(
Attachment
attachment
)
{
return
false
;
}
private
void
saveFileFormByteArray
(
byte
[]
b
,
String
path
,
String
fileName
)
throws
IOException
{
BufferedOutputStream
fs
=
new
BufferedOutputStream
(
new
FileOutputStream
(
path
+
"/"
+
fileName
,
true
));
fs
.
write
(
b
);
fs
.
flush
();
fs
.
close
();
}
}
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/uploader/IUploader.java
0 → 100644
View file @
21f4f0c1
package
com
.
github
.
tangyi
.
user
.
uploader
;
import
com.github.tangyi.user.api.module.Attachment
;
import
java.io.InputStream
;
/**
* @author tangyi
* @date 2020/04/05 13:36
*/
public
interface
IUploader
{
/**
* 上传附件
* @param attachment attachment
* @param bytes bytes
* @return Attachment
*/
Attachment
upload
(
Attachment
attachment
,
byte
[]
bytes
);
/**
* 保存附件信息
* @param attachment attachment
* @return int
*/
int
save
(
Attachment
attachment
);
/**
* 下载附件
* @param attachment attachment
* @return InputStream
*/
InputStream
download
(
Attachment
attachment
);
/**
* 删除附件
* @param attachment attachment
* @return boolean
*/
boolean
delete
(
Attachment
attachment
);
/**
* 批量删除
* @param attachment attachment
* @return boolean
*/
boolean
deleteAll
(
Attachment
attachment
);
}
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/uploader/QiNiuUploader.java
0 → 100644
View file @
21f4f0c1
package
com
.
github
.
tangyi
.
user
.
uploader
;
import
com.github.tangyi.oss.service.QiNiuUtil
;
import
com.github.tangyi.user.api.module.Attachment
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Service
;
import
java.io.InputStream
;
/**
* 上传到七牛云
*
* @author tangyi
* @date 2020/04/05 13:36
*/
@Slf4j
@Service
public
class
QiNiuUploader
extends
AbstractUploader
{
@Override
public
Attachment
upload
(
Attachment
attachment
,
byte
[]
bytes
)
{
String
result
=
QiNiuUtil
.
getInstance
().
upload
(
bytes
,
attachment
.
getAttachName
());
attachment
.
setUploadResult
(
result
);
attachment
.
setPreviewUrl
(
attachment
.
getUploadResult
());
return
attachment
;
}
@Override
public
InputStream
download
(
Attachment
attachment
)
{
return
null
;
}
@Override
public
boolean
delete
(
Attachment
attachment
)
{
return
QiNiuUtil
.
getInstance
().
delete
(
attachment
.
getAttachName
());
}
@Override
public
boolean
deleteAll
(
Attachment
attachment
)
{
return
false
;
}
}
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/uploader/UploadInvoker.java
0 → 100644
View file @
21f4f0c1
package
com
.
github
.
tangyi
.
user
.
uploader
;
import
com.github.tangyi.common.basic.properties.SysProperties
;
import
com.github.tangyi.common.core.exceptions.CommonException
;
import
com.github.tangyi.common.core.utils.SpringContextHolder
;
import
com.github.tangyi.user.api.module.Attachment
;
import
com.github.tangyi.user.enums.AttachUploaderEnum
;
import
com.github.tangyi.user.service.AttachmentService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang.StringUtils
;
import
java.io.InputStream
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* @author tangyi
* @date 2020/04/05 14:16
*/
@Slf4j
public
class
UploadInvoker
{
private
Map
<
Integer
,
IUploader
>
uploaderMap
=
null
;
private
static
UploadInvoker
instance
;
private
AttachmentService
attachmentService
;
public
UploadInvoker
(
AttachmentService
attachmentService
)
{
this
.
attachmentService
=
attachmentService
;
}
public
synchronized
static
UploadInvoker
getInstance
()
{
if
(
instance
==
null
)
{
instance
=
new
UploadInvoker
(
SpringContextHolder
.
getApplicationContext
().
getBean
(
AttachmentService
.
class
));
}
return
instance
;
}
/**
* 上传附件
*
* @param attachment attachment
* @param bytes bytes
* @return Attachment
* @author tangyi
* @date 2020/04/05 14:27
*/
public
Attachment
upload
(
Attachment
attachment
,
byte
[]
bytes
)
{
if
(
attachment
==
null
||
bytes
==
null
)
return
null
;
if
(
attachment
.
getUploadType
()
==
null
)
{
String
uploadType
=
SpringContextHolder
.
getApplicationContext
().
getBean
(
SysProperties
.
class
).
getAttachUploadType
();
if
(
StringUtils
.
isNotBlank
(
uploadType
))
{
attachment
.
setUploadType
(
Integer
.
parseInt
(
uploadType
));
}
}
IUploader
uploader
=
this
.
getUploader
(
attachment
.
getUploadType
());
if
(
uploader
==
null
)
throw
new
CommonException
(
"uploader is null"
);
attachment
=
uploader
.
upload
(
attachment
,
bytes
);
if
(
attachment
!=
null
)
{
uploader
.
save
(
attachment
);
}
return
attachment
;
}
/**
* 下载附件
*
* @param attachment attachment
* @return Attachment
* @author tangyi
* @date 2020/04/05 14:29
*/
public
InputStream
download
(
Attachment
attachment
)
{
if
(
attachment
==
null
)
return
null
;
IUploader
uploader
=
this
.
getUploader
(
attachment
.
getUploadType
());
if
(
uploader
==
null
)
throw
new
CommonException
(
"uploader is null"
);
return
uploader
.
download
(
attachment
);
}
/**
* 删除附件
*
* @param attachment attachment
* @return Attachment
* @author tangyi
* @date 2020/04/05 14:29
*/
public
boolean
delete
(
Attachment
attachment
)
{
if
(
attachment
==
null
)
return
Boolean
.
FALSE
;
IUploader
uploader
=
this
.
getUploader
(
attachment
.
getUploadType
());
if
(
uploader
==
null
)
throw
new
CommonException
(
"uploader is null"
);
return
uploader
.
delete
(
attachment
);
}
/**
* 批量删除附件
*
* @param ids ids
* @return Attachment
* @author tangyi
* @date 2020/04/05 15:03
*/
public
boolean
deleteAll
(
Long
[]
ids
)
{
boolean
result
=
false
;
for
(
Long
id
:
ids
)
{
// 查询出实体
Attachment
attachmentSearch
=
new
Attachment
();
attachmentSearch
.
setId
(
id
);
attachmentSearch
=
attachmentService
.
get
(
attachmentSearch
);
IUploader
uploader
=
getUploader
(
attachmentSearch
.
getUploadType
());
// 删除对应存储方式中的附件
result
=
uploader
.
delete
(
attachmentSearch
);
if
(
result
)
{
uploader
.
delete
(
attachmentSearch
);
}
}
return
result
;
}
/**
* 获取附件实现类
*
* @param uploadType uploadType
* @return IUploader
* @author tangyi
* @date 2020/04/05 14:17
*/
private
IUploader
getUploader
(
Integer
uploadType
)
{
IUploader
uploader
;
if
(
uploaderMap
==
null
)
{
uploaderMap
=
new
HashMap
<>();
}
uploader
=
uploaderMap
.
get
(
uploadType
);
try
{
if
(
uploader
==
null
)
{
// 如果没有初始化则创建
String
implClass
=
AttachUploaderEnum
.
matchByValue
(
uploadType
).
getImplClass
();
Class
<?>
clazz
=
Class
.
forName
(
implClass
);
uploader
=
(
IUploader
)
clazz
.
newInstance
();
uploaderMap
.
put
(
uploadType
,
uploader
);
}
}
catch
(
Exception
e
)
{
log
.
error
(
"getUploader error:{}"
,
e
.
getMessage
(),
e
);
return
null
;
}
return
uploader
;
}
}
modules/user-service-parent/user-service/src/main/resources/mapper/AttachmentMapper.xml
View file @
21f4f0c1
...
...
@@ -4,6 +4,7 @@
<resultMap
id=
"attachmentResultMap"
type=
"com.github.tangyi.user.api.module.Attachment"
>
<id
column=
"id"
property=
"id"
/>
<result
column=
"attach_name"
property=
"attachName"
/>
<result
column=
"attach_type"
property=
"attachType"
/>
<result
column=
"attach_size"
property=
"attachSize"
/>
<result
column=
"group_name"
property=
"groupName"
/>
<result
column=
"fast_file_id"
property=
"fastFileId"
/>
...
...
@@ -11,6 +12,7 @@
<result
column=
"busi_module"
property=
"busiModule"
/>
<result
column=
"busi_type"
property=
"busiType"
/>
<result
column=
"preview_url"
property=
"previewUrl"
/>
<result
column=
"upload_type"
property=
"uploadType"
/>
<result
column=
"creator"
property=
"creator"
/>
<result
column=
"create_date"
property=
"createDate"
javaType=
"java.util.Date"
jdbcType=
"TIMESTAMP"
/>
<result
column=
"modifier"
property=
"modifier"
/>
...
...
@@ -23,6 +25,7 @@
<sql
id=
"attachmentColumns"
>
a.id,
a.attach_name,
a.attach_type,
a.attach_size,
a.group_name,
a.fast_file_id,
...
...
@@ -30,6 +33,7 @@
a.busi_module,
a.busi_type,
a.preview_url,
a.upload_type,
a.creator,
a.create_date,
a.modifier,
...
...
@@ -92,6 +96,7 @@
INSERT INTO sys_attachment (
id,
attach_name,
attach_type,
attach_size,
group_name,
fast_file_id,
...
...
@@ -99,6 +104,7 @@
busi_module,
busi_type,
preview_url,
upload_type,
creator,
create_date,
modifier,
...
...
@@ -109,6 +115,7 @@
) VALUES (
#{id},
#{attachName},
#{attachType},
#{attachSize},
#{groupName},
#{fastFileId},
...
...
@@ -116,6 +123,7 @@
#{busiModule},
#{busiType},
#{previewUrl},
#{uploadType},
#{creator},
#{createDate, jdbcType=TIMESTAMP, javaType=java.util.Date},
#{modifier},
...
...
@@ -131,6 +139,9 @@
<if
test=
"attachName != null"
>
attach_name = #{attachName},
</if>
<if
test=
"attachType != null"
>
attach_type = #{attachType},
</if>
<if
test=
"attachSize != null"
>
attach_size = #{attachSize},
</if>
...
...
@@ -152,6 +163,9 @@
<if
test=
"previewUrl != null"
>
preview_url = #{previewUrl},
</if>
<if
test=
"uploadType != null"
>
upload_type = #{uploadType},
</if>
<if
test=
"delFlag != null"
>
del_flag = #{delFlag},
</if>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment