fix:1,优化投注记录
parent
609cc7b1b8
commit
3416e62a1b
|
|
@ -8,6 +8,22 @@ export function listRole(query) {
|
|||
params: query
|
||||
})
|
||||
}
|
||||
// 获取角色选择框列表
|
||||
export function optionselect(query) {
|
||||
return request({
|
||||
url: '/system/role/optionselect',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 获取菜单角色
|
||||
export function getMenu(roleId) {
|
||||
return request({
|
||||
url: '/system/role/getMenu/' + roleId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询角色详细
|
||||
export function getRole(roleId) {
|
||||
|
|
@ -97,7 +113,15 @@ export function authUserCancelAll(data) {
|
|||
return request({
|
||||
url: '/system/role/authUser/cancelAll',
|
||||
method: 'put',
|
||||
params: data
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 批量清除关联账号
|
||||
export function authRolecancelAll(data) {
|
||||
return request({
|
||||
url: '/system/role/authRole/cancelAll',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -106,7 +130,7 @@ export function authUserSelectAll(data) {
|
|||
return request({
|
||||
url: '/system/role/authUser/selectAll',
|
||||
method: 'put',
|
||||
params: data
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,13 +43,36 @@ export function delUser(userId) {
|
|||
method: 'delete'
|
||||
})
|
||||
}
|
||||
//删除账户/批量删除
|
||||
export function deleteUserSystem(data) {
|
||||
return request({
|
||||
url: '/system/user/delete',
|
||||
method: 'delete',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
//冻结账户
|
||||
export function changeStatus(data) {
|
||||
return request({
|
||||
url: '/system/user/changeStatus',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
//清空角色
|
||||
export function resetRole(data) {
|
||||
return request({
|
||||
url: '/system/user/resetRole',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 用户密码重置
|
||||
export function resetUserPwd(userId, password,codeGoogle) {
|
||||
export function resetUserPwd(userId,inputGoogleCode) {
|
||||
const data = {
|
||||
userId,
|
||||
password,
|
||||
codeGoogle
|
||||
inputGoogleCode
|
||||
}
|
||||
return request({
|
||||
url: '/system/user/resetPwd',
|
||||
|
|
@ -58,6 +81,20 @@ export function resetUserPwd(userId, password,codeGoogle) {
|
|||
})
|
||||
}
|
||||
|
||||
// 用户重置谷歌验证码
|
||||
export function resetGoogle(userId,inputGoogleCode) {
|
||||
const data = {
|
||||
userId,
|
||||
inputGoogleCode
|
||||
}
|
||||
return request({
|
||||
url: '/system/user/resetGoogle',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 用户状态修改
|
||||
export function changeUserStatus(userId, status) {
|
||||
const data = {
|
||||
|
|
@ -89,10 +126,11 @@ export function updateUserProfile(data) {
|
|||
}
|
||||
|
||||
// 用户密码重置
|
||||
export function updateUserPwd(oldPassword, newPassword) {
|
||||
export function updateUserPwd(oldPassword, newPassword,codeGoogle) {
|
||||
const data = {
|
||||
oldPassword,
|
||||
newPassword
|
||||
newPassword,
|
||||
codeGoogle
|
||||
}
|
||||
return request({
|
||||
url: '/system/user/profile/updatePwd',
|
||||
|
|
@ -101,6 +139,15 @@ export function updateUserPwd(oldPassword, newPassword) {
|
|||
})
|
||||
}
|
||||
|
||||
// 修改密码
|
||||
export function updateUserPassword(data) {
|
||||
return request({
|
||||
url: '/system/user/profile/change/password',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 用户头像上传
|
||||
export function uploadAvatar(data) {
|
||||
return request({
|
||||
|
|
@ -136,11 +183,10 @@ export function deptTreeSelect() {
|
|||
})
|
||||
}
|
||||
|
||||
// 修改密码
|
||||
export function updateUserPassword(data) {
|
||||
// 用户名称检查
|
||||
export function getSystemUserCheck(userName) {
|
||||
return request({
|
||||
url: '/resetPwd',
|
||||
method: 'post',
|
||||
data: data
|
||||
url: '/system/user/check/' + userName,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
<template>
|
||||
<!-- 表格批量操作组件 -->
|
||||
<div class="table-op">
|
||||
<el-checkbox v-model="isAllSelection" @change="allSelectionChange" style="transform: translateY(3px);">{{
|
||||
t('全选当前页')
|
||||
}}</el-checkbox>
|
||||
<el-select v-model="batchOpType" :disabled="selectionData.length === 0" :placeholder="t('批量操作')"
|
||||
style="width: 150px; margin-left: 20px;" @change="opTypeChange">
|
||||
<el-option v-for="item in opTypeOptions" :label="t(item.label)" :value="item.value" :disabled="item.disabled" />
|
||||
</el-select>
|
||||
<span class="selection-tips" v-if="selectionData.length > 0">{{ t('已选择')
|
||||
}}<b>{{ selectionData.length }}</b>{{ t('条数据') }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
selectionData: { // 选中的表格数据
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
opTypeOptions: { // 批量操作选项
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
});
|
||||
|
||||
const isAllSelection = defineModel('isAllSelection', { type: Boolean, default: false }); // 是否全选
|
||||
const batchOpType = defineModel('batchOpType', { type: String, default: '' }); // 选中的批量操作类型
|
||||
const emit = defineEmits(['allSelectionChange', 'opTypeChange']);
|
||||
|
||||
// 全选当前页
|
||||
const allSelectionChange = () => {
|
||||
emit('allSelectionChange');
|
||||
}
|
||||
|
||||
// 选择批量操作类型
|
||||
const opTypeChange = () => {
|
||||
emit('opTypeChange');
|
||||
}
|
||||
const reset = () => {
|
||||
batchOpType.value = null;
|
||||
emit('selectionDataNu');
|
||||
}
|
||||
defineExpose({
|
||||
reset
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.table-op {
|
||||
position: absolute;
|
||||
left: 5px;
|
||||
bottom: 10px;
|
||||
z-index: 100;
|
||||
|
||||
.selection-tips {
|
||||
font-size: 14px;
|
||||
padding-left: 10px;
|
||||
color: #666666;
|
||||
|
||||
b {
|
||||
color: #F56C6C;
|
||||
padding: 0 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -27,17 +27,19 @@
|
|||
/>
|
||||
</el-menu>
|
||||
</el-scrollbar> -->
|
||||
<div class="avatar-container">
|
||||
<el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
|
||||
<div class="avatar-wrapper">
|
||||
<img :src="userStore.avatar" class="user-avatar" />
|
||||
<el-icon><caret-bottom /></el-icon>
|
||||
<div class="avatar-container" style="margin-right: 10px;" >
|
||||
<el-dropdown @command="handleCommand" style="" class="right-menu-item hover-effect" trigger="click">
|
||||
<div class="avatar-wrapper" style="display: flex;align-items: center;justify-content: center;color: #fff;font-size: 14px;">
|
||||
<!-- <img :src="userStore.avatar" class="user-avatar" />
|
||||
<el-icon><caret-bottom /></el-icon> -->
|
||||
{{ nickName }}
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<router-link to="/user/profile">
|
||||
<!-- <router-link to="/user/profile">
|
||||
<el-dropdown-item>个人中心</el-dropdown-item>
|
||||
</router-link>
|
||||
</router-link> -->
|
||||
<el-dropdown-item @click="handleClick">{{ t("账户设置") }}</el-dropdown-item>
|
||||
<el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
|
||||
<span>布局设置</span>
|
||||
</el-dropdown-item>
|
||||
|
|
@ -48,6 +50,61 @@
|
|||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
|
||||
<el-dialog :title="t('账号设置')" align-center v-model="dialogVisible" width="700" append-to-body>
|
||||
<el-scrollbar max-height="600px">
|
||||
<el-form ref="userRef" :model="formData" :rules="rules" label-width="100px">
|
||||
<el-form-item label="后台账号" prop="roleName">
|
||||
{{ formData.userName }}
|
||||
</el-form-item>
|
||||
<el-form-item label="后台昵称" prop="nickName">
|
||||
<el-input v-model="formData.nickName"
|
||||
:placeholder="t('仅支持中英文和数字,为1-20个字符')" maxlength="20" />
|
||||
</el-form-item>
|
||||
<el-form-item label="登录密码">
|
||||
<el-row style="width: 100%;">
|
||||
<el-col :span="12">
|
||||
{{ t('已设置') }}
|
||||
</el-col>
|
||||
<el-col :span="12" style="display: flex;justify-content: right;">
|
||||
<el-button type="primary" @click="updatePassword">修改密码</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
<template #footer>
|
||||
<div class="dialog-footer" style="display: flex;justify-content: center;">
|
||||
<el-button @click="closeDialog">取 消</el-button>
|
||||
<el-button type="primary" @click="submitForm">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 修改密码 -->
|
||||
<el-dialog :title="t('修改密码')" align-center v-model="passwordDialogVisible" width="630" append-to-body>
|
||||
<el-scrollbar max-height="600px">
|
||||
<el-form ref="passwordRef" :model="passwordFormData" :rules="rulesPassword" label-width="100px">
|
||||
<el-form-item label="旧密码" prop="oldPassword">
|
||||
<el-input v-model="passwordFormData.oldPassword" placeholder="请输入旧密码" type="password" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newPassword">
|
||||
<el-input v-model="passwordFormData.newPassword" placeholder="请输入新密码" type="password" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="confirmPassword">
|
||||
<el-input v-model="passwordFormData.confirmPassword" placeholder="请确认新密码" type="password" show-password/>
|
||||
</el-form-item>
|
||||
<el-form-item label="谷歌验证码" prop="codeGoogle">
|
||||
<el-input v-model="passwordFormData.codeGoogle" maxlength="6" placeholder="请输入谷歌验证码"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
<template #footer>
|
||||
<div class="dialog-footer" style="display: flex;justify-content: center;">
|
||||
<el-button @click="closePasswordDialog">取 消</el-button>
|
||||
<el-button type="primary" @click="submitPasswordForm">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -60,19 +117,49 @@ import useAppStore from '@/store/modules/app'
|
|||
import useSettingsStore from '@/store/modules/settings'
|
||||
import usePermissionStore from '@/store/modules/permission'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
|
||||
import { getLocalStorage } from "@/utils/auth";
|
||||
import { updateUserProfile,getUserProfile,updateUserPwd } from "@/api/system/user";
|
||||
|
||||
const route = useRoute();
|
||||
const appStore = useAppStore()
|
||||
const userStore = useUserStore()
|
||||
const settingsStore = useSettingsStore()
|
||||
const permissionStore = usePermissionStore()
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const sidebarRouters = computed(() => permissionStore.sidebarRouters);
|
||||
const showLogo = computed(() => settingsStore.sidebarLogo);
|
||||
const sideTheme = computed(() => settingsStore.sideTheme);
|
||||
const theme = computed(() => settingsStore.theme);
|
||||
const windowWidth = ref(window.innerWidth)
|
||||
const nickName = ref(getLocalStorage('userInfo')?.nickName);
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const rules = ref({
|
||||
});
|
||||
const formData = ref({
|
||||
});
|
||||
const oldForm = shallowRef({ });
|
||||
const passwordDialogVisible = ref(false);
|
||||
const passwordFormData = ref({
|
||||
oldPassword: undefined,
|
||||
newPassword: undefined,
|
||||
confirmPassword: undefined,
|
||||
codeGoogle: undefined
|
||||
});
|
||||
|
||||
const equalToPassword = (rule, value, callback) => {
|
||||
if (passwordFormData.value.newPassword !== value) {
|
||||
callback(new Error("两次输入的密码不一致"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
const rulesPassword = ref({
|
||||
oldPassword: [{ required: true, message: "旧密码不能为空", trigger: "change" }],
|
||||
newPassword: [{ required: true, message: "新密码不能为空", trigger: "change" }, { min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "change" }, { pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "change" }],
|
||||
confirmPassword: [{ required: true, message: "确认密码不能为空", trigger: "change" }, { required: true, validator: equalToPassword, trigger: "change" }],
|
||||
codeGoogle: [{ required: true, message: "谷歌验证码不能为空", trigger: "change" }]
|
||||
});
|
||||
|
||||
function updateWidth() {
|
||||
windowWidth.value = window.innerWidth
|
||||
|
|
@ -125,6 +212,51 @@ function logout() {
|
|||
})
|
||||
}).catch(() => { });
|
||||
}
|
||||
const handleClick = () => {
|
||||
getUserProfile().then(response => {
|
||||
formData.value = response.data;
|
||||
dialogVisible.value = true;
|
||||
nextTick(() => {
|
||||
oldForm.value = JSON.stringify(formData.value);
|
||||
})
|
||||
});
|
||||
}
|
||||
const closeDialog = () => {
|
||||
dialogVisible.value = false;
|
||||
}
|
||||
//修改密码
|
||||
const updatePassword = () => {
|
||||
passwordDialogVisible.value = true;
|
||||
}
|
||||
const submitForm = () => {
|
||||
proxy.$refs.userRef.validate(valid => {
|
||||
if (valid) {
|
||||
if (JSON.stringify(formData.value) != oldForm.value) {
|
||||
updateUserProfile(formData.value).then(response => {
|
||||
proxy.$modal.msgSuccess("修改成功");
|
||||
nickName.value = formData.value.nickName;
|
||||
dialogVisible.value = false;
|
||||
});
|
||||
}else{
|
||||
dialogVisible.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const closePasswordDialog = () => {
|
||||
passwordDialogVisible.value = false;
|
||||
}
|
||||
const submitPasswordForm = () => {
|
||||
proxy.$refs.passwordRef.validate(valid => {
|
||||
if (valid) {
|
||||
updateUserPwd(passwordFormData.value.oldPassword, passwordFormData.value.newPassword,passwordFormData.value.codeGoogle).then(response => {
|
||||
proxy.$modal.msgSuccess("修改成功");
|
||||
passwordDialogVisible.value = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
|
|
@ -111,7 +111,8 @@
|
|||
</el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('谷歌验证码')" prop="googleCode">
|
||||
<el-input v-model="form.googleCode" style="width: 260px;" :placeholder="t('请输入谷歌验证码')" />
|
||||
<el-input v-model="form.googleCode" :maxlength="6" style="width: 260px;" :placeholder="t('请输入谷歌验证码')" />
|
||||
|
||||
</el-form-item>
|
||||
<!-- <div class="label-scoreRatio">
|
||||
<span>{{ t('平台比例') }}</span>
|
||||
|
|
@ -162,7 +163,7 @@
|
|||
</el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('谷歌验证码')" prop="googleCode">
|
||||
<el-input v-model="form.googleCode" style="width: 260px;" :placeholder="t('请输入谷歌验证码')" />
|
||||
<el-input v-model="form.googleCode" :maxlength="6" style="width: 260px;" :placeholder="t('请输入谷歌验证码')" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item :label="t('商户模式')" prop="tenantType">
|
||||
<el-radio-group v-model="form.tenantType" :disabled="openView">
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@
|
|||
{{ t(' (万法定货币=1万通用额度)') }}
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('谷歌验证码')" prop="googleCode">
|
||||
<el-input v-model="form.googleCode" style="width: 260px;" :placeholder="t('请输入谷歌验证码')" />
|
||||
<el-input v-model="form.googleCode" :maxlength="6" style="width: 260px;" :placeholder="t('请输入谷歌验证码')" />
|
||||
</el-form-item>
|
||||
<div class="label-scoreRatio">
|
||||
<span>{{ t('平台比例') }}</span>
|
||||
|
|
|
|||
|
|
@ -91,6 +91,12 @@
|
|||
<el-table-column :label="t('结算时间')" align="center" min-width="160" prop="settlementTime" :show-overflow-tooltip="true">
|
||||
<template #default="scope">{{ parseTime(scope.row.settlementTime) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('创建时间')" align="center" min-width="160" prop="ffcreateAt" :show-overflow-tooltip="true">
|
||||
<template #default="scope">{{ parseTime(scope.row.ffCreateAt) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('更新时间')" align="center" min-width="160" prop="ffupdateAt" :show-overflow-tooltip="true">
|
||||
<template #default="scope">{{ parseTime(scope.row.ffUpdateAt) }}</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column :label="t('操作')" align="center" width="200" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="handleView(scope.row)" v-hasPermi="['agent:tenant:view']">{{ t('详情') }}</el-button>
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@
|
|||
<el-input v-model="userInfos.walletAddress" disabled auto-complete="off" placeholder="请输入钱包地址" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('谷歌验证码')" prop="googleCode">
|
||||
<el-input v-model="form.googleCode" :placeholder="t('请输入谷歌验证码')" />
|
||||
<el-input v-model="form.googleCode" :maxlength="6" :placeholder="t('请输入谷歌验证码')" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@
|
|||
<el-dialog v-model="goodDialogVisible" style="margin-top: 45vh !important;" :title="t('温馨提示')" width="418" :before-close="handleClose">
|
||||
<div style="width: 90%;margin-bottom: 20px;">{{ t('请用手机打开客服端Google身份验证器,输入验证码') }}</div>
|
||||
<div class="">
|
||||
<el-input v-model="gooleCode" style="width: 90%" :placeholder="t('验证码只能为数字')" />
|
||||
<el-input v-model="gooleCode" :maxlength="6" style="width: 90%" :placeholder="t('验证码只能为数字')" />
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
|
|
@ -111,7 +111,7 @@
|
|||
</div>
|
||||
<el-form ref="authenticatorRef" :model="authenticatorForm" :rules="authenticatorRules">
|
||||
<el-form-item label="谷歌验证码" prop="authenticatorCode">
|
||||
<el-input v-model="authenticatorForm.authenticatorCode" :digit="2" style="width: 100%;height: 36px;" :placeholder="t('验证码只能为数字')" />
|
||||
<el-input v-model="authenticatorForm.authenticatorCode" :maxlength="6" :digit="2" style="width: 100%;height: 36px;" :placeholder="t('验证码只能为数字')" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="" style="margin-top: 20px;margin-bottom: 20px;">
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@
|
|||
{{ t('如需扣余额,则输入负数,例如:-10.50') }}
|
||||
</div>
|
||||
<el-form-item :label="t('谷歌验证码')" prop="googleCode">
|
||||
<el-input v-model="formAdjustment.googleCode" :placeholder="t('请输入谷歌验证码')" />
|
||||
<el-input v-model="formAdjustment.googleCode" :maxlength="6" :placeholder="t('请输入谷歌验证码')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('备注')" prop="remark">
|
||||
<el-input type="textarea" rows="4" v-model="formAdjustment.remark" :placeholder="t('请输入备注')" />
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('谷歌验证码')" prop="googleCode">
|
||||
<el-input v-model="formAdjustment.googleCode" :placeholder="t('请输入谷歌验证码')" />
|
||||
<el-input v-model="formAdjustment.googleCode" :maxlength="6" :placeholder="t('请输入谷歌验证码')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('备注')" prop="remark">
|
||||
<el-input type="textarea" rows="4" v-model="formAdjustment.remark" :placeholder="t('请输入备注')" />
|
||||
|
|
|
|||
|
|
@ -296,7 +296,12 @@ currencySelectArr.value = res.map(item => {
|
|||
/** 查询列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
superTenantList(queryParams.value).then(response => {
|
||||
let queryParams={
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
tenantKey: "",
|
||||
}
|
||||
superTenantList(queryParams).then(response => {
|
||||
agentList.value = response.rows;
|
||||
total.value = response.total;
|
||||
loading.value = false;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<table-search-card :leftSpan="20" :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
|
||||
<template #left>
|
||||
<table-search-date v-model:dateRange="dateRange" v-model:operateTimeType="operateTimeType"></table-search-date>
|
||||
<el-form-item :label="t('商户账号')" prop="tenantKey">
|
||||
<!-- <el-form-item :label="t('商户账号')" prop="tenantKey">
|
||||
<el-input
|
||||
v-model="queryParams.tenantKey"
|
||||
:placeholder="t('请输入商户账号')"
|
||||
|
|
@ -11,6 +11,40 @@
|
|||
style="width: 200px"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item> -->
|
||||
<el-form-item :label="t('商户账号')" prop="tenantKey">
|
||||
<el-select
|
||||
v-model="queryParams.tenantKey"
|
||||
filterable
|
||||
clearable
|
||||
reserve-keyword
|
||||
placeholder="请输入租户Key搜索"
|
||||
:remote-method="loadOptions"
|
||||
:loading="loadingSelect"
|
||||
style="width: 240px"
|
||||
>
|
||||
<!-- 正常列表 -->
|
||||
<el-option
|
||||
v-for="item in agentListSelect"
|
||||
:key="item.tenantKey"
|
||||
:label="item.tenantKey"
|
||||
:value="item.tenantKey"
|
||||
/>
|
||||
|
||||
<!-- 加载更多按钮 -->
|
||||
<el-option
|
||||
v-if="hasMore && agentListSelect.length > 0"
|
||||
disabled
|
||||
value=""
|
||||
>
|
||||
<div
|
||||
style="color:#409EFF;cursor:pointer;width:100%;"
|
||||
@click.stop="loadMore"
|
||||
>
|
||||
{{ loadingMore ? "加载中..." : "加载更多" }}
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('玩家账号')" prop="memberAccount">
|
||||
<el-input
|
||||
|
|
@ -43,9 +77,9 @@
|
|||
<CustomSelect v-if="showLoding3" v-model="queryParams.platformCode" :options="quotaplatformCodeArr" filterable placeholder="请选择平台" style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('操作类型')" prop="operationType">
|
||||
<el-select v-if="operationTypeOption.length > 0" v-model="queryParams.operationType" clearable style="width:220px;" :placeholder="t('请选择')">
|
||||
<el-select v-model="queryParams.operationType" clearable style="width:220px;" :placeholder="t('请选择')">
|
||||
<el-option
|
||||
v-for="dict in operationTypeOption"
|
||||
v-for="dict in operationTypes"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
|
|
@ -236,7 +270,7 @@
|
|||
</template>
|
||||
|
||||
<script setup name="Agent">
|
||||
import { superTenantQuotaflow,superCommonPlatSelect,superTenantQuotaAudit,getSuperCommonOperationType } from "@/api/super/tenant";
|
||||
import { superTenantQuotaflow,superCommonPlatSelect,superTenantQuotaAudit,getSuperCommonOperationType,superTenantList } from "@/api/super/tenant";
|
||||
import Crontab from '@/components/Crontab'
|
||||
import { getLocalStorage } from "@/utils/auth";
|
||||
import CopyIcon from '@/components/CopyIcon'
|
||||
|
|
@ -297,6 +331,18 @@ const dd = String(today.getDate()).padStart(2, '0');
|
|||
}
|
||||
});
|
||||
|
||||
//操作类型
|
||||
const operationTypes = ref([
|
||||
{ label: proxy.t('商户转入转出'), value: 1 },
|
||||
{ label: proxy.t('日用额度结算'), value: 2 },
|
||||
{ label: proxy.t('信誉额度充值'), value: 3 },
|
||||
{ label: proxy.t('后台人工操作'), value: 4 },
|
||||
{ label: proxy.t('商户订单充值'), value: 5 },
|
||||
{ label: proxy.t('转入恢复'), value: 6 },
|
||||
{ label: proxy.t('转出恢复'), value: 7 },
|
||||
|
||||
|
||||
]);
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
const quotaTypeArr = ref([
|
||||
{ label: proxy.t('可用额度'), value: "BALANCE" },
|
||||
|
|
@ -461,9 +507,52 @@ const handleAudit = (row) => {
|
|||
});
|
||||
});
|
||||
};
|
||||
const agentListSelect = ref([])
|
||||
|
||||
|
||||
const loadingSelect = ref(false)
|
||||
|
||||
const loadingMore = ref(false)
|
||||
|
||||
const hasMore = ref(true)
|
||||
|
||||
const queryParamSelect = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
tenantKey: ""
|
||||
})
|
||||
|
||||
// 加载第一页(搜索)
|
||||
const loadOptions = async (query) => {
|
||||
queryParamSelect.value.pageNum = 1
|
||||
queryParamSelect.value.tenantKey = query
|
||||
loadingSelect.value = true
|
||||
try {
|
||||
const res = await superTenantList(queryParamSelect.value)
|
||||
agentListSelect.value = res.rows || []
|
||||
hasMore.value = agentListSelect.value.length < (res.total || 0)
|
||||
} finally {
|
||||
loadingSelect.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 加载更多(分页)
|
||||
const loadMore = async () => {
|
||||
if (!hasMore.value) return
|
||||
queryParamSelect.value.pageNum++
|
||||
loadingMore.value = true
|
||||
try {
|
||||
const res = await superTenantList(queryParamSelect.value)
|
||||
agentListSelect.value = [...agentListSelect.value, ...(res.rows || [])]
|
||||
hasMore.value = agentListSelect.value.length < (res.total || 0)
|
||||
} finally {
|
||||
loadingMore.value = false
|
||||
}
|
||||
}
|
||||
//初始化
|
||||
onMounted(() => {
|
||||
getList();
|
||||
loadOptions('');
|
||||
getsuperCommonCurrencySelect();
|
||||
getSuperCommonOperationTypes();
|
||||
getsuperCommonPlatformTypeSelect();
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@
|
|||
loading.value = true;
|
||||
await passwordForm.value.validate();
|
||||
let objForm = {
|
||||
password:form.value.newPassword
|
||||
newPassword:form.value.newPassword
|
||||
}
|
||||
// 这里添加实际的API调用
|
||||
updateUserPassword(objForm).then(response => {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
<el-table-column label="权限字符" align="center" prop="roleKey" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
<span>{{ formatTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ onActivated(() => {
|
|||
|
||||
// 路由跳转过来
|
||||
if (Object.keys(routeParams).length) {
|
||||
activeName.value = routeParams.activeName || 'auditManage';
|
||||
activeName.value = routeParams.activeName || 'userList';
|
||||
memberAccount.value = routeParams.memberAccount || '';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
</li>
|
||||
<li class="list-group-item">
|
||||
<svg-icon icon-class="date" />创建日期
|
||||
<div class="pull-right">{{ state.user.createTime }}</div>
|
||||
<div class="pull-right">{{ formatTime(state.user.createTime) }}</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="user-info-head" @click="editCropper()">
|
||||
<img :src="options.img" title="点击上传头像" class="img-circle img-lg" />
|
||||
<el-dialog :title="title" align-center v-model="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog">
|
||||
<el-dialog :title="title" v-model="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog">
|
||||
<el-row>
|
||||
<el-col :xs="24" :md="12" :style="{ height: '350px' }">
|
||||
<vue-cropper
|
||||
|
|
@ -63,17 +63,19 @@ import "vue-cropper/dist/index.css";
|
|||
import { VueCropper } from "vue-cropper";
|
||||
import { uploadAvatar } from "@/api/system/user";
|
||||
import useUserStore from "@/store/modules/user";
|
||||
import { getLocalStorage } from "@/utils/auth";
|
||||
|
||||
const userStore = useUserStore();
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const fileHost = getLocalStorage('fileUrl') || ''; // 文件host
|
||||
const open = ref(false);
|
||||
const visible = ref(false);
|
||||
const title = ref("修改头像");
|
||||
|
||||
//图片裁剪数据
|
||||
const options = reactive({
|
||||
img: userStore.avatar, // 裁剪图片的地址
|
||||
img: fileHost + userStore.avatar, // 裁剪图片的地址
|
||||
autoCrop: true, // 是否默认生成截图框
|
||||
autoCropWidth: 200, // 默认生成截图框宽度
|
||||
autoCropHeight: 200, // 默认生成截图框高度
|
||||
|
|
@ -133,7 +135,7 @@ function uploadImg() {
|
|||
formData.append("avatarfile", data, options.filename);
|
||||
uploadAvatar(formData).then(response => {
|
||||
open.value = false;
|
||||
options.img = import.meta.env.VITE_APP_BASE_API + response.imgUrl;
|
||||
options.img = response.imgUrl;
|
||||
userStore.avatar = options.img;
|
||||
proxy.$modal.msgSuccess("修改成功");
|
||||
visible.value = false;
|
||||
|
|
@ -148,7 +150,7 @@ function realTime(data) {
|
|||
|
||||
/** 关闭窗口 */
|
||||
function closeDialog() {
|
||||
options.img = userStore.avatar;
|
||||
options.img = fileHost + userStore.avatar;
|
||||
options.visible = false;
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,221 +0,0 @@
|
|||
# 权限树状表格组件使用说明
|
||||
|
||||
## 概述
|
||||
|
||||
这个权限树状表格组件实现了类似表格的树形权限管理界面,左侧显示树形菜单结构,右侧显示对应的权限复选框,完全符合您截图中的设计需求。
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
src/views/system/user/role/
|
||||
├── render.vue # 核心权限树状表格组件
|
||||
├── permission-dialog.vue # 权限选择对话框组件
|
||||
├── permission-example.vue # 完整使用示例
|
||||
└── README.md # 使用说明
|
||||
```
|
||||
|
||||
## 核心功能
|
||||
|
||||
### 1. 树状表格展示
|
||||
- 表格样式的树形结构展示
|
||||
- 支持多级树形结构
|
||||
- 可展开/收起节点
|
||||
- 支持节点复选框选择(含半选状态)
|
||||
|
||||
### 2. 权限复选框管理
|
||||
- 每个节点可以配置独立的权限项
|
||||
- 权限项以复选框形式展示在右侧
|
||||
- 支持权限项的选中状态管理
|
||||
- 支持热门权限标记
|
||||
|
||||
### 3. 表格式布局
|
||||
- 左侧:菜单名称列(支持树形缩进)
|
||||
- 右侧:权限操作列(权限复选框)
|
||||
- 表格头部标题
|
||||
- 行分隔线和悬停效果
|
||||
|
||||
## 数据结构
|
||||
|
||||
```javascript
|
||||
const treeData = [
|
||||
{
|
||||
id: 1, // 节点唯一标识
|
||||
label: '开站管理', // 节点显示名称
|
||||
children: [ // 子节点(可选)
|
||||
{
|
||||
id: 11,
|
||||
label: '待审核',
|
||||
perms: [] // 权限列表(可选)
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
label: '待付款',
|
||||
perms: [ // 权限项配置
|
||||
{
|
||||
key: 'pay',
|
||||
label: '付款',
|
||||
checked: false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 15,
|
||||
label: '已上线',
|
||||
perms: [
|
||||
{
|
||||
key: 'add_brand',
|
||||
label: '新增子品牌',
|
||||
checked: false,
|
||||
isHot: true // 热门权限标记
|
||||
},
|
||||
{
|
||||
key: 'edit',
|
||||
label: '修改',
|
||||
checked: false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 1. 基础使用
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<PermissionTreeTable ref="treeTableRef" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import PermissionTreeTable from './render.vue'
|
||||
|
||||
const treeTableRef = ref()
|
||||
|
||||
// 获取选中的数据
|
||||
const getSelectedData = () => {
|
||||
if (treeTableRef.value) {
|
||||
return treeTableRef.value.getCheckedData()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
### 2. 对话框形式使用
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<PermissionDialog
|
||||
v-model="dialogVisible"
|
||||
:role-id="currentRoleId"
|
||||
@confirm="handlePermissionConfirm"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import PermissionDialog from './permission-dialog.vue'
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const currentRoleId = ref(1)
|
||||
|
||||
const handlePermissionConfirm = (data) => {
|
||||
console.log('选中的权限:', data)
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## 样式说明
|
||||
|
||||
### 1. 表格式布局
|
||||
- 使用 CSS Grid 布局实现表格效果
|
||||
- 左列:菜单名称(固定宽度 300px)
|
||||
- 右列:权限操作(自适应宽度)
|
||||
- 表格头部和内容分离
|
||||
|
||||
### 2. 主要样式类名
|
||||
- `.permission-tree-table`: 组件容器
|
||||
- `.table-header`: 表格头部
|
||||
- `.table-content`: 表格内容区域
|
||||
- `.table-row`: 每行的容器
|
||||
- `.row-left`: 左侧菜单名称区域
|
||||
- `.row-right`: 右侧权限操作区域
|
||||
- `.expand-icon`: 展开/收起图标
|
||||
- `.hot-tag`: 热门权限标记
|
||||
|
||||
### 3. 核心样式
|
||||
```css
|
||||
.permission-tree-table {
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
display: grid;
|
||||
grid-template-columns: 300px 1fr;
|
||||
background: #f5f7fa;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
display: grid;
|
||||
grid-template-columns: 300px 1fr;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.table-row:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
```
|
||||
|
||||
## API 说明
|
||||
|
||||
### Props
|
||||
- `modelValue`: 对话框显示状态(仅对话框组件)
|
||||
- `roleId`: 角色ID(可选)
|
||||
|
||||
### Events
|
||||
- `confirm`: 确认选择权限时触发,返回选中的权限数据
|
||||
|
||||
### Methods
|
||||
- `getCheckedData()`: 获取当前选中的数据
|
||||
- 返回格式:
|
||||
```javascript
|
||||
{
|
||||
checkedNodes: [ // 选中的节点
|
||||
{ id: 1, label: '开站管理' }
|
||||
],
|
||||
checkedPermissions: { // 选中的权限
|
||||
"12": [
|
||||
{ key: 'pay', label: '付款' }
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 扩展功能
|
||||
|
||||
### 1. 权限标记
|
||||
可以为特定权限添加标记(如"热门"标记):
|
||||
|
||||
```javascript
|
||||
const isHot = perm === '新增子品牌'
|
||||
// 在渲染时添加标记
|
||||
h('span', { class: 'hot-tag' }, '热')
|
||||
```
|
||||
|
||||
### 2. 权限分组
|
||||
可以通过树形结构对权限进行分组管理。
|
||||
|
||||
### 3. 权限搜索
|
||||
可以添加搜索功能来快速定位特定权限。
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 确保每个节点的 `id` 唯一
|
||||
2. `perms` 数组为空时不会显示权限复选框
|
||||
3. 权限状态通过 `permissionState` 响应式对象管理
|
||||
4. 使用 `:deep()` 选择器来修改 Element Plus 组件的默认样式
|
||||
|
|
@ -70,7 +70,7 @@
|
|||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
<span>{{ formatTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
|
|
@ -91,7 +91,7 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="User">
|
||||
<script setup name="AuthUser">
|
||||
import selectUser from "./selectUser";
|
||||
import { allocatedUserList, authUserCancel, authUserCancelAll } from "@/api/system/role";
|
||||
|
||||
|
|
@ -108,7 +108,7 @@ const userIds = ref([]);
|
|||
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
pageSize: 20,
|
||||
roleId: route.params.roleId,
|
||||
userName: undefined,
|
||||
phonenumber: undefined,
|
||||
|
|
|
|||
|
|
@ -1,188 +1,163 @@
|
|||
<template>
|
||||
<el-form :model="queryParams" ref="queryRef" v-show="showSearch" :inline="true" label-width="68px">
|
||||
<el-form-item label="角色名称" prop="roleName">
|
||||
<el-input
|
||||
v-model="queryParams.roleName"
|
||||
placeholder="请输入角色名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="权限字符" prop="roleKey">
|
||||
<el-input
|
||||
v-model="queryParams.roleKey"
|
||||
placeholder="请输入权限字符"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select
|
||||
v-model="queryParams.status"
|
||||
placeholder="角色状态"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in sys_normal_disable"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" style="width: 308px">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
value-format="YYYY-MM-DD"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="Plus"
|
||||
@click="handleAdd"
|
||||
v-hasPermi="['system:role:add']"
|
||||
>新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate"
|
||||
v-hasPermi="['system:role:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
v-hasPermi="['system:role:remove']"
|
||||
>删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleExport"
|
||||
v-hasPermi="['system:role:export']"
|
||||
>导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
|
||||
<template #left>
|
||||
<select-input-form ref="selectInputFormRef" :queryParamsList="queryParamsList" :queryParams="queryParams"
|
||||
@handleQuery="handleQuery">
|
||||
</select-input-form>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:role:add']">新增</el-button>
|
||||
</template>
|
||||
</table-search-card>
|
||||
<el-alert :title="t('提示: 删除权限:后台账号数为0时,才能删除权限')" style="margin-bottom: 10px;" :closable="false" type="warning"
|
||||
show-icon />
|
||||
<!-- 表格数据 -->
|
||||
<el-table v-loading="loading" :data="roleList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="角色编号" prop="roleId" width="120" />
|
||||
<el-table-column label="角色名称" prop="roleName" :show-overflow-tooltip="true" width="150" />
|
||||
<el-table-column label="权限字符" prop="roleKey" :show-overflow-tooltip="true" width="150" />
|
||||
<el-table-column label="显示顺序" prop="roleSort" width="100" />
|
||||
<el-table-column label="状态" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.status"
|
||||
active-value="0"
|
||||
inactive-value="1"
|
||||
@change="handleStatusChange(scope.row)"
|
||||
></el-switch>
|
||||
<el-table v-loading="loading" :data="roleList" ref="tableRef" class="c-table-main" @select="tableSelect"
|
||||
@select-all="tableSelect" stripe border>
|
||||
<el-table-column type="selection" width="55" :selectable="rowSelectable" align="center" />
|
||||
<el-table-column label="权限名称" prop="roleName" min-width="150" align="center" >
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.roleName }} <span v-if="row.defaultStatus == 0">(默认)</span></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
<!-- <el-table-column label="权限类型" prop="roleName" min-width="110" align="center" /> -->
|
||||
<el-table-column label="权限适用范围" prop="roleScope" min-width="150" align="center">
|
||||
<template #default="{ row }">
|
||||
{{ row.roleScope || '--' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<el-table-column label="用户列表" prop="roleSort" min-width="200">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.sysUsers.length > 0">
|
||||
<span v-for="(item, index) in row.sysUsers.slice(0, 5)" :key="item.userId" @click="handleUserListClick(row)" style="color: rgb(64, 158, 255);cursor: pointer;">
|
||||
{{ item.userName }}
|
||||
<span v-if="index < Math.min(5, row.sysUsers.length) - 1">,</span>
|
||||
</span>
|
||||
<span v-if="row.sysUsers.length > 5"> ...</span>
|
||||
</div>
|
||||
<div v-else>--</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="权限数" prop="menuCount" align="center" min-width="80">
|
||||
<template #default="{ row }">
|
||||
{{ row.menuCount || '--' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" prop="remark" min-width="130">
|
||||
<template #default="{ row }">
|
||||
{{ row.remark || '--' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" min-width="200" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top" v-if="scope.row.roleId !== 1">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:role:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top" v-if="scope.row.roleId !== 1">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:role:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="数据权限" placement="top" v-if="scope.row.roleId !== 1">
|
||||
<el-button link type="primary" icon="CircleCheck" @click="handleDataScope(scope.row)" v-hasPermi="['system:role:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="分配用户" placement="top" v-if="scope.row.roleId !== 1">
|
||||
<el-button link type="primary" icon="User" @click="handleAuthUser(scope.row)" v-hasPermi="['system:role:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-button link type="primary" @click="handleDetail(scope.row)" v-hasPermi="['system:role:edit']">{{ t('详情')
|
||||
}}</el-button>
|
||||
<el-button link type="primary" v-if="scope.row.defaultStatus == 1" @click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['system:role:edit']">{{ t('修改') }}</el-button>
|
||||
<el-button link type="primary" @click="handleManage(scope.row)" v-hasPermi="['system:role:edit']">{{ t('管理')
|
||||
}}</el-button>
|
||||
<el-button link type="primary" v-if="scope.row.defaultStatus == 1" @click="handleDelete(scope.row)"
|
||||
v-hasPermi="['system:role:remove']">{{ t('删除') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList" />
|
||||
<!-- 批量操作 -->
|
||||
<table-batch-operate v-if="total > 0" v-model:batchOpType="batchOpType"
|
||||
v-model:isAllSelection="isAllSelection" @allSelectionChange="allSelectionChange" @opTypeChange="opTypeChange"
|
||||
:selectionData="selectionData" :opTypeOptions="opTypeOptions"></table-batch-operate>
|
||||
|
||||
<!-- 添加或修改角色配置对话框 -->
|
||||
<el-dialog :title="title" align-center v-model="open" width="860px" append-to-body>
|
||||
<el-scrollbar max-height="600px">
|
||||
<el-scrollbar max-height="800px">
|
||||
<el-form ref="roleRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-form-item label="角色名称" prop="roleName">
|
||||
<el-input v-model="form.roleName" placeholder="请输入角色名称" />
|
||||
<el-input v-model="form.roleName" :disabled="modifyStatus == 'detail' || modifyStatus == 'Manage'"
|
||||
placeholder="请输入角色名称" maxlength="20" show-word-limit />
|
||||
</el-form-item>
|
||||
<el-form-item prop="roleKey">
|
||||
<template #label>
|
||||
<span>
|
||||
<el-tooltip content="控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasRole('admin')`)" placement="top">
|
||||
<el-icon><question-filled /></el-icon>
|
||||
</el-tooltip>
|
||||
权限字符
|
||||
</span>
|
||||
</template>
|
||||
<el-input v-model="form.roleKey" placeholder="请输入权限字符" />
|
||||
<el-form-item label="权限范围">
|
||||
<el-select disabled v-model="form.dataScope" style="width: 350px;" @change="dataScopeSelectChange">
|
||||
<el-option v-for="item in dataScopeOptions" :key="item.value" :label="item.label"
|
||||
:value="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="角色顺序" prop="roleSort">
|
||||
<el-input-number v-model="form.roleSort" controls-position="right" :min="0" />
|
||||
<el-form-item v-if="modifyStatus == 'add'" label="复制权限">
|
||||
<el-select v-model="form.copyRoleId" style="width: 350px;" clearable @change="changeMenu">
|
||||
<el-option v-for="item in roleOptions" :key="item.value" :label="item.label"
|
||||
:value="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="角色等级" prop="roleLevel">
|
||||
<NumberInput v-model="form.roleLevel" :placeholder="t('数字越高级别越高')" style="width: 200px;"></NumberInput>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="form.remark" :disabled="modifyStatus == 'detail' || modifyStatus == 'Manage'"
|
||||
type="textarea" placeholder="请输入内容"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio
|
||||
v-for="dict in sys_normal_disable"
|
||||
:key="dict.value"
|
||||
:value="dict.value"
|
||||
>{{ dict.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
<el-form-item v-if="modifyStatus == 'Manage'" label="添加账号">
|
||||
<el-row style="width: 100%;">
|
||||
<el-col :span="16">
|
||||
<div style="width: 100%;">
|
||||
<checkbox-select v-if="showLoding" collapse-tags collapse-tags-tooltip style="width: 100%;" v-model="accountLinking"
|
||||
:options="accountOptions" :placeholder="t('请选择账号进行权限关联')"></checkbox-select>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8" style="display: flex;justify-content: right;">
|
||||
<div style="margin-left: 10px;">
|
||||
<el-button type="primary" @click="handleAddAccount">{{ t('添加账户') }}</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="sysUsersArr.length > 0" style="width: 100%;margin-top: 20px;">
|
||||
<el-col :span="20">
|
||||
<div style="width: 100%;">
|
||||
<el-input v-model="userNameText" style="width: 100%" :placeholder="t('输入关键字进行用户列表过滤,支持空格隔开的多关键字匹配')" @input="handleFilter" />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="4" style="display: flex;justify-content: right;">
|
||||
<div style="margin-left: 10px;">
|
||||
<el-button type="primary" @click="handleRemoveAccount">{{ t('移出账户') }}</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="accounts-about-scroll-container" v-if="sysUsersArr.length > 0">
|
||||
<el-tag v-for="(item,index) in form.sysUsers" :key="item.userId" closable type="info" style="margin-right: 10px;" @close="handleClose(item)">
|
||||
{{ item.userName }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单权限">
|
||||
<!-- <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox> -->
|
||||
<el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
|
||||
<el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">父子联动</el-checkbox>
|
||||
|
||||
<div style="display: flex;">
|
||||
<div style="font-size: 14px;font-weight: 600;">{{ t('权限设置') }}</div>
|
||||
<div style="margin-left: 10px;">{{ t('权限数') }}:{{ countTree }}</div>
|
||||
<div @click="handleCheckedTreeExpand($event, 'menu')"
|
||||
style="cursor: pointer;color: rgb(64, 158, 255);margin-left: 10px;">
|
||||
<span v-if="!defaultExpandAll">{{ t('全部展开') }}</span>
|
||||
<span v-if="defaultExpandAll">{{ t('全部收起') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 100%;margin-top: 10px;">
|
||||
<el-input v-model="filterText" style="width: 100%" :placeholder="t('输入关键字进行权限过滤,支持空格隔开的多关键字匹配')" />
|
||||
</div>
|
||||
<div style="margin-top: 10px;">
|
||||
<el-checkbox v-model="menuNodeAll" :disabled="modifyStatus == 'Manage' || modifyStatus == 'detail'"
|
||||
@change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
|
||||
<el-checkbox v-model="form.menuCheckStrictly" :disabled="modifyStatus == 'Manage' || modifyStatus == 'detail'"
|
||||
@change="handleCheckedTreeConnect($event, 'menu')">父子联动</el-checkbox>
|
||||
<div class="table">
|
||||
<div class="menu-list">
|
||||
<el-tree ref="menuRef" :data="menuOptions" default-expand-all :expand-on-click-node='false' check-on-click-node show-checkbox node-key="id"
|
||||
:check-strictly="!form.menuCheckStrictly" :props="{ label: 'label', children: 'children' }"></el-tree>
|
||||
<el-tree ref="menuRef" :data="menuOptions" v-if="defaultExpandShow" :default-expand-all="defaultExpandAll"
|
||||
:expand-on-click-node='false' check-on-click-node show-checkbox node-key="id"
|
||||
:check-strictly="!form.menuCheckStrictly"
|
||||
:props="{ label: 'label', children: 'children', disabled: (data, node) => modifyStatus == 'Manage' || modifyStatus == 'detail', }"
|
||||
:filter-node-method="filterNode"></el-tree>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <el-form-item label="菜单权限">
|
||||
<el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>
|
||||
|
||||
<!-- <el-tree
|
||||
|
||||
<el-tree
|
||||
class="tree-border"
|
||||
:data="menuOptions"
|
||||
show-checkbox
|
||||
|
|
@ -192,21 +167,47 @@
|
|||
empty-text="加载中,请稍候"
|
||||
:render-content="renderContent"
|
||||
:props="{ label: 'label', children: 'children' }"
|
||||
></el-tree> -->
|
||||
></el-tree>
|
||||
</el-form-item> -->
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
<template #footer>
|
||||
<div class="dialog-footer" style="display: flex;justify-content: center;">
|
||||
<el-button v-if="modifyStatus == 'detail' || modifyStatus == 'Manage'" @click="cancel">关 闭</el-button>
|
||||
<el-button v-if="modifyStatus == 'add' || modifyStatus == 'edit'" type="primary" @click="submitForm">确
|
||||
定</el-button>
|
||||
<el-button v-if="modifyStatus == 'add' || modifyStatus == 'edit'" @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog :title="t('用户列表')" align-center v-model="openUserList" width="1050px" append-to-body>
|
||||
<el-scrollbar max-height="800px">
|
||||
<el-form ref="roleRef" label-width="100px">
|
||||
<el-form-item label="权限名称">
|
||||
{{ formUserList.roleName }}<span v-if="formUserList.defaultStatus == 0">(默认)</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
|
||||
<el-form-item label="用户列表">
|
||||
<el-row v-if="sysUsersArr.length > 0" style="width: 100%;margin-top: 20px;">
|
||||
<el-col :span="24">
|
||||
<div style="width: 100%;">
|
||||
<el-input v-model="userListText" style="width: 100%" :placeholder="t('输入关键字进行用户列表过滤,支持空格隔开的多关键字匹配')" @input="handleUserListFilter" />
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="accounts-about-scroll-container" v-if="sysUsersArr.length > 0">
|
||||
<el-tag v-for="(item,index) in formUserList.sysUsers" :key="item.userId" type="info" style="margin-right: 10px;" >
|
||||
{{ item.userName }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
<div class="dialog-footer" style="display: flex;justify-content: center;">
|
||||
<el-button @click="cancelUserList">关 闭</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 分配角色数据权限对话框 -->
|
||||
<el-dialog :title="title" align-center v-model="openDataScope" width="500px" append-to-body>
|
||||
<el-form :model="form" label-width="80px">
|
||||
|
|
@ -217,30 +218,19 @@
|
|||
<el-input v-model="form.roleKey" :disabled="true" />
|
||||
</el-form-item>
|
||||
<el-form-item label="权限范围">
|
||||
<el-select v-model="form.dataScope" @change="dataScopeSelectChange">
|
||||
<el-option
|
||||
v-for="item in dataScopeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
<el-select @change="dataScopeSelectChange">
|
||||
<el-option v-for="item in dataScopeOptions" :key="item.value" :label="item.label"
|
||||
:value="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="数据权限" v-show="form.dataScope == 2">
|
||||
<el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event, 'dept')">展开/折叠</el-checkbox>
|
||||
<el-checkbox v-model="deptNodeAll" @change="handleCheckedTreeNodeAll($event, 'dept')">全选/全不选</el-checkbox>
|
||||
<el-checkbox v-model="form.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'dept')">父子联动</el-checkbox>
|
||||
<el-tree
|
||||
class="tree-border"
|
||||
:data="deptOptions"
|
||||
show-checkbox
|
||||
default-expand-all
|
||||
ref="deptRef"
|
||||
node-key="id"
|
||||
:check-strictly="!form.deptCheckStrictly"
|
||||
empty-text="加载中,请稍候"
|
||||
:props="{ label: 'label', children: 'children' }"
|
||||
></el-tree>
|
||||
<el-checkbox v-model="form.deptCheckStrictly"
|
||||
@change="handleCheckedTreeConnect($event, 'dept')">父子联动</el-checkbox>
|
||||
<el-tree class="tree-border" :data="deptOptions" show-checkbox default-expand-all ref="deptRef" node-key="id"
|
||||
:check-strictly="!form.deptCheckStrictly" empty-text="加载中,请稍候"
|
||||
:props="{ label: 'label', children: 'children' }"></el-tree>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
|
|
@ -253,14 +243,18 @@
|
|||
</template>
|
||||
|
||||
<script setup name="User">
|
||||
import { addRole, changeRoleStatus, dataScope, delRole, getRole, listRole, updateRole, deptTreeSelect } from "@/api/system/role";
|
||||
import { addRole, changeRoleStatus, dataScope, delRole, getRole, listRole, updateRole, deptTreeSelect, optionselect, getMenu, unallocatedUserList,authUserSelectAll,authUserCancelAll,authUserCancel,authRolecancelAll } from "@/api/system/role";
|
||||
import { roleMenuTreeselect, treeselect as menuTreeselect } from "@/api/system/menu";
|
||||
import NumberInput from "@/components/NumberInput";
|
||||
import Render from "./render.vue";
|
||||
import TableBatchOperate from '@/components/TableBatchOperate'; // 批量操作
|
||||
import CheckboxSelect from "@/components/CheckboxSelect"; // 下拉框多/全选
|
||||
import { formatTime } from '@/utils/ruoyi';
|
||||
import SelectInputForm from '@/components/SelectInputForm';
|
||||
import { nextTick, ref } from "vue";
|
||||
const router = useRouter();
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
||||
|
||||
import { getLocalStorage } from "@/utils/auth";
|
||||
const roleList = ref([]);
|
||||
const open = ref(false);
|
||||
const loading = ref(true);
|
||||
|
|
@ -280,6 +274,23 @@ const deptOptions = ref([]);
|
|||
const openDataScope = ref(false);
|
||||
const menuRef = ref(null);
|
||||
const deptRef = ref(null);
|
||||
const filterText = ref('');
|
||||
const modifyStatus = ref('add');
|
||||
const accountLinking = ref([]);
|
||||
const accountOptions = ref([]);
|
||||
const sysUsersArr = ref([]);
|
||||
const formUserList = ref({});
|
||||
const oldForm = shallowRef({ });
|
||||
const queryParamsList = ref([{
|
||||
label: proxy.t('角色名称'),
|
||||
value: 'roleName',
|
||||
}, {
|
||||
label: proxy.t('后台账户'),
|
||||
value: 'account',
|
||||
}, {
|
||||
label: proxy.t('后台呢称'),
|
||||
value: 'nickName',
|
||||
}])
|
||||
|
||||
/** 数据范围选项*/
|
||||
const dataScopeOptions = ref([
|
||||
|
|
@ -293,7 +304,8 @@ const data = reactive({
|
|||
form: {},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
pageSize: 20,
|
||||
searchType: 'roleName',
|
||||
roleName: undefined,
|
||||
roleKey: undefined,
|
||||
status: undefined
|
||||
|
|
@ -307,7 +319,67 @@ const data = reactive({
|
|||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
// 批量操作
|
||||
const tableRef = ref(),
|
||||
isAllSelection = ref(false), // 是否全选
|
||||
selectionData = ref([]), // 选中的表格数据
|
||||
batchOpType = ref(''); // 选中的批量操作类型
|
||||
// 批量操作选项
|
||||
const opTypeOptions = ref([
|
||||
{ label: proxy.t('批量清除关联账户'), value: 'update' },
|
||||
{ label: proxy.t('批量删除'), value: 'ignore' },
|
||||
]);
|
||||
|
||||
// 勾选表格
|
||||
const tableSelect = (val) => {
|
||||
selectionData.value = val;
|
||||
// 是否全选中
|
||||
if (val.length == roleList.value.length) {
|
||||
isAllSelection.value = true;
|
||||
} else {
|
||||
isAllSelection.value = false;
|
||||
}
|
||||
}
|
||||
// 全选表格
|
||||
const allSelectionChange = () => {
|
||||
tableRef.value.toggleAllSelection();
|
||||
}
|
||||
// 选择批量数据操作类型
|
||||
const opTypeChange = () => {
|
||||
if (batchOpType.value === 'ignore') {
|
||||
const params = selectionData.value.map(i => i.roleId); // 选中的id集合
|
||||
proxy.$modal.confirm(proxy.t('确认批量删除已选的' + params.length + '条记录吗?')).then(() => {
|
||||
loading.value = true;
|
||||
delRole(params).then(res => {
|
||||
loading.value = false;
|
||||
batchOpType.value = '';
|
||||
proxy.$modal.msgSuccess(proxy.t('操作成功!'));
|
||||
handleQuery();
|
||||
}).catch(() => {
|
||||
batchOpType.value = '';
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => {
|
||||
batchOpType.value = '';
|
||||
});
|
||||
}else if (batchOpType.value === 'update') {
|
||||
const params = selectionData.value.map(i => i.roleId); // 选中的id集合
|
||||
proxy.$modal.confirm(proxy.t(`确认清除这些权限的关联账号(共${params.length}个)?`)).then(() => {
|
||||
loading.value = true;
|
||||
authRolecancelAll({roleIds: params}).then(res => {
|
||||
loading.value = false;
|
||||
batchOpType.value = '';
|
||||
proxy.$modal.msgSuccess(proxy.t('操作成功!'));
|
||||
handleQuery();
|
||||
}).catch(() => {
|
||||
batchOpType.value = '';
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => {
|
||||
batchOpType.value = '';
|
||||
});
|
||||
}
|
||||
}
|
||||
/** 查询角色列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
|
|
@ -318,6 +390,31 @@ function getList() {
|
|||
});
|
||||
}
|
||||
|
||||
// 监听输入框,调用 el-tree 的 filter
|
||||
watch(filterText, (val) => {
|
||||
menuRef.value && menuRef.value.filter(val);
|
||||
});
|
||||
const rowSelectable = (row, index) => {
|
||||
return row.defaultStatus == 0 ? false:true;
|
||||
}
|
||||
|
||||
const openUserList = ref(false);
|
||||
//打开用户列表
|
||||
const handleUserListClick = (row) => {
|
||||
openUserList.value = true;
|
||||
sysUsersArr.value = row.sysUsers;
|
||||
formUserList.value = row;
|
||||
};
|
||||
const cancelUserList = () => {
|
||||
openUserList.value = false;
|
||||
}
|
||||
// 节点过滤方法
|
||||
const filterNode = (value, data) => {
|
||||
if (!value) return true;
|
||||
// 支持多关键字,用空格分隔
|
||||
const keywords = value.split(" ");
|
||||
return keywords.every((kw) => data.label.includes(kw));
|
||||
};
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
queryParams.value.pageNum = 1;
|
||||
|
|
@ -339,7 +436,7 @@ function handleDelete(row) {
|
|||
}).then(() => {
|
||||
getList();
|
||||
proxy.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
}).catch(() => { });
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
|
|
@ -387,14 +484,115 @@ function handleCommand(command, row) {
|
|||
function handleAuthUser(row) {
|
||||
router.push("/system/role-auth/user/" + row.roleId);
|
||||
}
|
||||
|
||||
const countTree = ref(0);
|
||||
/** 查询菜单树结构 */
|
||||
function getMenuTreeselect() {
|
||||
menuTreeselect().then(response => {
|
||||
countTree.value = response.count;
|
||||
menuOptions.value = response.data;
|
||||
});
|
||||
}
|
||||
const showLoding = ref(true);
|
||||
/** 获取用户列表 */
|
||||
const getunallocatedUserList = (roleId) => {
|
||||
unallocatedUserList({roleId: roleId }).then(response => {
|
||||
accountOptions.value = response.data.map(item => {
|
||||
return {
|
||||
...item,
|
||||
label: item.userName,
|
||||
value: item.userId
|
||||
}
|
||||
});
|
||||
showLoding.value = false;
|
||||
nextTick(() => {
|
||||
showLoding.value = true;
|
||||
})
|
||||
});
|
||||
}
|
||||
//添加关联账户
|
||||
const handleAddAccount = () => {
|
||||
if (accountLinking.value.length == 0){
|
||||
proxy.$modal.msgError(proxy.t('请选择要关联的账户'));
|
||||
return;
|
||||
}
|
||||
proxy.$modal.confirm('请确认此操作,是否继续?').then(function () {
|
||||
let obj = {
|
||||
roleId:form.value.roleId,
|
||||
userIds:accountLinking.value
|
||||
}
|
||||
return authUserSelectAll(obj);
|
||||
}).then(() => {
|
||||
getRole(form.value.roleId).then(response => {
|
||||
form.value = response.data;
|
||||
sysUsersArr.value = response.data.sysUsers;
|
||||
});
|
||||
accountLinking.value = [];
|
||||
getunallocatedUserList(form.value.roleId);
|
||||
handleQuery();
|
||||
proxy.$modal.msgSuccess("关联成功");
|
||||
}).catch(() => { });
|
||||
}
|
||||
const userNameText = ref('');
|
||||
//片段2
|
||||
const handleFilter = () => {
|
||||
if (!userNameText.value.trim()) return form.value.sysUsers = sysUsersArr.value
|
||||
|
||||
const keywords = userNameText.value.trim().split(/\s+/) // 支持空格分隔多个关键词
|
||||
form.value.sysUsers = sysUsersArr.value.filter(user =>
|
||||
keywords.every(k => user.userName.includes(k))
|
||||
)
|
||||
}
|
||||
const userListText = ref('');
|
||||
//
|
||||
const handleUserListFilter = () => {
|
||||
if (!userListText.value.trim()) return formUserList.value.sysUsers = sysUsersArr.value
|
||||
const keywords = userListText.value.trim().split(/\s+/) // 支持空格分隔多个关键词
|
||||
formUserList.value.sysUsers = sysUsersArr.value.filter(user =>
|
||||
keywords.every(k => user.userName.includes(k))
|
||||
)
|
||||
}
|
||||
//移出关联账户
|
||||
const handleRemoveAccount = () => {
|
||||
if (form.value.sysUsers.length == 0){
|
||||
proxy.$modal.msgError("请选择要移出的账户");
|
||||
return
|
||||
}
|
||||
proxy.$modal.confirm('请确认此操作,是否继续?').then(function () {
|
||||
let userIds = form.value.sysUsers.map(item => item.userId);
|
||||
let obj = {
|
||||
roleId:form.value.roleId,
|
||||
userIds:userIds
|
||||
}
|
||||
return authUserCancelAll(obj);
|
||||
}).then(() => {
|
||||
getRole(form.value.roleId).then(response => {
|
||||
form.value = response.data;
|
||||
sysUsersArr.value = response.data.sysUsers;
|
||||
});
|
||||
handleQuery();
|
||||
getunallocatedUserList(form.value.roleId);
|
||||
proxy.$modal.msgSuccess("移出成功");
|
||||
}).catch(() => { });
|
||||
}
|
||||
//单个移出关联账户
|
||||
const handleClose = (row) => {
|
||||
proxy.$modal.confirm('请确认此操作,是否继续?').then(function () {
|
||||
let userIds = form.value.sysUsers.map(item => item.userId);
|
||||
let obj = {
|
||||
roleId:form.value.roleId,
|
||||
userId:row.userId
|
||||
}
|
||||
return authUserCancel(obj);
|
||||
}).then(() => {
|
||||
getRole(form.value.roleId).then(response => {
|
||||
form.value = response.data;
|
||||
sysUsersArr.value = response.data.sysUsers;
|
||||
});
|
||||
handleQuery();
|
||||
getunallocatedUserList(form.value.roleId);
|
||||
proxy.$modal.msgSuccess("移出成功");
|
||||
}).catch(() => { });
|
||||
}
|
||||
/** 所有部门节点数据 */
|
||||
function getDeptAllCheckedKeys() {
|
||||
// 目前被选中的部门节点
|
||||
|
|
@ -428,15 +626,94 @@ function reset() {
|
|||
};
|
||||
proxy.resetForm("roleRef");
|
||||
}
|
||||
|
||||
const roleOptions = ref([]);
|
||||
/** 添加角色 */
|
||||
function handleAdd() {
|
||||
reset();
|
||||
getMenuTreeselect();
|
||||
open.value = true;
|
||||
title.value = "添加角色";
|
||||
title.value = "新增角色";
|
||||
modifyStatus.value = 'add';
|
||||
form.value.dataScope = getLocalStorage('userInfo')?.nickName;
|
||||
optionselect({}).then(response => {
|
||||
roleOptions.value = response.data.map(item => {
|
||||
return {
|
||||
...item,
|
||||
label: item.roleName,
|
||||
value: item.roleId
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
//
|
||||
const handleDetail = (row) => {
|
||||
reset();
|
||||
const roleId = row.roleId || ids.value;
|
||||
const roleMenu = getRoleMenuTreeselect(roleId);
|
||||
getRole(roleId).then(response => {
|
||||
form.value = response.data;
|
||||
form.value.roleSort = Number(form.value.roleSort);
|
||||
open.value = true;
|
||||
nextTick(() => {
|
||||
roleMenu.then((res) => {
|
||||
let checkedKeys = res.checkedKeys;
|
||||
checkedKeys.forEach((v) => {
|
||||
nextTick(() => {
|
||||
menuRef.value.setChecked(v, true, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
form.value.dataScope = response.data.roleScope;
|
||||
modifyStatus.value = 'detail';
|
||||
title.value = "角色详情";
|
||||
});
|
||||
}
|
||||
|
||||
// 角色管理
|
||||
const handleManage = (row) => {
|
||||
reset();
|
||||
const roleId = row.roleId || ids.value;
|
||||
const roleMenu = getRoleMenuTreeselect(roleId);
|
||||
getunallocatedUserList(roleId);
|
||||
getRole(roleId).then(response => {
|
||||
form.value = response.data;
|
||||
sysUsersArr.value = response.data.sysUsers;
|
||||
form.value.roleSort = Number(form.value.roleSort);
|
||||
open.value = true;
|
||||
nextTick(() => {
|
||||
roleMenu.then((res) => {
|
||||
let checkedKeys = res.checkedKeys;
|
||||
checkedKeys.forEach((v) => {
|
||||
nextTick(() => {
|
||||
menuRef.value.setChecked(v, true, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
form.value.dataScope = response.data.roleScope;
|
||||
modifyStatus.value = 'Manage';
|
||||
title.value = "角色管理";
|
||||
form.value.roleId = row.roleId;
|
||||
});
|
||||
}
|
||||
//复制权限
|
||||
const changeMenu = (roleId) => {
|
||||
if (roleId) {
|
||||
getMenu(roleId).then(response => {
|
||||
let checkedKeys = response.data;
|
||||
checkedKeys.forEach((v) => {
|
||||
nextTick(() => {
|
||||
menuRef.value.setChecked(v, true, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
menuRef.value.setCheckedKeys([]);
|
||||
}
|
||||
|
||||
}
|
||||
/** 修改角色 */
|
||||
function handleUpdate(row) {
|
||||
reset();
|
||||
|
|
@ -456,6 +733,13 @@ function handleUpdate(row) {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
form.value.menuIds = getMenuAllCheckedKeys();
|
||||
oldForm.value = JSON.stringify(form.value);
|
||||
}, 600);
|
||||
form.value.dataScope = response.data.roleScope;
|
||||
modifyStatus.value = 'edit';
|
||||
title.value = "修改角色";
|
||||
});
|
||||
}
|
||||
|
|
@ -475,14 +759,25 @@ function getDeptTree(roleId) {
|
|||
return response;
|
||||
});
|
||||
}
|
||||
|
||||
const defaultExpandAll = ref(false);
|
||||
const defaultExpandShow = ref(true);
|
||||
/** 树权限(展开/折叠)*/
|
||||
function handleCheckedTreeExpand(value, type) {
|
||||
if (type == "menu") {
|
||||
let treeList = menuOptions.value;
|
||||
for (let i = 0; i < treeList.length; i++) {
|
||||
menuRef.value.store.nodesMap[treeList[i].id].expanded = value;
|
||||
|
||||
// let treeList = menuOptions.value;
|
||||
// for (let i = 0; i < treeList.length; i++) {
|
||||
// menuRef.value.store.nodesMap[treeList[i].id].expanded = value;
|
||||
// }
|
||||
if (!defaultExpandAll.value) {
|
||||
defaultExpandAll.value = true;
|
||||
} else {
|
||||
defaultExpandAll.value = false;
|
||||
}
|
||||
defaultExpandShow.value = false;
|
||||
nextTick(() => {
|
||||
defaultExpandShow.value = true;
|
||||
});
|
||||
} else if (type == "dept") {
|
||||
let treeList = deptOptions.value;
|
||||
for (let i = 0; i < treeList.length; i++) {
|
||||
|
|
@ -525,14 +820,32 @@ function submitForm() {
|
|||
if (valid) {
|
||||
if (form.value.roleId != undefined) {
|
||||
form.value.menuIds = getMenuAllCheckedKeys();
|
||||
updateRole(form.value).then(response => {
|
||||
|
||||
if (JSON.stringify(form.value) != oldForm.value) {
|
||||
let params = {
|
||||
menuIds: form.value.menuIds,
|
||||
roleName: form.value.roleName,
|
||||
remark: form.value.remark,
|
||||
roleSort: form.value.roleSort,
|
||||
roleId: form.value.roleId,
|
||||
};
|
||||
updateRole(params).then(response => {
|
||||
proxy.$modal.msgSuccess("修改成功");
|
||||
open.value = false;
|
||||
getList();
|
||||
});
|
||||
}else{
|
||||
open.value = false;
|
||||
}
|
||||
} else {
|
||||
form.value.menuIds = getMenuAllCheckedKeys();
|
||||
addRole(form.value).then(response => {
|
||||
let params = {
|
||||
menuIds: form.value.menuIds,
|
||||
roleName: form.value.roleName,
|
||||
remark: form.value.remark,
|
||||
roleSort: form.value.roleSort,
|
||||
};
|
||||
addRole(params).then(response => {
|
||||
proxy.$modal.msgSuccess("新增成功");
|
||||
open.value = false;
|
||||
getList();
|
||||
|
|
@ -592,8 +905,10 @@ function cancelDataScope() {
|
|||
openDataScope.value = false;
|
||||
reset();
|
||||
}
|
||||
|
||||
getList();
|
||||
//初始化
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.custom-node-row {
|
||||
|
|
@ -622,6 +937,7 @@ getList();
|
|||
width: 240px;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.table {
|
||||
// padding: 20px;
|
||||
// min-height: 88vh;
|
||||
|
|
@ -629,39 +945,51 @@ getList();
|
|||
width: 100%;
|
||||
// margin: 20px;
|
||||
}
|
||||
|
||||
.menu-list {
|
||||
::v-deep .el-tree {
|
||||
border-top: 1px solid #ebeef5;
|
||||
border-left: 1px solid #ebeef5;
|
||||
border-right: 1px solid #ebeef5;
|
||||
|
||||
.el-tree-node__expand-icon {
|
||||
// display: none !important;
|
||||
}
|
||||
|
||||
.el-tree-node {
|
||||
|
||||
&.is-expanded,
|
||||
&.is-current,
|
||||
&.is-focusable {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.el-tree-node__content {
|
||||
background-color: transparent !important;
|
||||
|
||||
&:hover {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
> .el-tree-node {
|
||||
|
||||
>.el-tree-node {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
position: relative;
|
||||
> .el-tree-node__content {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
|
||||
>.el-tree-node__content {
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
padding-left: 20px !important;
|
||||
}
|
||||
|
||||
.el-tree-node__children {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: ' ';
|
||||
display: block;
|
||||
|
|
@ -672,6 +1000,7 @@ getList();
|
|||
left: 0px;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
.el-tree-node {
|
||||
// width: 350px;
|
||||
padding: 10px 0px;
|
||||
|
|
@ -683,4 +1012,16 @@ getList();
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.accounts-about-scroll-container {
|
||||
align-items: flex-start;
|
||||
content-visibility: auto;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
margin-top: 10px;
|
||||
max-height: 100px;
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,78 +0,0 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
align-center
|
||||
title="新增权限"
|
||||
width="800px"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<div class="permission-dialog">
|
||||
<PermissionTreeTable ref="treeTableRef" />
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirm">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import PermissionTreeTable from './render.vue'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
roleId: {
|
||||
type: [String, Number],
|
||||
default: null
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'confirm'])
|
||||
|
||||
const treeTableRef = ref()
|
||||
|
||||
const dialogVisible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val) => emit('update:modelValue', val)
|
||||
})
|
||||
|
||||
// 获取选中的权限数据
|
||||
const getSelectedPermissions = () => {
|
||||
if (treeTableRef.value) {
|
||||
return treeTableRef.value.getCheckedData()
|
||||
}
|
||||
return { checkedNodes: [], checkedPermissions: {} }
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
dialogVisible.value = false
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
dialogVisible.value = false
|
||||
}
|
||||
|
||||
const handleConfirm = () => {
|
||||
const selectedData = getSelectedPermissions()
|
||||
emit('confirm', selectedData)
|
||||
dialogVisible.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.permission-dialog {
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,195 +0,0 @@
|
|||
<template>
|
||||
<div class="permission-example">
|
||||
<div class="header">
|
||||
<h2>权限树使用示例</h2>
|
||||
<el-button type="primary" @click="showPermissionDialog">
|
||||
新增权限
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 权限对话框 -->
|
||||
<PermissionDialog
|
||||
v-model="dialogVisible"
|
||||
:role-id="currentRoleId"
|
||||
@confirm="handlePermissionConfirm"
|
||||
/>
|
||||
|
||||
<!-- 直接展示权限树状表格 -->
|
||||
<div class="tree-container">
|
||||
<h3>权限树状表格展示:</h3>
|
||||
<PermissionTreeTable ref="treeTableRef" />
|
||||
|
||||
<div class="action-buttons">
|
||||
<el-button @click="getSelectedData">获取选中数据</el-button>
|
||||
<el-button type="primary" @click="savePermissions">保存权限</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 已选权限展示 -->
|
||||
<div v-if="selectedData" class="selected-permissions">
|
||||
<h3>已选择的权限:</h3>
|
||||
|
||||
<div class="permission-summary">
|
||||
<div class="section">
|
||||
<h4>选中的节点:</h4>
|
||||
<div class="node-list">
|
||||
<el-tag
|
||||
v-for="node in selectedData.checkedNodes"
|
||||
:key="node.id"
|
||||
size="small"
|
||||
class="node-tag"
|
||||
>
|
||||
{{ node.label }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h4>选中的权限:</h4>
|
||||
<div v-for="(perms, nodeId) in selectedData.checkedPermissions" :key="nodeId" class="node-permissions">
|
||||
<strong>节点 {{ nodeId }}:</strong>
|
||||
<el-tag
|
||||
v-for="perm in perms"
|
||||
:key="perm.key"
|
||||
size="small"
|
||||
type="success"
|
||||
class="perm-tag"
|
||||
>
|
||||
{{ perm.label }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import PermissionDialog from './permission-dialog.vue'
|
||||
import PermissionTreeTable from './render.vue'
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const currentRoleId = ref(1)
|
||||
const selectedData = ref(null)
|
||||
const treeTableRef = ref()
|
||||
|
||||
const showPermissionDialog = () => {
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const handlePermissionConfirm = (data) => {
|
||||
console.log('确认选择的权限:', data)
|
||||
selectedData.value = data
|
||||
|
||||
// 这里可以调用API保存权限
|
||||
// await saveRolePermissions(currentRoleId.value, data)
|
||||
}
|
||||
|
||||
const getSelectedData = () => {
|
||||
if (treeTableRef.value) {
|
||||
const data = treeTableRef.value.getCheckedData()
|
||||
selectedData.value = data
|
||||
console.log('当前选中的数据:', data)
|
||||
}
|
||||
}
|
||||
|
||||
const savePermissions = async () => {
|
||||
const data = getSelectedData()
|
||||
if (data) {
|
||||
try {
|
||||
// 这里调用保存权限的API
|
||||
// await saveRolePermissions(currentRoleId.value, data)
|
||||
console.log('保存权限成功:', data)
|
||||
// 显示成功消息
|
||||
// ElMessage.success('权限保存成功')
|
||||
} catch (error) {
|
||||
console.error('保存权限失败:', error)
|
||||
// ElMessage.error('权限保存失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.permission-example {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.tree-container {
|
||||
margin-bottom: 30px;
|
||||
padding: 20px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
margin-top: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.action-buttons .el-button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.selected-permissions {
|
||||
margin-top: 20px;
|
||||
padding: 20px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.permission-summary {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.section h4 {
|
||||
margin: 0 0 10px 0;
|
||||
color: #303133;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.node-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.node-permissions {
|
||||
margin-bottom: 15px;
|
||||
padding: 10px;
|
||||
background: white;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.node-permissions strong {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
color: #303133;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.node-tag,
|
||||
.perm-tag {
|
||||
margin-right: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.node-tag {
|
||||
background-color: #409eff;
|
||||
border-color: #409eff;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,588 +0,0 @@
|
|||
<template>
|
||||
<div class="table">
|
||||
<!-- default-expand-all 默认展开全部数据 -->
|
||||
<!-- expand-on-click-node 只有点击箭头才会收缩节点 -->
|
||||
<!-- check-on-click-node 点击文本选中 -->
|
||||
<!-- show-checkbox 复选框 -->
|
||||
<div class="menu-list">
|
||||
<el-tree ref="tree" :data="list" default-expand-all :expand-on-click-node='false' check-on-click-node show-checkbox node-key="menuId" :props="defaultProps"></el-tree>
|
||||
</div>
|
||||
<el-button @click="getCheckedKeys">通过 key 获取</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
list: [
|
||||
{
|
||||
"menuId": 1,
|
||||
"menuName": "首页(首页)",
|
||||
"menuCode": "首页",
|
||||
"parentId": 0,
|
||||
"orderNum": 0,
|
||||
"path": "/page",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 0,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "iconfont icon-shouye",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 1,
|
||||
"children": [
|
||||
{
|
||||
"menuId": 2,
|
||||
"menuName": "首页(首页)",
|
||||
"menuCode": "首页",
|
||||
"parentId": 1,
|
||||
"orderNum": 1,
|
||||
"path": "/welcome",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"menuId": 3,
|
||||
"menuName": "随访数据查询(随访数据查询)",
|
||||
"menuCode": "随访数据查询",
|
||||
"parentId": 0,
|
||||
"orderNum": 1,
|
||||
"path": "/followUpDataQuery",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 0,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "iconfont icon-shengwuxuejiance",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 1,
|
||||
"children": [
|
||||
{
|
||||
"menuId": 4,
|
||||
"menuName": "随访数据查询(随访数据查询)",
|
||||
"menuCode": "随访数据查询",
|
||||
"parentId": 3,
|
||||
"orderNum": 1,
|
||||
"path": "index",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"menuId": 5,
|
||||
"menuName": "随访详情(随访详情)",
|
||||
"menuCode": "随访详情",
|
||||
"parentId": 3,
|
||||
"orderNum": 2,
|
||||
"path": "detail",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"menuId": 21,
|
||||
"menuName": "此单名称(11)",
|
||||
"menuCode": "11",
|
||||
"parentId": 0,
|
||||
"orderNum": 1,
|
||||
"path": "请问请问饿```",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 0,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "321",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 1,
|
||||
// "children": null
|
||||
},
|
||||
{
|
||||
"menuId": 6,
|
||||
"menuName": "调查数据查询(调查数据查询)",
|
||||
"menuCode": "调查数据查询",
|
||||
"parentId": 0,
|
||||
"orderNum": 2,
|
||||
"path": "/surveyDataQuery",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 0,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "iconfont icon-shaichaxinxichaxun",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 1,
|
||||
"children": [
|
||||
{
|
||||
"menuId": 7,
|
||||
"menuName": "调查数据查询(调查数据查询)",
|
||||
"menuCode": "调查数据查询",
|
||||
"parentId": 6,
|
||||
"orderNum": 1,
|
||||
"path": "index",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"menuId": 8,
|
||||
"menuName": "新建问卷(新建问卷)",
|
||||
"menuCode": "新建问卷",
|
||||
"parentId": 6,
|
||||
"orderNum": 2,
|
||||
"path": "evaluationreport",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"menuId": 9,
|
||||
"menuName": "随访详情(随访详情)",
|
||||
"menuCode": "随访详情",
|
||||
"parentId": 6,
|
||||
"orderNum": 3,
|
||||
"path": "evaluationlook",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"menuId": 10,
|
||||
"menuName": "任务配置(任务配置)",
|
||||
"menuCode": "任务配置",
|
||||
"parentId": 0,
|
||||
"orderNum": 3,
|
||||
"path": "/taskSet",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 0,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "iconfont icon-renwuguanli",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 1,
|
||||
"children": [
|
||||
{
|
||||
"menuId": 11,
|
||||
"menuName": "任务配置(任务配置)",
|
||||
"menuCode": "任务配置",
|
||||
"parentId": 10,
|
||||
"orderNum": 1,
|
||||
"path": "index",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"menuId": 12,
|
||||
"menuName": "数据统计(数据统计)",
|
||||
"menuCode": "数据统计",
|
||||
"parentId": 0,
|
||||
"orderNum": 4,
|
||||
"path": "/dataStatistics",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 0,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "iconfont icon-shujutongji",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 1,
|
||||
"children": [
|
||||
{
|
||||
"menuId": 13,
|
||||
"menuName": "数据统计(数据统计)",
|
||||
"menuCode": "数据统计",
|
||||
"parentId": 12,
|
||||
"orderNum": 1,
|
||||
"path": "index",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"menuId": 14,
|
||||
"menuName": "数据导出(数据导出)",
|
||||
"menuCode": "数据导出",
|
||||
"parentId": 0,
|
||||
"orderNum": 5,
|
||||
"path": "/dataExport",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 0,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "iconfont icon-suifangrenwuguanli",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 1,
|
||||
"children": [
|
||||
{
|
||||
"menuId": 15,
|
||||
"menuName": "数据导出(数据导出)",
|
||||
"menuCode": "数据导出",
|
||||
"parentId": 14,
|
||||
"orderNum": 1,
|
||||
"path": "index",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"menuId": 16,
|
||||
"menuName": "系统管理(系统管理)",
|
||||
"menuCode": "系统管理",
|
||||
"parentId": 0,
|
||||
"orderNum": 6,
|
||||
"path": "/systemManage",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 0,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "iconfont icon-xitongguanli",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 1,
|
||||
"children": [
|
||||
{
|
||||
"menuId": 17,
|
||||
"menuName": "用户管理(用户管理)",
|
||||
"menuCode": "用户管理",
|
||||
"parentId": 16,
|
||||
"orderNum": 1,
|
||||
"path": "usersManage",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"menuId": 18,
|
||||
"menuName": "角色管理(角色管理)",
|
||||
"menuCode": "角色管理",
|
||||
"parentId": 16,
|
||||
"orderNum": 2,
|
||||
"path": "roleManage",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"menuId": 19,
|
||||
"menuName": "权限配置(权限配置)",
|
||||
"menuCode": "权限配置",
|
||||
"parentId": 16,
|
||||
"orderNum": 3,
|
||||
"path": "permissionSetting",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"menuId": 20,
|
||||
"menuName": "菜单管理(菜单管理)",
|
||||
"menuCode": "菜单管理",
|
||||
"parentId": 16,
|
||||
"orderNum": 4,
|
||||
"path": "menuManage",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
defaultProps: {
|
||||
children: 'children', // 子级
|
||||
label: 'menuName' // 名称
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// 回显菜单
|
||||
this.setCheckedKeys()
|
||||
},
|
||||
methods: {
|
||||
// 提交数据
|
||||
getCheckedKeys () {
|
||||
// 获取子级的key
|
||||
const childMenu = this.$refs.tree.getCheckedKeys()
|
||||
// 获取父级的key
|
||||
const partMenu = this.$refs.tree.getHalfCheckedKeys()
|
||||
// 合并数据
|
||||
const menu = partMenu.concat(childMenu)
|
||||
console.log(menu)
|
||||
},
|
||||
|
||||
// 回显菜单
|
||||
setCheckedKeys () {
|
||||
// 一般是调接口,拿到菜单数据和回显的菜单数组
|
||||
|
||||
// 如果default-expand-all没有展开列表时,可以使用下面代码,设置展开所有行,
|
||||
// const nodesMap = this.$refs.tree.store.nodesMap
|
||||
// const keys = Object.keys(nodesMap)
|
||||
// keys.forEach(key => {
|
||||
// nodesMap[key].expanded = true
|
||||
// })
|
||||
|
||||
// 设置回显的菜单
|
||||
this.$nextTick(() => {
|
||||
this.$refs.tree.setCheckedKeys([3])
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.table {
|
||||
padding: 20px;
|
||||
min-height: 88vh;
|
||||
background: #fff;
|
||||
margin: 20px;
|
||||
}
|
||||
.menu-list {
|
||||
::v-deep .el-tree {
|
||||
border-top: 1px solid #ebeef5;
|
||||
border-left: 1px solid #ebeef5;
|
||||
border-right: 1px solid #ebeef5;
|
||||
.el-tree-node__expand-icon {
|
||||
display: none !important;
|
||||
}
|
||||
.el-tree-node {
|
||||
&.is-expanded,
|
||||
&.is-current,
|
||||
&.is-focusable {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
.el-tree-node__content {
|
||||
background-color: transparent !important;
|
||||
&:hover {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
> .el-tree-node {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
position: relative;
|
||||
> .el-tree-node__content {
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
padding-left: 20px !important;
|
||||
}
|
||||
.el-tree-node__children {
|
||||
position: relative;
|
||||
&::after {
|
||||
content: ' ';
|
||||
display: block;
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
border-left: 1px solid #ebeef5;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
}
|
||||
.el-tree-node {
|
||||
width: 350px;
|
||||
padding: 10px 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<!-- 授权用户 -->
|
||||
<el-dialog title="选择用户" align-center v-model="visible" width="800px" top="5vh" append-to-body>
|
||||
<el-dialog title="选择用户" v-model="visible" width="800px" top="5vh" append-to-body>
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true">
|
||||
<el-form-item label="用户名称" prop="userName">
|
||||
<el-input
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
<span>{{ formatTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="User">
|
||||
<script setup name="SelectUser">
|
||||
import { authUserSelectAll, unallocatedUserList } from "@/api/system/role";
|
||||
|
||||
const props = defineProps({
|
||||
|
|
@ -79,7 +79,7 @@ const userIds = ref([]);
|
|||
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
pageSize: 20,
|
||||
roleId: undefined,
|
||||
userName: undefined,
|
||||
phonenumber: undefined
|
||||
|
|
|
|||
|
|
@ -1,132 +0,0 @@
|
|||
<template>
|
||||
<div class="test-page">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>权限树状表格测试页面</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 权限树状表格 -->
|
||||
<PermissionTreeTable ref="treeTableRef" />
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="actions">
|
||||
<el-button @click="getSelectedData">获取选中数据</el-button>
|
||||
<el-button type="primary" @click="showDialog">打开对话框</el-button>
|
||||
<el-button type="success" @click="setDefaultData">设置默认选中</el-button>
|
||||
<el-button type="warning" @click="clearAll">清空所有</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 结果展示 -->
|
||||
<div v-if="selectedData" class="result">
|
||||
<h3>选中结果:</h3>
|
||||
<el-alert
|
||||
title="数据获取成功"
|
||||
type="success"
|
||||
:closable="false"
|
||||
show-icon
|
||||
/>
|
||||
<pre>{{ JSON.stringify(selectedData, null, 2) }}</pre>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 对话框测试 -->
|
||||
<PermissionDialog
|
||||
v-model="dialogVisible"
|
||||
@confirm="handleDialogConfirm"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import PermissionTreeTable from './render.vue'
|
||||
import PermissionDialog from './permission-dialog.vue'
|
||||
|
||||
const treeTableRef = ref()
|
||||
const dialogVisible = ref(false)
|
||||
const selectedData = ref(null)
|
||||
|
||||
// 获取选中数据
|
||||
const getSelectedData = () => {
|
||||
if (treeTableRef.value) {
|
||||
const data = treeTableRef.value.getCheckedData()
|
||||
selectedData.value = data
|
||||
console.log('选中的数据:', data)
|
||||
}
|
||||
}
|
||||
|
||||
// 显示对话框
|
||||
const showDialog = () => {
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
// 处理对话框确认
|
||||
const handleDialogConfirm = (data) => {
|
||||
selectedData.value = data
|
||||
console.log('对话框确认的数据:', data)
|
||||
}
|
||||
|
||||
// 设置默认选中数据(示例)
|
||||
const setDefaultData = () => {
|
||||
// 这里可以实现设置默认选中状态的逻辑
|
||||
console.log('设置默认选中数据')
|
||||
// 由于当前实现是内部状态管理,这里只是示例
|
||||
// 实际使用时可能需要通过props传入初始状态
|
||||
}
|
||||
|
||||
// 清空所有选中
|
||||
const clearAll = () => {
|
||||
// 这里可以实现清空所有选中状态的逻辑
|
||||
console.log('清空所有选中')
|
||||
selectedData.value = null
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.test-page {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.actions {
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.actions .el-button {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.result {
|
||||
margin-top: 20px;
|
||||
padding: 20px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.result h3 {
|
||||
margin-top: 0;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.result pre {
|
||||
background: #fff;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #e4e7ed;
|
||||
overflow-x: auto;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.el-alert {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
<template>
|
||||
<!-- 账户详情 -->
|
||||
<el-dialog :title="t('账户详情')" align-center v-model="showDialog" width="700px" append-to-body
|
||||
class="el-dialog">
|
||||
<el-scrollbar max-height="700px">
|
||||
<el-descriptions :column="1" border class="c-descriptions">
|
||||
<el-descriptions-item :label="t('所属部门')" label-width="150">
|
||||
{{ modifyDate.dept?.deptName||'--' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('后台账号')" label-width="150" >
|
||||
{{ modifyDate.userName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('后台昵称')" label-width="150">
|
||||
{{ modifyDate.nickName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('权限名称')" label-width="150">
|
||||
{{ modifyDate.roleName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('创建人')" label-width="150">
|
||||
{{ modifyDate.updateBy||modifyDate.createBy }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('创建时间')" label-width="150">
|
||||
{{ formatTime(modifyDate.createTime) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('最后登录方式')" label-width="150">
|
||||
{{ t('密码登录') }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('最后登录时间')" label-width="150">
|
||||
{{ formatTime(modifyDate.loginDate) || '--' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('最后登出时间')" label-width="150">
|
||||
{{ formatTime(modifyDate.exitDate) || '--' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('最后登入IP')" label-width="150">
|
||||
{{ modifyDate.loginIp || '--' }}
|
||||
</el-descriptions-item>
|
||||
|
||||
|
||||
</el-descriptions>
|
||||
</el-scrollbar>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="closeDialog">{{ t('取 消') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import { nextTick, ref } from "vue";
|
||||
import { formatTime } from '@/utils/ruoyi';
|
||||
const { proxy } = getCurrentInstance()
|
||||
const emits = defineEmits(['submit', 'update:show']) // 自定义事件
|
||||
const props = defineProps({ // 父组件向子组件传值
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
modifyDate: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
})
|
||||
const showDialog = computed({// 对话框显示隐藏
|
||||
get() {
|
||||
return props.show
|
||||
},
|
||||
set(value) {
|
||||
emits('update:show', value)
|
||||
}
|
||||
})
|
||||
|
||||
const formAll = reactive({ // 表单验证数据
|
||||
id: '',
|
||||
rewardAmount:'',
|
||||
auditRate:'',
|
||||
remark:'',
|
||||
password:''
|
||||
})
|
||||
|
||||
//数据更新区域
|
||||
nextTick(() => {
|
||||
formAll.id = props.modifyDate.id;
|
||||
})
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
});
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
showDialog.value = false
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scope lang="scss">
|
||||
.icon-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
}
|
||||
.disable-click {
|
||||
pointer-events: none;
|
||||
}
|
||||
.clt-item {
|
||||
.label-box {
|
||||
vertical-align: middle;
|
||||
width: 150px;
|
||||
text-align: right;
|
||||
padding-right: 12px;
|
||||
word-break: break-all;
|
||||
line-height: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:deep(.el-form-item__error) {
|
||||
padding-left: 150px;
|
||||
}
|
||||
|
||||
.item-right {
|
||||
width: calc(100% - 150px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
<template>
|
||||
<!-- Google验证码 -->
|
||||
<el-dialog v-model="showDialog" align-center width="500px" append-to-body
|
||||
class="el-dialog">
|
||||
<template #title>
|
||||
<div class="title" style="width: 100%;text-align: center;">Google验证码</div>
|
||||
</template>
|
||||
<el-form :model="formGoogle" :rules="rulesGoogle" ref="googleRef" label-width="130px">
|
||||
<el-form-item label="Google验证码" prop="googleCode">
|
||||
<el-input v-model="formGoogle.googleCode" placeholder="请输入您的Google验证码" maxlength="6" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer" style="display: flex;justify-content: center;">
|
||||
<el-button @click="showDialog = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitGoogle">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import { nextTick, ref } from "vue";
|
||||
const { proxy } = getCurrentInstance()
|
||||
const emits = defineEmits(['submit', 'update:show']) // 自定义事件
|
||||
const props = defineProps({ // 父组件向子组件传值
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
modifyDate: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
})
|
||||
const showDialog = computed({// 对话框显示隐藏
|
||||
get() {
|
||||
return props.show
|
||||
},
|
||||
set(value) {
|
||||
emits('update:show', value)
|
||||
}
|
||||
})
|
||||
|
||||
const rulesGoogle = reactive({
|
||||
googleCode: [{ required: true, message: "请输入谷歌验证码", trigger: "change" }]
|
||||
});
|
||||
const formGoogle = reactive({
|
||||
googleCode: ''
|
||||
});
|
||||
|
||||
//数据更新区域
|
||||
nextTick(() => {
|
||||
|
||||
})
|
||||
const submitGoogle = () => {
|
||||
proxy.$refs["googleRef"].validate(valid => {
|
||||
if (valid) {
|
||||
emits('submit', formGoogle.googleCode)
|
||||
}
|
||||
})
|
||||
}
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
});
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
showDialog.value = false
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scope lang="scss">
|
||||
.icon-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
}
|
||||
.disable-click {
|
||||
pointer-events: none;
|
||||
}
|
||||
.clt-item {
|
||||
.label-box {
|
||||
vertical-align: middle;
|
||||
width: 150px;
|
||||
text-align: right;
|
||||
padding-right: 12px;
|
||||
word-break: break-all;
|
||||
line-height: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:deep(.el-form-item__error) {
|
||||
padding-left: 150px;
|
||||
}
|
||||
|
||||
.item-right {
|
||||
width: calc(100% - 150px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<template>
|
||||
<div>
|
||||
<div style="margin-bottom: 10px;">
|
||||
<span>批量数量:</span>
|
||||
<b>{{ batchCount }}</b>
|
||||
</div>
|
||||
|
||||
<el-form :model="form">
|
||||
<el-form-item label="操作类型">
|
||||
<el-select v-model="form.actionType" placeholder="请选择操作类型" style="width: 300px">
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive } from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
batchCount: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
});
|
||||
|
||||
const form = reactive({
|
||||
actionType: ""
|
||||
});
|
||||
|
||||
// 这里可以暴露给外部取值
|
||||
defineExpose({ form });
|
||||
</script>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue