feat: 新增角色列表

This commit is contained in:
xlsea
2025-05-09 23:26:09 +08:00
parent b70ddb31e9
commit 67b5af9892
25 changed files with 869 additions and 125 deletions

View File

@ -1,34 +0,0 @@
/**
* 查询系统菜单列表
*
* @param menu 菜单信息
* @return 菜单列表
*/
@Override
public List<SysMenuVo> selectMenuList(SysMenuBo menu, Long userId) {
List<SysMenuVo> menuList;
// 管理员显示所有菜单信息
if (LoginHelper.isSuperAdmin(userId)) {
menuList = baseMapper.selectVoList(new LambdaQueryWrapper<SysMenu>()
.like(StringUtils.isNotBlank(menu.getMenuName()), SysMenu::getMenuName, menu.getMenuName())
.eq(StringUtils.isNotBlank(menu.getVisible()), SysMenu::getVisible, menu.getVisible())
.eq(StringUtils.isNotBlank(menu.getStatus()), SysMenu::getStatus, menu.getStatus())
.eq(StringUtils.isNotBlank(menu.getMenuType()), SysMenu::getMenuType, menu.getMenuType())
.eq(ObjectUtil.isNotNull(menu.getParentId()), SysMenu::getParentId, menu.getParentId())
.orderByAsc(SysMenu::getParentId)
.orderByAsc(SysMenu::getOrderNum));
} else {
QueryWrapper<SysMenu> wrapper = Wrappers.query();
wrapper.inSql("r.role_id", "select role_id from sys_user_role where user_id = " + userId)
.like(StringUtils.isNotBlank(menu.getMenuName()), "m.menu_name", menu.getMenuName())
.eq(StringUtils.isNotBlank(menu.getVisible()), "m.visible", menu.getVisible())
.eq(StringUtils.isNotBlank(menu.getStatus()), "m.status", menu.getStatus())
.eq(StringUtils.isNotBlank(menu.getMenuType()), "m.menu_type", menu.getMenuType())
.eq(ObjectUtil.isNotNull(menu.getParentId()), "m.parent_id", menu.getParentId())
.orderByAsc("m.parent_id")
.orderByAsc("m.order_num");
List<SysMenu> list = baseMapper.selectMenuListByUserId(wrapper);
menuList = MapstructUtils.convert(list, SysMenuVo.class);
}
return menuList;
}

View File

