初始代码

This commit is contained in:
wangmingwei
2026-04-21 17:48:26 +08:00
parent d3631949e9
commit 7f9e424a5c
1822 changed files with 288292 additions and 0 deletions

View File

@@ -0,0 +1,127 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" title="生成菜单" @ok="handleSubmit" class="yunzhupaas-release-modal">
<a-alert message="将该报表发布至应用菜单" type="warning" show-icon />
<a-form class="release-main" :colon="false" :model="dataForm" :rules="rules" layout="vertical" ref="formElRef">
<div class="release-item report-item-left">
<a-form-item>
<div class="top-item" :class="{ active: dataForm.pc === 1 }" @click="selectToggle('pc')">
<i class="item-icon icon-ym icon-ym-pc"></i>
<p class="item-title">桌面端</p>
<div class="icon-checked">
<check-outlined />
</div>
</div>
</a-form-item>
<a-form-item label="上级" name="pcModuleParentId" v-if="dataForm.pc">
<YunzhupaasTreeSelect
v-model:value="pcModuleParentId"
:options="treeData"
treeCheckStrictly
multiple
:dropdownMatchSelectWidth="false"
@change="onPcChange" />
</a-form-item>
<a-form-item label="已发布菜单路径" v-if="record.pcIsRelease">
<div class="released">{{ record.pcReleaseName }}</div>
</a-form-item>
</div>
</a-form>
</BasicModal>
</template>
<script lang="ts" setup>
import { getReleaseMenu, createMenu } from '@/api/onlineDev/report';
import { BasicModal, useModalInner } from '@/components/Modal';
import { ref, reactive, toRefs, computed } from 'vue';
import type { FormInstance } from 'ant-design-vue';
import { CheckOutlined } from '@ant-design/icons-vue';
import { getMenuSelectorFilter } from '@/api/system/menu';
import { useMessage } from '@/hooks/web/useMessage';
import { useI18n } from '@/hooks/web/useI18n';
interface State {
dataForm: any;
record: any;
treeData: any[];
pcModuleParentId: any[];
}
const emit = defineEmits(['register', 'reload']);
const { createMessage, createConfirm } = useMessage();
const { t } = useI18n();
const [registerModal, { changeOkLoading, closeModal }] = useModalInner(init);
const formElRef = ref<FormInstance>();
const state = reactive<State>({
dataForm: {
pc: 1,
pcModuleParentId: [],
},
record: {},
treeData: [],
pcModuleParentId: [],
});
const { dataForm, record, treeData, pcModuleParentId } = toRefs(state);
const rules = computed(() => {
let rules: any = {
pcModuleParentId: [],
};
if (!state.record.pcIsRelease) rules.pcModuleParentId = [{ required: true, message: '必填', trigger: 'change', type: 'array' }];
return rules;
});
function init(data) {
state.pcModuleParentId = [];
getReleaseMenu(data.id).then(res => {
state.record = res.data;
const platformRelease = res.data.platformRelease ? JSON.parse(res.data.platformRelease) : {};
state.dataForm = {
pc: platformRelease.pc === 0 ? 0 : 1,
pcModuleParentId: [],
};
formElRef.value?.clearValidate();
});
getMenuOptions(data.id);
}
function getMenuOptions(id) {
getMenuSelectorFilter({ category: 'Web' }, id).then(res => {
state.treeData = res.data.list;
});
}
function onPcChange(data) {
state.dataForm.pcModuleParentId = data.map(o => o.value);
}
function selectToggle(key) {
state.dataForm[key] = state.dataForm[key] === 1 ? 0 : 1;
}
async function handleSubmit() {
try {
if (!state.dataForm.pc) return createMessage.error('请选择发布类型');
const values = await formElRef.value?.validate();
if (!values) return;
const platform = { pc: state.dataForm.pc };
const query = { ...state.dataForm, platformRelease: JSON.stringify(platform) };
const handleRelease = () => {
changeOkLoading(true);
createMenu(state.record.id, query)
.then(res => {
changeOkLoading(false);
createMessage.success(res.msg);
emit('reload');
closeModal();
})
.catch(() => {
changeOkLoading(false);
});
};
if (!state.record.isRelease) return handleRelease();
createConfirm({
iconType: 'warning',
title: t('common.tipTitle'),
content: '发布确定后会覆盖当前线上版本且进行菜单同步,是否继续?',
onOk: handleRelease,
});
} catch (_) {}
}
</script>

View File

