feat: 实现了许多功能

对接了kafka
实现了preUploadFile接口
接入了SaToken的注解鉴权
为BusinessError添加了cause属性
将register接口的请求数据改为了表单
将SaToken登录用的对象改为了user本身
修改了gradle的镜像构建配置
为gradlew添加了代理配置
master
ArgonarioD 2023-07-03 18:42:09 +08:00
parent 02ecdd3e18
commit a2086975f4
21 changed files with 1083 additions and 17 deletions

View File

@ -1,4 +1,5 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.springframework.boot.gradle.tasks.bundling.BootBuildImage
import org.springframework.boot.gradle.tasks.run.BootRun import org.springframework.boot.gradle.tasks.run.BootRun
plugins { plugins {
@ -46,6 +47,7 @@ dependencies {
implementation("com.lmax:disruptor:3.4.4") implementation("com.lmax:disruptor:3.4.4")
// kotlin 协程spring 异步接口) // kotlin 协程spring 异步接口)
val kotlinxCoroutinesVersion = "1.7.1" val kotlinxCoroutinesVersion = "1.7.1"
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:$kotlinxCoroutinesVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk9:$kotlinxCoroutinesVersion") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk9:$kotlinxCoroutinesVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$kotlinxCoroutinesVersion") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$kotlinxCoroutinesVersion")
implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-reflect")
@ -55,7 +57,9 @@ dependencies {
implementation("org.babyfish.jimmer:jimmer-spring-boot-starter:0.7.104") implementation("org.babyfish.jimmer:jimmer-spring-boot-starter:0.7.104")
ksp("org.babyfish.jimmer:jimmer-ksp:0.7.104") ksp("org.babyfish.jimmer:jimmer-ksp:0.7.104")
// developmentOnly("org.springframework.boot:spring-boot-docker-compose") // developmentOnly("org.springframework.boot:spring-boot-docker-compose")
runtimeOnly("org.postgresql:postgresql") implementation("org.postgresql:postgresql")
// Kafka
implementation("org.springframework.kafka:spring-kafka")
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("org.springframework.boot:spring-boot-starter-test")
} }
@ -65,6 +69,10 @@ tasks.withType<BootRun> {
jvmArgs = jvmArgs?.toMutableList()?.plus("-Dlog4j.skipJansi=false") jvmArgs = jvmArgs?.toMutableList()?.plus("-Dlog4j.skipJansi=false")
} }
tasks.withType<BootBuildImage> {
imageName.set("auto/aics_main")
}
tasks.withType<KotlinCompile> { tasks.withType<KotlinCompile> {
kotlinOptions { kotlinOptions {
freeCompilerArgs += "-Xjsr305=strict" freeCompilerArgs += "-Xjsr305=strict"

View File

@ -3,3 +3,7 @@ distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
systemProp.http.proxyHost=127.0.0.1
systemProp.http.proxyPort=7890
systemProp.https.proxyHost=127.0.0.1
systemProp.https.proxyPort=7890

View File

@ -1,12 +1,30 @@
package cn.edu.hfut.auto.knowledge.config package cn.edu.hfut.auto.knowledge.config
import org.babyfish.jimmer.sql.runtime.DefaultDatabaseNamingStrategy import org.babyfish.jimmer.sql.runtime.DefaultDatabaseNamingStrategy
import org.babyfish.jimmer.sql.runtime.ScalarProvider
import org.postgresql.util.PGobject
import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Configuration
import org.springframework.stereotype.Component
import java.util.*
@Configuration @Configuration
class JimmerConfig { class JimmerConfig {
@Bean @Bean
fun databaseNamingStrategy(): DefaultDatabaseNamingStrategy = fun databaseNamingStrategy(): DefaultDatabaseNamingStrategy =
DefaultDatabaseNamingStrategy.LOWER_CASE DefaultDatabaseNamingStrategy.LOWER_CASE
@Component
class PostgresUUIDScalarProvider : ScalarProvider<UUID, PGobject>() {
override fun toScalar(sqlValue: PGobject): UUID {
return UUID.fromString(sqlValue.value)
}
override fun toSql(scalarValue: UUID): PGobject {
return PGobject().apply {
type = "uuid"
value = scalarValue.toString()
}
}
}
} }

View File

@ -0,0 +1,29 @@
package cn.edu.hfut.auto.knowledge.config
import org.apache.kafka.clients.producer.ProducerConfig
import org.apache.kafka.common.serialization.StringSerializer
import org.springframework.boot.autoconfigure.kafka.KafkaProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.kafka.core.DefaultKafkaProducerFactory
import org.springframework.kafka.core.KafkaTemplate
import org.springframework.kafka.core.ProducerFactory
import org.springframework.kafka.support.serializer.JsonSerializer
@Configuration
class KafkaConfig(
private val kafkaProperties: KafkaProperties
) {
fun anyJsonProducerFactory(): ProducerFactory<String, Any?> =
DefaultKafkaProducerFactory(
hashMapOf(
ProducerConfig.BOOTSTRAP_SERVERS_CONFIG to kafkaProperties.bootstrapServers,
ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG to StringSerializer::class.java,
ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG to JsonSerializer::class.java
)
)
@Bean
fun anyJsonKafkaTemplate(): KafkaTemplate<String, Any?> =
KafkaTemplate(anyJsonProducerFactory())
}

View File

@ -0,0 +1,64 @@
package cn.edu.hfut.auto.knowledge.config
import cn.dev33.satoken.interceptor.SaInterceptor
import cn.dev33.satoken.stp.StpInterface
import cn.edu.hfut.auto.knowledge.entity.User
import cn.edu.hfut.auto.knowledge.util.getLogger
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Configuration
import org.springframework.stereotype.Component
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
@Configuration
class SaTokenConfig : WebMvcConfigurer {
override fun addInterceptors(registry: InterceptorRegistry) {
registry.run {
// addInterceptor(object : HandlerInterceptor {
// override fun preHandle(
// request: HttpServletRequest,
// response: HttpServletResponse,
// handler: Any
// ): Boolean {
// log.info("****** headers ******")
// for (headerName in request.headerNames) {
// log.info("{}: {}", headerName, request.getHeaders(headerName).toList().joinToString())
// }
// log.info("*********************")
// return super.preHandle(request, response, handler)
// }
// }).addPathPatterns("/**")
addInterceptor(SaInterceptor()).addPathPatterns("/**")
}
}
@Component
class StpInterfaceImpl(
@Value("\${aics.max-permission-level}")
private val maxPermissionLevel: Short,
private val objectMapper: ObjectMapper
) : StpInterface {
private val permissionCache: HashMap<Short, List<String>> = hashMapOf()
override fun getPermissionList(loginId: Any?, loginType: String?): List<String> {
return getRoleList(loginId, loginType)
}
override fun getRoleList(loginId: Any?, loginType: String?): List<String> {
return (loginId as? String)
?.let { objectMapper.readValue<User>(it).level }
?.let { getPermissionLevelStringList(it) }
?: mutableListOf()
}
private fun getPermissionLevelStringList(userLevel: Short): List<String> {
return permissionCache.getOrPut(userLevel) {
(userLevel..maxPermissionLevel).map { it.toString() }
}
}
}
}

View File

@ -19,6 +19,6 @@ class AuthorizeController(
val user = userRepository.findByUsername(vo.username) val user = userRepository.findByUsername(vo.username)
?.takeIf { BCrypt.checkpw(vo.password, it.password) } ?.takeIf { BCrypt.checkpw(vo.password, it.password) }
?: throw BusinessError(ErrorCode.INVALID_USERNAME_OR_PASSWORD) ?: throw BusinessError(ErrorCode.INVALID_USERNAME_OR_PASSWORD)
StpUtil.login(user.id) StpUtil.login(user)
} }
} }

View File

@ -3,12 +3,10 @@ package cn.edu.hfut.auto.knowledge.controller
import cn.dev33.satoken.secure.BCrypt import cn.dev33.satoken.secure.BCrypt
import cn.edu.hfut.auto.knowledge.entity.User import cn.edu.hfut.auto.knowledge.entity.User
import cn.edu.hfut.auto.knowledge.entity.by import cn.edu.hfut.auto.knowledge.entity.by
import cn.edu.hfut.auto.knowledge.entity.vo.LoginVO
import cn.edu.hfut.auto.knowledge.repository.UserRepository import cn.edu.hfut.auto.knowledge.repository.UserRepository
import org.babyfish.jimmer.kt.new import org.babyfish.jimmer.kt.new
import org.springframework.context.annotation.Profile import org.springframework.context.annotation.Profile
import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RestController import org.springframework.web.bind.annotation.RestController
@Profile("dev") @Profile("dev")
@ -17,11 +15,11 @@ class DevOnlyController(
private val userRepository: UserRepository private val userRepository: UserRepository
) { ) {
@PostMapping("/register") @PostMapping("/register")
fun register(@RequestBody vo: LoginVO) { fun register(username: String, password: String, level: Short) {
userRepository.insert(new(User::class).by { userRepository.insert(new(User::class).by {
username = vo.username this.username = username
password = BCrypt.hashpw(vo.password) this.password = BCrypt.hashpw(password)
level = 2 this.level = level
}) })
} }
} }

View File

@ -0,0 +1,71 @@
package cn.edu.hfut.auto.knowledge.controller
import cn.dev33.satoken.annotation.SaCheckRole
import cn.edu.hfut.auto.knowledge.entity.Knowledge
import cn.edu.hfut.auto.knowledge.entity.KnowledgeFileAttribute
import cn.edu.hfut.auto.knowledge.entity.by
import cn.edu.hfut.auto.knowledge.entity.rpc.FileTicket
import cn.edu.hfut.auto.knowledge.entity.vo.KnowledgeFileUploadVO
import cn.edu.hfut.auto.knowledge.exception.BusinessError
import cn.edu.hfut.auto.knowledge.exception.ErrorCode
import cn.edu.hfut.auto.knowledge.repository.KnowledgeFileAttributeRepository
import cn.edu.hfut.auto.knowledge.repository.KnowledgeRepository
import cn.edu.hfut.auto.knowledge.util.fileSuffix
import kotlinx.coroutines.future.await
import org.apache.kafka.common.KafkaException
import org.babyfish.jimmer.kt.new
import org.springframework.kafka.core.KafkaTemplate
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import java.time.LocalDateTime
const val UPLOAD_FILE_TOPIC = "upload_file"
@RestController
@RequestMapping("/knowledge")
class KnowledgeController(
private val kafkaTemplate: KafkaTemplate<String, Any?>,
private val knowledgeRepository: KnowledgeRepository,
private val knowledgeFileAttributeRepository: KnowledgeFileAttributeRepository
) {
@SaCheckRole("1")
@Transactional(rollbackFor = [Throwable::class])
@PostMapping("/file")
suspend fun preUploadFile(@RequestBody vo: KnowledgeFileUploadVO): String {
knowledgeRepository.findByNameAndParentId(vo.name, vo.parentId, Knowledge.AS_CHILD_FETCHER)?.let {
throw BusinessError(ErrorCode.TARGET_ALREADY_EXISTS)
}
val knowledgeResult = knowledgeRepository.save(new(Knowledge::class).by {
name = vo.name
createTime = LocalDateTime.now()
vo.parentId?.let {
parent().apply {
id = it
}
} ?: let {
parent = null
}
})
val fileResult = knowledgeFileAttributeRepository.save(new(KnowledgeFileAttribute::class).by {
suffix = vo.name.fileSuffix
size = vo.size
brief = vo.brief
pageView = 0
knowledge().apply {
id = knowledgeResult.id
}
})
FileTicket(fileResult).run {
try {
kafkaTemplate.send(UPLOAD_FILE_TOPIC, this).await()
} catch (e: KafkaException) {
throw BusinessError(ErrorCode.MESSAGING_FAILED, cause = e)
}
return ticket
}
}
}

