congzc há 1 ano
ascendente
cometimento
fedcf416d9
8 ficheiros alterados com 799 adições e 14 eliminações
  1. +13
    -0
      src/apis/system/userList.js
  2. +56
    -14
      src/layout/index.vue
  3. +38
    -0
      src/router/index.ts
  4. +13
    -0
      src/types/components.d.ts
  5. +325
    -0
      src/views/dict/components/dict-item.vue
  6. +322
    -0
      src/views/dict/index.vue
  7. +16
    -0
      src/views/mangage/ruleList.vue
  8. +16
    -0
      src/views/mangage/userList.vue

+ 13
- 0
src/apis/system/userList.js Ver ficheiro

@@ -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'
})
}

+ 56
- 14
src/layout/index.vue Ver ficheiro

@@ -11,47 +11,69 @@
</div>
<!-- 侧边路由列表 -->
<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="icon">
<el-icon><i-ep-edit /></el-icon>
{{ $t("modelMangage.title") }}
</div>
{{ $t("modelMangage.title") }}
</div>

<div class="myRouter-item" @click="router.push('/model')">
<div class="icon">
<el-icon><i-ep-edit /></el-icon>
{{ $t("businessMangage.title") }}
</div>
{{ $t("businessMangage.title") }}
</div>

<div class="myRouter-item" @click="router.push('/keyCheck')">
<div class="icon">
<el-icon><i-ep-edit /></el-icon>
{{ $t("keyMangage.title") }}
</div>
{{ $t("keyMangage.title") }}
</div>

<div class="myRouter-item" @click="router.push('/model')">
<div class="icon">
<el-icon><i-ep-edit /></el-icon>
{{ $t("priceMangage.title") }}
</div>
{{ $t("priceMangage.title") }}
</div>

<div class="myRouter-item" @click="router.push('/model')">
<div class="icon">
<el-icon><i-ep-edit /></el-icon>
{{ $t("dataCount.title") }}
</div>
{{ $t("dataCount.title") }}
</div>

<div class="bottomBtx">
<div class="myRouter-item" @click="router.push('/model')">
<div class="icon">
<el-icon><i-ep-DocumentAdd /></el-icon>
{{ $t("apiMangage.title") }}
</div>
{{ $t("apiMangage.title") }}
</div>
</div>
</div>
@@ -177,7 +199,7 @@ const updateShowTalkUsDialog = (newValue: any) => {
//#endregion ------------------------------------

//#region 获取路由列表
const MenuList = ref([]);
const MenuList = ref([{ id: "", name: "" }]);
async function getMenuNavFunc() {
try {
const res = await getMenuNavApi();
@@ -186,6 +208,11 @@ async function getMenuNavFunc() {
console.log(error);
}
}
//#endregion ------------------------------------

//#region 路由及子路由
const showChildrenRouter = ref("");

//#endregion ------------------------------------
</script>

@@ -221,10 +248,10 @@ async function getMenuNavFunc() {
bottom: 30px;
}
&-item {
display: flex;
// display: flex;
width: 100%;
height: 50px;
padding-left: 10px;
// height: 50px;
// padding-left: 10px;
font-size: 20px;
font-weight: 500;
line-height: 50px;
@@ -235,14 +262,20 @@ async function getMenuNavFunc() {
border-radius: 5px;
margin-bottom: 20px;
margin-right: 20px;
overflow: hidden;
.icon {
width: 40px;
height: 40px;
display: flex;
color: #fff;
border-radius: 50%;
margin-right: 10px;
width: 100%;
height: 50px;
line-height: 50px;

.el-icon {
margin-left: 10px;
margin-top: 12px;
margin-right: 10px;
width: 25px;
height: 25px;
font-size: 25px;
@@ -252,11 +285,20 @@ async function getMenuNavFunc() {
vertical-align: sub;
}
}

.childrenRouter {
cursor: pointer;
}
.childrenRouter:hover {
background-color: #304156;
}
&:hover {
// background: rgba(255, 255, 255, 0.2);

color: #000;
background: #fff;
.icon {
color: #000;
}
.el-icon {
// color: #d4d0ff;
color: #000;


+ 38
- 0
src/router/index.ts Ver ficheiro

@@ -37,6 +37,7 @@ export const constantRoutes: RouteRecordRaw[] = [
},
],
},

{
path: "/",
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",
},
},
],
},
];

/**


+ 13
- 0
src/types/components.d.ts Ver ficheiro

@@ -14,6 +14,7 @@ declare module '@vue/runtime-core' {
EditPosition: typeof import('./../components/EditPosition.vue')['default']
'EditPosition copy': typeof import('./../components/EditPosition copy.vue')['default']
ElButton: typeof import('element-plus/es')['ElButton']
ElCard: typeof import('element-plus/es')['ElCard']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDropdown: typeof import('element-plus/es')['ElDropdown']
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
@@ -24,15 +25,26 @@ declare module '@vue/runtime-core' {
ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
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']
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']
ElUpload: typeof import('element-plus/es')['ElUpload']
GithubCorner: typeof import('./../components/GithubCorner/index.vue')['default']
Hamburger: typeof import('./../components/Hamburger/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']
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']
MultiUpload: typeof import('./../components/Upload/MultiUpload.vue')['default']
MyLoading: typeof import('./../components/myLoading.vue')['default']
@@ -48,5 +60,6 @@ declare module '@vue/runtime-core' {
}
export interface ComponentCustomProperties {
vInfiniteScroll: typeof import('element-plus/es')['ElInfiniteScroll']
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
}
}

+ 325
- 0
src/views/dict/components/dict-item.vue Ver ficheiro

@@ -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>

+ 322
- 0
src/views/dict/index.vue Ver ficheiro

@@ -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>

+ 16
- 0
src/views/mangage/ruleList.vue Ver ficheiro

@@ -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>

+ 16
- 0
src/views/mangage/userList.vue Ver ficheiro

@@ -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>

Carregando…
Cancelar
Guardar