修复bug;完善错误信息提示机制
This commit is contained in:
@@ -3,3 +3,4 @@ web/dist/
|
||||
log/
|
||||
server/src/main/resources/dist/
|
||||
doc/票通Demo/untitled/.idea/
|
||||
server/.kotlin/
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$VERSION = "1.1"
|
||||
$VERSION = "1.2"
|
||||
|
||||
$IMAGE = "docker.bbitcn.net/bbit_invoice/server"
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ enum class ErrorCode(val code: String, val message: String) {
|
||||
UNAUTHORIZED("AUTH.UNAUTHORIZED", "未登录或登录已失效"),
|
||||
FORBIDDEN("AUTH.FORBIDDEN", "无权限访问"),
|
||||
USERNAME_OR_PASSWORD_INVALID("AUTH.USERNAME_OR_PASSWORD_INVALID", "用户名或密码错误"),
|
||||
ACCOUNT_NOT_FOUND("AUTH.ACCOUNT_NOT_FOUND", "账号不存在"),
|
||||
PASSWORD_INVALID("AUTH.PASSWORD_INVALID", "密码错误"),
|
||||
USER_DISABLED("AUTH.USER_DISABLED", "用户已禁用"),
|
||||
USER_NOT_FOUND("SYSTEM.USER_NOT_FOUND", "用户不存在"),
|
||||
ROLE_NOT_FOUND("SYSTEM.ROLE_NOT_FOUND", "角色不存在"),
|
||||
|
||||
@@ -99,7 +99,7 @@ fun Route.registerUserRoutes() {
|
||||
val id = parseUuid(call.parameters["id"] ?: "", "id")
|
||||
val request = call.receive<UpdateUserStatusRequest>()
|
||||
runCatching {
|
||||
UserService.updateStatus(id, request)
|
||||
UserService.updateStatus(id, currentUser.id, request)
|
||||
call.respond(ok<Unit>(message = "状态更新成功"))
|
||||
OperationLogService.success(call, currentUser, "UPDATE_STATUS", "更新用户状态", start.elapsedNow().inWholeMilliseconds)
|
||||
}.onFailure {
|
||||
|
||||
@@ -30,31 +30,31 @@ object AuthService {
|
||||
}
|
||||
|
||||
val user = dbQuery { UserDao.findByUsername(username) } ?: throw BizException(
|
||||
ErrorCode.USERNAME_OR_PASSWORD_INVALID.code,
|
||||
ErrorCode.USERNAME_OR_PASSWORD_INVALID.message,
|
||||
ErrorCode.ACCOUNT_NOT_FOUND.code,
|
||||
ErrorCode.ACCOUNT_NOT_FOUND.message,
|
||||
HttpStatusCode.BadRequest,
|
||||
)
|
||||
|
||||
if (!PasswordService.matches(request.password, user[com.bbit.ticket.database.system.SysUserTable.passwordHash])) {
|
||||
if (!PasswordService.matches(request.password, user[SysUserTable.passwordHash])) {
|
||||
throw BizException(
|
||||
ErrorCode.USERNAME_OR_PASSWORD_INVALID.code,
|
||||
ErrorCode.USERNAME_OR_PASSWORD_INVALID.message,
|
||||
ErrorCode.PASSWORD_INVALID.code,
|
||||
ErrorCode.PASSWORD_INVALID.message,
|
||||
HttpStatusCode.BadRequest,
|
||||
)
|
||||
}
|
||||
|
||||
if (user[com.bbit.ticket.database.system.SysUserTable.status] != "ENABLED") {
|
||||
if (user[SysUserTable.status] != "ENABLED") {
|
||||
throw BizException(ErrorCode.USER_DISABLED.code, ErrorCode.USER_DISABLED.message, HttpStatusCode.BadRequest)
|
||||
}
|
||||
|
||||
val userId = user[com.bbit.ticket.database.system.SysUserTable.id]
|
||||
val userId = user[SysUserTable.id]
|
||||
val roleCodes = dbQuery { UserDao.findEnabledRoleCodes(userId) }
|
||||
|
||||
val (accessToken, expiresIn) = JwtService.issueAccessToken(
|
||||
userId = userId.toString(),
|
||||
username = user[com.bbit.ticket.database.system.SysUserTable.username],
|
||||
username = user[SysUserTable.username],
|
||||
roles = roleCodes,
|
||||
tokenVersion = user[com.bbit.ticket.database.system.SysUserTable.tokenVersion],
|
||||
tokenVersion = user[SysUserTable.tokenVersion],
|
||||
)
|
||||
|
||||
dbQuery { UserDao.updateLoginInfo(userId, loginIp) }
|
||||
|
||||
@@ -63,7 +63,10 @@ object UserService {
|
||||
UserDao.softDelete(id)
|
||||
}
|
||||
|
||||
suspend fun updateStatus(id: Uuid, request: UpdateUserStatusRequest) = dbQuery {
|
||||
suspend fun updateStatus(id: Uuid, currentUserId: Uuid, request: UpdateUserStatusRequest) = dbQuery {
|
||||
if (id == currentUserId && request.status != "ENABLED") {
|
||||
throw BizException(ErrorCode.BAD_REQUEST.code, "不能禁用当前登录账号")
|
||||
}
|
||||
UserDao.requireActive(id)
|
||||
UserDao.updateStatus(id, request.status)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import java.time.OffsetDateTime
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
private val defaultZone: ZoneId = ZoneId.systemDefault()
|
||||
private val defaultZone: ZoneId = ZoneId.of("Asia/Shanghai")
|
||||
private val dateTimeFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
|
||||
|
||||
fun formatDateTime(value: OffsetDateTime?): String? {
|
||||
|
||||
@@ -40,7 +40,7 @@ object PTApi {
|
||||
|
||||
/** 发送登录短信验证码 2.4 */
|
||||
suspend fun sendLoginSmsCode(req: GetLoginSmsCodeRequest): LoginSmsCodeResponse =
|
||||
PTClient.ptPost("sendLoginSmsCode.pt", req)
|
||||
PTClient.ptPost("sendLoginSmsCode.pt", req, successResultCodes = setOf("0000", "6666"))
|
||||
|
||||
/** 短信验证码登录 2.5 */
|
||||
suspend fun smsLogin(req: SmsLoginRequest): SMSLoginResponse =
|
||||
|
||||
@@ -34,6 +34,7 @@ object PTClient {
|
||||
val logger = LoggerFactory.getLogger(PTClient::class.java)
|
||||
private const val CONNECT_TIMEOUT_MS = 10_000
|
||||
private const val READ_TIMEOUT_MS = 60_000
|
||||
private const val SHANGHAI_TIME_ZONE = "Asia/Shanghai"
|
||||
val wireJson = Json {
|
||||
explicitNulls = false
|
||||
ignoreUnknownKeys = true
|
||||
@@ -54,7 +55,8 @@ object PTClient {
|
||||
suspend inline fun <reified Req, reified Resp> ptGet(
|
||||
url: String,
|
||||
queryParams: Req,
|
||||
headers: Map<String, String> = emptyMap()
|
||||
headers: Map<String, String> = emptyMap(),
|
||||
successResultCodes: Set<String> = setOf("0000"),
|
||||
): Resp {
|
||||
|
||||
// query -> json
|
||||
@@ -128,6 +130,7 @@ object PTClient {
|
||||
message = "response content is null",
|
||||
serialNo = result.serialNo
|
||||
)
|
||||
ensureInnerResultOk(content, successResultCodes, result.serialNo)
|
||||
|
||||
return myJson.decodeFromJsonElement(content)
|
||||
}
|
||||
@@ -135,7 +138,8 @@ object PTClient {
|
||||
suspend inline fun <reified Req, reified Resp> ptPost(
|
||||
url: String,
|
||||
body: Req,
|
||||
headers: Map<String, String> = emptyMap()
|
||||
headers: Map<String, String> = emptyMap(),
|
||||
successResultCodes: Set<String> = setOf("0000"),
|
||||
): Resp {
|
||||
// req json
|
||||
val reqJson = wireJson.encodeToString(body)
|
||||
@@ -150,6 +154,7 @@ object PTClient {
|
||||
|
||||
val decrypted = disposeResponse(response)
|
||||
val result = myJson.decodeFromString<PTResponse<JsonElement>>(decrypted)
|
||||
logger.info("res = $result")
|
||||
if (result.code != "0000") {
|
||||
throw PTException(
|
||||
code = result.code,
|
||||
@@ -157,8 +162,14 @@ object PTClient {
|
||||
serialNo = result.serialNo
|
||||
)
|
||||
}
|
||||
logger.info("res = $result")
|
||||
return myJson.decodeFromJsonElement<Resp>(result.content!!)
|
||||
val content = result.content
|
||||
?: throw PTException(
|
||||
code = "CONTENT_NULL",
|
||||
message = "response content is null",
|
||||
serialNo = result.serialNo
|
||||
)
|
||||
ensureInnerResultOk(content, successResultCodes, result.serialNo)
|
||||
return myJson.decodeFromJsonElement<Resp>(content)
|
||||
}
|
||||
|
||||
suspend fun postJsonRaw(
|
||||
@@ -220,7 +231,7 @@ object PTClient {
|
||||
@Throws(Exception::class)
|
||||
fun buildRequestData(content: String): String {
|
||||
val reqContent: String = SecurityUtil.encrypt3DES(content) ?: ""
|
||||
val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
|
||||
val sdf = shanghaiDateFormat("yyyy-MM-dd HH:mm:ss")
|
||||
val map = HashMap<String, String>()
|
||||
map["platformCode"] = Global.ptPlatformCode
|
||||
map["signType"] = "RSA"
|
||||
@@ -287,10 +298,36 @@ object PTClient {
|
||||
|
||||
fun ptDate(): String {
|
||||
val date = Date()
|
||||
val sdf = SimpleDateFormat("YYYYMMddHHmmss")
|
||||
val sdf = shanghaiDateFormat("yyyyMMddHHmmss")
|
||||
val str = Global.ptPlatformAlias + sdf.format(date) + (Math.random() * 90 + 10).toInt()
|
||||
println(str)
|
||||
return str
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
internal fun ensureInnerResultOk(
|
||||
content: JsonElement,
|
||||
successResultCodes: Set<String>,
|
||||
serialNo: String?,
|
||||
) {
|
||||
val contentObject = content as? JsonObject ?: return
|
||||
val resultCode = contentObject.stringOrNull("resultCode") ?: return
|
||||
if (resultCode !in successResultCodes) {
|
||||
throw PTException(
|
||||
code = resultCode,
|
||||
message = contentObject.stringOrNull("resultMsg") ?: "票通业务处理失败",
|
||||
serialNo = serialNo,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
internal fun JsonObject.stringOrNull(key: String): String? =
|
||||
(this[key] as? JsonPrimitive)?.content?.trim()?.takeIf { it.isNotEmpty() }
|
||||
|
||||
private fun shanghaiDateFormat(pattern: String): SimpleDateFormat =
|
||||
SimpleDateFormat(pattern).apply {
|
||||
timeZone = TimeZone.getTimeZone(SHANGHAI_TIME_ZONE)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{traceId}] %logger{40} - %msg%n</pattern>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS, Asia/Shanghai} [%thread] %-5level [%X{traceId}] %logger{40} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
<appender name="PT_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>../log/pt-request.log</file>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %msg%n</pattern>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS, Asia/Shanghai} %msg%n</pattern>
|
||||
</encoder>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>../log/pt-request.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<fileNamePattern>../log/pt-request.%d{yyyy-MM-dd, Asia/Shanghai}.log</fileNamePattern>
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
Reference in New Issue
Block a user