1.更新 web-ui 页面 布局

2.修改 用户查询接口添加部门ID 条件
This commit is contained in:
Wang Chen Chen
2023-11-07 11:19:04 +08:00
parent 8b8e54bac9
commit 5c2acdc990
28 changed files with 1964 additions and 1906 deletions

View File

@@ -28,8 +28,13 @@ public class SearchPO extends PagePO implements java.io.Serializable {
/**
* 包含创建和修改用户信息
* include create and update user
*/
@Schema(description = "包含创建和修改用户信息")
private Boolean includeCauu;
public boolean isIncludeCauu() {
return this.getIncludeCauu() != null && this.getIncludeCauu();
}
}

View File

@@ -4,7 +4,6 @@ import com.xaaef.molly.common.domain.Pagination;
import com.xaaef.molly.common.po.SearchPO;
import com.xaaef.molly.common.util.JsonResult;
import com.xaaef.molly.monitor.entity.LmsLoginLog;
import com.xaaef.molly.monitor.entity.LmsOperLog;
import com.xaaef.molly.monitor.service.LmsLoginLogService;
import com.xaaef.molly.web.repeat.NoRepeatSubmit;
import io.swagger.v3.oas.annotations.Operation;

View File

@@ -23,7 +23,6 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Collection;
import java.util.List;
import static com.xaaef.molly.tenant.util.DelegateUtils.delegate;
@@ -60,8 +59,7 @@ public class PmsUserController {
@Operation(summary = "分页查询", description = "分页 查询所有")
@GetMapping("/query")
public JsonResult<Pagination<PmsUser>> pageQuery(UserQueryPO params) {
IPage<PmsUser> page = baseService.pageKeywords(params,
List.of(PmsUser::getUsername, PmsUser::getNickname));
IPage<PmsUser> page = baseService.pageKeywords(params);
return JsonResult.success(page.getTotal(), page.getRecords());
}

View File

@@ -29,4 +29,15 @@ public class UserQueryPO extends SearchParentPO {
*/
private Long deptId;
/**
* 包含关联的角色和部门信息
* include roles and departments
*/
@Schema(description = "包含关联的角色和部门信息")
private Boolean includeRad;
public boolean isIncludeRad() {
return this.getIncludeRad() != null && this.getIncludeRad();
}
}

View File

@@ -1,6 +1,8 @@
package com.xaaef.molly.perms.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xaaef.molly.perms.entity.PmsUser;
import com.xaaef.molly.perms.po.UserQueryPO;
import com.xaaef.molly.perms.vo.ResetPasswordVO;
import com.xaaef.molly.perms.vo.UpdatePasswordVO;
import com.xaaef.molly.perms.vo.UserRightsVO;
@@ -20,6 +22,10 @@ import java.util.Set;
public interface PmsUserService extends BaseService<PmsUser> {
IPage<PmsUser> pageKeywords(UserQueryPO params);
/**
* 修改密码
*

View File

@@ -7,7 +7,7 @@ import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xaaef.molly.auth.jwt.JwtLoginUser;
import com.xaaef.molly.auth.jwt.JwtSecurityUtils;
import com.xaaef.molly.auth.service.JwtTokenService;
@@ -15,7 +15,6 @@ import com.xaaef.molly.auth.service.UserLoginService;
import com.xaaef.molly.common.enums.AdminFlag;
import com.xaaef.molly.common.enums.StatusEnum;
import com.xaaef.molly.common.enums.UserType;
import com.xaaef.molly.common.po.SearchPO;
import com.xaaef.molly.common.util.IdUtils;
import com.xaaef.molly.internal.api.ApiCmsProjectService;
import com.xaaef.molly.internal.api.ApiSysConfigService;
@@ -27,6 +26,7 @@ import com.xaaef.molly.perms.entity.PmsRole;
import com.xaaef.molly.perms.entity.PmsUser;
import com.xaaef.molly.perms.mapper.PmsRoleMapper;
import com.xaaef.molly.perms.mapper.PmsUserMapper;
import com.xaaef.molly.perms.po.UserQueryPO;
import com.xaaef.molly.perms.service.PmsDeptService;
import com.xaaef.molly.perms.service.PmsRoleService;
import com.xaaef.molly.perms.service.PmsUserService;
@@ -83,12 +83,24 @@ public class PmsUserServiceImpl extends BaseServiceImpl<PmsUserMapper, PmsUser>
@Override
public IPage<PmsUser> pageKeywords(SearchPO params, Collection<SFunction<PmsUser, ?>> columns) {
var result = super.pageKeywords(params, columns);
setRoleAndDept(result.getRecords());
public IPage<PmsUser> pageKeywords(UserQueryPO params) {
var wrapper = super.getKeywordsQueryWrapper(params, List.of(PmsUser::getUsername, PmsUser::getNickname));
if (params.getDeptId() != null && params.getDeptId() > 0L) {
wrapper.lambda().eq(PmsUser::getDeptId, params.getDeptId());
}
Page<PmsUser> pageRequest = Page.of(params.getPageIndex(), params.getPageSize());
Page<PmsUser> result = super.page(pageRequest, wrapper);
if (params.isIncludeCauu()) {
reflectionFill(result.getRecords());
}
// 包含 角色和用户信息
if (params.isIncludeRad()) {
setRoleAndDept(result.getRecords());
}
return result;
}
private void setRoleAndDept(Collection<PmsUser> list) {
if (!list.isEmpty()) {
var userIds = list.stream().map(PmsUser::getUserId).collect(Collectors.toSet());
@@ -100,7 +112,7 @@ public class PmsUserServiceImpl extends BaseServiceImpl<PmsUserMapper, PmsUser>
r.setPassword(null);
r.setRoles(roleMaps.get(r.getUserId()));
r.setDept(deptMaps.get(r.getDeptId()));
// 如果包含,那么就是在线。【 0.离线 1.在线
// 如果 LoginId 为空。表示未在线
var loginUser = loginUserMap.getOrDefault(r.getUserId(), new JwtLoginUser().setLoginId(StrUtil.EMPTY));
r.setLoginId(loginUser.getLoginId());
});

View File

@@ -41,9 +41,9 @@ public class SysUserServiceImpl implements SysUserService {
@Override
public Set<String> listHaveTenantIds(Long userId) {
return delegate(tenantManager.getDefaultTenantId(), () -> {
return baseMapper.selectHaveTenants(userId);
});
return delegate(tenantManager.getDefaultTenantId(),
() -> baseMapper.selectHaveTenants(userId)
);
}
@@ -78,13 +78,13 @@ public class SysUserServiceImpl implements SysUserService {
var collect = tenantIds.stream().filter(tenantManager::existById).collect(Collectors.toSet());
return delegate(tenantManager.getDefaultTenantId(), () -> {
var sysUser = pmsUserService.getByUserId(userId);
// 判断系统用户是否存在
// 判断 系统用户 是否存在
if (sysUser == null) {
throw new RuntimeException(StrUtil.format("只有系统用户 {} 不存在!", userId));
throw new RuntimeException(StrUtil.format("系统用户 {} 不存在!", userId));
}
// 删除 用户 之前关联的租户
// 删除 系统用户 之前关联的租户
baseMapper.deleteHaveTenants(userId);
// 根据用户名,获取 登录的用户信息
// 根据 用户名,获取登录的用户信息
var loginUser = jwtTokenService.getLoginUserByUsername(sysUser.getUsername());
if (loginUser != null) {
// 更新 系统用户 关联的租户ID
@@ -92,7 +92,7 @@ public class SysUserServiceImpl implements SysUserService {
jwtTokenService.updateLoginUser(loginUser);
}
if (!collect.isEmpty()) {
// 用户 关联 新的租户
// 系统用户 关联 新的租户
var r2 = baseMapper.insertByTenants(userId, collect);
return r2 > 0;
}

View File

@@ -31,10 +31,6 @@ public class UpdateUserTenantVO {
@NotNull(message = "用户ID不能为空!")
private Long userId;
@Schema(description = "租户Id最少选择一个")
@NotNull(message = "租户Id必须填写")
private Set<String> tenantIds;
}

View File

@@ -280,6 +280,7 @@ public class JwtTokenServiceImpl implements JwtTokenService {
return result;
}
return objects.stream()
.filter(Objects::nonNull)
.map(a -> BeanUtil.copyProperties(a, JwtLoginUser.class))
.collect(Collectors.toMap(JwtLoginUser::getUserId, a -> a));
}

View File

@@ -82,7 +82,7 @@ public class OperateLogAspect {
timeCost = System.currentTimeMillis() - startTime;
} catch (Throwable ew) {
ex = ew;
log.error(ew.getMessage());
log.error(ew.getCause().getClass().getName(), ew.getMessage());
result = JsonResult.fail(ew.getMessage());
} finally {
//方法执行完成后增加日志

View File

@@ -49,10 +49,27 @@ div:focus {
// 业务页面几乎都应该在根元素上挂载 class="app-container",以保持页面美观
.app-container {
padding-top: 1rem;
padding: 10px;
}
// 业务页面几乎都应该在根元素上挂载 class="app-container1",以保持页面美观
.app-container1 {
padding: 1rem;
.search-wrapper {
margin-bottom: 10px;
:deep(.el-card__body) {
padding-bottom: 2px;
}
}
.toolbar-wrapper {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
}
.table-wrapper {
margin-bottom: 20px;
}
.pager-wrapper {
display: flex;
justify-content: flex-end;
}

View File

@@ -1,7 +1,7 @@
/** 全局 CSS 变量,这种变量不仅可以在 CSS 和 SCSS 中使用,还可以导入到 JS 中使用 */
:root {
/** 全局背景色 */
--v3-body-bg-color: #ffffff;
--v3-body-bg-color: #f2f3f5;
/** Header 区域 = NavigationBar 组件 + TagsView 组件 */
--v3-header-height: calc(var(--v3-navigationbar-height) + var(--v3-tagsview-height));
--v3-header-bg-color: #ffffff;

View File

@@ -1,5 +1,5 @@
<template>
<div class="app-container1">
<div class="app-container">
<el-row :gutter="10" class="chart">
<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
<v-chart autoresize :option="option1" />

View File

@@ -1,88 +1,83 @@
<template>
<el-container class="app-container" v-loading="loading">
<el-header>
<el-row :gutter="20">
<el-col :span="8">
<el-input v-model="params.keywords" clearable placeholder="根据设备名称搜索" />
</el-col>
<el-col :span="2">
<div class="app-container" v-loading="loading">
<el-card v-loading="loading" shadow="never" class="search-wrapper">
<el-form ref="searchFormRef" :inline="true" :model="params">
<el-form-item>
<el-input v-model="params.keywords" clearable placeholder="根据 设备名称 搜索" />
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="searchTableData">搜索</el-button>
</el-col>
<el-col :span="2">
</el-form-item>
<el-form-item>
<el-button type="success" :icon="Plus" @click="handleAdd()">新增</el-button>
</el-col>
<el-col :span="10">
<div class="grid-content ep-bg-purple" />
</el-col>
</el-row>
</el-header>
<el-main>
<el-table :data="tableData">
<el-table-column prop="deviceId" label="设备ID" />
<el-table-column prop="deviceName" label="设备名称" />
<el-table-column prop="status" label="状态">
<template #default="scope">
{{ dictStore.getNormalDisable(scope.row.status) }}
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<el-tooltip v-if="scope.row.lastUpdateTime" :content="scope.row.lastUpdateTime" placement="top">
<el-link> {{ showTimeAgo(scope.row.lastUpdateTime) }}</el-link>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="操作" width="130">
<template #default="scope">
<el-link :icon="Edit" type="warning" @click="handleEdit(scope.row)">编辑</el-link>
&nbsp;
<el-link :icon="Delete" type="danger" @click="handleDelete(scope.row)">删除</el-link>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
</el-card>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="30%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="deviceName" label="设备名称">
<el-input v-model.trim="entityForm.deviceName" placeholder="设备名称" type="text" tabindex="1" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="status" label="设备状态">
<select-dict-data v-model:value="entityForm.status" dictTypeKey="sys_normal_disable" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
</el-main>
<el-footer>
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-footer>
</el-container>
<el-card v-loading="loading" shadow="never">
<div class="toolbar-wrapper">
<el-table :data="tableData">
<el-table-column prop="deviceId" label="设备ID" />
<el-table-column prop="deviceName" label="设备名称" />
<el-table-column prop="status" label="状态">
<template #default="scope">
{{ dictStore.getNormalDisable(scope.row.status) }}
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<el-tooltip v-if="scope.row.lastUpdateTime" :content="scope.row.lastUpdateTime" placement="top">
<el-link> {{ showTimeAgo(scope.row.lastUpdateTime) }}</el-link>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="操作" width="130">
<template #default="scope">
<el-link :icon="Edit" type="warning" @click="handleEdit(scope.row)">编辑</el-link>
&nbsp;
<el-link :icon="Delete" type="danger" @click="handleDelete(scope.row)">删除</el-link>
</template>
</el-table-column>
</el-table>
</div>
<div class="pager-wrapper">
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="30%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
>
<el-form-item prop="deviceName" label="设备名称">
<el-input v-model.trim="entityForm.deviceName" placeholder="设备名称" type="text" tabindex="1" />
</el-form-item>
<el-form-item prop="status" label="设备状态">
<select-dict-data v-model:value="entityForm.status" dictTypeKey="sys_normal_disable" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">

View File

@@ -1,70 +1,73 @@
<template>
<el-container class="app-container" v-loading="loading" v-has="['pre_role:view']">
<el-header>
<el-row :gutter="20">
<el-col :span="8">
<el-input v-model="params.keywords" clearable placeholder="根据关键字搜索" />
</el-col>
<el-col :span="2">
<div class="app-container" v-loading="loading">
<el-card v-loading="loading" shadow="never" class="search-wrapper">
<el-form ref="searchFormRef" :inline="true" :model="params">
<el-form-item>
<el-input v-model="params.keywords" clearable placeholder="根据 昵称、用户名 搜索" />
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="searchTableData">搜索</el-button>
</el-col>
<el-col :span="2">
</el-form-item>
<el-form-item>
<el-button type="danger" :icon="Delete" @click="handleBatchDelete">批量删除</el-button>
</el-col>
<el-col :span="10"><div class="grid-content ep-bg-purple" /></el-col>
</el-row>
</el-header>
<el-main>
<el-table :data="tableData" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column prop="id" label="ID" />
<el-table-column prop="grantType" label="登录类型" />
<el-table-column prop="nickname" label="昵称" />
<el-table-column prop="username" label="用户名">
<template #default="scope">
<el-tooltip effect="dark" :content="`用户ID: ${scope.row.userId}`" placement="top">
<el-link> {{ scope.row.username }}</el-link>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="avatar" label="头像">
<template #default="scope">
<el-avatar :size="40" :icon="UserFilled" :src="scope.row.avatar" />
</template>
</el-table-column>
<el-table-column prop="requestUrl" label="请求地址" />
<el-table-column prop="requestIp" label="请求IP" />
<el-table-column prop="address" label="请求地址" />
<el-table-column prop="osName" label="操作系统" />
<el-table-column prop="browser" label="浏览器" />
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<el-tooltip v-if="scope.row.createTime" :content="scope.row.createTime" placement="top">
<el-link> {{ showTimeAgo(scope.row.createTime) }}</el-link>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="操作" width="80">
<template #default="scope">
<el-link :icon="Delete" type="danger" v-has="['pre_role:delete']" @click="handleDelete(scope.row)"
>删除</el-link
>
</template>
</el-table-column>
</el-table>
</el-main>
<el-footer>
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-footer>
</el-container>
</el-form-item>
</el-form>
</el-card>
<el-card v-loading="loading" shadow="never">
<div class="toolbar-wrapper">
<el-table :data="tableData" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column prop="id" label="ID" />
<el-table-column prop="grantType" label="登录类型" />
<el-table-column prop="nickname" label="昵称" />
<el-table-column prop="username" label="用户名">
<template #default="scope">
<el-tooltip effect="dark" :content="`用户ID: ${scope.row.userId}`" placement="top">
<el-link> {{ scope.row.username }}</el-link>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="avatar" label="头像">
<template #default="scope">
<el-avatar :size="40" :icon="UserFilled" :src="scope.row.avatar" />
</template>
</el-table-column>
<el-table-column prop="requestUrl" label="请求地址" />
<el-table-column prop="requestIp" label="请求IP" />
<el-table-column prop="address" label="请求地址" />
<el-table-column prop="osName" label="操作系统" />
<el-table-column prop="browser" label="浏览器" />
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<el-tooltip v-if="scope.row.createTime" :content="scope.row.createTime" placement="top">
<el-link> {{ showTimeAgo(scope.row.createTime) }}</el-link>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="操作" width="80">
<template #default="scope">
<el-link :icon="Delete" type="danger" v-has="['pre_role:delete']" @click="handleDelete(scope.row)"
>删除</el-link
>
</template>
</el-table-column>
</el-table>
</div>
<div class="pager-wrapper">
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
</div>
</template>
<script setup lang="ts">

View File

@@ -1,110 +1,111 @@
<template>
<el-container class="app-container" v-loading="loading" v-has="['pre_role:view']">
<el-header>
<el-row :gutter="20">
<el-col :span="8">
<el-input v-model="params.keywords" clearable placeholder="根据关键字搜索" />
</el-col>
<el-col :span="2">
<div class="app-container" v-loading="loading">
<el-card v-loading="loading" shadow="never" class="search-wrapper">
<el-form ref="searchFormRef" :inline="true" :model="params">
<el-form-item>
<el-input v-model="params.keywords" clearable placeholder="根据 昵称、用户名 搜索" />
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="searchTableData">搜索</el-button>
</el-col>
<el-col :span="2">
</el-form-item>
<el-form-item>
<el-button type="danger" :icon="Delete" @click="handleBatchDelete">批量删除</el-button>
</el-col>
<el-col :span="10">
<div class="grid-content ep-bg-purple" />
</el-col>
</el-row>
</el-header>
<el-main>
<el-table :data="tableData" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column prop="id" label="ID" />
<el-table-column prop="title" label="标题" />
<el-table-column prop="description" label="描述" />
<el-table-column prop="serviceName" label="服务名称" />
<el-table-column prop="requestMethod" label="请求类型" />
<el-table-column prop="username" label="用户名">
<template #default="scope">
<el-tooltip effect="dark" :content="`用户ID: ${scope.row.userId}`" placement="top">
<el-link> {{ scope.row.username }}</el-link>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="avatar" label="头像">
<template #default="scope">
<el-avatar :size="40" :icon="UserFilled" :src="scope.row.avatar" />
</template>
</el-table-column>
<el-table-column prop="requestUrl" label="请求地址" />
<el-table-column prop="requestIp" label="请求IP" />
<el-table-column prop="address" label="请求地址" />
<el-table-column prop="status" label="状态" />
<el-table-column prop="timeCost" label="耗时(毫秒)" />
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<el-tooltip v-if="scope.row.createTime" :content="scope.row.createTime" placement="top">
<el-link> {{ showTimeAgo(scope.row.createTime) }}</el-link>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="操作" width="120">
<template #default="scope">
<el-link :icon="View" type="primary" v-has="['pre_role:delete']" @click="handleInfo(scope.row)"
>详情</el-link
>
&nbsp;
<el-link :icon="Delete" type="danger" v-has="['pre_role:delete']" @click="handleDelete(scope.row)"
>删除</el-link
>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
</el-card>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="50%">
<el-form
ref="entityFormRef"
:model="entityForm"
label-position="right"
label-width="50px"
@keyup.enter="dialogVisible = false"
>
<el-form-item label="描述">
{{ entityForm.description }}
</el-form-item>
<el-form-item label="地址">
{{ entityForm.requestUrl }}
</el-form-item>
<el-form-item label="类型">
{{ entityForm.requestMethod }}
</el-form-item>
<el-form-item label="参数">
<el-input v-model="entityForm.methodArgs" rows="5" type="textarea" />
</el-form-item>
<el-form-item label="结果">
<el-input v-model="entityForm.responseResult" rows="10" type="textarea" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="dialogVisible = false">确定</el-button>
</span>
</template>
</el-dialog>
</el-main>
<el-footer>
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-footer>
</el-container>
<el-card v-loading="loading" shadow="never">
<div class="toolbar-wrapper">
<el-table :data="tableData" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column prop="id" label="ID" />
<el-table-column prop="title" label="标题" />
<el-table-column prop="description" label="描述" />
<el-table-column prop="serviceName" label="服务名称" />
<el-table-column prop="requestMethod" label="请求类型" />
<el-table-column prop="username" label="用户名">
<template #default="scope">
<el-tooltip effect="dark" :content="`用户ID: ${scope.row.userId}`" placement="top">
<el-link> {{ scope.row.username }}</el-link>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="avatar" label="头像">
<template #default="scope">
<el-avatar :size="40" :icon="UserFilled" :src="scope.row.avatar" />
</template>
</el-table-column>
<el-table-column prop="requestUrl" label="请求地址" />
<el-table-column prop="requestIp" label="请求IP" />
<el-table-column prop="address" label="请求地址" />
<el-table-column prop="status" label="状态" />
<el-table-column prop="timeCost" label="耗时(毫秒)" />
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<el-tooltip v-if="scope.row.createTime" :content="scope.row.createTime" placement="top">
<el-link> {{ showTimeAgo(scope.row.createTime) }}</el-link>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="操作" width="120">
<template #default="scope">
<el-link :icon="View" type="primary" v-has="['pre_role:delete']" @click="handleInfo(scope.row)"
>详情</el-link
>
&nbsp;
<el-link :icon="Delete" type="danger" v-has="['pre_role:delete']" @click="handleDelete(scope.row)"
>删除</el-link
>
</template>
</el-table-column>
</el-table>
</div>
<div class="pager-wrapper">
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="50%">
<el-form
ref="entityFormRef"
:model="entityForm"
label-position="right"
label-width="50px"
@keyup.enter="dialogVisible = false"
>
<el-form-item label="描述">
{{ entityForm.description }}
</el-form-item>
<el-form-item label="地址">
{{ entityForm.requestUrl }}
</el-form-item>
<el-form-item label="类型">
{{ entityForm.requestMethod }}
</el-form-item>
<el-form-item label="参数">
<el-input v-model="entityForm.methodArgs" rows="5" type="textarea" />
</el-form-item>
<el-form-item label="结果">
<el-input v-model="entityForm.responseResult" rows="10" type="textarea" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="dialogVisible = false">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">

View File

@@ -397,8 +397,8 @@ onMounted(() => {
<style lang="scss" scoped>
.card-box {
padding-right: 15px;
padding-left: 15px;
padding-right: 5px;
padding-left: 5px;
margin-bottom: 10px;
}
</style>

View File

@@ -1,6 +1,6 @@
<template>
<div class="app-container1">
<el-row :gutter="20">
<div class="app-container">
<el-row :gutter="10">
<el-col :span="6">
<el-card class="box-card">
<template #header>

View File

@@ -1,145 +1,146 @@
<template>
<el-container class="app-container" v-loading="loading" v-has="['pre_dept:view']">
<el-header height="30px">
<div class="app-container" v-loading="loading" v-has="['pre_dept:view']">
<el-card v-loading="loading" shadow="never" class="search-wrapper">
<div class="flex">
<el-button type="primary" :icon="Plus" v-has="['pre_dept:create']" @click="handleAdd(null)">新增</el-button>
<el-button type="success" :icon="Sort" @click="switchExpandAndCollapse">{{
expandAndCollapse ? "折叠" : "展开"
}}</el-button>
</div>
</el-header>
<el-main>
<el-table ref="tableRef" :data="tableData" row-key="id" :default-expand-all="expandAndCollapse">
<el-table-column prop="deptId" label="部门ID" />
<el-table-column prop="deptName" label="部门名称" />
<el-table-column prop="leader" label="领导名称" />
<el-table-column prop="leaderMobile" label="领导联系方式" />
<el-table-column prop="description" label="描述">
<template #default="scope">
<el-popover
placement="top-start"
:width="300"
trigger="hover"
v-if="scope.row.description"
:content="scope.row.description"
>
<template #reference>
<el-link> {{ showStringOverflow(scope.row.description) }}</el-link>
</template>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="sort" label="排序" width="80" />
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="scope">
<el-link :icon="Plus" type="primary" v-has="['pre_dept:create']" @click="handleAdd(scope.row)"
>新增</el-link
>
&nbsp;
<el-link :icon="Edit" type="warning" v-has="['pre_dept:update']" @click="handleEdit(scope.row)"
>编辑</el-link
>
&nbsp;
<el-link
:icon="Delete"
v-if="!scope.row.children"
type="danger"
v-has="['pre_dept:delete']"
@click="handleDelete(scope.row)"
>删除</el-link
>
</template>
</el-table-column>
</el-table>
</el-card>
<el-card v-loading="loading" shadow="never">
<div class="toolbar-wrapper">
<el-table ref="tableRef" :data="tableData" row-key="id" :default-expand-all="expandAndCollapse">
<el-table-column prop="deptId" label="部门ID" />
<el-table-column prop="deptName" label="部门名称" />
<el-table-column prop="leader" label="领导名称" />
<el-table-column prop="leaderMobile" label="领导联系方式" />
<el-table-column prop="description" label="描述">
<template #default="scope">
<el-popover
placement="top-start"
:width="300"
trigger="hover"
v-if="scope.row.description"
:content="scope.row.description"
>
<template #reference>
<el-link> {{ showStringOverflow(scope.row.description) }}</el-link>
</template>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="sort" label="排序" width="80" />
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="scope">
<el-link :icon="Plus" type="primary" v-has="['pre_dept:create']" @click="handleAdd(scope.row)"
>新增</el-link
>
&nbsp;
<el-link :icon="Edit" type="warning" v-has="['pre_dept:update']" @click="handleEdit(scope.row)"
>编辑</el-link
>
&nbsp;
<el-link
:icon="Delete"
v-if="!scope.row.children"
type="danger"
v-has="['pre_dept:delete']"
@click="handleDelete(scope.row)"
>删除</el-link
>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="50%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
@keyup.enter="handleSaveAndFlush"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="deptName" label="部门名称">
<el-input v-model.trim="entityForm.deptName" placeholder="名称" type="text" tabindex="1" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="parentId" label="上级部门">
<el-cascader
v-model="entityForm.parentId"
:options="parentMenus"
:props="{ checkStrictly: true }"
@change="cascaderChange"
filterable
tabindex="2"
/>
</el-form-item>
</el-col>
</el-row>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="50%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
@keyup.enter="handleSaveAndFlush"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="deptName" label="部门名称">
<el-input v-model.trim="entityForm.deptName" placeholder="名称" type="text" tabindex="1" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="parentId" label="上级部门">
<el-cascader
v-model="entityForm.parentId"
:options="parentMenus"
:props="{ checkStrictly: true }"
@change="cascaderChange"
filterable
tabindex="2"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="leader" label="领导名称">
<el-input v-model.trim="entityForm.leader" placeholder="领导名称" type="text" tabindex="3" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="leaderMobile" label="联系方式">
<el-input
v-model.trim="entityForm.leaderMobile"
placeholder="领导联系方式"
type="text"
maxlength="11"
show-word-limit
tabindex="4"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="leader" label="领导名称">
<el-input v-model.trim="entityForm.leader" placeholder="领导名称" type="text" tabindex="3" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="leaderMobile" label="联系方式">
<el-input
v-model.trim="entityForm.leaderMobile"
placeholder="领导联系方式"
type="text"
maxlength="11"
show-word-limit
tabindex="4"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="sort" label="部门排序">
<el-input-number v-model="entityForm.sort" :min="1" :max="9999999" tabindex="5" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="description" label="描述">
<el-input
v-model.trim="entityForm.description"
placeholder="描述"
:rows="3"
type="textarea"
tabindex="6"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
</el-main>
</el-container>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="sort" label="部门排序">
<el-input-number v-model="entityForm.sort" :min="1" :max="9999999" tabindex="5" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="description" label="描述">
<el-input
v-model.trim="entityForm.description"
placeholder="描述"
:rows="3"
type="textarea"
tabindex="6"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">

View File

@@ -1,195 +1,198 @@
<template>
<el-container class="app-container" v-loading="loading" v-has="['pre_menu:view']">
<el-header height="30px">
<div class="app-container" v-loading="loading" v-has="['pre_menu:view']">
<el-card v-loading="loading" shadow="never" class="search-wrapper">
<div class="flex">
<el-button type="primary" :icon="Plus" v-has="['pre_menu:create']" @click="handleAdd(null)">新增</el-button>
<el-button type="success" :icon="Sort" @click="switchExpandAndCollapse">{{
expandAndCollapse ? "折叠" : "展开"
}}</el-button>
</div>
</el-header>
<el-main>
<el-table ref="tableRef" :data="tableData" row-key="id" :default-expand-all="expandAndCollapse">
<el-table-column prop="menuId" label="权限ID" />
<el-table-column prop="menuName" label="权限名称" />
<el-table-column prop="perms" label="权限标识" />
<el-table-column prop="component" label="权限组件" />
<el-table-column prop="path" label="路由地址" />
<el-table-column prop="icon" label="权限图标">
<template #default="scope">
<svg-icon v-if="scope.row.icon" :name="scope.row.icon" :size="28" />
</template>
</el-table-column>
<el-table-column prop="sort" label="排序" width="80" />
<el-table-column prop="target" label="所属用户">
<template #default="scope">
<el-tag v-if="scope.row.target === 0" effect="dark">
{{ dictStore.getMenuTarget(scope.row.target) }}
</el-tag>
<el-tag v-else-if="scope.row.target === 1" effect="light" type="info">
{{ dictStore.getMenuTarget(scope.row.target) }}
</el-tag>
<el-tag v-else effect="plain" type="danger">
{{ dictStore.getMenuTarget(scope.row.target) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="menuType" label="权限类型">
<template #default="scope">
<el-tag v-if="scope.row.menuType === 0" effect="plain" type="info">
{{ dictStore.getMenuType(scope.row.menuType) }}
</el-tag>
<el-tag v-else effect="light" type="danger">
{{ dictStore.getMenuType(scope.row.menuType) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="visible" label="状态">
<template #default="scope">
{{ dictStore.getShowHide(scope.row.visible) }}
</template>
</el-table-column>
<el-table-column prop="keepAlive" label="保存状态">
<template #default="scope">
{{ dictStore.getYesNo(scope.row.keepAlive) }}
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="scope">
<el-link
:icon="Plus"
v-if="scope.row.menuType === 0"
v-has="['pre_menu:create']"
type="primary"
@click="handleAdd(scope.row)"
>新增</el-link
>
&nbsp;
<el-link :icon="Edit" type="warning" v-has="['pre_menu:update']" @click="handleEdit(scope.row)"
>编辑</el-link
>
&nbsp;
<el-link
:icon="Delete"
v-if="!scope.row.children"
type="danger"
v-has="['pre_menu:delete']"
@click="handleDelete(scope.row)"
>删除</el-link
>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="50%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
@keyup.enter="handleSaveAndFlush"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="menuName" label="权限名称">
<el-input v-model.trim="entityForm.menuName" placeholder="名称" type="text" tabindex="1" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="perms" label="权限标识">
<el-input v-model.trim="entityForm.perms" placeholder="标识" type="text" tabindex="2" />
</el-form-item>
</el-col>
</el-row>
<el-card v-loading="loading" shadow="never">
<div class="toolbar-wrapper">
<el-table ref="tableRef" :data="tableData" row-key="id" :default-expand-all="expandAndCollapse">
<el-table-column prop="menuId" label="权限ID" />
<el-table-column prop="menuName" label="权限名称" />
<el-table-column prop="perms" label="权限标识" />
<el-table-column prop="component" label="权限组件" />
<el-table-column prop="path" label="路由地址" />
<el-table-column prop="icon" label="权限图标">
<template #default="scope">
<svg-icon v-if="scope.row.icon" :name="scope.row.icon" :size="28" />
</template>
</el-table-column>
<el-table-column prop="sort" label="排序" width="80" />
<el-table-column prop="target" label="所属用户">
<template #default="scope">
<el-tag v-if="scope.row.target === 0" effect="dark">
{{ dictStore.getMenuTarget(scope.row.target) }}
</el-tag>
<el-tag v-else-if="scope.row.target === 1" effect="light" type="info">
{{ dictStore.getMenuTarget(scope.row.target) }}
</el-tag>
<el-tag v-else effect="plain" type="danger">
{{ dictStore.getMenuTarget(scope.row.target) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="menuType" label="权限类型">
<template #default="scope">
<el-tag v-if="scope.row.menuType === 0" effect="plain" type="info">
{{ dictStore.getMenuType(scope.row.menuType) }}
</el-tag>
<el-tag v-else effect="light" type="danger">
{{ dictStore.getMenuType(scope.row.menuType) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="visible" label="状态">
<template #default="scope">
{{ dictStore.getShowHide(scope.row.visible) }}
</template>
</el-table-column>
<el-table-column prop="keepAlive" label="保存状态">
<template #default="scope">
{{ dictStore.getYesNo(scope.row.keepAlive) }}
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="scope">
<el-link
:icon="Plus"
v-if="scope.row.menuType === 0"
v-has="['pre_menu:create']"
type="primary"
@click="handleAdd(scope.row)"
>新增</el-link
>
&nbsp;
<el-link :icon="Edit" type="warning" v-has="['pre_menu:update']" @click="handleEdit(scope.row)"
>编辑</el-link
>
&nbsp;
<el-link
:icon="Delete"
v-if="!scope.row.children"
type="danger"
v-has="['pre_menu:delete']"
@click="handleDelete(scope.row)"
>删除</el-link
>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="sort" label="权限排序">
<el-input-number v-model="entityForm.sort" :min="1" :max="9999999" tabindex="6" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="menuType" label="权限类型">
<select-dict-data v-model:value="entityForm.menuType" dictTypeKey="sys_menu_type" />
</el-form-item>
</el-col>
</el-row>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="50%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
@keyup.enter="handleSaveAndFlush"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="menuName" label="权限名称">
<el-input v-model.trim="entityForm.menuName" placeholder="名称" type="text" tabindex="1" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="perms" label="权限标识">
<el-input v-model.trim="entityForm.perms" placeholder="标识" type="text" tabindex="2" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" v-if="entityForm.menuType == 0">
<el-col :span="12">
<el-form-item prop="component" label="权限组件">
<el-input v-model.trim="entityForm.component" placeholder="组件" type="text" tabindex="3" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="icon" label="图标">
<svg-icon-select v-model:value="entityForm.icon" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="sort" label="权限排序">
<el-input-number v-model="entityForm.sort" :min="1" :max="9999999" tabindex="6" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="menuType" label="权限类型">
<select-dict-data v-model:value="entityForm.menuType" dictTypeKey="sys_menu_type" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" v-if="entityForm.menuType == 0">
<el-col :span="12">
<el-form-item prop="visible" label="显示隐藏">
<select-dict-data v-model:value="entityForm.visible" dictTypeKey="sys_show_hide" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="path" label="地址" v-if="entityForm.menuType == 0">
<el-input v-model.trim="entityForm.path" placeholder="路由" type="text" tabindex="5" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" v-if="entityForm.menuType == 0">
<el-col :span="12">
<el-form-item prop="component" label="权限组件">
<el-input v-model.trim="entityForm.component" placeholder="组件" type="text" tabindex="3" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="icon" label="图标">
<svg-icon-select v-model:value="entityForm.icon" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="target" label="权限所属">
<select-dict-data v-model:value="entityForm.target" dictTypeKey="sys_menu_target" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="parentId" label="上级权限">
<el-cascader
v-model="entityForm.parentId"
:options="parentMenus"
:props="{ checkStrictly: true }"
@change="cascaderChange"
filterable
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" v-if="entityForm.menuType == 0">
<el-col :span="12">
<el-form-item prop="visible" label="显示隐藏">
<select-dict-data v-model:value="entityForm.visible" dictTypeKey="sys_show_hide" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="path" label="地址" v-if="entityForm.menuType == 0">
<el-input v-model.trim="entityForm.path" placeholder="路由" type="text" tabindex="5" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="keepAlive" label="保持状态">
<select-dict-data v-model:value="entityForm.keepAlive" dictTypeKey="sys_yes_no" />
</el-form-item>
</el-col>
<el-col :span="12"> &nbsp; </el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
</el-main>
</el-container>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="target" label="权限所属">
<select-dict-data v-model:value="entityForm.target" dictTypeKey="sys_menu_target" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="parentId" label="上级权限">
<el-cascader
v-model="entityForm.parentId"
:options="parentMenus"
:props="{ checkStrictly: true }"
@change="cascaderChange"
filterable
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="keepAlive" label="保持状态">
<select-dict-data v-model:value="entityForm.keepAlive" dictTypeKey="sys_yes_no" />
</el-form-item>
</el-col>
<el-col :span="12"> &nbsp; </el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">

View File

@@ -1,164 +1,163 @@
<template>
<el-container class="app-container" v-loading="loading" v-has="['pre_role:view']">
<el-header>
<el-row :gutter="20">
<el-col :span="8">
<el-input v-model="params.keywords" clearable placeholder="根据关键字搜索" />
</el-col>
<el-col :span="2">
<div class="app-container" v-loading="loading" v-has="['pre_role:view']">
<el-card v-loading="loading" shadow="never" class="search-wrapper">
<el-form ref="searchFormRef" :inline="true" :model="params">
<el-form-item>
<el-input v-model="params.keywords" clearable placeholder="根据 角色名称 搜索" />
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="searchTableData">搜索</el-button>
</el-col>
<el-col :span="2">
</el-form-item>
<el-form-item>
<el-button type="success" :icon="Plus" v-has="['pre_role:create']" @click="handleAdd()">新增</el-button>
</el-col>
<el-col :span="10">
<div class="grid-content ep-bg-purple" />
</el-col>
</el-row>
</el-header>
<el-main>
<el-table :data="tableData">
<el-table-column prop="roleId" label="角色ID" />
<el-table-column prop="roleName" label="名称" />
<el-table-column prop="sort" label="排序" sortable />
<el-table-column prop="description" label="描述">
<template #default="scope">
<el-popover
placement="top-start"
:width="300"
trigger="hover"
v-if="scope.row.description"
:content="scope.row.description"
>
<template #reference>
<el-link> {{ showStringOverflow(scope.row.description) }}</el-link>
</template>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="scope">
<el-link
:icon="EditPen"
type="info"
v-has="['pre_role:update:permissions']"
@click="handleEditMenu(scope.row)"
>权限</el-link
>
&nbsp;
<el-link :icon="Edit" type="warning" v-has="['pre_role:update']" @click="handleEdit(scope.row)"
>编辑</el-link
>
&nbsp;
<el-link :icon="Delete" type="danger" v-has="['pre_role:delete']" @click="handleDelete(scope.row)"
>删除</el-link
>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
</el-card>
<el-card v-loading="loading" shadow="never">
<div class="toolbar-wrapper">
<el-table :data="tableData">
<el-table-column prop="roleId" label="角色ID" />
<el-table-column prop="roleName" label="名称" />
<el-table-column prop="description" label="描述">
<template #default="scope">
<el-popover
placement="top-start"
:width="300"
trigger="hover"
v-if="scope.row.description"
:content="scope.row.description"
>
<template #reference>
<el-link> {{ showStringOverflow(scope.row.description) }}</el-link>
</template>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="sort" label="排序" sortable />
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="scope">
<el-link
:icon="EditPen"
type="info"
v-has="['pre_role:update:permissions']"
@click="handleEditMenu(scope.row)"
>权限</el-link
>
&nbsp;
<el-link :icon="Edit" type="warning" v-has="['pre_role:update']" @click="handleEdit(scope.row)"
>编辑</el-link
>
&nbsp;
<el-link :icon="Delete" type="danger" v-has="['pre_role:delete']" @click="handleDelete(scope.row)"
>删除</el-link
>
</template>
</el-table-column>
</el-table>
</div>
<div class="pager-wrapper">
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="30%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
@keyup.enter="handleSaveAndFlush"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="roleName" label="名称">
<el-input v-model.trim="entityForm.roleName" placeholder="名称" type="text" tabindex="1" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="sort" label="排序">
<el-input-number v-model="entityForm.sort" :min="1" :max="9999999" tabindex="2" />
</el-form-item>
</el-col>
</el-row>
<el-form-item prop="description" label="描述">
<el-input
v-model="entityForm.description"
placeholder="描述"
:rows="3"
:maxlength="100"
type="textarea"
tabindex="3"
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
<!-- 修改权限 -->
<el-dialog v-model="menusDialogVisible" :title="menusDialogTitle" width="30%" :close-on-click-modal="false">
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="30%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
@keyup.enter="handleSaveAndFlush"
>
<el-row :gutter="20">
<el-col :span="14">
<el-input v-model="filterMenuText" clearable placeholder="根据菜单名称筛选" />
<el-col :span="12">
<el-form-item prop="roleName" label="名称">
<el-input v-model.trim="entityForm.roleName" placeholder="名称" type="text" tabindex="1" />
</el-form-item>
</el-col>
<el-col :span="5">
<el-button type="success" :icon="Sort" @click="switchExpandAndCollapse">{{
expandAndCollapse ? "折叠" : "展开"
}}</el-button>
</el-col>
<el-col :span="5">
<el-button type="success" :icon="checkAll ? 'CloseBold' : 'Select'" @click="switchCheckAll">{{
checkAll ? "取消" : "全选"
}}</el-button>
<el-col :span="12">
<el-form-item prop="sort" label="排序">
<el-input-number v-model="entityForm.sort" :min="1" :max="9999999" tabindex="2" />
</el-form-item>
</el-col>
</el-row>
<br />
<div :style="{ height: '400px', overflowY: 'scroll' }">
<el-tree
ref="treeRef"
:data="menusData?.all"
:check-strictly="true"
:default-expand-all="expandAndCollapse"
:filter-node-method="filterNode"
show-checkbox
node-key="id"
highlight-current
:props="{ children: 'children', label: 'name' }"
<el-form-item prop="description" label="描述">
<el-input
v-model="entityForm.description"
placeholder="描述"
:rows="3"
:maxlength="100"
type="textarea"
tabindex="3"
/>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="menusDialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleUpdateMenus">确定</el-button>
</span>
</template>
</el-dialog>
</el-main>
<el-footer>
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-footer>
</el-container>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
<!-- 修改权限 -->
<el-dialog v-model="menusDialogVisible" :title="menusDialogTitle" width="30%" :close-on-click-modal="false">
<el-row :gutter="20">
<el-col :span="14">
<el-input v-model="filterMenuText" clearable placeholder="根据菜单名称筛选" />
</el-col>
<el-col :span="5">
<el-button type="success" :icon="Sort" @click="switchExpandAndCollapse">{{
expandAndCollapse ? "折叠" : "展开"
}}</el-button>
</el-col>
<el-col :span="5">
<el-button type="success" :icon="checkAll ? 'CloseBold' : 'Select'" @click="switchCheckAll">{{
checkAll ? "取消" : "全选"
}}</el-button>
</el-col>
</el-row>
<br />
<div :style="{ height: '400px', overflowY: 'scroll' }">
<el-tree
ref="treeRef"
:data="menusData?.all"
:check-strictly="true"
:default-expand-all="expandAndCollapse"
:filter-node-method="filterNode"
show-checkbox
node-key="id"
highlight-current
:props="{ children: 'children', label: 'name' }"
/>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="menusDialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleUpdateMenus">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">

View File

@@ -1,294 +1,292 @@
<template>
<el-container class="app-container" v-loading="loading" v-has="['pre_user:view']">
<el-header>
<el-row :gutter="20">
<el-col :span="8">
<el-input v-model="params.keywords" clearable placeholder="根据关键字搜索" />
</el-col>
<el-col :span="2">
<div class="app-container" v-loading="loading" v-has="['pre_user:view']">
<el-card v-loading="loading" shadow="never" class="search-wrapper">
<el-form ref="searchFormRef" :inline="true" :model="params">
<el-form-item>
<el-input v-model="params.keywords" clearable placeholder="根据 用户名、昵称 搜索" />
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="searchTableData">搜索</el-button>
</el-col>
<el-col :span="2">
</el-form-item>
<el-form-item>
<el-button type="success" :icon="Plus" v-has="['pre_user:create']" @click="handleAdd()">新增</el-button>
</el-col>
<el-col :span="10">
<div class="grid-content ep-bg-purple" />
</el-col>
</el-row>
</el-header>
<el-main>
<el-table :data="tableData">
<el-table-column prop="userId" label="用户ID" />
<el-table-column prop="avatar" label="头像">
<template #default="scope">
<el-avatar :size="40" :icon="UserFilled" :src="scope.row.avatar" />
</template>
</el-table-column>
<el-table-column prop="nickname" label="昵称" />
<el-table-column prop="username" label="用户名" />
<el-table-column prop="mobile" label="手机号" />
<el-table-column prop="gender" label="性别">
<template #default="scope">
{{ dictStore.getUserSex(scope.row.gender) }}
</template>
</el-table-column>
<el-table-column prop="roles" label="角色" width="150">
<template #default="scope">
<el-tooltip
v-for="(item, index) in scope.row.roles"
:key="index"
effect="dark"
:content="item.description"
placement="top-start"
>
<el-tag>{{ showStringOverflow(item.roleName, 10) }}</el-tag>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="roles" label="部门" width="120">
<template #default="scope">
<el-popover placement="top-start" :width="230">
<template #reference>
<el-tag>{{ showStringOverflow(scope.row.dept.deptName, 10) }}</el-tag>
</template>
<div><strong>部门领导:</strong> &nbsp;&nbsp;&nbsp;{{ scope.row.dept.leader }}</div>
<div><strong>领导手机号:</strong> &nbsp;&nbsp;&nbsp;{{ scope.row.dept.leaderMobile }}</div>
<div><strong>部门描述:</strong> &nbsp;&nbsp;&nbsp;{{ scope.row.dept.description }}</div>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="adminFlag" label="管理员">
<template #default="scope">
<el-tag v-if="scope.row.adminFlag" type="success"></el-tag>
<span v-else></span>
</template>
</el-table-column>
<el-table-column prop="status" label="状态">
<template #default="scope">
<el-link v-if="scope.row.loginId" @click="showUserLoginLog(scope.row.loginId)" type="success">在线</el-link>
<span v-else>{{ dictStore.getNormalDisable(scope.row.status) }}</span>
</template>
</el-table-column>
<el-table-column prop="expired" label="过期时间">
<template #default="scope">
<el-tooltip v-if="scope.row.expired" :content="scope.row.expired" placement="top">
<el-link> {{ showExpiredDateAgo(scope.row.expired) }}</el-link>
</el-tooltip>
<span v-else>永久</span>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="130">
<template #default="scope">
<el-link :icon="Edit" type="warning" v-has="['pre_user:update']" @click="handleEdit(scope.row)"
>编辑</el-link
>
&nbsp;
<el-dropdown @command="(cmd: string) => handleCommand(cmd, scope.row)">
<span class="el-dropdown-link">
更多
<el-icon class="el-icon--right">
<arrow-down />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<div v-has="['pre_user:reset:password']">
<el-dropdown-item :icon="Link" command="ResetPassword">重置密码</el-dropdown-item>
</div>
<div v-if="isDefaultTenantId() && scope.row.adminFlag !== 1" v-has="['pre_user:link:tenant']">
<el-dropdown-item :icon="RefreshLeft" command="LinkTenant">关联租户</el-dropdown-item>
</div>
<div v-if="scope.row.adminFlag !== 1" v-has="['pre_user:delete']">
<el-dropdown-item :icon="Delete" command="Delete">删除</el-dropdown-item>
</div>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
</el-card>
<!-- 登录日志的弹窗 -->
<el-dialog v-model="userLoginLog.dialogVisible" width="50%">
<UserLoginLog :key="userLoginLog.loginId" :value="userLoginLog.loginId" />
</el-dialog>
<el-card v-loading="loading" shadow="never">
<div class="toolbar-wrapper">
<el-table :data="tableData">
<el-table-column prop="userId" label="用户ID" />
<el-table-column prop="avatar" label="头像">
<template #default="scope">
<el-avatar :size="40" :icon="UserFilled" :src="scope.row.avatar" />
</template>
</el-table-column>
<el-table-column prop="nickname" label="昵称" />
<el-table-column prop="username" label="用户名" />
<el-table-column prop="mobile" label="手机号" />
<el-table-column prop="gender" label="性别">
<template #default="scope">
{{ dictStore.getUserSex(scope.row.gender) }}
</template>
</el-table-column>
<el-table-column prop="roles" label="角色" width="150">
<template #default="scope">
<el-tooltip
v-for="(item, index) in scope.row.roles"
:key="index"
effect="dark"
:content="item.description"
placement="top-start"
>
<el-tag>{{ showStringOverflow(item.roleName, 10) }}</el-tag>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="roles" label="部门" width="120">
<template #default="scope">
<el-popover placement="top-start" :width="230">
<template #reference>
<el-tag>{{ showStringOverflow(scope.row.dept.deptName, 10) }}</el-tag>
</template>
<div><strong>部门领导:</strong> &nbsp;&nbsp;&nbsp;{{ scope.row.dept.leader }}</div>
<div><strong>领导手机号:</strong> &nbsp;&nbsp;&nbsp;{{ scope.row.dept.leaderMobile }}</div>
<div><strong>部门描述:</strong> &nbsp;&nbsp;&nbsp;{{ scope.row.dept.description }}</div>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="adminFlag" label="管理员">
<template #default="scope">
<el-tag v-if="scope.row.adminFlag" type="success"></el-tag>
<span v-else></span>
</template>
</el-table-column>
<el-table-column prop="status" label="状态">
<template #default="scope">
<el-link v-if="scope.row.loginId" @click="showUserLoginLog(scope.row.loginId)" type="success"
>在线</el-link
>
<span v-else>{{ dictStore.getNormalDisable(scope.row.status) }}</span>
</template>
</el-table-column>
<el-table-column prop="expired" label="过期时间">
<template #default="scope">
<el-tooltip v-if="scope.row.expired" :content="scope.row.expired" placement="top">
<el-link> {{ showExpiredDateAgo(scope.row.expired) }}</el-link>
</el-tooltip>
<span v-else>永久</span>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="130">
<template #default="scope">
<el-link :icon="Edit" type="warning" v-has="['pre_user:update']" @click="handleEdit(scope.row)"
>编辑</el-link
>
&nbsp;
<el-dropdown @command="(cmd: string) => handleCommand(cmd, scope.row)">
<span class="el-dropdown-link">
更多
<el-icon class="el-icon--right">
<arrow-down />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<div v-has="['pre_user:reset:password']">
<el-dropdown-item :icon="Link" command="ResetPassword">重置密码</el-dropdown-item>
</div>
<div v-if="isDefaultTenantId() && scope.row.adminFlag !== 1" v-has="['pre_user:link:tenant']">
<el-dropdown-item :icon="RefreshLeft" command="LinkTenant">关联租户</el-dropdown-item>
</div>
<div v-if="scope.row.adminFlag !== 1" v-has="['pre_user:delete']">
<el-dropdown-item :icon="Delete" command="Delete">删除</el-dropdown-item>
</div>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
</el-table-column>
</el-table>
</div>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="50%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
@keyup.enter="handleSaveAndFlush"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="avatar" label="头像">
<user-avatar :key="entityForm.avatar" :src="entityForm.avatar" @change="getAvatar" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="username" label="用户名">
<el-input
v-model.trim="entityForm.username"
placeholder="用户名"
type="text"
tabindex="1"
:disabled="!saveFlag"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="password" label="密码" v-if="saveFlag">
<el-input
v-model.trim="entityForm.password"
placeholder="密码"
type="password"
tabindex="2"
show-password
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="mobile" label="手机号">
<el-input
v-model.trim="entityForm.mobile"
placeholder="手机号"
type="text"
maxlength="11"
show-word-limit
tabindex="3"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="email" label="邮箱">
<el-input v-model.trim="entityForm.email" placeholder="邮箱" type="text" tabindex="4" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="nickname" label="昵称">
<el-input v-model.trim="entityForm.nickname" placeholder="昵称" type="text" tabindex="5" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="gender" label="性别">
<select-dict-data v-model:value="entityForm.gender" dictTypeKey="sys_user_sex" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="status" label="状态">
<select-dict-data v-model:value="entityForm.status" dictTypeKey="sys_normal_disable" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="deptId" label="部门">
<el-cascader
v-model="entityForm.deptId"
:options="deptTree"
:props="{ checkStrictly: true, value: 'deptId', label: 'deptName' }"
@change="deptCascaderChange"
filterable
tabindex="6"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="roles" label="角色">
<el-select v-model="entityRoles" filterable clearable multiple placeholder="选择角色">
<el-option v-for="item in roleList" :key="item.roleId" :label="item.roleName" :value="item.roleId">
<span style="float: left">{{ item.roleId }}</span>
<span style="float: right; font-size: 13px">{{ showStringOverflow(item.roleName) }}</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="expired" label="过期">
<el-date-picker
v-model="entityForm.expired"
type="datetime"
placeholder="请选择过期时间,不填即是永久"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
:shortcuts="futureShortcuts"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
<div class="pager-wrapper">
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
<!-- 新增和修改的弹窗 -->
<el-dialog
v-model="linkTenantForm.visible"
:title="linkTenantForm.title"
width="30%"
:close-on-click-modal="false"
<!-- 登录日志的弹窗 -->
<el-dialog v-model="userLoginLog.dialogVisible" width="50%">
<UserLoginLog :key="userLoginLog.loginId" :value="userLoginLog.loginId" />
</el-dialog>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="50%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
@keyup.enter="handleSaveAndFlush"
>
<el-select-v2
v-model="linkTenantForm.have"
:options="linkTenantForm.all"
placeholder="请选择租户"
style="width: 100%"
multiple
clearable
>
<template #default="{ item }">
<span style="margin-right: 8px">{{ item.value }}</span>
<span style="color: var(--el-text-color-secondary); font-size: 13px">
{{ item.label }}
</span>
</template>
</el-select-v2>
<template #footer>
<span class="dialog-footer">
<el-button @click="linkTenantForm.visible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveLinkTenant">确定</el-button>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="avatar" label="头像">
<user-avatar :key="entityForm.avatar" :src="entityForm.avatar" @change="getAvatar" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="username" label="用户名">
<el-input
v-model.trim="entityForm.username"
placeholder="用户名"
type="text"
tabindex="1"
:disabled="!saveFlag"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="password" label="密码" v-if="saveFlag">
<el-input
v-model.trim="entityForm.password"
placeholder="密码"
type="password"
tabindex="2"
show-password
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="mobile" label="手机号">
<el-input
v-model.trim="entityForm.mobile"
placeholder="手机号"
type="text"
maxlength="11"
show-word-limit
tabindex="3"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="email" label="邮箱">
<el-input v-model.trim="entityForm.email" placeholder="邮箱" type="text" tabindex="4" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="nickname" label="昵称">
<el-input v-model.trim="entityForm.nickname" placeholder="昵称" type="text" tabindex="5" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="gender" label="性别">
<select-dict-data v-model:value="entityForm.gender" dictTypeKey="sys_user_sex" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="status" label="状态">
<select-dict-data v-model:value="entityForm.status" dictTypeKey="sys_normal_disable" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="deptId" label="部门">
<el-cascader
v-model="entityForm.deptId"
:options="deptTree"
:props="{ checkStrictly: true, value: 'deptId', label: 'deptName' }"
@change="deptCascaderChange"
filterable
tabindex="6"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="roles" label="角色">
<el-select v-model="entityRoles" filterable clearable multiple placeholder="选择角色">
<el-option v-for="item in roleList" :key="item.roleId" :label="item.roleName" :value="item.roleId">
<span style="float: left">{{ item.roleId }}</span>
<span style="float: right; font-size: 13px">{{ showStringOverflow(item.roleName) }}</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="expired" label="过期">
<el-date-picker
v-model="entityForm.expired"
type="datetime"
placeholder="请选择过期时间,不填即是永久"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
:shortcuts="futureShortcuts"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="linkTenantForm.visible" :title="linkTenantForm.title" width="30%" :close-on-click-modal="false">
<el-select-v2
v-model="linkTenantForm.have"
:options="linkTenantForm.all"
placeholder="请选择租户"
style="width: 100%"
multiple
clearable
>
<template #default="{ item }">
<span style="margin-right: 8px">{{ item.value }}</span>
<span style="color: var(--el-text-color-secondary); font-size: 13px">
{{ item.label }}
</span>
</template>
</el-dialog>
</el-main>
<el-footer>
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-footer>
</el-container>
</el-select-v2>
<template #footer>
<span class="dialog-footer">
<el-button @click="linkTenantForm.visible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveLinkTenant">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
@@ -354,7 +352,8 @@ const params = reactive({
pageIndex: 1,
pageSize: 10,
keywords: "",
includeCauu: true
includeCauu: true,
includeRad: true
})
/// 表单数据

View File

@@ -1,202 +1,205 @@
<template>
<el-container class="app-container" v-loading="loading" v-has="['cms_project:view']">
<el-header>
<el-row :gutter="20">
<el-col :span="8">
<el-input v-model="params.keywords" clearable placeholder="根据项目名称搜索" />
</el-col>
<el-col :span="2">
<div class="app-container" v-loading="loading" v-has="['cms_project:view']">
<el-card v-loading="loading" shadow="never" class="search-wrapper">
<el-form ref="searchFormRef" :inline="true" :model="params">
<el-form-item>
<el-input v-model="params.keywords" clearable placeholder="根据 项目名称 搜索" />
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="searchTableData">搜索</el-button>
</el-col>
<el-col :span="2">
</el-form-item>
<el-form-item>
<el-button type="success" :icon="Plus" v-has="['cms_project:create']" @click="handleAdd()">新增</el-button>
</el-col>
<el-col :span="10"><div class="grid-content ep-bg-purple" /></el-col>
</el-row>
</el-header>
<el-main>
<el-table :data="tableData">
<el-table-column prop="projectId" label="项目ID" />
<el-table-column prop="projectName" label="项目名称" />
<el-table-column prop="linkman" label="联系人" />
<el-table-column prop="contactNumber" label="联系电话" />
<el-table-column prop="areaCode" label="行政区域">
<template #default="scope">
{{ showChinaArea(scope.row.areaCode) }}
</template>
</el-table-column>
<el-table-column prop="address" label="联系地址" />
<el-table-column prop="dept" label="部门" width="120">
<template #default="scope">
<el-popover v-if="scope.row.dept" placement="top-start" :width="230">
<template #reference>
<el-tag>{{ scope.row.dept.deptName }}</el-tag>
</template>
<div><strong>部门领导:</strong> &nbsp;&nbsp;&nbsp;{{ scope.row.dept.leader }}</div>
<div><strong>领导手机号:</strong> &nbsp;&nbsp;&nbsp;{{ scope.row.dept.leaderMobile }}</div>
<div><strong>部门描述:</strong> &nbsp;&nbsp;&nbsp;{{ scope.row.dept.description }}</div>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="status" label="状态">
<template #default="scope">
{{ dictStore.getNormalDisable(scope.row.status) }}
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="130">
<template #default="scope">
<el-link :icon="Edit" type="warning" v-has="['cms_project:update']" @click="handleEdit(scope.row)"
>编辑</el-link
>
<!-- v-admin 只有管理员才可以重置项目密码和删除项目 -->
&nbsp;
<el-dropdown v-admin @command="(cmd: string) => handleCommand(cmd, scope.row)">
<span class="el-dropdown-link">
更多
<el-icon class="el-icon--right">
<arrow-down />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<div v-has="['cms_project:reset:password']">
<el-dropdown-item :icon="Link" command="ResetPassword">重置密码</el-dropdown-item>
</div>
<div v-if="scope.row.projectId !== 10001" v-has="['cms_project:delete']">
<el-dropdown-item :icon="Delete" command="Delete">删除</el-dropdown-item>
</div>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
</el-card>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="50%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
@keyup.enter="handleSaveAndFlush"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="projectName" label="项目名称">
<el-input v-model.trim="entityForm.projectName" placeholder="项目名称" type="text" tabindex="1" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="saveFlag" prop="password" label="密码">
<el-input
v-model.trim="entityForm.password"
placeholder="项目密码"
type="password"
tabindex="2"
show-password
/>
</el-form-item>
<el-form-item v-else prop="projectId" label="项目ID">
<el-input
v-model.trim="entityForm.projectId"
placeholder="项目ID"
type="text"
tabindex="1"
:disabled="!saveFlag"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="联系人" label="联系人">
<el-input v-model.trim="entityForm.linkman" placeholder="联系人" type="text" tabindex="4" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="contactNumber" label="联系电话">
<el-input
v-model.trim="entityForm.contactNumber"
placeholder="联系电话"
type="text"
show-word-limit
tabindex="3"
/>
</el-form-item>
</el-col>
</el-row>
<el-card v-loading="loading" shadow="never">
<div class="toolbar-wrapper">
<el-table :data="tableData">
<el-table-column prop="projectId" label="项目ID" />
<el-table-column prop="projectName" label="项目名称" />
<el-table-column prop="linkman" label="联系人" />
<el-table-column prop="contactNumber" label="联系电话" />
<el-table-column prop="areaCode" label="行政区域">
<template #default="scope">
{{ showChinaArea(scope.row.areaCode) }}
</template>
</el-table-column>
<el-table-column prop="address" label="联系地址" />
<el-table-column prop="dept" label="部门" width="120">
<template #default="scope">
<el-popover v-if="scope.row.dept" placement="top-start" :width="230">
<template #reference>
<el-tag>{{ scope.row.dept.deptName }}</el-tag>
</template>
<div><strong>部门领导:</strong> &nbsp;&nbsp;&nbsp;{{ scope.row.dept.leader }}</div>
<div><strong>领导手机号:</strong> &nbsp;&nbsp;&nbsp;{{ scope.row.dept.leaderMobile }}</div>
<div><strong>部门描述:</strong> &nbsp;&nbsp;&nbsp;{{ scope.row.dept.description }}</div>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="status" label="状态">
<template #default="scope">
{{ dictStore.getNormalDisable(scope.row.status) }}
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="130">
<template #default="scope">
<el-link :icon="Edit" type="warning" v-has="['cms_project:update']" @click="handleEdit(scope.row)"
>编辑</el-link
>
<!-- v-admin 只有管理员才可以重置项目密码和删除项目 -->
&nbsp;
<el-dropdown v-admin @command="(cmd: string) => handleCommand(cmd, scope.row)">
<span class="el-dropdown-link">
更多
<el-icon class="el-icon--right">
<arrow-down />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<div v-has="['cms_project:reset:password']">
<el-dropdown-item :icon="Link" command="ResetPassword">重置密码</el-dropdown-item>
</div>
<div v-if="scope.row.projectId !== 10001" v-has="['cms_project:delete']">
<el-dropdown-item :icon="Delete" command="Delete">删除</el-dropdown-item>
</div>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
</el-table-column>
</el-table>
</div>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="status" label="状态">
<select-dict-data v-model:value="entityForm.status" dictTypeKey="sys_normal_disable" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="deptId" label="部门">
<el-cascader
v-model="entityForm.deptId"
:options="deptTree"
:props="{ checkStrictly: true, value: 'deptId', label: 'deptName' }"
@change="deptCascaderChange"
filterable
tabindex="6"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="areaCode" label="行政地址">
<search-china-area v-model="entityForm.areaCode" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="address" label="联系地址">
<el-input
v-model="entityForm.address"
:rows="3"
clearable
placeholder="联系地址"
type="textarea"
tabindex="6"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
</el-main>
<el-footer>
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-footer>
</el-container>
<div class="pager-wrapper">
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="50%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
@keyup.enter="handleSaveAndFlush"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="projectName" label="项目名称">
<el-input v-model.trim="entityForm.projectName" placeholder="项目名称" type="text" tabindex="1" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="saveFlag" prop="password" label="密码">
<el-input
v-model.trim="entityForm.password"
placeholder="项目密码"
type="password"
tabindex="2"
show-password
/>
</el-form-item>
<el-form-item v-else prop="projectId" label="项目ID">
<el-input
v-model.trim="entityForm.projectId"
placeholder="项目ID"
type="text"
tabindex="1"
:disabled="!saveFlag"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="linkman" label="联系人">
<el-input v-model.trim="entityForm.linkman" placeholder="联系人" type="text" tabindex="4" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="contactNumber" label="联系电话">
<el-input
v-model.trim="entityForm.contactNumber"
placeholder="联系电话"
type="text"
show-word-limit
tabindex="3"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="status" label="状态">
<select-dict-data v-model:value="entityForm.status" dictTypeKey="sys_normal_disable" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="deptId" label="部门">
<el-cascader
v-model="entityForm.deptId"
:options="deptTree"
:props="{ checkStrictly: true, value: 'deptId', label: 'deptName' }"
@change="deptCascaderChange"
filterable
tabindex="6"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="areaCode" label="行政地址">
<search-china-area v-model="entityForm.areaCode" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="address" label="联系地址">
<el-input
v-model="entityForm.address"
:rows="3"
clearable
placeholder="联系地址"
type="textarea"
tabindex="6"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">

View File

@@ -1,125 +1,126 @@
<template>
<el-container class="app-container" v-loading="loading">
<el-header>
<el-row :gutter="20">
<el-col :span="8">
<el-input v-model="params.keywords" clearable placeholder="根据关键字搜索" />
</el-col>
<el-col :span="2">
<div class="app-container" v-loading="loading">
<el-card v-loading="loading" shadow="never" class="search-wrapper">
<el-form ref="searchFormRef" :inline="true" :model="params">
<el-form-item>
<el-input v-model="params.keywords" clearable placeholder="根据 参数名称、参数键名 搜索" />
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="searchTableData">搜索</el-button>
</el-col>
<el-col :span="2">
</el-form-item>
<el-form-item>
<el-button type="success" :icon="Plus" @click="handleAdd()">新增</el-button>
</el-col>
<el-col :span="10">
<div class="grid-content ep-bg-purple" />
</el-col>
</el-row>
</el-header>
<el-main>
<el-table :data="tableData">
<el-table-column prop="configId" label="配置ID" />
<el-table-column prop="configName" label="参数名" />
<el-table-column prop="configKey" label="参数键" />
<el-table-column prop="configValue" label="参数键值">
<template #default="scope">
<el-popover
placement="top-start"
:width="300"
trigger="hover"
v-if="scope.row.configValue"
:content="scope.row.configValue"
>
<template #reference>
<el-link> {{ showStringOverflow(scope.row.configValue) }}</el-link>
</template>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="configType" label="系统内置">
<template #default="scope">
{{ dictStore.getYesNo(scope.row.configType) }}
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="130">
<template #default="scope">
<div v-admin>
<el-link :icon="Edit" type="warning" @click="handleEdit(scope.row)">编辑</el-link>
&nbsp;
<el-link v-if="scope.row.configType !== 1" :icon="Delete" type="danger" @click="handleDelete(scope.row)"
>删除</el-link
</el-form-item>
</el-form>
</el-card>
<el-card v-loading="loading" shadow="never">
<div class="toolbar-wrapper">
<el-table :data="tableData">
<el-table-column prop="configId" label="配置ID" />
<el-table-column prop="configName" label="参数名称" />
<el-table-column prop="configKey" label="参数名" />
<el-table-column prop="configValue" label="参数键">
<template #default="scope">
<el-popover
placement="top-start"
:width="300"
trigger="hover"
v-if="scope.row.configValue"
:content="scope.row.configValue"
>
</div>
</template>
</el-table-column>
</el-table>
<template #reference>
<el-link> {{ showStringOverflow(scope.row.configValue) }}</el-link>
</template>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="configType" label="系统内置">
<template #default="scope">
{{ dictStore.getYesNo(scope.row.configType) }}
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="130">
<template #default="scope">
<div v-admin>
<el-link :icon="Edit" type="warning" @click="handleEdit(scope.row)">编辑</el-link>
&nbsp;
<el-link v-if="scope.row.configType !== 1" :icon="Delete" type="danger" @click="handleDelete(scope.row)"
>删除</el-link
>
</div>
</template>
</el-table-column>
</el-table>
</div>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="30%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="configName" label="参数名称">
<el-input v-model.trim="entityForm.configName" placeholder="参数名称" type="text" tabindex="1" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="configType" label="系统内置">
<select-dict-data v-model:value="entityForm.configType" dictTypeKey="sys_yes_no" />
</el-form-item>
</el-col>
</el-row>
<div class="pager-wrapper">
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
<el-form-item prop="configKey" label="参数键名">
<el-input v-model.trim="entityForm.configKey" placeholder="参数键名" type="text" tabindex="2" />
</el-form-item>
<el-form-item prop="configValue" label="参数键值">
<el-input
v-model="entityForm.configValue"
placeholder="参数键值"
show-word-limit
type="textarea"
:rows="5"
tabindex="3"
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
</el-main>
<el-footer>
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-footer>
</el-container>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="30%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="configName" label="参数名称">
<el-input v-model.trim="entityForm.configName" placeholder="参数名称" type="text" tabindex="1" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="configType" label="系统内置">
<select-dict-data v-model:value="entityForm.configType" dictTypeKey="sys_yes_no" />
</el-form-item>
</el-col>
</el-row>
<el-form-item prop="configKey" label="参数键名">
<el-input v-model.trim="entityForm.configKey" placeholder="参数键名" type="text" tabindex="2" />
</el-form-item>
<el-form-item prop="configValue" label="参数键值">
<el-input
v-model="entityForm.configValue"
placeholder="参数键值"
show-word-limit
type="textarea"
:rows="5"
tabindex="3"
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">

View File

@@ -1,104 +1,107 @@
<template>
<el-container class="app-container" v-loading="loading">
<el-header>
<el-row :gutter="20">
<el-col :span="8">
<el-input v-model="params.keywords" clearable placeholder="根据关键字搜索" />
</el-col>
<el-col :span="2">
<div class="app-container" v-loading="loading">
<el-card v-loading="loading" shadow="never" class="search-wrapper">
<el-form ref="searchFormRef" :inline="true" :model="params">
<el-form-item>
<el-input v-model="params.keywords" clearable placeholder="根据 名称 搜索" />
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="searchTableData">搜索</el-button>
</el-col>
<el-col :span="2">
</el-form-item>
<el-form-item>
<el-button type="success" :icon="Plus" @click="handleAdd()">新增</el-button>
</el-col>
<el-col :span="10"><div class="grid-content ep-bg-purple" /></el-col>
</el-row>
</el-header>
<el-main>
<el-table :data="tableData">
<el-table-column prop="dictCode" label="ID" />
<el-table-column prop="dictLabel" label="名称" />
<el-table-column prop="dictValue" label="键值" />
<el-table-column prop="isDefault" label="默认">
<template #default="scope">
{{ dictStore.getYesNo(scope.row.isDefault) }}
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="130">
<template #default="scope">
<div v-admin>
<el-link :icon="Edit" type="warning" @click="handleEdit(scope.row)">编辑</el-link>
&nbsp;
<el-link v-if="scope.row.configType !== 1" :icon="Delete" type="danger" @click="handleDelete(scope.row)"
>删除</el-link
>
</div>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
</el-card>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="30%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="dictLabel" label="名称">
<el-input v-model.trim="entityForm.dictLabel" placeholder="名称" type="text" tabindex="1" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="isDefault" label="默认">
<select-dict-data v-model:value="entityForm.isDefault" dictTypeKey="sys_yes_no" />
</el-form-item>
</el-col>
</el-row>
<el-form-item prop="dictValue" label="键值">
<el-input
v-model="entityForm.dictValue"
placeholder="键值"
show-word-limit
type="textarea"
:rows="5"
tabindex="2"
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
</el-main>
<el-footer>
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-footer>
</el-container>
<el-card v-loading="loading" shadow="never">
<div class="toolbar-wrapper">
<el-table :data="tableData">
<el-table-column prop="dictCode" label="ID" />
<el-table-column prop="dictLabel" label="名称" />
<el-table-column prop="dictValue" label="键值" />
<el-table-column prop="isDefault" label="默认">
<template #default="scope">
{{ dictStore.getYesNo(scope.row.isDefault) }}
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="130">
<template #default="scope">
<div v-admin>
<el-link :icon="Edit" type="warning" @click="handleEdit(scope.row)">编辑</el-link>
&nbsp;
<el-link v-if="scope.row.configType !== 1" :icon="Delete" type="danger" @click="handleDelete(scope.row)"
>删除</el-link
>
</div>
</template>
</el-table-column>
</el-table>
</div>
<div class="pager-wrapper">
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="30%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="dictLabel" label="名称">
<el-input v-model.trim="entityForm.dictLabel" placeholder="名称" type="text" tabindex="1" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="isDefault" label="默认">
<select-dict-data v-model:value="entityForm.isDefault" dictTypeKey="sys_yes_no" />
</el-form-item>
</el-col>
</el-row>
<el-form-item prop="dictValue" label="键值">
<el-input
v-model="entityForm.dictValue"
placeholder="键值"
show-word-limit
type="textarea"
:rows="5"
tabindex="2"
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">

View File

@@ -1,120 +1,123 @@
<template>
<el-container class="app-container" v-loading="loading">
<el-header>
<el-row :gutter="20">
<el-col :span="8">
<el-input v-model="params.keywords" clearable placeholder="根据关键字搜索" />
</el-col>
<el-col :span="2">
<div class="app-container" v-loading="loading">
<el-card v-loading="loading" shadow="never" class="search-wrapper">
<el-form ref="searchFormRef" :inline="true" :model="params">
<el-form-item>
<el-input v-model="params.keywords" clearable placeholder="根据 字典名称 搜索" />
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="searchTableData">搜索</el-button>
</el-col>
<el-col :span="2">
</el-form-item>
<el-form-item>
<el-button type="success" :icon="Plus" @click="handleAdd()">新增</el-button>
</el-col>
<el-col :span="10"><div class="grid-content ep-bg-purple" /></el-col>
</el-row>
</el-header>
<el-main>
<el-table :data="tableData">
<el-table-column prop="typeId" label="字典ID" />
<el-table-column prop="typeName" label="字典名称" />
<el-table-column prop="typeKey" label="字典关键字">
<template #default="scope">
<router-link :to="{ path: '/sys/dict/data', query: { typeKey: scope.row.typeKey } }">
<el-link type="primary">{{ scope.row.typeKey }}</el-link>
</router-link>
</template>
</el-table-column>
<el-table-column prop="description" label="字典描述">
<template #default="scope">
<el-popover
placement="top-start"
:width="300"
trigger="hover"
v-if="scope.row.description"
:content="scope.row.description"
>
<template #reference>
<el-link> {{ showStringOverflow(scope.row.description) }}</el-link>
</template>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="130">
<template #default="scope">
<div v-admin>
<el-link :icon="Edit" type="warning" @click="handleEdit(scope.row)">编辑</el-link>
&nbsp;
<el-link v-if="scope.row.configType !== 1" :icon="Delete" type="danger" @click="handleDelete(scope.row)"
>删除</el-link
>
</div>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
</el-card>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="30%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="typeName" label="字典名称">
<el-input v-model.trim="entityForm.typeName" placeholder="字典名称" type="text" tabindex="1" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="typeKey" label="字典KEY">
<el-input v-model.trim="entityForm.typeKey" placeholder="字典KEY" type="text" tabindex="1" />
</el-form-item>
</el-col>
</el-row>
<el-form-item prop="description" label="字典描述">
<el-input
v-model="entityForm.description"
placeholder="字典描述"
show-word-limit
type="textarea"
:rows="5"
tabindex="3"
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
</el-main>
<el-footer>
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-footer>
</el-container>
<el-card v-loading="loading" shadow="never">
<div class="toolbar-wrapper">
<el-table :data="tableData">
<el-table-column prop="typeId" label="字典ID" />
<el-table-column prop="typeName" label="字典名称" />
<el-table-column prop="typeKey" label="字典关键字">
<template #default="scope">
<router-link :to="{ path: '/sys/dict/data', query: { typeKey: scope.row.typeKey } }">
<el-link type="primary">{{ scope.row.typeKey }}</el-link>
</router-link>
</template>
</el-table-column>
<el-table-column prop="description" label="字典描述">
<template #default="scope">
<el-popover
placement="top-start"
:width="300"
trigger="hover"
v-if="scope.row.description"
:content="scope.row.description"
>
<template #reference>
<el-link> {{ showStringOverflow(scope.row.description) }}</el-link>
</template>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="130">
<template #default="scope">
<div v-admin>
<el-link :icon="Edit" type="warning" @click="handleEdit(scope.row)">编辑</el-link>
&nbsp;
<el-link v-if="scope.row.configType !== 1" :icon="Delete" type="danger" @click="handleDelete(scope.row)"
>删除</el-link
>
</div>
</template>
</el-table-column>
</el-table>
</div>
<div class="pager-wrapper">
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="30%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="typeName" label="字典名称">
<el-input v-model.trim="entityForm.typeName" placeholder="字典名称" type="text" tabindex="1" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="typeKey" label="字典KEY">
<el-input v-model.trim="entityForm.typeKey" placeholder="字典KEY" type="text" tabindex="1" />
</el-form-item>
</el-col>
</el-row>
<el-form-item prop="description" label="字典描述">
<el-input
v-model="entityForm.description"
placeholder="字典描述"
show-word-limit
type="textarea"
:rows="5"
tabindex="3"
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">

View File

@@ -1,143 +1,144 @@
<template>
<el-container class="app-container" v-loading="loading">
<el-header>
<el-row :gutter="20">
<el-col :span="8">
<el-input v-model="params.keywords" clearable placeholder="根据关键字搜索" />
</el-col>
<el-col :span="2">
<div class="app-container" v-loading="loading">
<el-card v-loading="loading" shadow="never" class="search-wrapper">
<el-form ref="searchFormRef" :inline="true" :model="params">
<el-form-item>
<el-input v-model="params.keywords" clearable placeholder="根据 模板名称 搜索" />
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="searchTableData">搜索</el-button>
</el-col>
<el-col :span="2">
</el-form-item>
<el-form-item>
<el-button type="success" :icon="Plus" @click="handleAdd()">新增</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card v-loading="loading" shadow="never">
<div class="toolbar-wrapper">
<el-table :data="tableData">
<el-table-column prop="id" label="模板ID" />
<el-table-column prop="name" label="名称" />
<el-table-column prop="description" label="描述">
<template #default="scope">
<el-popover
placement="top-start"
:width="300"
trigger="hover"
v-if="scope.row.description"
:content="scope.row.description"
>
<template #reference>
<el-link> {{ showStringOverflow(scope.row.description) }}</el-link>
</template>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="scope">
<el-link :icon="EditPen" type="info" @click="handleEditMenu(scope.row)">权限</el-link>
&nbsp;
<el-link :icon="Edit" type="warning" @click="handleEdit(scope.row)">编辑</el-link>
&nbsp;
<el-link v-admin :icon="Delete" type="danger" @click="handleDelete(scope.row)">删除</el-link>
</template>
</el-table-column>
</el-table>
</div>
<div class="pager-wrapper">
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="30%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
>
<el-form-item prop="name" label="名称">
<el-input v-model.trim="entityForm.name" placeholder="名称" type="text" tabindex="1" />
</el-form-item>
<el-form-item prop="description" label="描述">
<el-input
v-model="entityForm.description"
placeholder="描述"
:rows="5"
:maxlength="100"
type="textarea"
tabindex="3"
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
<!-- 修改权限 -->
<el-dialog v-model="menusDialogVisible" :title="menusDialogTitle" width="30%" :close-on-click-modal="false">
<el-row :gutter="20">
<el-col :span="14">
<el-input v-model="filterMenuText" clearable placeholder="根据菜单名称筛选" />
</el-col>
<el-col :span="10">
<div class="grid-content ep-bg-purple" />
<el-col :span="5">
<el-button type="success" :icon="Sort" @click="switchExpandAndCollapse">{{
expandAndCollapse ? "折叠" : "展开"
}}</el-button>
</el-col>
<el-col :span="5">
<el-button type="success" :icon="checkAll ? 'CloseBold' : 'Select'" @click="switchCheckAll">{{
checkAll ? "取消" : "全选"
}}</el-button>
</el-col>
</el-row>
</el-header>
<el-main>
<el-table :data="tableData">
<el-table-column prop="id" label="模板ID" />
<el-table-column prop="name" label="名称" />
<el-table-column prop="description" label="描述">
<template #default="scope">
<el-popover
placement="top-start"
:width="300"
trigger="hover"
v-if="scope.row.description"
:content="scope.row.description"
>
<template #reference>
<el-link> {{ showStringOverflow(scope.row.description) }}</el-link>
</template>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="scope">
<el-link :icon="EditPen" type="info" @click="handleEditMenu(scope.row)">权限</el-link>
&nbsp;
<el-link :icon="Edit" type="warning" @click="handleEdit(scope.row)">编辑</el-link>
&nbsp;
<el-link v-admin :icon="Delete" type="danger" @click="handleDelete(scope.row)">删除</el-link>
</template>
</el-table-column>
</el-table>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="30%" :close-on-click-modal="false">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
>
<el-form-item prop="name" label="名称">
<el-input v-model.trim="entityForm.name" placeholder="名称" type="text" tabindex="1" />
</el-form-item>
<el-form-item prop="description" label="描述">
<el-input
v-model="entityForm.description"
placeholder="描述"
:rows="5"
:maxlength="100"
type="textarea"
tabindex="3"
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleSaveAndFlush">确定</el-button>
</span>
</template>
</el-dialog>
<!-- 修改权限 -->
<el-dialog v-model="menusDialogVisible" :title="menusDialogTitle" width="30%" :close-on-click-modal="false">
<el-row :gutter="20">
<el-col :span="14">
<el-input v-model="filterMenuText" clearable placeholder="根据菜单名称筛选" />
</el-col>
<el-col :span="5">
<el-button type="success" :icon="Sort" @click="switchExpandAndCollapse">{{
expandAndCollapse ? "折叠" : "展开"
}}</el-button>
</el-col>
<el-col :span="5">
<el-button type="success" :icon="checkAll ? 'CloseBold' : 'Select'" @click="switchCheckAll">{{
checkAll ? "取消" : "全选"
}}</el-button>
</el-col>
</el-row>
<br />
<div :style="{ height: '400px', overflowY: 'scroll' }">
<el-tree
ref="treeRef"
:data="menusData?.all"
:check-strictly="true"
:default-expand-all="expandAndCollapse"
:filter-node-method="filterNode"
show-checkbox
node-key="id"
highlight-current
:props="{ children: 'children', label: 'name' }"
/>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="menusDialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleUpdateMenus">确定</el-button>
</span>
</template>
</el-dialog>
</el-main>
<el-footer>
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-footer>
</el-container>
<br />
<div :style="{ height: '400px', overflowY: 'scroll' }">
<el-tree
ref="treeRef"
:data="menusData?.all"
:check-strictly="true"
:default-expand-all="expandAndCollapse"
:filter-node-method="filterNode"
show-checkbox
node-key="id"
highlight-current
:props="{ children: 'children', label: 'name' }"
/>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="menusDialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleUpdateMenus">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">

View File

@@ -1,233 +1,234 @@
<template>
<el-container class="app-container" v-loading="loading">
<el-header>
<el-row :gutter="20">
<el-col :span="8">
<el-input v-model="params.keywords" clearable placeholder="根据关键字搜索" />
</el-col>
<el-col :span="2">
<div class="app-container" v-loading="loading">
<el-card v-loading="loading" shadow="never" class="search-wrapper">
<el-form ref="searchFormRef" :inline="true" :model="params">
<el-form-item>
<el-input v-model="params.keywords" clearable placeholder="根据 租户名称 搜索" />
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="searchTableData">搜索</el-button>
</el-col>
<el-col :span="2">
</el-form-item>
<el-form-item>
<el-button type="success" :icon="Plus" @click="handleAdd()">新增</el-button>
</el-col>
<el-col :span="10">
<div class="grid-content ep-bg-purple" />
</el-col>
</el-row>
</el-header>
<el-main>
<el-table :data="tableData">
<el-table-column prop="tenantId" label="租户ID" />
<el-table-column prop="logo" label="Logo">
<template #default="scope">
<el-avatar :size="40" :icon="UserFilled" :src="scope.row.logo" />
</template>
</el-table-column>
<el-table-column prop="name" label="名称" />
<el-table-column prop="email" label="邮箱" />
<el-table-column prop="linkman" label="联系人" />
<el-table-column prop="contactNumber" label="联系方式" />
<el-table-column prop="areaCode" label="行政区域">
<template #default="scope">
{{ showChinaArea(scope.row.areaCode) }}
</template>
</el-table-column>
<el-table-column prop="address" label="联系地址" />
<el-table-column prop="templates" label="权限模板">
<template #default="scope">
<el-tooltip
v-for="(item, index) in scope.row.templates"
:key="index"
effect="dark"
:content="item.description"
placement="top-start"
>
<el-tag>{{ item.name }}</el-tag>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="status" label="状态">
<template #default="scope">
{{ dictStore.getNormalDisable(scope.row.status) }}
</template>
</el-table-column>
<el-table-column prop="expired" label="过期时间">
<template #default="scope">
<el-tooltip v-if="scope.row.expired" :content="scope.row.expired" placement="top">
<el-link> {{ showExpiredDateAgo(scope.row.expired) }}</el-link>
</el-tooltip>
<span v-else>永久</span>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="130">
<template #default="scope">
<el-link :icon="Edit" type="warning" @click="handleEdit(scope.row)">编辑</el-link>
&nbsp;
<!-- v-admin 只有管理员才可以删除租户 -->
<el-link
:icon="Delete"
v-admin
v-if="!isDefaultTenantId(scope.row.tenantId)"
type="danger"
@click="handleDelete(scope.row)"
>删除</el-link
>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
</el-card>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="50%" :close-on-click-modal="false">
<template v-if="saveFlag">
<create-tenant :template-list="templateList!" @close="closeCreateTenant" />
</template>
<el-card v-loading="loading" shadow="never">
<div class="toolbar-wrapper">
<el-table :data="tableData">
<el-table-column prop="tenantId" label="租户ID" />
<el-table-column prop="logo" label="Logo">
<template #default="scope">
<el-avatar :size="40" :icon="UserFilled" :src="scope.row.logo" />
</template>
</el-table-column>
<el-table-column prop="name" label="名称" />
<el-table-column prop="email" label="邮箱" />
<el-table-column prop="linkman" label="联系人" />
<el-table-column prop="contactNumber" label="联系方式" />
<el-table-column prop="areaCode" label="行政区域">
<template #default="scope">
{{ showChinaArea(scope.row.areaCode) }}
</template>
</el-table-column>
<el-table-column prop="address" label="联系地址" />
<el-table-column prop="templates" label="权限模板">
<template #default="scope">
<el-tooltip
v-for="(item, index) in scope.row.templates"
:key="index"
effect="dark"
:content="item.description"
placement="top-start"
>
<el-tag>{{ item.name }}</el-tag>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="status" label="状态">
<template #default="scope">
{{ dictStore.getNormalDisable(scope.row.status) }}
</template>
</el-table-column>
<el-table-column prop="expired" label="过期时间">
<template #default="scope">
<el-tooltip v-if="scope.row.expired" :content="scope.row.expired" placement="top">
<el-link> {{ showExpiredDateAgo(scope.row.expired) }}</el-link>
</el-tooltip>
<span v-else>永久</span>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
<operateUser :dateTime="scope.row.createTime" :entity="scope.row.createUserEntity" />
</template>
</el-table-column>
<el-table-column prop="lastUpdateTime" label="修改时间">
<template #default="scope">
<operateUser :dateTime="scope.row.lastUpdateTime" :entity="scope.row.lastUpdateUserEntity" />
</template>
</el-table-column>
<el-table-column label="操作" width="130">
<template #default="scope">
<el-link :icon="Edit" type="warning" @click="handleEdit(scope.row)">编辑</el-link>
&nbsp;
<!-- v-admin 只有管理员才可以删除租户 -->
<el-link
:icon="Delete"
v-admin
v-if="!isDefaultTenantId(scope.row.tenantId)"
type="danger"
@click="handleDelete(scope.row)"
>删除</el-link
>
</template>
</el-table-column>
</el-table>
</div>
<template v-if="!saveFlag">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
>
<el-form-item prop="logo" label="Logo">
<image-upload :key="entityForm.logo" :src="entityForm.logo" @change="getLogoSrc" />
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="tenantId" label="租户ID">
<el-input
v-model.trim="entityForm.tenantId"
clearable
placeholder="租户ID"
disabled
type="text"
tabindex="1"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="name" label="名称">
<el-input v-model.trim="entityForm.name" clearable placeholder="租户名称" type="text" tabindex="2" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="email" label="邮箱">
<el-input v-model.trim="entityForm.email" clearable placeholder="租户邮箱" type="text" tabindex="3" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="status" label="状态">
<select-dict-data v-model:value="entityForm.status" dictTypeKey="sys_normal_disable" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="linkman" label="联系人">
<el-input
v-model.trim="entityForm.linkman"
clearable
placeholder="租户联系人"
type="text"
tabindex="4"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="contactNumber" label="联系方式">
<el-input
v-model.trim="entityForm.contactNumber"
clearable
placeholder="租户联系方式"
type="text"
tabindex="5"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="areaCode" label="行政地址">
<search-china-area v-model="entityForm.areaCode" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="address" label="联系地址">
<el-input
v-model.trim="entityForm.address"
clearable
placeholder="租户联系地址"
type="text"
tabindex="6"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="templates" label="租户模板">
<el-select v-model="entityTemplates" filterable clearable multiple placeholder="选择租户模板">
<el-option v-for="item in templateList" :key="item.id" :label="item.name" :value="item.id">
<span style="float: left">{{ item.name }}</span>
<span style="float: right; color: var(--el-text-color-secondary); font-size: 13px">{{
showStringOverflow(item.description)
}}</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="expired" label="过期时间">
<el-date-picker
v-model="entityForm.expired"
clearable
type="datetime"
placeholder="请选择过期时间"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
:shortcuts="futureShortcuts"
tabindex="7"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<div class="pager-wrapper">
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
<template v-if="!saveFlag" #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleUpdate">确定</el-button>
</span>
</template>
</el-dialog>
</el-main>
<el-footer>
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-footer>
</el-container>
<!-- 新增和修改的弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="50%" :close-on-click-modal="false">
<template v-if="saveFlag">
<create-tenant :template-list="templateList!" @close="closeCreateTenant" />
</template>
<template v-if="!saveFlag">
<el-form
ref="entityFormRef"
:model="entityForm"
:rules="entityFormRules"
label-position="right"
label-width="80px"
>
<el-form-item prop="logo" label="Logo">
<image-upload :key="entityForm.logo" :src="entityForm.logo" @change="getLogoSrc" />
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="tenantId" label="租户ID">
<el-input
v-model.trim="entityForm.tenantId"
clearable
placeholder="租户ID"
disabled
type="text"
tabindex="1"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="name" label="名称">
<el-input v-model.trim="entityForm.name" clearable placeholder="租户名称" type="text" tabindex="2" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="email" label="邮箱">
<el-input v-model.trim="entityForm.email" clearable placeholder="租户邮箱" type="text" tabindex="3" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="status" label="状态">
<select-dict-data v-model:value="entityForm.status" dictTypeKey="sys_normal_disable" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="linkman" label="联系人">
<el-input
v-model.trim="entityForm.linkman"
clearable
placeholder="租户联系人"
type="text"
tabindex="4"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="contactNumber" label="联系方式">
<el-input
v-model.trim="entityForm.contactNumber"
clearable
placeholder="租户联系方式"
type="text"
tabindex="5"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="areaCode" label="行政地址">
<search-china-area v-model="entityForm.areaCode" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="address" label="联系地址">
<el-input
v-model.trim="entityForm.address"
clearable
placeholder="租户联系地址"
type="text"
tabindex="6"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="templates" label="租户模板">
<el-select v-model="entityTemplates" filterable clearable multiple placeholder="选择租户模板">
<el-option v-for="item in templateList" :key="item.id" :label="item.name" :value="item.id">
<span style="float: left">{{ item.name }}</span>
<span style="float: right; color: var(--el-text-color-secondary); font-size: 13px">{{
showStringOverflow(item.description)
}}</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="expired" label="过期时间">
<el-date-picker
v-model="entityForm.expired"
clearable
type="datetime"
placeholder="请选择过期时间"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
:shortcuts="futureShortcuts"
tabindex="7"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<template v-if="!saveFlag" #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" v-preventReClick @click="handleUpdate">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">