项目初始化
This commit is contained in:
294
web-vue/packages/core/views/sys/module/form.vue
Normal file
294
web-vue/packages/core/views/sys/module/form.vue
Normal file
@@ -0,0 +1,294 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now https://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
-->
|
||||
<template>
|
||||
<BasicDrawer
|
||||
v-bind="$attrs"
|
||||
:showFooter="true"
|
||||
:okAuth="'sys:module:edit'"
|
||||
@register="registerDrawer"
|
||||
@ok="handleSubmit"
|
||||
width="70%"
|
||||
>
|
||||
<template #title>
|
||||
<Icon :icon="getTitle.icon" class="m-1 pr-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<template #centerFooter>
|
||||
<a-button v-if="isCustomModule" type="primary" danger :loading="confirmLoading" @click="handleSubmitAndGen">
|
||||
<Icon icon="i-ant-design:bug-outlined" /> {{ t('确认并生成代码') }}
|
||||
</a-button>
|
||||
</template>
|
||||
<BasicForm @register="registerForm">
|
||||
<template #genBaseDir>
|
||||
<Input v-model:value="genBaseDir">
|
||||
<template #addonAfter>
|
||||
<Dropdown class="cursor-pointer" :trigger="['click']" :dropMenuList="genBaseDirList">
|
||||
{{ t('生成路径快速选择') }} <Icon icon="i-ant-design:down-outlined" />
|
||||
</Dropdown>
|
||||
</template>
|
||||
</Input>
|
||||
</template>
|
||||
</BasicForm>
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsSysModuleForm">
|
||||
import { ref, unref, computed } from 'vue';
|
||||
import { Input } from 'ant-design-vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { router } from '@jeesite/core/router';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicForm, FormSchema, useForm } from '@jeesite/core/components/Form';
|
||||
import { BasicDrawer, useDrawerInner } from '@jeesite/core/components/Drawer';
|
||||
import { Module, moduleSave, moduleForm } from '@jeesite/core/api/sys/module';
|
||||
import { Dropdown, DropMenu } from '@jeesite/core/components/Dropdown';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
|
||||
const { t } = useI18n('sys.module');
|
||||
const { showMessage, createConfirm } = useMessage();
|
||||
const { meta } = unref(router.currentRoute);
|
||||
const record = ref<Module>({} as Module);
|
||||
const genBaseDir = ref<string>('');
|
||||
const genBaseDirList = ref<DropMenu[]>([]);
|
||||
const genTplCategoryList = ref<string[]>([]);
|
||||
const getTitle = computed(() => ({
|
||||
icon: meta.icon || 'ant-design:book-outlined',
|
||||
value: record.value.isNewRecord ? t('新增模块') : t('编辑模块'),
|
||||
}));
|
||||
const moduleNames = [
|
||||
'app',
|
||||
'bpm',
|
||||
'cms',
|
||||
'core',
|
||||
'filemanager',
|
||||
'filepreview',
|
||||
'oauth2',
|
||||
'oss-client',
|
||||
'sharding',
|
||||
'swagger',
|
||||
'ureport',
|
||||
'visual',
|
||||
'weixin',
|
||||
];
|
||||
const isCustomModule = ref<boolean>(false);
|
||||
|
||||
const inputFormSchemas: FormSchema[] = [
|
||||
{
|
||||
label: t('基本信息'),
|
||||
field: 'basicInfo',
|
||||
component: 'FormGroup',
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('模块名称'),
|
||||
field: 'moduleName',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 100,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('模块编码'),
|
||||
field: 'moduleCode',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 64,
|
||||
},
|
||||
rules: [
|
||||
{ required: true },
|
||||
{
|
||||
pattern: /^[a-zA-Z]([a-zA-Z0-9_-])*[a-zA-Z0-9]$/,
|
||||
message: t('请输入2个以上字符,字母开头、允许字母数字下划线或减号、字母数字结尾'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: t('模块描述'),
|
||||
field: 'description',
|
||||
component: 'InputTextArea',
|
||||
componentProps: {
|
||||
maxlength: 500,
|
||||
rows: 3,
|
||||
},
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('主类全名'),
|
||||
helpMessage:
|
||||
'该模块的状态验证类,如果该类检测不存在,则该模块状态提示 “未安装” ,验证原理:\n' +
|
||||
'Class.forName(“com.jeesite.modules.sys.web.LoginController”);在微服务下不进行验证。',
|
||||
field: 'mainClassName',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 500,
|
||||
},
|
||||
colProps: { md: 24, lg: 24 },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('基础包名'),
|
||||
helpMessage: '该模块所属的基础包名',
|
||||
field: 'packageName',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 500,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('排序号'),
|
||||
field: 'moduleSort',
|
||||
helpMessage: '升序',
|
||||
component: 'InputNumber',
|
||||
defaultValue: '30',
|
||||
componentProps: {
|
||||
maxlength: 10,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('版本信息'),
|
||||
field: 'versionInfo',
|
||||
component: 'FormGroup',
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('当前版本'),
|
||||
field: 'currentVersion',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 50,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('升级信息'),
|
||||
field: 'upgradeInfo',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 300,
|
||||
disabled: true,
|
||||
},
|
||||
ifShow: () => !record.value.isNewRecord,
|
||||
},
|
||||
|
||||
{
|
||||
label: t('生成工程代码'),
|
||||
field: 'genModule',
|
||||
component: 'FormGroup',
|
||||
colProps: { md: 24, lg: 24 },
|
||||
ifShow: () => isCustomModule.value,
|
||||
},
|
||||
{
|
||||
label: t('生成基础路径'),
|
||||
field: 'genBaseDir',
|
||||
component: 'Input',
|
||||
slot: 'genBaseDir',
|
||||
colProps: { md: 24, lg: 24 },
|
||||
ifShow: () => isCustomModule.value,
|
||||
},
|
||||
{
|
||||
label: t('代码生成模板'),
|
||||
field: 'tplCategory',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: genTplCategoryList,
|
||||
allowClear: true,
|
||||
},
|
||||
ifShow: () => isCustomModule.value,
|
||||
},
|
||||
{
|
||||
field: 'replaceFile',
|
||||
component: 'Checkbox',
|
||||
renderComponentContent: t('是否替换现有文件'),
|
||||
ifShow: () => isCustomModule.value,
|
||||
},
|
||||
];
|
||||
|
||||
const [registerForm, { resetFields, setFieldsValue, updateSchema, validate }] = useForm({
|
||||
labelWidth: 120,
|
||||
schemas: inputFormSchemas,
|
||||
baseColProps: { md: 24, lg: 12 },
|
||||
});
|
||||
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer, getDrawerProps }] = useDrawerInner(async (data) => {
|
||||
setDrawerProps({ loading: true });
|
||||
await resetFields();
|
||||
const res = await moduleForm(data);
|
||||
record.value = (res.module || {}) as Module;
|
||||
genBaseDir.value = res.genBaseDir || '';
|
||||
genBaseDirList.value = (res.genBaseDirList || []).map((s: string) => {
|
||||
return {
|
||||
text: s,
|
||||
onClick: () => {
|
||||
genBaseDir.value = s;
|
||||
},
|
||||
};
|
||||
});
|
||||
genTplCategoryList.value = res.config?.moduleTplCategory?.tplCategoryList || [];
|
||||
isCustomModule.value = !moduleNames.includes(record.value.moduleCode || '');
|
||||
record.value.tplCategory = ''; // 不回显代码生成模版,选择生成模版后再编译或生成模版
|
||||
await setFieldsValue(record.value);
|
||||
await updateSchema([
|
||||
{
|
||||
field: 'moduleCode',
|
||||
componentProps: {
|
||||
disabled: !record.value.isNewRecord,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'currentVersion',
|
||||
componentProps: {
|
||||
disabled: !record.value.isNewRecord,
|
||||
},
|
||||
},
|
||||
]);
|
||||
setDrawerProps({ loading: false });
|
||||
});
|
||||
|
||||
const confirmLoading = computed(() => {
|
||||
return getDrawerProps().confirmLoading || false;
|
||||
});
|
||||
|
||||
async function handleSubmitAndGen() {
|
||||
createConfirm({
|
||||
title: t('提示'),
|
||||
content: t('是否要生成模块源码到 ‘' + genBaseDir.value + '’ 目录下?'),
|
||||
iconType: 'warning',
|
||||
width: '50%',
|
||||
onOk: () => {
|
||||
handleSubmit('2');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function handleSubmit(flag: string) {
|
||||
try {
|
||||
const data = await validate();
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
const params: any = {
|
||||
isNewRecord: record.value.isNewRecord,
|
||||
moduleCode: record.value.moduleCode,
|
||||
};
|
||||
data.genBaseDir = genBaseDir.value;
|
||||
data.genFlag = flag ? flag : '1';
|
||||
data.replaceFile = data.replaceFile ? '1' : '0';
|
||||
// console.log('submit', params, data, record);
|
||||
const res = await moduleSave(params, data);
|
||||
showMessage(res.message);
|
||||
setTimeout(closeDrawer);
|
||||
emit('success', data);
|
||||
} catch (error: any) {
|
||||
if (error && error.errorFields) {
|
||||
showMessage(error.message || t('common.validateError'));
|
||||
}
|
||||
console.log('error', error);
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
218
web-vue/packages/core/views/sys/module/list.vue
Normal file
218
web-vue/packages/core/views/sys/module/list.vue
Normal file
@@ -0,0 +1,218 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now https://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable">
|
||||
<template #tableTitle>
|
||||
<Icon :icon="getTitle.icon" class="m-1 pr-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<template #toolbar>
|
||||
<a-button type="primary" @click="handleForm({})" v-auth="'sys:module:edit'">
|
||||
<Icon icon="i-fluent:add-12-filled" /> {{ t('新增') }}
|
||||
</a-button>
|
||||
</template>
|
||||
<template #firstColumn="{ record }">
|
||||
<a @click="handleForm({ moduleCode: record.moduleCode })">
|
||||
{{ record.moduleName }}
|
||||
</a>
|
||||
</template>
|
||||
<template #statusColumn="{ column, record }">
|
||||
<DictLabel v-if="record.isLoader" :dictType="column.dictType" :dictValue="record[column.dataIndex]" />
|
||||
<span v-else style="color: red">{{ t('未安装') }}</span>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<InputForm @register="registerDrawer" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsSysModuleList">
|
||||
import { unref } from 'vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { router } from '@jeesite/core/router';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { DictLabel } from '@jeesite/core/components/Dict';
|
||||
import { BasicTable, BasicColumn, useTable } from '@jeesite/core/components/Table';
|
||||
import { moduleDelete, moduleListData } from '@jeesite/core/api/sys/module';
|
||||
import { moduleDisable, moduleEnable } from '@jeesite/core/api/sys/module';
|
||||
import { useDrawer } from '@jeesite/core/components/Drawer';
|
||||
import { FormProps } from '@jeesite/core/components/Form';
|
||||
import InputForm from './form.vue';
|
||||
|
||||
const { t } = useI18n('sys.module');
|
||||
const { showMessage } = useMessage();
|
||||
const { meta } = unref(router.currentRoute);
|
||||
const getTitle = {
|
||||
icon: meta.icon || 'ant-design:book-outlined',
|
||||
value: meta.title || t('模块管理'),
|
||||
};
|
||||
|
||||
const searchForm: FormProps = {
|
||||
baseColProps: { md: 8, lg: 6 },
|
||||
labelWidth: 90,
|
||||
schemas: [
|
||||
{
|
||||
label: t('模块名称'),
|
||||
field: 'moduleName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('主类全名'),
|
||||
field: 'mainClassName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('状态'),
|
||||
field: 'status',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'sys_search_status',
|
||||
allowClear: true,
|
||||
onChange: handleSuccess,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const tableColumns: BasicColumn[] = [
|
||||
{
|
||||
title: t('模块名称'),
|
||||
dataIndex: 'moduleName',
|
||||
key: 'a.module_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
slot: 'firstColumn',
|
||||
},
|
||||
{
|
||||
title: t('模块编码'),
|
||||
dataIndex: 'moduleCode',
|
||||
key: 'a.module_code',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('模块描述'),
|
||||
dataIndex: 'description',
|
||||
key: 'a.description',
|
||||
sorter: true,
|
||||
width: 230,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('版本'),
|
||||
dataIndex: 'currentVersion',
|
||||
key: 'a.current_version',
|
||||
sorter: true,
|
||||
width: 60,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('排序号'),
|
||||
dataIndex: 'moduleSort',
|
||||
key: 'a.module_sort',
|
||||
sorter: true,
|
||||
width: 60,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('状态'),
|
||||
dataIndex: 'status',
|
||||
key: 'a.status',
|
||||
sorter: true,
|
||||
width: 60,
|
||||
align: 'center',
|
||||
dictType: 'sys_status',
|
||||
slot: 'statusColumn',
|
||||
},
|
||||
];
|
||||
|
||||
const actionColumn: BasicColumn = {
|
||||
width: 130,
|
||||
actions: (record: Recordable) => [
|
||||
{
|
||||
icon: 'i-clarity:note-edit-line',
|
||||
title: t('编辑模块'),
|
||||
onClick: handleForm.bind(this, { moduleCode: record.moduleCode }),
|
||||
auth: 'sys:module:edit',
|
||||
},
|
||||
{
|
||||
icon: 'i-ant-design:stop-outlined',
|
||||
color: 'error',
|
||||
title: t('停用模块'),
|
||||
popConfirm: {
|
||||
title: t('是否确认停用模块'),
|
||||
confirm: handleDisable.bind(this, { moduleCode: record.moduleCode }),
|
||||
},
|
||||
auth: 'sys:module:edit',
|
||||
ifShow: () => record.status === '0',
|
||||
},
|
||||
{
|
||||
icon: 'i-ant-design:check-circle-outlined',
|
||||
color: 'success',
|
||||
title: t('启用模块'),
|
||||
popConfirm: {
|
||||
title: t('是否确认启用模块'),
|
||||
confirm: handleEnable.bind(this, { moduleCode: record.moduleCode }),
|
||||
},
|
||||
auth: 'sys:module:edit',
|
||||
ifShow: () => record.status === '2',
|
||||
},
|
||||
{
|
||||
icon: 'i-ant-design:delete-outlined',
|
||||
color: 'error',
|
||||
title: t('删除模块'),
|
||||
popConfirm: {
|
||||
title: t('是否确认删除模块'),
|
||||
confirm: handleDelete.bind(this, { moduleCode: record.moduleCode }),
|
||||
},
|
||||
auth: 'sys:module:edit',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
const [registerTable, { reload }] = useTable({
|
||||
api: moduleListData,
|
||||
beforeFetch: (params) => {
|
||||
return params;
|
||||
},
|
||||
columns: tableColumns,
|
||||
actionColumn: actionColumn,
|
||||
formConfig: searchForm,
|
||||
showTableSetting: true,
|
||||
useSearchForm: true,
|
||||
pagination: true,
|
||||
canResize: true,
|
||||
});
|
||||
|
||||
function handleForm(record: Recordable) {
|
||||
openDrawer(true, record);
|
||||
}
|
||||
|
||||
async function handleDisable(record: Recordable) {
|
||||
const res = await moduleDisable(record);
|
||||
showMessage(res.message);
|
||||
handleSuccess();
|
||||
}
|
||||
|
||||
async function handleEnable(record: Recordable) {
|
||||
const res = await moduleEnable(record);
|
||||
showMessage(res.message);
|
||||
handleSuccess();
|
||||
}
|
||||
|
||||
async function handleDelete(record: Recordable) {
|
||||
const res = await moduleDelete(record);
|
||||
showMessage(res.message);
|
||||
handleSuccess();
|
||||
}
|
||||
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user