@@ -0,0 +1,112 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="dataForm.id ? t('common.editText') : t('common.addText')" @ok="handleSubmit()">
<BasicForm @register="registerForm" />
<template #appendFooter>
<a-button type="primary" :loading="btnLoading" @click="handleSubmit(1)">确定并设计</a-button>
</template>
</BasicModal>
</template>
<script lang="ts" setup>
import { toRefs, reactive } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import formValidate from '@/utils/formValidate';
import { getReportInfo, updateReport, createReport } from '@/api/onlineDev/report';
import { useMessage } from '@/hooks/web/useMessage';
import { useI18n } from '@/hooks/web/useI18n';
interface State {
dataForm: any;
btnLoading: boolean;
}
const state = reactive<State>({
dataForm: {},
btnLoading: false,
});
const { dataForm, btnLoading } = toRefs(state);
const { createMessage } = useMessage();
const { t } = useI18n();
const emit = defineEmits(['register', 'reload', 'design']);
const [registerModal, { closeModal, changeLoading, changeOkLoading }] = useModalInner(init);
const [registerForm, { setFieldsValue, resetFields, validate, updateSchema }] = useForm({
schemas: [
{
field: 'fullName',
label: '名称',
component: 'Input',
componentProps: { placeholder: '请输入', maxlength: 100 },
rules: [{ required: true, trigger: 'blur', message: '必填' }],
},
{
field: 'enCode',
label: '编码',
component: 'Input',
componentProps: { placeholder: '请输入', maxlength: 50 },
rules: [
{ required: true, trigger: 'blur', message: '必填' },
{ validator: formValidate('enCode'), trigger: 'blur' },
],
},
{
field: 'category',
label: '分类',
component: 'Select',
componentProps: { placeholder: '请选择', showSearch: true },
rules: [{ required: true, trigger: 'change', message: '必填' }],
},
{
field: 'sortCode',
label: '排序',
defaultValue: 0,
component: 'InputNumber',
componentProps: { min: 0, max: 999999 },
},
{
field: 'description',
label: '说明 ',
component: 'Textarea',
componentProps: { placeholder: '请输入' },
},
],
});
function init(data) {
resetFields();
state.dataForm.id = data.id || '';
updateSchema([{ field: 'category', componentProps: { options: data.categoryList || [] } }]);
if (state.dataForm.id) {
changeLoading(true);
getReportInfo(state.dataForm.id)
.then(res => {
state.dataForm = res.data;
setFieldsValue(state.dataForm);
changeLoading(false);
})
.catch(() => {
changeLoading(false);
});
}
}
async function handleSubmit(type = 0) {
const values = await validate();
if (!values) return;
type === 1 ? (state.btnLoading = true) : changeOkLoading(true);
const query = { ...values, id: state.dataForm.id };
const formMethod = state.dataForm.id ? updateReport : createReport;
formMethod(query)
.then(res => {
createMessage.success(res.msg);
changeOkLoading(false);
state.btnLoading = false;
closeModal();
emit('reload');
if (!state.dataForm.id) state.dataForm.id = res.data;
if (type == 1) emit('design', { ...values, id: state.dataForm.id });
})
.catch(() => {
changeOkLoading(false);
state.btnLoading = false;
});
}
</script>

View File

