mirror of
https://github.com/bufanyun/hotgo.git
synced 2025-11-16 22:23:44 +08:00
发布v2.15.1版本,更新内容请查看:https://github.com/bufanyun/hotgo/blob/v2.0/docs/guide-zh-CN/start-update-log.md
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
|
||||
<n-modal
|
||||
v-model:show="showModal"
|
||||
:mask-closable="false"
|
||||
:show-icon="false"
|
||||
preset="dialog"
|
||||
title="创建新插件"
|
||||
@@ -127,12 +128,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h, reactive, ref } from 'vue';
|
||||
import { computed, h, reactive, ref } from 'vue';
|
||||
import { NIcon, useMessage, useDialog, useNotification } from 'naive-ui';
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm, useForm } from '@/components/Form/index';
|
||||
import { List, Build, UnInstall, Install, Upgrade } from '@/api/develop/addons';
|
||||
import { PlusOutlined, QuestionCircleOutlined } from '@vicons/antd';
|
||||
import { PlusOutlined } from '@vicons/antd';
|
||||
import { newState, schemas, columns, options } from './model';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
|
||||
@@ -144,15 +145,17 @@
|
||||
const formRef: any = ref(null);
|
||||
const actionRef = ref();
|
||||
const formParams = ref<any>();
|
||||
const dialogWidth = ref('50%');
|
||||
const checkedIds = ref([]);
|
||||
const searchFormRef = ref<any>();
|
||||
const dialogWidth = computed(() => {
|
||||
return adaModalWidth();
|
||||
});
|
||||
|
||||
const actionColumn = reactive({
|
||||
width: 220,
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
// fixed: 'right',
|
||||
fixed: 'right',
|
||||
render(record) {
|
||||
return h(TableAction as any, {
|
||||
style: 'button',
|
||||
@@ -196,7 +199,6 @@
|
||||
}
|
||||
|
||||
const loadDataTable = async (res) => {
|
||||
adaModalWidth(dialogWidth);
|
||||
return await List({ ...res, ...searchFormRef.value?.formModel });
|
||||
};
|
||||
|
||||
|
||||
@@ -60,6 +60,54 @@
|
||||
</n-form-item>
|
||||
</n-col>
|
||||
|
||||
<!-- 树表-->
|
||||
<template v-if="formValue.genType == 11">
|
||||
<n-col :span="6" style="min-width: 200px">
|
||||
<n-form-item path="title">
|
||||
<template #label>
|
||||
<div class="flex flex-row items-end"
|
||||
>树名称字段
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-button strong text>
|
||||
<template #icon>
|
||||
<n-icon size="15" color="#2d8cf0">
|
||||
<QuestionCircleOutlined />
|
||||
</n-icon>
|
||||
</template>
|
||||
</n-button>
|
||||
</template>
|
||||
树节点的显示名称字段名, 如:`title`
|
||||
</n-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<n-select
|
||||
filterable
|
||||
tag
|
||||
:loading="columnsLoading"
|
||||
placeholder="请选择"
|
||||
:options="columnsOption"
|
||||
v-model:value="formValue.options.tree.titleColumn"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-col>
|
||||
|
||||
<n-col :span="6" style="min-width: 200px">
|
||||
<n-form-item label="树表格样式" path="styleType">
|
||||
<n-radio-group v-model:value="formValue.options.tree.styleType" name="styleType">
|
||||
<n-radio
|
||||
v-for="status in selectList.treeStyleType"
|
||||
:value="status.value"
|
||||
:label="status.label"
|
||||
>{{ status.label }}</n-radio
|
||||
>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
</n-col>
|
||||
</template>
|
||||
|
||||
<!-- 树表-->
|
||||
|
||||
<n-col :span="18">
|
||||
<n-form-item
|
||||
label="表格头部按钮组"
|
||||
@@ -97,15 +145,6 @@
|
||||
<n-checkbox value="del" label="删除" />
|
||||
<n-checkbox value="view" label="详情页" />
|
||||
<n-checkbox value="check" label="开启勾选列" />
|
||||
<n-checkbox value="switch" label="操作开关" />
|
||||
<n-popover trigger="hover">
|
||||
<template #trigger>
|
||||
<n-icon size="15" class="tips-help-icon" color="#2d8cf0">
|
||||
<QuestionCircleOutlined />
|
||||
</n-icon>
|
||||
</template>
|
||||
<span>表单组件中存在`开关`类型才会生效</span>
|
||||
</n-popover>
|
||||
<n-checkbox value="notFilterAuth" label="不过滤权限" />
|
||||
<n-popover trigger="hover">
|
||||
<template #trigger>
|
||||
@@ -122,7 +161,7 @@
|
||||
|
||||
<n-col :span="24">
|
||||
<n-form-item
|
||||
label="自动化操作"
|
||||
label="高级设置"
|
||||
path="autoOps"
|
||||
v-show="formValue.genType >= 10 && formValue.genType < 20"
|
||||
>
|
||||
@@ -136,7 +175,7 @@
|
||||
<QuestionCircleOutlined />
|
||||
</n-icon>
|
||||
</template>
|
||||
<span>如果你选择的表已经生成过dao相关代码,可以忽略</span>
|
||||
<span>如果你选择的表已经生成过dao相关代码,取消勾选可减少生成时间</span>
|
||||
</n-popover>
|
||||
<n-checkbox value="runService" label="生成后运行 [gf gen service]" />
|
||||
<n-popover trigger="hover">
|
||||
@@ -147,6 +186,19 @@
|
||||
</template>
|
||||
<span>如果是插件模块,勾选后也会自动在对应插件下运行service相关代码生成</span>
|
||||
</n-popover>
|
||||
<n-checkbox
|
||||
value="genFuncDict"
|
||||
label="生成字典选项"
|
||||
@click="handleCheckboxGenFuncDict"
|
||||
/>
|
||||
<n-popover trigger="hover">
|
||||
<template #trigger>
|
||||
<n-icon size="15" class="tips-help-icon" color="#2d8cf0">
|
||||
<QuestionCircleOutlined />
|
||||
</n-icon>
|
||||
</template>
|
||||
<span>将表数据生成为数据选项,并注册到内置的方法字典</span>
|
||||
</n-popover>
|
||||
<n-checkbox value="forcedCover" label="强制覆盖" />
|
||||
<n-popover trigger="hover">
|
||||
<template #trigger>
|
||||
@@ -166,7 +218,13 @@
|
||||
style="min-width: 200px"
|
||||
v-show="formValue.options?.autoOps?.includes('genMenuPermissions')"
|
||||
>
|
||||
<n-form-item label="上级菜单" path="pid">
|
||||
<n-form-item path="pid">
|
||||
<template #label>
|
||||
<span>上级菜单</span>
|
||||
<n-button class="ml-2" text type="primary" strong @click="handleAddMenu"
|
||||
>菜单管理</n-button
|
||||
>
|
||||
</template>
|
||||
<n-tree-select
|
||||
:options="optionMenuTree"
|
||||
:value="formValue.options.menu.pid"
|
||||
@@ -224,16 +282,16 @@
|
||||
<template #header-extra>
|
||||
<n-space>
|
||||
<n-button
|
||||
type="warning"
|
||||
type="primary"
|
||||
@click="addJoin"
|
||||
:disabled="formValue.options?.join?.length >= 3"
|
||||
:disabled="formValue.options?.join?.length >= 20"
|
||||
>新增关联表</n-button
|
||||
>
|
||||
</n-space>
|
||||
</template>
|
||||
|
||||
<n-form ref="formRef" :model="formValue">
|
||||
<n-alert :show-icon="false">关联表数量建议在三个以下</n-alert>
|
||||
<n-alert type="warning" :show-icon="false" v-if="formValue.options?.join?.length > 3">关联表数量建议在三个以下</n-alert>
|
||||
<div class="mt-4"></div>
|
||||
<n-row :gutter="6" v-for="(join, index) in formValue.options.join" :key="index">
|
||||
<n-col :span="6" style="min-width: 200px">
|
||||
@@ -315,12 +373,19 @@
|
||||
</n-form>
|
||||
</n-card>
|
||||
</n-spin>
|
||||
|
||||
<MenuModal ref="menuModalRef" @reloadTable="loadMenuTreeOption" />
|
||||
<SetFuncDict
|
||||
ref="setFuncDictRef"
|
||||
@update="handleUpdateFuncDict"
|
||||
:columnsOption="columnsOption"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref, computed, watch } from 'vue';
|
||||
import { FormInst } from 'naive-ui';
|
||||
import { FormInst, useDialog, useMessage } from 'naive-ui';
|
||||
import { newState, selectListObj } from './model';
|
||||
import { TableSelect, ColumnSelect } from '@/api/develop/code';
|
||||
import { getRandomString } from '@/utils/charset';
|
||||
@@ -329,7 +394,11 @@
|
||||
import { getMenuList } from '@/api/system/menu';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { isLetterBegin } from '@/utils/is';
|
||||
import MenuModal from '@/views/permission/menu/menuModal.vue';
|
||||
import SetFuncDict from './SetFuncDict.vue';
|
||||
|
||||
const message = useMessage();
|
||||
const dialog = useDialog();
|
||||
const timer = ref();
|
||||
const formRef = ref<FormInst | null>(null);
|
||||
const bodyShow = ref(true);
|
||||
@@ -340,6 +409,8 @@
|
||||
const columnsOption = ref<any>([]); // 主表字段选项
|
||||
const linkTablesOption = ref<any>([]); // 关联表选项
|
||||
const linkColumnsOption = ref<any>([]); // 关联表字段选项
|
||||
const menuModalRef = ref();
|
||||
const setFuncDictRef = ref();
|
||||
|
||||
const optionMenuTree = ref([
|
||||
{
|
||||
@@ -515,6 +586,20 @@
|
||||
function handleUpdateMenuPid(value: string | number | Array<string | number> | null) {
|
||||
formValue.value.options.menu.pid = value;
|
||||
}
|
||||
|
||||
function handleAddMenu() {
|
||||
menuModalRef.value.openModal();
|
||||
}
|
||||
|
||||
function handleCheckboxGenFuncDict() {
|
||||
if (formValue.value.options.autoOps.includes('genFuncDict')) {
|
||||
setFuncDictRef.value.openModal(formValue.value.options.funcDict);
|
||||
}
|
||||
}
|
||||
|
||||
function handleUpdateFuncDict(value) {
|
||||
formValue.value.options.funcDict = value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
@@ -1,58 +1,85 @@
|
||||
<template>
|
||||
<n-spin :show="show" description="加载中...">
|
||||
<n-card :bordered="false" class="proCard">
|
||||
<n-card :bordered="false" class="proCard">
|
||||
<n-spin :show="show" description="加载中...">
|
||||
<BasicTable
|
||||
:single-line="false"
|
||||
size="small"
|
||||
:striped="true"
|
||||
:resizable="true"
|
||||
striped
|
||||
resizable
|
||||
canResize
|
||||
virtual-scroll
|
||||
:single-line="false"
|
||||
:showTopRight="false"
|
||||
:pagination="false"
|
||||
:columns="columns"
|
||||
:dataSource="dataSource"
|
||||
:openChecked="false"
|
||||
:showTopRight="false"
|
||||
:row-key="(row) => row.id"
|
||||
ref="actionRef"
|
||||
:canResize="true"
|
||||
:pagination="false"
|
||||
:scroll-x="3000"
|
||||
:resizeHeightOffset="-20000"
|
||||
:scroll-x="columnCollapse ? 1400 : 2400"
|
||||
:scroll-y="720"
|
||||
:scrollbar-props="{ trigger: 'none' }"
|
||||
>
|
||||
<template #tableTitle>
|
||||
<n-tooltip placement="top-start" trigger="hover">
|
||||
<template #trigger>
|
||||
<n-button type="primary" @click="reloadFields(true)" class="min-left-space">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<Reload />
|
||||
</n-icon>
|
||||
</template>
|
||||
重置字段
|
||||
</n-button>
|
||||
</template>
|
||||
主要用于重置字段设置或数据库表字段发生变化时重新载入
|
||||
</n-tooltip>
|
||||
<n-space>
|
||||
<n-popconfirm @positive-click="reloadColumns">
|
||||
<template #trigger>
|
||||
<n-button type="primary" class="min-left-space">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<Reload />
|
||||
</n-icon>
|
||||
</template>
|
||||
重置字段
|
||||
</n-button>
|
||||
</template>
|
||||
重置后将从数据库重新加载表,不保留当前字段配置,确定要重置吗?
|
||||
</n-popconfirm>
|
||||
|
||||
<n-popconfirm @positive-click="syncColumns">
|
||||
<template #trigger>
|
||||
<n-button type="primary" class="min-left-space">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<Sync />
|
||||
</n-icon>
|
||||
</template>
|
||||
同步字段
|
||||
</n-button>
|
||||
</template>
|
||||
同步是从数据库重新加载表,保留当前有效的字段配置,确定要同步吗?
|
||||
</n-popconfirm>
|
||||
|
||||
<n-button type="default" class="min-left-space" @click="handleMove">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<MoveOutline />
|
||||
</n-icon>
|
||||
</template>
|
||||
移动字段
|
||||
</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</n-card>
|
||||
</n-spin>
|
||||
</n-spin>
|
||||
</n-card>
|
||||
<Move ref="moveRef" v-model:columns="dataSource" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, h, onMounted, ref } from 'vue';
|
||||
import { BasicTable } from '@/components/Table';
|
||||
import { genInfoObj, selectListObj } from '@/views/develop/code/components/model';
|
||||
import {
|
||||
formatColumns,
|
||||
formGridColsOptions,
|
||||
formGridSpanOptions,
|
||||
genInfoObj,
|
||||
selectListObj,
|
||||
} from '@/views/develop/code/components/model';
|
||||
import { ColumnList } from '@/api/develop/code';
|
||||
import { NButton, NCheckbox, NInput, NSelect, NTooltip, NTreeSelect,NCascader } from 'naive-ui';
|
||||
import { HelpCircleOutline, Reload } from '@vicons/ionicons5';
|
||||
import { renderIcon } from '@/utils';
|
||||
import { NInputNumber, NSpace, NButton, NCheckbox, NInput, NSelect, NCascader } from 'naive-ui';
|
||||
import { HelpCircleOutline, Reload, Sync, MoveOutline } from '@vicons/ionicons5';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
const renderTooltip = (trigger, content) => {
|
||||
return h(NTooltip, null, {
|
||||
trigger: () => trigger,
|
||||
default: () => content,
|
||||
});
|
||||
};
|
||||
import { renderIcon, renderTooltip } from '@/utils';
|
||||
import Move from './Move.vue';
|
||||
|
||||
const emit = defineEmits(['update:value']);
|
||||
|
||||
@@ -75,93 +102,22 @@
|
||||
},
|
||||
});
|
||||
|
||||
const actionRef = ref();
|
||||
const columns = ref<any>([]);
|
||||
const show = ref(false);
|
||||
const dataSource = ref(formValue.value.masterColumns);
|
||||
|
||||
async function reloadFields(loading = false) {
|
||||
dataSource.value = [];
|
||||
if (loading) {
|
||||
show.value = true;
|
||||
}
|
||||
|
||||
formValue.value.masterColumns = await ColumnList({
|
||||
name: formValue.value.dbName,
|
||||
table: formValue.value.tableName,
|
||||
});
|
||||
dataSource.value = formValue.value.masterColumns;
|
||||
if (loading) {
|
||||
show.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
show.value = true;
|
||||
if (formValue.value.masterColumns.length === 0) {
|
||||
await reloadFields();
|
||||
}
|
||||
|
||||
columns.value = [
|
||||
{
|
||||
title: '位置',
|
||||
key: 'id',
|
||||
width: 50,
|
||||
},
|
||||
{
|
||||
title(_column) {
|
||||
return renderTooltip(
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
strong: true,
|
||||
size: 'small',
|
||||
text: true,
|
||||
iconPlacement: 'right',
|
||||
},
|
||||
{ default: () => '字段', icon: renderIcon(HelpCircleOutline) }
|
||||
),
|
||||
'Go类型和属性定义取决于你在/hack/config.yaml中的配置参数'
|
||||
);
|
||||
},
|
||||
key: 'field',
|
||||
align: 'center',
|
||||
width: 800,
|
||||
children: [
|
||||
const dataSource = ref([]);
|
||||
const moveRef = ref();
|
||||
const columnCollapse = ref(true);
|
||||
const columnsCollapseData = computed(() => {
|
||||
return columnCollapse.value
|
||||
? [
|
||||
{
|
||||
title: '字段列名',
|
||||
key: 'name',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '物理类型',
|
||||
key: 'sqlType',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'Go属性',
|
||||
key: 'goName',
|
||||
width: 130,
|
||||
},
|
||||
{
|
||||
title: 'Go类型',
|
||||
key: 'goType',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: 'Ts属性',
|
||||
key: 'tsName',
|
||||
width: 130,
|
||||
},
|
||||
{
|
||||
title: 'Ts类型',
|
||||
key: 'tsType',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '字段描述',
|
||||
key: 'dc',
|
||||
width: 150,
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(NInput, {
|
||||
value: row.dc,
|
||||
@@ -171,7 +127,98 @@
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
]
|
||||
: [
|
||||
{
|
||||
title: '字段列名',
|
||||
key: 'name',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '物理类型',
|
||||
key: 'sqlType',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: 'Go属性',
|
||||
key: 'goName',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: 'Go类型',
|
||||
key: 'goType',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: 'Ts属性',
|
||||
key: 'tsName',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: 'Ts类型',
|
||||
key: 'tsType',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '字段描述',
|
||||
key: 'dc',
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(NInput, {
|
||||
value: row.dc,
|
||||
onUpdateValue: function (e) {
|
||||
row.dc = e;
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
const columns = computed(() => {
|
||||
return [
|
||||
{
|
||||
title: '',
|
||||
key: 'id',
|
||||
width: 30,
|
||||
render(row, index) {
|
||||
return index + 1;
|
||||
},
|
||||
},
|
||||
{
|
||||
title(_column) {
|
||||
return h('div', null, [
|
||||
renderTooltip(
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
strong: true,
|
||||
size: 'small',
|
||||
text: true,
|
||||
iconPlacement: 'right',
|
||||
},
|
||||
{ default: () => '字段', icon: renderIcon(HelpCircleOutline) }
|
||||
),
|
||||
'Go类型和属性定义取决于你在/hack/config.yaml中的配置参数'
|
||||
),
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
strong: true,
|
||||
size: 'small',
|
||||
text: true,
|
||||
type: 'primary',
|
||||
style: { 'margin-left': '20px' },
|
||||
onClick: () => (columnCollapse.value = !columnCollapse.value),
|
||||
},
|
||||
{ default: () => (columnCollapse.value ? '展开 >>' : '折叠 <<') }
|
||||
),
|
||||
]);
|
||||
},
|
||||
key: 'field',
|
||||
align: 'center',
|
||||
width: 800,
|
||||
children: columnsCollapseData.value,
|
||||
},
|
||||
{
|
||||
width: 800,
|
||||
@@ -197,21 +244,26 @@
|
||||
align: 'center',
|
||||
title: '编辑',
|
||||
key: 'isEdit',
|
||||
width: 50,
|
||||
width: 30,
|
||||
render(row) {
|
||||
return h(NCheckbox, {
|
||||
const disabled = isEditDisabled(row);
|
||||
const checkbox = h(NCheckbox, {
|
||||
defaultChecked: row.isEdit,
|
||||
disabled: row.name === 'id',
|
||||
disabled: disabled,
|
||||
onUpdateChecked: function (e) {
|
||||
row.isEdit = e;
|
||||
},
|
||||
});
|
||||
if (!disabled) {
|
||||
return checkbox;
|
||||
}
|
||||
return renderTooltip(checkbox, '该字段属性由系统维护,无需单独配置!');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '必填',
|
||||
key: 'required',
|
||||
width: 50,
|
||||
width: 30,
|
||||
align: 'center',
|
||||
render(row) {
|
||||
return h(NCheckbox, {
|
||||
@@ -226,7 +278,7 @@
|
||||
{
|
||||
title: '唯一',
|
||||
key: 'unique',
|
||||
width: 50,
|
||||
width: 30,
|
||||
align: 'center',
|
||||
render(row) {
|
||||
return h(NCheckbox, {
|
||||
@@ -241,17 +293,12 @@
|
||||
{
|
||||
title: '表单组件',
|
||||
key: 'formMode',
|
||||
width: 200,
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(NSelect, {
|
||||
consistentMenuWidth: false,
|
||||
value: row.formMode,
|
||||
options: getFormModeOptions(row.tsType),
|
||||
// render: function (row) {
|
||||
// return props.selectList?.formMode ?? [];
|
||||
// },
|
||||
// onFocus: function (e) {
|
||||
// console.log('表单组件 onFocus row:', e);
|
||||
// },
|
||||
onUpdateValue: function (e) {
|
||||
row.formMode = e;
|
||||
},
|
||||
@@ -259,11 +306,35 @@
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '表单验证',
|
||||
title: '绑定字典',
|
||||
key: 'dictType',
|
||||
width: 100,
|
||||
render(row) {
|
||||
if (row.dictType == 0) {
|
||||
row.dictType = null;
|
||||
}
|
||||
return h(NCascader, {
|
||||
placeholder: ' ',
|
||||
filterable: true,
|
||||
clearable: true,
|
||||
showPath: false,
|
||||
checkStrategy: 'child',
|
||||
disabled: row.name === 'id',
|
||||
value: row.dictType,
|
||||
options: props.selectList?.dictMode ?? [],
|
||||
onUpdateValue: function (e) {
|
||||
row.dictType = e;
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '验证规则',
|
||||
key: 'formRole',
|
||||
width: 200,
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(NSelect, {
|
||||
consistentMenuWidth: false,
|
||||
value: row.formRole,
|
||||
disabled: row.name === 'id',
|
||||
options: props.selectList?.formRole ?? [],
|
||||
@@ -274,22 +345,43 @@
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '字典类型',
|
||||
key: 'dictType',
|
||||
width: 300,
|
||||
title(_column) {
|
||||
return h(NSpace, { inline: true }, [
|
||||
renderTooltip(
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
strong: true,
|
||||
size: 'small',
|
||||
text: true,
|
||||
iconPlacement: 'right',
|
||||
},
|
||||
{ default: () => '栅格', icon: renderIcon(HelpCircleOutline) }
|
||||
),
|
||||
'表单每行摆放组件的个数。响应式栅格,小屏幕自动转为每行摆放一个组件。参考文档:https://www.naiveui.com/zh-CN/os-theme/components/grid#responsive-item.vue'
|
||||
),
|
||||
h(NSelect, {
|
||||
style: { width: '100px' },
|
||||
size: 'small',
|
||||
consistentMenuWidth: false,
|
||||
value: formValue.value.options.presetStep.formGridCols,
|
||||
options: formGridColsOptions,
|
||||
onUpdateValue: function (e) {
|
||||
formValue.value.options.presetStep.formGridCols = e;
|
||||
},
|
||||
}),
|
||||
]);
|
||||
},
|
||||
key: 'formGridSpan',
|
||||
width: 120,
|
||||
render(row) {
|
||||
if (row.dictType == 0){
|
||||
row.dictType = null;
|
||||
}
|
||||
return h(NCascader, {
|
||||
placeholder: '请选择字典类型',
|
||||
filterable: true,
|
||||
clearable: true,
|
||||
return h(NSelect, {
|
||||
consistentMenuWidth: false,
|
||||
disabled: row.name === 'id',
|
||||
value: row.dictType,
|
||||
options: props.selectList?.dictMode ?? [],
|
||||
value: row.formGridSpan,
|
||||
options: getFormGridSpanOptions(formValue.value.options.presetStep.formGridCols),
|
||||
onUpdateValue: function (e) {
|
||||
row.dictType = e;
|
||||
row.formGridSpan = e;
|
||||
},
|
||||
});
|
||||
},
|
||||
@@ -305,7 +397,7 @@
|
||||
{
|
||||
title: '列表',
|
||||
key: 'isList',
|
||||
width: 50,
|
||||
width: 30,
|
||||
align: 'center',
|
||||
render(row) {
|
||||
return h(NCheckbox, {
|
||||
@@ -319,7 +411,7 @@
|
||||
{
|
||||
title: '导出',
|
||||
key: 'isExport',
|
||||
width: 50,
|
||||
width: 30,
|
||||
align: 'center',
|
||||
render(row) {
|
||||
return h(NCheckbox, {
|
||||
@@ -333,7 +425,7 @@
|
||||
{
|
||||
title: '查询',
|
||||
key: 'isQuery',
|
||||
width: 50,
|
||||
width: 30,
|
||||
align: 'center',
|
||||
render(row) {
|
||||
return h(NCheckbox, {
|
||||
@@ -347,9 +439,10 @@
|
||||
{
|
||||
title: '查询条件',
|
||||
key: 'queryWhere',
|
||||
width: 300,
|
||||
width: 90,
|
||||
render(row) {
|
||||
return h(NSelect, {
|
||||
consistentMenuWidth: false,
|
||||
value: row.queryWhere,
|
||||
disabled: row.name === 'id',
|
||||
options: props.selectList?.whereMode ?? [],
|
||||
@@ -359,13 +452,108 @@
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '排列方式',
|
||||
key: 'align',
|
||||
width: 80,
|
||||
render(row) {
|
||||
return h(NSelect, {
|
||||
consistentMenuWidth: false,
|
||||
value: row.align,
|
||||
options: props.selectList?.tableAlign ?? [],
|
||||
onUpdateValue: function (e) {
|
||||
row.align = e;
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title(_column) {
|
||||
return renderTooltip(
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
strong: true,
|
||||
size: 'small',
|
||||
text: true,
|
||||
iconPlacement: 'right',
|
||||
},
|
||||
{ default: () => '列宽', icon: renderIcon(HelpCircleOutline) }
|
||||
),
|
||||
'选填。设定固定值时表格生成自动计算scroll-x,未设定默认每列按100计算'
|
||||
);
|
||||
},
|
||||
key: 'width',
|
||||
width: 50,
|
||||
render(row) {
|
||||
return h(NInputNumber, {
|
||||
value: row.width,
|
||||
placeholder: ' ',
|
||||
min: -1,
|
||||
max: 2000,
|
||||
showButton: false,
|
||||
onUpdateValue: function (e) {
|
||||
row.width = e;
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
show.value = false;
|
||||
});
|
||||
|
||||
// 同步字段
|
||||
function syncColumns() {
|
||||
show.value = true;
|
||||
dataSource.value = [];
|
||||
|
||||
const params = {
|
||||
name: formValue.value.dbName,
|
||||
table: formValue.value.tableName,
|
||||
};
|
||||
|
||||
ColumnList(params)
|
||||
.then((res) => {
|
||||
const columns = formatColumns(res);
|
||||
for (let i = 0; i < columns.length; i++) {
|
||||
// 相同字段名称和类型,保留原字段属性
|
||||
const index = formValue.value.masterColumns.findIndex(
|
||||
(item) => item.name == columns[i].name && item.dataType == columns[i].dataType
|
||||
);
|
||||
if (index !== -1) {
|
||||
columns[i] = formValue.value.masterColumns[index];
|
||||
}
|
||||
}
|
||||
|
||||
formValue.value.masterColumns = columns;
|
||||
dataSource.value = formValue.value.masterColumns;
|
||||
})
|
||||
.finally(() => {
|
||||
show.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
// 重载字段属性
|
||||
function reloadColumns() {
|
||||
show.value = true;
|
||||
dataSource.value = [];
|
||||
|
||||
const params = {
|
||||
name: formValue.value.dbName,
|
||||
table: formValue.value.tableName,
|
||||
};
|
||||
|
||||
ColumnList(params)
|
||||
.then((res) => {
|
||||
formValue.value.masterColumns = formatColumns(res);
|
||||
dataSource.value = formValue.value.masterColumns;
|
||||
})
|
||||
.finally(() => {
|
||||
show.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
function getFormModeOptions(type: string) {
|
||||
const options = cloneDeep(props.selectList?.formMode ?? []);
|
||||
if (options.length === 0) {
|
||||
@@ -374,7 +562,16 @@
|
||||
switch (type) {
|
||||
case 'number':
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
const allows = ['InputNumber', 'Radio', 'Select', 'Switch', 'Rate'];
|
||||
const allows = [
|
||||
'Input',
|
||||
'InputNumber',
|
||||
'Radio',
|
||||
'Select',
|
||||
'Switch',
|
||||
'Rate',
|
||||
'TreeSelect',
|
||||
'Cascader',
|
||||
];
|
||||
if (!allows.includes(options[i].value)) {
|
||||
options[i].disabled = true;
|
||||
}
|
||||
@@ -382,8 +579,73 @@
|
||||
break;
|
||||
default:
|
||||
}
|
||||
options.sort((a, b) => (a.disabled === b.disabled ? 0 : a.disabled ? 1 : -1));
|
||||
return options;
|
||||
}
|
||||
|
||||
function getFormGridSpanOptions(cols: number) {
|
||||
if (cols < 1) {
|
||||
cols = 1;
|
||||
}
|
||||
if (cols > 4) {
|
||||
cols = 4;
|
||||
}
|
||||
for (let i = 0; i < formValue.value.masterColumns.length; i++) {
|
||||
if (!formValue.value.masterColumns[i].formGridSpan) {
|
||||
formValue.value.masterColumns[i].formGridSpan = 1;
|
||||
}
|
||||
if (formValue.value.masterColumns[i].formGridSpan > cols) {
|
||||
formValue.value.masterColumns[i].formGridSpan = cols;
|
||||
}
|
||||
}
|
||||
return formGridSpanOptions.slice(0, Math.min(cols, formGridSpanOptions.length));
|
||||
}
|
||||
|
||||
// 禁止编辑的字段,由系统维护
|
||||
function isEditDisabled(row) {
|
||||
const disabledNames = [
|
||||
'id',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'deleted_by',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
];
|
||||
if (disabledNames.includes(row.name)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (formValue.value.genType == 11) {
|
||||
const disabledTreeNames = ['pid', 'level', 'tree'];
|
||||
if (disabledTreeNames.includes(row.name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function handleMove() {
|
||||
moveRef.value.openModal();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (formValue.value.masterColumns.length === 0) {
|
||||
reloadColumns();
|
||||
} else {
|
||||
show.value = true;
|
||||
setTimeout(function () {
|
||||
dataSource.value = formValue.value.masterColumns;
|
||||
show.value = false;
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
<style lang="less" scoped>
|
||||
.tree-tips {
|
||||
margin-left: 12px;
|
||||
color: #18a058;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,43 +2,85 @@
|
||||
<n-spin :show="show" description="加载中...">
|
||||
<n-card :bordered="false" class="proCard">
|
||||
<BasicTable
|
||||
:single-line="false"
|
||||
size="small"
|
||||
:striped="true"
|
||||
:resizable="true"
|
||||
striped
|
||||
resizable
|
||||
canResize
|
||||
:single-line="false"
|
||||
:showTopRight="false"
|
||||
:pagination="false"
|
||||
:columns="columns"
|
||||
:dataSource="dataSource"
|
||||
:openChecked="false"
|
||||
:showTopRight="false"
|
||||
:row-key="(row) => row.id"
|
||||
ref="actionRef"
|
||||
:canResize="true"
|
||||
:resizeHeightOffset="-20000"
|
||||
:pagination="false"
|
||||
:scroll-x="1090"
|
||||
:scroll-x="columnCollapse ? 880 : 1880"
|
||||
:scroll-y="720"
|
||||
:scrollbar-props="{ trigger: 'none' }"
|
||||
/>
|
||||
>
|
||||
<template #tableTitle>
|
||||
<n-space>
|
||||
<n-popconfirm @positive-click="reloadColumns(getIndex())">
|
||||
<template #trigger>
|
||||
<n-button type="primary" class="min-left-space">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<Reload />
|
||||
</n-icon>
|
||||
</template>
|
||||
重置字段
|
||||
</n-button>
|
||||
</template>
|
||||
重置后将从数据库重新加载该表的默认配置,确定要重置吗?
|
||||
</n-popconfirm>
|
||||
|
||||
<n-popconfirm @positive-click="syncColumns(getIndex())">
|
||||
<template #trigger>
|
||||
<n-button type="primary" class="min-left-space">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<Sync />
|
||||
</n-icon>
|
||||
</template>
|
||||
同步字段
|
||||
</n-button>
|
||||
</template>
|
||||
同步是从数据库重新加载表,保留当前有效的字段配置,确定要同步吗?
|
||||
</n-popconfirm>
|
||||
|
||||
<n-button type="default" class="min-left-space" @click="handleMove">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<MoveOutline />
|
||||
</n-icon>
|
||||
</template>
|
||||
移动字段
|
||||
</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</n-card>
|
||||
<Move ref="moveRef" v-model:columns="dataSource" />
|
||||
</n-spin>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Component, computed, h, onMounted, ref } from 'vue';
|
||||
import { computed, h, onMounted, ref } from 'vue';
|
||||
import { BasicTable } from '@/components/Table';
|
||||
import { genInfoObj, selectListObj } from '@/views/develop/code/components/model';
|
||||
import { formatColumns, genInfoObj, selectListObj } from '@/views/develop/code/components/model';
|
||||
import { ColumnList } from '@/api/develop/code';
|
||||
import { NButton, NCheckbox, NIcon, NInput, NSelect, NTooltip } from 'naive-ui';
|
||||
import { HelpCircleOutline } from '@vicons/ionicons5';
|
||||
|
||||
const renderTooltip = (trigger, content) => {
|
||||
return h(NTooltip, null, {
|
||||
trigger: () => trigger,
|
||||
default: () => content,
|
||||
});
|
||||
};
|
||||
function renderIcon(icon: Component) {
|
||||
return () => h(NIcon, null, { default: () => h(icon) });
|
||||
}
|
||||
import {
|
||||
NButton,
|
||||
NCheckbox,
|
||||
NIcon,
|
||||
NInput,
|
||||
NInputNumber,
|
||||
NSelect,
|
||||
NSpace,
|
||||
NTooltip,
|
||||
} from 'naive-ui';
|
||||
import { HelpCircleOutline, MoveOutline, Reload, Sync, WarningOutline } from '@vicons/ionicons5';
|
||||
import { renderIcon, renderTooltip } from '@/utils';
|
||||
import Move from './Move.vue';
|
||||
|
||||
const emit = defineEmits(['update:value']);
|
||||
|
||||
@@ -54,8 +96,6 @@
|
||||
uuid: '',
|
||||
});
|
||||
|
||||
const columns = ref<any>([]);
|
||||
|
||||
const formValue = computed({
|
||||
get() {
|
||||
return props.value;
|
||||
@@ -65,6 +105,243 @@
|
||||
},
|
||||
});
|
||||
|
||||
const show = ref(false);
|
||||
const dataSource = ref([]);
|
||||
const moveRef = ref();
|
||||
const columnCollapse = ref(true);
|
||||
const columnsCollapseData = computed(() => {
|
||||
return columnCollapse.value
|
||||
? [
|
||||
{
|
||||
title: '字段列名',
|
||||
key: 'name',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '字段描述',
|
||||
key: 'dc',
|
||||
width: 150,
|
||||
render(row) {
|
||||
return h(NInput, {
|
||||
value: row.dc,
|
||||
onUpdateValue: function (e) {
|
||||
row.dc = e;
|
||||
// await saveProductCustom(row.id, 'frontShow', e);
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
title: '字段列名',
|
||||
key: 'name',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '物理类型',
|
||||
key: 'sqlType',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: 'Go属性',
|
||||
key: 'goName',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'Go类型',
|
||||
key: 'goType',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: 'Ts属性',
|
||||
key: 'tsName',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'Ts类型',
|
||||
key: 'tsType',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '字段描述',
|
||||
key: 'dc',
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(NInput, {
|
||||
value: row.dc,
|
||||
onUpdateValue: function (e) {
|
||||
row.dc = e;
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
const columns = computed(() => {
|
||||
return [
|
||||
{
|
||||
title: '',
|
||||
key: 'id',
|
||||
width: 50,
|
||||
render(row, index) {
|
||||
return index + 1;
|
||||
},
|
||||
},
|
||||
{
|
||||
title(_column) {
|
||||
return h('div', null, [
|
||||
renderTooltip(
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
strong: true,
|
||||
size: 'small',
|
||||
text: true,
|
||||
iconPlacement: 'right',
|
||||
},
|
||||
{ default: () => '字段', icon: renderIcon(HelpCircleOutline) }
|
||||
),
|
||||
'Go类型和属性定义取决于你在/hack/config.yaml中的配置参数'
|
||||
),
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
strong: true,
|
||||
size: 'small',
|
||||
text: true,
|
||||
type: 'primary',
|
||||
style: { 'margin-left': '20px' },
|
||||
onClick: () => (columnCollapse.value = !columnCollapse.value),
|
||||
},
|
||||
{ default: () => (columnCollapse.value ? '展开 >>' : '折叠 <<') }
|
||||
),
|
||||
]);
|
||||
},
|
||||
key: 'field',
|
||||
align: 'center',
|
||||
width: 800,
|
||||
children: columnsCollapseData.value,
|
||||
},
|
||||
{
|
||||
width: 800,
|
||||
title: '列表',
|
||||
key: 'list',
|
||||
align: 'center',
|
||||
children: [
|
||||
{
|
||||
title: '列表',
|
||||
key: 'isList',
|
||||
width: 50,
|
||||
align: 'center',
|
||||
render(row) {
|
||||
return h(NCheckbox, {
|
||||
defaultChecked: row.isList,
|
||||
onUpdateChecked: function (e) {
|
||||
row.isList = e;
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '导出',
|
||||
key: 'isExport',
|
||||
width: 50,
|
||||
align: 'center',
|
||||
render(row) {
|
||||
return h(NCheckbox, {
|
||||
defaultChecked: row.isExport,
|
||||
onUpdateChecked: function (e) {
|
||||
row.isExport = e;
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '查询',
|
||||
key: 'isQuery',
|
||||
width: 50,
|
||||
align: 'center',
|
||||
render(row) {
|
||||
return h(NCheckbox, {
|
||||
defaultChecked: row.isQuery,
|
||||
onUpdateChecked: function (e) {
|
||||
row.isQuery = e;
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '查询条件',
|
||||
key: 'queryWhere',
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(NSelect, {
|
||||
consistentMenuWidth: false,
|
||||
value: row.queryWhere,
|
||||
disabled: row.name === 'id',
|
||||
options: props.selectList?.whereMode ?? [],
|
||||
onUpdateValue: function (e) {
|
||||
row.queryWhere = e;
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '排列方式',
|
||||
key: 'align',
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(NSelect, {
|
||||
consistentMenuWidth: false,
|
||||
value: row.align,
|
||||
options: props.selectList?.tableAlign ?? [],
|
||||
onUpdateValue: function (e) {
|
||||
row.align = e;
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title(_column) {
|
||||
return renderTooltip(
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
strong: true,
|
||||
size: 'small',
|
||||
text: true,
|
||||
iconPlacement: 'right',
|
||||
},
|
||||
{ default: () => '列宽', icon: renderIcon(HelpCircleOutline) }
|
||||
),
|
||||
'选填。设定固定值时表格生成自动计算scroll-x,未设定默认每列按100计算'
|
||||
);
|
||||
},
|
||||
key: 'width',
|
||||
width: 50,
|
||||
render(row) {
|
||||
return h(NInputNumber, {
|
||||
value: row.width,
|
||||
placeholder: ' ',
|
||||
min: 0,
|
||||
max: 2000,
|
||||
showButton: false,
|
||||
onUpdateValue: function (e) {
|
||||
row.width = e;
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
function handleMove() {
|
||||
moveRef.value.openModal();
|
||||
}
|
||||
function getIndex() {
|
||||
if (formValue.value.options.join.length === 0) {
|
||||
return -1;
|
||||
@@ -77,166 +354,77 @@
|
||||
return -1;
|
||||
}
|
||||
|
||||
const show = ref(false);
|
||||
const dataSource = ref([]);
|
||||
onMounted(async () => {
|
||||
// 同步字段属性
|
||||
function syncColumns(index: number) {
|
||||
show.value = true;
|
||||
setTimeout(async () => {
|
||||
dataSource.value = [];
|
||||
|
||||
const join = formValue.value.options.join[index];
|
||||
const params = {
|
||||
name: formValue.value.dbName,
|
||||
table: join.linkTable,
|
||||
isLink: 1,
|
||||
alias: join.alias,
|
||||
};
|
||||
|
||||
ColumnList(params)
|
||||
.then((res) => {
|
||||
const columns = formatColumns(res);
|
||||
for (let i = 0; i < columns.length; i++) {
|
||||
// 相同字段名称和类型,保留原字段属性
|
||||
const index2 = join.columns.findIndex(
|
||||
(item) => item.name == columns[i].name && item.dataType == columns[i].dataType
|
||||
);
|
||||
if (index2 !== -1) {
|
||||
columns[i] = join.columns[index2];
|
||||
}
|
||||
}
|
||||
join.columns = columns;
|
||||
dataSource.value = join.columns;
|
||||
})
|
||||
.finally(() => {
|
||||
show.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
// 重载字段属性
|
||||
function reloadColumns(index: number) {
|
||||
show.value = true;
|
||||
dataSource.value = [];
|
||||
|
||||
const join = formValue.value.options.join[index];
|
||||
const params = {
|
||||
name: formValue.value.dbName,
|
||||
table: join.linkTable,
|
||||
isLink: 1,
|
||||
alias: join.alias,
|
||||
};
|
||||
|
||||
ColumnList(params)
|
||||
.then((res) => {
|
||||
join.columns = formatColumns(res);
|
||||
dataSource.value = join.columns;
|
||||
})
|
||||
.finally(() => {
|
||||
show.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
show.value = true;
|
||||
setTimeout(() => {
|
||||
const index = getIndex();
|
||||
if (formValue.value.options.join[index].columns.length === 0) {
|
||||
formValue.value.options.join[index].columns = await ColumnList({
|
||||
name: formValue.value.dbName,
|
||||
table: formValue.value.options.join[index].linkTable,
|
||||
isLink: 1,
|
||||
alias: formValue.value.options.join[index].alias,
|
||||
});
|
||||
|
||||
// 已存在直接加载
|
||||
if (formValue.value.options.join[index].columns.length > 0) {
|
||||
dataSource.value = formValue.value.options.join[index].columns;
|
||||
show.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
dataSource.value = formValue.value.options.join[index].columns;
|
||||
|
||||
columns.value = [
|
||||
{
|
||||
title: '位置',
|
||||
key: 'id',
|
||||
width: 50,
|
||||
},
|
||||
{
|
||||
title(_column) {
|
||||
return renderTooltip(
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
strong: true,
|
||||
size: 'small',
|
||||
text: true,
|
||||
iconPlacement: 'right',
|
||||
},
|
||||
{ default: () => '字段', icon: renderIcon(HelpCircleOutline) }
|
||||
),
|
||||
'Go类型和属性定义取决于你在/hack/config.yaml中的配置参数'
|
||||
);
|
||||
},
|
||||
key: 'field',
|
||||
align: 'center',
|
||||
width: 800,
|
||||
children: [
|
||||
{
|
||||
title: '字段列名',
|
||||
key: 'name',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '物理类型',
|
||||
key: 'sqlType',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'Go属性',
|
||||
key: 'goName',
|
||||
width: 260,
|
||||
},
|
||||
{
|
||||
title: 'Go类型',
|
||||
key: 'goType',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: 'Ts属性',
|
||||
key: 'tsName',
|
||||
width: 260,
|
||||
},
|
||||
{
|
||||
title: 'Ts类型',
|
||||
key: 'tsType',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '字段描述',
|
||||
key: 'dc',
|
||||
width: 150,
|
||||
render(row) {
|
||||
return h(NInput, {
|
||||
value: row.dc,
|
||||
onUpdateValue: function (e) {
|
||||
row.dc = e;
|
||||
// await saveProductCustom(row.id, 'frontShow', e);
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
width: 800,
|
||||
title: '列表',
|
||||
key: 'list',
|
||||
align: 'center',
|
||||
children: [
|
||||
{
|
||||
title: '列表',
|
||||
key: 'isList',
|
||||
width: 50,
|
||||
align: 'center',
|
||||
render(row) {
|
||||
return h(NCheckbox, {
|
||||
defaultChecked: row.isList,
|
||||
onUpdateChecked: function (e) {
|
||||
row.isList = e;
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '导出',
|
||||
key: 'isExport',
|
||||
width: 50,
|
||||
align: 'center',
|
||||
render(row) {
|
||||
return h(NCheckbox, {
|
||||
defaultChecked: row.isExport,
|
||||
onUpdateChecked: function (e) {
|
||||
row.isExport = e;
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '查询',
|
||||
key: 'isQuery',
|
||||
width: 50,
|
||||
align: 'center',
|
||||
render(row) {
|
||||
return h(NCheckbox, {
|
||||
defaultChecked: row.isQuery,
|
||||
onUpdateChecked: function (e) {
|
||||
row.isQuery = e;
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '查询条件',
|
||||
key: 'queryWhere',
|
||||
width: 300,
|
||||
render(row) {
|
||||
return h(NSelect, {
|
||||
value: row.queryWhere,
|
||||
disabled: row.name === 'id',
|
||||
options: props.selectList?.whereMode ?? [],
|
||||
onUpdateValue: function (e) {
|
||||
row.queryWhere = e;
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
show.value = false;
|
||||
}, 50);
|
||||
reloadColumns(index);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
const actionRef = ref();
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
82
web/src/views/develop/code/components/Move.vue
Normal file
82
web/src/views/develop/code/components/Move.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-modal
|
||||
v-model:show="showModal"
|
||||
:mask-closable="false"
|
||||
:show-icon="false"
|
||||
preset="dialog"
|
||||
transform-origin="center"
|
||||
title="移动字段"
|
||||
:style="{
|
||||
width: dialogWidth,
|
||||
}"
|
||||
>
|
||||
<n-scrollbar style="max-height: 87vh" class="pr-5">
|
||||
<n-card
|
||||
:bordered="false"
|
||||
:content-style="{ padding: '0px' }"
|
||||
:header-style="{ padding: 'px' }"
|
||||
:segmented="true"
|
||||
>
|
||||
请通过拖拽来移动字段的位置。
|
||||
<div class="mt-8"></div>
|
||||
<Draggable
|
||||
class="draggable-ul"
|
||||
animation="300"
|
||||
:list="columns"
|
||||
group="people"
|
||||
itemKey="name"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<div class="cursor-move draggable-li">
|
||||
<n-tag type="default" size="small" style="font-weight: 800">{{
|
||||
element.name
|
||||
}}</n-tag
|
||||
><span class="ml-2">{{ element.dc }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</Draggable>
|
||||
</n-card>
|
||||
</n-scrollbar>
|
||||
</n-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import Draggable from 'vuedraggable';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
|
||||
const showModal = ref(false);
|
||||
const columns = defineModel<[]>('columns');
|
||||
const dialogWidth = computed(() => {
|
||||
return adaModalWidth(360);
|
||||
});
|
||||
|
||||
function openModal() {
|
||||
showModal.value = true;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
openModal,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.draggable-ul {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
margin-top: -8px;
|
||||
|
||||
.draggable-li {
|
||||
width: 100%;
|
||||
padding: 8px 4px;
|
||||
color: #333;
|
||||
border-bottom: 1px solid #efeff5;
|
||||
}
|
||||
|
||||
.draggable-li:hover {
|
||||
background-color: rgba(229, 231, 235, var(--tw-border-opacity));
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,16 +1,28 @@
|
||||
<template>
|
||||
<div>
|
||||
<textarea id="copy-code" :value="content"></textarea>
|
||||
<n-tabs type="line" animated>
|
||||
<n-tab-pane v-for="(view, index) in views" :key="index" :name="view.name" :tab="view.name">
|
||||
<n-tag :type="view.tag.type" class="tag-margin">
|
||||
{{ view.tag.label }}
|
||||
<template #icon>
|
||||
<n-icon :component="view.tag.icon" />
|
||||
</template>
|
||||
{{ view.path }}
|
||||
</n-tag>
|
||||
<n-space justify="space-between">
|
||||
<n-tag :type="view.tag.type" class="tag-margin">
|
||||
{{ view.tag.label }}
|
||||
<template #icon>
|
||||
<n-icon :component="view.tag.icon" />
|
||||
</template>
|
||||
{{ view.path }}
|
||||
</n-tag>
|
||||
<n-button type="primary" size="small" class="tag-margin" @click="handleCopy(view.content)"
|
||||
>复制本页代码</n-button
|
||||
>
|
||||
</n-space>
|
||||
<n-scrollbar class="code-scrollbar" trigger="none">
|
||||
<n-code :code="view.content" :hljs="hljs" language="goLang" show-line-numbers />
|
||||
<n-code
|
||||
:class="'code-' + getFileExtension(view.path)"
|
||||
:code="view.content"
|
||||
:hljs="hljs"
|
||||
:language="getFileExtension(view.path)"
|
||||
show-line-numbers
|
||||
/>
|
||||
</n-scrollbar>
|
||||
</n-tab-pane>
|
||||
</n-tabs>
|
||||
@@ -18,9 +30,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import hljs from 'highlight.js/lib/core';
|
||||
import goLang from 'highlight.js/lib/languages/go';
|
||||
import go from 'highlight.js/lib/languages/go';
|
||||
import typescript from 'highlight.js/lib/languages/typescript';
|
||||
import xml from 'highlight.js/lib/languages/xml';
|
||||
import sql from 'highlight.js/lib/languages/sql';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import {
|
||||
CheckmarkCircle,
|
||||
@@ -29,8 +44,12 @@
|
||||
HelpCircleOutline,
|
||||
RemoveCircleOutline,
|
||||
} from '@vicons/ionicons5';
|
||||
import { useMessage } from 'naive-ui';
|
||||
|
||||
hljs.registerLanguage('goLang', goLang);
|
||||
hljs.registerLanguage('go', go);
|
||||
hljs.registerLanguage('ts', typescript);
|
||||
hljs.registerLanguage('sql', sql);
|
||||
hljs.registerLanguage('vue', xml);
|
||||
|
||||
interface Props {
|
||||
previewModel: any;
|
||||
@@ -41,7 +60,8 @@
|
||||
previewModel: cloneDeep({ views: {} }),
|
||||
showModal: false,
|
||||
});
|
||||
|
||||
const message = useMessage();
|
||||
const content = ref('');
|
||||
const views = computed(() => {
|
||||
let tmpViews: any = [];
|
||||
let i = 0;
|
||||
@@ -69,12 +89,31 @@
|
||||
}
|
||||
return tmpViews;
|
||||
});
|
||||
|
||||
function getFileExtension(path: string): string {
|
||||
const parts = path.split('.');
|
||||
if (parts.length > 1) {
|
||||
return parts[parts.length - 1];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function handleCopy(code: string) {
|
||||
content.value = code;
|
||||
setTimeout(function () {
|
||||
const copyVal = document.getElementById('copy-code');
|
||||
copyVal.select();
|
||||
document.execCommand('copy');
|
||||
message.success('已复制');
|
||||
}, 20);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
::v-deep(.alert-margin) {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
::v-deep(.tag-margin) {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
@@ -85,4 +124,38 @@
|
||||
color: #e0e2e4;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
::v-deep(.code-vue .hljs-tag) {
|
||||
color: rgb(242, 197, 92);
|
||||
}
|
||||
|
||||
::v-deep(.code-vue .hljs-name) {
|
||||
color: rgb(242, 197, 92);
|
||||
}
|
||||
|
||||
::v-deep(.code-vue .hljs-attr) {
|
||||
color: rgb(49, 104, 213);
|
||||
}
|
||||
|
||||
::v-deep(.code-go .hljs-params) {
|
||||
color: rgb(49, 104, 213);
|
||||
}
|
||||
|
||||
::v-deep(.code-ts .hljs-params) {
|
||||
color: rgb(49, 104, 213);
|
||||
}
|
||||
|
||||
::v-deep(.code-ts .hljs-property) {
|
||||
color: rgb(49, 104, 213);
|
||||
}
|
||||
|
||||
::v-deep(.code-ts .hljs-function) {
|
||||
color: rgb(49, 104, 213);
|
||||
}
|
||||
|
||||
#copy-code {
|
||||
position: fixed;
|
||||
top: -100px;
|
||||
left: -100px;
|
||||
}
|
||||
</style>
|
||||
|
||||
133
web/src/views/develop/code/components/SetFuncDict.vue
Normal file
133
web/src/views/develop/code/components/SetFuncDict.vue
Normal file
@@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-modal
|
||||
title="设置选项字段"
|
||||
v-model:show="showModal"
|
||||
:block-scroll="false"
|
||||
:mask-closable="false"
|
||||
:show-icon="false"
|
||||
preset="dialog"
|
||||
>
|
||||
<n-form
|
||||
:model="formValue"
|
||||
:rules="rules"
|
||||
ref="formRef"
|
||||
label-placement="left"
|
||||
:label-width="100"
|
||||
class="py-4"
|
||||
>
|
||||
<n-form-item label="选项值" path="valueColumn">
|
||||
<n-select
|
||||
filterable
|
||||
tag
|
||||
placeholder="请选择"
|
||||
:options="columnsOption"
|
||||
v-model:value="formValue.valueColumn"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="选项名称" path="labelColumn">
|
||||
<n-select
|
||||
filterable
|
||||
tag
|
||||
placeholder="请选择"
|
||||
:options="columnsOption"
|
||||
v-model:value="formValue.labelColumn"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
<template #action>
|
||||
<n-space>
|
||||
<n-button @click="closeForm">取消</n-button>
|
||||
<n-button type="info" @click="confirmForm">保存</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { rules } from '@/views/addons/stock/itemBrand/model';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { Edit } from '@/api/addons/stock/itemClass';
|
||||
|
||||
interface Props {
|
||||
columnsOption: any;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
columnsOption: [],
|
||||
});
|
||||
|
||||
const rules = {
|
||||
valueColumn: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
type: 'string',
|
||||
message: '选项值不能为空',
|
||||
},
|
||||
labelColumn: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
type: 'string',
|
||||
message: '选项名称不能为空',
|
||||
},
|
||||
};
|
||||
|
||||
const message = useMessage();
|
||||
const emit = defineEmits(['update']);
|
||||
const showModal = ref(false);
|
||||
const formRef = ref();
|
||||
const formValue = ref({
|
||||
valueColumn: null,
|
||||
labelColumn: null,
|
||||
});
|
||||
|
||||
function openModal(state) {
|
||||
showModal.value = true;
|
||||
if (!state) {
|
||||
state = {
|
||||
valueColumn: null,
|
||||
labelColumn: null,
|
||||
};
|
||||
}
|
||||
|
||||
if (!state.valueColumn) {
|
||||
const item = props.columnsOption.find((item) => item.value === 'id');
|
||||
if (item) {
|
||||
state.valueColumn = item.value;
|
||||
}
|
||||
}
|
||||
|
||||
if (!state.labelColumn) {
|
||||
const item = props.columnsOption.find((item) => item.value === 'title' || item.value === 'name');
|
||||
if (item) {
|
||||
state.labelColumn = item.value;
|
||||
}
|
||||
}
|
||||
formValue.value = cloneDeep(state);
|
||||
emit('update', formValue.value);
|
||||
}
|
||||
|
||||
function closeForm() {
|
||||
showModal.value = false;
|
||||
}
|
||||
|
||||
function confirmForm(e) {
|
||||
e.preventDefault();
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
emit('update', formValue.value);
|
||||
closeForm();
|
||||
} else {
|
||||
message.error('请填写完整信息');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
openModal,
|
||||
});
|
||||
</script>
|
||||
@@ -1,4 +1,5 @@
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { isJsonString } from '@/utils/is';
|
||||
|
||||
export const genFileObj = {
|
||||
meth: 1,
|
||||
@@ -24,7 +25,7 @@ export const genInfoObj = {
|
||||
varName: '',
|
||||
options: {
|
||||
headOps: ['add', 'batchDel', 'export'],
|
||||
columnOps: ['edit', 'del', 'view', 'status', 'switch', 'check'],
|
||||
columnOps: ['edit', 'del', 'view', 'status', 'check'],
|
||||
autoOps: ['genMenuPermissions', 'runDao', 'runService'],
|
||||
join: [],
|
||||
menu: {
|
||||
@@ -32,6 +33,17 @@ export const genInfoObj = {
|
||||
icon: 'MenuOutlined',
|
||||
sort: 0,
|
||||
},
|
||||
tree: {
|
||||
titleColumn: null,
|
||||
styleType: 1,
|
||||
},
|
||||
funcDict: {
|
||||
valueColumn: null,
|
||||
labelColumn: null,
|
||||
},
|
||||
presetStep: {
|
||||
formGridCols: 1,
|
||||
},
|
||||
},
|
||||
dbName: '',
|
||||
tableName: '',
|
||||
@@ -54,6 +66,8 @@ export const selectListObj = {
|
||||
dictMode: [],
|
||||
whereMode: [],
|
||||
buildMeth: [],
|
||||
tableAlign: [],
|
||||
treeStyleType: [],
|
||||
};
|
||||
|
||||
export function newState(state) {
|
||||
@@ -62,3 +76,67 @@ export function newState(state) {
|
||||
}
|
||||
return cloneDeep(genInfoObj);
|
||||
}
|
||||
|
||||
export const formGridColsOptions = [
|
||||
{
|
||||
value: 1,
|
||||
label: '一行一列',
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '一行两列',
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: '一行三列',
|
||||
},
|
||||
{
|
||||
value: 4,
|
||||
label: '一行四列',
|
||||
},
|
||||
];
|
||||
|
||||
export const formGridSpanOptions = [
|
||||
{
|
||||
value: 1,
|
||||
label: '占一列位置',
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '占两列位置',
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: '占三列位置',
|
||||
},
|
||||
{
|
||||
value: 4,
|
||||
label: '占四列位置',
|
||||
},
|
||||
];
|
||||
|
||||
// 格式化列字段
|
||||
export function formatColumns(columns: any) {
|
||||
if (columns === undefined || columns.length === 0) {
|
||||
columns = [];
|
||||
}
|
||||
|
||||
if (isJsonString(columns)) {
|
||||
columns = JSON.parse(columns);
|
||||
}
|
||||
|
||||
if (columns.length > 0) {
|
||||
for (let i = 0; i < columns.length; i++) {
|
||||
if (!columns[i].formGridSpan) {
|
||||
columns[i].formGridSpan = 1;
|
||||
}
|
||||
if (!columns[i].align) {
|
||||
columns[i].align = 'left';
|
||||
}
|
||||
if (!columns[i].width || columns[i].width < 1) {
|
||||
columns[i].width = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,10 @@
|
||||
|
||||
<template #suffix>
|
||||
<n-space>
|
||||
<n-button type="primary" @click="preview">预览代码</n-button>
|
||||
<n-button type="default" @click="handleBack">返回列表</n-button>
|
||||
<n-button type="primary" :loading="formBtnPreviewLoading" @click="preview"
|
||||
>预览代码</n-button
|
||||
>
|
||||
<n-button type="success" :loading="formBtnLoading" @click="submitBuild"
|
||||
>提交生成</n-button
|
||||
>
|
||||
@@ -87,7 +90,7 @@
|
||||
import EditMasterCell from './components/EditMasterCell.vue';
|
||||
import EditSlaveCell from './components/EditSlaveCell.vue';
|
||||
import { Selects, View, Preview, Build, Edit } from '@/api/develop/code';
|
||||
import { selectListObj, newState } from '@/views/develop/code/components/model';
|
||||
import { selectListObj, newState, formatColumns } from '@/views/develop/code/components/model';
|
||||
import PreviewTab from '@/views/develop/code/components/PreviewTab.vue';
|
||||
import { isJsonString } from '@/utils/is';
|
||||
|
||||
@@ -108,6 +111,7 @@
|
||||
const slavePanels = ref<any>([]);
|
||||
const showModal = ref(false);
|
||||
const formBtnLoading = ref(false);
|
||||
const formBtnPreviewLoading = ref(false);
|
||||
const previewModel = ref<any>();
|
||||
const dialog = useDialog();
|
||||
const notification = useNotification();
|
||||
@@ -123,15 +127,27 @@
|
||||
|
||||
async function getGenInfo() {
|
||||
let tmp = await View({ id: genId });
|
||||
// 导入主表数据
|
||||
tmp.masterColumns = formatColumns(tmp.masterColumns);
|
||||
|
||||
// 导入生成选项
|
||||
if (isJsonString(tmp.options)) {
|
||||
tmp.options = JSON.parse(tmp.options);
|
||||
}
|
||||
|
||||
if (tmp.masterColumns === undefined || tmp.masterColumns.length === 0) {
|
||||
tmp.masterColumns = [];
|
||||
// 预设流程
|
||||
if (!tmp.options.presetStep) {
|
||||
tmp.options.presetStep = {
|
||||
formGridCols: 1,
|
||||
};
|
||||
}
|
||||
if (isJsonString(tmp.masterColumns)) {
|
||||
tmp.masterColumns = JSON.parse(tmp.masterColumns);
|
||||
|
||||
// 树表
|
||||
if (!tmp.options.tree) {
|
||||
tmp.options.tree = {
|
||||
titleColumn: null,
|
||||
styleType: 1,
|
||||
};
|
||||
}
|
||||
|
||||
genInfo.value = tmp;
|
||||
@@ -146,12 +162,12 @@
|
||||
handleClose('主表字段');
|
||||
}
|
||||
|
||||
if (newVal.options.join !== undefined) {
|
||||
if (newVal && newVal.options && newVal.options.join !== undefined) {
|
||||
slavePanels.value = [];
|
||||
for (let i = 0; i <= newVal.options.join.length; i++) {
|
||||
if (newVal.options.join[i]?.alias !== undefined && newVal.options.join[i]?.alias !== '') {
|
||||
for (let i = 0; i < newVal.options.join.length; i++) {
|
||||
if (newVal.options.join[i]?.alias) {
|
||||
handleSlaveAdd(
|
||||
'关联表[ ' + newVal.options.join[i]?.alias + ' ]',
|
||||
'关联表[ ' + newVal.options.join[i].alias + ' ]',
|
||||
newVal.options.join[i]
|
||||
);
|
||||
}
|
||||
@@ -195,14 +211,21 @@
|
||||
selectList.value = await Selects({});
|
||||
};
|
||||
|
||||
async function preview() {
|
||||
previewModel.value = await Preview(genInfo.value);
|
||||
showModal.value = true;
|
||||
function preview() {
|
||||
formBtnPreviewLoading.value = true;
|
||||
Preview(genInfo.value)
|
||||
.then((res) => {
|
||||
previewModel.value = res;
|
||||
showModal.value = true;
|
||||
})
|
||||
.finally(() => {
|
||||
formBtnPreviewLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
function submitBuild() {
|
||||
dialog.warning({
|
||||
title: '警告',
|
||||
dialog.info({
|
||||
title: '提示',
|
||||
content: '你确定要提交生成吗?',
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
@@ -216,15 +239,12 @@
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function submitSave() {
|
||||
dialog.warning({
|
||||
title: '警告',
|
||||
dialog.info({
|
||||
title: '提示',
|
||||
content: '你确定要保存生成配置吗?',
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
@@ -233,18 +253,15 @@
|
||||
message.success('操作成功');
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function buildSuccessNotify() {
|
||||
let count = 6;
|
||||
let count = 10;
|
||||
const n = notification.success({
|
||||
title: '生成提交成功',
|
||||
content: `如果你使用的热编译,页面将在 ${count} 秒后自动刷新即可生效。否则请手动重启服务后刷新页面!`,
|
||||
duration: 6000,
|
||||
duration: 10000,
|
||||
closable: false,
|
||||
onAfterEnter: () => {
|
||||
const minusCount = () => {
|
||||
@@ -261,6 +278,18 @@
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function handleBack() {
|
||||
dialog.info({
|
||||
title: '提示',
|
||||
content: '你确定要返回生成列表?系统不会主动保存更改',
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: () => {
|
||||
router.push({ name: 'develop_code' });
|
||||
},
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
::v-deep(.alert-margin) {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
:actionColumn="actionColumn"
|
||||
@update:checked-row-keys="onCheckedRow"
|
||||
:scroll-x="1090"
|
||||
:resizeHeightOffset="-10000"
|
||||
>
|
||||
<template #tableTitle>
|
||||
<n-button type="primary" @click="addTable">
|
||||
@@ -30,8 +31,7 @@
|
||||
</template>
|
||||
立即生成
|
||||
</n-button>
|
||||
|
||||
<n-button type="error" @click="batchDelete" :disabled="batchDeleteDisabled">
|
||||
<n-button type="error" @click="batchDelete" :disabled="batchDeleteDisabled" class="min-left-space">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<DeleteOutlined />
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
<n-modal
|
||||
v-model:show="showModal"
|
||||
:mask-closable="false"
|
||||
:show-icon="false"
|
||||
preset="dialog"
|
||||
title="立即生成"
|
||||
@@ -302,10 +303,10 @@
|
||||
};
|
||||
|
||||
const actionColumn = reactive({
|
||||
width: 220,
|
||||
width: 180,
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
// fixed: 'right',
|
||||
fixed: 'right',
|
||||
render(record) {
|
||||
return h(TableAction as any, {
|
||||
style: 'button',
|
||||
|
||||
Reference in New Issue
Block a user