完善前端显示字段;去掉开放测试接口
This commit is contained in:
@@ -27,6 +27,8 @@ import com.bbit.ticket.service.openapi.OpenInvoiceTaskWorker
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import io.ktor.server.application.Application
|
||||
import io.ktor.server.auth.authenticate
|
||||
import io.ktor.server.http.content.singlePageApplication
|
||||
import io.ktor.server.http.content.vue
|
||||
import io.ktor.server.netty.EngineMain
|
||||
import io.ktor.server.response.respond
|
||||
import io.ktor.server.routing.get
|
||||
@@ -47,7 +49,7 @@ fun Application.module() {
|
||||
configureCors()
|
||||
configureSecurity()
|
||||
configureDatabase()
|
||||
configureRedis()
|
||||
// configureRedis()
|
||||
runBlocking {
|
||||
DatabaseInitializer.initialize()
|
||||
SeedData.seed()
|
||||
@@ -58,6 +60,10 @@ fun Application.module() {
|
||||
get("/health") {
|
||||
call.respond(ok(mapOf("status" to "UP", "service" to AppConfig.app.name)))
|
||||
}
|
||||
singlePageApplication {
|
||||
useResources = true
|
||||
vue("dist")
|
||||
}
|
||||
route("/api") {
|
||||
registerAuthRoutes()
|
||||
registerUserRoutes()
|
||||
|
||||
@@ -105,10 +105,33 @@ object EnterpriseManageDao {
|
||||
}
|
||||
}
|
||||
|
||||
fun digitalAccountsForEnterprise(enterpriseId: Uuid): List<DigitalAccountManageItem> =
|
||||
PtDigitalAccountTable.selectAll()
|
||||
.where { (PtDigitalAccountTable.enterpriseId eq enterpriseId) and PtDigitalAccountTable.deletedAt.isNull() }
|
||||
fun digitalAccountsForEnterprise(
|
||||
enterpriseId: Uuid,
|
||||
account: String?,
|
||||
status: String?,
|
||||
page: Int,
|
||||
pageSize: Int,
|
||||
): PageResult<DigitalAccountManageItem> {
|
||||
val where = digitalAccountWhere(enterpriseId, account, status)
|
||||
val total = PtDigitalAccountTable.selectAll().where { where }.count()
|
||||
val rows = PtDigitalAccountTable.selectAll()
|
||||
.where { where }
|
||||
.orderBy(PtDigitalAccountTable.createdAt, SortOrder.DESC)
|
||||
.limit(pageSize)
|
||||
.offset(pageOffset(page, pageSize))
|
||||
.map { it.toDigitalAccountItem() }
|
||||
return PageResult(rows, page, pageSize, total)
|
||||
}
|
||||
|
||||
fun digitalAccountOptionsForEnterprise(
|
||||
enterpriseId: Uuid,
|
||||
account: String?,
|
||||
limit: Int,
|
||||
): List<DigitalAccountManageItem> =
|
||||
PtDigitalAccountTable.selectAll()
|
||||
.where { digitalAccountWhere(enterpriseId, account, "ENABLED") }
|
||||
.orderBy(PtDigitalAccountTable.createdAt, SortOrder.DESC)
|
||||
.limit(limit)
|
||||
.map { it.toDigitalAccountItem() }
|
||||
|
||||
fun digitalAccount(id: Uuid): ResultRow? =
|
||||
@@ -134,6 +157,18 @@ object EnterpriseManageDao {
|
||||
}
|
||||
.singleOrNull()
|
||||
|
||||
private fun digitalAccountWhere(enterpriseId: Uuid, account: String?, status: String?): Op<Boolean> {
|
||||
var where: Op<Boolean> =
|
||||
(PtDigitalAccountTable.enterpriseId eq enterpriseId) and PtDigitalAccountTable.deletedAt.isNull()
|
||||
account?.trim()?.takeIf { it.isNotEmpty() }?.let {
|
||||
where = where and (PtDigitalAccountTable.account like "%$it%")
|
||||
}
|
||||
status?.trim()?.takeIf { it.isNotEmpty() }?.let {
|
||||
where = where and (PtDigitalAccountTable.status eq it.uppercase())
|
||||
}
|
||||
return where
|
||||
}
|
||||
|
||||
fun upsertDigitalAccount(enterpriseId: Uuid, item: DigitalAccountInfo): Uuid {
|
||||
val existing = PtDigitalAccountTable.selectAll()
|
||||
.where {
|
||||
|
||||
+8
-7
@@ -1,4 +1,4 @@
|
||||
package com.bbit.ticket.database.piaotong
|
||||
package com.bbit.ticket.database.piaotong
|
||||
|
||||
import org.jetbrains.exposed.v1.core.Table
|
||||
import org.jetbrains.exposed.v1.javatime.timestampWithTimeZone
|
||||
@@ -306,13 +306,13 @@ object HistoryInvoiceBasicTable : Table("history_invoice_basic") {
|
||||
.nullable()
|
||||
|
||||
/**
|
||||
* 冲红状态
|
||||
* 红冲状态
|
||||
*
|
||||
* NOT_RED:未冲红
|
||||
* ALREADY_RED:已冲红
|
||||
* REDING:冲红中
|
||||
* RED_FAIL:冲红失败
|
||||
* PART_RED:部分冲红
|
||||
* NOT_RED:未红冲
|
||||
* ALREADY_RED:已红冲
|
||||
* REDING:红冲中
|
||||
* RED_FAIL:红冲失败
|
||||
* PART_RED:部分红冲
|
||||
*/
|
||||
val redFlag = varchar("red_flag", 32)
|
||||
.nullable()
|
||||
@@ -453,3 +453,4 @@ object HistoryInvoiceBasicTable : Table("history_invoice_basic") {
|
||||
|
||||
override val primaryKey = PrimaryKey(id)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@file:OptIn(ExperimentalUuidApi::class)
|
||||
@file:OptIn(ExperimentalUuidApi::class)
|
||||
|
||||
package com.bbit.ticket.database.piaotong
|
||||
|
||||
@@ -26,13 +26,13 @@ object HistoryInvoiceRedTable : Table("history_invoice_red") {
|
||||
|
||||
/**
|
||||
* 发票代码
|
||||
* 需冲红的原发票代码,冲红增值税发票管理系统开具的发票或数电纸质发票时必填
|
||||
* 需红冲的原发票代码,红冲增值税发票管理系统开具的发票或数电纸质发票时必填
|
||||
*/
|
||||
val invoiceCode = varchar("invoice_code", 12).nullable()
|
||||
|
||||
/**
|
||||
* 发票请求流水号
|
||||
* 需冲红的原发票号码,冲红增值税发票管理系统开具的发票或数电纸质发票时必填
|
||||
* 需红冲的原发票号码,红冲增值税发票管理系统开具的发票或数电纸质发票时必填
|
||||
*/
|
||||
val invoiceNo = varchar("invoice_no", 8).nullable()
|
||||
|
||||
@@ -42,7 +42,7 @@ object HistoryInvoiceRedTable : Table("history_invoice_red") {
|
||||
val invoiceReqSerialNo = varchar("invoice_req_serial_no", 20)
|
||||
|
||||
/**
|
||||
* 冲红原因
|
||||
* 红冲原因
|
||||
* 01:开票有误
|
||||
* 02:销货退回
|
||||
* 03:服务中止
|
||||
@@ -61,9 +61,9 @@ object HistoryInvoiceRedTable : Table("history_invoice_red") {
|
||||
* 81:数电发票(增值税专用发票)
|
||||
* 82:数电发票(普通发票)。
|
||||
* 默认蓝票的发票种类代码。
|
||||
* 此字段目的解决数电发票冲红增值税发票,只有企业不再使用增值税系统时才可以跨票种冲红。
|
||||
* 数电发票(普通发票)可以冲红数电发票(普通发票)、增值税电子普通发票、增值税纸质普通发票。
|
||||
* 数电发票(增值税专用发票)可以冲红数电发票(增值税专用发票)、增值税电子专用发票、增值税纸质专用发票。
|
||||
* 此字段目的解决数电发票红冲增值税发票,只有企业不再使用增值税系统时才可以跨票种红冲。
|
||||
* 数电发票(普通发票)可以红冲数电发票(普通发票)、增值税电子普通发票、增值税纸质普通发票。
|
||||
* 数电发票(增值税专用发票)可以红冲数电发票(增值税专用发票)、增值税电子专用发票、增值税纸质专用发票。
|
||||
*/
|
||||
val invoiceKind = varchar("invoice_kind", 2).nullable()
|
||||
|
||||
@@ -104,3 +104,4 @@ object HistoryInvoiceRedTable : Table("history_invoice_red") {
|
||||
|
||||
override val primaryKey = PrimaryKey(id)
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ object OpenInvoiceTaskTable : Table("open_invoice_task") {
|
||||
val taxAccount = varchar("tax_account", 64).nullable()
|
||||
val taskType = varchar("task_type", 32)
|
||||
val sourceType = varchar("source_type", 32)
|
||||
val runMode = varchar("run_mode", 16)
|
||||
val invoiceReqSerialNo = varchar("invoice_req_serial_no", 20)
|
||||
val batchNo = varchar("batch_no", 64).nullable()
|
||||
val status = varchar("status", 32)
|
||||
|
||||
@@ -9,7 +9,6 @@ data class OpenInvoiceTaskSubmitResponse(
|
||||
val invoiceReqSerialNo: String,
|
||||
val status: String,
|
||||
val taskType: String,
|
||||
val runMode: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
@@ -37,7 +36,6 @@ data class OpenInvoiceTaskItem(
|
||||
val account: String? = null,
|
||||
val taskType: String,
|
||||
val sourceType: String,
|
||||
val runMode: String,
|
||||
val invoiceReqSerialNo: String,
|
||||
val batchNo: String? = null,
|
||||
val status: String,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bbit.ticket.entity.request
|
||||
package com.bbit.ticket.entity.request
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
@@ -28,7 +28,7 @@ data class CreateRedInvoiceRequest(
|
||||
/**
|
||||
* 蓝票代码
|
||||
*
|
||||
* 冲红税控发票或数电纸质发票时必填
|
||||
* 红冲税控发票或数电纸质发票时必填
|
||||
*/
|
||||
@SerialName("blueInvoiceCode")
|
||||
val blueInvoiceCode: String? = null,
|
||||
@@ -36,7 +36,7 @@ data class CreateRedInvoiceRequest(
|
||||
/**
|
||||
* 蓝票号码
|
||||
*
|
||||
* 冲红税控发票或数电纸质发票时必填
|
||||
* 红冲税控发票或数电纸质发票时必填
|
||||
*/
|
||||
@SerialName("blueInvoiceNo")
|
||||
val blueInvoiceNo: String? = null,
|
||||
@@ -98,4 +98,4 @@ data class CreateRedInvoiceRequest(
|
||||
*/
|
||||
@SerialName("definedData")
|
||||
val definedData: String? = null
|
||||
)
|
||||
)
|
||||
|
||||
+6
-6
@@ -1,4 +1,4 @@
|
||||
package com.bbit.ticket.entity.request
|
||||
package com.bbit.ticket.entity.request
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@@ -20,25 +20,25 @@ data class InitRedInvoiceConfirmRequest(
|
||||
|
||||
/**
|
||||
* 税控蓝字发票代码(10或12位)
|
||||
* 冲红增值税发票管理系统开具的发票或数电纸票时必填
|
||||
* 红冲增值税发票管理系统开具的发票或数电纸票时必填
|
||||
*/
|
||||
val invoiceCode: String? = null,
|
||||
|
||||
/**
|
||||
* 税控蓝字发票号码(8位)
|
||||
* 冲红增值税发票管理系统开具的发票或数电纸票时必填
|
||||
* 红冲增值税发票管理系统开具的发票或数电纸票时必填
|
||||
*/
|
||||
val invoiceNo: String? = null,
|
||||
|
||||
/**
|
||||
* 蓝字数电票号码(20位)
|
||||
* 冲红数电发票时必填
|
||||
* 红冲数电发票时必填
|
||||
*/
|
||||
val blueAllEleInvNo: String? = null,
|
||||
|
||||
/**
|
||||
* 蓝字发票开票日期(yyyyMMdd)
|
||||
* 冲红非票通平台开具的发票时必填
|
||||
* 红冲非票通平台开具的发票时必填
|
||||
*/
|
||||
val blueInvoiceDate: String? = null,
|
||||
|
||||
@@ -48,4 +48,4 @@ data class InitRedInvoiceConfirmRequest(
|
||||
* 若不传:优先取蓝票开票账号,否则取企业当前账号
|
||||
*/
|
||||
val account: String? = null
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.bbit.ticket.entity.request
|
||||
package com.bbit.ticket.entity.request
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* 快捷冲红数电发票请求
|
||||
* 快捷红冲数电发票请求
|
||||
*/
|
||||
@Serializable
|
||||
data class QuickRedInvoiceRequest(
|
||||
@@ -29,7 +29,7 @@ data class QuickRedInvoiceRequest(
|
||||
/**
|
||||
* 原发票代码
|
||||
*
|
||||
* 冲红增值税系统发票或数电纸质发票时必填
|
||||
* 红冲增值税系统发票或数电纸质发票时必填
|
||||
*/
|
||||
@SerialName("invoiceCode")
|
||||
val invoiceCode: String? = null,
|
||||
@@ -37,7 +37,7 @@ data class QuickRedInvoiceRequest(
|
||||
/**
|
||||
* 原发票号码
|
||||
*
|
||||
* 冲红增值税系统发票或数电纸质发票时必填
|
||||
* 红冲增值税系统发票或数电纸质发票时必填
|
||||
*/
|
||||
@SerialName("invoiceNo")
|
||||
val invoiceNo: String? = null,
|
||||
@@ -45,7 +45,7 @@ data class QuickRedInvoiceRequest(
|
||||
/**
|
||||
* 原数电发票号码
|
||||
*
|
||||
* 冲红数电发票时必填
|
||||
* 红冲数电发票时必填
|
||||
*/
|
||||
@SerialName("blueAllEleInvNo")
|
||||
val blueAllEleInvNo: String? = null,
|
||||
@@ -56,14 +56,14 @@ data class QuickRedInvoiceRequest(
|
||||
* 格式:yyyyMMdd
|
||||
*
|
||||
* 场景:
|
||||
* 冲红非票通平台开具的发票时必填,
|
||||
* 红冲非票通平台开具的发票时必填,
|
||||
* 税局会结合该日期与数电发票号码拉取原票
|
||||
*/
|
||||
@SerialName("blueInvoiceDate")
|
||||
val blueInvoiceDate: String? = null,
|
||||
|
||||
/**
|
||||
* 冲红原因
|
||||
* 红冲原因
|
||||
*
|
||||
* 默认值:01
|
||||
*
|
||||
@@ -108,7 +108,7 @@ data class QuickRedInvoiceRequest(
|
||||
*
|
||||
* 默认取蓝票票种
|
||||
*
|
||||
* 用于跨票种冲红场景
|
||||
* 用于跨票种红冲场景
|
||||
*/
|
||||
@SerialName("invoiceKind")
|
||||
val invoiceKind: String? = null,
|
||||
@@ -150,4 +150,4 @@ data class QuickRedInvoiceRequest(
|
||||
*/
|
||||
@SerialName("definedData")
|
||||
val definedData: String? = null
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bbit.ticket.entity.request
|
||||
package com.bbit.ticket.entity.request
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@@ -7,11 +7,11 @@ data class RedCreateRequest(
|
||||
|
||||
val historyId: String,
|
||||
/**
|
||||
* 平台数电账号 ID。企业管理员发起冲红时用于指定开票员。
|
||||
* 平台数电账号 ID。企业管理员发起红冲时用于指定开票员。
|
||||
*/
|
||||
val digitalAccountId: String? = null,
|
||||
/**
|
||||
* 冲红原因
|
||||
* 红冲原因
|
||||
*
|
||||
* 默认值:01
|
||||
*
|
||||
@@ -26,3 +26,4 @@ data class RedCreateRequest(
|
||||
val takerTel: String? = null,
|
||||
val takerEmail: String? = null,
|
||||
)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
|
||||
package com.bbit.ticket.entity.response
|
||||
|
||||
@@ -100,7 +100,7 @@ data class InvoiceHistoryItem(
|
||||
// ===== 发票状态标记 =====
|
||||
/** 作废状态 */
|
||||
val invalidFlag: String? = null,
|
||||
/** 冲红状态 */
|
||||
/** 红冲状态 */
|
||||
val redFlag: String? = null,
|
||||
|
||||
// ===== 人员信息 =====
|
||||
@@ -149,3 +149,4 @@ data class InvoiceHistoryItem(
|
||||
/** 删除标记 */
|
||||
val invDeletedFlag: String? = null,
|
||||
)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bbit.ticket.entity.response
|
||||
package com.bbit.ticket.entity.response
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
@@ -168,13 +168,13 @@ data class InvoiceInfo(
|
||||
val invalidFlag: String,
|
||||
|
||||
/**
|
||||
* 冲红标志
|
||||
* 红冲标志
|
||||
*
|
||||
* NOT_RED:未冲红
|
||||
* ALREADY_RED:已冲红
|
||||
* REDING:冲红中
|
||||
* RED_FAIL:冲红失败
|
||||
* PART_RED:部分冲红
|
||||
* NOT_RED:未红冲
|
||||
* ALREADY_RED:已红冲
|
||||
* REDING:红冲中
|
||||
* RED_FAIL:红冲失败
|
||||
* PART_RED:部分红冲
|
||||
*/
|
||||
@SerialName("redFlag")
|
||||
val redFlag: String,
|
||||
@@ -345,4 +345,4 @@ data class InvoiceItem(
|
||||
*/
|
||||
@SerialName("itemNo")
|
||||
val itemNo: String
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bbit.ticket.entity.response
|
||||
package com.bbit.ticket.entity.response
|
||||
|
||||
import com.bbit.ticket.entity.request.InvoiceItem
|
||||
import kotlinx.serialization.SerialName
|
||||
@@ -187,12 +187,12 @@ data class GetInvoiceInfoResponse(
|
||||
val invalidFlag: String? = null,
|
||||
|
||||
/**
|
||||
* 冲红状态
|
||||
* NOT_RED:未冲红
|
||||
* ALREADY_RED:已冲红
|
||||
* REDING:冲红中
|
||||
* RED_FAIL:冲红失败
|
||||
* PART_RED:部分冲红
|
||||
* 红冲状态
|
||||
* NOT_RED:未红冲
|
||||
* ALREADY_RED:已红冲
|
||||
* REDING:红冲中
|
||||
* RED_FAIL:红冲失败
|
||||
* PART_RED:部分红冲
|
||||
*/
|
||||
val redFlag: String? = null,
|
||||
|
||||
@@ -344,4 +344,4 @@ data class GetInvoiceInfoItem(
|
||||
|
||||
/** 蓝字发票明细序号(红票场景) */
|
||||
val blueInvOrderNo: String? = null
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.bbit.ticket.entity.response
|
||||
package com.bbit.ticket.entity.response
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* 快捷冲红数电发票响应
|
||||
* 快捷红冲数电发票响应
|
||||
*/
|
||||
@Serializable
|
||||
data class QuickRedInvoiceResponse(
|
||||
@@ -51,4 +51,4 @@ data class QuickRedInvoiceResponse(
|
||||
*/
|
||||
@SerialName("redApplySerialNo")
|
||||
val redApplySerialNo: String? = null
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
package com.bbit.ticket.entity.response
|
||||
package com.bbit.ticket.entity.response
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* 红票申请信息
|
||||
*
|
||||
* 对应 [HistoryInvoiceRedTable] 的冲红申请字段,
|
||||
* 对应 [HistoryInvoiceRedTable] 的红冲申请字段,
|
||||
* 用于红票详情弹窗展示。
|
||||
*/
|
||||
@Serializable
|
||||
data class RedInvoiceInfoResponse(
|
||||
/** 冲红原因:01=开票有误 02=销货退回 03=服务中止 04=销售折让 */
|
||||
/** 红冲原因:01=开票有误 02=销货退回 03=服务中止 04=销售折让 */
|
||||
val redReason: String,
|
||||
/** 收票人名称 */
|
||||
val takerName: String? = null,
|
||||
@@ -19,3 +19,4 @@ data class RedInvoiceInfoResponse(
|
||||
/** 收票人邮箱 */
|
||||
val takerEmail: String? = null,
|
||||
)
|
||||
|
||||
|
||||
+2
-16
@@ -8,27 +8,13 @@ import io.ktor.server.routing.Route
|
||||
import io.ktor.server.routing.post
|
||||
|
||||
fun Route.registerOpenInvoiceTaskRoutes() {
|
||||
post("/test") {
|
||||
post {
|
||||
val principal = call.requireOpenApiPrincipal()
|
||||
val request = call.receive<OpenBlueInvoiceCreateRequest>()
|
||||
call.respondOpenApi(principal, "blue-invoice-task.test", null) {
|
||||
call.respondOpenApi(principal, "blue-invoice-task.create", null) {
|
||||
OpenInvoiceTaskService.createIssueTask(
|
||||
principal = principal,
|
||||
request = request,
|
||||
runMode = OpenInvoiceTaskService.MODE_SIMULATED,
|
||||
sourceType = OpenInvoiceTaskService.SOURCE_TEST,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
post("/production") {
|
||||
val principal = call.requireOpenApiPrincipal()
|
||||
val request = call.receive<OpenBlueInvoiceCreateRequest>()
|
||||
call.respondOpenApi(principal, "blue-invoice-task.production", null) {
|
||||
OpenInvoiceTaskService.createIssueTask(
|
||||
principal = principal,
|
||||
request = request,
|
||||
runMode = OpenInvoiceTaskService.MODE_REAL,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -21,7 +21,6 @@ fun Route.registerOpenInvoiceTaskManageRoutes() {
|
||||
digitalAccountId = call.request.queryParameters["digitalAccountId"],
|
||||
status = call.request.queryParameters["status"],
|
||||
sourceType = call.request.queryParameters["sourceType"],
|
||||
runMode = call.request.queryParameters["runMode"],
|
||||
page = call.request.queryParameters["page"]?.toIntOrNull() ?: 1,
|
||||
pageSize = call.request.queryParameters["pageSize"]?.toIntOrNull() ?: 20,
|
||||
)
|
||||
|
||||
@@ -12,6 +12,8 @@ import com.bbit.ticket.entity.request.UpdateDigitalAccountStatusRequest
|
||||
import com.bbit.ticket.entity.request.UpdateInvoiceSettingRequest
|
||||
import com.bbit.ticket.service.piaotong.PTAuthService
|
||||
import com.bbit.ticket.service.piaotong.PTConfigService
|
||||
import com.bbit.ticket.utils.queryInt
|
||||
import com.bbit.ticket.utils.queryString
|
||||
import com.bbit.ticket.utils.requireCurrentUser
|
||||
import io.ktor.server.request.receive
|
||||
import io.ktor.server.routing.Route
|
||||
@@ -59,7 +61,23 @@ fun Route.registerPTAuthRoutes() {
|
||||
|
||||
get("/digital-accounts") {
|
||||
call.respondPt("查询数电账号失败") {
|
||||
PTConfigService.listDigitalAccounts(call.requireCurrentUser())
|
||||
PTConfigService.listDigitalAccounts(
|
||||
user = call.requireCurrentUser(),
|
||||
account = call.queryString("account"),
|
||||
status = call.queryString("status"),
|
||||
page = call.queryInt("page", 1),
|
||||
pageSize = call.queryInt("pageSize", 20),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
get("/digital-accounts/options") {
|
||||
call.respondPt("查询数电账号选项失败") {
|
||||
PTConfigService.listDigitalAccountOptions(
|
||||
user = call.requireCurrentUser(),
|
||||
account = call.queryString("account"),
|
||||
limit = call.queryInt("limit", 200),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,9 +56,6 @@ object OpenInvoiceTaskService {
|
||||
const val TASK_ISSUE_BLUE = "ISSUE_BLUE"
|
||||
const val TASK_QUERY_BLUE = "QUERY_BLUE"
|
||||
const val SOURCE_SINGLE = "SINGLE"
|
||||
const val SOURCE_TEST = "TEST"
|
||||
const val MODE_REAL = "REAL"
|
||||
const val MODE_SIMULATED = "SIMULATED"
|
||||
|
||||
private const val STATUS_PENDING = "PENDING"
|
||||
private const val STATUS_PROCESSING = "PROCESSING"
|
||||
@@ -75,7 +72,6 @@ object OpenInvoiceTaskService {
|
||||
suspend fun createIssueTask(
|
||||
principal: OpenApiPrincipal,
|
||||
request: OpenBlueInvoiceCreateRequest,
|
||||
runMode: String,
|
||||
sourceType: String = SOURCE_SINGLE,
|
||||
batchNo: String? = null,
|
||||
): OpenInvoiceTaskSubmitResponse {
|
||||
@@ -97,12 +93,6 @@ object OpenInvoiceTaskService {
|
||||
.singleOrNull()
|
||||
}
|
||||
if (existing != null) {
|
||||
if (existing[OpenInvoiceTaskTable.runMode] != runMode) {
|
||||
throw BizException(
|
||||
ErrorCode.BAD_REQUEST.code,
|
||||
"invoiceReqSerialNo 已存在 ${existing[OpenInvoiceTaskTable.runMode]} 任务,不能重复创建 $runMode 任务",
|
||||
)
|
||||
}
|
||||
return existing.toSubmitResponse()
|
||||
}
|
||||
|
||||
@@ -129,7 +119,6 @@ object OpenInvoiceTaskService {
|
||||
it[taxAccount] = principal.taxAccount
|
||||
it[taskType] = TASK_ISSUE_BLUE
|
||||
it[OpenInvoiceTaskTable.sourceType] = sourceType
|
||||
it[OpenInvoiceTaskTable.runMode] = runMode
|
||||
it[OpenInvoiceTaskTable.invoiceReqSerialNo] = invoiceReqSerialNo
|
||||
it[OpenInvoiceTaskTable.batchNo] = batchNo
|
||||
it[status] = STATUS_PENDING
|
||||
@@ -146,19 +135,12 @@ object OpenInvoiceTaskService {
|
||||
}
|
||||
.single()
|
||||
}
|
||||
if (task[OpenInvoiceTaskTable.runMode] != runMode) {
|
||||
throw BizException(
|
||||
ErrorCode.BAD_REQUEST.code,
|
||||
"invoiceReqSerialNo 已存在 ${task[OpenInvoiceTaskTable.runMode]} 任务,不能重复创建 $runMode 任务",
|
||||
)
|
||||
}
|
||||
|
||||
return OpenInvoiceTaskSubmitResponse(
|
||||
taskId = task[OpenInvoiceTaskTable.id].toString(),
|
||||
invoiceReqSerialNo = invoiceReqSerialNo,
|
||||
status = task[OpenInvoiceTaskTable.status],
|
||||
taskType = TASK_ISSUE_BLUE,
|
||||
runMode = runMode,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -201,7 +183,6 @@ object OpenInvoiceTaskService {
|
||||
digitalAccountId: String?,
|
||||
status: String?,
|
||||
sourceType: String?,
|
||||
runMode: String?,
|
||||
page: Int,
|
||||
pageSize: Int,
|
||||
): PageResult<OpenInvoiceTaskItem> = dbQuery {
|
||||
@@ -215,9 +196,6 @@ object OpenInvoiceTaskService {
|
||||
sourceType?.takeIf { it.isNotBlank() }?.let {
|
||||
where = where and (OpenInvoiceTaskTable.sourceType eq it)
|
||||
}
|
||||
runMode?.takeIf { it.isNotBlank() }?.let {
|
||||
where = where and (OpenInvoiceTaskTable.runMode eq it)
|
||||
}
|
||||
val accountRows = PtDigitalAccountTable.selectAll()
|
||||
.where { accountScope(user) }
|
||||
.associateBy { it[PtDigitalAccountTable.id] }
|
||||
@@ -290,18 +268,13 @@ object OpenInvoiceTaskService {
|
||||
|
||||
private suspend fun processIssueTask(task: ResultRow) {
|
||||
val taskId = task[OpenInvoiceTaskTable.id]
|
||||
val runMode = task[OpenInvoiceTaskTable.runMode]
|
||||
val request = task[OpenInvoiceTaskTable.requestBody]
|
||||
?.let { myJson.decodeFromString<OpenBlueInvoiceCreateRequest>(it) }
|
||||
?: return failTask(taskId, "REQUEST_BODY_NULL", "任务请求体为空")
|
||||
val askRequest = request.toAskInvoiceRequest(task)
|
||||
createHistoryPlaceholder(task, askRequest)
|
||||
try {
|
||||
if (runMode == MODE_SIMULATED) {
|
||||
delay(2000)
|
||||
} else {
|
||||
PTApi.invoiceBlue(askRequest)
|
||||
}
|
||||
PTApi.invoiceBlue(askRequest)
|
||||
completeIssueTask(task)
|
||||
} catch (e: PTException) {
|
||||
failTask(taskId, e.code, e.message)
|
||||
@@ -314,31 +287,23 @@ object OpenInvoiceTaskService {
|
||||
}
|
||||
|
||||
private suspend fun processQueryTask(task: ResultRow) {
|
||||
val taskId = task[OpenInvoiceTaskTable.id]
|
||||
val runMode = task[OpenInvoiceTaskTable.runMode]
|
||||
val invoiceReqSerialNo = task[OpenInvoiceTaskTable.invoiceReqSerialNo]
|
||||
try {
|
||||
val (code, message) = if (runMode == MODE_SIMULATED) {
|
||||
delay(2000)
|
||||
simulatedQueryCode(invoiceReqSerialNo, task[OpenInvoiceTaskTable.pollCount]) to null
|
||||
} else {
|
||||
val res = PTApi.queryInvoiceInfo(
|
||||
QueryInvoiceRequest(
|
||||
taxpayerNum = task[OpenInvoiceTaskTable.taxpayerNum],
|
||||
invoiceReqSerialNo = invoiceReqSerialNo,
|
||||
)
|
||||
val res = PTApi.queryInvoiceInfo(
|
||||
QueryInvoiceRequest(
|
||||
taxpayerNum = task[OpenInvoiceTaskTable.taxpayerNum],
|
||||
invoiceReqSerialNo = invoiceReqSerialNo,
|
||||
)
|
||||
)
|
||||
dbQuery {
|
||||
BlueInvoiceDao.upsertInvoiceInfo(
|
||||
task[OpenInvoiceTaskTable.userId],
|
||||
res,
|
||||
task[OpenInvoiceTaskTable.enterpriseId],
|
||||
task[OpenInvoiceTaskTable.digitalAccountId],
|
||||
)
|
||||
dbQuery {
|
||||
BlueInvoiceDao.upsertInvoiceInfo(
|
||||
task[OpenInvoiceTaskTable.userId],
|
||||
res,
|
||||
task[OpenInvoiceTaskTable.enterpriseId],
|
||||
task[OpenInvoiceTaskTable.digitalAccountId],
|
||||
)
|
||||
}
|
||||
res.code to res.msg
|
||||
}
|
||||
handleQueryCode(task, code, message)
|
||||
handleQueryCode(task, res.code, res.msg)
|
||||
} catch (e: PTException) {
|
||||
retryOrFail(task, e.code, e.message)
|
||||
} catch (e: Exception) {
|
||||
@@ -368,7 +333,6 @@ object OpenInvoiceTaskService {
|
||||
it[taxAccount] = task[OpenInvoiceTaskTable.taxAccount]
|
||||
it[taskType] = TASK_QUERY_BLUE
|
||||
it[sourceType] = task[OpenInvoiceTaskTable.sourceType]
|
||||
it[runMode] = task[OpenInvoiceTaskTable.runMode]
|
||||
it[OpenInvoiceTaskTable.invoiceReqSerialNo] = invoiceReqSerialNo
|
||||
it[batchNo] = task[OpenInvoiceTaskTable.batchNo]
|
||||
it[status] = STATUS_PENDING
|
||||
@@ -660,15 +624,6 @@ object OpenInvoiceTaskService {
|
||||
orderList = orderList,
|
||||
)
|
||||
|
||||
private fun simulatedQueryCode(invoiceReqSerialNo: String, pollCount: Int): String =
|
||||
when {
|
||||
invoiceReqSerialNo.contains("3999", ignoreCase = true) -> AUTH_REQUIRED_CODE
|
||||
invoiceReqSerialNo.contains("FAIL", ignoreCase = true) -> "9999"
|
||||
pollCount <= 0 -> "7777"
|
||||
pollCount == 1 -> "6666"
|
||||
else -> "0000"
|
||||
}
|
||||
|
||||
private fun historyCode(code: String): String =
|
||||
if (code.length <= 8) code else HISTORY_FAILED_CODE
|
||||
|
||||
@@ -706,7 +661,6 @@ object OpenInvoiceTaskService {
|
||||
invoiceReqSerialNo = this[OpenInvoiceTaskTable.invoiceReqSerialNo],
|
||||
status = this[OpenInvoiceTaskTable.status],
|
||||
taskType = this[OpenInvoiceTaskTable.taskType],
|
||||
runMode = this[OpenInvoiceTaskTable.runMode],
|
||||
)
|
||||
|
||||
private fun ResultRow.toTaskItem(account: String?, historyMessage: String?): OpenInvoiceTaskItem =
|
||||
@@ -717,7 +671,6 @@ object OpenInvoiceTaskService {
|
||||
account = account,
|
||||
taskType = this[OpenInvoiceTaskTable.taskType],
|
||||
sourceType = this[OpenInvoiceTaskTable.sourceType],
|
||||
runMode = this[OpenInvoiceTaskTable.runMode],
|
||||
invoiceReqSerialNo = this[OpenInvoiceTaskTable.invoiceReqSerialNo],
|
||||
batchNo = this[OpenInvoiceTaskTable.batchNo],
|
||||
status = this[OpenInvoiceTaskTable.status],
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.bbit.ticket.dao.piaotong.EnterpriseManageDao
|
||||
import com.bbit.ticket.dao.system.UserDao
|
||||
import com.bbit.ticket.database.piaotong.PtDigitalAccountTable
|
||||
import com.bbit.ticket.database.system.SysUserTable
|
||||
import com.bbit.ticket.entity.common.PageResult
|
||||
import com.bbit.ticket.entity.request.CreateDigitalAccountRequest
|
||||
import com.bbit.ticket.entity.request.QueryDigitalAccountListRequest
|
||||
import com.bbit.ticket.entity.request.QueryEnterpriseBankAccountRequest
|
||||
@@ -62,15 +63,42 @@ object PTConfigService {
|
||||
return PTAuthService.queryEnterpriseBankInfo(QueryEnterpriseBankAccountRequest(taxpayerNum)).bankList
|
||||
}
|
||||
|
||||
suspend fun listDigitalAccounts(user: CurrentUser): List<DigitalAccountManageItem> = dbQuery {
|
||||
suspend fun listDigitalAccounts(
|
||||
user: CurrentUser,
|
||||
account: String?,
|
||||
status: String?,
|
||||
page: Int,
|
||||
pageSize: Int,
|
||||
): PageResult<DigitalAccountManageItem> = dbQuery {
|
||||
when {
|
||||
user.isSuperAdmin || user.isEnterpriseAdmin -> {
|
||||
EnterpriseManageDao.digitalAccountsForEnterprise(requireEnterpriseId(user))
|
||||
EnterpriseManageDao.digitalAccountsForEnterprise(requireEnterpriseId(user), account, status, page, pageSize)
|
||||
}
|
||||
user.isDigitalOperator -> {
|
||||
val id = user.digitalAccountId
|
||||
?: throw BizException(ErrorCode.BAD_REQUEST.code, "当前账号未绑定数电账号")
|
||||
EnterpriseManageDao.digitalAccount(id)?.let { listOf(EnterpriseManageDao.run { it.toDigitalAccountItem() }) }
|
||||
val item = EnterpriseManageDao.digitalAccount(id)
|
||||
?.let { EnterpriseManageDao.run { it.toDigitalAccountItem() } }
|
||||
?.takeIf { account.isNullOrBlank() || it.account.contains(account.trim(), ignoreCase = true) }
|
||||
?.takeIf { status.isNullOrBlank() || it.status == status.trim().uppercase() }
|
||||
PageResult(listOfNotNull(item), page, pageSize, if (item == null) 0 else 1)
|
||||
}
|
||||
else -> PageResult(emptyList(), page, pageSize, 0)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun listDigitalAccountOptions(user: CurrentUser, account: String?, limit: Int): List<DigitalAccountManageItem> = dbQuery {
|
||||
when {
|
||||
user.isSuperAdmin || user.isEnterpriseAdmin -> {
|
||||
EnterpriseManageDao.digitalAccountOptionsForEnterprise(requireEnterpriseId(user), account, limit.coerceIn(1, 200))
|
||||
}
|
||||
user.isDigitalOperator -> {
|
||||
val id = user.digitalAccountId
|
||||
?: throw BizException(ErrorCode.BAD_REQUEST.code, "当前账号未绑定数电账号")
|
||||
EnterpriseManageDao.digitalAccount(id)
|
||||
?.let { EnterpriseManageDao.run { it.toDigitalAccountItem() } }
|
||||
?.takeIf { account.isNullOrBlank() || it.account.contains(account.trim(), ignoreCase = true) }
|
||||
?.let { listOf(it) }
|
||||
?: emptyList()
|
||||
}
|
||||
else -> emptyList()
|
||||
@@ -97,7 +125,7 @@ object PTConfigService {
|
||||
)
|
||||
}
|
||||
}
|
||||
return listDigitalAccounts(user)
|
||||
return listDigitalAccountOptions(user, null, 200)
|
||||
}
|
||||
|
||||
suspend fun createDigitalAccount(user: CurrentUser, req: CreateDigitalAccountRequest): DigitalAccountManageItem {
|
||||
|
||||
@@ -59,6 +59,7 @@ object DatabaseInitializer {
|
||||
exec(it)
|
||||
}
|
||||
}
|
||||
exec("ALTER TABLE open_invoice_task DROP COLUMN IF EXISTS run_mode")
|
||||
}
|
||||
logger.info("Database schema initialized")
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.bbit.ticket.utils.bootstrap
|
||||
|
||||
object Global {
|
||||
|
||||
val isDev = true
|
||||
val isDev = false
|
||||
|
||||
// 请求基础地址
|
||||
var baseUrl: String
|
||||
|
||||
Reference in New Issue
Block a user