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'
|
||||
|
|
@ -296,7 +330,19 @@ const dd = String(today.getDate()).padStart(2, '0');
|
|||
tenantType: [{ required: true, message: proxy.t('商户模式不能为空'), trigger: "change" }],
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//操作类型
|
||||
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,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -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