From 694a615effa1cb50fa0abddf008db8cca75ec275 Mon Sep 17 00:00:00 2001 From: ChiveHao Date: Sun, 8 Dec 2024 14:27:50 +0800 Subject: [PATCH] feat: subject collection score and comment (#746) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * build: upgrade to v0.20.7 * feat: add column 'comment' and 'score' in table 'subject_collection' and add dml for flyway migration sql. * feat: add SubjectCollectionRepositoryTest * feat: 条目收藏分数后台接口 * build: gen new api-client v20.7.0 * optimize: 分数范围配置为0到10 * feat: console条目详情页SubjectDetails.vue完成条目收藏中评分和评论的对接 * docs: update CHANGELOG.MD * test: disable unit test in SubjectCollectionServiceTest --- CHANGELOG.MD | 6 + .../core/collection/SubjectCollection.java | 5 + .../ikaros/api/infra/utils/StringUtils.java | 11 ++ console/packages/api-client/README.md | 2 +- console/packages/api-client/package.json | 2 +- .../api/v1alpha1-collection-subject-api.ts | 36 ++++ .../src/api/v1alpha1-indices-api.ts | 26 +-- .../api-client/src/models/paging-wrap.ts | 8 +- .../src/models/subject-collection.ts | 12 ++ console/src/components/image/Cropperjs.vue | 2 +- .../src/components/image/CropperjsDialog.vue | 8 +- .../modules/content/subject/SubjectCard.vue | 4 +- .../content/subject/SubjectCollectDialog.vue | 51 ++++- .../upload/AttachmentPondUpload.vue | 8 +- console/src/components/upload/UppyUpload.vue | 16 +- console/src/components/video/Artplayer.vue | 12 +- console/src/layouts/BasicLayout.vue | 10 +- console/src/layouts/components/Wellcome.vue | 2 +- console/src/modules/common/constants.ts | 14 ++ .../attachment/AttachmentDeatilDrawer.vue | 32 ++-- .../AttachmentMultiSelectDialog.vue | 42 ++-- .../content/subject/EpisodeDetailsDialog.vue | 37 ++-- .../content/subject/EpisodePostDialog.vue | 33 ++-- .../content/subject/EpisodePutDialog.vue | 33 ++-- .../content/subject/SubjectDetails.vue | 179 +++++++++++------- .../modules/content/subject/SubjectPost.vue | 60 +++--- .../modules/content/subject/SubjectPut.vue | 67 ++++--- .../subject/SubjectRelactionDeleteDrawer.vue | 10 +- .../subject/SubjectRelationDeleteDialog.vue | 22 ++- .../content/subject/SubjectRelationDialog.vue | 28 ++- .../subject/SubjectRelationPostDialog.vue | 21 +- .../content/subject/SubjectSelectDrawer.vue | 32 ++-- .../content/subject/SubjectSyncDialog.vue | 49 ++--- .../src/modules/content/subject/Subjects.vue | 24 ++- console/src/modules/system/about/About.vue | 16 +- console/src/modules/system/about/module.ts | 6 +- .../modules/system/plugin/PluginDetail.vue | 19 +- .../modules/system/role/RoleAuthorities.vue | 34 ++-- console/src/modules/system/role/Roles.vue | 28 +-- console/src/modules/system/role/module.ts | 6 +- .../src/modules/system/setting/Setting.vue | 20 +- console/src/modules/system/task/module.ts | 6 +- console/src/modules/system/user/Users.vue | 40 ++-- console/src/modules/system/user/module.ts | 6 +- console/src/modules/user/Collection.vue | 19 +- console/src/modules/user/Profile.vue | 32 ++-- console/src/stores/user.ts | 10 +- console/src/utils/api-client.ts | 56 +++--- gradle.properties | 2 +- .../collection/SubjectCollectionEndpoint.java | 25 ++- .../collection/SubjectCollectionImpl.java | 29 +++ .../collection/SubjectCollectionService.java | 3 + .../store/entity/SubjectCollectionEntity.java | 7 + ....7_0001__DML_SUBJECT_COLLECTION_COLUMN.SQL | 5 + ....7_0001__DML_SUBJECT_COLLECTION_COLUMN.SQL | 5 + .../SubjectCollectionServiceTest.java | 18 +- .../SubjectCollectionRepositoryTest.java | 24 +++ 57 files changed, 853 insertions(+), 467 deletions(-) create mode 100644 server/src/main/resources/db/h2/migration/V0.20.7_0001__DML_SUBJECT_COLLECTION_COLUMN.SQL create mode 100644 server/src/main/resources/db/postgresql/migration/V0.20.7_0001__DML_SUBJECT_COLLECTION_COLUMN.SQL create mode 100644 server/src/test/java/run/ikaros/server/store/repository/SubjectCollectionRepositoryTest.java diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 64946fce7..9edf93288 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -2,6 +2,12 @@ 更新日志文档,版本顺序从新到旧,最新版本在最前(上)面。 +# 0.20.7 + +## 新特性 + +- 新增Console条目收藏的评分和评论支持 + # 0.20.6 ## 新特性 diff --git a/api/src/main/java/run/ikaros/api/core/collection/SubjectCollection.java b/api/src/main/java/run/ikaros/api/core/collection/SubjectCollection.java index e9c83421f..23bd521f1 100644 --- a/api/src/main/java/run/ikaros/api/core/collection/SubjectCollection.java +++ b/api/src/main/java/run/ikaros/api/core/collection/SubjectCollection.java @@ -51,4 +51,9 @@ public class SubjectCollection { private String cover; @JsonProperty("air_time") private LocalDateTime airTime; + private String comment; + /** + * Subject score, from 0 to 10. + */ + private Integer score; } diff --git a/api/src/main/java/run/ikaros/api/infra/utils/StringUtils.java b/api/src/main/java/run/ikaros/api/infra/utils/StringUtils.java index ea1a14283..700e60fa0 100644 --- a/api/src/main/java/run/ikaros/api/infra/utils/StringUtils.java +++ b/api/src/main/java/run/ikaros/api/infra/utils/StringUtils.java @@ -69,4 +69,15 @@ public static String generateRandomStr(int length) { return sb.toString(); } + /** + * 判断是否经过Base64编码. + * + * @param str 字符串 + * @return 是否 + */ + public static boolean isBase64Encoded(String str) { + // 判断字符串是否符合Base64编码规则 + String regex = "^[A-Za-z0-9+/=]+$"; + return str.matches(regex) && str.length() % 4 == 0; + } } diff --git a/console/packages/api-client/README.md b/console/packages/api-client/README.md index ea802b05d..25ad795d1 100644 --- a/console/packages/api-client/README.md +++ b/console/packages/api-client/README.md @@ -58,7 +58,7 @@ npm publish 选择当前目录下的更改进行`git add .` ```bash -git commit -am "build: gen new api-client v20.6.0" +git commit -am "build: gen new api-client v20.7.0" ``` 合成版(powershell),升级 package.json 版本,并启动服务端后,在 api-client 路径下: diff --git a/console/packages/api-client/package.json b/console/packages/api-client/package.json index 9db18d55c..742681ed8 100644 --- a/console/packages/api-client/package.json +++ b/console/packages/api-client/package.json @@ -1,6 +1,6 @@ { "name": "@runikaros/api-client", - "version": "20.6.0", + "version": "20.7.0", "description": "Project ikaros console api-client package", "type": "module", "scripts": { diff --git a/console/packages/api-client/src/api/v1alpha1-collection-subject-api.ts b/console/packages/api-client/src/api/v1alpha1-collection-subject-api.ts index 8501b1e61..d93aee60e 100644 --- a/console/packages/api-client/src/api/v1alpha1-collection-subject-api.ts +++ b/console/packages/api-client/src/api/v1alpha1-collection-subject-api.ts @@ -54,6 +54,8 @@ export const V1alpha1CollectionSubjectApiAxiosParamCreator = function ( * @param {number} subjectId Subject id. * @param {'WISH' | 'DOING' | 'DONE' | 'SHELVE' | 'DISCARD'} type Collection type. * @param {boolean} [isPrivate] Is private, default is false. + * @param {string} [comment] Subject comment, with base64 encoded. + * @param {number} [score] Subject score, from 0 to 100. * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -61,6 +63,8 @@ export const V1alpha1CollectionSubjectApiAxiosParamCreator = function ( subjectId: number, type: "WISH" | "DOING" | "DONE" | "SHELVE" | "DISCARD", isPrivate?: boolean, + comment?: string, + score?: number, options: AxiosRequestConfig = {} ): Promise => { // verify required parameter 'subjectId' is not null or undefined @@ -103,6 +107,14 @@ export const V1alpha1CollectionSubjectApiAxiosParamCreator = function ( localVarQueryParameter["isPrivate"] = isPrivate; } + if (comment !== undefined) { + localVarQueryParameter["comment"] = comment; + } + + if (score !== undefined) { + localVarQueryParameter["score"] = score; + } + setSearchParams(localVarUrlObj, localVarQueryParameter); let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; @@ -378,6 +390,8 @@ export const V1alpha1CollectionSubjectApiFp = function ( * @param {number} subjectId Subject id. * @param {'WISH' | 'DOING' | 'DONE' | 'SHELVE' | 'DISCARD'} type Collection type. * @param {boolean} [isPrivate] Is private, default is false. + * @param {string} [comment] Subject comment, with base64 encoded. + * @param {number} [score] Subject score, from 0 to 100. * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -385,6 +399,8 @@ export const V1alpha1CollectionSubjectApiFp = function ( subjectId: number, type: "WISH" | "DOING" | "DONE" | "SHELVE" | "DISCARD", isPrivate?: boolean, + comment?: string, + score?: number, options?: AxiosRequestConfig ): Promise< (axios?: AxiosInstance, basePath?: string) => AxiosPromise @@ -393,6 +409,8 @@ export const V1alpha1CollectionSubjectApiFp = function ( subjectId, type, isPrivate, + comment, + score, options ); return createRequestFunction( @@ -542,6 +560,8 @@ export const V1alpha1CollectionSubjectApiFactory = function ( requestParameters.subjectId, requestParameters.type, requestParameters.isPrivate, + requestParameters.comment, + requestParameters.score, options ) .then((request) => request(axios, basePath)); @@ -641,6 +661,20 @@ export interface V1alpha1CollectionSubjectApiCollectSubjectRequest { * @memberof V1alpha1CollectionSubjectApiCollectSubject */ readonly isPrivate?: boolean; + + /** + * Subject comment, with base64 encoded. + * @type {string} + * @memberof V1alpha1CollectionSubjectApiCollectSubject + */ + readonly comment?: string; + + /** + * Subject score, from 0 to 100. + * @type {number} + * @memberof V1alpha1CollectionSubjectApiCollectSubject + */ + readonly score?: number; } /** @@ -750,6 +784,8 @@ export class V1alpha1CollectionSubjectApi extends BaseAPI { requestParameters.subjectId, requestParameters.type, requestParameters.isPrivate, + requestParameters.comment, + requestParameters.score, options ) .then((request) => request(this.axios, this.basePath)); diff --git a/console/packages/api-client/src/api/v1alpha1-indices-api.ts b/console/packages/api-client/src/api/v1alpha1-indices-api.ts index ae459a164..c22b83483 100644 --- a/console/packages/api-client/src/api/v1alpha1-indices-api.ts +++ b/console/packages/api-client/src/api/v1alpha1-indices-api.ts @@ -97,16 +97,16 @@ export const V1alpha1IndicesApiAxiosParamCreator = function ( * Search subjects with fuzzy query * @param {string} keyword * @param {number} [limit] - * @param {string} [highlightPreTag] * @param {string} [highlightPostTag] + * @param {string} [highlightPreTag] * @param {*} [options] Override http request option. * @throws {RequiredError} */ searchSubject: async ( keyword: string, limit?: number, - highlightPreTag?: string, highlightPostTag?: string, + highlightPreTag?: string, options: AxiosRequestConfig = {} ): Promise => { // verify required parameter 'keyword' is not null or undefined @@ -139,16 +139,16 @@ export const V1alpha1IndicesApiAxiosParamCreator = function ( localVarQueryParameter["limit"] = limit; } - if (keyword !== undefined) { - localVarQueryParameter["keyword"] = keyword; + if (highlightPostTag !== undefined) { + localVarQueryParameter["highlightPostTag"] = highlightPostTag; } if (highlightPreTag !== undefined) { localVarQueryParameter["highlightPreTag"] = highlightPreTag; } - if (highlightPostTag !== undefined) { - localVarQueryParameter["highlightPostTag"] = highlightPostTag; + if (keyword !== undefined) { + localVarQueryParameter["keyword"] = keyword; } setSearchParams(localVarUrlObj, localVarQueryParameter); @@ -199,16 +199,16 @@ export const V1alpha1IndicesApiFp = function (configuration?: Configuration) { * Search subjects with fuzzy query * @param {string} keyword * @param {number} [limit] - * @param {string} [highlightPreTag] * @param {string} [highlightPostTag] + * @param {string} [highlightPreTag] * @param {*} [options] Override http request option. * @throws {RequiredError} */ async searchSubject( keyword: string, limit?: number, - highlightPreTag?: string, highlightPostTag?: string, + highlightPreTag?: string, options?: AxiosRequestConfig ): Promise< (axios?: AxiosInstance, basePath?: string) => AxiosPromise @@ -216,8 +216,8 @@ export const V1alpha1IndicesApiFp = function (configuration?: Configuration) { const localVarAxiosArgs = await localVarAxiosParamCreator.searchSubject( keyword, limit, - highlightPreTag, highlightPostTag, + highlightPreTag, options ); return createRequestFunction( @@ -265,8 +265,8 @@ export const V1alpha1IndicesApiFactory = function ( .searchSubject( requestParameters.keyword, requestParameters.limit, - requestParameters.highlightPreTag, requestParameters.highlightPostTag, + requestParameters.highlightPreTag, options ) .then((request) => request(axios, basePath)); @@ -299,14 +299,14 @@ export interface V1alpha1IndicesApiSearchSubjectRequest { * @type {string} * @memberof V1alpha1IndicesApiSearchSubject */ - readonly highlightPreTag?: string; + readonly highlightPostTag?: string; /** * * @type {string} * @memberof V1alpha1IndicesApiSearchSubject */ - readonly highlightPostTag?: string; + readonly highlightPreTag?: string; } /** @@ -343,8 +343,8 @@ export class V1alpha1IndicesApi extends BaseAPI { .searchSubject( requestParameters.keyword, requestParameters.limit, - requestParameters.highlightPreTag, requestParameters.highlightPostTag, + requestParameters.highlightPreTag, options ) .then((request) => request(this.axios, this.basePath)); diff --git a/console/packages/api-client/src/models/paging-wrap.ts b/console/packages/api-client/src/models/paging-wrap.ts index df967c879..26cd71fd5 100644 --- a/console/packages/api-client/src/models/paging-wrap.ts +++ b/console/packages/api-client/src/models/paging-wrap.ts @@ -43,17 +43,17 @@ export interface PagingWrap { */ items: Array; /** - * Indicates whether current page is the last page. + * Indicates whether current page is the first page. * @type {boolean} * @memberof PagingWrap */ - lastPage: boolean; + firstPage: boolean; /** - * Indicates whether current page is the first page. + * Indicates whether current page is the last page. * @type {boolean} * @memberof PagingWrap */ - firstPage: boolean; + lastPage: boolean; /** * Indicates whether current page has previous page. * @type {boolean} diff --git a/console/packages/api-client/src/models/subject-collection.ts b/console/packages/api-client/src/models/subject-collection.ts index 52f773a94..e086768ab 100644 --- a/console/packages/api-client/src/models/subject-collection.ts +++ b/console/packages/api-client/src/models/subject-collection.ts @@ -60,6 +60,18 @@ export interface SubjectCollection { * @memberof SubjectCollection */ cover?: string; + /** + * + * @type {string} + * @memberof SubjectCollection + */ + comment?: string; + /** + * + * @type {number} + * @memberof SubjectCollection + */ + score?: number; /** * * @type {number} diff --git a/console/src/components/image/Cropperjs.vue b/console/src/components/image/Cropperjs.vue index a404891d7..e8204deee 100644 --- a/console/src/components/image/Cropperjs.vue +++ b/console/src/components/image/Cropperjs.vue @@ -1,7 +1,7 @@ diff --git a/console/src/modules/common/constants.ts b/console/src/modules/common/constants.ts index 2a1aaf292..f78a40e3f 100644 --- a/console/src/modules/common/constants.ts +++ b/console/src/modules/common/constants.ts @@ -114,3 +114,17 @@ export const subjectRelationTypes = [ 'ORIGINAL_VIDEO_ANIMATION', 'ORIGINAL_ANIMATION_DISC', ]; + +export const scoreColors = ['#99A9BF', '#F7BA2A', '#FF9900']; +export const scoreTexts = [ + '不忍直视 1 (请谨慎评价)', + '很差 2', + '差 3', + '较差 4', + '不过不失 5', + '还行 6', + '推荐 7', + '力荐 8', + '神作 9', + '超神作 10 (请谨慎评价)', +]; diff --git a/console/src/modules/content/attachment/AttachmentDeatilDrawer.vue b/console/src/modules/content/attachment/AttachmentDeatilDrawer.vue index 3d1ad161e..468c4de7d 100644 --- a/console/src/modules/content/attachment/AttachmentDeatilDrawer.vue +++ b/console/src/modules/content/attachment/AttachmentDeatilDrawer.vue @@ -1,22 +1,22 @@