View File

@ -15,6 +15,7 @@ interface KnowledgeFileAttribute {
val pageView: Long val pageView: Long
@OneToOne @OneToOne
@Key
val knowledge: Knowledge val knowledge: Knowledge
@ManyToMany @ManyToMany

View File

@ -0,0 +1,24 @@
package cn.edu.hfut.auto.knowledge.entity.rpc
import cn.edu.hfut.auto.knowledge.entity.KnowledgeFileAttribute
import org.apache.commons.codec.digest.Sha2Crypt
import java.time.LocalDateTime
import java.util.UUID
data class FileTicket(
val ticket: String,
val id: UUID
) {
constructor(knowledgeFileAttribute: KnowledgeFileAttribute): this(
buildString {
knowledgeFileAttribute.run {
append(id)
append(size)
append(LocalDateTime.now())
}
}.let {
Sha2Crypt.sha256Crypt(it.toByteArray())
},
knowledgeFileAttribute.id
)
}

View File

@ -0,0 +1,12 @@
package cn.edu.hfut.auto.knowledge.entity.vo
import java.util.*
data class KnowledgeFileUploadVO(
val name: String,
val brief: String,
val size: Long,
val sha256: String,
val tags: List<Long>,
val parentId: UUID?
)

View File

@ -3,7 +3,7 @@ package cn.edu.hfut.auto.knowledge.exception
import org.springframework.http.ProblemDetail import org.springframework.http.ProblemDetail
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
class BusinessError(val code: ErrorCode, override val message: String = code.message) : RuntimeException() { class BusinessError(val code: ErrorCode, override val message: String = code.message, override val cause: Throwable? = null) : RuntimeException() {
override fun fillInStackTrace(): Throwable = this override fun fillInStackTrace(): Throwable = this
fun toResponseEntity(): ResponseEntity<ProblemDetail> = fun toResponseEntity(): ResponseEntity<ProblemDetail> =
ResponseEntity( ResponseEntity(

View File

@ -3,5 +3,14 @@ package cn.edu.hfut.auto.knowledge.exception
import org.springframework.http.HttpStatus import org.springframework.http.HttpStatus
enum class ErrorCode(val code: Int, val status: HttpStatus, val message: String) { enum class ErrorCode(val code: Int, val status: HttpStatus, val message: String) {
INVALID_USERNAME_OR_PASSWORD(200, HttpStatus.BAD_REQUEST, "用户名或密码错误") INVALID_USERNAME_OR_PASSWORD(200, HttpStatus.BAD_REQUEST, "用户名或密码错误"),
UNAUTHORIZED(300, HttpStatus.UNAUTHORIZED, "未登录或登录已过期"),
RESOURCE_NOT_FOUND(400, HttpStatus.NOT_FOUND, "找不到对应资源"),
TARGET_ALREADY_EXISTS(401, HttpStatus.CONFLICT, "目标已存在"),
MESSAGING_FAILED(500, HttpStatus.SERVICE_UNAVAILABLE, "消息通信失败,请重试"),
UNKNOWN_ERROR(999, HttpStatus.INTERNAL_SERVER_ERROR, "出现未知错误")
} }

View File

@ -1,5 +1,8 @@
package cn.edu.hfut.auto.knowledge.exception package cn.edu.hfut.auto.knowledge.exception
import cn.dev33.satoken.exception.NotLoginException
import cn.dev33.satoken.exception.NotRoleException
import cn.edu.hfut.auto.knowledge.util.getLogger
import org.springframework.http.ProblemDetail import org.springframework.http.ProblemDetail
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.ExceptionHandler import org.springframework.web.bind.annotation.ExceptionHandler
@ -7,8 +10,26 @@ import org.springframework.web.bind.annotation.RestControllerAdvice
@RestControllerAdvice @RestControllerAdvice
class ExceptionHandlerAdvice { class ExceptionHandlerAdvice {
private val log = getLogger()
@ExceptionHandler(BusinessError::class) @ExceptionHandler(BusinessError::class)
fun handleBusinessError(e: BusinessError): ResponseEntity<ProblemDetail> { fun handleBusinessError(e: BusinessError): ResponseEntity<ProblemDetail> {
e.cause?.run { log.error("BusinessError with cause: ", this) }
return e.toResponseEntity() return e.toResponseEntity()
} }
@ExceptionHandler(NotRoleException::class)
fun handleNotRoleException(e: NotRoleException): ResponseEntity<ProblemDetail> {
return BusinessError(ErrorCode.RESOURCE_NOT_FOUND).toResponseEntity()
}
@ExceptionHandler(NotLoginException::class)
fun handleNotLoginException(e: NotLoginException): ResponseEntity<ProblemDetail> {
return BusinessError(ErrorCode.UNAUTHORIZED).toResponseEntity()
}
@ExceptionHandler(Throwable::class)
fun handleThrowable(e: Throwable): ResponseEntity<ProblemDetail> {
log.error("Unknown Error: ", e)
return BusinessError(ErrorCode.UNKNOWN_ERROR).toResponseEntity()
}
} }

View File

@ -0,0 +1,7 @@
package cn.edu.hfut.auto.knowledge.repository
import cn.edu.hfut.auto.knowledge.entity.KnowledgeFileAttribute
import org.babyfish.jimmer.spring.repository.KRepository
import java.util.*
interface KnowledgeFileAttributeRepository : KRepository<KnowledgeFileAttribute, UUID>

View File

@ -0,0 +1,10 @@
package cn.edu.hfut.auto.knowledge.repository
import cn.edu.hfut.auto.knowledge.entity.Knowledge
import org.babyfish.jimmer.spring.repository.KRepository
import org.babyfish.jimmer.sql.fetcher.Fetcher
import java.util.*
interface KnowledgeRepository : KRepository<Knowledge, UUID> {
fun findByNameAndParentId(name: String, parentId: UUID?, fetcher: Fetcher<Knowledge>? = null): Knowledge?
}

View File

@ -0,0 +1,4 @@
package cn.edu.hfut.auto.knowledge.util
inline val String.fileSuffix
get() = this.substringAfterLast('.', "")

View File

@ -0,0 +1,6 @@
package cn.edu.hfut.auto.knowledge.util
import org.slf4j.Logger
import org.slf4j.LoggerFactory
inline fun <reified T> T.getLogger(): Logger = LoggerFactory.getLogger(T::class.java)

View File

@ -1,7 +1,7 @@
server: server:
ssl: # ssl:
key-store: classpath:ssl-rsa.pfx # key-store: classpath:ssl-rsa.pfx
key-store-password: auto # key-store-password: auto
http2: http2:
enabled: true enabled: true
@ -12,13 +12,22 @@ sa-token:
spring: spring:
datasource: datasource:
driver-class-name: org.postgresql.Driver driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://101.34.228.45:5432/aics_knowledge?useUnicode=true url: jdbc:postgresql://localhost:5432/aics_knowledge?useUnicode=true
username: aics_backend username: aics_backend
password: 123456 password: 123456
kafka:
bootstrap-servers:
- "localhost:9094"
producer:
retries: 3
jimmer: jimmer:
language: kotlin language: kotlin
dialect: org.babyfish.jimmer.sql.dialect.PostgresDialect dialect: org.babyfish.jimmer.sql.dialect.PostgresDialect
show-sql: true
logging: logging:
config: classpath:log4j2-dev.xml config: classpath:log4j2-dev.xml
aics:
max-permission-level: 3

View File

@ -1,7 +1,7 @@
server: server:
ssl: # ssl:
key-store: classpath:ssl-rsa.pfx # key-store: classpath:ssl-rsa.pfx
key-store-password: auto # key-store-password: auto
http2: http2:
enabled: true enabled: true
@ -15,9 +15,18 @@ spring:
url: jdbc:postgresql://localhost:5432/aics_knowledge?useUnicode=true url: jdbc:postgresql://localhost:5432/aics_knowledge?useUnicode=true
username: aics_backend username: aics_backend
password: 123456 password: 123456
kafka:
bootstrap-servers:
- "kafka:9092"
producer:
retries: 3
jimmer: jimmer:
language: kotlin language: kotlin
dialect: org.babyfish.jimmer.sql.dialect.PostgresDialect dialect: org.babyfish.jimmer.sql.dialect.PostgresDialect
logging: logging:
config: classpath:log4j2-prod.xml config: classpath:log4j2-prod.xml
aics:
max-permission-level: 3

View File

@ -0,0 +1,762 @@
--
-- PostgreSQL database dump
--
-- Dumped from database version 15.3 (Debian 15.3-1.pgdg120+1)
-- Dumped by pg_dump version 15.3
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
DROP DATABASE IF EXISTS aics_knowledge;
--
-- Name: aics_knowledge; Type: DATABASE; Schema: -; Owner: postgres
--
CREATE DATABASE aics_knowledge WITH TEMPLATE = template0 ENCODING = 'UTF8' LOCALE_PROVIDER = libc LOCALE = 'en_US.utf8';
ALTER DATABASE aics_knowledge OWNER TO postgres;
\connect aics_knowledge
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
--
-- Name: filetype; Type: TYPE; Schema: public; Owner: postgres
--
CREATE TYPE public.filetype AS ENUM (
'image',
'audio',
'video',
'doc',
'ppt',
'md',
'pdf',
'html',
'other'
);
ALTER TYPE public.filetype OWNER TO postgres;
SET default_tablespace = '';
SET default_table_access_method = heap;
--
-- Name: comment; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.comment (
id uuid NOT NULL,
content text NOT NULL,
author_id bigint NOT NULL,
note_id uuid NOT NULL,
create_time timestamp without time zone NOT NULL
);
ALTER TABLE public.comment OWNER TO postgres;
--
-- Name: knowledge; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.knowledge (
id uuid NOT NULL,
name character varying(60) NOT NULL,
parent_id uuid,
create_time timestamp without time zone NOT NULL
);
ALTER TABLE public.knowledge OWNER TO postgres;
--
-- Name: knowledge_file_attribute; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.knowledge_file_attribute (
id uuid NOT NULL,
suffix character varying(20) NOT NULL,
size bigint NOT NULL,
brief text NOT NULL,
page_view bigint NOT NULL,
knowledge_id uuid NOT NULL
);
ALTER TABLE public.knowledge_file_attribute OWNER TO postgres;
--
-- Name: knowledge_file_attribute_starer_mapping; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.knowledge_file_attribute_starer_mapping (
knowledge_file_attribute_id uuid NOT NULL,
user_id bigint NOT NULL
);
ALTER TABLE public.knowledge_file_attribute_starer_mapping OWNER TO postgres;
--
-- Name: knowledge_file_attribute_tag_mapping; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.knowledge_file_attribute_tag_mapping (
knowledge_file_attribute_id uuid NOT NULL,
tag_id bigint NOT NULL
);
ALTER TABLE public.knowledge_file_attribute_tag_mapping OWNER TO postgres;
--
-- Name: note; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.note (
id uuid NOT NULL,
title character varying(60) NOT NULL,
author_id bigint NOT NULL,
create_time timestamp without time zone NOT NULL,
update_time timestamp without time zone NOT NULL,
page_view bigint NOT NULL
);
ALTER TABLE public.note OWNER TO postgres;
--
-- Name: note_knowledge_file_mapping; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.note_knowledge_file_mapping (
note_id uuid NOT NULL,
knowledge_file_attribute_id uuid NOT NULL
);
ALTER TABLE public.note_knowledge_file_mapping OWNER TO postgres;
--
-- Name: note_liker_mapping; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.note_liker_mapping (
note_id uuid NOT NULL,
user_id bigint NOT NULL
);
ALTER TABLE public.note_liker_mapping OWNER TO postgres;
--
-- Name: note_starer_mapping; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.note_starer_mapping (
note_id uuid NOT NULL,
user_id bigint NOT NULL
);
ALTER TABLE public.note_starer_mapping OWNER TO postgres;
--
-- Name: note_tag_mapping; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.note_tag_mapping (
note_id uuid NOT NULL,
tag_id bigint NOT NULL
);
ALTER TABLE public.note_tag_mapping OWNER TO postgres;
--
-- Name: notice; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.notice (
id uuid NOT NULL,
viewed boolean NOT NULL,
create_time timestamp without time zone NOT NULL,
note_id uuid NOT NULL,
comment_id uuid NOT NULL,
target_user_id bigint NOT NULL
);
ALTER TABLE public.notice OWNER TO postgres;
--
-- Name: t_user; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.t_user (
id bigint NOT NULL,
username character varying(15) NOT NULL,
password character(60) NOT NULL,
level smallint NOT NULL
);
ALTER TABLE public.t_user OWNER TO postgres;
--
-- Name: t_user_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres
--
CREATE SEQUENCE public.t_user_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER TABLE public.t_user_id_seq OWNER TO postgres;
--
-- Name: t_user_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres
--
ALTER SEQUENCE public.t_user_id_seq OWNED BY public.t_user.id;
--
-- Name: tag; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.tag (
id bigint NOT NULL,
name character varying(20) NOT NULL
);
ALTER TABLE public.tag OWNER TO postgres;
--
-- Name: tag_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres
--
CREATE SEQUENCE public.tag_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER TABLE public.tag_id_seq OWNER TO postgres;
--
-- Name: tag_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres
--
ALTER SEQUENCE public.tag_id_seq OWNED BY public.tag.id;
--
-- Name: t_user id; Type: DEFAULT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.t_user ALTER COLUMN id SET DEFAULT nextval('public.t_user_id_seq'::regclass);
--
-- Name: tag id; Type: DEFAULT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.tag ALTER COLUMN id SET DEFAULT nextval('public.tag_id_seq'::regclass);
--
-- Data for Name: comment; Type: TABLE DATA; Schema: public; Owner: postgres
--
--
-- Data for Name: knowledge; Type: TABLE DATA; Schema: public; Owner: postgres
--
--
-- Data for Name: knowledge_file_attribute; Type: TABLE DATA; Schema: public; Owner: postgres
--
--
-- Data for Name: knowledge_file_attribute_starer_mapping; Type: TABLE DATA; Schema: public; Owner: postgres
--
--
-- Data for Name: knowledge_file_attribute_tag_mapping; Type: TABLE DATA; Schema: public; Owner: postgres
--
--
-- Data for Name: note; Type: TABLE DATA; Schema: public; Owner: postgres
--
--
-- Data for Name: note_knowledge_file_mapping; Type: TABLE DATA; Schema: public; Owner: postgres
--
--
-- Data for Name: note_liker_mapping; Type: TABLE DATA; Schema: public; Owner: postgres
--
--
-- Data for Name: note_starer_mapping; Type: TABLE DATA; Schema: public; Owner: postgres
--
--
-- Data for Name: note_tag_mapping; Type: TABLE DATA; Schema: public; Owner: postgres
--
--
-- Data for Name: notice; Type: TABLE DATA; Schema: public; Owner: postgres
--
--
-- Data for Name: t_user; Type: TABLE DATA; Schema: public; Owner: postgres
--
INSERT INTO public.t_user VALUES (1, 'test1', '$2a$10$Dbfl3tW/eIcjgJRrAxJNK.HODD/OJhboNWgIrFT8JnL5iGp45F2Ou', 2);
--
-- Data for Name: tag; Type: TABLE DATA; Schema: public; Owner: postgres
--
--
-- Name: t_user_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres
--
SELECT pg_catalog.setval('public.t_user_id_seq', 1, true);
--
-- Name: tag_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres
--
SELECT pg_catalog.setval('public.tag_id_seq', 1, false);
--
-- Name: comment comment_pk; Type: CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.comment
ADD CONSTRAINT comment_pk PRIMARY KEY (id);
--
-- Name: knowledge_file_attribute_tag_mapping file_tags_mapping_pk; Type: CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.knowledge_file_attribute_tag_mapping
ADD CONSTRAINT file_tags_mapping_pk PRIMARY KEY (knowledge_file_attribute_id, tag_id);
--
-- Name: knowledge_file_attribute knowledge_file_attribute_pk; Type: CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.knowledge_file_attribute
ADD CONSTRAINT knowledge_file_attribute_pk PRIMARY KEY (id);
--
-- Name: knowledge_file_attribute_starer_mapping knowledge_file_attribute_starer_mapping_pk; Type: CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.knowledge_file_attribute_starer_mapping
ADD CONSTRAINT knowledge_file_attribute_starer_mapping_pk PRIMARY KEY (knowledge_file_attribute_id, user_id);
--
-- Name: knowledge knowledge_pk; Type: CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.knowledge
ADD CONSTRAINT knowledge_pk PRIMARY KEY (id);
--
-- Name: note_knowledge_file_mapping note_knowledge_file_mapping_pk; Type: CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.note_knowledge_file_mapping
ADD CONSTRAINT note_knowledge_file_mapping_pk PRIMARY KEY (knowledge_file_attribute_id, note_id);
--
-- Name: note_liker_mapping note_liker_mapping_pk; Type: CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.note_liker_mapping
ADD CONSTRAINT note_liker_mapping_pk PRIMARY KEY (user_id, note_id);
--
-- Name: note note_pk; Type: CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.note
ADD CONSTRAINT note_pk PRIMARY KEY (id);
--
-- Name: note_starer_mapping note_starer_mapping_pk; Type: CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.note_starer_mapping
ADD CONSTRAINT note_starer_mapping_pk PRIMARY KEY (note_id, user_id);
--
-- Name: note_tag_mapping note_tag_mapping_pk; Type: CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.note_tag_mapping
ADD CONSTRAINT note_tag_mapping_pk PRIMARY KEY (tag_id, note_id);
--
-- Name: notice notice_pk; Type: CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.notice
ADD CONSTRAINT notice_pk PRIMARY KEY (id);
--
-- Name: t_user t_user_pk; Type: CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.t_user
ADD CONSTRAINT t_user_pk PRIMARY KEY (id);
--
-- Name: t_user t_user_username; Type: CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.t_user
ADD CONSTRAINT t_user_username UNIQUE (username);
--
-- Name: tag tag_pk; Type: CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.tag
ADD CONSTRAINT tag_pk PRIMARY KEY (id);
--
-- Name: comment_create_time_index; Type: INDEX; Schema: public; Owner: postgres
--
CREATE INDEX comment_create_time_index ON public.comment USING btree (create_time DESC);
--
-- Name: knowledge_file_attribute_suffix_index; Type: INDEX; Schema: public; Owner: postgres
--
CREATE INDEX knowledge_file_attribute_suffix_index ON public.knowledge_file_attribute USING hash (suffix);
--
-- Name: note_update_time_index; Type: INDEX; Schema: public; Owner: postgres
--
CREATE INDEX note_update_time_index ON public.note USING btree (update_time DESC);
--
-- Name: comment comment_note_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.comment
ADD CONSTRAINT comment_note_id_fk FOREIGN KEY (note_id) REFERENCES public.note(id);
--
-- Name: comment comment_t_user_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.comment
ADD CONSTRAINT comment_t_user_id_fk FOREIGN KEY (author_id) REFERENCES public.t_user(id);
--
-- Name: knowledge_file_attribute_tag_mapping file_tags_mapping_knowledge_file_attribute_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.knowledge_file_attribute_tag_mapping
ADD CONSTRAINT file_tags_mapping_knowledge_file_attribute_id_fk FOREIGN KEY (knowledge_file_attribute_id) REFERENCES public.knowledge_file_attribute(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: knowledge_file_attribute_tag_mapping file_tags_mapping_tag_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.knowledge_file_attribute_tag_mapping
ADD CONSTRAINT file_tags_mapping_tag_id_fk FOREIGN KEY (tag_id) REFERENCES public.tag(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: knowledge_file_attribute knowledge_file_attribute_knowledge_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.knowledge_file_attribute
ADD CONSTRAINT knowledge_file_attribute_knowledge_id_fk FOREIGN KEY (knowledge_id) REFERENCES public.knowledge(id);
--
-- Name: knowledge knowledge_parent_knowledge_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.knowledge
ADD CONSTRAINT knowledge_parent_knowledge_id_fk FOREIGN KEY (parent_id) REFERENCES public.knowledge(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: note_knowledge_file_mapping note_knowledge_file_mapping_knowledge_file_attribute_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.note_knowledge_file_mapping
ADD CONSTRAINT note_knowledge_file_mapping_knowledge_file_attribute_id_fk FOREIGN KEY (knowledge_file_attribute_id) REFERENCES public.knowledge_file_attribute(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: note_knowledge_file_mapping note_knowledge_file_mapping_note_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.note_knowledge_file_mapping
ADD CONSTRAINT note_knowledge_file_mapping_note_id_fk FOREIGN KEY (note_id) REFERENCES public.note(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: note_liker_mapping note_liker_mapping_note_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.note_liker_mapping
ADD CONSTRAINT note_liker_mapping_note_id_fk FOREIGN KEY (note_id) REFERENCES public.note(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: note_liker_mapping note_liker_mapping_t_user_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.note_liker_mapping
ADD CONSTRAINT note_liker_mapping_t_user_id_fk FOREIGN KEY (user_id) REFERENCES public.t_user(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: note_starer_mapping note_starer_mapping_note_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.note_starer_mapping
ADD CONSTRAINT note_starer_mapping_note_id_fk FOREIGN KEY (note_id) REFERENCES public.note(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: note_starer_mapping note_starer_mapping_t_user_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.note_starer_mapping
ADD CONSTRAINT note_starer_mapping_t_user_id_fk FOREIGN KEY (user_id) REFERENCES public.t_user(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: note note_t_user_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.note
ADD CONSTRAINT note_t_user_id_fk FOREIGN KEY (author_id) REFERENCES public.t_user(id);
--
-- Name: note_tag_mapping note_tag_mapping_note_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.note_tag_mapping
ADD CONSTRAINT note_tag_mapping_note_id_fk FOREIGN KEY (note_id) REFERENCES public.note(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: note_tag_mapping note_tag_mapping_tag_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.note_tag_mapping
ADD CONSTRAINT note_tag_mapping_tag_id_fk FOREIGN KEY (tag_id) REFERENCES public.tag(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: notice notice_comment_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.notice
ADD CONSTRAINT notice_comment_id_fk FOREIGN KEY (comment_id) REFERENCES public.comment(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: notice notice_note_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.notice
ADD CONSTRAINT notice_note_id_fk FOREIGN KEY (note_id) REFERENCES public.note(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: notice notice_t_user_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.notice
ADD CONSTRAINT notice_t_user_id_fk FOREIGN KEY (target_user_id) REFERENCES public.t_user(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: knowledge_file_attribute_starer_mapping starer_mapping_knowledge_file_attribute_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.knowledge_file_attribute_starer_mapping
ADD CONSTRAINT starer_mapping_knowledge_file_attribute_id_fk FOREIGN KEY (knowledge_file_attribute_id) REFERENCES public.knowledge_file_attribute(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: knowledge_file_attribute_starer_mapping starer_t_user_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.knowledge_file_attribute_starer_mapping
ADD CONSTRAINT starer_t_user_id_fk FOREIGN KEY (user_id) REFERENCES public.t_user(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: DATABASE aics_knowledge; Type: ACL; Schema: -; Owner: postgres
--
GRANT ALL ON DATABASE aics_knowledge TO aics_backend;
--
-- Name: TABLE comment; Type: ACL; Schema: public; Owner: postgres
--
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE public.comment TO aics_backend;
--
-- Name: TABLE knowledge; Type: ACL; Schema: public; Owner: postgres
--
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE public.knowledge TO aics_backend;
--
-- Name: TABLE knowledge_file_attribute; Type: ACL; Schema: public; Owner: postgres
--
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE public.knowledge_file_attribute TO aics_backend;
--
-- Name: TABLE knowledge_file_attribute_tag_mapping; Type: ACL; Schema: public; Owner: postgres
--
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE public.knowledge_file_attribute_tag_mapping TO aics_backend;
--
-- Name: TABLE note; Type: ACL; Schema: public; Owner: postgres
--
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE public.note TO aics_backend;
--
-- Name: TABLE notice; Type: ACL; Schema: public; Owner: postgres
--
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE public.notice TO aics_backend;
--
-- Name: TABLE t_user; Type: ACL; Schema: public; Owner: postgres
--
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE public.t_user TO aics_backend;
--
-- Name: SEQUENCE t_user_id_seq; Type: ACL; Schema: public; Owner: postgres
--
GRANT USAGE ON SEQUENCE public.t_user_id_seq TO aics_backend;
--
-- Name: TABLE tag; Type: ACL; Schema: public; Owner: postgres
--
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE public.tag TO aics_backend;
--
-- Name: SEQUENCE tag_id_seq; Type: ACL; Schema: public; Owner: postgres
--
GRANT USAGE ON SEQUENCE public.tag_id_seq TO aics_backend;
--
-- PostgreSQL database dump complete
--