@@ -0,0 +1,13 @@ | |||||
import request from "@/utils/request.js"; | |||||
/** | |||||
* @description 获取用户列表 | |||||
* @param sex ,pageNum,pageSize | |||||
* @returns data | |||||
*/ | |||||
export function modeListApi(sex, pageNum, pageSize, videoType) { | |||||
return request({ | |||||
url: `/api/personPatch/list?sex=${sex}&pageNum=${pageNum}&pageSize=${pageSize}&videoType=${videoType}`, | |||||
method: 'get' | |||||
}) | |||||
} |
@@ -11,47 +11,69 @@ | |||||
</div> | </div> | ||||
<!-- 侧边路由列表 --> | <!-- 侧边路由列表 --> | ||||
<div class="myRouter"> | <div class="myRouter"> | ||||
<!-- 动态路由 --> | |||||
<div | |||||
v-for="item in MenuList" | |||||
:key="item.id" | |||||
class="myRouter-item" | |||||
@click="showChildrenRouter = item.name" | |||||
> | |||||
<div class="icon"> | |||||
<el-icon><i-ep-edit /></el-icon> | |||||
<span>{{ item.name }}</span> | |||||
</div> | |||||
<div | |||||
v-show="showChildrenRouter == item.name" | |||||
v-for="childrens in item.children" | |||||
:key="childrens.id" | |||||
class="childrenRouter" | |||||
@click="router.push(`/${childrens.url}`)" | |||||
> | |||||
{{ childrens.name }} | |||||
</div> | |||||
</div> | |||||
<!-- 固定路由 --> | |||||
<div class="myRouter-item" @click="router.push('/model')"> | <div class="myRouter-item" @click="router.push('/model')"> | ||||
<div class="icon"> | <div class="icon"> | ||||
<el-icon><i-ep-edit /></el-icon> | <el-icon><i-ep-edit /></el-icon> | ||||
{{ $t("modelMangage.title") }} | |||||
</div> | </div> | ||||
{{ $t("modelMangage.title") }} | |||||
</div> | </div> | ||||
<div class="myRouter-item" @click="router.push('/model')"> | <div class="myRouter-item" @click="router.push('/model')"> | ||||
<div class="icon"> | <div class="icon"> | ||||
<el-icon><i-ep-edit /></el-icon> | <el-icon><i-ep-edit /></el-icon> | ||||
{{ $t("businessMangage.title") }} | |||||
</div> | </div> | ||||
{{ $t("businessMangage.title") }} | |||||
</div> | </div> | ||||
<div class="myRouter-item" @click="router.push('/keyCheck')"> | <div class="myRouter-item" @click="router.push('/keyCheck')"> | ||||
<div class="icon"> | <div class="icon"> | ||||
<el-icon><i-ep-edit /></el-icon> | <el-icon><i-ep-edit /></el-icon> | ||||
{{ $t("keyMangage.title") }} | |||||
</div> | </div> | ||||
{{ $t("keyMangage.title") }} | |||||
</div> | </div> | ||||
<div class="myRouter-item" @click="router.push('/model')"> | <div class="myRouter-item" @click="router.push('/model')"> | ||||
<div class="icon"> | <div class="icon"> | ||||
<el-icon><i-ep-edit /></el-icon> | <el-icon><i-ep-edit /></el-icon> | ||||
{{ $t("priceMangage.title") }} | |||||
</div> | </div> | ||||
{{ $t("priceMangage.title") }} | |||||
</div> | </div> | ||||
<div class="myRouter-item" @click="router.push('/model')"> | <div class="myRouter-item" @click="router.push('/model')"> | ||||
<div class="icon"> | <div class="icon"> | ||||
<el-icon><i-ep-edit /></el-icon> | <el-icon><i-ep-edit /></el-icon> | ||||
{{ $t("dataCount.title") }} | |||||
</div> | </div> | ||||
{{ $t("dataCount.title") }} | |||||
</div> | </div> | ||||
<div class="bottomBtx"> | <div class="bottomBtx"> | ||||
<div class="myRouter-item" @click="router.push('/model')"> | <div class="myRouter-item" @click="router.push('/model')"> | ||||
<div class="icon"> | <div class="icon"> | ||||
<el-icon><i-ep-DocumentAdd /></el-icon> | <el-icon><i-ep-DocumentAdd /></el-icon> | ||||
{{ $t("apiMangage.title") }} | |||||
</div> | </div> | ||||
{{ $t("apiMangage.title") }} | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
@@ -177,7 +199,7 @@ const updateShowTalkUsDialog = (newValue: any) => { | |||||
//#endregion ------------------------------------ | //#endregion ------------------------------------ | ||||
//#region 获取路由列表 | //#region 获取路由列表 | ||||
const MenuList = ref([]); | |||||
const MenuList = ref([{ id: "", name: "" }]); | |||||
async function getMenuNavFunc() { | async function getMenuNavFunc() { | ||||
try { | try { | ||||
const res = await getMenuNavApi(); | const res = await getMenuNavApi(); | ||||
@@ -186,6 +208,11 @@ async function getMenuNavFunc() { | |||||
console.log(error); | console.log(error); | ||||
} | } | ||||
} | } | ||||
//#endregion ------------------------------------ | |||||
//#region 路由及子路由 | |||||
const showChildrenRouter = ref(""); | |||||
//#endregion ------------------------------------ | //#endregion ------------------------------------ | ||||
</script> | </script> | ||||
@@ -221,10 +248,10 @@ async function getMenuNavFunc() { | |||||
bottom: 30px; | bottom: 30px; | ||||
} | } | ||||
&-item { | &-item { | ||||
display: flex; | |||||
// display: flex; | |||||
width: 100%; | width: 100%; | ||||
height: 50px; | |||||
padding-left: 10px; | |||||
// height: 50px; | |||||
// padding-left: 10px; | |||||
font-size: 20px; | font-size: 20px; | ||||
font-weight: 500; | font-weight: 500; | ||||
line-height: 50px; | line-height: 50px; | ||||
@@ -235,14 +262,20 @@ async function getMenuNavFunc() { | |||||
border-radius: 5px; | border-radius: 5px; | ||||
margin-bottom: 20px; | margin-bottom: 20px; | ||||
margin-right: 20px; | margin-right: 20px; | ||||
overflow: hidden; | |||||
.icon { | .icon { | ||||
width: 40px; | |||||
height: 40px; | |||||
display: flex; | |||||
color: #fff; | color: #fff; | ||||
border-radius: 50%; | border-radius: 50%; | ||||
margin-right: 10px; | |||||
width: 100%; | |||||
height: 50px; | |||||
line-height: 50px; | |||||
.el-icon { | .el-icon { | ||||
margin-left: 10px; | |||||
margin-top: 12px; | |||||
margin-right: 10px; | |||||
width: 25px; | width: 25px; | ||||
height: 25px; | height: 25px; | ||||
font-size: 25px; | font-size: 25px; | ||||
@@ -252,11 +285,20 @@ async function getMenuNavFunc() { | |||||
vertical-align: sub; | vertical-align: sub; | ||||
} | } | ||||
} | } | ||||
.childrenRouter { | |||||
cursor: pointer; | |||||
} | |||||
.childrenRouter:hover { | |||||
background-color: #304156; | |||||
} | |||||
&:hover { | &:hover { | ||||
// background: rgba(255, 255, 255, 0.2); | // background: rgba(255, 255, 255, 0.2); | ||||
color: #000; | color: #000; | ||||
background: #fff; | background: #fff; | ||||
.icon { | |||||
color: #000; | |||||
} | |||||
.el-icon { | .el-icon { | ||||
// color: #d4d0ff; | // color: #d4d0ff; | ||||
color: #000; | color: #000; | ||||
@@ -37,6 +37,7 @@ export const constantRoutes: RouteRecordRaw[] = [ | |||||
}, | }, | ||||
], | ], | ||||
}, | }, | ||||
{ | { | ||||
path: "/", | path: "/", | ||||
component: Layout, | component: Layout, | ||||
@@ -55,6 +56,43 @@ export const constantRoutes: RouteRecordRaw[] = [ | |||||
}, | }, | ||||
], | ], | ||||
}, | }, | ||||
// 系统设置路由 | |||||
{ | |||||
path: "/", | |||||
component: Layout, | |||||
redirect: "/userList", | |||||
children: [ | |||||
{ | |||||
path: "userList", | |||||
component: () => import("@/views/dict/index.vue"), | |||||
name: "userList", | |||||
meta: { | |||||
title: "userList", | |||||
icon: "homepage", | |||||
affix: true, | |||||
name: "userListMangage.title", | |||||
}, | |||||
}, | |||||
], | |||||
}, | |||||
{ | |||||
path: "/", | |||||
component: Layout, | |||||
redirect: "/ruleList", | |||||
children: [ | |||||
{ | |||||
path: "ruleList", | |||||
component: () => import("@/views/mangage/ruleList.vue"), | |||||
name: "ruleList", | |||||
meta: { | |||||
title: "ruleList", | |||||
icon: "homepage", | |||||
affix: true, | |||||
name: "ruleListMangage.title", | |||||
}, | |||||
}, | |||||
], | |||||
}, | |||||
]; | ]; | ||||
/** | /** | ||||
@@ -14,6 +14,7 @@ declare module '@vue/runtime-core' { | |||||
EditPosition: typeof import('./../components/EditPosition.vue')['default'] | EditPosition: typeof import('./../components/EditPosition.vue')['default'] | ||||
'EditPosition copy': typeof import('./../components/EditPosition copy.vue')['default'] | 'EditPosition copy': typeof import('./../components/EditPosition copy.vue')['default'] | ||||
ElButton: typeof import('element-plus/es')['ElButton'] | ElButton: typeof import('element-plus/es')['ElButton'] | ||||
ElCard: typeof import('element-plus/es')['ElCard'] | |||||
ElDialog: typeof import('element-plus/es')['ElDialog'] | ElDialog: typeof import('element-plus/es')['ElDialog'] | ||||
ElDropdown: typeof import('element-plus/es')['ElDropdown'] | ElDropdown: typeof import('element-plus/es')['ElDropdown'] | ||||
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem'] | ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem'] | ||||
@@ -24,15 +25,26 @@ declare module '@vue/runtime-core' { | |||||
ElInput: typeof import('element-plus/es')['ElInput'] | ElInput: typeof import('element-plus/es')['ElInput'] | ||||
ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] | ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] | ||||
ElOption: typeof import('element-plus/es')['ElOption'] | ElOption: typeof import('element-plus/es')['ElOption'] | ||||
ElPagination: typeof import('element-plus/es')['ElPagination'] | |||||
ElRadio: typeof import('element-plus/es')['ElRadio'] | |||||
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] | |||||
ElSelect: typeof import('element-plus/es')['ElSelect'] | ElSelect: typeof import('element-plus/es')['ElSelect'] | ||||
ElSwitch: typeof import('element-plus/es')['ElSwitch'] | ElSwitch: typeof import('element-plus/es')['ElSwitch'] | ||||
ElTable: typeof import('element-plus/es')['ElTable'] | |||||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] | |||||
ElTag: typeof import('element-plus/es')['ElTag'] | |||||
ElTooltip: typeof import('element-plus/es')['ElTooltip'] | ElTooltip: typeof import('element-plus/es')['ElTooltip'] | ||||
ElUpload: typeof import('element-plus/es')['ElUpload'] | ElUpload: typeof import('element-plus/es')['ElUpload'] | ||||
GithubCorner: typeof import('./../components/GithubCorner/index.vue')['default'] | GithubCorner: typeof import('./../components/GithubCorner/index.vue')['default'] | ||||
Hamburger: typeof import('./../components/Hamburger/index.vue')['default'] | Hamburger: typeof import('./../components/Hamburger/index.vue')['default'] | ||||
IconSelect: typeof import('./../components/IconSelect/index.vue')['default'] | IconSelect: typeof import('./../components/IconSelect/index.vue')['default'] | ||||
IEpCollection: typeof import('~icons/ep/collection')['default'] | |||||
IEpDelete: typeof import('~icons/ep/delete')['default'] | |||||
IEpDocumentAdd: typeof import('~icons/ep/document-add')['default'] | IEpDocumentAdd: typeof import('~icons/ep/document-add')['default'] | ||||
IEpEdit: typeof import('~icons/ep/edit')['default'] | IEpEdit: typeof import('~icons/ep/edit')['default'] | ||||
IEpPlus: typeof import('~icons/ep/plus')['default'] | |||||
IEpRefresh: typeof import('~icons/ep/refresh')['default'] | |||||
IEpSearch: typeof import('~icons/ep/search')['default'] | |||||
LangSelect: typeof import('./../components/LangSelect/index.vue')['default'] | LangSelect: typeof import('./../components/LangSelect/index.vue')['default'] | ||||
MultiUpload: typeof import('./../components/Upload/MultiUpload.vue')['default'] | MultiUpload: typeof import('./../components/Upload/MultiUpload.vue')['default'] | ||||
MyLoading: typeof import('./../components/myLoading.vue')['default'] | MyLoading: typeof import('./../components/myLoading.vue')['default'] | ||||
@@ -48,5 +60,6 @@ declare module '@vue/runtime-core' { | |||||
} | } | ||||
export interface ComponentCustomProperties { | export interface ComponentCustomProperties { | ||||
vInfiniteScroll: typeof import('element-plus/es')['ElInfiniteScroll'] | vInfiniteScroll: typeof import('element-plus/es')['ElInfiniteScroll'] | ||||
vLoading: typeof import('element-plus/es')['ElLoadingDirective'] | |||||
} | } | ||||
} | } |
@@ -0,0 +1,325 @@ | |||||
<!-- 字典数据 --> | |||||
<script setup lang="ts"> | |||||
import { | |||||
getDictPage, | |||||
getDictFormData, | |||||
addDict, | |||||
updateDict, | |||||
deleteDict, | |||||
} from "@/api/dict"; | |||||
import { DictPageVO, DictForm, DictQuery } from "@/api/dict/types"; | |||||
defineOptions({ | |||||
name: "DictData", | |||||
inheritAttrs: false, | |||||
}); | |||||
const props = defineProps({ | |||||
typeCode: { | |||||
type: String, | |||||
default: () => { | |||||
return ""; | |||||
}, | |||||
}, | |||||
typeName: { | |||||
type: String, | |||||
default: () => { | |||||
return ""; | |||||
}, | |||||
}, | |||||
}); | |||||
watch( | |||||
() => props.typeCode, | |||||
(newVal: string) => { | |||||
queryParams.typeCode = newVal; | |||||
formData.typeCode = newVal; | |||||
resetQuery(); | |||||
} | |||||
); | |||||
const queryFormRef = ref(ElForm); | |||||
const dataFormRef = ref(ElForm); | |||||
const loading = ref(false); | |||||
const ids = ref<number[]>([]); | |||||
const total = ref(0); | |||||
const queryParams = reactive<DictQuery>({ | |||||
pageNum: 1, | |||||
pageSize: 10, | |||||
typeCode: props.typeCode, | |||||
}); | |||||
const dictList = ref<DictPageVO[]>(); | |||||
const dialog = reactive<DialogOption>({ | |||||
visible: false, | |||||
}); | |||||
const formData = reactive<DictForm>({ | |||||
status: 1, | |||||
typeCode: props.typeCode, | |||||
sort: 1, | |||||
}); | |||||
const rules = reactive({ | |||||
name: [{ required: true, message: "请输入字典名称", trigger: "blur" }], | |||||
value: [{ required: true, message: "请输入字典值", trigger: "blur" }], | |||||
}); | |||||
/** | |||||
* 查询 | |||||
*/ | |||||
function handleQuery() { | |||||
if (queryParams.typeCode) { | |||||
loading.value = true; | |||||
getDictPage(queryParams) | |||||
.then(({ data }) => { | |||||
dictList.value = data.list; | |||||
total.value = data.total; | |||||
}) | |||||
.finally(() => (loading.value = false)); | |||||
} | |||||
} | |||||
/** | |||||
* 重置查询 | |||||
*/ | |||||
function resetQuery() { | |||||
queryFormRef.value.resetFields(); | |||||
queryParams.pageNum = 1; | |||||
handleQuery(); | |||||
} | |||||
/** | |||||
* 行checkbox change事件 | |||||
* | |||||
* @param selection | |||||
*/ | |||||
function handleSelectionChange(selection: any) { | |||||
ids.value = selection.map((item: any) => item.id); | |||||
} | |||||
/** | |||||
* 打开字典表单弹窗 | |||||
* | |||||
* @param dictId 字典ID | |||||
*/ | |||||
function openDialog(dictId?: number) { | |||||
dialog.visible = true; | |||||
if (dictId) { | |||||
dialog.title = "修改字典"; | |||||
getDictFormData(dictId).then(({ data }) => { | |||||
Object.assign(formData, data); | |||||
}); | |||||
} else { | |||||
dialog.title = "新增字典"; | |||||
} | |||||
} | |||||
/** | |||||
* 字典表单提交 | |||||
*/ | |||||
function handleSubmit() { | |||||
dataFormRef.value.validate((isValid: boolean) => { | |||||
if (isValid) { | |||||
loading.value = false; | |||||
const dictId = formData.id; | |||||
if (dictId) { | |||||
updateDict(dictId, formData) | |||||
.then(() => { | |||||
ElMessage.success("修改成功"); | |||||
closeDialog(); | |||||
resetQuery(); | |||||
}) | |||||
.finally(() => (loading.value = false)); | |||||
} else { | |||||
addDict(formData) | |||||
.then(() => { | |||||
ElMessage.success("新增成功"); | |||||
closeDialog(); | |||||
resetQuery(); | |||||
}) | |||||
.finally(() => (loading.value = false)); | |||||
} | |||||
} | |||||
}); | |||||
} | |||||
/** | |||||
* 关闭弹窗 | |||||
*/ | |||||
function closeDialog() { | |||||
dialog.visible = false; | |||||
resetForm(); | |||||
} | |||||
/** | |||||
* 重置表单 | |||||
*/ | |||||
function resetForm() { | |||||
dataFormRef.value.resetFields(); | |||||
dataFormRef.value.clearValidate(); | |||||
formData.id = undefined; | |||||
formData.status = 1; | |||||
formData.sort = 1; | |||||
formData.typeCode = props.typeCode; | |||||
} | |||||
/** | |||||
* 删除字典 | |||||
*/ | |||||
function handleDelete(dictId?: number) { | |||||
const dictIds = [dictId || ids.value].join(","); | |||||
if (!dictIds) { | |||||
ElMessage.warning("请勾选删除项"); | |||||
return; | |||||
} | |||||
ElMessageBox.confirm("确认删除已选中的数据项?", "警告", { | |||||
confirmButtonText: "确定", | |||||
cancelButtonText: "取消", | |||||
type: "warning", | |||||
}).then(() => { | |||||
deleteDict(dictIds).then(() => { | |||||
ElMessage.success("删除成功"); | |||||
resetQuery(); | |||||
}); | |||||
}); | |||||
} | |||||
onMounted(() => { | |||||
handleQuery(); | |||||
}); | |||||
</script> | |||||
<template> | |||||
<div class="app-container"> | |||||
<div class="search-container"> | |||||
<!-- 搜索表单 --> | |||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true"> | |||||
<el-form-item label="关键字" prop="name"> | |||||
<el-input | |||||
v-model="queryParams.name" | |||||
placeholder="字典名称" | |||||
clearable | |||||
/> | |||||
</el-form-item> | |||||
<el-form-item> | |||||
<el-button type="primary" @click="handleQuery" | |||||
><i-ep-search />搜索</el-button | |||||
> | |||||
<el-button @click="resetQuery"> <i-ep-refresh />重置</el-button> | |||||
</el-form-item> | |||||
</el-form> | |||||
</div> | |||||
<el-card shadow="never"> | |||||
<template #header> | |||||
<el-button | |||||
v-hasPerm="['sys:dict:add']" | |||||
type="success" | |||||
@click="openDialog()" | |||||
><i-ep-plus />新增</el-button | |||||
> | |||||
<el-button | |||||
v-hasPerm="['sys:dict:delete']" | |||||
type="danger" | |||||
:disabled="ids.length === 0" | |||||
@click="handleDelete()" | |||||
><i-ep-delete />删除</el-button | |||||
> | |||||
</template> | |||||
<!-- 数据表格 --> | |||||
<el-table | |||||
v-loading="loading" | |||||
:data="dictList" | |||||
border | |||||
@selection-change="handleSelectionChange" | |||||
> | |||||
<el-table-column type="selection" width="50" /> | |||||
<el-table-column label="字典名称" prop="name" /> | |||||
<el-table-column label="字典值" prop="value" /> | |||||
<el-table-column label="状态" align="center"> | |||||
<template #default="scope"> | |||||
<el-tag v-if="scope.row.status === 1" type="success">启用</el-tag> | |||||
<el-tag v-else type="info">禁用</el-tag> | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column fixed="right" label="操作" align="center"> | |||||
<template #default="scope"> | |||||
<el-button | |||||
v-hasPerm="['sys:dict:edit']" | |||||
type="primary" | |||||
link | |||||
@click="openDialog(scope.row.id)" | |||||
><i-ep-edit />编辑</el-button | |||||
> | |||||
<el-button | |||||
v-hasPerm="['sys:dict:delete']" | |||||
type="primary" | |||||
link | |||||
@click.stop="handleDelete(scope.row.id)" | |||||
><i-ep-delete />删除</el-button | |||||
> | |||||
</template> | |||||
</el-table-column> | |||||
</el-table> | |||||
<pagination | |||||
v-if="total > 0" | |||||
v-model:total="total" | |||||
v-model:page="queryParams.pageNum" | |||||
v-model:limit="queryParams.pageSize" | |||||
@pagination="handleQuery" | |||||
/> | |||||
</el-card> | |||||
<!-- 表单弹窗 --> | |||||
<el-dialog | |||||
v-model="dialog.visible" | |||||
:title="dialog.title" | |||||
width="500px" | |||||
@close="closeDialog" | |||||
> | |||||
<el-form | |||||
ref="dataFormRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-width="100px" | |||||
> | |||||
<el-form-item label="字典名称">{{ typeName }}</el-form-item> | |||||
<el-form-item label="字典名称" prop="name"> | |||||
<el-input v-model="formData.name" placeholder="请输入字典名称" /> | |||||
</el-form-item> | |||||
<el-form-item label="字典值" prop="value"> | |||||
<el-input v-model="formData.value" placeholder="字典值" /> | |||||
</el-form-item> | |||||
<el-form-item label="排序" prop="sort"> | |||||
<el-input-number | |||||
v-model="formData.sort" | |||||
controls-position="right" | |||||
:min="0" | |||||
/> | |||||
</el-form-item> | |||||
<el-form-item label="状态" prop="status"> | |||||
<el-radio-group v-model="formData.status"> | |||||
<el-radio :label="1">正常</el-radio> | |||||
<el-radio :label="0">停用</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
<el-form-item label="备注" prop="remark"> | |||||
<el-input v-model="formData.remark" type="textarea" /> | |||||
</el-form-item> | |||||
</el-form> | |||||
<template #footer> | |||||
<div class="dialog-footer"> | |||||
<el-button type="primary" @click="handleSubmit">确 定</el-button> | |||||
<el-button @click="closeDialog">取 消</el-button> | |||||
</div> | |||||
</template> | |||||
</el-dialog> | |||||
</div> | |||||
</template> |
@@ -0,0 +1,322 @@ | |||||
<template> | |||||
<div class="app-container"> | |||||
<div class="search-container"> | |||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true"> | |||||
<el-form-item label="关键字" prop="name"> | |||||
<el-input | |||||
v-model="queryParams.keywords" | |||||
placeholder="字典类型名称/编码" | |||||
clearable | |||||
@keyup.enter="handleQuery" | |||||
/> | |||||
</el-form-item> | |||||
<el-form-item> | |||||
<el-button type="primary" @click="handleQuery()" | |||||
><i-ep-search />搜索</el-button | |||||
> | |||||
<el-button @click="resetQuery()"><i-ep-refresh />重置</el-button> | |||||
</el-form-item> | |||||
</el-form> | |||||
</div> | |||||
<el-card shadow="never" class="table-container"> | |||||
<template #header> | |||||
<el-button | |||||
v-hasPerm="['sys:dict_type:add']" | |||||
type="success" | |||||
@click="openDialog()" | |||||
><i-ep-plus />新增</el-button | |||||
> | |||||
<el-button | |||||
type="danger" | |||||
:disabled="ids.length === 0" | |||||
@click="handleDelete()" | |||||
><i-ep-delete />删除</el-button | |||||
> | |||||
</template> | |||||
<el-table | |||||
v-loading="loading" | |||||
highlight-current-row | |||||
:data="dictTypeList" | |||||
border | |||||
@selection-change="handleSelectionChange" | |||||
> | |||||
<el-table-column type="selection" width="55" align="center" /> | |||||
<el-table-column label="字典类型名称" prop="name" width="200" /> | |||||
<el-table-column label="字典类型编码" prop="code" width="200" /> | |||||
<el-table-column label="状态" align="center" width="100"> | |||||
<template #default="scope"> | |||||
<el-tag v-if="scope.row.status === 1" type="success">启用</el-tag> | |||||
<el-tag v-else type="info">禁用</el-tag> | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column label="备注" prop="remark" align="center" /> | |||||
<el-table-column fixed="right" label="操作" align="center" width="220"> | |||||
<template #default="scope"> | |||||
<el-button | |||||
type="primary" | |||||
link | |||||
size="small" | |||||
@click.stop="openDictDialog(scope.row)" | |||||
><i-ep-Collection />字典数据</el-button | |||||
> | |||||
<el-button | |||||
v-hasPerm="['sys:dict_type:edit']" | |||||
type="primary" | |||||
link | |||||
size="small" | |||||
@click.stop="openDialog(scope.row.id)" | |||||
><i-ep-edit />编辑</el-button | |||||
> | |||||
<el-button | |||||
v-hasPerm="['sys:dict_type:delete']" | |||||
type="primary" | |||||
link | |||||
size="small" | |||||
@click.stop="handleDelete(scope.row.id)" | |||||
><i-ep-delete />删除</el-button | |||||
> | |||||
</template> | |||||
</el-table-column> | |||||
</el-table> | |||||
<pagination | |||||
v-if="total > 0" | |||||
v-model:total="total" | |||||
v-model:page="queryParams.pageNum" | |||||
v-model:limit="queryParams.pageSize" | |||||
@pagination="handleQuery" | |||||
/> | |||||
</el-card> | |||||
<el-dialog | |||||
v-model="dialog.visible" | |||||
:title="dialog.title" | |||||
width="500px" | |||||
@close="closeDialog" | |||||
> | |||||
<el-form | |||||
ref="dataFormRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-width="80px" | |||||
> | |||||
<el-form-item label="字典名称" prop="name"> | |||||
<el-input v-model="formData.name" placeholder="请输入字典名称" /> | |||||
</el-form-item> | |||||
<el-form-item label="字典编码" prop="code"> | |||||
<el-input v-model="formData.code" placeholder="请输入字典编码" /> | |||||
</el-form-item> | |||||
<el-form-item label="状态" prop="status"> | |||||
<el-radio-group v-model="formData.status"> | |||||
<el-radio :label="1">正常</el-radio> | |||||
<el-radio :label="0">停用</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
<el-form-item label="备注" prop="remark"> | |||||
<el-input | |||||
v-model="formData.remark" | |||||
type="textarea" | |||||
placeholder="字典类型备注" | |||||
:autosize="{ minRows: 2, maxRows: 4 }" | |||||
/> | |||||
</el-form-item> | |||||
</el-form> | |||||
<template #footer> | |||||
<div class="dialog-footer"> | |||||
<el-button type="primary" @click="handleSubmit">确 定</el-button> | |||||
<el-button @click="closeDialog">取 消</el-button> | |||||
</div> | |||||
</template> | |||||
</el-dialog> | |||||
<!--字典数据弹窗--> | |||||
<el-dialog | |||||
v-model="dictDataDialog.visible" | |||||
:title="dictDataDialog.title" | |||||
width="1000px" | |||||
@close="closeDictDialog" | |||||
> | |||||
<dict-item | |||||
v-model:typeCode="selectedDictType.typeCode" | |||||
v-model:typeName="selectedDictType.typeName" | |||||
/> | |||||
</el-dialog> | |||||
</div> | |||||
</template> | |||||
<script setup> | |||||
import { | |||||
getDictTypePage, | |||||
getDictTypeForm, | |||||
addDictType, | |||||
updateDictType, | |||||
deleteDictTypes, | |||||
} from "@/api/dict"; | |||||
// import { DictTypePageVO, DictTypeQuery, DictTypeForm } from "@/api/dict/types"; | |||||
defineOptions({ | |||||
name: "DictType", | |||||
inheritAttrs: false, | |||||
}); | |||||
const queryFormRef = ref(""); | |||||
const dataFormRef = ref(""); | |||||
const loading = ref(false); | |||||
const ids = ref([]); | |||||
const total = ref(0); | |||||
const queryParams = reactive({ | |||||
pageNum: 1, | |||||
pageSize: 10, | |||||
}); | |||||
const dictTypeList = ref(); | |||||
const dialog = reactive({ | |||||
visible: false, | |||||
}); | |||||
const formData = reactive({ | |||||
status: 1, | |||||
}); | |||||
const rules = reactive({ | |||||
name: [{ required: true, message: "请输入字典类型名称", trigger: "blur" }], | |||||
code: [{ required: true, message: "请输入字典类型编码", trigger: "blur" }], | |||||
}); | |||||
/** 查询 */ | |||||
function handleQuery() { | |||||
loading.value = true; | |||||
getDictTypePage(queryParams) | |||||
.then(({ data }) => { | |||||
dictTypeList.value = data.list; | |||||
total.value = data.total; | |||||
}) | |||||
.finally(() => { | |||||
loading.value = false; | |||||
}); | |||||
} | |||||
/** | |||||
* 重置查询 | |||||
*/ | |||||
function resetQuery() { | |||||
queryFormRef.value.resetFields(); | |||||
queryParams.pageNum = 1; | |||||
handleQuery(); | |||||
} | |||||
/** 行复选框选中 */ | |||||
function handleSelectionChange(selection) { | |||||
ids.value = selection.map((item) => item.id); | |||||
} | |||||
/** | |||||
* 打开字典类型表单弹窗 | |||||
* | |||||
* @param dicTypeId 字典类型ID | |||||
*/ | |||||
function openDialog(dicTypeId) { | |||||
dialog.visible = true; | |||||
if (dicTypeId) { | |||||
dialog.title = "修改字典类型"; | |||||
getDictTypeForm(dicTypeId).then(({ data }) => { | |||||
Object.assign(formData, data); | |||||
}); | |||||
} else { | |||||
dialog.title = "新增字典类型"; | |||||
} | |||||
} | |||||
/** 字典类型表单提交 */ | |||||
function handleSubmit() { | |||||
dataFormRef.value.validate((isValid) => { | |||||
if (isValid) { | |||||
loading.value = false; | |||||
const dictTypeId = formData.id; | |||||
if (dictTypeId) { | |||||
updateDictType(dictTypeId, formData) | |||||
.then(() => { | |||||
ElMessage.success("修改成功"); | |||||
closeDialog(); | |||||
handleQuery(); | |||||
}) | |||||
.finally(() => (loading.value = false)); | |||||
} else { | |||||
addDictType(formData) | |||||
.then(() => { | |||||
ElMessage.success("新增成功"); | |||||
closeDialog(); | |||||
handleQuery(); | |||||
}) | |||||
.finally(() => (loading.value = false)); | |||||
} | |||||
} | |||||
}); | |||||
} | |||||
/** 关闭字典类型弹窗 */ | |||||
function closeDialog() { | |||||
dialog.visible = false; | |||||
resetForm(); | |||||
} | |||||
/** 重置字典类型表单 */ | |||||
function resetForm() { | |||||
dataFormRef.value.resetFields(); | |||||
dataFormRef.value.clearValidate(); | |||||
formData.id = undefined; | |||||
formData.status = 1; | |||||
} | |||||
/** 删除字典类型 */ | |||||
function handleDelete(dictTypeId) { | |||||
const dictTypeIds = [dictTypeId || ids.value].join(","); | |||||
if (!dictTypeIds) { | |||||
ElMessage.warning("请勾选删除项"); | |||||
return; | |||||
} | |||||
ElMessageBox.confirm("确认删除已选中的数据项?", "警告", { | |||||
confirmButtonText: "确定", | |||||
cancelButtonText: "取消", | |||||
type: "warning", | |||||
}).then(() => { | |||||
deleteDictTypes(dictTypeIds).then(() => { | |||||
ElMessage.success("删除成功"); | |||||
resetQuery(); | |||||
}); | |||||
}); | |||||
} | |||||
const dictDataDialog = reactive({ | |||||
visible: false, | |||||
}); | |||||
const selectedDictType = reactive({ typeCode: "", typeName: "" }); // 当前选中的字典类型 | |||||
/** 打开字典数据弹窗 */ | |||||
function openDictDialog(row) { | |||||
dictDataDialog.visible = true; | |||||
dictDataDialog.title = "【" + row.name + "】字典数据"; | |||||
selectedDictType.typeCode = row.code; | |||||
selectedDictType.typeName = row.name; | |||||
} | |||||
/** 关闭字典数据弹窗 */ | |||||
function closeDictDialog() { | |||||
dictDataDialog.visible = false; | |||||
} | |||||
onMounted(() => { | |||||
handleQuery(); | |||||
}); | |||||
</script> | |||||
<style lang="scss" scoped></style> |
@@ -0,0 +1,16 @@ | |||||
<template> | |||||
<div class="page flex justify-around"></div> | |||||
</template> | |||||
<!-- videoType==1为竖,==2为横 --> | |||||
<script setup></script> | |||||
<style lang="scss" scoped> | |||||
.page { | |||||
height: calc(100vh - 80px); | |||||
// height: calc(100vh - 80px); | |||||
background-color: #fff; | |||||
border-radius: 30px 0 0 0; | |||||
overflow: hidden; | |||||
} | |||||
</style> |
@@ -0,0 +1,16 @@ | |||||
<template> | |||||
<div class="page flex justify-around"></div> | |||||
</template> | |||||
<!-- videoType==1为竖,==2为横 --> | |||||
<script setup></script> | |||||
<style lang="scss" scoped> | |||||
.page { | |||||
height: calc(100vh - 80px); | |||||
// height: calc(100vh - 80px); | |||||
background-color: #fff; | |||||
border-radius: 30px 0 0 0; | |||||
overflow: hidden; | |||||
} | |||||
</style> |