feat: 🚀 文章分类
This commit is contained in:
@@ -5,6 +5,10 @@ const ARTICLE_CATEGORY = `/article/category`;
|
||||
export const getArticleClassListApi = (params: any) => {
|
||||
return http.get<any>(`${ARTICLE_CATEGORY}/index`, params);
|
||||
};
|
||||
//文章分类下拉框
|
||||
export const getArticleClassApi = () => {
|
||||
return http.get<any>(`/article/categorys`);
|
||||
};
|
||||
//文章分类新增
|
||||
export const getArticleClassAddSaveApi = (params: any) => {
|
||||
return http.post<any>(`${ARTICLE_CATEGORY}/save`, params);
|
||||
@@ -15,12 +19,13 @@ export const getArticleClassDelApi = (params: any) => {
|
||||
};
|
||||
//文章分类更新(用于编辑后)
|
||||
export const getArticleClassEditUpApi = (params: any) => {
|
||||
const { id, name, sort, is_show, seo_title, seo_keywords, seo_desc } = params;
|
||||
const { id, name, sort, is_show, pid, seo_title, seo_keywords, seo_desc } = params;
|
||||
|
||||
return http.put<any>(`/article/category/update/${id}`, {
|
||||
name,
|
||||
sort,
|
||||
is_show,
|
||||
pid,
|
||||
seo_title,
|
||||
seo_keywords,
|
||||
seo_desc
|
||||
@@ -30,3 +35,7 @@ export const getArticleClassEditUpApi = (params: any) => {
|
||||
export const getArticleClassDetailsApi = (params: any) => {
|
||||
return http.get<any>(`${ARTICLE_CATEGORY}/read/${params}`);
|
||||
};
|
||||
export const getArticleClassSortApi = (params: any) => {
|
||||
const { id, sort } = params;
|
||||
return http.post<any>(`${ARTICLE_CATEGORY}/sort/${id}`, { sort });
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
:accept="fileType.join(',')"
|
||||
>
|
||||
<!-- disabled -->
|
||||
<el-input v-model="videoShowUrl" style="width: 414px" @click.stop @input="handleInput" disabled>
|
||||
<el-input v-model="videoShowUrl" style="width: 414px" @click.stop @input="handleInput">
|
||||
<template #prepend
|
||||
><el-icon :size="20" style="cursor: pointer"><FolderAdd /></el-icon
|
||||
></template>
|
||||
@@ -45,7 +45,7 @@ interface UploadFileProps {
|
||||
fileType?: any[]; //视频类型限制 ==> 非必传(默认为[".mp4", ".avi", ".mov"])
|
||||
borderRadius?: string; // 组件边框圆角 ==> 非必传(默认为 8px)
|
||||
}
|
||||
const videoShowUrl = ref(null);
|
||||
const videoShowUrl = ref<any>(null);
|
||||
// 接受父组件参数
|
||||
const props = withDefaults(defineProps<UploadFileProps>(), {
|
||||
videoUrl: "",
|
||||
@@ -98,6 +98,7 @@ const handleHttpUpload = async (options: UploadRequestOptions) => {
|
||||
};
|
||||
|
||||
const handleInput = () => {
|
||||
emit("update:videoUrl", videoShowUrl.value);
|
||||
console.log("会触发吗");
|
||||
};
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
<el-tab-pane label="问答详细" name="third">
|
||||
<div style="width: 1280px; margin: 0 auto">
|
||||
<WangEditor v-model:value="dataStore.value" />
|
||||
<WangEditor v-model:value="dataStore.editRuleForm.answer" />
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
@@ -40,7 +40,7 @@ const $route = useRoute();
|
||||
const activeName = ref("basicInfo");
|
||||
//数据集合
|
||||
const dataStore = reactive<any>({
|
||||
value: "",
|
||||
// value: "",
|
||||
editRuleForm: cloneDeep(EDIT_RULE_FORM),
|
||||
editFormData: cloneDeep(EDIT_FORM_DATA),
|
||||
rules: RULES
|
||||
@@ -58,12 +58,14 @@ const getQAListDetails = async () => {
|
||||
const { data } = result;
|
||||
//这里是传给基本信息组件的表单数据
|
||||
dataStore.editRuleForm = cloneDeep(data);
|
||||
dataStore.value = data.answer;
|
||||
}
|
||||
};
|
||||
getQAListDetails();
|
||||
|
||||
//更新
|
||||
const getQAListEditUp = async () => {
|
||||
// dataStore.editRuleForm.answer = dataStore.value;
|
||||
const result: any = await getQAListEditUpApi(dataStore.editRuleForm);
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
@@ -72,6 +74,7 @@ const getQAListEditUp = async () => {
|
||||
};
|
||||
//新增 getQAListSaveApi
|
||||
const getQAListSave = async () => {
|
||||
// dataStore.editRuleForm.answer = dataStore.value;
|
||||
const result: any = await getQAListSaveApi(dataStore.editRuleForm);
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
@@ -88,6 +91,10 @@ const handleReset = () => {
|
||||
const resetFields = () => {
|
||||
if (!formRef.value!.ruleFormRef) return;
|
||||
formRef!.value!.ruleFormRef.resetFields();
|
||||
for (let key in dataStore.editRuleForm) {
|
||||
dataStore.editRuleForm[key] = "";
|
||||
}
|
||||
// dataStore.value = "";
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
|
||||
@@ -46,34 +46,20 @@ export const EDIT_FORM_DATA: FormItem[] = [
|
||||
value: 0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
prop: "pid",
|
||||
placeholder: "请选择",
|
||||
type: "treeSelect",
|
||||
label: "所属分类: ",
|
||||
options: []
|
||||
}
|
||||
|
||||
// {
|
||||
// prop: "seo_title",
|
||||
// placeholder: "请输入",
|
||||
// type: "input",
|
||||
// label: "SEO标题: "
|
||||
// },
|
||||
// {
|
||||
// prop: "seo_keywords",
|
||||
// placeholder: "请输入",
|
||||
// type: "input",
|
||||
// label: "SEO关键词: "
|
||||
// },
|
||||
// {
|
||||
// prop: "seo_desc",
|
||||
// placeholder: "请输入",
|
||||
// type: "input",
|
||||
// label: "SEO描述: "
|
||||
// }
|
||||
];
|
||||
export const EDIT_RULE_FORM = {
|
||||
is_show: 1,
|
||||
seo_desc: "",
|
||||
seo_keywords: "",
|
||||
seo_title: "",
|
||||
sort: 1,
|
||||
name: ""
|
||||
name: "",
|
||||
pid: 0
|
||||
};
|
||||
// editRuleForm: {},
|
||||
//editFormData: [],
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export const RULES = {
|
||||
name: [{ required: true, message: "文章分类名称不能为空 ! ", trigger: "blur" }],
|
||||
sort: [{ required: true, message: "文章分类排序不能为空 ! ", trigger: "blur" }]
|
||||
sort: [{ required: true, message: "文章分类排序不能为空 ! ", trigger: "blur" }],
|
||||
pid: [{ required: true, message: "所属分类不能为空 ! ", trigger: "blur" }]
|
||||
};
|
||||
|
||||
@@ -26,6 +26,6 @@ export const FORM_DATA: FormItem[] = [
|
||||
];
|
||||
|
||||
export const RULE_FORM = {
|
||||
page: 1,
|
||||
size: 50
|
||||
// page: 1,
|
||||
// size: 50
|
||||
};
|
||||
|
||||
@@ -32,7 +32,5 @@ export const COLUMNS = [
|
||||
render: (scope: RenderScope<any>): VNode | string | any => {
|
||||
return YES_OR_NO[scope.row.is_show];
|
||||
}
|
||||
},
|
||||
|
||||
{ prop: "operation", label: "操作", fixed: "right", width: 300 }
|
||||
}
|
||||
];
|
||||
|
||||
@@ -4,24 +4,45 @@
|
||||
<div style="padding-bottom: 16px">
|
||||
<el-button type="primary" @click="handleAdd"> 添加 </el-button>
|
||||
</div>
|
||||
<ProTable
|
||||
ref="proTableRef"
|
||||
:formData="dataStore.formData"
|
||||
:columns="dataStore.columns"
|
||||
:request-api="getArticleClassListApi"
|
||||
:init-param="dataStore.initParam"
|
||||
>
|
||||
<template #operation="scope">
|
||||
<el-button
|
||||
size="small"
|
||||
v-for="(item, index) in dataStore.btns"
|
||||
:key="index"
|
||||
:type="item.btnType"
|
||||
@click="handleBtnClick(item.type, scope.row)"
|
||||
>{{ item.name }}</el-button
|
||||
>
|
||||
</template>
|
||||
</ProTable>
|
||||
<div class="card table-main">
|
||||
<SearchForm :search="search" :reset="reset" :formData="dataStore.formData" :search-param="dataStore.ruleForm" />
|
||||
<el-table
|
||||
:data="dataStore.tableData"
|
||||
style="width: 100%; margin-bottom: 20px; font-size: 14px"
|
||||
row-key="id"
|
||||
border
|
||||
default-expand-all
|
||||
>
|
||||
<el-table-column prop="id" label="id" />
|
||||
<el-table-column prop="name" label="分类名称" />
|
||||
<el-table-column prop="sort" label="分类排序">
|
||||
<template #default="{ row }">
|
||||
<div @click.stop="">
|
||||
<el-input v-model="row.sort" @blur="handleBlur(row)" @input="handleInput(row)" />
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="is_show" label="是否显示">
|
||||
<template #default="{ row }">
|
||||
{{ row.is_show === 1 ? "✔️" : "❌" }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <template #default="scope"> -->
|
||||
<el-table-column label="操作" :width="240">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
size="small"
|
||||
v-for="(item, index) in dataStore.btns"
|
||||
:key="index"
|
||||
:type="item.btnType"
|
||||
@click="handleBtnClick(item.type, scope.row)"
|
||||
>{{ item.name }}</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<el-drawer
|
||||
v-model="dataStore.visible"
|
||||
:show-close="true"
|
||||
@@ -40,6 +61,7 @@
|
||||
:formData="dataStore.editFormData"
|
||||
:rules="dataStore.rules"
|
||||
ref="formRef"
|
||||
@handleSelectChangeEmits="handleSelectChangeEmits"
|
||||
/>
|
||||
</div>
|
||||
<template #footer>
|
||||
@@ -54,7 +76,8 @@
|
||||
|
||||
<script setup lang="ts" name="articleClassListIndex">
|
||||
import rulesForm from "@/components/rulesForm/index.vue";
|
||||
import ProTable from "@/components/ProTable/index.vue";
|
||||
import { integerRexg } from "@/utils/regexp/index";
|
||||
// import ProTable from "@/components/ProTable/index.vue";
|
||||
import { messageBox } from "@/utils/messageBox";
|
||||
import { useMsg } from "@/hooks/useMsg";
|
||||
//列表接口
|
||||
@@ -63,14 +86,15 @@ import {
|
||||
getArticleClassAddSaveApi,
|
||||
getArticleClassDelApi,
|
||||
getArticleClassEditUpApi,
|
||||
getArticleClassDetailsApi
|
||||
getArticleClassDetailsApi,
|
||||
getArticleClassApi,
|
||||
getArticleClassSortApi
|
||||
} from "@/api/modules/articleClass";
|
||||
//深拷贝方法
|
||||
import { cloneDeep } from "lodash-es";
|
||||
//表格和搜索條件
|
||||
import { RULE_FORM, FORM_DATA, COLUMNS, EDIT_FORM_DATA, EDIT_RULE_FORM, RULES, BTNS } from "./constant/index";
|
||||
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
|
||||
const proTableRef = ref<any>(null);
|
||||
|
||||
const formRef: any = ref(null);
|
||||
const $router = useRouter();
|
||||
// 数据源
|
||||
@@ -85,9 +109,71 @@ const dataStore = reactive<any>({
|
||||
formData: FORM_DATA, //搜索配置项
|
||||
visible: false,
|
||||
btns: BTNS,
|
||||
tableData: [],
|
||||
selectRow: {} //当前选择的row
|
||||
});
|
||||
const getArticleClassSort = async (row: any) => {
|
||||
const result = await getArticleClassSortApi(row);
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
getArticleClassList();
|
||||
}
|
||||
};
|
||||
//排序input框失焦
|
||||
const handleBlur = (row: any) => {
|
||||
getArticleClassSort(row);
|
||||
};
|
||||
//
|
||||
const handleInput = (row: any) => {
|
||||
row.sort = integerRexg(row.sort);
|
||||
};
|
||||
|
||||
const search = () => {
|
||||
getArticleClassList();
|
||||
};
|
||||
const reset = () => {
|
||||
for (let key in dataStore.ruleForm) {
|
||||
dataStore.ruleForm[key] = "";
|
||||
}
|
||||
getArticleClassList();
|
||||
};
|
||||
|
||||
const addLabelValue = (arr: any) => {
|
||||
return arr.map((item: any) => {
|
||||
// 为当前对象添加 label 和 value 属性
|
||||
const newItem = { ...item };
|
||||
newItem.label = newItem.name;
|
||||
newItem.value = newItem.id;
|
||||
|
||||
// 如果有子对象,递归调用 addLabelValue 处理子对象
|
||||
if (newItem.children && Array.isArray(newItem.children)) {
|
||||
newItem.children = addLabelValue(newItem.children);
|
||||
}
|
||||
return newItem;
|
||||
});
|
||||
};
|
||||
|
||||
const handleSelectChangeEmits = (params: any) => {
|
||||
const { id } = params;
|
||||
dataStore.editRuleForm.pid = id;
|
||||
};
|
||||
|
||||
const getArticleClass = async () => {
|
||||
const result = await getArticleClassApi();
|
||||
if (result?.code === 0) {
|
||||
dataStore.editFormData[3].options = addLabelValue(result?.data);
|
||||
dataStore.editFormData[3].options.unshift({ value: 0, label: "无" });
|
||||
console.log(result?.data);
|
||||
}
|
||||
};
|
||||
getArticleClass();
|
||||
const getArticleClassList = async () => {
|
||||
const result = await getArticleClassListApi(dataStore.ruleForm);
|
||||
if (result?.code === 0) {
|
||||
dataStore.tableData = result?.data;
|
||||
}
|
||||
};
|
||||
getArticleClassList();
|
||||
//新增文章接口
|
||||
const getArticleClassAddSave = async () => {
|
||||
const result = await getArticleClassAddSaveApi(dataStore.editRuleForm);
|
||||
@@ -96,18 +182,20 @@ const getArticleClassAddSave = async () => {
|
||||
useMsg("success", msg);
|
||||
dataStore.visible = false;
|
||||
dataStore.editRuleForm = cloneDeep(EDIT_RULE_FORM);
|
||||
proTableRef?.value?.getTableList();
|
||||
getArticleClassList();
|
||||
}
|
||||
};
|
||||
//文章编辑
|
||||
const getArticleClassUpEdit = async () => {
|
||||
console.log("编辑");
|
||||
const result = await getArticleClassEditUpApi(dataStore.editRuleForm);
|
||||
const { msg, code } = result;
|
||||
|
||||
if (code === 0) {
|
||||
useMsg("success", msg);
|
||||
dataStore.visible = false;
|
||||
proTableRef?.value?.getTableList();
|
||||
dataStore.editRuleForm = cloneDeep(EDIT_RULE_FORM);
|
||||
getArticleClassList();
|
||||
}
|
||||
};
|
||||
//删除文章
|
||||
@@ -117,7 +205,7 @@ const getArticleClassDel = (row: any) => {
|
||||
const { msg, code } = result;
|
||||
if (code === 0) {
|
||||
useMsg("success", msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
getArticleClassList();
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -141,12 +229,16 @@ const resetFields = () => {
|
||||
};
|
||||
//抽屉重置
|
||||
const handleResetClick = () => {
|
||||
resetFields();
|
||||
getArticleClassDetails(dataStore.selectRow);
|
||||
if (dataStore.title == "添加文章分类") {
|
||||
resetFields();
|
||||
} else {
|
||||
getArticleClassDetails(dataStore.selectRow);
|
||||
}
|
||||
};
|
||||
|
||||
//添加
|
||||
const handleAdd = () => {
|
||||
dataStore.title = "添加文章分类";
|
||||
dataStore.visible = true;
|
||||
};
|
||||
//弹窗关闭钩子
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export const RULES = {
|
||||
title: [{ required: true, message: "Banner名称不能为空 ! ", trigger: "blur" }],
|
||||
type: [{ required: true, message: "前台显示不能为空 ! ", trigger: "change" }],
|
||||
image: [{ required: true, message: "Banner图片不能为空 ! ", trigger: "change" }],
|
||||
// image: [{ required: true, message: "Banner图片不能为空 ! ", trigger: "change" }],
|
||||
banner_id: [{ required: true, message: "Banner分类不能为空 ! ", trigger: "change" }],
|
||||
sort: [{ required: true, message: "排序不能为空 ! ", trigger: "change" }]
|
||||
};
|
||||
|
||||
@@ -4,7 +4,6 @@ const YES_OR_NO: any = {
|
||||
0: "❌"
|
||||
};
|
||||
export const COLUMNS = [
|
||||
{ type: "selection", fixed: "left", width: 40 },
|
||||
{
|
||||
align: "center",
|
||||
fixed: true,
|
||||
|
||||
Reference in New Issue
Block a user