@ -62,7 +62,7 @@ public class VelocityUtils {
velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName()));
velocityContext.put("businessName", genTable.getBusinessName());
velocityContext.put("business_name", StrUtil.toUnderlineCase(genTable.getBusinessName()));
velocityContext.put("business-name", StrUtil.toSymbolCase(genTable.getBusinessName(),'-'));
velocityContext.put("business__name", StrUtil.toSymbolCase(genTable.getBusinessName(), '-'));
velocityContext.put("businessname", StrUtil.toSymbolCase(genTable.getBusinessName(), ' '));
velocityContext.put("basePackage", getPackagePrefix(packageName));
velocityContext.put("packageName", packageName);
@ -180,7 +180,7 @@ public class VelocityUtils {
} else if (template.contains("soy.api.d.ts.vm")) {
fileName = StringUtils.format("soybean/typings/api/{}.api.d.ts", moduleName);
} else if (template.contains("soy.api.ts.vm")) {
fileName = StringUtils.format("soybean/api/{}/{}.ts", moduleName, StrUtil.toSymbolCase(businessName, '-'));
fileName = StringUtils.format("soybean/api/{}/{}.ts", moduleName, StrUtil.toSymbolCase(businessName, '-'));
} else if (template.contains("soy.search.vue.vm")) {
fileName = StringUtils.format("soybean/views/{}/{}/modules/{}-search.vue", moduleName, businessName, StrUtil.toSymbolCase(businessName, '-'));
} else if (template.contains("soy.operate-drawer.vue.vm")) {

View File

@ -1,9 +1,9 @@
<script setup lang="ts">
import { computed, reactive, watch } from 'vue';
import { fetchCreate${BusinessName}, fetchUpdate${BusinessName} } from '@/service/api/${moduleName}/${business__name}';
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
import { $t } from '@/locales';
import { fetchCreate${BusinessName}, fetchUpdate${BusinessName} } from '@/service/api/${moduleName}/${business-name}';
#if($dictList && $dictList.size() > 0)import { useDict } from '@/hooks/business/dict';#end
import { $t } from '@/locales';
defineOptions({
name: '${BusinessName}OperateDrawer'
@ -177,7 +177,7 @@ watch(visible, () => {
value-format="yyyy-MM-dd HH:mm:ss"
clearable
/>
#else <NInput v-model:value="model.$column.javaField" placeholder="请输入$column.columnComment" />
#else <NInput v-model:value="model.$column.javaField" placeholder="请输入$column.columnComment" />
#end
</NFormItem>
#end

View File

@ -1,7 +1,8 @@
#set($ModuleName=$moduleName.substring(0, 1).toUpperCase() + $moduleName.substring(1))
<script setup lang="ts">
import { $t } from '@/locales';
import { ref } from 'vue';
import { useNaiveForm } from '@/hooks/common/form';
import { $t } from '@/locales';
#if($dictList && $dictList.size() > 0)import { useDict } from '@/hooks/business/dict';#end
defineOptions({
@ -20,7 +21,7 @@ const { formRef, validate, restoreValidation } = useNaiveForm();
#foreach ($column in $columns)
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
const dateRange${AttrName} = ref<[string, string]>();
const dateRange${AttrName} = ref<[string, string] | null>(null);
#end#end
const model = defineModel<Api.$ModuleName.${BusinessName}SearchParams>('model', { required: true });
@ -34,9 +35,10 @@ async function reset() {
#foreach ($column in $columns)
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
dateRange${AttrName}.value = undefined;
dateRange${AttrName}.value = null;
#end
#end
Object.assign(model.value.params!, {});
await restoreValidation();
emit('reset');
}

View File

@ -1,13 +1,14 @@
<script setup lang="tsx">
import { NButton, NPopconfirm } from 'naive-ui';
import { NDivider } from 'naive-ui';
import { fetchBatchDelete${BusinessName}, fetchGet${BusinessName}List } from '@/service/api/${moduleName}/${businessName}';
import { $t } from '@/locales';
import { useAuth } from '@/hooks/business/auth';
import { useAppStore } from '@/store/modules/app';
import { useAuth } from '@/hooks/business/auth';
import { useDownload } from '@/hooks/business/download';
import { useTable, useTableOperate } from '@/hooks/common/table';
import ${BusinessName}OperateDrawer from './modules/${business-name}-operate-drawer.vue';
import ${BusinessName}Search from './modules/${business-name}-search.vue';
import { $t } from '@/locales';
import ButtonIcon from '@/components/custom/button-icon.vue';
import ${BusinessName}OperateDrawer from './modules/${business__name}-operate-drawer.vue';
import ${BusinessName}Search from './modules/${business__name}-search.vue';
defineOptions({
name: '${BusinessName}List'
@ -39,6 +40,7 @@ const {
$column.javaField: null#if($foreach.hasNext),#end
#end
#end
params: {}
},
columns: () => [
{
@ -68,67 +70,69 @@ const {
align: 'center',
width: 130,
render: row => {
const divider = () => {
if (!hasAuth('${moduleName}:${businessName}:edit') || !hasAuth('${moduleName}:${businessName}:remove')) {
return null;
}
return <NDivider vertical />;
};
const editBtn = () => {
if (!hasAuth('${moduleName}:${businessName}:edit')) {
return null;
}
return (
<NButton type="primary" ghost size="small" onClick={() => edit(row.#foreach($column in $columns)#if($column.isPk == '1')$column.javaField#end#end!)}>
{$t('common.edit')}
</NButton>
);
if (!hasAuth('${moduleName}:${businessName}:edit')) {
return null;
}
return (
<ButtonIcon
text
type="primary"
icon="material-symbols:drive-file-rename-outline-outline"
tooltipContent={$t('common.edit')}
onClick={() => edit(row.#foreach($column in $columns)#if($column.isPk == '1')$column.javaField#end#end!)}
/>
);
};
const deleteBtn = () => {
if (!hasAuth('${moduleName}:${businessName}:remove')) {
return null;
}
return (
<NPopconfirm onPositiveClick={() => handleDelete(row.#foreach($column in $columns)#if($column.isPk == '1')$column.javaField#end#end!)}>
{{
default: () => $t('common.confirmDelete'),
trigger: () => (
<NButton type="error" ghost size="small">
{$t('common.delete')}
</NButton>
)
}}
</NPopconfirm>
);
if (!hasAuth('${moduleName}:${businessName}:remove')) {
return null;
}
return (
<ButtonIcon
text
type="error"
icon="material-symbols:delete-outline"
tooltipContent={$t('common.delete')}
popconfirmContent={$t('common.confirmDelete')}
onPositiveClick={() => handleDelete(row.#foreach($column in $columns)#if($column.isPk == '1')$column.javaField#end#end!)}
/>
);
};
return (
<div class="flex-center gap-8px">
{editBtn()}
{deleteBtn()}
</div>
<div class="flex-center gap-8px">
{editBtn()}
{divider()}
{deleteBtn()}
</div>
);
}
}
]
});
const {
drawerVisible,
operateType,
editingData,
handleAdd,
handleEdit,
checkedRowKeys,
onBatchDeleted,
onDeleted
} = useTableOperate(data, getData);
const { drawerVisible, operateType, editingData, handleAdd, handleEdit, checkedRowKeys, onBatchDeleted, onDeleted } =
useTableOperate(data, getData);
async function handleBatchDelete() {
// request
const { error } = await fetchBatchDelete${BusinessName}(checkedRowKeys.value)
const { error } = await fetchBatchDelete${BusinessName}(checkedRowKeys.value);
if (error) return;
onBatchDeleted();
}
async function handleDelete(#foreach($column in $columns)#if($column.isPk == '1')$column.javaField#end#end: CommonType.IdType) {
// request
const { error } = await fetchBatchDelete${BusinessName}([#foreach($column in $columns)#if($column.isPk == '1')$column.javaField#end#end])
const { error } = await fetchBatchDelete${BusinessName}([#foreach($column in $columns)#if($column.isPk == '1')$column.javaField#end#end]);
if (error) return;
onDeleted();
}
@ -138,7 +142,7 @@ async function edit(#foreach($column in $columns)#if($column.isPk == '1')$column
}
async function handleExport() {
download('/${moduleName}/${businessName}/export', searchParams, `${functionName}_#[[${new Date().getTime()}]]#.xlsx`);
download('/${moduleName}/${businessName}/export', searchParams, `${functionName}_#[[${new Date().getTime()}]]#.xlsx`);
}
</script>
@ -169,7 +173,7 @@ async function handleExport() {
:scroll-x="962"
:loading="loading"
remote
:row-key="row => row.id"
:row-key="row => row.#foreach($column in $columns)#if($column.isPk == '1')$column.javaField#end#end"
:pagination="mobilePagination"
class="sm:h-full"
/>