明树Git Lab

Commit 6ca05967 authored by yangyajing's avatar yangyajing

项目管理动态表头、级联选择、前端xlsx导出

parent 47077233
Pipeline #104099 failed with stage
in 2 seconds
......@@ -10,6 +10,7 @@
"dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",
"@element-plus/icons": "^0.0.11",
"@element-plus/icons-vue": "^2.3.2",
"@kjgl77/datav-vue3": "^1.7.4",
"axios": "^1.13.2",
"echarts": "^6.0.0",
......@@ -18,7 +19,8 @@
"less-loader": "^12.3.0",
"pinia": "^3.0.4",
"vue": "^3.5.24",
"vue-router": "^4.6.3"
"vue-router": "^4.6.3",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@vitejs/plugin-vue": "^6.0.1",
......@@ -1144,6 +1146,15 @@
}
}
},
"node_modules/adler-32": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
"integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==",
"license": "Apache-2.0",
"engines": {
"node": ">=0.8"
}
},
"node_modules/async-validator": {
"version": "4.2.5",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
......@@ -1184,6 +1195,28 @@
"node": ">= 0.4"
}
},
"node_modules/cfb": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz",
"integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
"license": "Apache-2.0",
"dependencies": {
"adler-32": "~1.3.0",
"crc-32": "~1.2.0"
},
"engines": {
"node": ">=0.8"
}
},
"node_modules/codepage": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz",
"integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==",
"license": "Apache-2.0",
"engines": {
"node": ">=0.8"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
......@@ -1206,6 +1239,18 @@
"url": "https://github.com/sponsors/mesqueeb"
}
},
"node_modules/crc-32": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
"license": "Apache-2.0",
"bin": {
"crc32": "bin/crc32.njs"
},
"engines": {
"node": ">=0.8"
}
},
"node_modules/csstype": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
......@@ -1536,6 +1581,15 @@
"node": ">= 6"
}
},
"node_modules/frac": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
"integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==",
"license": "Apache-2.0",
"engines": {
"node": ">=0.8"
}
},
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
......@@ -2047,6 +2101,18 @@
"node": ">=0.10.0"
}
},
"node_modules/ssf": {
"version": "0.11.2",
"resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
"integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
"license": "Apache-2.0",
"dependencies": {
"frac": "~1.1.2"
},
"engines": {
"node": ">=0.8"
}
},
"node_modules/superjson": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.5.tgz",
......@@ -2217,6 +2283,45 @@
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g=="
},
"node_modules/wmf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
"integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==",
"license": "Apache-2.0",
"engines": {
"node": ">=0.8"
}
},
"node_modules/word": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz",
"integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==",
"license": "Apache-2.0",
"engines": {
"node": ">=0.8"
}
},
"node_modules/xlsx": {
"version": "0.18.5",
"resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
"integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
"license": "Apache-2.0",
"dependencies": {
"adler-32": "~1.3.0",
"cfb": "~1.2.1",
"codepage": "~1.15.0",
"crc-32": "~1.2.1",
"ssf": "~0.11.2",
"wmf": "~1.0.1",
"word": "~0.3.0"
},
"bin": {
"xlsx": "bin/xlsx.njs"
},
"engines": {
"node": ">=0.8"
}
},
"node_modules/zrender": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/zrender/-/zrender-6.0.0.tgz",
......@@ -2902,6 +3007,11 @@
}
}
},
"adler-32": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
"integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A=="
},
"async-validator": {
"version": "4.2.5",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
......@@ -2936,6 +3046,20 @@
"function-bind": "^1.1.2"
}
},
"cfb": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz",
"integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
"requires": {
"adler-32": "~1.3.0",
"crc-32": "~1.2.0"
}
},
"codepage": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz",
"integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA=="
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
......@@ -2952,6 +3076,11 @@
"is-what": "^3.14.1"
}
},
"crc-32": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="
},
"csstype": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
......@@ -3178,6 +3307,11 @@
"mime-types": "^2.1.12"
}
},
"frac": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
"integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA=="
},
"fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
......@@ -3511,6 +3645,14 @@
"resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
"integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ=="
},
"ssf": {
"version": "0.11.2",
"resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
"integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
"requires": {
"frac": "~1.1.2"
}
},
"superjson": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.5.tgz",
......@@ -3591,6 +3733,30 @@
}
}
},
"wmf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
"integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw=="
},
"word": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz",
"integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA=="
},
"xlsx": {
"version": "0.18.5",
"resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
"integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
"requires": {
"adler-32": "~1.3.0",
"cfb": "~1.2.1",
"codepage": "~1.15.0",
"crc-32": "~1.2.1",
"ssf": "~0.11.2",
"wmf": "~1.0.1",
"word": "~0.3.0"
}
},
"zrender": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/zrender/-/zrender-6.0.0.tgz",
......
......@@ -20,7 +20,8 @@
"less-loader": "^12.3.0",
"pinia": "^3.0.4",
"vue": "^3.5.24",
"vue-router": "^4.6.3"
"vue-router": "^4.6.3",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@vitejs/plugin-vue": "^6.0.1",
......
......@@ -514,7 +514,7 @@ const handleNextClick = (val) => {
.common-table {
background: #fff;
border-radius: 8px;
padding: 20px;
padding: 10px 20px;
.table-header {
display: flex;
......@@ -591,10 +591,10 @@ const handleNextClick = (val) => {
line-height: 45px;
}
}
.el-table__cell {
.cell {
text-align: center;
}
}
// .el-table__cell {
// .cell {
// text-align: center;
// }
// }
}
</style>
......@@ -55,7 +55,7 @@
:index="child.path"
style="padding-left: 20px !important"
>
<el-icon><component :is="child.meta?.icon || ''" /></el-icon>
<el-icon><component v-if="child.meta?.icon" :is="child.meta?.icon" /></el-icon>
<span>{{ child.meta?.menuName || child.name }}</span>
</el-menu-item>
</template>
......@@ -74,7 +74,7 @@
<script setup>
import { computed, h, resolveComponent } from "vue";
import { useRouter } from "vue-router";
import { useRouter, useRoute } from "vue-router";
const router = useRouter();
......
......@@ -39,6 +39,13 @@ const routes = [
showInMenu: false // 不在菜单中显示
}
},
{
path: '/templateManage',
name: 'templateManage',
title: '模板管理',
component: () => import('@/views/managePage/templateManage.vue'),
meta: { menuName: '模板管理', icon: 'Management' }
},
{
path: '/systemManage',
name: '系统管理',
......
......@@ -241,7 +241,9 @@
<el-col :span="6">
<div class="col-title">投资属性分类</div>
<el-form-item label="一级分类">
<el-select v-model="formData.tzsxyjfl" placeholder="请选择">
<el-select v-model="formData.tzsxyjfl" placeholder="请选择"
@change="changeTzsxyjfl"
>
<el-option v-for="item in tzsxyjflList" :key="item.value"
:label="item.value" :value="item.key"
></el-option>
......@@ -249,7 +251,9 @@
</el-form-item>
<el-form-item label="二级分类">
<el-select v-model="formData.tzsxejfl" placeholder="请选择">
<el-option label="1" value="1" />
<el-option v-for="item in tzsxejflList" :key="item.value"
:label="item.value" :value="item.key"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="投资板块">
......@@ -301,9 +305,13 @@
</el-col>
<el-col :span="12">
<el-form-item label="国民经济行业">
<el-select v-model="formData.gmjjhy" placeholder="请选择">
<el-option label="1" value="1" />
</el-select>
<el-tree-select
v-model="formData.gmjjhy"
:data="gmjjhyList"
multiple
show-checkbox
:render-after-expand="false"
/>
</el-form-item>
</el-col>
</el-row>
......@@ -764,7 +772,9 @@
"建设规模(实物量指标)", "股东信息", "项目必要性及可行性", "立项资料", "项目投资总额(全口径)",
"财务评价指标", "核心边界条件", "项目立项信息", "审批意见"
]);
let formData = reactive({});
let formData = reactive({
gmjjhy: ["1.1", "2.2"]
});
let loading = ref(false);
// 建设规模(实物量指标)
let swlzbData = reactive([]);
......@@ -960,8 +970,45 @@
let qxgjList = reactive([]); // 区县(境内)/国家(境外)
let xmqyList = reactive([]); // 项目区域
let bzList = reactive([]); // 币种
let tzsxyjflList = reactive([]); // 投资属性一级分类
let lxzzspyjList = reactive([]); // 立项最终审批意见
let tzsxyjflList = ref([]); // 投资属性一级分类
let tzsxejflList = ref([]); // 投资属性二级分类
const changeTzsxyjfl = (val) => {
if (val) {
let selectData = tzsxyjflList.value.filter(item => item.key === val);
tzsxejflList.value = selectData[0] && selectData[0].children || [];
}
};
let gmjjhyList = ref([
{
value: "1",
label: "一级1",
children: [
{
value: "1.1",
label: "二级1.1"
},
{
value: "1.2",
label: "二级1.2"
}
]
},
{
value: "2",
label: "一级2",
children: [
{
value: "2.1",
label: "二级2.1"
},
{
value: "2.2",
label: "二级2.2"
}
]
}
]); //国民经济行业
let lxzzspyjList = ref([]); // 立项最终审批意见
const getResourceData = () => {
proxy.$post({
url: "/api/resource/listResourceAll",
......@@ -981,7 +1028,7 @@
// 计量币种
bzList = data.bizhong || [];
// 投资分类
tzsxyjflList = data.tzsxyjfl || [];
tzsxyjflList.value = data.tzsxyjfl || [];
// 项目立项信息
lxzzspyjList = data.lxzzspyj || [];
}
......
......@@ -3,12 +3,15 @@
<div class="project-manage-header">
<div class="header-left"></div>
<div class="header-right">
<el-button type="primary" @click="showFieldsModal">表头筛选</el-button>
<el-button type="primary" @click="addProject">新增</el-button>
</div>
</div>
<div class="project-manage-content" v-loading="loading">
<common-table
:tableHeight="tableHeight"
:autoHeight="true"
:maxRows="10"
:rowHeight="40"
:data="tableData"
:columns="tableColumns"
:total="total"
......@@ -47,6 +50,27 @@
<el-pagination background layout="prev, pager, next" :total="1000" />
</div> -->
</div>
<el-dialog v-model="filedsModalShow"
modal-class="fields-modal"
title="筛选查询" width="50%" top="10vh"
>
<common-table
:data="tableFields"
:columns="fieldsTableColumns"
:selection="true"
:border="true"
:pagination="false"
:autoHeight="true"
:rowHeight="40"
@selection-change="handleFieldsSelectChange"
></common-table>
<template #footer>
<div class="dialog-footer">
<el-button @click="cancelFieldsModal">取消</el-button>
<el-button type="primary" @click="confirmFieldsModal">确定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
......@@ -64,7 +88,7 @@
// 计算表格高度
let tableData = ref([]);
const tableColumns = reactive([
let tableColumns = ref([
{
prop: "projectName",
label: "项目名称",
......@@ -81,9 +105,57 @@
width: 160,
slot: "operations",
fixed: "right",
align: "center",
align: "center"
}
]);
// 获取可显示表头项
let filedsModalShow = ref(false);
let tableFields = reactive([]);
const fieldsTableColumns = reactive([
{
prop: "comment",
label: "名称"
}
]);
const getTableFields = () => {
proxy.$post({
url: "/api/project/getProjectFields",
data: {},
callback: (data) => {
tableFields = (data[0] && data[0].attributes) || [];
}
})
};
const showFieldsModal = () => {
filedsModalShow.value = true;
}
let selectFields = ref([]);
const handleFieldsSelectChange = (datas) => {
selectFields.value = datas;
};
const cancelFieldsModal = () => {
selectFields.value = [];
filedsModalShow.value = false;
}
const confirmFieldsModal = () => {
tableColumns.value = selectFields.value.map(item => {
return {
prop: item.fieldName,
label: item.comment,
showOverflowTooltip: true
};
}).concat({
prop: "operations",
label: "操作",
width: 160,
slot: "operations",
fixed: "right",
align: "center",
});
filedsModalShow.value = false;
};
const tableHeight = computed(() => {
const headerHeight = 50;
const rowHeight = 45;
......@@ -96,6 +168,7 @@
let total = ref(0);
let currentPage = ref(1);
let pageSize = ref(10);
// 获取列表数据
const getProjectData = () => {
loading.value = true;
proxy.$post({
......@@ -161,6 +234,7 @@
}).catch(() => {})
}
onMounted(() => {
getTableFields();
getProjectData();
})
</script>
......
<template>
<div class="template-manage-container">
<div class="template-manage-header">
<div class="header-left"></div>
<div class="header-right">
<el-button type="primary" @click="addItem">新增</el-button>
<el-button type="primary" @click="exportData">导出</el-button>
</div>
</div>
<div class="project-manage-content">
<el-table :data="tableData" style="width: 100%; height: 100%;" empty-text="暂无数据" border>
<el-table-column type="index" width="50" />
<el-table-column v-for="column in tableColumns" :key="column.prop"
:prop="column.prop" :label="column.label"
>
<template #default="scope">
<el-input v-model="scope.row[column.prop]" />
</template>
</el-table-column>
<el-table-column label="操作" width="60">
<template #default="scope">
<el-button link type="danger" size="small" @click="deleteItem(scope.$index)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>
<script setup>
import { reactive, ref } from "vue";
import * as XLSX from "xlsx";
const tableColumns = reactive([
{
prop: "projectName",
label: "项目名称"
},
{
prop: "tzglzt",
label: "投资管理主体"
},
{
prop: "jcdw",
label: "决策单位"
},
{
prop: "xdpfsj",
label: "下达批复时间"
},
{
prop: "zyx",
label: "重要性"
},
{
prop: "ssjd",
label: "实施阶段"
},
{
prop: "pfnr",
label: "批复内容"
},
{
prop: "pfyjsm",
label: "批复意见落实情况具体说明"
},
{
prop: "lszxqk",
label: "落实(执行)情况"
},
{
prop: "zcclxh",
label: "支撑材料序号"
},
{
prop: "wlsyy",
label: "未落实原因"
},
{
prop: "xybgzcs",
label: "下一步工作措施"
},
{
prop: "yjwcsj",
label: "预计完成时间"
},
{
prop: "zrld",
label: "责任领导"
},
{
prop: "zrbnmjzrr",
label: "责任部门及责任人"
},
{
prop: "sfgx",
label: "是否更新"
},
{
prop: "bz",
label: "备注"
}
]);
let tableData = ref([]);
const addItem = () => {
tableData.value.push({});
}
const deleteItem = (index) => {
ElMessageBox.confirm("确认删除该项?", "提示",{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
tableData.value.splice(index, 1);
}).catch(() => {});
};
const exportData = () => {
// 1. 创建工作簿
const wb = XLSX.utils.book_new()
// 2. 准备数据
let wsData = [["投资项目批复意见落实情况统计表"], []]
// 添加表头
if (tableColumns && tableColumns.length > 0) {
const headerRow = tableColumns.map(h => h.label || h)
wsData.push(headerRow)
}
// 添加数据行
tableData.value.forEach(item => {
if (tableColumns) {
// 按表头配置提取数据
const row = tableColumns.map(header => {
const value = getNestedValue(item, header.prop || header)
return formatCellValue(value, header.formatter)
})
wsData.push(row)
} else {
// 如果没有表头配置,直接使用对象值
const row = Object.values(item)
wsData.push(row)
}
})
// 3. 创建工作表
const ws = XLSX.utils.aoa_to_sheet(wsData)
// 4. 设置列宽(可选)
if (tableColumns) {
const colWidths = tableColumns.map(header => ({
wch: header.width || Math.max(
(header.label || header).length,
...tableData.value.map(item => {
const value = getNestedValue(item, header.prop || header)
return String(value || '').length
})
) * 2
}))
ws['!cols'] = colWidths
}
// 合并标题单元格
ws['!merges'] = [
XLSX.utils.decode_range('A1:Q1') // 合并第一行的 A-E 列
]
// 5. 将工作表添加到工作簿
XLSX.utils.book_append_sheet(wb, ws, 'Sheet1')
// 6. 生成 Excel 文件并下载
XLSX.writeFile(wb, "导出文件.xlsx");
};
// 辅助函数:获取嵌套对象的值
function getNestedValue(obj, path) {
return path.split('.').reduce((prev, curr) => {
return prev ? prev[curr] : null
}, obj)
}
// 辅助函数:格式化单元格值
function formatCellValue(value, formatter) {
if (formatter && typeof formatter === 'function') {
return formatter(value)
}
return value
}
</script>
<style lang="less">
.template-manage{
&-container{
width: 100%;
height: 100%;
padding: 20px;
box-sizing: border-box;
display: flex;
flex-direction: column;
.tab-content{
padding: 10px 15px;
}
}
&-header{
display: flex;
justify-content: space-between;
}
}
</style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment