2025-03-26
This commit is contained in:
60
src/views/QAManagement/list/constant/edit.ts
Normal file
60
src/views/QAManagement/list/constant/edit.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
disabled?: boolean;
|
||||
fileList?: any;
|
||||
prompt?: any;
|
||||
}
|
||||
export const EDIT_FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "question",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "标题: "
|
||||
},
|
||||
{
|
||||
prop: "image",
|
||||
type: "upImg",
|
||||
placeholder: "请输入",
|
||||
label: "图片: "
|
||||
},
|
||||
|
||||
{
|
||||
prop: "recommend",
|
||||
placeholder: "",
|
||||
type: "radio",
|
||||
label: "首页推荐: ",
|
||||
options: [
|
||||
{
|
||||
label: "是",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: "否",
|
||||
value: 0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
prop: "sort",
|
||||
placeholder: "请输入",
|
||||
type: "inputNumber",
|
||||
label: "问答排序: "
|
||||
}
|
||||
];
|
||||
export const EDIT_RULE_FORM = {
|
||||
sort: 1
|
||||
};
|
||||
5
src/views/QAManagement/list/constant/index.ts
Normal file
5
src/views/QAManagement/list/constant/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { FORM_DATA, RULE_FORM } from "./search";
|
||||
import { COLUMNS } from "./table";
|
||||
import { EDIT_FORM_DATA, EDIT_RULE_FORM } from "./edit";
|
||||
import { RULES } from "./rules";
|
||||
export { FORM_DATA, RULE_FORM, COLUMNS, EDIT_FORM_DATA, EDIT_RULE_FORM, RULES };
|
||||
5
src/views/QAManagement/list/constant/rules.ts
Normal file
5
src/views/QAManagement/list/constant/rules.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export const RULES = {
|
||||
question: [{ required: true, message: "标题不能为空 ! ", trigger: "blur" }],
|
||||
sort: [{ required: true, message: "问答排序不能为空 ! ", trigger: "change" }],
|
||||
image: [{ required: true, message: "图片不能为空 ! ", trigger: "change" }]
|
||||
};
|
||||
42
src/views/QAManagement/list/constant/search.ts
Normal file
42
src/views/QAManagement/list/constant/search.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
}
|
||||
export const FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "question",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
isArray: true,
|
||||
label: "标题: "
|
||||
},
|
||||
|
||||
{
|
||||
prop: "Time",
|
||||
type: "daterange",
|
||||
options: [],
|
||||
startPlaceholder: "开始日期",
|
||||
endPlaceholder: "结束日期",
|
||||
startDate: "created_at",
|
||||
// endDate: "createEndDate",
|
||||
label: "添加时间: "
|
||||
}
|
||||
];
|
||||
|
||||
export const RULE_FORM = {
|
||||
page: 1,
|
||||
size: 50
|
||||
};
|
||||
48
src/views/QAManagement/list/constant/table.ts
Normal file
48
src/views/QAManagement/list/constant/table.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { RenderScope } from "@/components/ProTable/interface";
|
||||
const YES_OR_NO: any = {
|
||||
1: "✔️",
|
||||
0: "❌"
|
||||
};
|
||||
export const COLUMNS = [
|
||||
{ type: "selection", fixed: "left", width: 40 },
|
||||
{
|
||||
align: "center",
|
||||
fixed: true,
|
||||
label: "ID",
|
||||
prop: "id",
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
align: "center",
|
||||
label: "图片",
|
||||
prop: "image",
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "标题",
|
||||
prop: "question"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "首页显示",
|
||||
prop: "recommend",
|
||||
render: (scope: RenderScope<any>): VNode | string | any => {
|
||||
return YES_OR_NO[scope.row.recommend];
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
align: "left",
|
||||
label: "问答排序",
|
||||
prop: "sort"
|
||||
},
|
||||
|
||||
{
|
||||
align: "center",
|
||||
label: "添加时间",
|
||||
prop: "created_at"
|
||||
},
|
||||
|
||||
{ prop: "operation", label: "操作", fixed: "right", width: 300 }
|
||||
];
|
||||
107
src/views/QAManagement/list/edit.vue
Normal file
107
src/views/QAManagement/list/edit.vue
Normal file
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<!-- style="margin-bottom: 16px" -->
|
||||
|
||||
<div class="table-box">
|
||||
<div style="padding-bottom: 16px">
|
||||
<el-button @click="handleReset"> 重置 </el-button>
|
||||
<el-button type="primary" @click="handleSubmit"> 提交 </el-button>
|
||||
</div>
|
||||
<div class="card table-main">
|
||||
<el-tabs v-model="activeName" class="demo-tabs">
|
||||
<el-tab-pane label="基本信息" name="basicInfo">
|
||||
<rulesForm
|
||||
:ruleForm="dataStore.editRuleForm"
|
||||
:formData="dataStore.editFormData"
|
||||
:rules="dataStore.rules"
|
||||
ref="formRef"
|
||||
>
|
||||
</rulesForm>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="问答详细" name="third">
|
||||
<div style="width: 1280px; margin: 0 auto">
|
||||
<WangEditor v-model:value="dataStore.value" />
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="QAManagementListEdit">
|
||||
import rulesForm from "@/components/rulesForm/index.vue";
|
||||
import { getQAListDetailsApi, getQAListEditUpApi, getQAListSaveApi } from "@/api/modules/QAList";
|
||||
import { ref, reactive } from "vue";
|
||||
import WangEditor from "@/components/WangEditor/index.vue";
|
||||
import { useMsg } from "@/hooks/useMsg";
|
||||
import { EDIT_FORM_DATA, EDIT_RULE_FORM, RULES } from "./constant/index";
|
||||
import { cloneDeep } from "lodash-es";
|
||||
const $route = useRoute();
|
||||
const activeName = ref("basicInfo");
|
||||
//数据集合
|
||||
const dataStore = reactive<any>({
|
||||
value: "",
|
||||
editRuleForm: cloneDeep(EDIT_RULE_FORM),
|
||||
editFormData: cloneDeep(EDIT_FORM_DATA),
|
||||
rules: RULES
|
||||
});
|
||||
const formRef: any = ref(null);
|
||||
//详情
|
||||
const getQAListDetails = async () => {
|
||||
let id = $route.query.id;
|
||||
console.log(id, "=========id========");
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
const result = await getQAListDetailsApi(id);
|
||||
if (result?.code === 0) {
|
||||
const { data } = result;
|
||||
//这里是传给基本信息组件的表单数据
|
||||
dataStore.editRuleForm = cloneDeep(data);
|
||||
}
|
||||
};
|
||||
getQAListDetails();
|
||||
|
||||
//更新
|
||||
const getQAListEditUp = async () => {
|
||||
const result: any = await getQAListEditUpApi(dataStore.editRuleForm);
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
// dataStore.editRuleForm = result?.data;
|
||||
}
|
||||
};
|
||||
//新增 getQAListSaveApi
|
||||
const getQAListSave = async () => {
|
||||
const result: any = await getQAListSaveApi(dataStore.editRuleForm);
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
}
|
||||
};
|
||||
const handleReset = () => {
|
||||
if ($route.query.id) {
|
||||
getQAListDetails();
|
||||
} else {
|
||||
resetFields();
|
||||
}
|
||||
};
|
||||
//重置验证状态
|
||||
const resetFields = () => {
|
||||
if (!formRef.value!.ruleFormRef) return;
|
||||
formRef!.value!.ruleFormRef.resetFields();
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (!formRef.value!.ruleFormRef) return;
|
||||
formRef!.value!.ruleFormRef!.validate((valid: any) => {
|
||||
if (valid) {
|
||||
$route.query.id ? getQAListEditUp() : getQAListSave();
|
||||
console.log("submit!");
|
||||
} else {
|
||||
console.log("error submit!");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
99
src/views/QAManagement/list/index.vue
Normal file
99
src/views/QAManagement/list/index.vue
Normal file
@@ -0,0 +1,99 @@
|
||||
<!-- QA列表 -->
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<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="getQAListApi"
|
||||
:init-param="dataStore.initParam"
|
||||
>
|
||||
<template #sort="scope">
|
||||
<el-input v-model="scope.row.sort" @blur="handleBlur(scope.row)" @input="handleInput(scope.row)"></el-input>
|
||||
</template>
|
||||
<template #image="scope">
|
||||
<el-image :src="h + scope.row.image" style="width: 60px; height: 60px" />
|
||||
</template>
|
||||
|
||||
<template #operation="scope">
|
||||
<el-button size="small" type="primary" @click="handleToDetails(scope.row.id)">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click="getQADel(scope.row.id)">删除</el-button>
|
||||
</template>
|
||||
</ProTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="QAListIndex">
|
||||
import ProTable from "@/components/ProTable/index.vue";
|
||||
const h = import.meta.env.VITE_APP_API_BASE_UPLOAD_URL;
|
||||
import { useMsg } from "@/hooks/useMsg";
|
||||
import { integerRexg } from "@/utils/regexp/index";
|
||||
import { messageBox } from "@/utils/messageBox";
|
||||
//列表接口
|
||||
import { getQAListApi, getQASortApi, getQAListDelApi } from "@/api/modules/QAList";
|
||||
//深拷贝方法
|
||||
import { cloneDeep } from "lodash-es";
|
||||
//表格和搜索條件
|
||||
import { RULE_FORM, FORM_DATA, COLUMNS } from "./constant/index";
|
||||
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
|
||||
const proTableRef = ref<any>(null);
|
||||
const $router = useRouter();
|
||||
// 数据源
|
||||
const dataStore = reactive<any>({
|
||||
columns: COLUMNS, //列表配置项
|
||||
initParam: cloneDeep(RULE_FORM), // 初始化搜索条件|重置搜索条件
|
||||
ruleForm: cloneDeep(RULE_FORM), // 搜索參數
|
||||
formData: FORM_DATA //搜索配置项
|
||||
});
|
||||
//详情
|
||||
const handleToDetails = async (id: any) => {
|
||||
$router.push({
|
||||
path: "/admin/QAManagement/list/edit",
|
||||
query: {
|
||||
id,
|
||||
title: "编辑问答"
|
||||
}
|
||||
});
|
||||
};
|
||||
//添加
|
||||
const handleAdd = async () => {
|
||||
$router.push({
|
||||
path: "/admin/QAManagement/list/edit",
|
||||
query: {
|
||||
title: "添加问答"
|
||||
}
|
||||
});
|
||||
};
|
||||
//排序
|
||||
const getQASort = async (row: any) => {
|
||||
const result = await getQASortApi({ id: row.id, sort: row.sort });
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
};
|
||||
//删除
|
||||
const getQADel = async (id: any) => {
|
||||
messageBox("你确定要删除?", async () => {
|
||||
const result = await getQAListDelApi(id);
|
||||
if (result?.code === 0) {
|
||||
const { msg } = result;
|
||||
useMsg("success", msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
});
|
||||
};
|
||||
//排序input框失焦
|
||||
const handleBlur = (row: any) => {
|
||||
getQASort(row);
|
||||
};
|
||||
//排序input输入
|
||||
const handleInput = (row: any) => {
|
||||
row.sort = integerRexg(row.sort);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
5
src/views/articleManagement/class/constant/btns.ts
Normal file
5
src/views/articleManagement/class/constant/btns.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export const BTNS = [
|
||||
{ name: "编辑", type: "edit", btnType: "primary" },
|
||||
{ name: "添加文章", type: "add", btnType: "primary" },
|
||||
{ name: "删除", type: "del", btnType: "danger" }
|
||||
];
|
||||
79
src/views/articleManagement/class/constant/edit.ts
Normal file
79
src/views/articleManagement/class/constant/edit.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
disabled?: boolean;
|
||||
fileList?: any;
|
||||
}
|
||||
export const EDIT_FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "name",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "文章分类名称: "
|
||||
},
|
||||
|
||||
{
|
||||
prop: "sort",
|
||||
placeholder: "请输入",
|
||||
type: "inputNumber",
|
||||
label: "文章分类排序: "
|
||||
},
|
||||
{
|
||||
prop: "is_show",
|
||||
placeholder: "请输入",
|
||||
type: "radio",
|
||||
label: "是否显示: ",
|
||||
options: [
|
||||
{
|
||||
label: "是",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: "否",
|
||||
value: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// {
|
||||
// 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: ""
|
||||
};
|
||||
// editRuleForm: {},
|
||||
//editFormData: [],
|
||||
6
src/views/articleManagement/class/constant/index.ts
Normal file
6
src/views/articleManagement/class/constant/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { FORM_DATA, RULE_FORM } from "./search";
|
||||
import { COLUMNS } from "./table";
|
||||
import { RULES } from "./rules";
|
||||
import { EDIT_FORM_DATA, EDIT_RULE_FORM } from "./edit";
|
||||
import { BTNS } from "./btns";
|
||||
export { FORM_DATA, RULE_FORM, COLUMNS, EDIT_FORM_DATA, EDIT_RULE_FORM, RULES, BTNS };
|
||||
4
src/views/articleManagement/class/constant/rules.ts
Normal file
4
src/views/articleManagement/class/constant/rules.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export const RULES = {
|
||||
name: [{ required: true, message: "文章分类名称不能为空 ! ", trigger: "blur" }],
|
||||
sort: [{ required: true, message: "文章分类排序不能为空 ! ", trigger: "blur" }]
|
||||
};
|
||||
31
src/views/articleManagement/class/constant/search.ts
Normal file
31
src/views/articleManagement/class/constant/search.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
}
|
||||
export const FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "name",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
isArray: true,
|
||||
label: "文章分类名称: "
|
||||
}
|
||||
];
|
||||
|
||||
export const RULE_FORM = {
|
||||
page: 1,
|
||||
size: 50
|
||||
};
|
||||
38
src/views/articleManagement/class/constant/table.ts
Normal file
38
src/views/articleManagement/class/constant/table.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { RenderScope } from "@/components/ProTable/interface";
|
||||
|
||||
const YES_OR_NO: any = {
|
||||
1: "✔️",
|
||||
0: "❌"
|
||||
};
|
||||
|
||||
export const COLUMNS = [
|
||||
{
|
||||
align: "center",
|
||||
fixed: true,
|
||||
label: "ID",
|
||||
prop: "id",
|
||||
width: 80
|
||||
},
|
||||
|
||||
{
|
||||
align: "left",
|
||||
label: "文章分类名称",
|
||||
prop: "name"
|
||||
},
|
||||
|
||||
{
|
||||
align: "left",
|
||||
label: "文章分类排序",
|
||||
prop: "sort"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "是否显示",
|
||||
prop: "is_show",
|
||||
render: (scope: RenderScope<any>): VNode | string | any => {
|
||||
return YES_OR_NO[scope.row.is_show];
|
||||
}
|
||||
},
|
||||
|
||||
{ prop: "operation", label: "操作", fixed: "right", width: 300 }
|
||||
];
|
||||
194
src/views/articleManagement/class/index.vue
Normal file
194
src/views/articleManagement/class/index.vue
Normal file
@@ -0,0 +1,194 @@
|
||||
<!-- 文章分类 -->
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<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>
|
||||
<el-drawer
|
||||
v-model="dataStore.visible"
|
||||
:show-close="true"
|
||||
:size="600"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
:before-close="handleBeforeClone"
|
||||
destroy-on-close
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<h4 :id="titleId" :class="titleClass">{{ dataStore.title }}</h4>
|
||||
</template>
|
||||
<div>
|
||||
<rulesForm
|
||||
:ruleForm="dataStore.editRuleForm"
|
||||
:formData="dataStore.editFormData"
|
||||
:rules="dataStore.rules"
|
||||
ref="formRef"
|
||||
/>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div style="flex: auto">
|
||||
<el-button @click="handleResetClick">重置</el-button>
|
||||
<el-button type="primary" @click="handleConfirmClick">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="articleClassListIndex">
|
||||
import rulesForm from "@/components/rulesForm/index.vue";
|
||||
import ProTable from "@/components/ProTable/index.vue";
|
||||
import { messageBox } from "@/utils/messageBox";
|
||||
import { useMsg } from "@/hooks/useMsg";
|
||||
//列表接口
|
||||
import {
|
||||
getArticleClassListApi,
|
||||
getArticleClassAddSaveApi,
|
||||
getArticleClassDelApi,
|
||||
getArticleClassEditUpApi,
|
||||
getArticleClassDetailsApi
|
||||
} 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();
|
||||
// 数据源
|
||||
const dataStore = reactive<any>({
|
||||
title: "添加文章分类",
|
||||
columns: COLUMNS, //列表配置项
|
||||
rules: cloneDeep(RULES), //抽屉表单验证
|
||||
editRuleForm: cloneDeep(EDIT_RULE_FORM),
|
||||
editFormData: cloneDeep(EDIT_FORM_DATA), //抽屉表单配置项
|
||||
initParam: cloneDeep(RULE_FORM), // 初始化搜索条件|重置搜索条件
|
||||
ruleForm: cloneDeep(RULE_FORM), // 搜索參數
|
||||
formData: FORM_DATA, //搜索配置项
|
||||
visible: false,
|
||||
btns: BTNS,
|
||||
selectRow: {} //当前选择的row
|
||||
});
|
||||
|
||||
//新增文章接口
|
||||
const getArticleClassAddSave = async () => {
|
||||
const result = await getArticleClassAddSaveApi(dataStore.editRuleForm);
|
||||
const { msg, code } = result;
|
||||
if (code === 0) {
|
||||
useMsg("success", msg);
|
||||
dataStore.visible = false;
|
||||
dataStore.editRuleForm = cloneDeep(EDIT_RULE_FORM);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
};
|
||||
//文章编辑
|
||||
const getArticleClassUpEdit = async () => {
|
||||
const result = await getArticleClassEditUpApi(dataStore.editRuleForm);
|
||||
const { msg, code } = result;
|
||||
|
||||
if (code === 0) {
|
||||
useMsg("success", msg);
|
||||
dataStore.visible = false;
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
};
|
||||
//删除文章
|
||||
const getArticleClassDel = (row: any) => {
|
||||
messageBox("你确定要删除?", async () => {
|
||||
const result = await getArticleClassDelApi(row.id);
|
||||
const { msg, code } = result;
|
||||
if (code === 0) {
|
||||
useMsg("success", msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
});
|
||||
};
|
||||
//抽屉确认
|
||||
const handleConfirmClick = () => {
|
||||
if (!formRef.value!.ruleFormRef) return;
|
||||
formRef!.value!.ruleFormRef!.validate((valid: any) => {
|
||||
if (valid) {
|
||||
dataStore.title === "添加文章分类" ? getArticleClassAddSave() : getArticleClassUpEdit();
|
||||
} else {
|
||||
console.log("error submit!");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
//重置验证状态
|
||||
const resetFields = () => {
|
||||
if (!formRef.value!.ruleFormRef) return;
|
||||
formRef!.value!.ruleFormRef.resetFields();
|
||||
dataStore.editRuleForm = cloneDeep(EDIT_RULE_FORM);
|
||||
};
|
||||
//抽屉重置
|
||||
const handleResetClick = () => {
|
||||
resetFields();
|
||||
getArticleClassDetails(dataStore.selectRow);
|
||||
};
|
||||
|
||||
//添加
|
||||
const handleAdd = () => {
|
||||
dataStore.visible = true;
|
||||
};
|
||||
//弹窗关闭钩子
|
||||
const handleBeforeClone = () => {
|
||||
dataStore.editRuleForm = cloneDeep(EDIT_RULE_FORM);
|
||||
resetFields();
|
||||
dataStore.visible = false;
|
||||
};
|
||||
//文章分类详情
|
||||
const getArticleClassDetails = async (row: any) => {
|
||||
const result = await getArticleClassDetailsApi(row.id);
|
||||
const { code, data } = result;
|
||||
if (code === 0) {
|
||||
dataStore.editRuleForm = cloneDeep(data);
|
||||
}
|
||||
};
|
||||
//按钮点击事件
|
||||
const handleBtnClick = (type: any, row: any) => {
|
||||
dataStore.selectRow = row;
|
||||
//添加
|
||||
if (type === "add") {
|
||||
$router.push({
|
||||
path: "/admin/articleManagement/list/edit",
|
||||
query: {
|
||||
type,
|
||||
title: "添加文章",
|
||||
category_id: row.id
|
||||
}
|
||||
});
|
||||
}
|
||||
//编辑
|
||||
if (type === "edit") {
|
||||
dataStore.visible = true;
|
||||
dataStore.title = "编辑文章分类";
|
||||
getArticleClassDetails(row);
|
||||
return;
|
||||
}
|
||||
//删除
|
||||
if (type === "del") {
|
||||
getArticleClassDel(row);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
112
src/views/articleManagement/list/constant/edit.ts
Normal file
112
src/views/articleManagement/list/constant/edit.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
disabled?: boolean;
|
||||
fileList?: any;
|
||||
prompt?: any;
|
||||
}
|
||||
export const EDIT_FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "title",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "文章名称: "
|
||||
},
|
||||
|
||||
{
|
||||
prop: "category_id",
|
||||
placeholder: "请选择",
|
||||
type: "treeSelect",
|
||||
label: "文章分类: ",
|
||||
options: []
|
||||
},
|
||||
{
|
||||
prop: "sort",
|
||||
placeholder: "请输入",
|
||||
type: "inputNumber",
|
||||
label: "文章排序: "
|
||||
},
|
||||
{
|
||||
prop: "recommend",
|
||||
placeholder: "请选择",
|
||||
type: "radio",
|
||||
label: "首页推荐: ",
|
||||
options: [
|
||||
{
|
||||
label: "是",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: "否",
|
||||
value: 0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
prop: "link",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "跳转链接: "
|
||||
},
|
||||
{
|
||||
prop: "desc",
|
||||
placeholder: "请输入",
|
||||
type: "textarea",
|
||||
label: "文章描述: "
|
||||
},
|
||||
{
|
||||
prop: "release_time",
|
||||
placeholder: "请选择",
|
||||
type: "datetime",
|
||||
label: "发布时间: "
|
||||
},
|
||||
{
|
||||
prop: "image",
|
||||
type: "upImg",
|
||||
label: "封面图: ",
|
||||
prompt: "图片尺寸320x320"
|
||||
},
|
||||
|
||||
{
|
||||
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 = {
|
||||
category_id: "",
|
||||
title: "",
|
||||
image: "",
|
||||
link: "",
|
||||
sort: 1,
|
||||
desc: "",
|
||||
content: "",
|
||||
recommend: 1,
|
||||
release_time: ""
|
||||
};
|
||||
5
src/views/articleManagement/list/constant/index.ts
Normal file
5
src/views/articleManagement/list/constant/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { FORM_DATA, RULE_FORM } from "./search";
|
||||
import { COLUMNS } from "./table";
|
||||
import { RULES } from "./rules";
|
||||
import { EDIT_FORM_DATA, EDIT_RULE_FORM } from "./edit";
|
||||
export { FORM_DATA, RULE_FORM, COLUMNS, EDIT_FORM_DATA, EDIT_RULE_FORM, RULES };
|
||||
5
src/views/articleManagement/list/constant/rules.ts
Normal file
5
src/views/articleManagement/list/constant/rules.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export const RULES = {
|
||||
title: [{ required: true, message: "文章名称不能为空 ! ", trigger: "blur" }],
|
||||
category_id: [{ required: true, message: "文章分类不能为空 ! ", trigger: "change" }],
|
||||
sort: [{ required: true, message: "文章排序不能为空 ! ", trigger: "blur" }]
|
||||
};
|
||||
50
src/views/articleManagement/list/constant/search.ts
Normal file
50
src/views/articleManagement/list/constant/search.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
}
|
||||
export const FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "title",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
isArray: true,
|
||||
label: "文章名称: "
|
||||
},
|
||||
|
||||
{
|
||||
prop: "category_id",
|
||||
placeholder: "请选择",
|
||||
type: "treeSelect",
|
||||
isArray: true,
|
||||
label: "文章分类: ",
|
||||
options: []
|
||||
},
|
||||
{
|
||||
prop: "Time",
|
||||
type: "daterange",
|
||||
options: [],
|
||||
startPlaceholder: "开始日期",
|
||||
endPlaceholder: "结束日期",
|
||||
startDate: "created_at",
|
||||
// endDate: "createEndDate",
|
||||
label: "发布时间: "
|
||||
}
|
||||
];
|
||||
|
||||
export const RULE_FORM = {
|
||||
page: 1,
|
||||
size: 50
|
||||
};
|
||||
53
src/views/articleManagement/list/constant/table.ts
Normal file
53
src/views/articleManagement/list/constant/table.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
//import { RenderScope } from "@/components/ProTable/interface";
|
||||
export const COLUMNS = [
|
||||
{
|
||||
align: "center",
|
||||
fixed: true,
|
||||
label: "ID",
|
||||
prop: "id",
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
align: "center",
|
||||
label: "图片",
|
||||
prop: "image",
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "文章名称",
|
||||
prop: "title"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "文章分类",
|
||||
prop: "category_name"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "文章排序",
|
||||
prop: "sort",
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "首页推荐",
|
||||
prop: "recommend"
|
||||
},
|
||||
|
||||
{
|
||||
align: "left",
|
||||
label: "发布时间",
|
||||
prop: "release_time",
|
||||
width: 160
|
||||
},
|
||||
|
||||
{
|
||||
align: "center",
|
||||
label: "状态",
|
||||
prop: "enabled",
|
||||
width: 80
|
||||
},
|
||||
|
||||
{ prop: "operation", label: "操作", fixed: "right", width: 200 }
|
||||
];
|
||||
126
src/views/articleManagement/list/edit.vue
Normal file
126
src/views/articleManagement/list/edit.vue
Normal file
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<!-- style="margin-bottom: 16px" -->
|
||||
|
||||
<div class="table-box">
|
||||
<div style="padding-bottom: 16px">
|
||||
<el-button @click="handleReset"> 重置 </el-button>
|
||||
<el-button type="primary" @click="handleConfirmClick"> 提交 </el-button>
|
||||
</div>
|
||||
<div class="card table-main">
|
||||
<el-tabs v-model="activeName" class="demo-tabs">
|
||||
<el-tab-pane label="基本信息" name="basicInfo">
|
||||
<rulesForm
|
||||
:ruleForm="dataStore.editRuleForm"
|
||||
:formData="dataStore.editFormData"
|
||||
:rules="dataStore.rules"
|
||||
ref="formRef"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="详细内容" name="third">
|
||||
<div style="width: 1280px; margin: 0 auto">
|
||||
<WangEditor v-model:value="dataStore.editRuleForm.content" />
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="articleEditIndex">
|
||||
import rulesForm from "@/components/rulesForm/index.vue";
|
||||
import {
|
||||
getArticleClassDataApi,
|
||||
getArticleListAddSaveApi,
|
||||
getArticleListDetailsApi,
|
||||
getArticleListUpApi
|
||||
} from "@/api/modules/articleList";
|
||||
// /handleSubmit,
|
||||
import { EDIT_FORM_DATA, EDIT_RULE_FORM, RULES } from "./constant/index";
|
||||
import { useSearchInfoArray } from "@/hooks/useSearch";
|
||||
import { ref, reactive } from "vue";
|
||||
import WangEditor from "@/components/WangEditor/index.vue";
|
||||
// import rulesForm from "@/components/rulesForm/index.vue";
|
||||
|
||||
import { cloneDeep } from "lodash-es";
|
||||
import { useMsg } from "@/hooks/useMsg";
|
||||
const formRef = ref<any>(null);
|
||||
const activeName = ref("basicInfo");
|
||||
const $route = useRoute();
|
||||
|
||||
//数据集合
|
||||
const dataStore = reactive<any>({
|
||||
rules: cloneDeep(RULES), //抽屉表单验证
|
||||
editRuleForm: cloneDeep(EDIT_RULE_FORM),
|
||||
editFormData: cloneDeep(EDIT_FORM_DATA) //抽屉表单配置项
|
||||
});
|
||||
//新增
|
||||
const getArticleListAddSave = async () => {
|
||||
const result = await getArticleListAddSaveApi(dataStore.editRuleForm);
|
||||
if (result.code === 0) {
|
||||
const { msg } = result;
|
||||
useMsg("success", msg);
|
||||
}
|
||||
};
|
||||
//文章分类
|
||||
const getArticleClassData = async () => {
|
||||
const result = await getArticleClassDataApi();
|
||||
if (result?.code === 0) {
|
||||
const { data } = result;
|
||||
dataStore.editFormData[1].options = useSearchInfoArray(data);
|
||||
//如果有category_id就代表是从文章分类跳转过来的
|
||||
if ($route.query.category_id) {
|
||||
dataStore.editRuleForm.category_id = Number($route.query.category_id);
|
||||
}
|
||||
}
|
||||
};
|
||||
getArticleClassData();
|
||||
|
||||
//文章详情
|
||||
const getArticleListDetails = async () => {
|
||||
let id = $route.query.id;
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
const result = await getArticleListDetailsApi(id);
|
||||
if (result?.code === 0) {
|
||||
const { data } = result;
|
||||
dataStore.editRuleForm = data;
|
||||
console.log(data);
|
||||
}
|
||||
};
|
||||
//更新
|
||||
const getArticleListUp = async () => {
|
||||
const result = await getArticleListUpApi({ id: $route.query.id, ...dataStore.editRuleForm });
|
||||
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
}
|
||||
};
|
||||
|
||||
getArticleListDetails();
|
||||
|
||||
//提交
|
||||
const handleConfirmClick = () => {
|
||||
if (!formRef.value!.ruleFormRef) return;
|
||||
formRef!.value!.ruleFormRef!.validate((valid: any) => {
|
||||
if (valid) {
|
||||
console.log("submit!");
|
||||
$route.query.type === "add" ? getArticleListAddSave() : getArticleListUp();
|
||||
} else {
|
||||
console.log("error submit!");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
//重置
|
||||
const handleReset = () => {
|
||||
if ($route.query.type === "add") {
|
||||
dataStore.editRuleForm = cloneDeep(EDIT_RULE_FORM);
|
||||
} else {
|
||||
getArticleListDetails();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
122
src/views/articleManagement/list/index.vue
Normal file
122
src/views/articleManagement/list/index.vue
Normal file
@@ -0,0 +1,122 @@
|
||||
<!-- 视频列表 -->
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<div style="padding-bottom: 16px">
|
||||
<el-button type="primary" @click="handleAdd('add')"> 添加 </el-button>
|
||||
<el-button type="primary" @click="handleExport"> 导出 </el-button>
|
||||
</div>
|
||||
<ProTable
|
||||
ref="proTableRef"
|
||||
:formData="dataStore.formData"
|
||||
:columns="dataStore.columns"
|
||||
:request-api="getArticleListApi"
|
||||
:init-param="dataStore.initParam"
|
||||
>
|
||||
<template #image="scope">
|
||||
<el-image :src="h + scope.row.image" style="width: 60px; height: 60px" />
|
||||
</template>
|
||||
<template #enabled="scope">
|
||||
<el-tag type="success" effect="dark">{{ scope.row.enabled === 1 ? "启用" : "禁用" }}</el-tag>
|
||||
</template>
|
||||
<template #operation="scope">
|
||||
<el-button size="small" type="primary" @click="handleBtnClick('edit', scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click="handleBtnClick('del', scope.row)">删除</el-button>
|
||||
</template>
|
||||
</ProTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="articleListIndex">
|
||||
import { useExport } from "@/hooks/useExport";
|
||||
import { messageBox } from "@/utils/messageBox";
|
||||
import { useMsg } from "@/hooks/useMsg";
|
||||
import ProTable from "@/components/ProTable/index.vue";
|
||||
//列表接口
|
||||
import {
|
||||
getArticleListApi,
|
||||
getArticleClassDataApi,
|
||||
getArticleListExportApi,
|
||||
getArticleListDelApi
|
||||
} from "@/api/modules/articleList";
|
||||
import { useSearchInfoArray } from "@/hooks/useSearch";
|
||||
//深拷贝方法
|
||||
import { cloneDeep } from "lodash-es";
|
||||
//表格和搜索條件
|
||||
import { RULE_FORM, FORM_DATA, COLUMNS } from "./constant/index";
|
||||
//图片地址
|
||||
const h = import.meta.env.VITE_APP_API_BASE_UPLOAD_URL;
|
||||
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
|
||||
const proTableRef = ref<any>(null);
|
||||
const $router = useRouter();
|
||||
|
||||
// 数据源
|
||||
const dataStore = reactive<any>({
|
||||
columns: COLUMNS, //列表配置项
|
||||
initParam: cloneDeep(RULE_FORM), // 初始化搜索条件|重置搜索条件
|
||||
ruleForm: cloneDeep(RULE_FORM), // 搜索參數
|
||||
formData: FORM_DATA, //搜索配置项
|
||||
selectRow: {} //当前选择的row
|
||||
});
|
||||
|
||||
//文章分类(搜索条件)
|
||||
const getArticleClassData = async () => {
|
||||
const result = await getArticleClassDataApi();
|
||||
if (result?.code === 0) {
|
||||
const { data } = result;
|
||||
dataStore.formData[1].options = useSearchInfoArray(data);
|
||||
}
|
||||
};
|
||||
getArticleClassData();
|
||||
//添加
|
||||
const handleAdd = (type: any) => {
|
||||
$router.push({
|
||||
path: "/admin/articleManagement/list/edit",
|
||||
query: {
|
||||
type,
|
||||
title: "添加文章"
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//导出接口
|
||||
const getArticleListExport = async () => {
|
||||
const result = await getArticleListExportApi(dataStore.ruleForm);
|
||||
await useExport(result);
|
||||
};
|
||||
//导出
|
||||
const handleExport = () => {
|
||||
getArticleListExport();
|
||||
};
|
||||
//删除
|
||||
const getArticleListDel = async (id: any) => {
|
||||
messageBox("你确定要删除?", async () => {
|
||||
const result = await getArticleListDelApi(id);
|
||||
if (result?.code === 0) {
|
||||
const { msg } = result;
|
||||
useMsg("success", msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
});
|
||||
};
|
||||
//按钮点击事件
|
||||
const handleBtnClick = (type: any, row: any) => {
|
||||
dataStore.selectRow = row;
|
||||
//编辑
|
||||
if (type === "edit") {
|
||||
$router.push({
|
||||
path: "/admin/articleManagement/list/edit",
|
||||
query: {
|
||||
id: row.id,
|
||||
type
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
//删除
|
||||
if (type === "del") {
|
||||
getArticleListDel(row.id);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
3
src/views/articleManagement/recycle/constant/index.ts
Normal file
3
src/views/articleManagement/recycle/constant/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { FORM_DATA, RULE_FORM } from "./search";
|
||||
import { COLUMNS } from "./table";
|
||||
export { FORM_DATA, RULE_FORM, COLUMNS };
|
||||
40
src/views/articleManagement/recycle/constant/search.ts
Normal file
40
src/views/articleManagement/recycle/constant/search.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
}
|
||||
export const FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "title",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
isArray: true,
|
||||
label: "文章名称: "
|
||||
},
|
||||
|
||||
{
|
||||
prop: "category_id",
|
||||
placeholder: "请选择",
|
||||
type: "select",
|
||||
isArray: true,
|
||||
label: "文章分类: ",
|
||||
options: []
|
||||
}
|
||||
];
|
||||
|
||||
export const RULE_FORM = {
|
||||
page: 1,
|
||||
size: 50
|
||||
};
|
||||
61
src/views/articleManagement/recycle/constant/table.ts
Normal file
61
src/views/articleManagement/recycle/constant/table.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { RenderScope } from "@/components/ProTable/interface";
|
||||
const YES_OR_NO: any = {
|
||||
1: "✔️",
|
||||
0: "❌"
|
||||
};
|
||||
export const COLUMNS = [
|
||||
{ type: "selection", fixed: "left", width: 40 },
|
||||
{
|
||||
align: "center",
|
||||
fixed: true,
|
||||
label: "ID",
|
||||
prop: "id",
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
align: "center",
|
||||
label: "图片",
|
||||
prop: "image",
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "文章名称",
|
||||
prop: "title"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "文章分类",
|
||||
prop: "category_name"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "文章排序",
|
||||
prop: "sort",
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "首页推荐",
|
||||
prop: "recommend",
|
||||
render: (scope: RenderScope<any>): VNode | string | any => {
|
||||
return YES_OR_NO[scope.row.recommend];
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
align: "left",
|
||||
label: "发布时间",
|
||||
prop: "release_time",
|
||||
width: 160
|
||||
},
|
||||
|
||||
{
|
||||
align: "center",
|
||||
label: "状态",
|
||||
prop: "status",
|
||||
width: 80
|
||||
},
|
||||
|
||||
{ prop: "operation", label: "操作", fixed: "right", width: 200 }
|
||||
];
|
||||
81
src/views/articleManagement/recycle/index.vue
Normal file
81
src/views/articleManagement/recycle/index.vue
Normal file
@@ -0,0 +1,81 @@
|
||||
<!-- 文章回收 -->
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<ProTable
|
||||
ref="proTableRef"
|
||||
:formData="dataStore.formData"
|
||||
:columns="dataStore.columns"
|
||||
:request-api="getArticleTrashListApi"
|
||||
:init-param="dataStore.initParam"
|
||||
>
|
||||
<template #image="scope">
|
||||
<el-image :src="h + scope.row.image" style="width: 60px; height: 60px" />
|
||||
</template>
|
||||
|
||||
<template #status="scope">
|
||||
<el-tag type="danger" effect="dark">{{ scope.row.status ? "删除" : "删除" }}</el-tag>
|
||||
</template>
|
||||
<template #operation="scope">
|
||||
<el-button size="small" type="danger" @click="getArticleTrashDel(scope.row.id)">删除</el-button>
|
||||
<el-button size="small" type="primary" @click="getArticleTrashRestore(scope.row.id)">恢复</el-button>
|
||||
</template>
|
||||
</ProTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="articleRecycleListIndex">
|
||||
import ProTable from "@/components/ProTable/index.vue";
|
||||
import { messageBox } from "@/utils/messageBox";
|
||||
import { useMsg } from "@/hooks/useMsg";
|
||||
import { useSearchInfoArray } from "@/hooks/useSearch";
|
||||
const h = import.meta.env.VITE_APP_API_BASE_UPLOAD_URL;
|
||||
//列表接口
|
||||
import { getArticleTrashListApi, getArticleTrashDelApi, getArticleTrashRestoreApi } from "@/api/modules/articleRecycle";
|
||||
import { getArticleClassDataApi } from "@/api/modules/articleList";
|
||||
//深拷贝方法
|
||||
import { cloneDeep } from "lodash-es";
|
||||
//表格和搜索條件
|
||||
import { RULE_FORM, FORM_DATA, COLUMNS } from "./constant/index";
|
||||
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
|
||||
const proTableRef = ref<any>(null);
|
||||
|
||||
// 数据源
|
||||
const dataStore = reactive<any>({
|
||||
columns: COLUMNS, //列表配置项
|
||||
initParam: cloneDeep(RULE_FORM), // 初始化搜索条件|重置搜索条件
|
||||
ruleForm: cloneDeep(RULE_FORM), // 搜索參數
|
||||
formData: FORM_DATA //搜索配置项
|
||||
});
|
||||
//恢复
|
||||
const getArticleTrashRestore = async (id: any) => {
|
||||
const result = await getArticleTrashRestoreApi(id);
|
||||
if (result?.code === 0) {
|
||||
const { msg } = result;
|
||||
useMsg("success", msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
};
|
||||
//删除
|
||||
const getArticleTrashDel = (id: any) => {
|
||||
messageBox("你确定要删除?", async () => {
|
||||
const result = await getArticleTrashDelApi(id);
|
||||
if (result?.code === 0) {
|
||||
const { msg } = result;
|
||||
useMsg("success", msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
});
|
||||
};
|
||||
//文章分类(搜索条件)
|
||||
const getArticleClassData = async () => {
|
||||
const result = await getArticleClassDataApi();
|
||||
if (result?.code === 0) {
|
||||
const { data } = result;
|
||||
dataStore.formData[1].options = useSearchInfoArray(data);
|
||||
}
|
||||
};
|
||||
getArticleClassData();
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@/api/modules/articleRecycle
|
||||
136
src/views/articleManagement/remark/constant/edit.ts
Normal file
136
src/views/articleManagement/remark/constant/edit.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
disabled?: boolean;
|
||||
fileList?: any;
|
||||
prompt?: any;
|
||||
}
|
||||
export const EDIT_FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "videoName",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "下载名称: "
|
||||
},
|
||||
|
||||
{
|
||||
prop: "videoType",
|
||||
placeholder: "请选择",
|
||||
type: "treeSelect",
|
||||
label: "下载分类: ",
|
||||
options: [
|
||||
{
|
||||
value: "1",
|
||||
label: "Level one 1",
|
||||
children: [
|
||||
{
|
||||
value: "1-1",
|
||||
label: "Level two 1-1",
|
||||
children: [
|
||||
{
|
||||
value: "1-1-1",
|
||||
label: "Level three 1-1-1"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
prop: "videoSort",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "下载排序: "
|
||||
},
|
||||
{
|
||||
prop: "recommend",
|
||||
placeholder: "请输入",
|
||||
type: "radio",
|
||||
label: "首页推荐: ",
|
||||
options: [
|
||||
{
|
||||
label: "是",
|
||||
value: "是"
|
||||
},
|
||||
{
|
||||
label: "否",
|
||||
value: "否"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
prop: "imgUrl",
|
||||
type: "upImg",
|
||||
label: "下载图片: ",
|
||||
prompt: "图片尺寸320x320"
|
||||
},
|
||||
{
|
||||
prop: "table",
|
||||
type: "table",
|
||||
label: "下载文件: "
|
||||
},
|
||||
{
|
||||
prop: "videoDescribe",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "适合型号: "
|
||||
},
|
||||
{
|
||||
prop: "videoDescribe",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "支持系统: "
|
||||
},
|
||||
{
|
||||
prop: "videoDescribe",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "文件格式: "
|
||||
},
|
||||
|
||||
{
|
||||
prop: "SEOTitle",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "SEO标题: "
|
||||
},
|
||||
{
|
||||
prop: "SEOKeywords",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "SEO关键词: "
|
||||
},
|
||||
{
|
||||
prop: "SEODescribe",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "SEO描述: "
|
||||
}
|
||||
];
|
||||
export const EDIT_RULE_FORM = {
|
||||
videoName: "",
|
||||
videoType: "",
|
||||
videoSort: 1,
|
||||
recommend: "",
|
||||
videoDescribe: "",
|
||||
link: "",
|
||||
SEOTitle: "",
|
||||
SEOKeywords: "",
|
||||
SEODescribe: ""
|
||||
};
|
||||
// editRuleForm: {},
|
||||
//editFormData: [],
|
||||
5
src/views/articleManagement/remark/constant/index.ts
Normal file
5
src/views/articleManagement/remark/constant/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { FORM_DATA, RULE_FORM } from "./search";
|
||||
import { COLUMNS } from "./table";
|
||||
import { RULES } from "./rules";
|
||||
import { EDIT_FORM_DATA, EDIT_RULE_FORM } from "./edit";
|
||||
export { FORM_DATA, RULE_FORM, COLUMNS, EDIT_FORM_DATA, EDIT_RULE_FORM, RULES };
|
||||
5
src/views/articleManagement/remark/constant/rules.ts
Normal file
5
src/views/articleManagement/remark/constant/rules.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export const RULES = {
|
||||
videoName: [{ required: true, message: "下载名称不能为空 ! ", trigger: "blur" }],
|
||||
videoType: [{ required: true, message: "下载分类不能为空 ! ", trigger: "blur" }],
|
||||
videoSort: [{ required: true, message: "下载排序不能为空 ! ", trigger: "blur" }]
|
||||
};
|
||||
57
src/views/articleManagement/remark/constant/search.ts
Normal file
57
src/views/articleManagement/remark/constant/search.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
}
|
||||
export const FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "title",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
isArray: true,
|
||||
label: "文章标题: "
|
||||
},
|
||||
{
|
||||
prop: "is_audited",
|
||||
placeholder: "请选择",
|
||||
type: "select",
|
||||
options: [
|
||||
{
|
||||
value: 0,
|
||||
label: "待审核"
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
label: "已审核"
|
||||
}
|
||||
],
|
||||
label: "状态: "
|
||||
},
|
||||
{
|
||||
prop: "Time",
|
||||
type: "daterange",
|
||||
options: [],
|
||||
startPlaceholder: "开始日期",
|
||||
endPlaceholder: "结束日期",
|
||||
startDate: "created_at",
|
||||
// endDate: "createEndDate",
|
||||
label: "提交时间: "
|
||||
}
|
||||
];
|
||||
|
||||
export const RULE_FORM = {
|
||||
page: 1,
|
||||
size: 50
|
||||
};
|
||||
41
src/views/articleManagement/remark/constant/table.ts
Normal file
41
src/views/articleManagement/remark/constant/table.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
//import { RenderScope } from "@/components/ProTable/interface";
|
||||
export const COLUMNS = [
|
||||
{
|
||||
align: "center",
|
||||
fixed: true,
|
||||
label: "留言人",
|
||||
prop: "name",
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
align: "center",
|
||||
label: "联系邮箱",
|
||||
prop: "email",
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "留言内容",
|
||||
prop: "content"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "文章标题",
|
||||
prop: "article_title"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "提交时间",
|
||||
prop: "created_at",
|
||||
width: 160
|
||||
},
|
||||
|
||||
{
|
||||
align: "center",
|
||||
label: "状态",
|
||||
prop: "is_audited",
|
||||
width: 160
|
||||
},
|
||||
|
||||
{ prop: "operation", label: "操作", fixed: "right", width: 200 }
|
||||
];
|
||||
90
src/views/articleManagement/remark/index.vue
Normal file
90
src/views/articleManagement/remark/index.vue
Normal file
@@ -0,0 +1,90 @@
|
||||
<!-- 文章评论 -->
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<div style="padding-bottom: 16px">
|
||||
<el-button type="primary" @click="getArticleRemarkExport"> 导出 </el-button>
|
||||
</div>
|
||||
<ProTable
|
||||
ref="proTableRef"
|
||||
:formData="dataStore.formData"
|
||||
:columns="dataStore.columns"
|
||||
:request-api="getArticleRemarkListApi"
|
||||
:init-param="dataStore.initParam"
|
||||
>
|
||||
<template #image="scope">
|
||||
<el-image :src="h + scope.row.image" style="width: 60px; height: 60px" />
|
||||
</template>
|
||||
<template #is_audited="scope">
|
||||
<el-tag :type="scope.row.is_audited ? 'success' : 'danger'" effect="dark">{{
|
||||
scope.row.is_audited ? "已审核" : "待审核"
|
||||
}}</el-tag>
|
||||
</template>
|
||||
<template #operation="scope">
|
||||
<el-button size="small" type="primary" @click="getArticleRemarkExamine(scope.row.id)">{{
|
||||
scope.row.is_audited ? "取消审核" : "审核通过"
|
||||
}}</el-button>
|
||||
<el-button size="small" type="danger" @click="getArticleRemarkDel(scope.row.id)">删除</el-button>
|
||||
</template>
|
||||
</ProTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="articleRemarkListIndex">
|
||||
import ProTable from "@/components/ProTable/index.vue";
|
||||
import { messageBox } from "@/utils/messageBox";
|
||||
import { useMsg } from "@/hooks/useMsg";
|
||||
import { useExport } from "@/hooks/useExport";
|
||||
const h = import.meta.env.VITE_APP_API_BASE_UPLOAD_URL;
|
||||
//列表接口
|
||||
|
||||
import {
|
||||
getArticleRemarkListApi,
|
||||
getArticleRemarkDelApi,
|
||||
getArticleRemarkExamineApi,
|
||||
getArticleRemarkExportApi
|
||||
} from "@/api/modules/articleRemark";
|
||||
//深拷贝方法
|
||||
import { cloneDeep } from "lodash-es";
|
||||
//表格和搜索條件
|
||||
import { RULE_FORM, FORM_DATA, COLUMNS, RULES } from "./constant/index";
|
||||
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
|
||||
const proTableRef = ref<any>(null);
|
||||
|
||||
// 数据源
|
||||
const dataStore = reactive<any>({
|
||||
columns: COLUMNS, //列表配置项
|
||||
rules: cloneDeep(RULES), //抽屉表单验证
|
||||
initParam: cloneDeep(RULE_FORM), // 初始化搜索条件|重置搜索条件
|
||||
ruleForm: cloneDeep(RULE_FORM), // 搜索參數
|
||||
formData: FORM_DATA, //搜索配置项
|
||||
selectRow: {} //当前选择的row
|
||||
});
|
||||
//导出
|
||||
const getArticleRemarkExport = async () => {
|
||||
const result = await getArticleRemarkExportApi(dataStore.ruleForm);
|
||||
await useExport(result);
|
||||
};
|
||||
|
||||
//删除
|
||||
const getArticleRemarkDel = async (id: any) => {
|
||||
messageBox("你确定要删除?", async () => {
|
||||
const result = await getArticleRemarkDelApi(id);
|
||||
if (result?.code === 0) {
|
||||
const { msg } = result;
|
||||
useMsg("success", msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
});
|
||||
};
|
||||
//审核
|
||||
const getArticleRemarkExamine = async (id: any) => {
|
||||
const result = await getArticleRemarkExamineApi(id);
|
||||
if (result?.code === 0) {
|
||||
const { msg } = result;
|
||||
useMsg("success", msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
79
src/views/bannerManagement/class/constant/edit.ts
Normal file
79
src/views/bannerManagement/class/constant/edit.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
disabled?: boolean;
|
||||
fileList?: any;
|
||||
}
|
||||
export const EDIT_FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "name",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: " Banner分类名称: "
|
||||
},
|
||||
{
|
||||
prop: "recommend",
|
||||
placeholder: "请输入",
|
||||
type: "radio",
|
||||
label: "首页推荐: ",
|
||||
options: [
|
||||
{
|
||||
label: "是",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: "否",
|
||||
value: 0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
prop: "at_platform",
|
||||
placeholder: "请输入",
|
||||
type: "radio",
|
||||
label: "显示端口: ",
|
||||
options: [
|
||||
{
|
||||
label: "PC端",
|
||||
value: "pc"
|
||||
},
|
||||
{
|
||||
label: "移动端",
|
||||
value: "mobile"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
prop: "desc",
|
||||
placeholder: "请输入",
|
||||
type: "textarea",
|
||||
label: "描述: "
|
||||
}
|
||||
];
|
||||
export const EDIT_RULE_FORM = {
|
||||
videoName: "",
|
||||
videoType: "",
|
||||
videoSort: 1,
|
||||
recommend: "",
|
||||
videoDescribe: "",
|
||||
link: "",
|
||||
SEOTitle: "",
|
||||
SEOKeywords: "",
|
||||
SEODescribe: ""
|
||||
};
|
||||
// editRuleForm: {},
|
||||
//editFormData: [],
|
||||
5
src/views/bannerManagement/class/constant/index.ts
Normal file
5
src/views/bannerManagement/class/constant/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { FORM_DATA, RULE_FORM } from "./search";
|
||||
import { COLUMNS } from "./table";
|
||||
import { RULES } from "./rules";
|
||||
import { EDIT_FORM_DATA, EDIT_RULE_FORM } from "./edit";
|
||||
export { FORM_DATA, RULE_FORM, COLUMNS, EDIT_FORM_DATA, EDIT_RULE_FORM, RULES };
|
||||
3
src/views/bannerManagement/class/constant/rules.ts
Normal file
3
src/views/bannerManagement/class/constant/rules.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export const RULES = {
|
||||
at_platform: [{ required: true, message: "首页推荐不能为空 ! ", trigger: "change" }]
|
||||
};
|
||||
31
src/views/bannerManagement/class/constant/search.ts
Normal file
31
src/views/bannerManagement/class/constant/search.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
}
|
||||
export const FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "name",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
isArray: true,
|
||||
label: "Banner名称: "
|
||||
}
|
||||
];
|
||||
|
||||
export const RULE_FORM = {
|
||||
page: 1,
|
||||
size: 50
|
||||
};
|
||||
52
src/views/bannerManagement/class/constant/table.ts
Normal file
52
src/views/bannerManagement/class/constant/table.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { RenderScope } from "@/components/ProTable/interface";
|
||||
const YES_OR_NO: any = {
|
||||
1: "✔️",
|
||||
0: "❌"
|
||||
};
|
||||
export const COLUMNS = [
|
||||
{
|
||||
align: "center",
|
||||
fixed: true,
|
||||
label: "ID",
|
||||
prop: "id",
|
||||
width: 80
|
||||
},
|
||||
|
||||
{
|
||||
align: "left",
|
||||
label: "Banner分类名称",
|
||||
prop: "name"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "首页推荐",
|
||||
prop: "recommend",
|
||||
render: (scope: RenderScope<any>): VNode | string | any => {
|
||||
return YES_OR_NO[scope.row.recommend];
|
||||
}
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "显示端口",
|
||||
prop: "at_platform",
|
||||
render: (scope: RenderScope<any>): VNode | string | any => {
|
||||
const OBJ: any = {
|
||||
pc: "PC端",
|
||||
mobile: "移动端"
|
||||
};
|
||||
return OBJ[scope.row.at_platform];
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
align: "left",
|
||||
label: "描述",
|
||||
prop: "desc"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "添加时间",
|
||||
prop: "created_at"
|
||||
},
|
||||
{ prop: "operation", label: "操作", fixed: "right", width: 200 }
|
||||
];
|
||||
167
src/views/bannerManagement/class/index.vue
Normal file
167
src/views/bannerManagement/class/index.vue
Normal file
@@ -0,0 +1,167 @@
|
||||
<!-- 视频列表 -->
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<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="getBannerClassListApi"
|
||||
:init-param="dataStore.initParam"
|
||||
>
|
||||
<template #image="scope">
|
||||
<el-image :src="h + scope.row.image" style="width: 60px; height: 60px" />
|
||||
</template>
|
||||
<template #status="scope">
|
||||
<el-tag type="success" effect="dark">{{ scope.row.status }}</el-tag>
|
||||
</template>
|
||||
<template #operation="scope">
|
||||
<el-button size="small" type="primary" @click="getBannerClassListRead(scope.row.id)">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click="getBannerClassListDel(scope.row.id)">删除</el-button>
|
||||
</template>
|
||||
</ProTable>
|
||||
<el-drawer
|
||||
v-model="dataStore.visible"
|
||||
:show-close="true"
|
||||
:size="600"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
:before-close="handleBeforeClone"
|
||||
destroy-on-close
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<h4 :id="titleId" :class="titleClass">{{ dataStore.title }}</h4>
|
||||
</template>
|
||||
<div>
|
||||
<rulesForm
|
||||
:ruleForm="dataStore.editRuleForm"
|
||||
:formData="dataStore.editFormData"
|
||||
:rules="dataStore.rules"
|
||||
ref="formRef"
|
||||
/>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div style="flex: auto">
|
||||
<el-button @click="handleResetClick">重置</el-button>
|
||||
<el-button type="primary" @click="handleConfirmClick">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="bannerClassListIndex">
|
||||
import ProTable from "@/components/ProTable/index.vue";
|
||||
import rulesForm from "@/components/rulesForm/index.vue";
|
||||
import { messageBox } from "@/utils/messageBox";
|
||||
import { useMsg } from "@/hooks/useMsg";
|
||||
const h = import.meta.env.VITE_APP_API_BASE_UPLOAD_URL;
|
||||
//列表接口
|
||||
import {
|
||||
getBannerClassListApi,
|
||||
getBannerClassListDelApi,
|
||||
getBannerClassListReadApi,
|
||||
getBannerClassListUpApi,
|
||||
getBannerClassListSaveApi
|
||||
} from "@/api/modules/bannerClass";
|
||||
//深拷贝方法
|
||||
import { cloneDeep } from "lodash-es";
|
||||
//表格和搜索條件
|
||||
import { RULE_FORM, FORM_DATA, COLUMNS, EDIT_FORM_DATA, EDIT_RULE_FORM, RULES } from "./constant/index";
|
||||
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
|
||||
const proTableRef = ref<any>(null);
|
||||
const formRef: any = ref(null);
|
||||
// 数据源
|
||||
const dataStore = reactive<any>({
|
||||
title: "添加Banner分类",
|
||||
columns: COLUMNS, //列表配置项
|
||||
rules: cloneDeep(RULES), //抽屉表单验证
|
||||
editRuleForm: cloneDeep(EDIT_RULE_FORM),
|
||||
editFormData: cloneDeep(EDIT_FORM_DATA), //抽屉表单配置项
|
||||
initParam: cloneDeep(RULE_FORM), // 初始化搜索条件|重置搜索条件
|
||||
ruleForm: cloneDeep(RULE_FORM), // 搜索參數
|
||||
formData: FORM_DATA, //搜索配置项
|
||||
visible: false
|
||||
});
|
||||
|
||||
//抽屉确认
|
||||
const handleConfirmClick = () => {
|
||||
if (!formRef.value!.ruleFormRef) return;
|
||||
formRef!.value!.ruleFormRef!.validate((valid: any) => {
|
||||
if (valid) {
|
||||
dataStore.title === "添加Banner分类" ? getBannerClassListSave() : getBannerClassListUp();
|
||||
console.log("submit!");
|
||||
} else {
|
||||
console.log("error submit!");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
//重置验证状态
|
||||
const resetFields = () => {
|
||||
if (!formRef.value!.ruleFormRef) return;
|
||||
formRef!.value!.ruleFormRef.resetFields();
|
||||
};
|
||||
//抽屉重置
|
||||
const handleResetClick = () => {
|
||||
if (dataStore.title === "添加Banner分类") {
|
||||
resetFields();
|
||||
} else {
|
||||
getBannerClassListRead(dataStore.editRuleForm.id);
|
||||
}
|
||||
};
|
||||
//添加
|
||||
const handleAdd = () => {
|
||||
dataStore.visible = true;
|
||||
dataStore.title = "添加Banner分类";
|
||||
};
|
||||
const handleBeforeClone = () => {
|
||||
dataStore.editRuleForm = cloneDeep(EDIT_RULE_FORM);
|
||||
resetFields();
|
||||
dataStore.visible = false;
|
||||
};
|
||||
//更新
|
||||
const getBannerClassListUp = async () => {
|
||||
const result = await getBannerClassListUpApi(dataStore.editRuleForm);
|
||||
if (result?.code === 0) {
|
||||
dataStore.visible = false;
|
||||
dataStore.editRuleForm = cloneDeep(EDIT_RULE_FORM);
|
||||
formRef!.value!.ruleFormRef.resetFields();
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
};
|
||||
//新增 getBannerListSave
|
||||
const getBannerClassListSave = async () => {
|
||||
const result = await getBannerClassListSaveApi(dataStore.editRuleForm);
|
||||
if (result?.code === 0) {
|
||||
dataStore.visible = false;
|
||||
dataStore.editRuleForm = cloneDeep(EDIT_RULE_FORM);
|
||||
formRef!.value!.ruleFormRef.resetFields();
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
};
|
||||
//删除
|
||||
const getBannerClassListDel = async (id: any) => {
|
||||
messageBox("你确定要删除?", async () => {
|
||||
const result = await getBannerClassListDelApi(id);
|
||||
if (result?.code === 0) {
|
||||
const { msg } = result;
|
||||
useMsg("success", msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
});
|
||||
};
|
||||
//详情
|
||||
const getBannerClassListRead = async (id: any) => {
|
||||
dataStore.title = "编辑Banner";
|
||||
dataStore.visible = true;
|
||||
const result = await getBannerClassListReadApi(id);
|
||||
if (result?.code === 0) {
|
||||
dataStore.editRuleForm = result?.data;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
187
src/views/bannerManagement/list/constant/edit.ts
Normal file
187
src/views/bannerManagement/list/constant/edit.ts
Normal file
@@ -0,0 +1,187 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
disabled?: boolean;
|
||||
fileList?: any;
|
||||
prompt?: any;
|
||||
placeholder1?: any;
|
||||
prop1?: any;
|
||||
}
|
||||
export const EDIT_FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "title",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "Banner名称: "
|
||||
},
|
||||
{
|
||||
prop: "title_txt_color",
|
||||
placeholder: "填写RGB值",
|
||||
type: "input",
|
||||
label: "文字颜色: "
|
||||
},
|
||||
{
|
||||
prop: "type",
|
||||
placeholder: "请输入",
|
||||
type: "radio",
|
||||
label: "前台显示: ",
|
||||
options: [
|
||||
{
|
||||
label: "显示图片",
|
||||
value: "image"
|
||||
},
|
||||
{
|
||||
label: "显示视频",
|
||||
value: "video"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
prop: "image",
|
||||
type: "upImg",
|
||||
label: "Banner图片: "
|
||||
},
|
||||
|
||||
{
|
||||
prop: "banner_id",
|
||||
placeholder: "请选择",
|
||||
type: "select",
|
||||
label: "Banner分类: ",
|
||||
options: [
|
||||
{
|
||||
value: "1",
|
||||
label: "Level one 1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
prop: "sort",
|
||||
placeholder: "请输入",
|
||||
type: "inputNumber",
|
||||
label: "Banner排序: "
|
||||
},
|
||||
{
|
||||
prop: "link",
|
||||
placeholder: "请输入",
|
||||
type: "treeSelectInput",
|
||||
label: "链接地址: ",
|
||||
placeholder1: "请选择",
|
||||
prop1: "link_to",
|
||||
options: []
|
||||
},
|
||||
|
||||
{
|
||||
prop: "desc",
|
||||
placeholder: "请输入",
|
||||
type: "textarea",
|
||||
label: "Banner描述: "
|
||||
},
|
||||
{
|
||||
prop: "desc_txt_color",
|
||||
placeholder: "填写RGB值",
|
||||
type: "input",
|
||||
label: "描述颜色: "
|
||||
}
|
||||
];
|
||||
|
||||
export const EDIT_FORM_DATA1: FormItem[] = [
|
||||
{
|
||||
prop: "title",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "Banner名称: "
|
||||
},
|
||||
{
|
||||
prop: "title_txt_color",
|
||||
placeholder: "填写RGB值",
|
||||
type: "input",
|
||||
label: "文字颜色: "
|
||||
},
|
||||
{
|
||||
prop: "type",
|
||||
placeholder: "请输入",
|
||||
type: "radio",
|
||||
label: "前台显示: ",
|
||||
options: [
|
||||
{
|
||||
label: "显示图片",
|
||||
value: "image"
|
||||
},
|
||||
{
|
||||
label: "显示视频",
|
||||
value: "video"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
prop: "image",
|
||||
type: "upImg",
|
||||
label: "Banner图片: "
|
||||
},
|
||||
|
||||
{
|
||||
prop: "banner_id",
|
||||
placeholder: "请选择",
|
||||
type: "select",
|
||||
label: "Banner分类: ",
|
||||
options: [
|
||||
{
|
||||
value: "1",
|
||||
label: "Level one 1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
prop: "sort",
|
||||
placeholder: "请输入",
|
||||
type: "inputNumber",
|
||||
label: "Banner排序: "
|
||||
},
|
||||
{
|
||||
prop: "link",
|
||||
placeholder: "请输入",
|
||||
type: "inputSelect",
|
||||
label: "链接地址: ",
|
||||
placeholder1: "请选择",
|
||||
prop1: "link_type",
|
||||
options: []
|
||||
},
|
||||
{
|
||||
prop: "video",
|
||||
type: "video",
|
||||
label: "视频文件: ",
|
||||
fileList: []
|
||||
},
|
||||
{
|
||||
prop: "desc",
|
||||
placeholder: "请输入",
|
||||
type: "textarea",
|
||||
label: "Banner描述: "
|
||||
},
|
||||
{
|
||||
prop: "desc_txt_color",
|
||||
placeholder: "填写RGB值",
|
||||
type: "input",
|
||||
label: "描述颜色: "
|
||||
}
|
||||
];
|
||||
|
||||
export const EDIT_RULE_FORM = {
|
||||
type: "image",
|
||||
sort: 1
|
||||
};
|
||||
// editRuleForm: {},
|
||||
//editFormData: [],
|
||||
5
src/views/bannerManagement/list/constant/index.ts
Normal file
5
src/views/bannerManagement/list/constant/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { FORM_DATA, RULE_FORM } from "./search";
|
||||
import { COLUMNS } from "./table";
|
||||
import { RULES, RULES1 } from "./rules";
|
||||
import { EDIT_FORM_DATA, EDIT_RULE_FORM, EDIT_FORM_DATA1 } from "./edit";
|
||||
export { FORM_DATA, RULE_FORM, COLUMNS, EDIT_FORM_DATA, EDIT_FORM_DATA1, EDIT_RULE_FORM, RULES, RULES1 };
|
||||
15
src/views/bannerManagement/list/constant/rules.ts
Normal file
15
src/views/bannerManagement/list/constant/rules.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
export const RULES = {
|
||||
title: [{ required: true, message: "Banner名称不能为空 ! ", trigger: "blur" }],
|
||||
type: [{ required: true, message: "前台显示不能为空 ! ", trigger: "change" }],
|
||||
image: [{ required: true, message: "Banner图片不能为空 ! ", trigger: "change" }],
|
||||
banner_id: [{ required: true, message: "Banner分类不能为空 ! ", trigger: "change" }],
|
||||
sort: [{ required: true, message: "排序不能为空 ! ", trigger: "change" }]
|
||||
};
|
||||
export const RULES1 = {
|
||||
title: [{ required: true, message: "Banner名称不能为空 ! ", trigger: "blur" }],
|
||||
type: [{ required: true, message: "前台显示不能为空 ! ", trigger: "change" }],
|
||||
image: [{ required: true, message: "Banner图片不能为空 ! ", trigger: "change" }],
|
||||
banner_id: [{ required: true, message: "Banner分类不能为空 ! ", trigger: "change" }],
|
||||
sort: [{ required: true, message: "排序不能为空 ! ", trigger: "change" }],
|
||||
video: [{ required: true, message: "视频不能为空 ! ", trigger: "change" }]
|
||||
};
|
||||
50
src/views/bannerManagement/list/constant/search.ts
Normal file
50
src/views/bannerManagement/list/constant/search.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
}
|
||||
export const FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "title",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
isArray: true,
|
||||
label: "Banner名称: "
|
||||
},
|
||||
|
||||
{
|
||||
prop: "banner_id",
|
||||
placeholder: "请选择",
|
||||
type: "select",
|
||||
isArray: true,
|
||||
label: "Banner分类: ",
|
||||
options: []
|
||||
},
|
||||
{
|
||||
prop: "Time",
|
||||
type: "daterange",
|
||||
options: [],
|
||||
startPlaceholder: "开始日期",
|
||||
endPlaceholder: "结束日期",
|
||||
startDate: "created_at",
|
||||
// endDate: "createEndDate",
|
||||
label: "添加时间: "
|
||||
}
|
||||
];
|
||||
|
||||
export const RULE_FORM = {
|
||||
page: 1,
|
||||
size: 50
|
||||
};
|
||||
38
src/views/bannerManagement/list/constant/table.ts
Normal file
38
src/views/bannerManagement/list/constant/table.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
//import { RenderScope } from "@/components/ProTable/interface";
|
||||
export const COLUMNS = [
|
||||
{
|
||||
align: "center",
|
||||
fixed: true,
|
||||
label: "ID",
|
||||
prop: "id"
|
||||
},
|
||||
{
|
||||
align: "center",
|
||||
label: "图片",
|
||||
prop: "image",
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "Banner名称",
|
||||
prop: "title"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "Banner分类",
|
||||
prop: "banner_name"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "Banner排序",
|
||||
prop: "sort"
|
||||
},
|
||||
|
||||
{
|
||||
align: "left",
|
||||
label: "添加时间",
|
||||
prop: "created_at"
|
||||
},
|
||||
|
||||
{ prop: "operation", label: "操作", fixed: "right", width: 200 }
|
||||
];
|
||||
339
src/views/bannerManagement/list/index.vue
Normal file
339
src/views/bannerManagement/list/index.vue
Normal file
@@ -0,0 +1,339 @@
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<div style="padding-bottom: 16px">
|
||||
<el-button type="primary" @click="handleAdd"> 添加 </el-button>
|
||||
<el-button type="primary" @click="handleExport"> 导出 </el-button>
|
||||
</div>
|
||||
<ProTable
|
||||
ref="proTableRef"
|
||||
:formData="dataStore.formData"
|
||||
:columns="dataStore.columns"
|
||||
:request-api="getBannerListApi"
|
||||
:init-param="dataStore.initParam"
|
||||
>
|
||||
<template #image="scope">
|
||||
<el-image :src="h + scope.row.image" style="width: 60px; height: 60px" />
|
||||
</template>
|
||||
<template #sort="scope">
|
||||
<el-input v-model="scope.row.sort" @blur="handleBlur(scope.row)" @input="handleInput(scope.row)"></el-input>
|
||||
</template>
|
||||
<template #operation="scope">
|
||||
<el-button size="small" type="primary" @click="getBannerRead(scope.row.id)">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click="getBannerDel(scope.row.id)">删除</el-button>
|
||||
</template>
|
||||
</ProTable>
|
||||
<el-drawer
|
||||
v-model="dataStore.visible"
|
||||
:show-close="true"
|
||||
:size="640"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
:before-close="handleBeforeClone"
|
||||
destroy-on-close
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<h4 :id="titleId" :class="titleClass">{{ dataStore.title }}</h4>
|
||||
</template>
|
||||
<div>
|
||||
<rulesForm
|
||||
:ruleForm="dataStore.editRuleForm"
|
||||
:formData="dataStore.editFormData"
|
||||
:rules="dataStore.rules"
|
||||
ref="formRef"
|
||||
@handleRadioGroupEmits="handleRadioGroupEmits"
|
||||
>
|
||||
<el-input v-model.trim="dataStore.editRuleForm.link" clearable style="width: 440px">
|
||||
<template #append>
|
||||
<el-tree-select
|
||||
lazy
|
||||
:props="treeProps"
|
||||
:load="getSystemUrls"
|
||||
show-checkbox
|
||||
v-model="selectedNodes"
|
||||
ref="treeRef"
|
||||
check-strictly
|
||||
accordion
|
||||
:cache-data="dataStore.data"
|
||||
@check="handleCheck"
|
||||
placeholder="请选择"
|
||||
style="padding: 0"
|
||||
@visible-change="visibleChange"
|
||||
/>
|
||||
</template>
|
||||
</el-input>
|
||||
</rulesForm>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div style="flex: auto">
|
||||
<el-button @click="handleResetClick">重置</el-button>
|
||||
<el-button type="primary" @click="handleConfirmClick">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="bannerListIndex">
|
||||
import rulesForm from "@/components/rulesForm/index.vue";
|
||||
import ProTable from "@/components/ProTable/index.vue";
|
||||
import { messageBox } from "@/utils/messageBox";
|
||||
import { useMsg } from "@/hooks/useMsg";
|
||||
import { useExport } from "@/hooks/useExport";
|
||||
import { integerRexg } from "@/utils/regexp/index";
|
||||
// 图片地址
|
||||
const h = import.meta.env.VITE_APP_API_BASE_UPLOAD_URL;
|
||||
// 列表接口
|
||||
import {
|
||||
getBannerListApi,
|
||||
getBannerDelApi,
|
||||
getBannerReadApi,
|
||||
getBannerListSortApi,
|
||||
getBannerUpApi,
|
||||
getBannerListSaveApi,
|
||||
getBannerListExportApi
|
||||
} from "@/api/modules/banner";
|
||||
import { getBannerClassListApi } from "@/api/modules/bannerClass";
|
||||
import { getSystemUrlsApi } from "@/api/modules/home";
|
||||
// 深拷贝方法
|
||||
import { cloneDeep } from "lodash-es";
|
||||
// 表格和搜索條件
|
||||
import { RULE_FORM, FORM_DATA, COLUMNS, EDIT_FORM_DATA, EDIT_FORM_DATA1, EDIT_RULE_FORM, RULES, RULES1 } from "./constant/index";
|
||||
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
|
||||
const proTableRef = ref<any>(null);
|
||||
const formRef: any = ref(null);
|
||||
// 数据源
|
||||
const dataStore = reactive<any>({
|
||||
title: "添加Banner",
|
||||
columns: COLUMNS, // 列表配置项
|
||||
rules: cloneDeep(RULES), // 抽屉表单验证
|
||||
editRuleForm: cloneDeep(EDIT_RULE_FORM),
|
||||
editFormData: cloneDeep(EDIT_FORM_DATA), // 抽屉表单配置项
|
||||
initParam: cloneDeep(RULE_FORM), // 初始化搜索条件|重置搜索条件
|
||||
ruleForm: cloneDeep(RULE_FORM), // 搜索參數
|
||||
formData: FORM_DATA, // 搜索配置项 dataStore.formData
|
||||
visible: false,
|
||||
data: [],
|
||||
is: false
|
||||
});
|
||||
|
||||
const selectedNodes = ref(null);
|
||||
|
||||
const treeRef = ref(null);
|
||||
|
||||
// 配置 tree-select 的属性
|
||||
const treeProps = {
|
||||
children: "children",
|
||||
label: "label",
|
||||
value: "value"
|
||||
};
|
||||
const visibleChange = (is: any) => {
|
||||
dataStore.is = is;
|
||||
if (dataStore.is) {
|
||||
}
|
||||
};
|
||||
const buildTree = (data: any, outerLinkTo: any = "") => {
|
||||
return data.map((item: any) => {
|
||||
const { name, id, url, data: childData = [], children: nestedChildren = [] } = item;
|
||||
const currentLinkTo = item.link_to || outerLinkTo;
|
||||
const value = id ? `${currentLinkTo}/${id}/${name}` : currentLinkTo || name;
|
||||
|
||||
const combinedChildren = [...childData, ...nestedChildren];
|
||||
const childNodes = buildTree(combinedChildren, currentLinkTo);
|
||||
|
||||
return {
|
||||
label: name,
|
||||
value,
|
||||
url,
|
||||
link_to: currentLinkTo,
|
||||
children: childNodes
|
||||
};
|
||||
});
|
||||
};
|
||||
let isFirstRequest = true;
|
||||
const getSystemUrls = async (node: any, resolve: any) => {
|
||||
//第一次请求
|
||||
if (isFirstRequest) {
|
||||
const result = await getSystemUrlsApi();
|
||||
if (result?.code === 0) {
|
||||
const children = buildTree(result?.data);
|
||||
resolve(children);
|
||||
isFirstRequest = false;
|
||||
}
|
||||
} else {
|
||||
//第二次请求
|
||||
if (node.data.children) {
|
||||
resolve(node.data.children);
|
||||
}
|
||||
if (!node.data.children.length && !node.data.url && node.level > 1) {
|
||||
const [link_to, id] = node?.data?.value?.split("/");
|
||||
const result = await getSystemUrlsApi({ link_to, id });
|
||||
if (result?.code === 0) {
|
||||
const children = buildTree(result?.data, link_to);
|
||||
resolve(children);
|
||||
} else {
|
||||
resolve([]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
// 详情
|
||||
const getBannerRead = async (id: any) => {
|
||||
dataStore.title = "编辑Banner";
|
||||
dataStore.visible = true;
|
||||
const result = await getBannerReadApi(id);
|
||||
if (result?.code === 0) {
|
||||
dataStore.editRuleForm = result?.data;
|
||||
if (dataStore.editRuleForm.link && dataStore.editRuleForm.link_to) {
|
||||
let { id, name, link } = dataStore.editRuleForm.link_echo_data;
|
||||
let obj: any = {
|
||||
label: name, // 确保这里的name是你想要显示的文本
|
||||
value: `${dataStore.editRuleForm.link_to}` + "/" + `${id}` + "/" + `${name}`,
|
||||
url: link,
|
||||
link_to: dataStore.editRuleForm.link_to,
|
||||
children: []
|
||||
};
|
||||
let data: any = [];
|
||||
data.push(obj);
|
||||
selectedNodes.value = obj.value;
|
||||
dataStore.data = data;
|
||||
}
|
||||
}
|
||||
};
|
||||
const handleCheck = (checkedNodes: any, values: any) => {
|
||||
const { checkedKeys } = values;
|
||||
if (checkedKeys.length) {
|
||||
dataStore.editRuleForm.link = checkedNodes.url;
|
||||
dataStore.editRuleForm.link_to = checkedNodes.link_to;
|
||||
} else {
|
||||
dataStore.editRuleForm.link = "";
|
||||
dataStore.editRuleForm.link_to = "";
|
||||
}
|
||||
};
|
||||
|
||||
// 更新
|
||||
const getBannerUp = async () => {
|
||||
const result = await getBannerUpApi(dataStore.editRuleForm);
|
||||
if (result?.code === 0) {
|
||||
dataStore.visible = false;
|
||||
dataStore.editRuleForm = cloneDeep(EDIT_RULE_FORM);
|
||||
formRef!.value!.ruleFormRef.resetFields();
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
};
|
||||
|
||||
// 分类
|
||||
const getBannerClassList = async () => {
|
||||
const result = await getBannerClassListApi({ page: 1, size: 500 });
|
||||
if (result?.code === 0) {
|
||||
let arr: any = [];
|
||||
result?.data?.data?.forEach((item: any) => {
|
||||
arr.push({ value: item.id, label: item.name });
|
||||
});
|
||||
dataStore.formData[1].options = arr;
|
||||
dataStore.editFormData[4].options = arr;
|
||||
}
|
||||
};
|
||||
getBannerClassList();
|
||||
// 新增 getBannerListSave
|
||||
const getBannerListSave = async () => {
|
||||
const result = await getBannerListSaveApi(dataStore.editRuleForm);
|
||||
if (result?.code === 0) {
|
||||
dataStore.visible = false;
|
||||
dataStore.editRuleForm = cloneDeep(EDIT_RULE_FORM);
|
||||
useMsg("success", result?.msg);
|
||||
formRef!.value!.ruleFormRef.resetFields();
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
};
|
||||
// 导出接口
|
||||
const getArticleListExport = async () => {
|
||||
const result = await getBannerListExportApi(dataStore.ruleForm);
|
||||
await useExport(result);
|
||||
};
|
||||
// 导出
|
||||
const handleExport = () => {
|
||||
getArticleListExport();
|
||||
};
|
||||
// 抽屉确认
|
||||
const handleConfirmClick = () => {
|
||||
if (!formRef.value!.ruleFormRef) return;
|
||||
formRef!.value!.ruleFormRef!.validate((valid: any) => {
|
||||
if (valid) {
|
||||
dataStore.title === "编辑Banner" ? getBannerUp() : getBannerListSave();
|
||||
console.log("submit!");
|
||||
} else {
|
||||
console.log("error submit!");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
// 重置验证状态
|
||||
const resetFields = () => {
|
||||
if (!formRef.value!.ruleFormRef) return;
|
||||
formRef!.value!.ruleFormRef.resetFields();
|
||||
};
|
||||
// 抽屉重置
|
||||
const handleResetClick = () => {
|
||||
if (dataStore.title === "添加Banner") {
|
||||
resetFields();
|
||||
} else {
|
||||
getBannerRead(dataStore.editRuleForm.id);
|
||||
}
|
||||
};
|
||||
// 添加
|
||||
const handleAdd = () => {
|
||||
dataStore.title = "添加Banner";
|
||||
dataStore.visible = true;
|
||||
};
|
||||
// 抽屉关闭前的钩子
|
||||
const handleBeforeClone = () => {
|
||||
dataStore.editRuleForm = cloneDeep(EDIT_RULE_FORM);
|
||||
resetFields();
|
||||
dataStore.visible = false;
|
||||
};
|
||||
|
||||
const handleRadioGroupEmits = (value: any) => {
|
||||
if (value === "image") {
|
||||
dataStore.editFormData = EDIT_FORM_DATA;
|
||||
dataStore.rules = RULES;
|
||||
} else {
|
||||
dataStore.editFormData = EDIT_FORM_DATA1;
|
||||
dataStore.rules = RULES1;
|
||||
}
|
||||
};
|
||||
// 删除
|
||||
const getBannerDel = async (id: any) => {
|
||||
messageBox("你确定要删除?", async () => {
|
||||
const result = await getBannerDelApi(id);
|
||||
if (result?.code === 0) {
|
||||
const { msg } = result;
|
||||
useMsg("success", msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
});
|
||||
};
|
||||
// 排序
|
||||
const getBannerListSort = async (row: any) => {
|
||||
const result = await getBannerListSortApi({ id: row.id, sort: row.sort });
|
||||
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
};
|
||||
|
||||
// 排序 input 框失焦
|
||||
const handleBlur = (row: any) => {
|
||||
getBannerListSort(row);
|
||||
};
|
||||
// 排序 input 输入
|
||||
const handleInput = (row: any) => {
|
||||
row.sort = integerRexg(row.sort);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
::v-deep(.el-input-group__append) {
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
55
src/views/downloadManagement/class/constant/edit.ts
Normal file
55
src/views/downloadManagement/class/constant/edit.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
disabled?: boolean;
|
||||
fileList?: any;
|
||||
}
|
||||
export const EDIT_FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "name",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "文章分类名称: "
|
||||
},
|
||||
|
||||
{
|
||||
prop: "sort",
|
||||
placeholder: "请输入",
|
||||
type: "inputNumber",
|
||||
label: "下载分类排序: "
|
||||
},
|
||||
{
|
||||
prop: "is_show",
|
||||
placeholder: "请输入",
|
||||
type: "radio",
|
||||
label: "是否显示: ",
|
||||
options: [
|
||||
{
|
||||
label: "是",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: "否",
|
||||
value: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
export const EDIT_RULE_FORM = {
|
||||
sort: 1
|
||||
};
|
||||
// editRuleForm: {},
|
||||
//editFormData: [],
|
||||
5
src/views/downloadManagement/class/constant/index.ts
Normal file
5
src/views/downloadManagement/class/constant/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { FORM_DATA, RULE_FORM } from "./search";
|
||||
import { COLUMNS } from "./table";
|
||||
import { RULES } from "./rules";
|
||||
import { EDIT_FORM_DATA, EDIT_RULE_FORM } from "./edit";
|
||||
export { FORM_DATA, RULE_FORM, COLUMNS, EDIT_FORM_DATA, EDIT_RULE_FORM, RULES };
|
||||
4
src/views/downloadManagement/class/constant/rules.ts
Normal file
4
src/views/downloadManagement/class/constant/rules.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export const RULES = {
|
||||
name: [{ required: true, message: "文章分类名称不能为空 ! ", trigger: "blur" }],
|
||||
sort: [{ required: true, message: "下载分类排序不能为空 ! ", trigger: "blur" }]
|
||||
};
|
||||
31
src/views/downloadManagement/class/constant/search.ts
Normal file
31
src/views/downloadManagement/class/constant/search.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
}
|
||||
export const FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "name",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
isArray: true,
|
||||
label: "下载名称: "
|
||||
}
|
||||
];
|
||||
|
||||
export const RULE_FORM = {
|
||||
page: 1,
|
||||
size: 50
|
||||
};
|
||||
36
src/views/downloadManagement/class/constant/table.ts
Normal file
36
src/views/downloadManagement/class/constant/table.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { RenderScope } from "@/components/ProTable/interface";
|
||||
const YES_OR_NO: any = {
|
||||
0: "❌",
|
||||
1: "✔️"
|
||||
};
|
||||
export const COLUMNS = [
|
||||
{
|
||||
align: "center",
|
||||
fixed: true,
|
||||
label: "ID",
|
||||
prop: "id",
|
||||
width: 80
|
||||
},
|
||||
|
||||
{
|
||||
align: "left",
|
||||
label: "下载分类名称",
|
||||
prop: "name"
|
||||
},
|
||||
|
||||
{
|
||||
align: "left",
|
||||
label: "下载分类排序",
|
||||
prop: "sort"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "是否显示",
|
||||
prop: "is_show",
|
||||
render: (scope: RenderScope<any>): VNode | string | any => {
|
||||
return YES_OR_NO[scope.row.is_show];
|
||||
}
|
||||
},
|
||||
|
||||
{ prop: "operation", label: "操作", fixed: "right", width: 260 }
|
||||
];
|
||||
208
src/views/downloadManagement/class/index.vue
Normal file
208
src/views/downloadManagement/class/index.vue
Normal file
@@ -0,0 +1,208 @@
|
||||
<!-- 视频列表 -->
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<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="getCategoryListApi"
|
||||
:init-param="dataStore.initParam"
|
||||
>
|
||||
<template #image="scope">
|
||||
<el-image :src="h + scope.row.image" style="width: 60px; height: 60px" />
|
||||
</template>
|
||||
<template #status="scope">
|
||||
<el-tag type="success" effect="dark">{{ scope.row.status }}</el-tag>
|
||||
</template>
|
||||
<template #sort="scope">
|
||||
<el-input v-model="scope.row.sort" @blur="handleBlur(scope.row)" @input="handleInput(scope.row)"></el-input>
|
||||
</template>
|
||||
<template #operation="scope">
|
||||
<el-button size="small" type="primary" @click="handleBtnClick('编辑', scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="primary" @click="handleBtnClick('添加', scope.row)">添加下载</el-button>
|
||||
<el-button size="small" type="danger" @click="handleBtnClick('删除', scope.row)">删除</el-button>
|
||||
</template>
|
||||
</ProTable>
|
||||
<el-drawer
|
||||
v-model="dataStore.visible"
|
||||
:show-close="true"
|
||||
:size="600"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
:before-close="handleBeforeClone"
|
||||
destroy-on-close
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<h4 :id="titleId" :class="titleClass">{{ dataStore.title }}</h4>
|
||||
</template>
|
||||
<div>
|
||||
<rulesForm
|
||||
:ruleForm="dataStore.editRuleForm"
|
||||
:formData="dataStore.editFormData"
|
||||
:rules="dataStore.rules"
|
||||
ref="formRef"
|
||||
/>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div style="flex: auto">
|
||||
<el-button @click="handleResetClick">重置</el-button>
|
||||
<el-button type="primary" @click="handleConfirmClick">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="downloadClassListIndex">
|
||||
import ProTable from "@/components/ProTable/index.vue";
|
||||
import rulesForm from "@/components/rulesForm/index.vue";
|
||||
import { messageBox } from "@/utils/messageBox";
|
||||
import { useMsg } from "@/hooks/useMsg";
|
||||
import { integerRexg } from "@/utils/regexp/index";
|
||||
const h = import.meta.env.VITE_APP_API_BASE_UPLOAD_URL;
|
||||
//列表接口
|
||||
import {
|
||||
getCategoryListApi,
|
||||
getCategoryDelApi,
|
||||
getCategorySortApi,
|
||||
getCategorySaveApi,
|
||||
getCategoryReadApi,
|
||||
getCategoryUpdateApi
|
||||
} from "@/api/modules/downloadClass";
|
||||
//深拷贝方法
|
||||
import { cloneDeep } from "lodash-es";
|
||||
//表格和搜索條件
|
||||
import { RULE_FORM, FORM_DATA, COLUMNS, EDIT_FORM_DATA, EDIT_RULE_FORM, RULES } from "./constant/index";
|
||||
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
|
||||
const proTableRef = ref<any>(null);
|
||||
const formRef: any = ref(null);
|
||||
const $router = useRouter();
|
||||
// 数据源
|
||||
const dataStore = reactive<any>({
|
||||
title: "添加下载分类",
|
||||
columns: COLUMNS, //列表配置项
|
||||
rules: cloneDeep(RULES), //抽屉表单验证
|
||||
editRuleForm: cloneDeep(EDIT_RULE_FORM),
|
||||
editFormData: cloneDeep(EDIT_FORM_DATA), //抽屉表单配置项
|
||||
initParam: cloneDeep(RULE_FORM), // 初始化搜索条件|重置搜索条件
|
||||
ruleForm: cloneDeep(RULE_FORM), // 搜索參數
|
||||
formData: FORM_DATA, //搜索配置项
|
||||
visible: false,
|
||||
selectRow: {} //当前选择的row
|
||||
});
|
||||
|
||||
//抽屉确认
|
||||
const handleConfirmClick = () => {
|
||||
if (!formRef.value!.ruleFormRef) return;
|
||||
formRef!.value!.ruleFormRef!.validate((valid: any) => {
|
||||
if (valid) {
|
||||
console.log("submit!");
|
||||
|
||||
dataStore.title === "添加下载分类" ? getCategorySave() : getCategoryUpdate();
|
||||
} else {
|
||||
console.log("error submit!");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
//重置验证状态
|
||||
const resetFields = () => {
|
||||
if (!formRef.value!.ruleFormRef) return;
|
||||
formRef!.value!.ruleFormRef.resetFields();
|
||||
};
|
||||
//抽屉重置
|
||||
const handleResetClick = () => {
|
||||
dataStore.title === "添加下载分类" ? resetFields() : getCategoryRead(dataStore.editRuleForm.id);
|
||||
};
|
||||
//添加
|
||||
const handleAdd = () => {
|
||||
dataStore.visible = true;
|
||||
};
|
||||
const handleBeforeClone = () => {
|
||||
dataStore.editRuleForm = cloneDeep(EDIT_RULE_FORM);
|
||||
resetFields();
|
||||
dataStore.visible = false;
|
||||
};
|
||||
//按钮点击事件
|
||||
const handleBtnClick = (type: any, row: any) => {
|
||||
dataStore.selectRow = row;
|
||||
//编辑
|
||||
if (type === "编辑") {
|
||||
dataStore.visible = true;
|
||||
dataStore.title = "编辑下载分类";
|
||||
getCategoryRead(row.id);
|
||||
return;
|
||||
}
|
||||
if (type === "添加") {
|
||||
$router.push({
|
||||
path: "/admin/downloadManagement/list/edit",
|
||||
query: {
|
||||
title: "添加下载"
|
||||
}
|
||||
});
|
||||
}
|
||||
//删除
|
||||
if (type === "删除") {
|
||||
getCategoryDel(row.id);
|
||||
}
|
||||
};
|
||||
//更新
|
||||
const getCategoryUpdate = async () => {
|
||||
const result = await getCategoryUpdateApi(dataStore.editRuleForm);
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
dataStore.visible = false;
|
||||
dataStore.editRuleForm = cloneDeep(EDIT_RULE_FORM);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
};
|
||||
//详情
|
||||
const getCategoryRead = async (id: any) => {
|
||||
const result = await getCategoryReadApi(id);
|
||||
if (result?.code === 0) {
|
||||
dataStore.editRuleForm = result?.data;
|
||||
}
|
||||
};
|
||||
//添加
|
||||
const getCategorySave = async () => {
|
||||
const result = await getCategorySaveApi(dataStore.editRuleForm);
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
dataStore.visible = false;
|
||||
dataStore.editRuleForm = cloneDeep(EDIT_RULE_FORM);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
};
|
||||
//删除
|
||||
const getCategoryDel = (id: any) => {
|
||||
messageBox("你确定要删除?", async () => {
|
||||
const result = await getCategoryDelApi(id);
|
||||
if (result?.code === 0) {
|
||||
const { msg } = result;
|
||||
useMsg("success", msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
});
|
||||
};
|
||||
//排序input框失焦
|
||||
const handleBlur = (row: any) => {
|
||||
getCategorySort(row);
|
||||
};
|
||||
//排序input输入
|
||||
const handleInput = (row: any) => {
|
||||
row.sort = integerRexg(row.sort);
|
||||
};
|
||||
//排序
|
||||
const getCategorySort = async (row: any) => {
|
||||
const result = await getCategorySortApi({ id: row.id, sort: row.sort });
|
||||
useMsg("success", result?.msg);
|
||||
if (result?.code === 0) {
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
111
src/views/downloadManagement/list/constant/edit.ts
Normal file
111
src/views/downloadManagement/list/constant/edit.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
disabled?: boolean;
|
||||
fileList?: any;
|
||||
prompt?: any;
|
||||
}
|
||||
export const EDIT_FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "name",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "下载名称: "
|
||||
},
|
||||
|
||||
{
|
||||
prop: "category_id",
|
||||
placeholder: "请选择",
|
||||
type: "select",
|
||||
label: "下载分类: ",
|
||||
options: []
|
||||
},
|
||||
{
|
||||
prop: "sort",
|
||||
placeholder: "请输入",
|
||||
type: "inputNumber",
|
||||
label: "下载排序: "
|
||||
},
|
||||
{
|
||||
prop: "recommend",
|
||||
placeholder: "请输入",
|
||||
type: "radio",
|
||||
label: "首页推荐: ",
|
||||
options: [
|
||||
{
|
||||
label: "是",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: "否",
|
||||
value: 0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
prop: "image",
|
||||
type: "upImg",
|
||||
label: "下载图片: ",
|
||||
prompt: "图片尺寸320x320"
|
||||
},
|
||||
{
|
||||
prop: "table",
|
||||
type: "table",
|
||||
label: "下载文件: "
|
||||
},
|
||||
{
|
||||
prop: "applicable_to",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "适合型号: "
|
||||
},
|
||||
{
|
||||
prop: "support_platform",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "支持系统: "
|
||||
},
|
||||
|
||||
{
|
||||
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_TABLE_DATA = [
|
||||
{
|
||||
file_path: "", //文件路径
|
||||
btn_name: "", //按钮名字
|
||||
file_ext: "" //文件格式
|
||||
}
|
||||
];
|
||||
export const EDIT_RULE_FORM = {};
|
||||
// editRuleForm: {},
|
||||
//editFormData: [],
|
||||
5
src/views/downloadManagement/list/constant/index.ts
Normal file
5
src/views/downloadManagement/list/constant/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { FORM_DATA, RULE_FORM } from "./search";
|
||||
import { COLUMNS } from "./table";
|
||||
import { RULES } from "./rules";
|
||||
import { EDIT_FORM_DATA, EDIT_RULE_FORM, EDIT_TABLE_DATA } from "./edit";
|
||||
export { FORM_DATA, RULE_FORM, COLUMNS, EDIT_FORM_DATA, EDIT_RULE_FORM, RULES, EDIT_TABLE_DATA };
|
||||
5
src/views/downloadManagement/list/constant/rules.ts
Normal file
5
src/views/downloadManagement/list/constant/rules.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export const RULES = {
|
||||
name: [{ required: true, message: "下载名称不能为空 ! ", trigger: "blur" }],
|
||||
category_id: [{ required: true, message: "下载分类不能为空 ! ", trigger: "blur" }],
|
||||
sort: [{ required: true, message: "下载排序不能为空 ! ", trigger: "blur" }]
|
||||
};
|
||||
50
src/views/downloadManagement/list/constant/search.ts
Normal file
50
src/views/downloadManagement/list/constant/search.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
}
|
||||
export const FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "name",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
isArray: true,
|
||||
label: "下载名称: "
|
||||
},
|
||||
|
||||
{
|
||||
prop: "category_id",
|
||||
placeholder: "请选择",
|
||||
type: "select",
|
||||
isArray: true,
|
||||
label: "下载分类: ",
|
||||
options: []
|
||||
},
|
||||
{
|
||||
prop: "Time",
|
||||
type: "daterange",
|
||||
options: [],
|
||||
startPlaceholder: "开始日期",
|
||||
endPlaceholder: "结束日期",
|
||||
startDate: "created_at",
|
||||
// endDate: "createEndDate",
|
||||
label: "添加时间: "
|
||||
}
|
||||
];
|
||||
|
||||
export const RULE_FORM = {
|
||||
page: 1,
|
||||
size: 50
|
||||
};
|
||||
59
src/views/downloadManagement/list/constant/table.ts
Normal file
59
src/views/downloadManagement/list/constant/table.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { RenderScope } from "@/components/ProTable/interface";
|
||||
const YES_OR_NO: any = {
|
||||
1: "✔️",
|
||||
0: "❌"
|
||||
};
|
||||
export const COLUMNS = [
|
||||
{
|
||||
align: "center",
|
||||
fixed: true,
|
||||
label: "ID",
|
||||
prop: "id",
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
align: "center",
|
||||
label: "图片",
|
||||
prop: "image",
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "下载名称",
|
||||
prop: "name"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "下载分类",
|
||||
prop: "category_name"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "下载排序",
|
||||
prop: "sort",
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "首页推荐",
|
||||
prop: "recommend",
|
||||
render: (scope: RenderScope<any>): VNode | string | any => {
|
||||
return YES_OR_NO[scope.row.recommend];
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
align: "left",
|
||||
label: "添加时间",
|
||||
prop: "created_at"
|
||||
},
|
||||
|
||||
{
|
||||
align: "center",
|
||||
label: "状态",
|
||||
prop: "status",
|
||||
width: 80
|
||||
},
|
||||
|
||||
{ prop: "operation", label: "操作", fixed: "right", width: 200 }
|
||||
];
|
||||
268
src/views/downloadManagement/list/edit.vue
Normal file
268
src/views/downloadManagement/list/edit.vue
Normal file
@@ -0,0 +1,268 @@
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<div style="padding-bottom: 16px">
|
||||
<el-button @click="handleResetClick()"> 重置 </el-button>
|
||||
<el-button type="primary" @click="handleConfirmClick()"> 提交 </el-button>
|
||||
</div>
|
||||
<div class="card table-main">
|
||||
<div style="width: 900px">
|
||||
<rulesForm
|
||||
:ruleForm="dataStore.editRuleForm"
|
||||
:formData="dataStore.editFormData"
|
||||
:rules="dataStore.rules"
|
||||
ref="formRef"
|
||||
>
|
||||
<el-button type="primary" size="small" style="margin-bottom: 10px" @click="handleEditAdd">添加行</el-button>
|
||||
<FormTable :columns="dataStore.editColumns" :tableData="dataStore.editTableData" :height="200">
|
||||
<template #up="scope">
|
||||
<el-upload
|
||||
action="#"
|
||||
class="upload"
|
||||
:limit="1"
|
||||
:multiple="true"
|
||||
:show-file-list="false"
|
||||
:http-request="param => uploadExcel(param)"
|
||||
:before-upload="file => beforeExcelUpload(file)"
|
||||
:on-exceed="handleExceed"
|
||||
:on-success="(response, file, fileList) => excelUploadSuccess(response, scope.row)"
|
||||
:on-error="excelUploadError"
|
||||
:accept="filesType!.join(',')"
|
||||
ref="uploadRef"
|
||||
>
|
||||
<el-button type="primary" size="small">文件上传</el-button>
|
||||
</el-upload>
|
||||
<!-- 显示文件名 -->
|
||||
<div v-if="scope.row.file_path" style="display: flex; align-items: center; justify-content: center">
|
||||
<span style="padding: 0 10px; margin-right: 20px; border: 1px solid #eeeeee">
|
||||
{{ scope.row.file_path }}</span
|
||||
>
|
||||
<el-icon style="cursor: pointer" @click="handleDelete(scope.row)"><Delete /></el-icon>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #operation="scope">
|
||||
<el-button type="danger" size="small" @click="handleEditDelete(scope)">删除行</el-button>
|
||||
</template>
|
||||
</FormTable>
|
||||
</rulesForm>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import rulesForm from "@/components/rulesForm/index.vue";
|
||||
import FormTable from "@/components/FormTable/index.vue";
|
||||
import { EDIT_TABLE_DATA, RULES, EDIT_RULE_FORM, EDIT_FORM_DATA } from "./constant/index";
|
||||
import { useMsg } from "@/hooks/useMsg";
|
||||
import { Delete } from "@element-plus/icons-vue";
|
||||
const $route = useRoute();
|
||||
import { getCategorysApi } from "@/api/modules/downloadClass";
|
||||
//深拷贝方法
|
||||
import { cloneDeep } from "lodash-es";
|
||||
import {
|
||||
getAttachmentUpFileApi,
|
||||
getAttachmentSaveApi,
|
||||
getAttachmentUpdateApi,
|
||||
getAttachmentReadApi
|
||||
} from "@/api/modules/downloadList";
|
||||
//上传文件格式
|
||||
const filesType = ref([".inf", ".sys", ".dll", ".exe", ".cat", ".ko", ".rpm", ".kext", ".zip", ".bin", ".rar", ".tar", ".gz"]);
|
||||
const dataStore = reactive<any>({
|
||||
rules: cloneDeep(RULES), //抽屉表单验证
|
||||
editRuleForm: cloneDeep(EDIT_RULE_FORM),
|
||||
editFormData: cloneDeep(EDIT_FORM_DATA), //抽屉表单配置项
|
||||
editTableData: cloneDeep(EDIT_TABLE_DATA), //添加|编辑里的表格数据
|
||||
editColumns: [
|
||||
{
|
||||
label: "文件",
|
||||
prop: "file_path",
|
||||
disabled: false,
|
||||
formType: "up",
|
||||
width: "350",
|
||||
align: "left"
|
||||
},
|
||||
{
|
||||
label: "文件格式",
|
||||
prop: "file_ext",
|
||||
disabled: false,
|
||||
formType: "input",
|
||||
maxLength: 50,
|
||||
width: "150"
|
||||
},
|
||||
//operation
|
||||
{
|
||||
label: "按钮名称",
|
||||
prop: "btn_name",
|
||||
disabled: false,
|
||||
formType: "input",
|
||||
maxLength: 50,
|
||||
width: "150"
|
||||
},
|
||||
{
|
||||
label: "操作",
|
||||
prop: "operation",
|
||||
|
||||
width: "112"
|
||||
}
|
||||
] //添加|编辑里的表格配置项
|
||||
});
|
||||
const formRef: any = ref(null);
|
||||
const uploadRef = ref<any>(null);
|
||||
// 文件上传
|
||||
const uploadExcel = async (param: any) => {
|
||||
let excelFormData = new FormData();
|
||||
excelFormData.append("attachment", param.file);
|
||||
const result = await getAttachmentUpFileApi(excelFormData);
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* @description 文件上传之前判断
|
||||
* @param file 上传的文件
|
||||
* @param row 当前行数据
|
||||
* */
|
||||
const beforeExcelUpload = (file: any) => {
|
||||
const maxSize = 50 * 1024 * 1024;
|
||||
if (file.size > maxSize) {
|
||||
setTimeout(() => {
|
||||
ElNotification({
|
||||
title: "温馨提示",
|
||||
message: `上传文件大小不能超过 ${50}MB!`,
|
||||
type: "warning"
|
||||
});
|
||||
}, 0);
|
||||
}
|
||||
// return isExcel && fileSize;
|
||||
};
|
||||
|
||||
// 上传错误提示
|
||||
const excelUploadError = () => {
|
||||
ElNotification({
|
||||
title: "温馨提示",
|
||||
message: `文件上传失败,请您重新上传!`,
|
||||
type: "error"
|
||||
});
|
||||
};
|
||||
|
||||
// 上传成功提示
|
||||
const excelUploadSuccess = (response: any, row: any) => {
|
||||
console.log(response, "=response=");
|
||||
// 假设后端返回的数据中有文件路径和文件格式
|
||||
if (response?.code === 0) {
|
||||
row.file_path = response.data.path; // 假设后端返回的文件路径在 data.path 中
|
||||
}
|
||||
console.log(row, "====row========");
|
||||
ElNotification({
|
||||
title: "温馨提示",
|
||||
message: `文件上传成功!`,
|
||||
type: "success"
|
||||
});
|
||||
};
|
||||
// 文件数超出提示
|
||||
const handleExceed = () => {
|
||||
ElNotification({
|
||||
title: "温馨提示",
|
||||
message: "最多只能上传一个文件!",
|
||||
type: "warning"
|
||||
});
|
||||
};
|
||||
//添加
|
||||
const getAttachmentSave = async () => {
|
||||
const result = await getAttachmentSaveApi({ ...dataStore.editRuleForm, attach: JSON.stringify(dataStore.editTableData) });
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
}
|
||||
};
|
||||
// //更新
|
||||
const getAttachmentUpdate = async () => {
|
||||
const result = await getAttachmentUpdateApi({ ...dataStore.editRuleForm, attach: JSON.stringify(dataStore.editTableData) });
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
}
|
||||
};
|
||||
//抽屉确认
|
||||
const handleConfirmClick = () => {
|
||||
if (!formRef.value!.ruleFormRef) return;
|
||||
formRef!.value!.ruleFormRef!.validate((valid: any) => {
|
||||
if (valid) {
|
||||
console.log("submit!");
|
||||
$route.query.title === "添加下载" ? getAttachmentSave() : getAttachmentUpdate();
|
||||
} else {
|
||||
console.log("error submit!");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
//抽屉重置
|
||||
const handleResetClick = () => {
|
||||
if ($route.query.title === "添加下载") {
|
||||
resetFields();
|
||||
} else {
|
||||
getAttachmentRead();
|
||||
}
|
||||
};
|
||||
//重置验证状态
|
||||
const resetFields = () => {
|
||||
if (!formRef.value!.ruleFormRef) return;
|
||||
formRef!.value!.ruleFormRef.resetFields();
|
||||
};
|
||||
|
||||
const handleEditDelete = (scope: any) => {
|
||||
dataStore.editTableData.splice(scope.$index, 1);
|
||||
};
|
||||
const handleEditAdd = () => {
|
||||
dataStore.editTableData.push({
|
||||
file_path: "", //文件路径
|
||||
btn_name: "", //按钮名字
|
||||
file_ext: "" //文件格式
|
||||
});
|
||||
};
|
||||
//详情
|
||||
const getAttachmentRead = async () => {
|
||||
let id = $route.query.id;
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
const result = await getAttachmentReadApi(id);
|
||||
if (result?.code === 0) {
|
||||
dataStore.editRuleForm = result?.data;
|
||||
dataStore.editTableData = result?.data.attach;
|
||||
}
|
||||
};
|
||||
getAttachmentRead();
|
||||
|
||||
//分类
|
||||
const getCategorys = async () => {
|
||||
const result = await getCategorysApi();
|
||||
|
||||
if (result?.code === 0) {
|
||||
let arr: any[] = [];
|
||||
result?.data?.forEach((item: any) => {
|
||||
let obj = {
|
||||
value: item.id,
|
||||
label: item.name
|
||||
};
|
||||
arr.push(obj);
|
||||
});
|
||||
dataStore.editFormData[1].options = arr;
|
||||
}
|
||||
};
|
||||
getCategorys();
|
||||
const handleDelete = async (row: any) => {
|
||||
row.file_path = "";
|
||||
// 清空上传组件的文件列表
|
||||
|
||||
if (uploadRef.value) {
|
||||
uploadRef.value.clearFiles();
|
||||
}
|
||||
|
||||
ElNotification({
|
||||
title: "温馨提示",
|
||||
message: `文件已删除!`,
|
||||
type: "success"
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
172
src/views/downloadManagement/list/index.vue
Normal file
172
src/views/downloadManagement/list/index.vue
Normal file
@@ -0,0 +1,172 @@
|
||||
<!-- 视频列表 -->
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<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="getAttachmentListApi"
|
||||
:init-param="dataStore.initParam"
|
||||
>
|
||||
<template #image="scope">
|
||||
<el-image :src="h + scope.row.image" style="width: 60px; height: 60px" />
|
||||
</template>
|
||||
<template #status="scope">
|
||||
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'" effect="dark">{{
|
||||
scope.row.status === 1 ? "启用" : "禁用"
|
||||
}}</el-tag>
|
||||
</template>
|
||||
<template #sort="scope">
|
||||
<el-input v-model="scope.row.sort" @blur="handleBlur(scope.row)" @input="handleInput(scope.row)"></el-input>
|
||||
</template>
|
||||
<template #operation="scope">
|
||||
<el-button size="small" type="primary" @click="handleBtnClick('编辑', scope.row)">编辑</el-button>
|
||||
|
||||
<el-button size="small" type="danger" @click="handleBtnClick('删除', scope.row)">删除</el-button>
|
||||
</template>
|
||||
</ProTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="downloadListIndex">
|
||||
import ProTable from "@/components/ProTable/index.vue";
|
||||
|
||||
//列表接口
|
||||
import { getAttachmentListApi, getAttachmentListDelApi, getAttachmentSortApi } from "@/api/modules/downloadList";
|
||||
import { getCategorysApi } from "@/api/modules/downloadClass";
|
||||
import { integerRexg } from "@/utils/regexp/index";
|
||||
import { messageBox } from "@/utils/messageBox";
|
||||
import { useMsg } from "@/hooks/useMsg";
|
||||
//深拷贝方法
|
||||
import { cloneDeep } from "lodash-es";
|
||||
//表格和搜索條件 FORM_DATA
|
||||
import { RULE_FORM, COLUMNS, EDIT_FORM_DATA, EDIT_RULE_FORM, RULES, EDIT_TABLE_DATA, FORM_DATA } from "./constant/index";
|
||||
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
|
||||
const proTableRef = ref<any>(null);
|
||||
const $router = useRouter();
|
||||
|
||||
//图片地址
|
||||
const h = import.meta.env.VITE_APP_API_BASE_UPLOAD_URL;
|
||||
// 数据源
|
||||
const dataStore = reactive<any>({
|
||||
editTableData: cloneDeep(EDIT_TABLE_DATA), //添加|编辑里的表格数据
|
||||
editColumns: [
|
||||
{
|
||||
label: "文件",
|
||||
prop: "file_path",
|
||||
disabled: false,
|
||||
formType: "up",
|
||||
width: "250",
|
||||
align: "left"
|
||||
},
|
||||
{
|
||||
label: "文件格式",
|
||||
prop: "file_ext",
|
||||
disabled: false,
|
||||
formType: "input",
|
||||
maxLength: 50,
|
||||
width: "100"
|
||||
},
|
||||
//operation
|
||||
{
|
||||
label: "按钮名称",
|
||||
prop: "btn_name",
|
||||
disabled: false,
|
||||
formType: "input",
|
||||
maxLength: 50,
|
||||
width: "150"
|
||||
},
|
||||
{
|
||||
label: "操作",
|
||||
prop: "operation",
|
||||
|
||||
width: "112"
|
||||
}
|
||||
], //添加|编辑里的表格配置项
|
||||
formData: cloneDeep(FORM_DATA),
|
||||
columns: COLUMNS, //列表配置项
|
||||
rules: cloneDeep(RULES), //抽屉表单验证
|
||||
editRuleForm: cloneDeep(EDIT_RULE_FORM),
|
||||
editFormData: cloneDeep(EDIT_FORM_DATA), //抽屉表单配置项
|
||||
initParam: cloneDeep(RULE_FORM) // 初始化搜索条件|重置搜索条件
|
||||
});
|
||||
|
||||
//按钮点击事件
|
||||
const handleBtnClick = (type: any, row: any) => {
|
||||
//编辑
|
||||
if (type === "编辑") {
|
||||
$router.push({
|
||||
path: "/admin/downloadManagement/list/edit",
|
||||
query: {
|
||||
id: row.id,
|
||||
title: "编辑下载"
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
//删除
|
||||
if (type === "删除") {
|
||||
getAttachmentListDel(row.id);
|
||||
}
|
||||
};
|
||||
|
||||
const handleAdd = () => {
|
||||
$router.push({
|
||||
path: "/admin/downloadManagement/list/edit",
|
||||
query: {
|
||||
title: "添加下载"
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//删除
|
||||
const getAttachmentListDel = (id: any) => {
|
||||
messageBox("你确定要删除?", async () => {
|
||||
const result = await getAttachmentListDelApi(id);
|
||||
if (result?.code === 0) {
|
||||
const { msg } = result;
|
||||
useMsg("success", msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
});
|
||||
};
|
||||
//排序
|
||||
const getAttachmentSort = async (row: any) => {
|
||||
const result = await getAttachmentSortApi({ id: row.id, sort: row.sort });
|
||||
useMsg("success", result?.msg);
|
||||
if (result?.code === 0) {
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
};
|
||||
|
||||
//排序input框失焦
|
||||
const handleBlur = (row: any) => {
|
||||
getAttachmentSort(row);
|
||||
};
|
||||
//排序input输入
|
||||
const handleInput = (row: any) => {
|
||||
row.sort = integerRexg(row.sort);
|
||||
};
|
||||
const getCategorys = async () => {
|
||||
const result = await getCategorysApi();
|
||||
|
||||
if (result?.code === 0) {
|
||||
let arr: any[] = [];
|
||||
result?.data?.forEach((item: any) => {
|
||||
let obj = {
|
||||
value: item.id,
|
||||
label: item.name
|
||||
};
|
||||
arr.push(obj);
|
||||
});
|
||||
|
||||
dataStore.formData[1].options = arr;
|
||||
}
|
||||
};
|
||||
getCategorys();
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
3
src/views/downloadManagement/recycle/constant/index.ts
Normal file
3
src/views/downloadManagement/recycle/constant/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { FORM_DATA, RULE_FORM } from "./search";
|
||||
import { COLUMNS } from "./table";
|
||||
export { FORM_DATA, RULE_FORM, COLUMNS };
|
||||
40
src/views/downloadManagement/recycle/constant/search.ts
Normal file
40
src/views/downloadManagement/recycle/constant/search.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
}
|
||||
export const FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "name",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
isArray: true,
|
||||
label: "下载名称: "
|
||||
},
|
||||
|
||||
{
|
||||
prop: "category_id",
|
||||
placeholder: "请选择",
|
||||
type: "select",
|
||||
isArray: true,
|
||||
label: "下载分类: ",
|
||||
options: []
|
||||
}
|
||||
];
|
||||
|
||||
export const RULE_FORM = {
|
||||
page: 1,
|
||||
size: 50
|
||||
};
|
||||
60
src/views/downloadManagement/recycle/constant/table.ts
Normal file
60
src/views/downloadManagement/recycle/constant/table.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { RenderScope } from "@/components/ProTable/interface";
|
||||
const YES_OR_NO: any = {
|
||||
1: "✔️",
|
||||
0: "❌"
|
||||
};
|
||||
export const COLUMNS = [
|
||||
{ type: "selection", fixed: "left", width: 40 },
|
||||
{
|
||||
align: "center",
|
||||
fixed: true,
|
||||
label: "ID",
|
||||
prop: "id",
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
align: "center",
|
||||
label: "图片",
|
||||
prop: "image",
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "下载名称",
|
||||
prop: "name"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "下载分类",
|
||||
prop: "category_name"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "下载排序",
|
||||
prop: "sort",
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "首页推荐",
|
||||
prop: "recommend",
|
||||
render: (scope: RenderScope<any>): VNode | string | any => {
|
||||
return YES_OR_NO[scope.row.recommend];
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
align: "left",
|
||||
label: "添加时间",
|
||||
prop: "created_at"
|
||||
},
|
||||
|
||||
{
|
||||
align: "center",
|
||||
label: "状态",
|
||||
prop: "status",
|
||||
width: 80
|
||||
},
|
||||
|
||||
{ prop: "operation", label: "操作", fixed: "right", width: 200 }
|
||||
];
|
||||
96
src/views/downloadManagement/recycle/index.vue
Normal file
96
src/views/downloadManagement/recycle/index.vue
Normal file
@@ -0,0 +1,96 @@
|
||||
<!-- 视频列表 -->
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<ProTable
|
||||
ref="proTableRef"
|
||||
:formData="dataStore.formData"
|
||||
:columns="dataStore.columns"
|
||||
:request-api="getAttachmentTrashListApi"
|
||||
:init-param="dataStore.initParam"
|
||||
>
|
||||
<template #image="scope">
|
||||
<el-image :src="h + scope.row.image" style="width: 60px; height: 60px" />
|
||||
</template>
|
||||
<template #status="scope">
|
||||
<el-tag type="danger" effect="dark">{{ scope.row.status ? "删除" : "删除" }}</el-tag>
|
||||
</template>
|
||||
|
||||
<template #operation="scope">
|
||||
<el-button size="small" type="danger" @click="handleBtnClick('删除', scope.row)">删除</el-button>
|
||||
<el-button size="small" type="primary" @click="handleBtnClick('恢复', scope.row)">恢复</el-button>
|
||||
</template>
|
||||
</ProTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="downloadRecycleListIndex">
|
||||
import ProTable from "@/components/ProTable/index.vue";
|
||||
import { messageBox } from "@/utils/messageBox";
|
||||
import { useMsg } from "@/hooks/useMsg";
|
||||
//列表接口
|
||||
import { getAttachmentTrashListApi, getAttachmentTrashRestoreApi, getAttachmentTrashDelApi } from "@/api/modules/downloadRecycle";
|
||||
import { getCategorysApi } from "@/api/modules/downloadClass";
|
||||
//深拷贝方法
|
||||
import { cloneDeep } from "lodash-es";
|
||||
//表格和搜索條件
|
||||
import { RULE_FORM, FORM_DATA, COLUMNS } from "./constant/index";
|
||||
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
|
||||
const proTableRef = ref<any>(null);
|
||||
//图片地址
|
||||
const h = import.meta.env.VITE_APP_API_BASE_UPLOAD_URL;
|
||||
// 数据源
|
||||
const dataStore = reactive<any>({
|
||||
columns: COLUMNS, //列表配置项
|
||||
initParam: cloneDeep(RULE_FORM), // 初始化搜索条件|重置搜索条件
|
||||
ruleForm: cloneDeep(RULE_FORM), // 搜索參數
|
||||
formData: FORM_DATA //搜索配置项
|
||||
});
|
||||
//分类列表
|
||||
const getCategorys = async () => {
|
||||
const result = await getCategorysApi();
|
||||
|
||||
if (result?.code === 0) {
|
||||
let arr: any[] = [];
|
||||
result?.data?.forEach((item: any) => {
|
||||
let obj = {
|
||||
value: item.id,
|
||||
label: item.name
|
||||
};
|
||||
arr.push(obj);
|
||||
});
|
||||
dataStore.formData[1].options = arr;
|
||||
}
|
||||
};
|
||||
getCategorys();
|
||||
//删除
|
||||
const getAttachmentTrashDel = (id: any) => {
|
||||
messageBox("你确定要删除?", async () => {
|
||||
const result = await getAttachmentTrashDelApi(id);
|
||||
if (result?.code === 0) {
|
||||
const { msg } = result;
|
||||
useMsg("success", msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
});
|
||||
};
|
||||
//恢复
|
||||
const getAttachmentTrashRestore = async (id: any) => {
|
||||
const result = await getAttachmentTrashRestoreApi(id);
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
}
|
||||
};
|
||||
//按钮点击事件
|
||||
const handleBtnClick = (type: any, row: any) => {
|
||||
if (type === "恢复") {
|
||||
getAttachmentTrashRestore(row.id);
|
||||
}
|
||||
//删除
|
||||
if (type === "删除") {
|
||||
getAttachmentTrashDel(row.id);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
4
src/views/feedbackManagement/agent/constant/index.ts
Normal file
4
src/views/feedbackManagement/agent/constant/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { FORM_DATA, RULE_FORM } from "./search";
|
||||
import { COLUMNS } from "./table";
|
||||
|
||||
export { FORM_DATA, RULE_FORM, COLUMNS };
|
||||
57
src/views/feedbackManagement/agent/constant/search.ts
Normal file
57
src/views/feedbackManagement/agent/constant/search.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
}
|
||||
export const FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "corp_name",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
isArray: true,
|
||||
label: "公司名称: "
|
||||
},
|
||||
{
|
||||
prop: "size_type",
|
||||
placeholder: "请选择",
|
||||
type: "select",
|
||||
options: [
|
||||
{
|
||||
value: 1,
|
||||
label: "待审核"
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: "已审核"
|
||||
}
|
||||
],
|
||||
label: "企业规模: "
|
||||
},
|
||||
{
|
||||
prop: "Time",
|
||||
type: "daterange",
|
||||
options: [],
|
||||
startPlaceholder: "开始日期",
|
||||
endPlaceholder: "结束日期",
|
||||
startDate: "created_at",
|
||||
//endDate: "createEndDate",
|
||||
label: "提交时间: "
|
||||
}
|
||||
];
|
||||
|
||||
export const RULE_FORM = {
|
||||
page: 1,
|
||||
size: 50
|
||||
};
|
||||
49
src/views/feedbackManagement/agent/constant/table.ts
Normal file
49
src/views/feedbackManagement/agent/constant/table.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
//import { RenderScope } from "@/components/ProTable/interface";
|
||||
export const COLUMNS = [
|
||||
{
|
||||
align: "center",
|
||||
fixed: true,
|
||||
label: "提交时间",
|
||||
prop: "created_at"
|
||||
},
|
||||
{
|
||||
align: "center",
|
||||
label: "IP定位",
|
||||
prop: "ip"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "公司名称",
|
||||
prop: "corp_name"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "邮箱",
|
||||
prop: "email"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "手机号码",
|
||||
prop: "phone"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "业务类型",
|
||||
prop: "business_type_name"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "企业规模",
|
||||
prop: "enterprise_size_name"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "公司地址",
|
||||
prop: "address"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "留言内容",
|
||||
prop: "message"
|
||||
}
|
||||
];
|
||||
63
src/views/feedbackManagement/agent/index.vue
Normal file
63
src/views/feedbackManagement/agent/index.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<!-- 联系我们列表 -->
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<div style="padding-bottom: 16px">
|
||||
<el-button type="primary" @click="handleExport"> 导出 </el-button>
|
||||
</div>
|
||||
|
||||
<ProTable
|
||||
ref="proTableRef"
|
||||
:formData="dataStore.formData"
|
||||
:columns="dataStore.columns"
|
||||
:request-api="getAgentListApi"
|
||||
:init-param="dataStore.initParam"
|
||||
>
|
||||
</ProTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="feedbackContactIndex">
|
||||
import ProTable from "@/components/ProTable/index.vue";
|
||||
import { useExport } from "@/hooks/useExport";
|
||||
//列表接口
|
||||
import { getAgentListApi, getAgentListExportApi, getAgentTypesListApi } from "@/api/modules/agent";
|
||||
//深拷贝方法
|
||||
import { cloneDeep } from "lodash-es";
|
||||
//表格和搜索條件
|
||||
import { RULE_FORM, FORM_DATA, COLUMNS } from "./constant/index";
|
||||
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
|
||||
const proTableRef = ref<any>(null);
|
||||
|
||||
// 数据源
|
||||
const dataStore = reactive<any>({
|
||||
columns: COLUMNS, //列表配置项
|
||||
initParam: cloneDeep(RULE_FORM), // 初始化搜索条件|重置搜索条件
|
||||
ruleForm: cloneDeep(RULE_FORM), // 搜索參數
|
||||
formData: FORM_DATA //搜索配置项
|
||||
});
|
||||
const handleExport = () => {
|
||||
getMenusLisExport();
|
||||
};
|
||||
//导出
|
||||
const getMenusLisExport = async () => {
|
||||
const result = await getAgentListExportApi(dataStore.ruleForm);
|
||||
await useExport(result);
|
||||
};
|
||||
const getAgentTypesList = async () => {
|
||||
const result = await getAgentTypesListApi();
|
||||
if (result?.code === 0) {
|
||||
let arr: any = [];
|
||||
result?.data.forEach((item: any) => {
|
||||
arr.push({
|
||||
value: item.value,
|
||||
label: item.name
|
||||
});
|
||||
});
|
||||
dataStore.formData[1].options = arr;
|
||||
console.log(result?.data);
|
||||
}
|
||||
};
|
||||
getAgentTypesList();
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
4
src/views/feedbackManagement/contact/constant/index.ts
Normal file
4
src/views/feedbackManagement/contact/constant/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { FORM_DATA, RULE_FORM } from "./search";
|
||||
import { COLUMNS } from "./table";
|
||||
|
||||
export { FORM_DATA, RULE_FORM, COLUMNS };
|
||||
34
src/views/feedbackManagement/contact/constant/search.ts
Normal file
34
src/views/feedbackManagement/contact/constant/search.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
}
|
||||
export const FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "Time",
|
||||
type: "daterange",
|
||||
options: [],
|
||||
startPlaceholder: "开始日期",
|
||||
endPlaceholder: "结束日期",
|
||||
startDate: "created_at",
|
||||
// endDate: "createEndDate",
|
||||
label: "提交时间: "
|
||||
}
|
||||
];
|
||||
|
||||
export const RULE_FORM = {
|
||||
page: 1,
|
||||
size: 50
|
||||
};
|
||||
29
src/views/feedbackManagement/contact/constant/table.ts
Normal file
29
src/views/feedbackManagement/contact/constant/table.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
//import { RenderScope } from "@/components/ProTable/interface";
|
||||
export const COLUMNS = [
|
||||
{
|
||||
align: "center",
|
||||
fixed: true,
|
||||
label: "提交时间",
|
||||
prop: "created_at"
|
||||
},
|
||||
{
|
||||
align: "center",
|
||||
label: "IP定位",
|
||||
prop: "ip"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "姓名",
|
||||
prop: "name"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "邮箱",
|
||||
prop: "email"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "留言内容",
|
||||
prop: "content"
|
||||
}
|
||||
];
|
||||
48
src/views/feedbackManagement/contact/index.vue
Normal file
48
src/views/feedbackManagement/contact/index.vue
Normal file
@@ -0,0 +1,48 @@
|
||||
<!-- 联系我们列表 -->
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<div style="padding-bottom: 16px">
|
||||
<el-button type="primary" @click="handleExport"> 导出 </el-button>
|
||||
</div>
|
||||
|
||||
<ProTable
|
||||
ref="proTableRef"
|
||||
:formData="dataStore.formData"
|
||||
:columns="dataStore.columns"
|
||||
:request-api="getLeaveMsgListApi"
|
||||
:init-param="dataStore.initParam"
|
||||
>
|
||||
</ProTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="feedbackContactIndex">
|
||||
import ProTable from "@/components/ProTable/index.vue";
|
||||
import { useExport } from "@/hooks/useExport";
|
||||
//列表接口
|
||||
import { getLeaveMsgListExportApi, getLeaveMsgListApi } from "@/api/modules/contact";
|
||||
//深拷贝方法
|
||||
import { cloneDeep } from "lodash-es";
|
||||
//表格和搜索條件
|
||||
import { RULE_FORM, FORM_DATA, COLUMNS } from "./constant/index";
|
||||
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
|
||||
const proTableRef = ref<any>(null);
|
||||
|
||||
// 数据源
|
||||
const dataStore = reactive<any>({
|
||||
columns: COLUMNS, //列表配置项
|
||||
initParam: cloneDeep(RULE_FORM), // 初始化搜索条件|重置搜索条件
|
||||
ruleForm: cloneDeep(RULE_FORM), // 搜索參數
|
||||
formData: FORM_DATA //搜索配置项
|
||||
});
|
||||
const handleExport = () => {
|
||||
getMenusLisExport();
|
||||
};
|
||||
//导出
|
||||
const getMenusLisExport = async () => {
|
||||
const result = await getLeaveMsgListExportApi(dataStore.ruleForm);
|
||||
await useExport(result);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
4
src/views/feedbackManagement/product/constant/index.ts
Normal file
4
src/views/feedbackManagement/product/constant/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { FORM_DATA, RULE_FORM } from "./search";
|
||||
import { COLUMNS } from "./table";
|
||||
|
||||
export { FORM_DATA, RULE_FORM, COLUMNS };
|
||||
49
src/views/feedbackManagement/product/constant/search.ts
Normal file
49
src/views/feedbackManagement/product/constant/search.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
}
|
||||
export const FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "corp_name",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
isArray: true,
|
||||
label: "公司名称: "
|
||||
},
|
||||
{
|
||||
prop: "country_name",
|
||||
placeholder: "请选择",
|
||||
type: "selectRemote",
|
||||
options: [],
|
||||
label: "所在国家: "
|
||||
},
|
||||
{
|
||||
prop: "Time",
|
||||
type: "daterange",
|
||||
options: [],
|
||||
startPlaceholder: "开始日期",
|
||||
endPlaceholder: "结束日期",
|
||||
startDate: "created_at",
|
||||
// endDate: "createEndDate",
|
||||
label: "提交时间: "
|
||||
}
|
||||
];
|
||||
|
||||
export const RULE_FORM = {
|
||||
page: 1,
|
||||
size: 50,
|
||||
orgCode: 0
|
||||
};
|
||||
47
src/views/feedbackManagement/product/constant/table.ts
Normal file
47
src/views/feedbackManagement/product/constant/table.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { RenderScope } from "@/components/ProTable/interface";
|
||||
export const COLUMNS = [
|
||||
{
|
||||
align: "center",
|
||||
fixed: true,
|
||||
label: "姓名",
|
||||
prop: "first_name",
|
||||
render: (scope: RenderScope<any>): VNode | string | any => {
|
||||
return scope.row.first_name + scope.row.last_name;
|
||||
}
|
||||
},
|
||||
{
|
||||
align: "center",
|
||||
label: "公司名称",
|
||||
prop: "corp_name"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "邮箱",
|
||||
prop: "email"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "手机号码",
|
||||
prop: "phone"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "所在国家",
|
||||
prop: "country_name"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "行业",
|
||||
prop: "industry"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "留言内容",
|
||||
prop: "message"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "提交时间",
|
||||
prop: "created_at"
|
||||
}
|
||||
];
|
||||
68
src/views/feedbackManagement/product/index.vue
Normal file
68
src/views/feedbackManagement/product/index.vue
Normal file
@@ -0,0 +1,68 @@
|
||||
<!-- 批量采购询盘列表 -->
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<ProTable
|
||||
ref="proTableRef"
|
||||
:formData="dataStore.formData"
|
||||
:columns="dataStore.columns"
|
||||
:request-api="getProductListApi"
|
||||
:init-param="dataStore.initParam"
|
||||
>
|
||||
</ProTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="feedbackProductIndex">
|
||||
import ProTable from "@/components/ProTable/index.vue";
|
||||
|
||||
//列表接口
|
||||
import { getProductListApi } from "@/api/modules/product";
|
||||
// import { getCountryListApi } from "@/api/modules/global";
|
||||
// import { useUserStore } from "@/stores/modules/user";
|
||||
// const userStore: any = useUserStore();
|
||||
//深拷贝方法
|
||||
import { cloneDeep } from "lodash-es";
|
||||
//表格和搜索條件
|
||||
import { RULE_FORM, FORM_DATA, COLUMNS } from "./constant/index";
|
||||
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
|
||||
const proTableRef = ref<any>(null);
|
||||
// 数据源
|
||||
const dataStore = reactive<any>({
|
||||
columns: COLUMNS, //列表配置项
|
||||
initParam: cloneDeep(RULE_FORM), // 初始化搜索条件|重置搜索条件
|
||||
ruleForm: cloneDeep(RULE_FORM), // 搜索參數
|
||||
formData: FORM_DATA //搜索配置项
|
||||
// ZH: [],
|
||||
// EN: []
|
||||
});
|
||||
|
||||
// const getCountryList = async () => {
|
||||
// const result = await getCountryListApi();
|
||||
|
||||
// if (result?.code === 0) {
|
||||
// dataStore.ZH = [];
|
||||
// dataStore.EN = [];
|
||||
// result?.data.forEach((item: any) => {
|
||||
// dataStore.ZH.push({
|
||||
// label: item.name,
|
||||
// value: item.id
|
||||
// });
|
||||
// dataStore.EN.push({
|
||||
// label: item.name,
|
||||
// value: item.id
|
||||
// });
|
||||
// });
|
||||
// dataStore.formData[1].options = userStore.languageType === 1 ? dataStore.ZH : dataStore.EN;
|
||||
// }
|
||||
// };
|
||||
// getCountryList();
|
||||
// watch(
|
||||
// () => userStore.languageType,
|
||||
// (newVal: any) => {
|
||||
// dataStore.formData[1].options = newVal === 1 ? dataStore.ZH : dataStore.EN;
|
||||
// },
|
||||
// { deep: true, immediate: true }
|
||||
// );
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
4
src/views/feedbackManagement/purchase/constant/index.ts
Normal file
4
src/views/feedbackManagement/purchase/constant/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { FORM_DATA, RULE_FORM } from "./search";
|
||||
import { COLUMNS } from "./table";
|
||||
|
||||
export { FORM_DATA, RULE_FORM, COLUMNS };
|
||||
49
src/views/feedbackManagement/purchase/constant/search.ts
Normal file
49
src/views/feedbackManagement/purchase/constant/search.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
}
|
||||
export const FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "corp_name",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
isArray: true,
|
||||
label: "公司名称: "
|
||||
},
|
||||
{
|
||||
prop: "interested",
|
||||
placeholder: "请选择",
|
||||
type: "select",
|
||||
options: [],
|
||||
label: "想采购的产品: "
|
||||
},
|
||||
{
|
||||
prop: "Time",
|
||||
type: "daterange",
|
||||
options: [],
|
||||
startPlaceholder: "开始日期",
|
||||
endPlaceholder: "结束日期",
|
||||
startDate: "created_at",
|
||||
// endDate: "createEndDate",
|
||||
label: "提交时间: "
|
||||
}
|
||||
];
|
||||
|
||||
export const RULE_FORM = {
|
||||
page: 1,
|
||||
size: 50,
|
||||
orgCode: 0
|
||||
};
|
||||
47
src/views/feedbackManagement/purchase/constant/table.ts
Normal file
47
src/views/feedbackManagement/purchase/constant/table.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { RenderScope } from "@/components/ProTable/interface";
|
||||
export const COLUMNS = [
|
||||
{
|
||||
align: "center",
|
||||
fixed: true,
|
||||
label: "提交时间",
|
||||
prop: "created_at"
|
||||
},
|
||||
{
|
||||
align: "center",
|
||||
label: "IP定位",
|
||||
prop: "ip"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "公司名称",
|
||||
prop: "corp_name"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "姓名",
|
||||
prop: "first_name",
|
||||
render: (scope: RenderScope<any>): VNode | string | any => {
|
||||
return scope.row.first_name + scope.row.last_name;
|
||||
}
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "邮箱",
|
||||
prop: "email"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "手机号码",
|
||||
prop: "phone"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "想采购的产品",
|
||||
prop: "interested"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "询问内容",
|
||||
prop: "message"
|
||||
}
|
||||
];
|
||||
64
src/views/feedbackManagement/purchase/index.vue
Normal file
64
src/views/feedbackManagement/purchase/index.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<!-- 联系我们列表 -->
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<div style="padding-bottom: 16px">
|
||||
<el-button type="primary" @click="handleExport"> 导出 </el-button>
|
||||
</div>
|
||||
|
||||
<ProTable
|
||||
ref="proTableRef"
|
||||
:formData="dataStore.formData"
|
||||
:columns="dataStore.columns"
|
||||
:request-api="getBPListApi"
|
||||
:init-param="dataStore.initParam"
|
||||
>
|
||||
</ProTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="feedbackContactIndex">
|
||||
import ProTable from "@/components/ProTable/index.vue";
|
||||
import { useExport } from "@/hooks/useExport";
|
||||
//列表接口
|
||||
import { getBPListExportApi, getBPListApi, getBPInterestedListApi } from "@/api/modules/purchase";
|
||||
//深拷贝方法
|
||||
import { cloneDeep } from "lodash-es";
|
||||
//表格和搜索條件
|
||||
import { RULE_FORM, FORM_DATA, COLUMNS } from "./constant/index";
|
||||
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
|
||||
const proTableRef = ref<any>(null);
|
||||
|
||||
// 数据源
|
||||
const dataStore = reactive<any>({
|
||||
columns: COLUMNS, //列表配置项
|
||||
initParam: cloneDeep(RULE_FORM), // 初始化搜索条件|重置搜索条件
|
||||
ruleForm: cloneDeep(RULE_FORM), // 搜索參數
|
||||
formData: FORM_DATA //搜索配置项
|
||||
});
|
||||
const handleExport = () => {
|
||||
getBPListExport();
|
||||
};
|
||||
//导出
|
||||
const getBPListExport = async () => {
|
||||
const result = await getBPListExportApi(dataStore.ruleForm);
|
||||
await useExport(result);
|
||||
};
|
||||
//
|
||||
const getBPInterestedList = async () => {
|
||||
const result = await getBPInterestedListApi();
|
||||
if (result?.code === 0) {
|
||||
let arr: any = [];
|
||||
result?.data.forEach((item: any) => {
|
||||
arr.push({
|
||||
label: item,
|
||||
value: item
|
||||
});
|
||||
});
|
||||
dataStore.formData[1].options = arr;
|
||||
console.log(result?.data, "=======data========");
|
||||
}
|
||||
};
|
||||
getBPInterestedList();
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
29
src/views/home/index.scss
Normal file
29
src/views/home/index.scss
Normal file
@@ -0,0 +1,29 @@
|
||||
.box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
// justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.box-bg {
|
||||
width: 70%;
|
||||
max-width: 1200px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
.tableItem {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
}
|
||||
.tableItem1 {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-right: 1px solid #eeeeee;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
}
|
||||
108
src/views/home/index.vue
Normal file
108
src/views/home/index.vue
Normal file
@@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="card">
|
||||
<h4 style="display: flex; align-items: center; margin: 0">
|
||||
<el-icon :size="20" style="margin-right: 2px"><BellFilled /></el-icon>信息
|
||||
</h4>
|
||||
<el-divider style="margin: 10px 0" />
|
||||
<div style="padding: 20px; color: #ffffff; background: #027415; border-radius: 4px">
|
||||
<div style="display: flex; align-items: center">
|
||||
<el-icon :size="18"><Select /></el-icon>
|
||||
<div style="margin-left: 10px; font-size: 20px; font-weight: 900">欢迎 !</div>
|
||||
</div>
|
||||
<div style="margin-top: 10px">欢迎来到首页 !</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" style="margin-top: 20px">
|
||||
<h4 style="display: flex; align-items: center; margin: 0">
|
||||
<el-icon :size="20" style="margin-right: 2px"><DArrowLeft /></el-icon>快速进入
|
||||
</h4>
|
||||
<el-divider style="margin: 10px 0" />
|
||||
<!-- 按钮组 -->
|
||||
<div style="padding-top: 12px">
|
||||
<el-button
|
||||
style="margin-bottom: 12px; margin-left: 12px"
|
||||
type="primary"
|
||||
v-for="(item, index) in menuList"
|
||||
:key="index"
|
||||
@click="handleClickMenu(item)"
|
||||
>{{ item.meta.title }}</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" style="padding-bottom: 4%; margin-top: 20px">
|
||||
<h4 style="display: flex; align-items: center; margin: 0">
|
||||
<el-icon :size="20" style="margin-right: 2px"><Tools /></el-icon>系统信息
|
||||
</h4>
|
||||
<el-divider style="margin: 10px 0" />
|
||||
<div style="min-width: 1340px; border: 1px solid #eeeeee; border-bottom: none">
|
||||
<div style="display: flex; height: 34px" v-for="(item, index) in tableData" :key="index">
|
||||
<div class="tableItem1" style="font-weight: 900">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
<div class="tableItem1">
|
||||
{{ item.text }}
|
||||
</div>
|
||||
<div class="tableItem1" style="font-weight: 900">
|
||||
{{ item.name1 }}
|
||||
</div>
|
||||
<div class="tableItem">
|
||||
{{ item.text1 }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="home">
|
||||
import { Select, Tools, BellFilled, DArrowLeft } from "@element-plus/icons-vue";
|
||||
import { useAuthStore } from "@/stores/modules/auth";
|
||||
import { getSystemInfoApi } from "@/api/modules/home";
|
||||
const $router = useRouter();
|
||||
const tableData = ref<any>([]);
|
||||
|
||||
const authStore = useAuthStore();
|
||||
const menuList = computed(() =>
|
||||
authStore.flatMenuListGet.filter(item => {
|
||||
const ON_PATH = [
|
||||
"产品管理",
|
||||
"视频管理",
|
||||
"下载管理",
|
||||
"文章管理",
|
||||
"Banner管理",
|
||||
"用户角色管理",
|
||||
"问答管理",
|
||||
"反馈管理",
|
||||
"网站管理"
|
||||
];
|
||||
return item.hidden && !ON_PATH.includes(item.meta.title);
|
||||
})
|
||||
);
|
||||
const handleClickMenu = (item: any) => {
|
||||
$router.push({ path: item.path });
|
||||
};
|
||||
const getSystemInfo = async () => {
|
||||
const result = await getSystemInfoApi();
|
||||
if (result?.code === 0) {
|
||||
const newArray = [];
|
||||
const batchSize = 2; // 每个对象包含的属性对数,这里设置为2
|
||||
|
||||
for (let i = 0; i < result?.data.length; i += batchSize) {
|
||||
const obj: any = {};
|
||||
for (let j = 0; j < batchSize && i + j < result?.data.length; j++) {
|
||||
const keyPrefix = j === 0 ? "" : j.toString();
|
||||
obj[`name${keyPrefix}`] = result?.data[i + j].name;
|
||||
obj[`text${keyPrefix}`] = result?.data[i + j].value;
|
||||
}
|
||||
newArray.push(obj);
|
||||
}
|
||||
tableData.value = newArray;
|
||||
}
|
||||
};
|
||||
getSystemInfo();
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "./index.scss";
|
||||
</style>
|
||||
3
src/views/login/constant/index.ts
Normal file
3
src/views/login/constant/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { RULES, RULE_FORM } from "./ruleForm";
|
||||
import { RESET_RULES, RESET_RULE_FORM } from "./resetRuleForm";
|
||||
export { RULES, RULE_FORM, RESET_RULES, RESET_RULE_FORM };
|
||||
41
src/views/login/constant/resetRuleForm.ts
Normal file
41
src/views/login/constant/resetRuleForm.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
export const RESET_RULE_FORM = {
|
||||
iphone: "", //手机号码
|
||||
code: "", //验证码
|
||||
newPassword: "", //新密码
|
||||
confirmPassword: "" //确认新密码
|
||||
};
|
||||
export const RESET_RULES = {
|
||||
iphone: [
|
||||
{
|
||||
required: true,
|
||||
message: "请填写手机号码",
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
pattern: /^1[3-9]\d{9}$/,
|
||||
message: "请输入正确的手机号码",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
code: [
|
||||
{
|
||||
required: true,
|
||||
message: "请填写验证码",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
newPassword: [
|
||||
{
|
||||
required: true,
|
||||
message: "请填写新密码",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
confirmPassword: [
|
||||
{
|
||||
required: true,
|
||||
message: "请填写确认密码",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
};
|
||||
29
src/views/login/constant/ruleForm.ts
Normal file
29
src/views/login/constant/ruleForm.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
export const RULE_FORM = {
|
||||
username: "",
|
||||
password: "",
|
||||
captcha: "",
|
||||
token: "" //此token是从图片验证码接口获取
|
||||
}; //登录表单数据
|
||||
export const RULES = {
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: "请填写账号",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: "请填写密码",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
captcha: [
|
||||
{
|
||||
required: true,
|
||||
message: "请填写验证码",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
};
|
||||
95
src/views/login/index.scss
Normal file
95
src/views/login/index.scss
Normal file
@@ -0,0 +1,95 @@
|
||||
.main {
|
||||
width: 100%;
|
||||
min-width: 830px;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.main::before {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 33%;
|
||||
height: 100%;
|
||||
content: "";
|
||||
background-color: #4178d5;
|
||||
}
|
||||
.container {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
width: 800px;
|
||||
height: 500px;
|
||||
font-size: 0;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 1px 40px 1px rgb(52 69 94 / 19%);
|
||||
transform: translate(-50%, -50%);
|
||||
.left {
|
||||
position: relative;
|
||||
width: 300px;
|
||||
height: 500px;
|
||||
background-image: url("@/assets/images/electronic_component.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
.left-logo-box {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 250px;
|
||||
height: 150px;
|
||||
background-image: url("@/assets/images/login_logo.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
.left::before {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
content: "";
|
||||
background-color: rgb(65 120 213 / 60%);
|
||||
}
|
||||
.right {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
// align-items: center;
|
||||
justify-content: center;
|
||||
width: 500px;
|
||||
height: 460px;
|
||||
padding: 20px 0;
|
||||
.right-logo-box {
|
||||
// position: absolute;
|
||||
// top: 0;
|
||||
// left: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
width: 75px;
|
||||
height: 75px;
|
||||
margin-left: 100px;
|
||||
background-image: url("@/assets/images/right-logo.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
|
||||
// transform: translate(-50%, -50%);
|
||||
.right-logo-font {
|
||||
font-family: "Microsoft YaHei", Georgia, "Times New Roman", Times, serif;
|
||||
font-size: 19px;
|
||||
font-weight: 900;
|
||||
color: #122b5a;
|
||||
}
|
||||
.sign-in {
|
||||
font-family: "Microsoft YaHei", Georgia, "Times New Roman", Times, serif;
|
||||
font-size: 12px;
|
||||
color: #b5bdce;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-input-group__append {
|
||||
padding: 0 8px;
|
||||
}
|
||||
291
src/views/login/index.vue
Normal file
291
src/views/login/index.vue
Normal file
@@ -0,0 +1,291 @@
|
||||
<template>
|
||||
<div class="main">
|
||||
<div class="container">
|
||||
<div class="left">
|
||||
<div class="left-logo-box"></div>
|
||||
</div>
|
||||
<!-- 登录 -->
|
||||
<div class="right" v-if="dataStore.type === 1">
|
||||
<div class="right-logo-box">
|
||||
<div>
|
||||
<div class="right-logo-font">登录</div>
|
||||
<div class="sign-in">Sign in</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-left: 100px">
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="width: 300px"
|
||||
:model="dataStore.ruleForm"
|
||||
:rules="dataStore.rules"
|
||||
label-width="auto"
|
||||
label-position="top"
|
||||
class="demo-ruleForm"
|
||||
hide-required-asterisk
|
||||
>
|
||||
<el-form-item label="账号" prop="username">
|
||||
<el-input v-model="dataStore.ruleForm.username" :prefix-icon="Iphone" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="密码" prop="password">
|
||||
<el-input
|
||||
v-model="dataStore.ruleForm.password"
|
||||
type="password"
|
||||
show-password
|
||||
:prefix-icon="Lock"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<!-- <div
|
||||
style="
|
||||
width: 350px;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
color: #4178d5;
|
||||
text-align: right;
|
||||
cursor: pointer;
|
||||
"
|
||||
@click="handleTabClick(2)"
|
||||
>
|
||||
忘记密码?
|
||||
</div> -->
|
||||
</el-form-item>
|
||||
<!-- <el-form-item prop="captcha">
|
||||
<span style="margin-right: 10px; color: #606266">验证码</span>
|
||||
<el-input v-model="dataStore.ruleForm.captcha" style="width: 80px" autocomplete="off" />
|
||||
<img :src="dataStore.base64" style="width: 150px; height: 60px; margin: 0 6px" />
|
||||
<el-button type="primary" v-debounce="getLoginCodeImg">刷新</el-button>
|
||||
</el-form-item> -->
|
||||
<el-form-item>
|
||||
<el-button
|
||||
size="large"
|
||||
type="primary"
|
||||
style="width: 100px; height: 36px; border-radius: 2px; box-shadow: 2px 5px 16px #4178d5"
|
||||
v-debounce="submitForm"
|
||||
>登录</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<!--忘记密码 -->
|
||||
<div class="right" v-if="dataStore.type === 2">
|
||||
<div style="margin-left: 100px">
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="ArrowLeftBold"
|
||||
circle
|
||||
style="margin: 60px 0 20px"
|
||||
@click="handleTabClick(1)"
|
||||
/>
|
||||
<el-form
|
||||
ref="resetRuleFormRef"
|
||||
:model="dataStore.resetRuleForm"
|
||||
:rules="dataStore.resetRules"
|
||||
label-width="auto"
|
||||
label-position="top"
|
||||
class="demo-ruleForm"
|
||||
hide-required-asterisk
|
||||
>
|
||||
<el-form-item label="手机号" prop="iphone">
|
||||
<el-input v-model="dataStore.resetRuleForm.iphone" :prefix-icon="Iphone" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="code" label="验证码">
|
||||
<el-input v-model="dataStore.resetRuleForm.code" autocomplete="off">
|
||||
<template #append>
|
||||
<div style="font-size: 14px; color: #4178d5; cursor: pointer" v-debounce="handleGetCode">
|
||||
{{ dataStore.codeFont }}
|
||||
</div>
|
||||
<div v-if="dataStore.isShowTime" style="margin: 0 5px; font-size: 14px; color: #4178d5">
|
||||
{{ dataStore.timeCount }}s
|
||||
</div>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newPassword">
|
||||
<el-input
|
||||
v-model="dataStore.resetRuleForm.newPassword"
|
||||
type="password"
|
||||
show-password
|
||||
:prefix-icon="Lock"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="confirmPassword">
|
||||
<el-input
|
||||
v-model="dataStore.resetRuleForm.confirmPassword"
|
||||
type="password"
|
||||
show-password
|
||||
:prefix-icon="Lock"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
size="large"
|
||||
type="primary"
|
||||
style="width: 100px; height: 36px; border-radius: 2px; box-shadow: 2px 5px 16px #4178d5"
|
||||
v-debounce="resetConfirmForm"
|
||||
>提交</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import CryptoJS from "crypto-js";
|
||||
//loginCodeImgApi
|
||||
import { loginApi } from "@/api/modules/login";
|
||||
import { Iphone, Lock, ArrowLeftBold } from "@element-plus/icons-vue";
|
||||
import { RULES, RULE_FORM, RESET_RULES, RESET_RULE_FORM } from "./constant/index";
|
||||
import { cloneDeep } from "lodash-es";
|
||||
//用户信息存储
|
||||
import { useUserStore } from "@/stores/modules/user";
|
||||
const userStore = useUserStore();
|
||||
const $router = useRouter();
|
||||
//登录表单Ref
|
||||
const ruleFormRef: any = ref(null);
|
||||
//修改密码表单Ref
|
||||
const resetRuleFormRef: any = ref(null);
|
||||
//数据源
|
||||
const dataStore = reactive<any>({
|
||||
timeCount: 120, //修改密码里验证码倒计时
|
||||
isShowTime: false,
|
||||
|
||||
base64: "", //验证码图片
|
||||
type: 1, //1:登录,2:修改密码
|
||||
codeFont: "获取验证码", //修改密码里的验证码按钮文字
|
||||
ruleForm: cloneDeep(RULE_FORM), //登录表单数据
|
||||
rules: cloneDeep(RULES), //登录表单验证
|
||||
resetRuleForm: cloneDeep(RESET_RULE_FORM), //修改密码表单数据
|
||||
resetRules: cloneDeep(RESET_RULES) //修改密码表单验证
|
||||
});
|
||||
//计时器
|
||||
let intervalId: any = null;
|
||||
|
||||
//登录
|
||||
const submitForm = () => {
|
||||
console.log(ruleFormRef);
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef?.value?.validate((valid: any) => {
|
||||
if (valid) {
|
||||
login();
|
||||
} else {
|
||||
console.log("error submit!");
|
||||
}
|
||||
});
|
||||
};
|
||||
//忘记密码提交事件
|
||||
const resetConfirmForm = () => {
|
||||
if (!resetRuleFormRef) return;
|
||||
resetRuleFormRef?.value?.validate((valid: any) => {
|
||||
if (valid) {
|
||||
let password = CryptoJS.MD5(dataStore.ruleForm.password)?.toString();
|
||||
console.log(password, "==== dataStore.ruleForm.password====");
|
||||
console.log("submit!");
|
||||
} else {
|
||||
console.log("error submit!");
|
||||
}
|
||||
});
|
||||
};
|
||||
//登录接口
|
||||
const login = async () => {
|
||||
const result: any = await loginApi({
|
||||
...dataStore.ruleForm,
|
||||
password: CryptoJS?.MD5(dataStore.ruleForm.password)?.toString()
|
||||
});
|
||||
|
||||
if (result?.code === 0) {
|
||||
const { data } = result;
|
||||
setUserData(data);
|
||||
}
|
||||
// else {
|
||||
// getLoginCodeImg();
|
||||
// }
|
||||
};
|
||||
//获取验证码图片接口
|
||||
// const getLoginCodeImg = async () => {
|
||||
// const result: any = await loginCodeImgApi();
|
||||
// if (result?.code === 0) {
|
||||
// const { data } = result;
|
||||
// const { captcha, token } = data;
|
||||
// dataStore.base64 = captcha;
|
||||
// dataStore.ruleForm.token = token;
|
||||
// }
|
||||
// };
|
||||
// getLoginCodeImg();
|
||||
//登录和密码重置切换
|
||||
const handleTabClick = (type: any) => {
|
||||
dataStore.type = type;
|
||||
for (let key in dataStore.ruleForm) {
|
||||
dataStore.ruleForm[key] = "";
|
||||
}
|
||||
for (let key in dataStore.resetRuleForm) {
|
||||
dataStore.resetRuleForm[key] = "";
|
||||
}
|
||||
if (intervalId) {
|
||||
handleClearInterval();
|
||||
dataStore.timeCount = 120;
|
||||
dataStore.isShowTime = false;
|
||||
}
|
||||
};
|
||||
//120秒验证时间
|
||||
const updateCountdown = () => {
|
||||
intervalId = setInterval(() => {
|
||||
if (dataStore.timeCount > 0) {
|
||||
dataStore.isShowTime = true;
|
||||
dataStore.timeCount--;
|
||||
} else {
|
||||
handleClearInterval();
|
||||
dataStore.timeCount = 120;
|
||||
dataStore.isShowTime = false;
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
//获取验证码
|
||||
const handleGetCode = () => {
|
||||
//如果计时器已经启动了,就不要再去触发了
|
||||
if (intervalId) {
|
||||
return;
|
||||
}
|
||||
resetRuleFormRef.value.validateField("iphone", (valid: any) => {
|
||||
if (valid) {
|
||||
updateCountdown();
|
||||
} else {
|
||||
}
|
||||
});
|
||||
};
|
||||
//清理定时器
|
||||
const handleClearInterval = () => {
|
||||
clearInterval(intervalId);
|
||||
intervalId = null;
|
||||
};
|
||||
|
||||
// 设置用户数据
|
||||
const setUserData = (data: any) => {
|
||||
const { username, uid, token, avatar } = data;
|
||||
console.log();
|
||||
// 设置token
|
||||
userStore.setToken(token);
|
||||
userStore.setUid(uid);
|
||||
userStore.setNickname(username);
|
||||
userStore.setAvatar(avatar);
|
||||
// await userStore.getAuthMenuList();
|
||||
//跳转到首页
|
||||
setTimeout(() => {
|
||||
$router.push("/admin/index");
|
||||
}, 500);
|
||||
};
|
||||
|
||||
onUnmounted(() => {
|
||||
//页面卸载的时候清空定时器
|
||||
if (intervalId) {
|
||||
handleClearInterval();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style lang="scss">
|
||||
@import "./index.scss";
|
||||
</style>
|
||||
62
src/views/productManagement/attributeList/constant/edit.ts
Normal file
62
src/views/productManagement/attributeList/constant/edit.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
disabled?: boolean;
|
||||
}
|
||||
export const EDIT_FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "attr_name",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "属性: ",
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
prop: "propsStr",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "属性值: ",
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
prop: "addAttribute",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "新增属性值: "
|
||||
}
|
||||
];
|
||||
|
||||
export const ADD_FORM_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "attr_name",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "属性: "
|
||||
},
|
||||
{
|
||||
prop: "propsStr",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "属性值: ",
|
||||
disabled: false
|
||||
}
|
||||
];
|
||||
|
||||
export const EDIT_RULE_FORM = {
|
||||
attr_name: "", //属性
|
||||
propsStr: "", //属性值
|
||||
addAttribute: "" //新增
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
import { SEARCH_DATA, RULE_FORM } from "./search";
|
||||
import { COLUMNS } from "./table";
|
||||
import { RULES } from "./rules";
|
||||
import { EDIT_FORM_DATA, EDIT_RULE_FORM, ADD_FORM_DATA } from "./edit";
|
||||
export { SEARCH_DATA, RULE_FORM, COLUMNS, RULES, EDIT_FORM_DATA, EDIT_RULE_FORM, ADD_FORM_DATA };
|
||||
@@ -0,0 +1,4 @@
|
||||
export const RULES = {
|
||||
attr_name: [{ required: true, message: "产品属性不能为空 ! ", trigger: "blur" }]
|
||||
// attributeValue: [{ required: true, message: "产品属性值不能为空 ! ", trigger: "blur" }]
|
||||
};
|
||||
30
src/views/productManagement/attributeList/constant/search.ts
Normal file
30
src/views/productManagement/attributeList/constant/search.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
interface FormItem {
|
||||
prop: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
type: string;
|
||||
isCopy?: boolean;
|
||||
optionProps?: any;
|
||||
startPlaceholder?: string;
|
||||
endPlaceholder?: string;
|
||||
options?: any;
|
||||
isArray?: boolean;
|
||||
startDate?: string; //开始时间(传入后台需要的参数)
|
||||
endDate?: string; //结束时间(传入后台需要的参数)
|
||||
startProp?: string;
|
||||
endProp?: string;
|
||||
isInteger?: boolean;
|
||||
}
|
||||
export const SEARCH_DATA: FormItem[] = [
|
||||
{
|
||||
prop: "keywords",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "属性: "
|
||||
}
|
||||
];
|
||||
|
||||
export const RULE_FORM = {
|
||||
page: 1,
|
||||
size: 50
|
||||
};
|
||||
33
src/views/productManagement/attributeList/constant/table.ts
Normal file
33
src/views/productManagement/attributeList/constant/table.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { RenderScope } from "@/components/ProTable/interface";
|
||||
export const COLUMNS = [
|
||||
{
|
||||
align: "center",
|
||||
fixed: true,
|
||||
label: "ID",
|
||||
prop: "id"
|
||||
},
|
||||
|
||||
{
|
||||
align: "left",
|
||||
label: "属性",
|
||||
prop: "attr_name"
|
||||
},
|
||||
{
|
||||
align: "left",
|
||||
label: "属性值",
|
||||
prop: "props",
|
||||
render: (scope: RenderScope<any>): VNode | string | any => {
|
||||
let arr: any = [];
|
||||
if (scope.row.props.length) {
|
||||
scope.row.props.forEach((item: any) => {
|
||||
arr.push(item.prop_name);
|
||||
});
|
||||
return arr.join(",");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{ prop: "operation", label: "操作", fixed: "right", width: 160 }
|
||||
];
|
||||
202
src/views/productManagement/attributeList/index.vue
Normal file
202
src/views/productManagement/attributeList/index.vue
Normal file
@@ -0,0 +1,202 @@
|
||||
<!-- 属性列表 -->
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<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="getProductAttrListApi"
|
||||
:init-param="dataStore.initParam"
|
||||
>
|
||||
<template #operation="scope">
|
||||
<el-button size="small" type="primary" @click="handleBtnClick(scope.row)" v-if="scope.row.id !== 1"
|
||||
>编辑</el-button
|
||||
>
|
||||
</template>
|
||||
</ProTable>
|
||||
<!-- :show-close="false" -->
|
||||
<el-drawer
|
||||
v-model="dataStore.visible"
|
||||
:show-close="true"
|
||||
:size="600"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
:before-close="handleBeforeClone"
|
||||
destroy-on-close
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<h4 :id="titleId" :class="titleClass">{{ dataStore.title }}</h4>
|
||||
</template>
|
||||
<div>
|
||||
<rulesForm
|
||||
:ruleForm="dataStore.editRuleForm"
|
||||
:formData="dataStore.editFormData"
|
||||
:rules="dataStore.rules"
|
||||
ref="formRef"
|
||||
/>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div style="flex: auto">
|
||||
<el-button @click="handleResetClick">重置</el-button>
|
||||
<el-button type="primary" @click="handleConfirmClick">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="productAttributeListIndex">
|
||||
import ProTable from "@/components/ProTable/index.vue";
|
||||
import rulesForm from "@/components/rulesForm/index.vue";
|
||||
import qs from "qs";
|
||||
//接口
|
||||
import {
|
||||
getProductAttrListApi,
|
||||
getProductAttrDetailsApi,
|
||||
getProductAttrUpApi,
|
||||
getProductAttrAddApi
|
||||
} from "@/api/modules/productAttributeList";
|
||||
//深拷贝方法
|
||||
import { cloneDeep } from "lodash-es";
|
||||
//表格和搜索條件
|
||||
import { RULE_FORM, COLUMNS, RULES, SEARCH_DATA, EDIT_FORM_DATA, EDIT_RULE_FORM, ADD_FORM_DATA } from "./constant/index";
|
||||
import { useMsg } from "@/hooks/useMsg";
|
||||
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
|
||||
const proTableRef = ref<any>(null);
|
||||
// 数据源
|
||||
const dataStore = reactive<any>({
|
||||
title: "编辑产品属性",
|
||||
rules: cloneDeep(RULES), //抽屉表单验证
|
||||
row: {},
|
||||
editRuleForm: cloneDeep(EDIT_RULE_FORM),
|
||||
editFormData: cloneDeep(EDIT_FORM_DATA), //抽屉表单配置项
|
||||
visible: false, //抽屉控制
|
||||
columns: COLUMNS, //列表配置项
|
||||
initParam: cloneDeep(RULE_FORM), // 初始化搜索条件|重置搜索条件
|
||||
ruleForm: cloneDeep(RULE_FORM), // 搜索參數
|
||||
formData: SEARCH_DATA //搜索配置项
|
||||
});
|
||||
const formRef: any = ref(null);
|
||||
//设置表单
|
||||
const handleSetRuleForm = () => {
|
||||
dataStore.editRuleForm.attributeKey = dataStore.row.productName;
|
||||
dataStore.editRuleForm.attributeValue = dataStore.row.model;
|
||||
};
|
||||
|
||||
//编辑
|
||||
const handleBtnClick = (row: any) => {
|
||||
dataStore.visible = true;
|
||||
dataStore.title = "编辑产品属性";
|
||||
dataStore.editFormData = cloneDeep(EDIT_FORM_DATA);
|
||||
dataStore.row = cloneDeep(row);
|
||||
dataStore.editFormData[0].disabled = true;
|
||||
handleSetRuleForm();
|
||||
getProductAttrDetails(row.id);
|
||||
};
|
||||
//更新
|
||||
const getProductAttrUp = async () => {
|
||||
let obj = {
|
||||
prop_name: dataStore.editRuleForm.addAttribute,
|
||||
prop_value: dataStore.editRuleForm.addAttribute
|
||||
};
|
||||
if (obj.prop_name) {
|
||||
dataStore.editRuleForm.props.push(obj);
|
||||
}
|
||||
const result = await getProductAttrUpApi(dataStore.editRuleForm);
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
dataStore.visible = false;
|
||||
handleClear();
|
||||
// getProductAttrDetails(dataStore.editRuleForm.id);
|
||||
}
|
||||
};
|
||||
//添加
|
||||
const getProductAttrAdd = async () => {
|
||||
let params = {
|
||||
attr_name: dataStore.editRuleForm.attr_name,
|
||||
props: JSON.stringify([
|
||||
{
|
||||
prop_name: dataStore.editRuleForm.propsStr,
|
||||
prop_value: dataStore.editRuleForm.propsStr
|
||||
}
|
||||
])
|
||||
};
|
||||
const result = await getProductAttrAddApi(qs.stringify(params));
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
proTableRef?.value?.getTableList();
|
||||
dataStore.visible = false;
|
||||
handleClear();
|
||||
}
|
||||
};
|
||||
//详情
|
||||
const getProductAttrDetails = async (id: any) => {
|
||||
const result = await getProductAttrDetailsApi(id);
|
||||
if (result?.code === 0) {
|
||||
dataStore.editRuleForm = cloneDeep(result?.data);
|
||||
|
||||
if (dataStore.editRuleForm.props.length) {
|
||||
let arr: any = [];
|
||||
|
||||
dataStore.editRuleForm.props.forEach((item: any) => {
|
||||
arr.push(item.prop_name);
|
||||
});
|
||||
|
||||
dataStore.editRuleForm.propsStr = arr.length ? arr.join(",") : [];
|
||||
}
|
||||
}
|
||||
};
|
||||
//清空表单数据
|
||||
const handleClear = () => {
|
||||
for (let key in dataStore.editRuleForm) {
|
||||
dataStore.editRuleForm[key] = "";
|
||||
}
|
||||
};
|
||||
//添加
|
||||
const handleAdd = () => {
|
||||
dataStore.visible = true;
|
||||
dataStore.title = "添加产品属性";
|
||||
dataStore.editFormData = cloneDeep(ADD_FORM_DATA);
|
||||
handleClear();
|
||||
};
|
||||
//重置验证
|
||||
const resetFields = () => {
|
||||
if (!formRef.value!.ruleFormRef) return;
|
||||
formRef!.value!.ruleFormRef.resetFields();
|
||||
};
|
||||
//抽屉关闭前的钩子
|
||||
const handleBeforeClone = () => {
|
||||
dataStore.visible = false;
|
||||
dataStore.editRuleForm.addAttribute = "";
|
||||
resetFields();
|
||||
handleClear();
|
||||
};
|
||||
//重置按钮
|
||||
const handleResetClick = () => {
|
||||
if (dataStore.title === "添加产品属性") {
|
||||
dataStore.editRuleForm.addAttribute = "";
|
||||
handleSetRuleForm();
|
||||
resetFields();
|
||||
} else {
|
||||
getProductAttrDetails(dataStore.row.id);
|
||||
}
|
||||
};
|
||||
//确认
|
||||
const handleConfirmClick = async () => {
|
||||
if (!formRef.value!.ruleFormRef) return;
|
||||
formRef!.value!.ruleFormRef!.validate((valid: any) => {
|
||||
if (valid) {
|
||||
dataStore.title === "添加产品属性" ? getProductAttrAdd() : getProductAttrUp();
|
||||
} else {
|
||||
console.log("error submit!");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,3 @@
|
||||
import { handleSubmit } from "./submit";
|
||||
import { handleReset } from "./reset";
|
||||
export { handleSubmit, handleReset };
|
||||
@@ -0,0 +1,7 @@
|
||||
import { cloneDeep } from "lodash-es";
|
||||
import { messageBox } from "@/utils/messageBox";
|
||||
export const handleReset = (dataStore: any) => {
|
||||
messageBox("该操作会将数据重置为初始状态", () => {
|
||||
dataStore.basicInfoRuleForm = cloneDeep(dataStore.resetBasicInfoRuleForm);
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
import { useMsg } from "@/hooks/useMsg";
|
||||
const WARN: any = {
|
||||
name: "产品名称不能为空 !",
|
||||
model: "型号不能为空 !",
|
||||
type: "产品分类不能为空 !",
|
||||
sort: "产品排序不能为空 !"
|
||||
};
|
||||
const warnFunction = (data: any) => {
|
||||
if (!data.name) {
|
||||
useMsg("warning", WARN["name"]);
|
||||
return false;
|
||||
}
|
||||
if (!data.model) {
|
||||
useMsg("warning", WARN["model"]);
|
||||
return false;
|
||||
}
|
||||
if (!data.type) {
|
||||
useMsg("warning", WARN["type"]);
|
||||
return false;
|
||||
}
|
||||
if (!data.name) {
|
||||
useMsg("warning", WARN["sort"]);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
export const handleSubmit = async (infoRef: any) => {
|
||||
console.log(infoRef.ruleForm, "============ruleForm===========");
|
||||
|
||||
let is = await warnFunction(infoRef.ruleForm);
|
||||
if (!is) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
import { ElMessageBox } from "element-plus";
|
||||
|
||||
export const messageBox = (message: any, callback: any) => {
|
||||
ElMessageBox.confirm(message, "警告", {
|
||||
confirmButtonText: "确认",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
console.log("132323");
|
||||
callback && callback();
|
||||
})
|
||||
.catch(() => {
|
||||
console.log("取消323232");
|
||||
});
|
||||
};
|
||||
123
src/views/productManagement/classList/constant/form.ts
Normal file
123
src/views/productManagement/classList/constant/form.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
//新增产品分类
|
||||
export const FORM_DATA_LV1: any[] = [
|
||||
{
|
||||
prop: "name",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "产品分类名称: "
|
||||
},
|
||||
{
|
||||
prop: "pid",
|
||||
placeholder: "请选择",
|
||||
type: "treeSelect",
|
||||
label: "所属分类: ",
|
||||
options: []
|
||||
},
|
||||
{
|
||||
prop: "sort",
|
||||
placeholder: "请输入",
|
||||
type: "inputNumber",
|
||||
label: "产品分类排序: "
|
||||
},
|
||||
{
|
||||
prop: "is_show",
|
||||
placeholder: "请输入",
|
||||
type: "radio",
|
||||
label: "是否显示: ",
|
||||
options: [
|
||||
{
|
||||
label: "是",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: "否",
|
||||
value: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
//编辑产品分类
|
||||
export const EDIT_FORM_DATA_LV1: any[] = [
|
||||
{
|
||||
prop: "name",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "产品分类名称: "
|
||||
},
|
||||
|
||||
{
|
||||
prop: "pid",
|
||||
placeholder: "请选择",
|
||||
type: "treeSelect",
|
||||
label: "所属分类: ",
|
||||
options: []
|
||||
},
|
||||
{
|
||||
prop: "sort",
|
||||
placeholder: "请输入",
|
||||
type: "inputNumber",
|
||||
label: "产品分类排序: "
|
||||
},
|
||||
{
|
||||
prop: "is_show",
|
||||
placeholder: "请输入",
|
||||
type: "radio",
|
||||
label: "是否显示: ",
|
||||
options: [
|
||||
{
|
||||
label: "是",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: "否",
|
||||
value: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
export const FORM_DATA_LV2: any[] = [
|
||||
{
|
||||
prop: "name",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
label: "产品分类名称: "
|
||||
},
|
||||
|
||||
{
|
||||
prop: "pid",
|
||||
placeholder: "请选择",
|
||||
type: "treeSelect",
|
||||
label: "所属分类: ",
|
||||
options: []
|
||||
},
|
||||
{
|
||||
prop: "related_tco_category",
|
||||
placeholder: "请选择",
|
||||
type: "treeSelects",
|
||||
label: "对应成本系统分类: ",
|
||||
options: []
|
||||
},
|
||||
{
|
||||
prop: "sort",
|
||||
placeholder: "请输入",
|
||||
type: "inputNumber",
|
||||
label: "产品分类排序: "
|
||||
},
|
||||
{
|
||||
prop: "is_show",
|
||||
placeholder: "请输入",
|
||||
type: "radio",
|
||||
label: "是否显示: ",
|
||||
options: [
|
||||
{
|
||||
label: "是",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: "否",
|
||||
value: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
5
src/views/productManagement/classList/constant/index.ts
Normal file
5
src/views/productManagement/classList/constant/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { FORM_DATA_LV1, FORM_DATA_LV2 } from "./form";
|
||||
import { RULES_LV1, RULES_LV2 } from "./rules";
|
||||
import { RULE_FORM_LV1, RULE_FORM_LV2 } from "./ruleForm";
|
||||
import { SEARCH } from "./search";
|
||||
export { FORM_DATA_LV1, FORM_DATA_LV2, RULES_LV1, RULES_LV2, RULE_FORM_LV1, RULE_FORM_LV2, SEARCH };
|
||||
@@ -0,0 +1,6 @@
|
||||
export const RULE_FORM_LV1: any = {
|
||||
sort: 1
|
||||
};
|
||||
export const RULE_FORM_LV2: any = {
|
||||
sort: 1
|
||||
};
|
||||
15
src/views/productManagement/classList/constant/rules.ts
Normal file
15
src/views/productManagement/classList/constant/rules.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
export const RULES_LV1 = {
|
||||
name: [{ required: true, message: "产品分类名称不能为空 ! ", trigger: "blur" }],
|
||||
pid: [{ required: true, message: "所属分类不能为空 ! ", trigger: "change" }],
|
||||
sort: [{ required: true, message: "产品分类排序不能为空 ! ", trigger: "blur" }],
|
||||
is_show: [{ required: true, message: "请选择是否展示 ! ", trigger: "change" }],
|
||||
related_tco_category: [{ required: true, message: "所属分类不能为空 ! ", trigger: "change" }]
|
||||
};
|
||||
export const RULES_LV2 = {
|
||||
name: [{ required: true, message: "产品分类名称不能为空 ! ", trigger: "blur" }],
|
||||
// id: [{ required: true, message: "产品分类ID不能为空 ! ", trigger: "blur" }],
|
||||
pid: [{ required: true, message: "所属分类不能为空 ! ", trigger: "change" }],
|
||||
costSystemType: [{ required: true, message: "对应成本系统分类不能为空 ! ", trigger: "change" }],
|
||||
sort: [{ required: true, message: "产品分类排序不能为空 ! ", trigger: "blur" }],
|
||||
is_show: [{ required: true, message: "请选择是否展示 ! ", trigger: "change" }]
|
||||
};
|
||||
9
src/views/productManagement/classList/constant/search.ts
Normal file
9
src/views/productManagement/classList/constant/search.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export const SEARCH = [
|
||||
{
|
||||
prop: "keywords",
|
||||
placeholder: "请输入",
|
||||
type: "input",
|
||||
isArray: true,
|
||||
label: "分类名称"
|
||||
}
|
||||
];
|
||||
291
src/views/productManagement/classList/index.vue
Normal file
291
src/views/productManagement/classList/index.vue
Normal file
@@ -0,0 +1,291 @@
|
||||
<!-- 分类列表 -->
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<div class="card table-main">
|
||||
<SearchForm
|
||||
:search="search"
|
||||
:reset="reset"
|
||||
:formData="dataStore.searchFormData"
|
||||
:search-param="dataStore.searchParam"
|
||||
/>
|
||||
<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>
|
||||
<el-table-column label="操作" :width="350">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleAddChild(scope.$index, scope.row)"
|
||||
v-if="scope.row.level != 3"
|
||||
>添加子类</el-button
|
||||
>
|
||||
<el-button type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button
|
||||
type="info"
|
||||
size="small"
|
||||
style="cursor: not-allowed"
|
||||
@click="handleAddProduct(scope.$index, scope.row)"
|
||||
>添加产品</el-button
|
||||
>
|
||||
<el-button
|
||||
size="small"
|
||||
type="info"
|
||||
style="cursor: not-allowed"
|
||||
@click="handleDelete(scope.$index, scope.row)"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-drawer
|
||||
v-model="dataStore.visible"
|
||||
:show-close="true"
|
||||
:size="600"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
:before-close="handleBeforeClone"
|
||||
destroy-on-close
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<h4 :id="titleId" :class="titleClass">{{ dataStore.title }}</h4>
|
||||
</template>
|
||||
<rulesForm
|
||||
:ruleForm="dataStore.ruleForm"
|
||||
:formData="dataStore.formData"
|
||||
:rules="dataStore.rules"
|
||||
ref="formRef"
|
||||
@handleSelectChangeEmits="handleSelectChangeEmits"
|
||||
@handleTreesSelectChangeEmits="handleTreesSelectChangeEmits"
|
||||
/>
|
||||
<template #footer>
|
||||
<div style="flex: auto">
|
||||
<el-button @click="handleResetClick">重置</el-button>
|
||||
<el-button type="primary" @click="handleConfirmClick">提交</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="productClassListIndex">
|
||||
import SearchForm from "@/components/SearchForm/index.vue";
|
||||
import rulesForm from "@/components/rulesForm/index.vue";
|
||||
import { integerRexg } from "@/utils/regexp/index";
|
||||
//getProductCategoryDelApi
|
||||
import {
|
||||
getProductCategoryListApi,
|
||||
getArticleCategorySaveApi,
|
||||
getProductClassCategoryReadApi,
|
||||
getProductCategoryUpdateApi,
|
||||
getArticleCategorySortApi,
|
||||
getProductClassTcoTreeApi
|
||||
} from "@/api/modules/productClass";
|
||||
import { addLabelValue } from "../list/utils/common/addLabelValue";
|
||||
|
||||
import { useMsg } from "@/hooks/useMsg";
|
||||
|
||||
import { FORM_DATA_LV1, FORM_DATA_LV2, RULE_FORM_LV1, RULE_FORM_LV2, RULES_LV1, RULES_LV2, SEARCH } from "./constant/index";
|
||||
import { cloneDeep } from "lodash-es";
|
||||
|
||||
const formRef: any = ref(null);
|
||||
const dataStore = reactive<any>({
|
||||
visible: false,
|
||||
title: "添加产品分类",
|
||||
selectLevel: 1,
|
||||
searchParam: {}, //搜索参数
|
||||
searchFormData: cloneDeep(SEARCH), //搜索配置
|
||||
ruleForm: cloneDeep(RULE_FORM_LV1),
|
||||
rules: cloneDeep(RULES_LV1),
|
||||
formData: cloneDeep(FORM_DATA_LV1),
|
||||
row: {},
|
||||
tableData: [],
|
||||
treeData: []
|
||||
});
|
||||
//成本系统
|
||||
const getProductClassTcoTree = async () => {
|
||||
const result = await getProductClassTcoTreeApi();
|
||||
if (result?.code === 0) {
|
||||
FORM_DATA_LV2[2].options = addLabelValue(result?.data);
|
||||
}
|
||||
};
|
||||
getProductClassTcoTree();
|
||||
//列表接口
|
||||
const getProductCategoryList = async () => {
|
||||
const result = await getProductCategoryListApi(dataStore.searchParam);
|
||||
if (result?.code === 0) {
|
||||
let tableData = cloneDeep(result?.data);
|
||||
dataStore.tableData = tableData;
|
||||
dataStore.treeData = [];
|
||||
dataStore.treeData = addLabelValue(tableData);
|
||||
dataStore.treeData.unshift({ value: 0, label: "无" });
|
||||
}
|
||||
};
|
||||
getProductCategoryList();
|
||||
//添加子类
|
||||
const getArticleCategorySave = async (params: any) => {
|
||||
const result = await getArticleCategorySaveApi(params);
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
dataStore.visible = false;
|
||||
resetFrom();
|
||||
formRef!.value!.ruleFormRef.resetFields();
|
||||
getProductCategoryList();
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectChangeEmits = (value: any) => {
|
||||
dataStore.ruleForm.pid = value.id;
|
||||
};
|
||||
const handleTreesSelectChangeEmits = (value: any) => {
|
||||
console.log(value, "=========value=========");
|
||||
};
|
||||
//更新接口
|
||||
const getProductCategoryUpdate = async () => {
|
||||
dataStore.ruleForm.related_tco_category = dataStore.ruleForm.related_tco_category
|
||||
? dataStore.ruleForm.related_tco_category.join(",")
|
||||
: dataStore.ruleForm.related_tco_category;
|
||||
const result = await getProductCategoryUpdateApi(dataStore.ruleForm);
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
dataStore.visible = false;
|
||||
resetFrom();
|
||||
getProductCategoryList();
|
||||
}
|
||||
};
|
||||
//产品详情
|
||||
const getProductClassCategoryRead = async (id: any) => {
|
||||
const result = await getProductClassCategoryReadApi(id);
|
||||
if (result?.code === 0) {
|
||||
dataStore.ruleForm = result?.data;
|
||||
if (dataStore.ruleForm.related_tco_category) {
|
||||
dataStore.ruleForm.related_tco_category = dataStore.ruleForm.related_tco_category
|
||||
.split(",")
|
||||
.map((item: any) => Number(item));
|
||||
}
|
||||
setFormDatOptions();
|
||||
getProductCategoryList();
|
||||
}
|
||||
};
|
||||
//排序
|
||||
const getArticleCategorySort = async (row: any) => {
|
||||
const result = await getArticleCategorySortApi({ id: row.id, sort: row.sort });
|
||||
if (result?.code === 0) {
|
||||
useMsg("success", result?.msg);
|
||||
getProductCategoryList();
|
||||
}
|
||||
};
|
||||
|
||||
const search = () => {
|
||||
getProductCategoryList();
|
||||
};
|
||||
const reset = () => {
|
||||
dataStore.searchParam.keywords = "";
|
||||
getProductCategoryList();
|
||||
};
|
||||
//重置表单配置
|
||||
const resetFrom = () => {
|
||||
if (dataStore.selectLevel === 1 || dataStore.selectLevel === 2) {
|
||||
dataStore.ruleForm = cloneDeep(RULE_FORM_LV1);
|
||||
dataStore.formData = cloneDeep(FORM_DATA_LV1);
|
||||
dataStore.rules = RULES_LV1;
|
||||
}
|
||||
if (dataStore.selectLevel === 3) {
|
||||
dataStore.ruleForm = cloneDeep(RULE_FORM_LV2);
|
||||
dataStore.formData = cloneDeep(FORM_DATA_LV2);
|
||||
dataStore.rules = RULES_LV2;
|
||||
}
|
||||
};
|
||||
const setFormDatOptions = () => {
|
||||
// dataStore.formData[1].options = [];
|
||||
dataStore.formData[1].options = dataStore.treeData;
|
||||
// dataStore.formData[1].options.unshift({ value: 0, label: "无" });
|
||||
// console.log("12323");
|
||||
};
|
||||
//添加子类
|
||||
const handleAddChild = (index: any, row: any) => {
|
||||
dataStore.selectLevel = row.level;
|
||||
resetFrom();
|
||||
dataStore.visible = true;
|
||||
dataStore.title = "添加产品分类";
|
||||
setFormDatOptions();
|
||||
// dataStore.formData[1].options.unshift({ value: 0, label: "无" });
|
||||
// dataStore.formData[1].options = dataStore.treeData;
|
||||
};
|
||||
|
||||
//before-close
|
||||
const handleBeforeClone = () => {
|
||||
resetFrom();
|
||||
formRef!.value!.ruleFormRef.resetFields();
|
||||
dataStore.visible = false;
|
||||
};
|
||||
const handleEdit = (row: any) => {
|
||||
dataStore.selectLevel = row.level;
|
||||
dataStore.visible = true;
|
||||
dataStore.title = "编辑产品分类";
|
||||
dataStore.row = row;
|
||||
resetFrom();
|
||||
getProductClassCategoryRead(row.id);
|
||||
};
|
||||
//重置
|
||||
const handleResetClick = () => {
|
||||
if (dataStore.title === "添加产品分类") {
|
||||
formRef!.value!.ruleFormRef.resetFields();
|
||||
resetFrom();
|
||||
} else {
|
||||
getProductClassCategoryRead(dataStore.row.id);
|
||||
}
|
||||
};
|
||||
//提交
|
||||
const handleConfirmClick = () => {
|
||||
if (!formRef.value!.ruleFormRef) return;
|
||||
formRef!.value!.ruleFormRef!.validate((valid: any) => {
|
||||
if (valid) {
|
||||
dataStore.title === "编辑产品分类" ? getProductCategoryUpdate() : getArticleCategorySave(dataStore.ruleForm);
|
||||
console.log("submit!");
|
||||
} else {
|
||||
console.log("error submit!");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
//排序input框失焦
|
||||
const handleBlur = (row: any) => {
|
||||
getArticleCategorySort(row);
|
||||
};
|
||||
//
|
||||
const handleInput = (row: any) => {
|
||||
row.sort = integerRexg(row.sort);
|
||||
};
|
||||
|
||||
//添加产品
|
||||
const handleAddProduct = (index: any, row: any) => {
|
||||
console.log(index, row, "=========row========");
|
||||
};
|
||||
//删除
|
||||
const handleDelete = (index: any, row: any) => {
|
||||
// getProductCategoryDel(row.id);
|
||||
console.log(index, row, "=========row========");
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
4
src/views/productManagement/link/constant/index.ts
Normal file
4
src/views/productManagement/link/constant/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { FORM_DATA, RULE_FORM } from "./search";
|
||||
import { COLUMNS } from "./table";
|
||||
import { OPERATIONS } from "./operations";
|
||||
export { FORM_DATA, RULE_FORM, COLUMNS, OPERATIONS };
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user