From 1295b09ecb5fed16a6fba43204adbf9e4c71588b Mon Sep 17 00:00:00 2001 From: shuai Date: Tue, 18 Nov 2025 10:55:11 +0800 Subject: [PATCH 01/29] fix: fix the issue where the comment_id parameter is forcibly converted to a string, causing a 500 error in the PostgreSQL database interface. #1426 --- ui/src/components/Comment/index.tsx | 2 +- ui/src/pages/Questions/Detail/components/Answer/index.tsx | 2 +- ui/src/pages/Questions/Detail/components/Question/index.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/src/components/Comment/index.tsx b/ui/src/components/Comment/index.tsx index ec42c562f..af2ddbd4f 100644 --- a/ui/src/components/Comment/index.tsx +++ b/ui/src/components/Comment/index.tsx @@ -53,7 +53,7 @@ import './index.scss'; interface IProps { objectId: string; mode?: 'answer' | 'question'; - commentId?: string; + commentId?: string | null; children?: React.ReactNode; } diff --git a/ui/src/pages/Questions/Detail/components/Answer/index.tsx b/ui/src/pages/Questions/Detail/components/Answer/index.tsx index 957a60df0..bd0ecbb5b 100644 --- a/ui/src/pages/Questions/Detail/components/Answer/index.tsx +++ b/ui/src/pages/Questions/Detail/components/Answer/index.tsx @@ -169,7 +169,7 @@ const Index: FC = ({ + commentId={searchParams.get('commentId')}> = ({ data, initPage, hasAnswer, isLogged }) => { + commentId={searchParams.get('commentId')}> Date: Tue, 18 Nov 2025 11:12:12 +0800 Subject: [PATCH 02/29] fix: Optimization of request parameters --- ui/src/pages/Admin/Badges/index.tsx | 2 +- ui/src/services/admin/badges.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/src/pages/Admin/Badges/index.tsx b/ui/src/pages/Admin/Badges/index.tsx index 9b99f8eb2..50396cd42 100644 --- a/ui/src/pages/Admin/Badges/index.tsx +++ b/ui/src/pages/Admin/Badges/index.tsx @@ -52,7 +52,7 @@ const Badges: FC = () => { const { data, isLoading, mutate } = useQueryBadges({ page: curPage, page_size: PAGE_SIZE, - q: curQuery, + ...(curQuery ? { q: curQuery } : {}), ...(curFilter === 'all' ? {} : { status: curFilter }), }); diff --git a/ui/src/services/admin/badges.ts b/ui/src/services/admin/badges.ts index 64685bc5e..69ea34036 100644 --- a/ui/src/services/admin/badges.ts +++ b/ui/src/services/admin/badges.ts @@ -24,7 +24,7 @@ import request from '@/utils/request'; import type * as Type from '@/common/interface'; export const useQueryBadges = (params) => { - const apiUrl = `/answer/admin/api/badges?${qs.stringify(params)}`; + const apiUrl = `/answer/admin/api/badges?${qs.stringify(params, { skipNulls: true })}`; const { data, error, mutate } = useSWR< Type.ListResult, Error From 666ab706a66f7c39c8bb758c0abc2c08c15d4967 Mon Sep 17 00:00:00 2001 From: Dinesht04 Date: Thu, 13 Nov 2025 02:22:58 +0530 Subject: [PATCH 03/29] feat(ui): add min values for inputs and context-based keyboards for inputs --- ui/src/components/SchemaForm/components/Input.tsx | 15 +++++++++++++++ ui/src/components/SchemaForm/index.tsx | 3 +++ ui/src/components/SchemaForm/types.ts | 10 ++++++++++ ui/src/pages/Admin/Privileges/index.tsx | 2 ++ ui/src/pages/Admin/Write/index.tsx | 10 ++++++++++ 5 files changed, 40 insertions(+) diff --git a/ui/src/components/SchemaForm/components/Input.tsx b/ui/src/components/SchemaForm/components/Input.tsx index 1a3fe319b..c0fd084ca 100644 --- a/ui/src/components/SchemaForm/components/Input.tsx +++ b/ui/src/components/SchemaForm/components/Input.tsx @@ -29,6 +29,17 @@ interface Props { onChange?: (fd: Type.FormDataType) => void; formData: Type.FormDataType; readOnly: boolean; + minValue?: number; + inputMode?: + | 'text' + | 'search' + | 'none' + | 'tel' + | 'url' + | 'email' + | 'numeric' + | 'decimal' + | undefined; } const Index: FC = ({ type = 'text', @@ -37,6 +48,8 @@ const Index: FC = ({ onChange, formData, readOnly = false, + minValue = 0, + inputMode = 'text', }) => { const fieldObject = formData[fieldName]; const handleChange = (evt: React.ChangeEvent) => { @@ -60,6 +73,8 @@ const Index: FC = ({ placeholder={placeholder} type={type} value={fieldObject?.value || ''} + min={minValue} + inputMode={inputMode} onChange={handleChange} disabled={readOnly} isInvalid={fieldObject?.isInvalid} diff --git a/ui/src/components/SchemaForm/index.tsx b/ui/src/components/SchemaForm/index.tsx index 421e0b1e1..23b193b48 100644 --- a/ui/src/components/SchemaForm/index.tsx +++ b/ui/src/components/SchemaForm/index.tsx @@ -368,6 +368,9 @@ const SchemaForm: ForwardRefRenderFunction = ( {widget === 'input' ? ( { } return true; }, + inputType: 'number', + inputMode: 'numeric', }, }; }); diff --git a/ui/src/pages/Admin/Write/index.tsx b/ui/src/pages/Admin/Write/index.tsx index 86d44d6d9..fee2d28cc 100644 --- a/ui/src/pages/Admin/Write/index.tsx +++ b/ui/src/pages/Admin/Write/index.tsx @@ -261,6 +261,8 @@ const Index: FC = () => { {t('min_tags.label')} { @@ -302,6 +304,8 @@ const Index: FC = () => { {t('min_content.label')} { @@ -344,6 +348,8 @@ const Index: FC = () => { {t('image_size.label')} { @@ -366,6 +372,8 @@ const Index: FC = () => { {t('attachment_size.label')} { @@ -388,6 +396,8 @@ const Index: FC = () => { {t('image_megapixels.label')} { From 157dbfd08a1474534fe3548ef02243bf421ba020 Mon Sep 17 00:00:00 2001 From: Dinesht04 Date: Fri, 14 Nov 2025 02:28:46 +0530 Subject: [PATCH 04/29] feat(ui): add types, logic and defaults for min, max value of input component of form --- ui/src/components/SchemaForm/components/Input.tsx | 9 ++++++--- ui/src/components/SchemaForm/index.tsx | 9 +++++++++ ui/src/components/SchemaForm/types.ts | 2 ++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/ui/src/components/SchemaForm/components/Input.tsx b/ui/src/components/SchemaForm/components/Input.tsx index c0fd084ca..3a2c0397d 100644 --- a/ui/src/components/SchemaForm/components/Input.tsx +++ b/ui/src/components/SchemaForm/components/Input.tsx @@ -29,7 +29,8 @@ interface Props { onChange?: (fd: Type.FormDataType) => void; formData: Type.FormDataType; readOnly: boolean; - minValue?: number; + min?: number; + max?: number; inputMode?: | 'text' | 'search' @@ -48,7 +49,8 @@ const Index: FC = ({ onChange, formData, readOnly = false, - minValue = 0, + min = 0, + max = 65355, inputMode = 'text', }) => { const fieldObject = formData[fieldName]; @@ -73,7 +75,8 @@ const Index: FC = ({ placeholder={placeholder} type={type} value={fieldObject?.value || ''} - min={minValue} + min={min} + max={max} inputMode={inputMode} onChange={handleChange} disabled={readOnly} diff --git a/ui/src/components/SchemaForm/index.tsx b/ui/src/components/SchemaForm/index.tsx index 23b193b48..5bde2fdc8 100644 --- a/ui/src/components/SchemaForm/index.tsx +++ b/ui/src/components/SchemaForm/index.tsx @@ -260,6 +260,8 @@ const SchemaForm: ForwardRefRenderFunction = ( enum: enumValues = [], enumNames = [], max_length = 0, + max = 65355, + min = 0, } = properties[key]; const { 'ui:widget': widget = 'input', 'ui:options': uiOpt } = uiSchema?.[key] || {}; @@ -374,6 +376,8 @@ const SchemaForm: ForwardRefRenderFunction = ( placeholder={ uiOpt && 'placeholder' in uiOpt ? uiOpt.placeholder : '' } + min={min} + max={max} fieldName={key} onChange={onChange} formData={formData} @@ -408,9 +412,14 @@ const SchemaForm: ForwardRefRenderFunction = ( type={ uiOpt && 'inputType' in uiOpt ? uiOpt.inputType : 'text' } + inputMode={ + uiOpt && 'inputMode' in uiOpt ? uiOpt.inputMode : 'text' + } placeholder={ uiOpt && 'placeholder' in uiOpt ? uiOpt.placeholder : '' } + min={min} + max={max} fieldName={key} onChange={onChange} formData={formData} diff --git a/ui/src/components/SchemaForm/types.ts b/ui/src/components/SchemaForm/types.ts index eaedf902a..55cf8e99d 100644 --- a/ui/src/components/SchemaForm/types.ts +++ b/ui/src/components/SchemaForm/types.ts @@ -49,6 +49,8 @@ export interface JSONSchema { description?: string; enum?: Array; enumNames?: string[]; + min?: number; + max?: number; default?: string | boolean | number | any[]; max_length?: number; }; From 54e602c5e6ad9a8c49187eadc4d480fbd7892a97 Mon Sep 17 00:00:00 2001 From: Dinesht04 Date: Wed, 19 Nov 2025 15:28:58 +0530 Subject: [PATCH 05/29] fix(ui): refactor number input props (min,max) --- ui/src/components/SchemaForm/components/Input.tsx | 9 ++++++--- ui/src/components/SchemaForm/index.tsx | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ui/src/components/SchemaForm/components/Input.tsx b/ui/src/components/SchemaForm/components/Input.tsx index 3a2c0397d..d84d7d55a 100644 --- a/ui/src/components/SchemaForm/components/Input.tsx +++ b/ui/src/components/SchemaForm/components/Input.tsx @@ -50,10 +50,14 @@ const Index: FC = ({ formData, readOnly = false, min = 0, - max = 65355, + max, inputMode = 'text', }) => { const fieldObject = formData[fieldName]; + const numberInputProps = + type === 'number' + ? { min, ...(max != null && max > 0 ? { max } : {}) } + : {}; const handleChange = (evt: React.ChangeEvent) => { const { name, value } = evt.currentTarget; const state = { @@ -75,8 +79,7 @@ const Index: FC = ({ placeholder={placeholder} type={type} value={fieldObject?.value || ''} - min={min} - max={max} + {...numberInputProps} inputMode={inputMode} onChange={handleChange} disabled={readOnly} diff --git a/ui/src/components/SchemaForm/index.tsx b/ui/src/components/SchemaForm/index.tsx index 5bde2fdc8..171b5f675 100644 --- a/ui/src/components/SchemaForm/index.tsx +++ b/ui/src/components/SchemaForm/index.tsx @@ -260,7 +260,7 @@ const SchemaForm: ForwardRefRenderFunction = ( enum: enumValues = [], enumNames = [], max_length = 0, - max = 65355, + max, min = 0, } = properties[key]; const { 'ui:widget': widget = 'input', 'ui:options': uiOpt } = From 9a7eb0f450d31042c8badf080354754a8704e429 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Thu, 20 Nov 2025 17:42:35 +0800 Subject: [PATCH 06/29] fix(service): set default language to "en_US" if invalid language is provided --- internal/service/siteinfo/siteinfo_service.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go index a0f4891c4..92b3e0c71 100644 --- a/internal/service/siteinfo/siteinfo_service.go +++ b/internal/service/siteinfo/siteinfo_service.go @@ -40,7 +40,6 @@ import ( tagcommon "github.com/apache/answer/internal/service/tag_common" "github.com/apache/answer/plugin" "github.com/jinzhu/copier" - "github.com/segmentfault/pacman/errors" "github.com/segmentfault/pacman/log" ) @@ -159,10 +158,9 @@ func (s *SiteInfoService) SaveSiteGeneral(ctx context.Context, req schema.SiteGe } func (s *SiteInfoService) SaveSiteInterface(ctx context.Context, req schema.SiteInterfaceReq) (err error) { - // check language + // If the language is invalid, set it to the default language "en_US" if !translator.CheckLanguageIsValid(req.Language) { - err = errors.BadRequest(reason.LangNotFound) - return + req.Language = "en_US" } content, _ := json.Marshal(req) From 09b6b34b0540b1aa6f344b20df8507f56e6fb406 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Thu, 20 Nov 2025 17:50:57 +0800 Subject: [PATCH 07/29] fix(comment): decode CommentID using DeShortID for consistency --- internal/controller/comment_controller.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/controller/comment_controller.go b/internal/controller/comment_controller.go index 5b807d935..65fbedf04 100644 --- a/internal/controller/comment_controller.go +++ b/internal/controller/comment_controller.go @@ -246,6 +246,7 @@ func (cc *CommentController) GetCommentWithPage(ctx *gin.Context) { return } req.ObjectID = uid.DeShortID(req.ObjectID) + req.CommentID = uid.DeShortID(req.CommentID) req.UserID = middleware.GetLoginUserIDFromContext(ctx) canList, err := cc.rankService.CheckOperationPermissions(ctx, req.UserID, []string{ permission.CommentEdit, From a15dd41550c282a4de44259c69a57dd52eeb0e9c Mon Sep 17 00:00:00 2001 From: ferhat elmas Date: Sat, 22 Nov 2025 12:43:55 +0100 Subject: [PATCH 08/29] refactor(internal): compile regex once while clearing text Regex and Replacer can be reused. No need to recreate for each invocation. Signed-off-by: ferhat elmas --- pkg/htmltext/htmltext.go | 48 ++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/pkg/htmltext/htmltext.go b/pkg/htmltext/htmltext.go index 49049109d..0b84cda49 100644 --- a/pkg/htmltext/htmltext.go +++ b/pkg/htmltext/htmltext.go @@ -34,38 +34,34 @@ import ( "github.com/mozillazg/go-pinyin" ) +var ( + reCode = regexp.MustCompile(`(?ism)<(pre)>.*<\/pre>`) + reCodeReplace = "{code...}" + reLink = regexp.MustCompile(`(?ism)(.*)?<\/a>`) + reLinkReplace = " [$1] " + reSpace = regexp.MustCompile(` +`) + reSpaceReplace = " " + + spaceReplacer = strings.NewReplacer( + "\n", " ", + "\r", " ", + "\t", " ", + ) +) + // ClearText clear HTML, get the clear text -func ClearText(html string) (text string) { - if len(html) == 0 { - text = html - return +func ClearText(html string) string { + if html == "" { + return html } - var ( - re *regexp.Regexp - codeReg = `(?ism)<(pre)>.*<\/pre>` - codeRepl = "{code...}" - linkReg = `(?ism)(.*)?<\/a>` - linkRepl = " [$1] " - spaceReg = ` +` - spaceRepl = " " - ) - re = regexp.MustCompile(codeReg) - html = re.ReplaceAllString(html, codeRepl) + html = reCode.ReplaceAllString(html, reCodeReplace) + html = reLink.ReplaceAllString(html, reLinkReplace) - re = regexp.MustCompile(linkReg) - html = re.ReplaceAllString(html, linkRepl) - - text = strings.NewReplacer( - "\n", " ", - "\r", " ", - "\t", " ", - ).Replace(strip.StripTags(html)) + text := spaceReplacer.Replace(strip.StripTags(html)) // replace multiple spaces to one space - re = regexp.MustCompile(spaceReg) - text = strings.TrimSpace(re.ReplaceAllString(text, spaceRepl)) - return + return strings.TrimSpace(reSpace.ReplaceAllString(text, reSpaceReplace)) } func UrlTitle(title string) (text string) { From ce053ccfa6620cc4c8263ba3b54dfcd988a1e6e9 Mon Sep 17 00:00:00 2001 From: ferhat elmas Date: Tue, 25 Nov 2025 00:34:24 +0100 Subject: [PATCH 09/29] fix: multi byte run boundary for cut long title Signed-off-by: ferhat elmas --- pkg/htmltext/htmltext.go | 12 +++++++++--- pkg/htmltext/htmltext_test.go | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/pkg/htmltext/htmltext.go b/pkg/htmltext/htmltext.go index 0b84cda49..707c20a80 100644 --- a/pkg/htmltext/htmltext.go +++ b/pkg/htmltext/htmltext.go @@ -96,10 +96,16 @@ func convertChinese(content string) string { } func cutLongTitle(title string) string { - if len(title) > 150 { - return title[0:150] + maxBytes := 150 + if len(title) <= maxBytes { + return title } - return title + + truncated := title[:maxBytes] + for len(truncated) > 0 && !utf8.ValidString(truncated) { + truncated = truncated[:len(truncated)-1] + } + return truncated } // FetchExcerpt return the excerpt from the HTML string diff --git a/pkg/htmltext/htmltext_test.go b/pkg/htmltext/htmltext_test.go index d549d8874..63866eb28 100644 --- a/pkg/htmltext/htmltext_test.go +++ b/pkg/htmltext/htmltext_test.go @@ -21,6 +21,7 @@ package htmltext import ( "fmt" + "strings" "testing" "github.com/stretchr/testify/assert" @@ -178,6 +179,27 @@ func TestFetchRangedExcerpt(t *testing.T) { assert.Equal(t, expected, actual) } +func TestCutLongTitle(t *testing.T) { + // Short title, no cutting needed + short := "hello" + assert.Equal(t, short, cutLongTitle(short)) + + // Exactly max bytes, no cutting needed + exact150 := strings.Repeat("a", 150) + assert.Equal(t, 150, len(cutLongTitle(exact150))) + + // Just over max bytes, should be cut + exact151 := strings.Repeat("a", 151) + assert.Equal(t, 150, len(cutLongTitle(exact151))) + + // Multi-byte rune at boundary gets removed properly + asciiPart := strings.Repeat("a", 149) // 149 bytes + multiByteChar := "中" // 3 bytes - will span bytes 149-151 + title := asciiPart + multiByteChar // 152 bytes total + + assert.Equal(t, asciiPart, cutLongTitle(title)) +} + func TestFetchMatchedExcerpt(t *testing.T) { var ( expected, From 0777291e80c804cb836b5059d7e0fad5f2b7fe79 Mon Sep 17 00:00:00 2001 From: ferhat elmas Date: Wed, 26 Nov 2025 01:00:42 +0100 Subject: [PATCH 10/29] fix(ui): null pointer access if get branding fails Signed-off-by: ferhat elmas --- internal/router/ui.go | 6 ++-- internal/router/ui_test.go | 59 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 internal/router/ui_test.go diff --git a/internal/router/ui.go b/internal/router/ui.go index 0b5ee3f96..14f71f5fc 100644 --- a/internal/router/ui.go +++ b/internal/router/ui.go @@ -22,7 +22,6 @@ package router import ( "embed" "fmt" - "github.com/apache/answer/plugin" "io/fs" "net/http" "os" @@ -31,6 +30,7 @@ import ( "github.com/apache/answer/internal/controller" "github.com/apache/answer/internal/service/siteinfo_common" "github.com/apache/answer/pkg/htmltext" + "github.com/apache/answer/plugin" "github.com/apache/answer/ui" "github.com/gin-gonic/gin" "github.com/segmentfault/pacman/log" @@ -111,10 +111,10 @@ func (a *UIRouter) Register(r *gin.Engine, baseURLPath string) { if err != nil { log.Error(err) } - if branding.Favicon != "" { + if branding != nil && branding.Favicon != "" { c.String(http.StatusOK, htmltext.GetPicByUrl(branding.Favicon)) return - } else if branding.SquareIcon != "" { + } else if branding != nil && branding.SquareIcon != "" { c.String(http.StatusOK, htmltext.GetPicByUrl(branding.SquareIcon)) return } else { diff --git a/internal/router/ui_test.go b/internal/router/ui_test.go new file mode 100644 index 000000000..645529338 --- /dev/null +++ b/internal/router/ui_test.go @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package router + +import ( + "errors" + "net/http" + "net/http/httptest" + "testing" + + "github.com/apache/answer/internal/service/mock" + "github.com/gin-gonic/gin" + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" +) + +func TestUIRouter_FaviconWithNilBranding(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockSiteInfoService := mock.NewMockSiteInfoCommonService(ctrl) + + // Simulate a database error + mockSiteInfoService.EXPECT(). + GetSiteBranding(gomock.Any()). + Return(nil, errors.New("database connection failed")) + + router := &UIRouter{ + siteInfoService: mockSiteInfoService, + } + + gin.SetMode(gin.TestMode) + r := gin.New() + router.Register(r, "") + + req := httptest.NewRequest(http.MethodGet, "/favicon.ico", nil) + w := httptest.NewRecorder() + + r.ServeHTTP(w, req) + + assert.Equal(t, http.StatusOK, w.Code) +} From da27577d9c7d0c72dd2c565770931fa2150ed0ad Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Fri, 28 Nov 2025 10:49:10 +0800 Subject: [PATCH 11/29] fix(answer): update QuestionID handling in answer update process --- internal/controller/answer_controller.go | 1 - internal/schema/answer_schema.go | 1 - internal/service/content/answer_service.go | 19 +++++++++---------- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/internal/controller/answer_controller.go b/internal/controller/answer_controller.go index 7c5aca1db..0e43121c5 100644 --- a/internal/controller/answer_controller.go +++ b/internal/controller/answer_controller.go @@ -318,7 +318,6 @@ func (ac *AnswerController) UpdateAnswer(ctx *gin.Context) { handler.HandleResponse(ctx, err, nil) return } - req.QuestionID = uid.DeShortID(req.QuestionID) linkUrlLimitUser := canList[2] isAdmin := middleware.GetUserIsAdminModerator(ctx) if !isAdmin || !linkUrlLimitUser { diff --git a/internal/schema/answer_schema.go b/internal/schema/answer_schema.go index 015e26ac5..9ac4bcad7 100644 --- a/internal/schema/answer_schema.go +++ b/internal/schema/answer_schema.go @@ -78,7 +78,6 @@ type GetAnswerInfoResp struct { type AnswerUpdateReq struct { ID string `json:"id"` - QuestionID string `json:"question_id"` Title string `json:"title"` Content string `validate:"required,notblank,gte=6,lte=65535" json:"content"` EditSummary string `validate:"omitempty" json:"edit_summary"` diff --git a/internal/service/content/answer_service.go b/internal/service/content/answer_service.go index b9d45b522..982bbf88a 100644 --- a/internal/service/content/answer_service.go +++ b/internal/service/content/answer_service.go @@ -346,24 +346,23 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq return "", errors.BadRequest(reason.AnswerCannotUpdate) } - questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, req.QuestionID) + answerInfo, exist, err := as.answerRepo.GetByID(ctx, req.ID) if err != nil { return "", err } if !exist { - return "", errors.BadRequest(reason.QuestionNotFound) + return "", errors.BadRequest(reason.AnswerNotFound) + } + if answerInfo.Status == entity.AnswerStatusDeleted { + return "", errors.BadRequest(reason.AnswerCannotUpdate) } - answerInfo, exist, err := as.answerRepo.GetByID(ctx, req.ID) + questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, answerInfo.QuestionID) if err != nil { return "", err } if !exist { - return "", errors.BadRequest(reason.AnswerNotFound) - } - - if answerInfo.Status == entity.AnswerStatusDeleted { - return "", errors.BadRequest(reason.AnswerCannotUpdate) + return "", errors.BadRequest(reason.QuestionNotFound) } //If the content is the same, ignore it @@ -374,7 +373,7 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq insertData := &entity.Answer{} insertData.ID = req.ID insertData.UserID = answerInfo.UserID - insertData.QuestionID = req.QuestionID + insertData.QuestionID = questionInfo.ID insertData.OriginalText = req.Content insertData.ParsedText = req.HTML insertData.UpdatedAt = time.Now() @@ -403,7 +402,7 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq if err = as.answerRepo.UpdateAnswer(ctx, insertData, []string{"original_text", "parsed_text", "updated_at", "last_edit_user_id"}); err != nil { return "", err } - err = as.questionCommon.UpdatePostTime(ctx, req.QuestionID) + err = as.questionCommon.UpdatePostTime(ctx, questionInfo.ID) if err != nil { return insertData.ID, err } From bc629db13266dfcd9560da38b39d71a615a1664f Mon Sep 17 00:00:00 2001 From: ferhat elmas Date: Thu, 27 Nov 2025 22:05:14 +0100 Subject: [PATCH 12/29] chore(deps): bump mockgen to 0.6.0 for go1.25 support Signed-off-by: ferhat elmas --- Makefile | 4 ++-- README.md | 2 +- cmd/wire_gen.go | 8 ++++---- docs/docs.go | 32 +++++++++++++++++++++++--------- docs/swagger.json | 32 +++++++++++++++++++++++--------- docs/swagger.yaml | 28 +++++++++++++++++++--------- go.mod | 14 +++++++------- go.sum | 36 ++++++++++++++++++------------------ 8 files changed, 97 insertions(+), 59 deletions(-) diff --git a/Makefile b/Makefile index 6e9679a89..8ab23cce3 100644 --- a/Makefile +++ b/Makefile @@ -23,10 +23,10 @@ universal: generate generate: @$(GO) get github.com/swaggo/swag/cmd/swag@v1.16.3 @$(GO) get github.com/google/wire/cmd/wire@v0.5.0 - @$(GO) get go.uber.org/mock/mockgen@v0.5.0 + @$(GO) get go.uber.org/mock/mockgen@v0.6.0 @$(GO) install github.com/swaggo/swag/cmd/swag@v1.16.3 @$(GO) install github.com/google/wire/cmd/wire@v0.5.0 - @$(GO) install go.uber.org/mock/mockgen@v0.5.0 + @$(GO) install go.uber.org/mock/mockgen@v0.6.0 @$(GO) generate ./... @$(GO) mod tidy diff --git a/README.md b/README.md index 8d201500e..362365496 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ You can also check out the [plugins here](https://answer.apache.org/plugins). - Golang >= 1.23 - Node.js >= 20 - pnpm >= 9 -- [mockgen](https://github.com/uber-go/mock?tab=readme-ov-file#installation) >= 1.6.0 +- [mockgen](https://github.com/uber-go/mock?tab=readme-ov-file#installation) >= 0.6.0 - [wire](https://github.com/google/wire/) >= 0.5.0 ### Build diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go index bda555bca..aae1c6af6 100644 --- a/cmd/wire_gen.go +++ b/cmd/wire_gen.go @@ -192,22 +192,22 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, objService := object_info.NewObjService(answerRepo, questionRepo, commentCommonRepo, tagCommonRepo, tagCommonService) notificationQueueService := notice_queue.NewNotificationQueueService() externalNotificationQueueService := notice_queue.NewNewQuestionNotificationQueueService() + reviewRepo := review.NewReviewRepo(dataData) + reviewService := review2.NewReviewService(reviewRepo, objService, userCommon, userRepo, questionRepo, answerRepo, userRoleRelService, externalNotificationQueueService, tagCommonService, questionCommon, notificationQueueService, siteInfoCommonService, commentCommonRepo) + commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, notificationQueueService, externalNotificationQueueService, activityQueueService, eventQueueService, reviewService) rolePowerRelRepo := role.NewRolePowerRelRepo(dataData) rolePowerRelService := role2.NewRolePowerRelService(rolePowerRelRepo, userRoleRelService) rankService := rank2.NewRankService(userCommon, userRankRepo, objService, userRoleRelService, rolePowerRelService, configService) limitRepo := limit.NewRateLimitRepo(dataData) rateLimitMiddleware := middleware.NewRateLimitMiddleware(limitRepo) + commentController := controller.NewCommentController(commentService, rankService, captchaService, rateLimitMiddleware) reportRepo := report.NewReportRepo(dataData, uniqueIDRepo) tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService, activityQueueService) answerActivityRepo := activity.NewAnswerActivityRepo(dataData, activityRepo, userRankRepo, notificationQueueService) answerActivityService := activity2.NewAnswerActivityService(answerActivityRepo, configService) externalNotificationService := notification.NewExternalNotificationService(dataData, userNotificationConfigRepo, followRepo, emailService, userRepo, externalNotificationQueueService, userExternalLoginRepo, siteInfoCommonService) - reviewRepo := review.NewReviewRepo(dataData) - reviewService := review2.NewReviewService(reviewRepo, objService, userCommon, userRepo, questionRepo, answerRepo, userRoleRelService, externalNotificationQueueService, tagCommonService, questionCommon, notificationQueueService, siteInfoCommonService, commentCommonRepo) questionService := content.NewQuestionService(activityRepo, questionRepo, answerRepo, tagCommonService, tagService, questionCommon, userCommon, userRepo, userRoleRelService, revisionService, metaCommonService, collectionCommon, answerActivityService, emailService, notificationQueueService, externalNotificationQueueService, activityQueueService, siteInfoCommonService, externalNotificationService, reviewService, configService, eventQueueService, reviewRepo) answerService := content.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, notificationQueueService, externalNotificationQueueService, activityQueueService, reviewService, eventQueueService) - commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, notificationQueueService, externalNotificationQueueService, activityQueueService, eventQueueService, reviewService) - commentController := controller.NewCommentController(commentService, rankService, captchaService, rateLimitMiddleware) reportHandle := report_handle.NewReportHandle(questionService, answerService, commentService) reportService := report2.NewReportService(reportRepo, objService, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService, eventQueueService) reportController := controller.NewReportController(reportService, rankService, captchaService) diff --git a/docs/docs.go b/docs/docs.go index 263e6775e..c87313917 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -9780,8 +9780,6 @@ const docTemplate = `{ "schema.QuestionAdd": { "type": "object", "required": [ - "content", - "tags", "title" ], "properties": { @@ -9796,7 +9794,7 @@ const docTemplate = `{ "description": "content", "type": "string", "maxLength": 65535, - "minLength": 6 + "minLength": 0 }, "tags": { "description": "tags", @@ -9817,8 +9815,6 @@ const docTemplate = `{ "type": "object", "required": [ "answer_content", - "content", - "tags", "title" ], "properties": { @@ -9838,7 +9834,7 @@ const docTemplate = `{ "description": "content", "type": "string", "maxLength": 65535, - "minLength": 6 + "minLength": 0 }, "mention_username_list": { "type": "array", @@ -10119,9 +10115,7 @@ const docTemplate = `{ "schema.QuestionUpdate": { "type": "object", "required": [ - "content", "id", - "tags", "title" ], "properties": { @@ -10136,7 +10130,7 @@ const docTemplate = `{ "description": "content", "type": "string", "maxLength": 65535, - "minLength": 6 + "minLength": 0 }, "edit_summary": { "description": "edit summary", @@ -11047,6 +11041,16 @@ const docTemplate = `{ "max_image_size": { "type": "integer" }, + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, "recommend_tags": { "type": "array", "items": { @@ -11091,6 +11095,16 @@ const docTemplate = `{ "max_image_size": { "type": "integer" }, + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, "recommend_tags": { "type": "array", "items": { diff --git a/docs/swagger.json b/docs/swagger.json index 8cc85e263..9f89cb157 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -9753,8 +9753,6 @@ "schema.QuestionAdd": { "type": "object", "required": [ - "content", - "tags", "title" ], "properties": { @@ -9769,7 +9767,7 @@ "description": "content", "type": "string", "maxLength": 65535, - "minLength": 6 + "minLength": 0 }, "tags": { "description": "tags", @@ -9790,8 +9788,6 @@ "type": "object", "required": [ "answer_content", - "content", - "tags", "title" ], "properties": { @@ -9811,7 +9807,7 @@ "description": "content", "type": "string", "maxLength": 65535, - "minLength": 6 + "minLength": 0 }, "mention_username_list": { "type": "array", @@ -10092,9 +10088,7 @@ "schema.QuestionUpdate": { "type": "object", "required": [ - "content", "id", - "tags", "title" ], "properties": { @@ -10109,7 +10103,7 @@ "description": "content", "type": "string", "maxLength": 65535, - "minLength": 6 + "minLength": 0 }, "edit_summary": { "description": "edit summary", @@ -11020,6 +11014,16 @@ "max_image_size": { "type": "integer" }, + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, "recommend_tags": { "type": "array", "items": { @@ -11064,6 +11068,16 @@ "max_image_size": { "type": "integer" }, + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, "recommend_tags": { "type": "array", "items": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 9cdf248e1..d2dd076cf 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1589,7 +1589,7 @@ definitions: content: description: content maxLength: 65535 - minLength: 6 + minLength: 0 type: string tags: description: tags @@ -1602,8 +1602,6 @@ definitions: minLength: 6 type: string required: - - content - - tags - title type: object schema.QuestionAddByAnswer: @@ -1620,7 +1618,7 @@ definitions: content: description: content maxLength: 65535 - minLength: 6 + minLength: 0 type: string mention_username_list: items: @@ -1638,8 +1636,6 @@ definitions: type: string required: - answer_content - - content - - tags - title type: object schema.QuestionInfoResp: @@ -1826,7 +1822,7 @@ definitions: content: description: content maxLength: 65535 - minLength: 6 + minLength: 0 type: string edit_summary: description: edit summary @@ -1849,9 +1845,7 @@ definitions: minLength: 6 type: string required: - - content - id - - tags - title type: object schema.QuestionUpdateInviteUser: @@ -2453,6 +2447,14 @@ definitions: type: integer max_image_size: type: integer + min_content: + maximum: 65535 + minimum: 0 + type: integer + min_tags: + maximum: 5 + minimum: 0 + type: integer recommend_tags: items: $ref: '#/definitions/schema.SiteWriteTag' @@ -2482,6 +2484,14 @@ definitions: type: integer max_image_size: type: integer + min_content: + maximum: 65535 + minimum: 0 + type: integer + min_tags: + maximum: 5 + minimum: 0 + type: integer recommend_tags: items: $ref: '#/definitions/schema.SiteWriteTag' diff --git a/go.mod b/go.mod index 417688120..969d9ebbc 100644 --- a/go.mod +++ b/go.mod @@ -56,12 +56,12 @@ require ( github.com/swaggo/swag v1.16.3 github.com/tidwall/gjson v1.17.3 github.com/yuin/goldmark v1.7.4 - go.uber.org/mock v0.5.0 - golang.org/x/crypto v0.36.0 + go.uber.org/mock v0.6.0 + golang.org/x/crypto v0.41.0 golang.org/x/image v0.20.0 - golang.org/x/net v0.38.0 - golang.org/x/term v0.30.0 - golang.org/x/text v0.23.0 + golang.org/x/net v0.43.0 + golang.org/x/term v0.34.0 + golang.org/x/text v0.28.0 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/yaml.v3 v3.0.1 modernc.org/sqlite v1.33.0 @@ -161,8 +161,8 @@ require ( go.uber.org/zap v1.27.0 // indirect golang.org/x/arch v0.10.0 // indirect golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/tools v0.25.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/tools v0.36.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index b45d881fe..35db004db 100644 --- a/go.sum +++ b/go.sum @@ -654,8 +654,8 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= -go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -685,8 +685,8 @@ golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= +golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= @@ -703,8 +703,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= +golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -731,8 +731,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -743,8 +743,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -779,14 +779,14 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= -golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= +golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= +golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -795,8 +795,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -820,8 +820,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= -golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= +golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= +golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From fc2a1d8afeb86602215d831c2767c2a1a56f30a2 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Fri, 28 Nov 2025 10:49:10 +0800 Subject: [PATCH 13/29] fix(answer): update QuestionID handling in answer update process --- internal/controller/answer_controller.go | 1 - internal/schema/answer_schema.go | 1 - internal/service/content/answer_service.go | 19 +++++++++---------- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/internal/controller/answer_controller.go b/internal/controller/answer_controller.go index 7c5aca1db..0e43121c5 100644 --- a/internal/controller/answer_controller.go +++ b/internal/controller/answer_controller.go @@ -318,7 +318,6 @@ func (ac *AnswerController) UpdateAnswer(ctx *gin.Context) { handler.HandleResponse(ctx, err, nil) return } - req.QuestionID = uid.DeShortID(req.QuestionID) linkUrlLimitUser := canList[2] isAdmin := middleware.GetUserIsAdminModerator(ctx) if !isAdmin || !linkUrlLimitUser { diff --git a/internal/schema/answer_schema.go b/internal/schema/answer_schema.go index 015e26ac5..9ac4bcad7 100644 --- a/internal/schema/answer_schema.go +++ b/internal/schema/answer_schema.go @@ -78,7 +78,6 @@ type GetAnswerInfoResp struct { type AnswerUpdateReq struct { ID string `json:"id"` - QuestionID string `json:"question_id"` Title string `json:"title"` Content string `validate:"required,notblank,gte=6,lte=65535" json:"content"` EditSummary string `validate:"omitempty" json:"edit_summary"` diff --git a/internal/service/content/answer_service.go b/internal/service/content/answer_service.go index b9d45b522..982bbf88a 100644 --- a/internal/service/content/answer_service.go +++ b/internal/service/content/answer_service.go @@ -346,24 +346,23 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq return "", errors.BadRequest(reason.AnswerCannotUpdate) } - questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, req.QuestionID) + answerInfo, exist, err := as.answerRepo.GetByID(ctx, req.ID) if err != nil { return "", err } if !exist { - return "", errors.BadRequest(reason.QuestionNotFound) + return "", errors.BadRequest(reason.AnswerNotFound) + } + if answerInfo.Status == entity.AnswerStatusDeleted { + return "", errors.BadRequest(reason.AnswerCannotUpdate) } - answerInfo, exist, err := as.answerRepo.GetByID(ctx, req.ID) + questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, answerInfo.QuestionID) if err != nil { return "", err } if !exist { - return "", errors.BadRequest(reason.AnswerNotFound) - } - - if answerInfo.Status == entity.AnswerStatusDeleted { - return "", errors.BadRequest(reason.AnswerCannotUpdate) + return "", errors.BadRequest(reason.QuestionNotFound) } //If the content is the same, ignore it @@ -374,7 +373,7 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq insertData := &entity.Answer{} insertData.ID = req.ID insertData.UserID = answerInfo.UserID - insertData.QuestionID = req.QuestionID + insertData.QuestionID = questionInfo.ID insertData.OriginalText = req.Content insertData.ParsedText = req.HTML insertData.UpdatedAt = time.Now() @@ -403,7 +402,7 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq if err = as.answerRepo.UpdateAnswer(ctx, insertData, []string{"original_text", "parsed_text", "updated_at", "last_edit_user_id"}); err != nil { return "", err } - err = as.questionCommon.UpdatePostTime(ctx, req.QuestionID) + err = as.questionCommon.UpdatePostTime(ctx, questionInfo.ID) if err != nil { return insertData.ID, err } From f723d120d924dcf7e65b969ce18f8111cac40343 Mon Sep 17 00:00:00 2001 From: ferhat elmas Date: Fri, 28 Nov 2025 23:11:57 +0100 Subject: [PATCH 14/29] feat: add golangci-lint into lint target * replace empty interface with any * run fmt via golangci-lint related to #1432 Signed-off-by: ferhat elmas --- .gitignore | 2 +- .golangci.yaml | 30 +++++++++++++++++++ Makefile | 17 +++++++++-- docs/docs.go | 7 ++--- docs/swagger.json | 7 ++--- docs/swagger.yaml | 6 ++-- internal/base/handler/handler.go | 6 ++-- internal/base/handler/response.go | 4 +-- internal/base/pager/pager.go | 2 +- internal/base/pager/pagination.go | 6 ++-- internal/base/server/http_funcmap.go | 6 ++-- internal/base/translator/provider.go | 8 ++--- internal/base/validator/validator.go | 4 +-- internal/install/install_from_env.go | 2 +- internal/migrations/init.go | 10 +++---- internal/migrations/init_data.go | 2 +- internal/migrations/v25.go | 2 +- internal/migrations/v6.go | 2 +- internal/repo/meta/meta_repo.go | 2 +- .../plugin_config/plugin_user_config_repo.go | 2 +- internal/repo/revision/revision_repo.go | 2 +- internal/repo/role/user_role_rel_repo.go | 2 +- internal/repo/search_common/search_repo.go | 26 ++++++++-------- internal/repo/user/user_repo.go | 2 +- internal/schema/question_schema.go | 28 ++++++++--------- internal/schema/revision_schema.go | 2 +- internal/schema/siteinfo_schema.go | 14 ++++----- internal/schema/user_schema.go | 2 +- internal/service/question_common/question.go | 2 +- internal/service/siteinfo/siteinfo_service.go | 2 +- .../siteinfo_common/siteinfo_service.go | 4 +-- pkg/converter/str.go | 2 +- 32 files changed, 125 insertions(+), 90 deletions(-) create mode 100644 .golangci.yaml diff --git a/.gitignore b/.gitignore index 1fc116a74..257ef31d6 100644 --- a/.gitignore +++ b/.gitignore @@ -28,7 +28,7 @@ vendor/ /answer-data/ /answer /new_answer - +build/tools/ dist/ # Lint setup generated file diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 000000000..af00efc3b --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,30 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +version: "2" +linters: + default: none + +formatters: + enable: + - gofmt + settings: + gofmt: + simplify: true + rewrite-rules: + - pattern: 'interface{}' + replacement: 'any' diff --git a/Makefile b/Makefile index 8ab23cce3..fd3f044fa 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,15 @@ Revision=$(shell git rev-parse --short HEAD 2>/dev/null || echo "") GO_FLAGS=-ldflags="-X github.com/apache/answer/cmd.Version=$(VERSION) -X 'github.com/apache/answer/cmd.Revision=$(Revision)' -X 'github.com/apache/answer/cmd.Time=`date +%s`' -extldflags -static" GO=$(GO_ENV) "$(shell which go)" +GOLANGCI_VERSION ?= v2.6.2 +TOOLS_BIN := $(shell mkdir -p build/tools && realpath build/tools) + +GOLANGCI = $(TOOLS_BIN)/golangci-lint-$(GOLANGCI_VERSION) +$(GOLANGCI): + rm -f $(TOOLS_BIN)/golangci-lint* + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/$(GOLANGCI_VERSION)/install.sh | sh -s -- -b $(TOOLS_BIN) $(GOLANGCI_VERSION) + mv $(TOOLS_BIN)/golangci-lint $(TOOLS_BIN)/golangci-lint-$(GOLANGCI_VERSION) + build: generate @$(GO) build $(GO_FLAGS) -o $(BIN) $(DIR_SRC) @@ -50,8 +59,12 @@ install-ui-packages: ui: @cd ui && pnpm pre-install && pnpm build && cd - -lint: generate +lint: generate $(GOLANGCI) + @bash ./script/check-asf-header.sh + $(GOLANGCI) run + +lint-fix: generate $(GOLANGCI) @bash ./script/check-asf-header.sh - @gofmt -w -l . + $(GOLANGCI) run --fix all: clean build diff --git a/docs/docs.go b/docs/docs.go index c87313917..5e9d5b39d 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -8080,9 +8080,6 @@ const docTemplate = `{ "id": { "type": "string" }, - "question_id": { - "type": "string" - }, "title": { "type": "string" } @@ -10920,7 +10917,7 @@ const docTemplate = `{ }, "theme_config": { "type": "object", - "additionalProperties": true + "additionalProperties": {} } } }, @@ -10935,7 +10932,7 @@ const docTemplate = `{ }, "theme_config": { "type": "object", - "additionalProperties": true + "additionalProperties": {} }, "theme_options": { "type": "array", diff --git a/docs/swagger.json b/docs/swagger.json index 9f89cb157..e0f6378e4 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -8053,9 +8053,6 @@ "id": { "type": "string" }, - "question_id": { - "type": "string" - }, "title": { "type": "string" } @@ -10893,7 +10890,7 @@ }, "theme_config": { "type": "object", - "additionalProperties": true + "additionalProperties": {} } } }, @@ -10908,7 +10905,7 @@ }, "theme_config": { "type": "object", - "additionalProperties": true + "additionalProperties": {} }, "theme_options": { "type": "array", diff --git a/docs/swagger.yaml b/docs/swagger.yaml index d2dd076cf..e0244083b 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -399,8 +399,6 @@ definitions: type: string id: type: string - question_id: - type: string title: type: string required: @@ -2364,7 +2362,7 @@ definitions: maxLength: 255 type: string theme_config: - additionalProperties: true + additionalProperties: {} type: object required: - theme @@ -2376,7 +2374,7 @@ definitions: theme: type: string theme_config: - additionalProperties: true + additionalProperties: {} type: object theme_options: items: diff --git a/internal/base/handler/handler.go b/internal/base/handler/handler.go index 7670feea7..5a4961a3e 100644 --- a/internal/base/handler/handler.go +++ b/internal/base/handler/handler.go @@ -31,7 +31,7 @@ import ( ) // HandleResponse Handle response body -func HandleResponse(ctx *gin.Context, err error, data interface{}) { +func HandleResponse(ctx *gin.Context, err error, data any) { lang := GetLang(ctx) // no error if err == nil { @@ -61,7 +61,7 @@ func HandleResponse(ctx *gin.Context, err error, data interface{}) { } // BindAndCheck bind request and check -func BindAndCheck(ctx *gin.Context, data interface{}) bool { +func BindAndCheck(ctx *gin.Context, data any) bool { lang := GetLang(ctx) ctx.Set(constant.AcceptLanguageFlag, lang) if err := ctx.ShouldBind(data); err != nil { @@ -79,7 +79,7 @@ func BindAndCheck(ctx *gin.Context, data interface{}) bool { } // BindAndCheckReturnErr bind request and check -func BindAndCheckReturnErr(ctx *gin.Context, data interface{}) (errFields []*validator.FormErrorField) { +func BindAndCheckReturnErr(ctx *gin.Context, data any) (errFields []*validator.FormErrorField) { lang := GetLang(ctx) if err := ctx.ShouldBind(data); err != nil { log.Errorf("http_handle BindAndCheck fail, %s", err.Error()) diff --git a/internal/base/handler/response.go b/internal/base/handler/response.go index 827e0b362..51be8a8a1 100644 --- a/internal/base/handler/response.go +++ b/internal/base/handler/response.go @@ -34,7 +34,7 @@ type RespBody struct { // response message Message string `json:"msg"` // response data - Data interface{} `json:"data"` + Data any `json:"data"` } // TrMsg translate the reason cause as a message @@ -63,7 +63,7 @@ func NewRespBodyFromError(e *errors.Error) *RespBody { } // NewRespBodyData new response body with data -func NewRespBodyData(code int, reason string, data interface{}) *RespBody { +func NewRespBodyData(code int, reason string, data any) *RespBody { return &RespBody{ Code: code, Reason: reason, diff --git a/internal/base/pager/pager.go b/internal/base/pager/pager.go index d7a4caa14..b14d99bfa 100644 --- a/internal/base/pager/pager.go +++ b/internal/base/pager/pager.go @@ -27,7 +27,7 @@ import ( ) // Help xorm page helper -func Help(page, pageSize int, rowsSlicePtr interface{}, rowElement interface{}, session *xorm.Session) (total int64, err error) { +func Help(page, pageSize int, rowsSlicePtr any, rowElement any, session *xorm.Session) (total int64, err error) { page, pageSize = ValPageAndPageSize(page, pageSize) sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) diff --git a/internal/base/pager/pagination.go b/internal/base/pager/pagination.go index 36849fed5..1b09e1f21 100644 --- a/internal/base/pager/pagination.go +++ b/internal/base/pager/pagination.go @@ -25,8 +25,8 @@ import ( // PageModel page model type PageModel struct { - Count int64 `json:"count"` - List interface{} `json:"list"` + Count int64 `json:"count"` + List any `json:"list"` } // PageCond page condition @@ -36,7 +36,7 @@ type PageCond struct { } // NewPageModel new page model -func NewPageModel(totalRecords int64, records interface{}) *PageModel { +func NewPageModel(totalRecords int64, records any) *PageModel { sliceValue := reflect.Indirect(reflect.ValueOf(records)) if sliceValue.Kind() != reflect.Slice { panic("not a slice") diff --git a/internal/base/server/http_funcmap.go b/internal/base/server/http_funcmap.go index 9d8e98f96..8f6cac5fc 100644 --- a/internal/base/server/http_funcmap.go +++ b/internal/base/server/http_funcmap.go @@ -64,7 +64,7 @@ var funcMap = template.FuncMap{ "formatLinkNofollow": func(data string) template.HTML { return template.HTML(FormatLinkNofollow(data)) }, - "translator": func(la i18n.Language, data string, params ...interface{}) string { + "translator": func(la i18n.Language, data string, params ...any) string { trans := translator.GlobalTrans.Tr(la, data) if len(params) > 0 && len(params)%2 == 0 { @@ -128,8 +128,8 @@ var funcMap = template.FuncMap{ trans = translator.GlobalTrans.Tr(la, "ui.dates.long_date_with_year") return day.Format(timestamp, trans, tz) }, - "wrapComments": func(comments []*schema.GetCommentResp, la i18n.Language, tz string) map[string]interface{} { - return map[string]interface{}{ + "wrapComments": func(comments []*schema.GetCommentResp, la i18n.Language, tz string) map[string]any { + return map[string]any{ "comments": comments, "language": la, "timezone": tz, diff --git a/internal/base/translator/provider.go b/internal/base/translator/provider.go index 9838d185d..47212e84f 100644 --- a/internal/base/translator/provider.go +++ b/internal/base/translator/provider.go @@ -76,14 +76,14 @@ func NewTranslator(c *I18n) (tr i18n.Translator, err error) { // parse the backend translation originalTr := struct { - Backend map[string]map[string]interface{} `yaml:"backend"` - UI map[string]interface{} `yaml:"ui"` - Plugin map[string]interface{} `yaml:"plugin"` + Backend map[string]map[string]any `yaml:"backend"` + UI map[string]any `yaml:"ui"` + Plugin map[string]any `yaml:"plugin"` }{} if err = yaml.Unmarshal(buf, &originalTr); err != nil { return nil, err } - translation := make(map[string]interface{}, 0) + translation := make(map[string]any, 0) for k, v := range originalTr.Backend { translation[k] = v } diff --git a/internal/base/validator/validator.go b/internal/base/validator/validator.go index 70c7be2e9..22761c521 100644 --- a/internal/base/validator/validator.go +++ b/internal/base/validator/validator.go @@ -187,7 +187,7 @@ func GetValidatorByLang(lang i18n.Language) *MyValidator { } // Check / -func (m *MyValidator) Check(value interface{}) (errFields []*FormErrorField, err error) { +func (m *MyValidator) Check(value any) (errFields []*FormErrorField, err error) { defer func() { if len(errFields) == 0 { return @@ -261,7 +261,7 @@ type Checker interface { Check() (errField []*FormErrorField, err error) } -func getObjectTagByFieldName(obj interface{}, fieldName string) (tag string) { +func getObjectTagByFieldName(obj any, fieldName string) (tag string) { defer func() { if err := recover(); err != nil { log.Error(err) diff --git a/internal/install/install_from_env.go b/internal/install/install_from_env.go index a6b668bab..c05d2aaba 100644 --- a/internal/install/install_from_env.go +++ b/internal/install/install_from_env.go @@ -133,7 +133,7 @@ func initBaseInfo(env *Env) (err error) { return requestAPI(req, "POST", "/installation/base-info", InitBaseInfo) } -func requestAPI(req interface{}, method, url string, handlerFunc gin.HandlerFunc) error { +func requestAPI(req any, method, url string, handlerFunc gin.HandlerFunc) error { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) body, _ := json.Marshal(req) diff --git a/internal/migrations/init.go b/internal/migrations/init.go index 392ecb2c6..184c986b9 100644 --- a/internal/migrations/init.go +++ b/internal/migrations/init.go @@ -208,7 +208,7 @@ func (m *Mentor) initSiteInfoGeneralData() { } func (m *Mentor) initSiteInfoLoginConfig() { - loginConfig := map[string]interface{}{ + loginConfig := map[string]any{ "allow_new_registrations": true, "allow_email_registrations": true, "allow_password_login": true, @@ -223,7 +223,7 @@ func (m *Mentor) initSiteInfoLoginConfig() { } func (m *Mentor) initSiteInfoLegalConfig() { - legalConfig := map[string]interface{}{ + legalConfig := map[string]any{ "external_content_display": m.userData.ExternalContentDisplay, } legalConfigDataBytes, _ := json.Marshal(legalConfig) @@ -244,7 +244,7 @@ func (m *Mentor) initSiteInfoThemeConfig() { } func (m *Mentor) initSiteInfoSEOConfig() { - seoData := map[string]interface{}{ + seoData := map[string]any{ "permalink": constant.PermalinkQuestionID, "robots": defaultSEORobotTxt + m.userData.SiteURL + "/sitemap.xml", } @@ -276,7 +276,7 @@ func (m *Mentor) initSiteInfoUsersConfig() { } func (m *Mentor) initSiteInfoPrivilegeRank() { - privilegeRankData := map[string]interface{}{ + privilegeRankData := map[string]any{ "level": schema.PrivilegeLevel2, } privilegeRankDataBytes, _ := json.Marshal(privilegeRankData) @@ -288,7 +288,7 @@ func (m *Mentor) initSiteInfoPrivilegeRank() { } func (m *Mentor) initSiteInfoWrite() { - writeData := map[string]interface{}{ + writeData := map[string]any{ "min_content": 6, "restrict_answer": true, "min_tags": 1, diff --git a/internal/migrations/init_data.go b/internal/migrations/init_data.go index 96151625d..356a915a7 100644 --- a/internal/migrations/init_data.go +++ b/internal/migrations/init_data.go @@ -43,7 +43,7 @@ Sitemap: ` ) var ( - tables = []interface{}{ + tables = []any{ &entity.Activity{}, &entity.Answer{}, &entity.Collection{}, diff --git a/internal/migrations/v25.go b/internal/migrations/v25.go index 560a852ac..228c2ef26 100644 --- a/internal/migrations/v25.go +++ b/internal/migrations/v25.go @@ -39,7 +39,7 @@ func addFileRecord(ctx context.Context, x *xorm.Engine) error { if err != nil { return fmt.Errorf("get legal config failed: %w", err) } - legalConfig := make(map[string]interface{}) + legalConfig := make(map[string]any) if exist { if err := json.Unmarshal([]byte(legalInfo.Content), &legalConfig); err != nil { return fmt.Errorf("unmarshal legal config failed: %w", err) diff --git a/internal/migrations/v6.go b/internal/migrations/v6.go index 9171ad47a..88fb58497 100644 --- a/internal/migrations/v6.go +++ b/internal/migrations/v6.go @@ -45,7 +45,7 @@ func addNewAnswerNotification(ctx context.Context, x *xorm.Engine) error { } } - m := make(map[string]interface{}) + m := make(map[string]any) _ = json.Unmarshal([]byte(cond.Value), &m) m["new_answer_title"] = "[{{.SiteName}}] {{.DisplayName}} answered your question" m["new_answer_body"] = "{{.QuestionTitle}}

