修复bug;完善错误信息提示机制

This commit is contained in:
BBIT-Kai
2026-07-10 14:06:07 +08:00
parent ee355db48e
commit 8b5e2b6a38
10 changed files with 66 additions and 23 deletions
+1
View File
@@ -3,3 +3,4 @@ web/dist/
log/
server/src/main/resources/dist/
doc/票通Demo/untitled/.idea/
server/.kotlin/
+1 -1
View File
@@ -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)
}
}
+3 -3
View File
@@ -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>