|
|
@ -35,7 +35,7 @@
|
|
|
|
value: 'id',
|
|
|
|
value: 'id',
|
|
|
|
children: 'menuChild',
|
|
|
|
children: 'menuChild',
|
|
|
|
}"
|
|
|
|
}"
|
|
|
|
@current-change="(data) => (state.condition2.menuId = data.id)"
|
|
|
|
@node-click="(data) => handleCreateMenu(data)"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<template #default="{ data }">
|
|
|
|
<template #default="{ data }">
|
|
|
|
<div class="flex">
|
|
|
|
<div class="flex">
|
|
|
@ -46,9 +46,6 @@
|
|
|
|
<el-button type="text" @click.stop="handleCreateMenu(null, data)">
|
|
|
|
<el-button type="text" @click.stop="handleCreateMenu(null, data)">
|
|
|
|
<el-icon name="Plus" />
|
|
|
|
<el-icon name="Plus" />
|
|
|
|
</el-button>
|
|
|
|
</el-button>
|
|
|
|
<el-button type="text" @click.stop="handleCreateMenu(data)">
|
|
|
|
|
|
|
|
<el-icon name="Edit" />
|
|
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
|
|
<el-button type="text" @click.stop="handleDeleteMenu([data])">
|
|
|
|
<el-button type="text" @click.stop="handleDeleteMenu([data])">
|
|
|
|
<el-icon name="Delete" />
|
|
|
|
<el-icon name="Delete" />
|
|
|
|
</el-button>
|
|
|
|
</el-button>
|
|
|
@ -58,12 +55,12 @@
|
|
|
|
</el-tree>
|
|
|
|
</el-tree>
|
|
|
|
</el-scrollbar>
|
|
|
|
</el-scrollbar>
|
|
|
|
</el-card>
|
|
|
|
</el-card>
|
|
|
|
<el-card class="feature">
|
|
|
|
<el-card v-show="state.condition2.menuId" class="feature">
|
|
|
|
<template #header>
|
|
|
|
<template #header>
|
|
|
|
<div class="card-header">
|
|
|
|
<div class="card-header">
|
|
|
|
<div class="title">功能</div>
|
|
|
|
<div class="title">功能</div>
|
|
|
|
<div class="action">
|
|
|
|
<div class="action">
|
|
|
|
<el-button type="text" @click="handleCreateFeature()">新增</el-button>
|
|
|
|
<el-button type="text" @click="handlePickFeature()">新增</el-button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
@ -78,6 +75,7 @@
|
|
|
|
label: 'name',
|
|
|
|
label: 'name',
|
|
|
|
value: 'id',
|
|
|
|
value: 'id',
|
|
|
|
}"
|
|
|
|
}"
|
|
|
|
|
|
|
|
@node-click="(data) => handleCreateFeature(data)"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<template #default="{ data }">
|
|
|
|
<template #default="{ data }">
|
|
|
|
<div class="flex">
|
|
|
|
<div class="flex">
|
|
|
@ -85,12 +83,9 @@
|
|
|
|
{{ data.name }}
|
|
|
|
{{ data.name }}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="btns">
|
|
|
|
<div class="btns">
|
|
|
|
<el-button type="text" @click.stop="handleCreateFeature(data)">
|
|
|
|
<!-- <el-button type="text" @click.stop="handleDeleteFeature([data])">
|
|
|
|
<el-icon name="Edit" />
|
|
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
|
|
<el-button type="text" @click.stop="handleDeleteFeature([data])">
|
|
|
|
|
|
|
|
<el-icon name="Delete" />
|
|
|
|
<el-icon name="Delete" />
|
|
|
|
</el-button>
|
|
|
|
</el-button> -->
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
@ -137,10 +132,10 @@
|
|
|
|
<el-radio-group v-model="menuState.form.type" :opts="opts.type" />
|
|
|
|
<el-radio-group v-model="menuState.form.type" :opts="opts.type" />
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="菜单名称" prop="title">
|
|
|
|
<el-form-item label="菜单名称" prop="title">
|
|
|
|
<el-input v-model="menuState.form.title" />
|
|
|
|
<el-input v-model="menuState.form.title" maxlength="6" />
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="权限标识" prop="permission">
|
|
|
|
<el-form-item label="权限标识" prop="permission">
|
|
|
|
<el-input v-model="menuState.form.permission" />
|
|
|
|
<el-input v-model="menuState.form.permission" maxlength="20" />
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="路由路径" prop="path">
|
|
|
|
<el-form-item label="路由路径" prop="path">
|
|
|
|
<el-input v-model="menuState.form.path" />
|
|
|
|
<el-input v-model="menuState.form.path" />
|
|
|
@ -201,23 +196,52 @@
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="功能名称" prop="name">
|
|
|
|
<el-form-item label="功能名称" prop="name">
|
|
|
|
<el-input v-model="featureState.form.name" />
|
|
|
|
<el-input v-model="featureState.form.name" maxlength="20" />
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item label="服务名称" prop="service">
|
|
|
|
|
|
|
|
<el-input v-model="featureState.form.service" />
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="请求方式" prop="method">
|
|
|
|
<el-form-item label="请求方式" prop="method">
|
|
|
|
<el-select v-model="featureState.form.method" :opts="opts.method" />
|
|
|
|
<el-select v-model="featureState.form.method" :opts="opts.method" />
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="接口路径" prop="uri">
|
|
|
|
<el-form-item label="接口路径" prop="uri">
|
|
|
|
<el-input v-model="featureState.form.uri" />
|
|
|
|
<el-input v-model="featureState.form.uri" :rows="3" type="textarea" />
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="是否启用" prop="isEnable">
|
|
|
|
<el-form-item label="是否启用" prop="isEnable">
|
|
|
|
<el-switch v-model="featureState.form.isEnable" />
|
|
|
|
<el-switch v-model="featureState.form.isEnable" />
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item label="权限类型" prop="type">
|
|
|
|
|
|
|
|
<el-radio-group v-model="featureState.form.type" :opts="opts2.type" />
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item>
|
|
|
|
<el-form-item>
|
|
|
|
<el-button type="primary" @click="handleSaveFeature">保存</el-button>
|
|
|
|
<el-button type="primary" @click="handleSaveFeature">保存</el-button>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form>
|
|
|
|
</el-form>
|
|
|
|
</el-scrollbar>
|
|
|
|
</el-scrollbar>
|
|
|
|
</el-card>
|
|
|
|
</el-card>
|
|
|
|
|
|
|
|
<el-dialog v-model="featureState.pickVisible" title="选择功能权限">
|
|
|
|
|
|
|
|
<el-form
|
|
|
|
|
|
|
|
ref="refsPickForm"
|
|
|
|
|
|
|
|
v-loading="featureState.submitting"
|
|
|
|
|
|
|
|
label-width="100px"
|
|
|
|
|
|
|
|
:model="featureState.pick"
|
|
|
|
|
|
|
|
:rules="featureState.pickRules"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<el-form-item label="功能菜单" prop="permissionId">
|
|
|
|
|
|
|
|
<el-select
|
|
|
|
|
|
|
|
v-model="featureState.pick.permissionId"
|
|
|
|
|
|
|
|
:config="{ label: 'name', value: 'id' }"
|
|
|
|
|
|
|
|
:opts="opts.free"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
</el-form>
|
|
|
|
|
|
|
|
<template #footer>
|
|
|
|
|
|
|
|
<el-button @click="handleCancelPick">取消</el-button>
|
|
|
|
|
|
|
|
<el-button :loading="featureState.submitting" type="primary" @click="handleSavePick">
|
|
|
|
|
|
|
|
保存
|
|
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
</el-dialog>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
@ -227,6 +251,7 @@
|
|
|
|
const store = useStore();
|
|
|
|
const store = useStore();
|
|
|
|
const { proxy } = getCurrentInstance();
|
|
|
|
const { proxy } = getCurrentInstance();
|
|
|
|
const opts = computed(() => store.state.menu.opts);
|
|
|
|
const opts = computed(() => store.state.menu.opts);
|
|
|
|
|
|
|
|
const opts2 = computed(() => store.state.feature.opts);
|
|
|
|
if (!unref(opts).init) {
|
|
|
|
if (!unref(opts).init) {
|
|
|
|
store.dispatch('menu/load');
|
|
|
|
store.dispatch('menu/load');
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -243,6 +268,15 @@
|
|
|
|
await store.dispatch('menu/search');
|
|
|
|
await store.dispatch('menu/search');
|
|
|
|
loading.value = false;
|
|
|
|
loading.value = false;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
watch(
|
|
|
|
|
|
|
|
() => unref(opts).system,
|
|
|
|
|
|
|
|
(value) => {
|
|
|
|
|
|
|
|
state.condition.systemId = value?.[0]?.id;
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
deep: true,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
);
|
|
|
|
watch(
|
|
|
|
watch(
|
|
|
|
() => state.condition,
|
|
|
|
() => state.condition,
|
|
|
|
(value) => {
|
|
|
|
(value) => {
|
|
|
@ -297,7 +331,11 @@
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
const handleCreateMenu = (row, parent) => {
|
|
|
|
const handleCreateMenu = (row, parent) => {
|
|
|
|
|
|
|
|
if (row) {
|
|
|
|
|
|
|
|
state.condition2.menuId = row.id;
|
|
|
|
|
|
|
|
}
|
|
|
|
menuState.formVisible = true;
|
|
|
|
menuState.formVisible = true;
|
|
|
|
|
|
|
|
featureState.formVisible = false;
|
|
|
|
Object.assign(
|
|
|
|
Object.assign(
|
|
|
|
menuState.form,
|
|
|
|
menuState.form,
|
|
|
|
row || {
|
|
|
|
row || {
|
|
|
@ -341,6 +379,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
/* 功能表单 */
|
|
|
|
/* 功能表单 */
|
|
|
|
const refsFeatureForm = ref(null);
|
|
|
|
const refsFeatureForm = ref(null);
|
|
|
|
|
|
|
|
const refsPickForm = ref(null);
|
|
|
|
const featureState = reactive({
|
|
|
|
const featureState = reactive({
|
|
|
|
formVisible: false,
|
|
|
|
formVisible: false,
|
|
|
|
submitting: false,
|
|
|
|
submitting: false,
|
|
|
@ -349,21 +388,66 @@
|
|
|
|
systemId: null,
|
|
|
|
systemId: null,
|
|
|
|
menuId: null,
|
|
|
|
menuId: null,
|
|
|
|
name: null,
|
|
|
|
name: null,
|
|
|
|
|
|
|
|
service: null,
|
|
|
|
method: 'GET',
|
|
|
|
method: 'GET',
|
|
|
|
uri: null,
|
|
|
|
uri: null,
|
|
|
|
|
|
|
|
type: 1,
|
|
|
|
isEnable: true,
|
|
|
|
isEnable: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
rules: {
|
|
|
|
rules: {
|
|
|
|
systemId: [{ required: true, message: '所属系统不能为空' }],
|
|
|
|
systemId: [{ required: true, message: '所属系统不能为空' }],
|
|
|
|
menuId: [{ required: true, message: '所属菜单不能为空' }],
|
|
|
|
menuId: [{ required: true, message: '所属菜单不能为空' }],
|
|
|
|
name: [{ required: true, message: '功能名称不能为空' }],
|
|
|
|
name: [{ required: true, message: '功能名称不能为空' }],
|
|
|
|
|
|
|
|
service: [{ required: true, message: '服务名称不能为空' }],
|
|
|
|
method: [{ required: true, message: '请求方式不能为空' }],
|
|
|
|
method: [{ required: true, message: '请求方式不能为空' }],
|
|
|
|
uri: [{ required: true, message: '接口路径不能为空' }],
|
|
|
|
uri: [{ required: true, message: '接口路径不能为空' }],
|
|
|
|
|
|
|
|
type: [{ required: true, message: '权限类型不能为空' }],
|
|
|
|
isEnable: [{ required: true, message: '是否启用不能为空' }],
|
|
|
|
isEnable: [{ required: true, message: '是否启用不能为空' }],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
pickVisible: false,
|
|
|
|
|
|
|
|
pick: {
|
|
|
|
|
|
|
|
permissionId: null,
|
|
|
|
|
|
|
|
menuId: null,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
pickRules: {
|
|
|
|
|
|
|
|
permissionId: [{ required: true, message: '功能权限不能为空' }],
|
|
|
|
|
|
|
|
},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
const handleCreateFeature = (row) => {
|
|
|
|
const handleCancelPick = () => {
|
|
|
|
|
|
|
|
featureState.pickVisible = false;
|
|
|
|
|
|
|
|
featureState.pick = {
|
|
|
|
|
|
|
|
permissionId: null,
|
|
|
|
|
|
|
|
menuId: null,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleSavePick = async () => {
|
|
|
|
|
|
|
|
featureState.submitting = true;
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
await proxy.$validate(refsPickForm);
|
|
|
|
|
|
|
|
let res = await store.dispatch('feature/assign', featureState.pick);
|
|
|
|
|
|
|
|
if (res) {
|
|
|
|
|
|
|
|
handleSearchFeature();
|
|
|
|
|
|
|
|
handleCancelPick();
|
|
|
|
|
|
|
|
store.dispatch('menu/load');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
|
|
console.info('取消保存', e);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
featureState.submitting = false;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
const handlePickFeature = async () => {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
await proxy.$confirm('是否选择尚未分配菜单的功能权限?');
|
|
|
|
|
|
|
|
featureState.formVisible = false;
|
|
|
|
|
|
|
|
featureState.pickVisible = true;
|
|
|
|
|
|
|
|
featureState.pick.menuId = state.condition2.menuId;
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
|
|
handleCreateFeature();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleCreateFeature = async (row) => {
|
|
|
|
featureState.formVisible = true;
|
|
|
|
featureState.formVisible = true;
|
|
|
|
|
|
|
|
menuState.formVisible = false;
|
|
|
|
Object.assign(
|
|
|
|
Object.assign(
|
|
|
|
featureState.form,
|
|
|
|
featureState.form,
|
|
|
|
row || {
|
|
|
|
row || {
|
|
|
@ -371,8 +455,10 @@
|
|
|
|
systemId: state.condition.systemId,
|
|
|
|
systemId: state.condition.systemId,
|
|
|
|
menuId: state.condition2.menuId,
|
|
|
|
menuId: state.condition2.menuId,
|
|
|
|
name: null,
|
|
|
|
name: null,
|
|
|
|
|
|
|
|
service: null,
|
|
|
|
method: 'GET',
|
|
|
|
method: 'GET',
|
|
|
|
uri: null,
|
|
|
|
uri: null,
|
|
|
|
|
|
|
|
type: 1,
|
|
|
|
isEnable: true,
|
|
|
|
isEnable: true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
);
|
|
|
@ -391,12 +477,12 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
featureState.submitting = false;
|
|
|
|
featureState.submitting = false;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
const handleDeleteFeature = (data) => {
|
|
|
|
// const handleDeleteFeature = (data) => {
|
|
|
|
store.dispatch(
|
|
|
|
// store.dispatch(
|
|
|
|
'feature/remove',
|
|
|
|
// 'feature/remove',
|
|
|
|
data.map((item) => item.id)
|
|
|
|
// data.map((item) => item.id)
|
|
|
|
);
|
|
|
|
// );
|
|
|
|
};
|
|
|
|
// };
|
|
|
|
</script>
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="less" scoped>
|
|
|
|
<style lang="less" scoped>
|
|
|
|