diff --git a/.changeset/five-dragons-do.md b/.changeset/five-dragons-do.md new file mode 100644 index 0000000..8b5ae6f --- /dev/null +++ b/.changeset/five-dragons-do.md @@ -0,0 +1,6 @@ +--- +"frontend": minor +"backend": minor +--- + +创作时支持分类模糊搜索 diff --git a/.lintstagedrc b/.lintstagedrc index 02ca6a0..940a6cd 100644 --- a/.lintstagedrc +++ b/.lintstagedrc @@ -1,4 +1,5 @@ { - "app/**/src/**/*.{js,mjs,jsx,ts,tsx,vue}": "eslint --cache --fix", - "app/**/src/**/*.{css,less,scss,vue}": "stylelint --cache --fix" + "app/frontend/src/**/*.{js,mjs,jsx,ts,tsx,vue}": "pnpm --filter frontend lint-fix", + "app/frontend/src/**/*.{css,less,scss,vue}": "pnpm --filter frontend lint-style-fix", + "app/backend/src/**/*.{js}": "pnpm --filter backend lint-fix" } diff --git a/app/backend/src/controllers/category.js b/app/backend/src/controllers/category.js index 1c450aa..eff03c8 100644 --- a/app/backend/src/controllers/category.js +++ b/app/backend/src/controllers/category.js @@ -45,6 +45,32 @@ router.get("/count", (req, res, next) => { }); }); +/** + * 模糊查询分类 + */ +router.get("/fuzzy", async (req, res) => { + const params = req.query; + if (!params.wd) { + return res.status(400).json({ + msg: "请求有误", + }); + } + try { + const { results } = await dbUtils.query({ + sql: indexSQL.FuzzyQueryCategory, + values: [`%${params.wd}%`], + }); + res.send({ + code: "0", + data: results || [], + }); + } catch (error) { + res.send({ + code: "007005", + }); + } +}); + /** * 管理员分页获取 */ diff --git a/app/backend/src/sql/category.js b/app/backend/src/sql/category.js index 9d72e8a..213df0c 100644 --- a/app/backend/src/sql/category.js +++ b/app/backend/src/sql/category.js @@ -20,4 +20,5 @@ module.exports = { LIMIT ?, ?;\ SELECT FOUND_ROWS() AS total;", AdminUpdateCategory: "UPDATE category SET ? WHERE id = ?", + FuzzyQueryCategory: "SELECT id, category_name FROM category WHERE category_name LIKE ?", }; diff --git a/app/frontend/package.json b/app/frontend/package.json index 92127fc..2e13116 100644 --- a/app/frontend/package.json +++ b/app/frontend/package.json @@ -9,6 +9,8 @@ "test:unit": "vue-cli-service test:unit", "lint": "vue-cli-service lint --no-fix", "lint-fix": "vue-cli-service lint", + "lint-style": "stylelint src/**/*.{vue,less,scss,css} --cache", + "lint-style-fix": "stylelint src/**/*.{vue,less,scss,css} --cache --fix", "vue-ui": "vue ui", "webpack-output": "vue inspect > output.js" }, diff --git a/app/frontend/src/services/category.ts b/app/frontend/src/services/category.ts index bd30d0a..eb28f67 100644 --- a/app/frontend/src/services/category.ts +++ b/app/frontend/src/services/category.ts @@ -18,6 +18,10 @@ class CategoryService extends ApiService { public adminUpdate(params?: UpdateCategoryModel) { return this.$putJson>("admin/update", params); } + + public fuzzy(params: { wd: string }) { + return this.$get>>("fuzzy", params); + } } export const categoryService = new CategoryService("category"); diff --git a/app/frontend/src/views/backend/write/index.vue b/app/frontend/src/views/backend/write/index.vue index 97bfbd6..dbc57c5 100644 --- a/app/frontend/src/views/backend/write/index.vue +++ b/app/frontend/src/views/backend/write/index.vue @@ -77,13 +77,23 @@ - - - - {{ category.category_name }} - - - +
+ +
+ + + + {{ category.category_name }} + + + +
{{ @@ -105,6 +115,7 @@ import css from "highlight.js/lib/languages/css"; import shell from "highlight.js/lib/languages/shell"; import json from "highlight.js/lib/languages/json"; import plaintext from "highlight.js/lib/languages/plaintext"; +import yaml from "highlight.js/lib/languages/yaml"; // 皮肤 import "highlight.js/styles/atom-one-dark.css"; import DOMPurify from "dompurify"; @@ -127,6 +138,7 @@ hljs.registerLanguage("css", css); hljs.registerLanguage("shell", shell); hljs.registerLanguage("json", json); hljs.registerLanguage("plaintext", plaintext); +hljs.registerLanguage("yaml", yaml); interface NewTagDTO { value: string; @@ -144,14 +156,15 @@ export default defineComponent({ components: { PlusOutlined, DeleteOutlined, - [Form.name]: Form, - [Form.Item.name]: Form.Item, - [Input.name]: Input, - [Input.TextArea.name]: Input.TextArea, - [Radio.name]: Radio, - [Radio.Group.name]: Radio.Group, - [Modal.name]: Modal, - [Spin.name]: Spin, + [Form.name as string]: Form, + [Form.Item.name as string]: Form.Item, + [Input.name as string]: Input, + [Input.TextArea.name as string]: Input.TextArea, + [Input.Search.name as string]: Input.Search, + [Radio.name as string]: Radio, + [Radio.Group.name as string]: Radio.Group, + [Modal.name as string]: Modal, + [Spin.name as string]: Spin, }, setup() { // vuex @@ -165,6 +178,9 @@ export default defineComponent({ const formRef = ref(); const formModel = reactive({ + articleTitle: "", + summary: "", + poster: "", articleText: "", private: 0, }); @@ -315,6 +331,24 @@ export default defineComponent({ newTagList.value.splice(index, 1); }; + // 分类搜索 + const categoryWd = ref(""); + const handleSearchCategory = async () => { + if (categoryWd.value) { + const { data } = await categoryService.fuzzy({ + wd: categoryWd.value, + }); + categorys.value = data; + } else { + categorys.value = allCategorys.value; + } + }; + const { loading: categorySearchLoading, trigger: searchCategory } = useAsyncLoading(handleSearchCategory); + const throttleSearchCategory = throttle(searchCategory, 1000); + const onCategorySearchInput = () => { + throttleSearchCategory(); + }; + // 新分类处理 const newCategoryList = ref([]); @@ -344,11 +378,13 @@ export default defineComponent({ }; // 已存在的分类 - const categorys = ref([]); + const allCategorys = ref([]); + const categorys = ref[]>([]); const categoryNames = computed(() => categorys.value.map((item) => item.category_name)); const getCategorys = async () => { const res = await categoryService.all(); + allCategorys.value = res.data; categorys.value = res.data; }; @@ -460,6 +496,9 @@ export default defineComponent({ addCategory, deleteCategory, categorys, + categoryWd, + categorySearchLoading, + onCategorySearchInput, }; }, });