Files
vue3-element-admin/src/views/system/dict/dict-item.vue
Ray.Hao ff6f68c0ce feat: 更新mock数据和用户store逻辑
重构用户模块的异步函数,添加租户和租户计划的mock接口,优化字典表单和请求拦截器的实现。
2026-03-06 22:47:09 +08:00

340 lines
9.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="app-container">
<div class="filter-section">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="关键字" prop="keywords">
<el-input
v-model="queryParams.keywords"
placeholder="字典标签/字典值"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item class="search-buttons">
<el-button type="primary" icon="search" @click="handleQuery">搜索</el-button>
<el-button icon="refresh" @click="handleResetQuery">重置</el-button>
</el-form-item>
</el-form>
</div>
<el-card shadow="never" class="table-section">
<div class="table-section__toolbar">
<div class="table-section__toolbar--actions">
<el-button type="success" icon="plus" @click="openDialog()">新增</el-button>
<el-button
type="danger"
:disabled="ids.length === 0"
icon="delete"
@click="handleDelete()"
>
删除
</el-button>
</div>
</div>
<el-table
v-loading="loading"
highlight-current-row
:data="tableData"
border
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="字典项标签" prop="label" />
<el-table-column label="字典项值" prop="value" />
<el-table-column label="排序" prop="sort" />
<el-table-column label="状态">
<template #default="scope">
<el-tag :type="scope.row.status === 1 ? 'success' : 'info'">
{{ scope.row.status === 1 ? "启用" : "禁用" }}
</el-tag>
</template>
</el-table-column>
<el-table-column fixed="right" label="操作" align="center" width="220">
<template #default="scope">
<el-button
type="primary"
link
size="small"
icon="edit"
@click.stop="openDialog(scope.row)"
>
编辑
</el-button>
<el-button
type="danger"
link
size="small"
icon="delete"
@click.stop="handleDelete(scope.row.id)"
>
删除
</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="fetchData"
/>
</el-card>
<el-dialog
v-model="dialogState.visible"
:title="dialogState.title"
width="600px"
@close="closeDialog"
>
<el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="100px">
<el-form-item label="字典项标签" prop="label">
<el-input v-model="formData.label" placeholder="请输入字典标签" />
</el-form-item>
<el-form-item label="字典项值" prop="value">
<el-input v-model="formData.value" placeholder="请输入字典值" />
</el-form-item>
<el-form-item label="状态">
<el-radio-group v-model="formData.status">
<el-radio :value="1">启用</el-radio>
<el-radio :value="0">禁用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="排序">
<el-input-number v-model="formData.sort" controls-position="right" />
</el-form-item>
<el-form-item>
<template #label>
<div class="flex-y-center">
标签类型
<el-tooltip>
<template #content>回显样式为空时则显示 '文本'</template>
<el-icon class="ml-1 cursor-pointer">
<QuestionFilled />
</el-icon>
</el-tooltip>
</div>
</template>
<el-select
v-model="formData.tagType"
placeholder="请选择标签类型"
clearable
@clear="formData.tagType = ''"
>
<template #label="{ value }">
<el-tag v-if="value" :type="value">
{{ formData.label ? formData.label : "字典标签" }}
</el-tag>
</template>
<!-- <el-option label="默认文本" value="" /> -->
<el-option v-for="type in tagType" :key="type" :label="type" :value="type as string">
<div flex-y-center gap-10px>
<el-tag :type="type">{{ formData.label ?? "字典标签" }}</el-tag>
<span>{{ type }}</span>
</div>
</el-option>
</el-select>
</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>
<script setup lang="ts">
import DictAPI from "@/api/system/dict";
import type { DictItemQueryParams, DictItem, DictItemForm } from "@/types/api";
import type { FormInstance, FormRules } from "element-plus";
const route = useRoute();
// 字典编码
const dictCode = ref(route.query.dictCode as string);
// 表单引用
const queryFormRef = ref<FormInstance>();
const dataFormRef = ref<FormInstance>();
// 查询参数
const queryParams = reactive<DictItemQueryParams>({
pageNum: 1,
pageSize: 10,
});
// 列表数据
const tableData = ref<DictItem[]>();
const total = ref(0);
const loading = ref(false);
const ids = ref<string[]>([]);
// 弹窗状态
const dialogState = reactive({
title: "",
visible: false,
});
// 表单数据
const formData = reactive<DictItemForm>({
sort: 1,
status: 1,
tagType: "",
});
// 标签类型选项
const tagType = ["primary", "success", "info", "warning", "danger"] as const;
// 验证规则
const rules: FormRules = {
value: [{ required: true, message: "请输入字典值", trigger: "blur" }],
label: [{ required: true, message: "请输入字典标签", trigger: "blur" }],
};
/**
* 加载字典项列表数据
*/
function fetchData(): void {
loading.value = true;
DictAPI.getDictItemPage(dictCode.value, queryParams)
.then((data) => {
tableData.value = data.list;
total.value = data.total ?? 0;
})
.finally(() => {
loading.value = false;
});
}
/**
* 查询按钮点击事件
*/
function handleQuery(): void {
queryParams.pageNum = 1;
fetchData();
}
/**
* 重置查询
*/
function handleResetQuery(): void {
queryFormRef.value?.resetFields();
queryParams.pageNum = 1;
fetchData();
}
/**
* 表格选择变化事件
*/
function handleSelectionChange(selection: DictItem[]): void {
ids.value = selection.map((item) => item.id);
}
/**
* 打开弹窗
* @param row 字典项数据(编辑时传入)
*/
function openDialog(row?: DictItem): void {
resetForm();
dialogState.visible = true;
dialogState.title = row ? "编辑字典值" : "新增字典值";
if (row?.id) {
DictAPI.getDictItemFormData(dictCode.value, row.id).then((data) => {
Object.assign(formData, data);
});
}
}
function resetForm(): void {
dataFormRef.value?.clearValidate();
formData.id = undefined;
formData.dictCode = dictCode.value;
formData.label = undefined;
formData.value = undefined;
formData.sort = 1;
formData.status = 1;
formData.tagType = "";
}
/**
* 提交表单
*/
function handleSubmit(): void {
dataFormRef.value?.validate((isValid) => {
if (isValid) {
loading.value = true;
const id = formData.id;
formData.dictCode = dictCode.value;
if (id) {
DictAPI.updateDictItem(dictCode.value, id, formData)
.then(() => {
ElMessage.success("修改成功");
closeDialog();
handleQuery();
})
.finally(() => (loading.value = false));
} else {
DictAPI.createDictItem(dictCode.value, formData)
.then(() => {
ElMessage.success("新增成功");
closeDialog();
handleQuery();
})
.finally(() => (loading.value = false));
}
}
});
}
/**
* 关闭弹窗
*/
function closeDialog(): void {
dialogState.visible = false;
dataFormRef.value?.resetFields();
resetForm();
}
/**
* 删除字典项
* @param id 字典项ID
*/
function handleDelete(id?: number): void {
const itemIds = [id || ids.value].join(",");
if (!itemIds) {
ElMessage.warning("请勾选删除项");
return;
}
ElMessageBox.confirm("确认删除已选中的数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(
() => {
DictAPI.deleteDictItems(dictCode.value, itemIds).then(() => {
ElMessage.success("删除成功");
handleResetQuery();
});
},
() => {
ElMessage.info("已取消删除");
}
);
}
onMounted(() => {
handleQuery();
});
</script>