\n\n{{.DisplayName}}:
\n
{{.AnswerSummary}}

\nView it on {{.SiteName}}

\n\nYou are receiving this because you authored the thread. Unsubscribe" diff --git a/internal/repo/meta/meta_repo.go b/internal/repo/meta/meta_repo.go index 767bd04c7..9680fb419 100644 --- a/internal/repo/meta/meta_repo.go +++ b/internal/repo/meta/meta_repo.go @@ -72,7 +72,7 @@ func (mr *metaRepo) UpdateMeta(ctx context.Context, meta *entity.Meta) (err erro // AddOrUpdateMetaByObjectIdAndKey if exist record with same objectID and key, update it. Or create a new one func (mr *metaRepo) AddOrUpdateMetaByObjectIdAndKey(ctx context.Context, objectId, key string, f func(*entity.Meta, bool) (*entity.Meta, error)) error { - _, err := mr.data.DB.Transaction(func(session *xorm.Session) (interface{}, error) { + _, err := mr.data.DB.Transaction(func(session *xorm.Session) (any, error) { session = session.Context(ctx) // 1. acquire meta entity with target object id and key diff --git a/internal/repo/plugin_config/plugin_user_config_repo.go b/internal/repo/plugin_config/plugin_user_config_repo.go index 19d6af5f9..83da8e758 100644 --- a/internal/repo/plugin_config/plugin_user_config_repo.go +++ b/internal/repo/plugin_config/plugin_user_config_repo.go @@ -44,7 +44,7 @@ func NewPluginUserConfigRepo(data *data.Data) plugin_common.PluginUserConfigRepo func (ur *pluginUserConfigRepo) SaveUserPluginConfig(ctx context.Context, userID string, pluginSlugName, configValue string) (err error) { - _, err = ur.data.DB.Transaction(func(session *xorm.Session) (interface{}, error) { + _, err = ur.data.DB.Transaction(func(session *xorm.Session) (any, error) { session = session.Context(ctx) old := &entity.PluginUserConfig{ UserID: userID, diff --git a/internal/repo/revision/revision_repo.go b/internal/repo/revision/revision_repo.go index 09ba1aacd..8b9e08400 100644 --- a/internal/repo/revision/revision_repo.go +++ b/internal/repo/revision/revision_repo.go @@ -64,7 +64,7 @@ func (rr *revisionRepo) AddRevision(ctx context.Context, revision *entity.Revisi if !rr.allowRecord(revision.ObjectType) { return nil } - _, err = rr.data.DB.Transaction(func(session *xorm.Session) (interface{}, error) { + _, err = rr.data.DB.Transaction(func(session *xorm.Session) (any, error) { session = session.Context(ctx) _, err = session.Insert(revision) if err != nil { diff --git a/internal/repo/role/user_role_rel_repo.go b/internal/repo/role/user_role_rel_repo.go index 7bd14ecea..1925339c0 100644 --- a/internal/repo/role/user_role_rel_repo.go +++ b/internal/repo/role/user_role_rel_repo.go @@ -45,7 +45,7 @@ func NewUserRoleRelRepo(data *data.Data) role.UserRoleRelRepo { // SaveUserRoleRel save user role rel func (ur *userRoleRelRepo) SaveUserRoleRel(ctx context.Context, userID string, roleID int) (err error) { - _, err = ur.data.DB.Transaction(func(session *xorm.Session) (interface{}, error) { + _, err = ur.data.DB.Transaction(func(session *xorm.Session) (any, error) { session = session.Context(ctx) item := &entity.UserRoleRel{UserID: userID} exist, err := session.Get(item) diff --git a/internal/repo/search_common/search_repo.go b/internal/repo/search_common/search_repo.go index 314c51878..806517234 100644 --- a/internal/repo/search_common/search_repo.go +++ b/internal/repo/search_common/search_repo.go @@ -107,8 +107,8 @@ func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs ub *builder.Builder qfs = qFields afs = aFields - argsQ = []interface{}{} - argsA = []interface{}{} + argsQ = []any{} + argsA = []any{} ) if order == "relevance" { @@ -212,8 +212,8 @@ func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs return } - queryArgs := []interface{}{} - countArgs := []interface{}{} + queryArgs := []any{} + countArgs := []any{} queryArgs = append(queryArgs, querySQL) queryArgs = append(queryArgs, argsQ...) @@ -246,7 +246,7 @@ func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, tagID words = filterWords(words) var ( qfs = qFields - args = []interface{}{} + args = []any{} ) if order == "relevance" { if len(words) > 0 { @@ -313,8 +313,8 @@ func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, tagID args = append(args, answers) } - queryArgs := []interface{}{} - countArgs := []interface{}{} + queryArgs := []any{} + countArgs := []any{} countSQL, _, err := builder.MySQL().Select("count(*) total").From(b, "c").ToSQL() if err != nil { @@ -358,7 +358,7 @@ func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, tagIDs var ( afs = aFields - args = []interface{}{} + args = []any{} ) if order == "relevance" { if len(words) > 0 { @@ -409,8 +409,8 @@ func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, tagIDs args = append(args, questionID) } - queryArgs := []interface{}{} - countArgs := []interface{}{} + queryArgs := []any{} + countArgs := []any{} countSQL, _, err := builder.MySQL().Select("count(*) total").From(b, "c").ToSQL() if err != nil { @@ -575,9 +575,9 @@ func (sr *searchRepo) parseResult(ctx context.Context, res []map[string][]byte, return resultList, nil } -func addRelevanceField(searchFields, words, fields []string) (res []string, args []interface{}) { +func addRelevanceField(searchFields, words, fields []string) (res []string, args []any) { relevanceRes := []string{} - args = []interface{}{} + args = []any{} for _, searchField := range searchFields { var ( @@ -585,7 +585,7 @@ func addRelevanceField(searchFields, words, fields []string) (res []string, args replacement = "REPLACE(%s, ?, '')" replaceField = searchField replaced string - argsField = []interface{}{} + argsField = []any{} ) res = fields diff --git a/internal/repo/user/user_repo.go b/internal/repo/user/user_repo.go index a85cd79a1..1533cc5e8 100644 --- a/internal/repo/user/user_repo.go +++ b/internal/repo/user/user_repo.go @@ -51,7 +51,7 @@ func NewUserRepo(data *data.Data) usercommon.UserRepo { // AddUser add user func (ur *userRepo) AddUser(ctx context.Context, user *entity.User) (err error) { - _, err = ur.data.DB.Transaction(func(session *xorm.Session) (interface{}, error) { + _, err = ur.data.DB.Transaction(func(session *xorm.Session) (any, error) { session = session.Context(ctx) userInfo := &entity.User{} exist, err := session.Where("username = ?", user.Username).Get(userInfo) diff --git a/internal/schema/question_schema.go b/internal/schema/question_schema.go index 84b97b830..133208286 100644 --- a/internal/schema/question_schema.go +++ b/internal/schema/question_schema.go @@ -330,24 +330,24 @@ type UserAnswerInfo struct { CreateTime int `json:"create_time"` UpdateTime int `json:"update_time"` QuestionInfo struct { - Title string `json:"title"` - UrlTitle string `json:"url_title"` - Tags []interface{} `json:"tags"` + Title string `json:"title"` + UrlTitle string `json:"url_title"` + Tags []any `json:"tags"` } `json:"question_info"` } type UserQuestionInfo struct { - ID string `json:"question_id"` - Title string `json:"title"` - UrlTitle string `json:"url_title"` - VoteCount int `json:"vote_count"` - Tags []interface{} `json:"tags"` - ViewCount int `json:"view_count"` - AnswerCount int `json:"answer_count"` - CollectionCount int `json:"collection_count"` - CreatedAt int64 `json:"created_at"` - AcceptedAnswerID string `json:"accepted_answer_id"` - Status string `json:"status"` + ID string `json:"question_id"` + Title string `json:"title"` + UrlTitle string `json:"url_title"` + VoteCount int `json:"vote_count"` + Tags []any `json:"tags"` + ViewCount int `json:"view_count"` + AnswerCount int `json:"answer_count"` + CollectionCount int `json:"collection_count"` + CreatedAt int64 `json:"created_at"` + AcceptedAnswerID string `json:"accepted_answer_id"` + Status string `json:"status"` } const ( diff --git a/internal/schema/revision_schema.go b/internal/schema/revision_schema.go index 946d11653..b3ac0aadd 100644 --- a/internal/schema/revision_schema.go +++ b/internal/schema/revision_schema.go @@ -97,7 +97,7 @@ type GetRevisionResp struct { Title string `json:"title"` UrlTitle string `json:"url_title"` Content string `json:"-"` - ContentParsed interface{} `json:"content"` + ContentParsed any `json:"content"` Status int `json:"status"` CreatedAt time.Time `json:"-"` CreatedAtParsed int64 `json:"create_at"` diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index 76f66cb07..0e43bb420 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -178,9 +178,9 @@ type SiteCustomCssHTMLReq struct { // SiteThemeReq site theme config type SiteThemeReq struct { - Theme string `validate:"required,gt=0,lte=255" json:"theme"` - ThemeConfig map[string]interface{} `validate:"omitempty" json:"theme_config"` - ColorScheme string `validate:"omitempty,gt=0,lte=100" json:"color_scheme"` + Theme string `validate:"required,gt=0,lte=255" json:"theme"` + ThemeConfig map[string]any `validate:"omitempty" json:"theme_config"` + ColorScheme string `validate:"omitempty,gt=0,lte=100" json:"color_scheme"` } type SiteSeoReq struct { @@ -213,10 +213,10 @@ type SiteUsersResp SiteUsersReq // SiteThemeResp site theme response type SiteThemeResp struct { - ThemeOptions []*ThemeOption `json:"theme_options"` - Theme string `json:"theme"` - ThemeConfig map[string]interface{} `json:"theme_config"` - ColorScheme string `json:"color_scheme"` + ThemeOptions []*ThemeOption `json:"theme_options"` + Theme string `json:"theme"` + ThemeConfig map[string]any `json:"theme_config"` + ColorScheme string `json:"color_scheme"` } func (s *SiteThemeResp) TrTheme(ctx context.Context) { diff --git a/internal/schema/user_schema.go b/internal/schema/user_schema.go index 7ba8817a8..d209c8f58 100644 --- a/internal/schema/user_schema.go +++ b/internal/schema/user_schema.go @@ -200,7 +200,7 @@ func (r *GetOtherUserInfoByUsernameResp) ConvertFromUserEntityWithLang(ctx conte r.SuspendedUntil = userInfo.SuspendedUntil.Unix() trans := translator.GlobalTrans.Tr(lang, "ui.dates.long_date_with_time") suspendedUntilFormatted := day.Format(userInfo.SuspendedUntil.Unix(), trans, "UTC") - r.StatusMsg = translator.TrWithData(lang, reason.UserStatusSuspendedUntil, map[string]interface{}{ + r.StatusMsg = translator.TrWithData(lang, reason.UserStatusSuspendedUntil, map[string]any{ "SuspendedUntil": suspendedUntilFormatted, }) } diff --git a/internal/service/question_common/question.go b/internal/service/question_common/question.go index feb5626ed..333806445 100644 --- a/internal/service/question_common/question.go +++ b/internal/service/question_common/question.go @@ -622,7 +622,7 @@ func (qs *QuestionCommon) SitemapCron(ctx context.Context) { } } -func (qs *QuestionCommon) SetCache(ctx context.Context, cachekey string, info interface{}) error { +func (qs *QuestionCommon) SetCache(ctx context.Context, cachekey string, info any) error { infoStr, err := json.Marshal(info) if err != nil { return errors.InternalServer(reason.UnknownError).WithError(err).WithStack() diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go index 92b3e0c71..cf43d68d5 100644 --- a/internal/service/siteinfo/siteinfo_service.go +++ b/internal/service/siteinfo/siteinfo_service.go @@ -183,7 +183,7 @@ func (s *SiteInfoService) SaveSiteBranding(ctx context.Context, req *schema.Site } // SaveSiteWrite save site configuration about write -func (s *SiteInfoService) SaveSiteWrite(ctx context.Context, req *schema.SiteWriteReq) (resp interface{}, err error) { +func (s *SiteInfoService) SaveSiteWrite(ctx context.Context, req *schema.SiteWriteReq) (resp any, err error) { recommendTags, reservedTags := make([]string, 0), make([]string, 0) recommendTagMapping, reservedTagMapping := make(map[string]bool), make(map[string]bool) for _, tag := range req.ReservedTags { diff --git a/internal/service/siteinfo_common/siteinfo_service.go b/internal/service/siteinfo_common/siteinfo_service.go index ef4869cc4..fda117229 100644 --- a/internal/service/siteinfo_common/siteinfo_service.go +++ b/internal/service/siteinfo_common/siteinfo_service.go @@ -56,7 +56,7 @@ type SiteInfoCommonService interface { GetSiteCustomCssHTML(ctx context.Context) (resp *schema.SiteCustomCssHTMLResp, err error) GetSiteTheme(ctx context.Context) (resp *schema.SiteThemeResp, err error) GetSiteSeo(ctx context.Context) (resp *schema.SiteSeoResp, err error) - GetSiteInfoByType(ctx context.Context, siteType string, resp interface{}) (err error) + GetSiteInfoByType(ctx context.Context, siteType string, resp any) (err error) IsBrandingFileUsed(ctx context.Context, filePath string) bool } @@ -224,7 +224,7 @@ func (s *siteInfoCommonService) EnableShortID(ctx context.Context) (enabled bool return siteSeo.IsShortLink() } -func (s *siteInfoCommonService) GetSiteInfoByType(ctx context.Context, siteType string, resp interface{}) (err error) { +func (s *siteInfoCommonService) GetSiteInfoByType(ctx context.Context, siteType string, resp any) (err error) { siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, siteType) if err != nil { return err diff --git a/pkg/converter/str.go b/pkg/converter/str.go index 40c147fdc..5164609ca 100644 --- a/pkg/converter/str.go +++ b/pkg/converter/str.go @@ -47,7 +47,7 @@ func IntToString(data int64) string { // InterfaceToString converts data to string // It will be used in template render -func InterfaceToString(data interface{}) string { +func InterfaceToString(data any) string { switch t := data.(type) { case int: i := data.(int) From 9540ef60050fb6e2598d8d72ab23514f6e6d4f93 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Mon, 1 Dec 2025 11:30:42 +0800 Subject: [PATCH 15/29] refactor(goimports): add goimports to golangci-lint configuration #1432 --- .golangci.yaml | 1 + internal/base/handler/handler.go | 3 ++- internal/base/middleware/accept_language.go | 3 ++- internal/base/middleware/rate_limit.go | 1 + internal/cli/config.go | 1 + internal/cli/i18n.go | 7 ++++--- internal/controller/template_render/comment.go | 1 + internal/controller/user_plugin_controller.go | 3 ++- internal/entity/badge_entity.go | 3 ++- internal/entity/config_entity.go | 1 + internal/migrations/v1.go | 1 + internal/migrations/v13.go | 1 + internal/migrations/v14.go | 1 + internal/migrations/v15.go | 1 + internal/migrations/v16.go | 1 + internal/migrations/v17.go | 1 + internal/migrations/v18.go | 1 + internal/migrations/v19.go | 1 + internal/migrations/v2.go | 1 + internal/migrations/v21.go | 1 + internal/migrations/v22.go | 1 + internal/migrations/v24.go | 1 + internal/repo/activity/answer_repo.go | 3 ++- internal/repo/activity/user_active_repo.go | 1 + internal/repo/activity_common/vote.go | 1 + internal/repo/auth/auth.go | 1 + internal/repo/badge/badge_event_rule.go | 3 ++- internal/repo/badge/badge_repo.go | 1 + internal/repo/badge_award/badge_award_repo.go | 1 + internal/repo/badge_group/badge_group_repo.go | 1 + internal/repo/collection/collection_repo.go | 1 + internal/repo/export/email_repo.go | 3 ++- internal/repo/limit/limit.go | 3 ++- internal/repo/meta/meta_repo.go | 2 +- internal/repo/plugin_config/plugin_user_config_repo.go | 1 + internal/repo/search_sync/search_sync.go | 1 + .../user_notification_config_repo.go | 1 + internal/schema/email_template.go | 1 + internal/schema/notification_schema.go | 3 ++- internal/schema/user_notification_schema.go | 1 + internal/service/activity/activity.go | 2 +- internal/service/activity/answer_activity_service.go | 1 + internal/service/badge/badge_award_service.go | 1 + internal/service/badge/badge_event_handler.go | 1 + internal/service/badge/badge_group_service.go | 1 + internal/service/badge/badge_service.go | 3 ++- internal/service/content/question_hottest_service.go | 5 +++-- internal/service/content/vote_service.go | 3 ++- internal/service/export/email_service.go | 3 ++- internal/service/meta/meta_service.go | 3 ++- internal/service/notification/notification_service.go | 1 + internal/service/permission/answer_permission.go | 1 + internal/service/permission/question_permission.go | 1 + internal/service/provider.go | 2 +- internal/service/report/report_service.go | 1 + internal/service/search_parser/search_parser.go | 3 ++- .../user_notification_config_service.go | 1 + pkg/converter/str.go | 3 ++- pkg/day/day_test.go | 3 ++- pkg/gravatar/gravatar_test.go | 3 ++- 60 files changed, 82 insertions(+), 25 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index af00efc3b..263f63f70 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -22,6 +22,7 @@ linters: formatters: enable: - gofmt + - goimports settings: gofmt: simplify: true diff --git a/internal/base/handler/handler.go b/internal/base/handler/handler.go index 5a4961a3e..b545b5e01 100644 --- a/internal/base/handler/handler.go +++ b/internal/base/handler/handler.go @@ -21,13 +21,14 @@ package handler import ( "errors" + "net/http" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/reason" "github.com/apache/answer/internal/base/validator" "github.com/gin-gonic/gin" myErrors "github.com/segmentfault/pacman/errors" "github.com/segmentfault/pacman/log" - "net/http" ) // HandleResponse Handle response body diff --git a/internal/base/middleware/accept_language.go b/internal/base/middleware/accept_language.go index 7a8ee391a..ca8a1f903 100644 --- a/internal/base/middleware/accept_language.go +++ b/internal/base/middleware/accept_language.go @@ -20,13 +20,14 @@ package middleware import ( + "strings" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/handler" "github.com/apache/answer/internal/base/translator" "github.com/gin-gonic/gin" "github.com/segmentfault/pacman/i18n" "golang.org/x/text/language" - "strings" ) // ExtractAndSetAcceptLanguage extract accept language from header and set to context diff --git a/internal/base/middleware/rate_limit.go b/internal/base/middleware/rate_limit.go index 29b961757..d376a6d50 100644 --- a/internal/base/middleware/rate_limit.go +++ b/internal/base/middleware/rate_limit.go @@ -22,6 +22,7 @@ package middleware import ( "encoding/json" "fmt" + "github.com/apache/answer/internal/base/handler" "github.com/apache/answer/internal/base/reason" "github.com/apache/answer/internal/repo/limit" diff --git a/internal/cli/config.go b/internal/cli/config.go index 93cb8eab2..ecb62a13c 100644 --- a/internal/cli/config.go +++ b/internal/cli/config.go @@ -23,6 +23,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/entity" diff --git a/internal/cli/i18n.go b/internal/cli/i18n.go index faef0f28a..819ebd753 100644 --- a/internal/cli/i18n.go +++ b/internal/cli/i18n.go @@ -21,13 +21,14 @@ package cli import ( "fmt" + "os" + "path/filepath" + "strings" + "github.com/apache/answer/i18n" "github.com/apache/answer/pkg/dir" "github.com/apache/answer/pkg/writer" "gopkg.in/yaml.v3" - "os" - "path/filepath" - "strings" ) type YamlPluginContent struct { diff --git a/internal/controller/template_render/comment.go b/internal/controller/template_render/comment.go index 67efd2129..2862ad8dd 100644 --- a/internal/controller/template_render/comment.go +++ b/internal/controller/template_render/comment.go @@ -21,6 +21,7 @@ package templaterender import ( "context" + "github.com/apache/answer/internal/base/pager" "github.com/apache/answer/internal/schema" ) diff --git a/internal/controller/user_plugin_controller.go b/internal/controller/user_plugin_controller.go index 310215253..1c4c041c5 100644 --- a/internal/controller/user_plugin_controller.go +++ b/internal/controller/user_plugin_controller.go @@ -21,10 +21,11 @@ package controller import ( "encoding/json" + "net/http" + "github.com/apache/answer/internal/base/middleware" "github.com/apache/answer/internal/base/reason" "github.com/segmentfault/pacman/errors" - "net/http" "github.com/apache/answer/internal/base/handler" "github.com/apache/answer/internal/schema" diff --git a/internal/entity/badge_entity.go b/internal/entity/badge_entity.go index a370e2750..367bb7456 100644 --- a/internal/entity/badge_entity.go +++ b/internal/entity/badge_entity.go @@ -20,8 +20,9 @@ package entity import ( - "github.com/tidwall/gjson" "time" + + "github.com/tidwall/gjson" ) type BadgeLevel int diff --git a/internal/entity/config_entity.go b/internal/entity/config_entity.go index 95a02be48..d39af7b2d 100644 --- a/internal/entity/config_entity.go +++ b/internal/entity/config_entity.go @@ -21,6 +21,7 @@ package entity import ( "encoding/json" + "github.com/segmentfault/pacman/log" "github.com/apache/answer/pkg/converter" diff --git a/internal/migrations/v1.go b/internal/migrations/v1.go index c5e731a0e..688732fa7 100644 --- a/internal/migrations/v1.go +++ b/internal/migrations/v1.go @@ -21,6 +21,7 @@ package migrations import ( "context" + "xorm.io/xorm" ) diff --git a/internal/migrations/v13.go b/internal/migrations/v13.go index 30bfbb542..57d248482 100644 --- a/internal/migrations/v13.go +++ b/internal/migrations/v13.go @@ -24,6 +24,7 @@ import ( "encoding/json" "fmt" "time" + "xorm.io/builder" "github.com/apache/answer/internal/base/constant" diff --git a/internal/migrations/v14.go b/internal/migrations/v14.go index ee3a3d0d6..5e125c98e 100644 --- a/internal/migrations/v14.go +++ b/internal/migrations/v14.go @@ -22,6 +22,7 @@ package migrations import ( "context" "time" + "xorm.io/xorm/schemas" "xorm.io/xorm" diff --git a/internal/migrations/v15.go b/internal/migrations/v15.go index 5195c105a..5858d0097 100644 --- a/internal/migrations/v15.go +++ b/internal/migrations/v15.go @@ -21,6 +21,7 @@ package migrations import ( "context" + "github.com/apache/answer/internal/entity" "xorm.io/xorm" ) diff --git a/internal/migrations/v16.go b/internal/migrations/v16.go index 11643600c..11ae36843 100644 --- a/internal/migrations/v16.go +++ b/internal/migrations/v16.go @@ -21,6 +21,7 @@ package migrations import ( "context" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/entity" "github.com/segmentfault/pacman/log" diff --git a/internal/migrations/v17.go b/internal/migrations/v17.go index 655e547a2..3fa2c7b31 100644 --- a/internal/migrations/v17.go +++ b/internal/migrations/v17.go @@ -22,6 +22,7 @@ package migrations import ( "context" "fmt" + "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/service/permission" "github.com/segmentfault/pacman/log" diff --git a/internal/migrations/v18.go b/internal/migrations/v18.go index 89db524f5..7178c704e 100644 --- a/internal/migrations/v18.go +++ b/internal/migrations/v18.go @@ -23,6 +23,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/schema" diff --git a/internal/migrations/v19.go b/internal/migrations/v19.go index b45d374bb..b50c89f14 100644 --- a/internal/migrations/v19.go +++ b/internal/migrations/v19.go @@ -21,6 +21,7 @@ package migrations import ( "context" + "github.com/apache/answer/internal/entity" "xorm.io/xorm" ) diff --git a/internal/migrations/v2.go b/internal/migrations/v2.go index 4e17597dc..601ff98b2 100644 --- a/internal/migrations/v2.go +++ b/internal/migrations/v2.go @@ -21,6 +21,7 @@ package migrations import ( "context" + "xorm.io/xorm" ) diff --git a/internal/migrations/v21.go b/internal/migrations/v21.go index 880852f8e..de38bffbd 100644 --- a/internal/migrations/v21.go +++ b/internal/migrations/v21.go @@ -21,6 +21,7 @@ package migrations import ( "context" + "xorm.io/xorm" ) diff --git a/internal/migrations/v22.go b/internal/migrations/v22.go index 14292a1e7..e7177deae 100644 --- a/internal/migrations/v22.go +++ b/internal/migrations/v22.go @@ -22,6 +22,7 @@ package migrations import ( "context" "fmt" + "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/repo/unique" diff --git a/internal/migrations/v24.go b/internal/migrations/v24.go index 19358af45..a488679f6 100644 --- a/internal/migrations/v24.go +++ b/internal/migrations/v24.go @@ -23,6 +23,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/schema" diff --git a/internal/repo/activity/answer_repo.go b/internal/repo/activity/answer_repo.go index db6e3bde4..4aca874a7 100644 --- a/internal/repo/activity/answer_repo.go +++ b/internal/repo/activity/answer_repo.go @@ -22,8 +22,9 @@ package activity import ( "context" "fmt" - "github.com/segmentfault/pacman/log" "time" + + "github.com/segmentfault/pacman/log" "xorm.io/builder" "github.com/apache/answer/internal/base/constant" diff --git a/internal/repo/activity/user_active_repo.go b/internal/repo/activity/user_active_repo.go index 2452bcf83..68dfec7d7 100644 --- a/internal/repo/activity/user_active_repo.go +++ b/internal/repo/activity/user_active_repo.go @@ -22,6 +22,7 @@ package activity import ( "context" "fmt" + "xorm.io/builder" "github.com/apache/answer/internal/base/data" diff --git a/internal/repo/activity_common/vote.go b/internal/repo/activity_common/vote.go index cb7d23d00..506578424 100644 --- a/internal/repo/activity_common/vote.go +++ b/internal/repo/activity_common/vote.go @@ -21,6 +21,7 @@ package activity_common import ( "context" + "github.com/apache/answer/pkg/uid" "github.com/apache/answer/internal/base/data" diff --git a/internal/repo/auth/auth.go b/internal/repo/auth/auth.go index a1e358f9a..597352b23 100644 --- a/internal/repo/auth/auth.go +++ b/internal/repo/auth/auth.go @@ -22,6 +22,7 @@ package auth import ( "context" "encoding/json" + "github.com/apache/answer/internal/service/auth" "github.com/apache/answer/internal/base/constant" diff --git a/internal/repo/badge/badge_event_rule.go b/internal/repo/badge/badge_event_rule.go index 8c4656db3..786d988ac 100644 --- a/internal/repo/badge/badge_event_rule.go +++ b/internal/repo/badge/badge_event_rule.go @@ -21,6 +21,8 @@ package badge import ( "context" + "strconv" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/reason" @@ -29,7 +31,6 @@ import ( "github.com/apache/answer/internal/service/badge" "github.com/segmentfault/pacman/errors" "github.com/segmentfault/pacman/log" - "strconv" ) // eventRuleRepo event rule repo diff --git a/internal/repo/badge/badge_repo.go b/internal/repo/badge/badge_repo.go index 257caef81..baff45d8a 100644 --- a/internal/repo/badge/badge_repo.go +++ b/internal/repo/badge/badge_repo.go @@ -21,6 +21,7 @@ package badge import ( "context" + "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/pager" "github.com/apache/answer/internal/base/reason" diff --git a/internal/repo/badge_award/badge_award_repo.go b/internal/repo/badge_award/badge_award_repo.go index eda5d80c2..11429e570 100644 --- a/internal/repo/badge_award/badge_award_repo.go +++ b/internal/repo/badge_award/badge_award_repo.go @@ -22,6 +22,7 @@ package badge_award import ( "context" "fmt" + "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/pager" "github.com/apache/answer/internal/base/reason" diff --git a/internal/repo/badge_group/badge_group_repo.go b/internal/repo/badge_group/badge_group_repo.go index 839ba4691..8f1111a48 100644 --- a/internal/repo/badge_group/badge_group_repo.go +++ b/internal/repo/badge_group/badge_group_repo.go @@ -21,6 +21,7 @@ package badge_group import ( "context" + "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/service/badge" diff --git a/internal/repo/collection/collection_repo.go b/internal/repo/collection/collection_repo.go index a3faacdb5..f30692c97 100644 --- a/internal/repo/collection/collection_repo.go +++ b/internal/repo/collection/collection_repo.go @@ -21,6 +21,7 @@ package collection import ( "context" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/handler" diff --git a/internal/repo/export/email_repo.go b/internal/repo/export/email_repo.go index 1f8e1ce83..a3e619712 100644 --- a/internal/repo/export/email_repo.go +++ b/internal/repo/export/email_repo.go @@ -21,9 +21,10 @@ package export import ( "context" + "time" + "github.com/apache/answer/internal/base/constant" "github.com/tidwall/gjson" - "time" "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/reason" diff --git a/internal/repo/limit/limit.go b/internal/repo/limit/limit.go index 4868accd5..524ad12bc 100644 --- a/internal/repo/limit/limit.go +++ b/internal/repo/limit/limit.go @@ -22,11 +22,12 @@ package limit import ( "context" "fmt" + "time" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/reason" "github.com/segmentfault/pacman/errors" - "time" ) // LimitRepo auth repository diff --git a/internal/repo/meta/meta_repo.go b/internal/repo/meta/meta_repo.go index 9680fb419..fecd7bd5d 100644 --- a/internal/repo/meta/meta_repo.go +++ b/internal/repo/meta/meta_repo.go @@ -25,7 +25,7 @@ import ( "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/reason" "github.com/apache/answer/internal/entity" - "github.com/apache/answer/internal/service/meta_common" + metacommon "github.com/apache/answer/internal/service/meta_common" "github.com/segmentfault/pacman/errors" "xorm.io/builder" "xorm.io/xorm" diff --git a/internal/repo/plugin_config/plugin_user_config_repo.go b/internal/repo/plugin_config/plugin_user_config_repo.go index 83da8e758..d14442a56 100644 --- a/internal/repo/plugin_config/plugin_user_config_repo.go +++ b/internal/repo/plugin_config/plugin_user_config_repo.go @@ -21,6 +21,7 @@ package plugin_config import ( "context" + "github.com/apache/answer/internal/base/pager" "xorm.io/xorm" diff --git a/internal/repo/search_sync/search_sync.go b/internal/repo/search_sync/search_sync.go index 5c0adc0f9..889ffe5be 100644 --- a/internal/repo/search_sync/search_sync.go +++ b/internal/repo/search_sync/search_sync.go @@ -21,6 +21,7 @@ package search_sync import ( "context" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/entity" diff --git a/internal/repo/user_notification_config/user_notification_config_repo.go b/internal/repo/user_notification_config/user_notification_config_repo.go index 8ea2b065b..0e761514b 100644 --- a/internal/repo/user_notification_config/user_notification_config_repo.go +++ b/internal/repo/user_notification_config/user_notification_config_repo.go @@ -21,6 +21,7 @@ package user_notification_config import ( "context" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/reason" diff --git a/internal/schema/email_template.go b/internal/schema/email_template.go index 1fcdfbce3..d7e4b929a 100644 --- a/internal/schema/email_template.go +++ b/internal/schema/email_template.go @@ -21,6 +21,7 @@ package schema import ( "encoding/json" + "github.com/apache/answer/internal/base/constant" ) diff --git a/internal/schema/notification_schema.go b/internal/schema/notification_schema.go index a68328ace..e5d60615e 100644 --- a/internal/schema/notification_schema.go +++ b/internal/schema/notification_schema.go @@ -21,8 +21,9 @@ package schema import ( "encoding/json" - "github.com/apache/answer/internal/entity" "sort" + + "github.com/apache/answer/internal/entity" ) const ( diff --git a/internal/schema/user_notification_schema.go b/internal/schema/user_notification_schema.go index eca97e81c..60cc4a27b 100644 --- a/internal/schema/user_notification_schema.go +++ b/internal/schema/user_notification_schema.go @@ -21,6 +21,7 @@ package schema import ( "encoding/json" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/entity" ) diff --git a/internal/service/activity/activity.go b/internal/service/activity/activity.go index 2d384f34c..061d84493 100644 --- a/internal/service/activity/activity.go +++ b/internal/service/activity/activity.go @@ -26,7 +26,7 @@ import ( "strings" "github.com/apache/answer/internal/service/activity_common" - "github.com/apache/answer/internal/service/meta_common" + metacommon "github.com/apache/answer/internal/service/meta_common" "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/handler" diff --git a/internal/service/activity/answer_activity_service.go b/internal/service/activity/answer_activity_service.go index 169e7eb39..48b5f3ef9 100644 --- a/internal/service/activity/answer_activity_service.go +++ b/internal/service/activity/answer_activity_service.go @@ -21,6 +21,7 @@ package activity import ( "context" + "github.com/apache/answer/internal/schema" "github.com/apache/answer/internal/service/activity_type" "github.com/apache/answer/internal/service/config" diff --git a/internal/service/badge/badge_award_service.go b/internal/service/badge/badge_award_service.go index 397a7471a..982c1d1a4 100644 --- a/internal/service/badge/badge_award_service.go +++ b/internal/service/badge/badge_award_service.go @@ -21,6 +21,7 @@ package badge import ( "context" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/handler" "github.com/apache/answer/internal/base/reason" diff --git a/internal/service/badge/badge_event_handler.go b/internal/service/badge/badge_event_handler.go index 219822947..cc161f6ad 100644 --- a/internal/service/badge/badge_event_handler.go +++ b/internal/service/badge/badge_event_handler.go @@ -21,6 +21,7 @@ package badge import ( "context" + "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/schema" diff --git a/internal/service/badge/badge_group_service.go b/internal/service/badge/badge_group_service.go index e0dab6e89..7c220a0be 100644 --- a/internal/service/badge/badge_group_service.go +++ b/internal/service/badge/badge_group_service.go @@ -21,6 +21,7 @@ package badge import ( "context" + "github.com/apache/answer/internal/entity" ) diff --git a/internal/service/badge/badge_service.go b/internal/service/badge/badge_service.go index 7bc9ffe21..03b8a8774 100644 --- a/internal/service/badge/badge_service.go +++ b/internal/service/badge/badge_service.go @@ -21,6 +21,8 @@ package badge import ( "context" + "strings" + "github.com/apache/answer/internal/base/handler" "github.com/apache/answer/internal/base/reason" "github.com/apache/answer/internal/base/translator" @@ -32,7 +34,6 @@ import ( "github.com/gin-gonic/gin" "github.com/segmentfault/pacman/errors" "github.com/segmentfault/pacman/log" - "strings" ) type BadgeRepo interface { diff --git a/internal/service/content/question_hottest_service.go b/internal/service/content/question_hottest_service.go index a33b155fb..085b36709 100644 --- a/internal/service/content/question_hottest_service.go +++ b/internal/service/content/question_hottest_service.go @@ -21,11 +21,12 @@ package content import ( "context" + "math" + "time" + "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/schema" "github.com/segmentfault/pacman/log" - "math" - "time" ) func (q *QuestionService) RefreshHottestCron(ctx context.Context) { diff --git a/internal/service/content/vote_service.go b/internal/service/content/vote_service.go index ff3ee5974..92f0c9962 100644 --- a/internal/service/content/vote_service.go +++ b/internal/service/content/vote_service.go @@ -22,9 +22,10 @@ package content import ( "context" "fmt" - "github.com/apache/answer/internal/service/event_queue" "strings" + "github.com/apache/answer/internal/service/event_queue" + "github.com/apache/answer/internal/service/activity_common" "github.com/apache/answer/internal/base/constant" diff --git a/internal/service/export/email_service.go b/internal/service/export/email_service.go index b00ee093b..ddf31b348 100644 --- a/internal/service/export/email_service.go +++ b/internal/service/export/email_service.go @@ -23,12 +23,13 @@ import ( "crypto/tls" "encoding/json" "fmt" - "github.com/apache/answer/pkg/display" "mime" "os" "strings" "time" + "github.com/apache/answer/pkg/display" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/handler" "github.com/apache/answer/internal/base/reason" diff --git a/internal/service/meta/meta_service.go b/internal/service/meta/meta_service.go index 9e4f07410..4b3104197 100644 --- a/internal/service/meta/meta_service.go +++ b/internal/service/meta/meta_service.go @@ -23,10 +23,11 @@ import ( "context" "encoding/json" "errors" - "github.com/apache/answer/internal/service/event_queue" "strconv" "strings" + "github.com/apache/answer/internal/service/event_queue" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/handler" "github.com/apache/answer/internal/base/reason" diff --git a/internal/service/notification/notification_service.go b/internal/service/notification/notification_service.go index 598212aa1..09d871351 100644 --- a/internal/service/notification/notification_service.go +++ b/internal/service/notification/notification_service.go @@ -23,6 +23,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/handler" diff --git a/internal/service/permission/answer_permission.go b/internal/service/permission/answer_permission.go index 4eb563a5a..340fca8db 100644 --- a/internal/service/permission/answer_permission.go +++ b/internal/service/permission/answer_permission.go @@ -21,6 +21,7 @@ package permission import ( "context" + "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/base/handler" diff --git a/internal/service/permission/question_permission.go b/internal/service/permission/question_permission.go index b6750beae..eca0a58f2 100644 --- a/internal/service/permission/question_permission.go +++ b/internal/service/permission/question_permission.go @@ -21,6 +21,7 @@ package permission import ( "context" + "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/base/handler" diff --git a/internal/service/provider.go b/internal/service/provider.go index 4b1b64276..65535f41b 100644 --- a/internal/service/provider.go +++ b/internal/service/provider.go @@ -40,7 +40,7 @@ import ( "github.com/apache/answer/internal/service/follow" "github.com/apache/answer/internal/service/importer" "github.com/apache/answer/internal/service/meta" - "github.com/apache/answer/internal/service/meta_common" + metacommon "github.com/apache/answer/internal/service/meta_common" "github.com/apache/answer/internal/service/notice_queue" "github.com/apache/answer/internal/service/notification" notficationcommon "github.com/apache/answer/internal/service/notification_common" diff --git a/internal/service/report/report_service.go b/internal/service/report/report_service.go index 7dcc1d689..d32ccdabf 100644 --- a/internal/service/report/report_service.go +++ b/internal/service/report/report_service.go @@ -21,6 +21,7 @@ package report import ( "encoding/json" + "github.com/apache/answer/internal/service/event_queue" "github.com/apache/answer/internal/base/constant" diff --git a/internal/service/search_parser/search_parser.go b/internal/service/search_parser/search_parser.go index e87efaf6f..3e6182e15 100644 --- a/internal/service/search_parser/search_parser.go +++ b/internal/service/search_parser/search_parser.go @@ -22,10 +22,11 @@ package search_parser import ( "context" "fmt" - "github.com/apache/answer/internal/base/constant" "regexp" "strings" + "github.com/apache/answer/internal/base/constant" + "github.com/apache/answer/internal/schema" "github.com/apache/answer/internal/service/tag_common" usercommon "github.com/apache/answer/internal/service/user_common" diff --git a/internal/service/user_notification_config/user_notification_config_service.go b/internal/service/user_notification_config/user_notification_config_service.go index 7c54df0aa..01da3ee2f 100644 --- a/internal/service/user_notification_config/user_notification_config_service.go +++ b/internal/service/user_notification_config/user_notification_config_service.go @@ -21,6 +21,7 @@ package user_notification_config import ( "context" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/schema" diff --git a/pkg/converter/str.go b/pkg/converter/str.go index 5164609ca..8553975be 100644 --- a/pkg/converter/str.go +++ b/pkg/converter/str.go @@ -21,8 +21,9 @@ package converter import ( "fmt" - "github.com/segmentfault/pacman/log" "strconv" + + "github.com/segmentfault/pacman/log" ) func StringToInt64(str string) int64 { diff --git a/pkg/day/day_test.go b/pkg/day/day_test.go index 73e49aca3..4f945d88f 100644 --- a/pkg/day/day_test.go +++ b/pkg/day/day_test.go @@ -20,9 +20,10 @@ package day import ( - "github.com/stretchr/testify/assert" "testing" "time" + + "github.com/stretchr/testify/assert" ) func TestFormat(t *testing.T) { diff --git a/pkg/gravatar/gravatar_test.go b/pkg/gravatar/gravatar_test.go index bf504e68f..b88a69649 100644 --- a/pkg/gravatar/gravatar_test.go +++ b/pkg/gravatar/gravatar_test.go @@ -20,9 +20,10 @@ package gravatar import ( - "github.com/apache/answer/internal/base/constant" "testing" + "github.com/apache/answer/internal/base/constant" + "github.com/stretchr/testify/assert" ) From b54e734e60b5553353f6f1313072cf9d4be8165b Mon Sep 17 00:00:00 2001 From: shuai Date: Mon, 1 Dec 2025 11:37:48 +0800 Subject: [PATCH 16/29] fix: footer layout adjustment --- i18n/en_US.yaml | 5 +-- i18n/zh_CN.yaml | 4 +- ui/src/components/Footer/index.tsx | 56 +++++++++++++++------------- ui/src/index.scss | 2 - ui/src/pages/SideNavLayout/index.tsx | 3 +- 5 files changed, 36 insertions(+), 34 deletions(-) diff --git a/i18n/en_US.yaml b/i18n/en_US.yaml index 40017b75a..b9cbccfa9 100644 --- a/i18n/en_US.yaml +++ b/i18n/en_US.yaml @@ -1208,9 +1208,7 @@ ui: search: placeholder: Search footer: - build_on: >- - Powered by <1> Apache Answer - the open-source software that powers Q&A - communities.
Made with love © {{cc}}. + build_on: Powered by <1> Apache Answer upload_img: name: Change loading: loading... @@ -1807,6 +1805,7 @@ ui: branding: Branding legal: Legal write: Write + terms: Terms tos: Terms of Service privacy: Privacy seo: SEO diff --git a/i18n/zh_CN.yaml b/i18n/zh_CN.yaml index 0f7a25154..9d6605a1d 100644 --- a/i18n/zh_CN.yaml +++ b/i18n/zh_CN.yaml @@ -1190,8 +1190,7 @@ ui: search: placeholder: 搜索 footer: - build_on: >- - 由 <1>Apache Answer 提供动力 - 驱动问答社区的开源软件。
用爱制造 © {{cc}}. + build_on: 由 <1>Apache Answer 提供动力 upload_img: name: 更改 loading: 加载中... @@ -1768,6 +1767,7 @@ ui: branding: 品牌 legal: 法律条款 write: 撰写 + terms: 服务条款 tos: 服务条款 privacy: 隐私政策 seo: SEO diff --git a/ui/src/components/Footer/index.tsx b/ui/src/components/Footer/index.tsx index ad6e27559..340264b9b 100644 --- a/ui/src/components/Footer/index.tsx +++ b/ui/src/components/Footer/index.tsx @@ -21,6 +21,7 @@ import React from 'react'; import { Link } from 'react-router-dom'; import { Trans, useTranslation } from 'react-i18next'; +import Row from 'react-bootstrap/Row'; import dayjs from 'dayjs'; import { siteInfoStore } from '@/stores'; @@ -29,34 +30,37 @@ const Index = () => { const { t } = useTranslation('translation', { keyPrefix: 'footer' }); // Scoped translations for footer const fullYear = dayjs().format('YYYY'); const siteName = siteInfoStore((state) => state.siteInfo.name); - const cc = `${fullYear} ${siteName}`; + const cc = `${siteName} © ${fullYear}`; return ( -
-

- {/* Link to Terms of Service with right margin */} - - {t('label', { keyPrefix: 'admin.legal.terms_of_service' })} - - - {/* Link to Privacy Policy with right margin for spacing */} - - {t('label', { keyPrefix: 'admin.legal.privacy_policy' })} - -

-

- - Powered by - {/* eslint-disable-next-line react/jsx-no-target-blank */} - - Apache Answer - - - the open-source software that powers Q&A communities. -
- Made with love. © 2022 Answer. -
-

-
+ +
+
+
{cc}
+ + + {t('terms', { keyPrefix: 'nav_menus' })} + + + {/* Link to Privacy Policy with right margin for spacing */} + + {t('privacy', { keyPrefix: 'nav_menus' })} + +
+
+ + Powered by + + Apache Answer + + +
+
+
); }; diff --git a/ui/src/index.scss b/ui/src/index.scss index 92f143d5f..135261137 100644 --- a/ui/src/index.scss +++ b/ui/src/index.scss @@ -127,8 +127,6 @@ img[src=''] { margin-top: auto !important; padding-bottom: constant(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom); - padding-left: 12px !important; - padding-right: 12px !important; } .bg-f5 { diff --git a/ui/src/pages/SideNavLayout/index.tsx b/ui/src/pages/SideNavLayout/index.tsx index 0db8593e9..3ace21659 100644 --- a/ui/src/pages/SideNavLayout/index.tsx +++ b/ui/src/pages/SideNavLayout/index.tsx @@ -36,9 +36,10 @@ const Index: FC = () => {
+ +
-