@@ -0,0 +1,191 @@
<template>
<div class="yunzhupaas-content-wrapper">
<div class="yunzhupaas-content-wrapper-center">
<div class="yunzhupaas-content-wrapper-content">
<BasicTable @register="registerTable">
<template #tableTitle>
<a-button type="primary" preIcon="icon-ym icon-ym-btn-add" @click="addOrUpdateHandle()">{{ t('common.addText') }}</a-button>
<yunzhupaas-upload-btn url="/api/Report/Actions/Import" accept=".rp" @on-success="reload" type="report" />
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'state'">
<a-tag :color="record.enabledMark == 1 ? 'success' : ''">{{ record.enabledMark == 1 ? '已发布' : '未发布' }}</a-tag>
</template>
<template v-if="column.key === 'action'">
<TableAction :actions="getTableActions(record)" :dropDownActions="getDropDownActions(record)" />
</template>
</template>
</BasicTable>
</div>
</div>
<Form @register="registerForm" @reload="reload" @design="handleDesign" />
<Report @register="registerDesign" @reload="reload" />
<ReportPreview @register="registerPreview" />
<CreateMenuModal @register="registerCreateMenu" />
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { BasicTable, useTable, TableAction, BasicColumn, ActionItem } from '@/components/Table';
import { getReportList, delReport, copy, exportData } from '@/api/onlineDev/report';
import { useModal } from '@/components/Modal';
import { useI18n } from '@/hooks/web/useI18n';
import { useMessage } from '@/hooks/web/useMessage';
import { downloadByUrlReport } from '@/utils/file/download';
import { useBaseStore } from '@/store/modules/base';
import { Report, ReportPreview } from '@/components/Report';
import Form from './Form.vue';
import CreateMenuModal from './CreateMenuModal.vue';
defineOptions({ name: 'onlineDev-report' });
const { t } = useI18n();
const baseStore = useBaseStore();
const { createMessage } = useMessage();
const categoryList = ref<any[]>([]);
const columns: BasicColumn[] = [
{ title: '名称', dataIndex: 'fullName' },
{ title: '编码', dataIndex: 'enCode', width: 200 },
{ title: '分类', dataIndex: 'category', width: 150 },
{ title: '创建人', dataIndex: 'creatorUser', width: 120 },
{ title: '创建时间', dataIndex: 'creatorTime', width: 150, format: 'date|YYYY-MM-DD HH:mm:ss' },
{ title: '最后修改时间', dataIndex: 'lastModifyTime', width: 150, format: 'date|YYYY-MM-DD HH:mm:ss' },
{ title: '排序', dataIndex: 'sortCode', width: 70, align: 'center' },
{ title: '状态', dataIndex: 'state', width: 80, align: 'center' },
];
const [registerTable, { reload, getForm }] = useTable({
api: getReportList,
columns,
useSearchForm: true,
formConfig: {
schemas: [
{
field: 'keyword',
label: t('common.keyword'),
component: 'Input',
componentProps: {
placeholder: t('common.enterKeyword'),
submitOnPressEnter: true,
},
},
{
field: 'category',
label: '分类',
component: 'Select',
componentProps: {
placeholder: '请选择',
},
},
{
field: 'state',
label: '状态',
component: 'Select',
componentProps: {
placeholder: '请选择',
options: [
{ fullName: '未发布', id: 0 },
{ fullName: '已发布', id: 1 },
],
},
},
],
},
actionColumn: {
width: 220,
title: '操作',
dataIndex: 'action',
},
});
const [registerForm, { openModal: openFormModal }] = useModal();
const [registerDesign, { openModal: openDesign }] = useModal();
const [registerPreview, { openModal: openPreviewModal }] = useModal();
const [registerCreateMenu, { openModal: openCreateMenuModal }] = useModal();
function getTableActions(record): ActionItem[] {
return [
{
label: t('common.editText'),
onClick: addOrUpdateHandle.bind(null, record.id),
},
{
label: '设计',
color: 'error',
onClick: handleDesign.bind(null, record),
},
{
label: '生成菜单',
disabled: !record.state,
onClick: handleCreateMenu.bind(null, record),
},
];
}
function getDropDownActions(record): ActionItem[] {
return [
{
label: t('common.previewText'),
ifShow: !!record.state,
onClick: handlePreview.bind(null, record.id),
},
{
label: t('common.copyText'),
ifShow: !!record.state,
modelConfirm: {
content: '您确定要复制该模板, 是否继续?',
onOk: handleCopy.bind(null, record.id),
},
},
{
label: t('common.exportText'),
ifShow: !!record.state,
modelConfirm: {
content: '您确定要导出该模板, 是否继续?',
onOk: handleExport.bind(null, record.id),
},
},
{
label: t('common.delText'),
color: 'error',
modelConfirm: {
onOk: handleDelete.bind(null, record.id),
},
},
];
}
function addOrUpdateHandle(id = '') {
openFormModal(true, { id, categoryList: categoryList.value });
}
function handleExport(id) {
exportData(id).then(res => {
downloadByUrlReport({ url: res.data.url });
});
}
function handleCopy(id) {
copy(id).then(res => {
createMessage.success(res.msg);
reload();
});
}
function handleDelete(id) {
delReport(id).then(res => {
createMessage.success(res.msg);
reload();
});
}
function handleDesign(record) {
openDesign(true, record);
}
function handlePreview(id) {
openPreviewModal(true, { id });
}
async function getOptions() {
categoryList.value = (await baseStore.getDictionaryData('businessType')) as any[];
getForm().updateSchema({ field: 'category', componentProps: { options: categoryList.value } });
}
function handleCreateMenu(data) {
openCreateMenuModal(true, data);
}
onMounted(() => {
getOptions();
});
</script>