RuralDatabase/reference/3d-map/renderApiServer/renderVue/renderListView.js

506 lines
18 KiB
JavaScript
Raw Normal View History

2024-06-30 21:39:37 +08:00
//思路1、根据renderController生成的目录将每个目录下的getpage文件读取出来查找<any,和>(`中间的字符串获取到接口返回类型的名称,
//2、将获取到的类型名称从interface目录下读取出来然后查找data:和下一个;之间的字符串用replace方法将空格去掉获取到data的类型名称
//2.1、继续在getpage文件中查找 `符号和`符号间的数据例如`/api/admin/api/get-page`用replace去掉/get-page然后再将/替换成冒号:(用来设置权限)
// 3、将获取到的data的类型名称从interface目录下读取出来然后查找list:和下一个;之间的字符串,用replace方法将[]和空格去掉获取到list的类型名称
// 4、将获取到的list的类型名称从interface目录下读取出来查找大括号{}中的数据将这个字符串放到之前我写好的内容中待改善可以生成到table中每一个字段的column
const content = `
<!--
此代码由renderVue工具自动生成
作者mask
-->
<template>
<div class="my-layout">
<el-card class="mt8" shadow="never" :body-style="{ paddingBottom: '0' }">
<el-form :inline="true" @submit.stop.prevent>
<div class="search-box">
<div class="search-simple-box">
<el-form-item>
<my-select-input v-model="state.basic" :filters="state.filters" />
</el-form-item>
<el-form-item>
<el-link type="primary" @click.prevent="openAdvancedSearch">高级搜索</el-link>
</el-form-item>
</div>
<div class="func-btn-box">
<el-form-item>
<el-checkbox class="mr10" v-model="listView.state.pageInput.isDelete" label="已删除" size="large"
@change="onSearch" />
<el-button type="primary" :loading="listView.state.listLoading" size="default" @click="onSearch"> 查询
</el-button>
<el-button type="warning" size="default" @click="cleanSearchParams"> 重置
</el-button>
<el-button v-auth="'<%= permissionPrefix %>:add'" type="primary" size="default" @click="onAdd"> 新增 </el-button>
<!-- 判断条件需要放到单独的标签中否则切换时会导致渲染问题 -->
<template v-if="!listView.state.pageInput.isDelete">
<el-button :loading="listView.state.batchSoftDeleteLoading" size="default"
v-auth="'<%= permissionPrefix %>:soft-delete'" type="danger" :disabled="!selected.length"
@click="onSelectSoftDelete">
批量删除
</el-button>
</template>
<template v-if="listView.state.pageInput.isDelete">
<el-button :loading="listView.state.batchDeleteLoading" size="default" v-auth="'<%= permissionPrefix %>:delete'"
type="danger" :disabled="!selected.length" @click="onSelectDelete"> 批量彻底删除
</el-button>
<el-button :loading="listView.state.batchRecoveryLoading" size="default" v-auth="'<%= permissionPrefix %>:delete'"
type="success" :disabled="!selected.length" @click="onSelectRefresh">
批量恢复
</el-button>
</template>
<el-button :loading="listView.state.downloadLoading" size="default" v-auth="'<%= permissionPrefix %>:add'"
type="success" @click="onDownload">
下载导入模板 </el-button>
<!-- bind解决this指向的问题 -->
<el-upload v-auth="'<%= permissionPrefix %>:add'" class="upload-import" :action="importObject.importUrl"
:headers="{ 'Authorization': listView.token }"
:on-success="importObject.onImportSuccess.bind(importObject)"
:on-error="importObject.onImportError.bind(importObject)"
:on-progress="importObject.onImportProgress.bind(importObject)" :auto-upload="true"
:show-file-list="false">
<el-button :loading="importObject.importLoading" size="default" type="warning" class="ml10">
导入模板
</el-button>
</el-upload>
</el-form-item>
</div>
</div>
</el-form>
</el-card>
<el-card class="my-fill mt8" shadow="never">
<el-table ref="table" :data="listView.state.list" style="width: 100%" v-loading="listView.state.listLoading"
row-key="id" default-expand-all @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<%- tableColumn %>
<el-table-column label="操作" width="180" fixed="right" header-align="center" align="center">
<template #default="{ row, $index }">
<el-button v-auth="'<%= permissionPrefix %>:update'" size="small" text type="primary" @click.stop="onEdit(row)"
v-if="!row.isDeleted">编辑</el-button>
<el-button v-auth="'<%= permissionPrefix %>:soft-delete'" size="small" text type="danger"
@click.stop="onSoftDelete(row)" v-if="!row.isDeleted">删除</el-button>
<el-button v-auth="'<%= permissionPrefix %>:get'" size="small" text type="warning" @click.stop="onOpenDetail(row)"
v-if="!row.isDeleted">查看</el-button>
<el-button v-auth="'<%= permissionPrefix %>:delete'" size="small" text type="danger" @click.stop="onDelete(row)"
v-if="row.isDeleted">彻底删除</el-button>
<el-button v-auth="'<%= permissionPrefix %>:delete'" size="small" text type="success" @click.stop="onRefresh(row)"
v-if="row.isDeleted">恢复</el-button>
</template>
</el-table-column>
</el-table>
<div class="my-flex my-flex-end" style="margin-top: 20px">
<el-pagination v-model:currentPage="listView.state.pageInput.currentPage"
v-model:page-size="listView.state.pageInput.pageSize" :total="listView.state.total"
:page-sizes="[10, 20, 50, 100]" small background @size-change="onSizeChange" @current-change="onCurrentChange"
layout="total, sizes, prev, pager, next, jumper" />
</div>
</el-card>
<!-- 根据新增接口中是否有字典类型生成sexOptions -->
<FormDialog ref="FormDialogRef" @refresh="onQuery">
</FormDialog>
<DetailDialog ref="detailDialogRef" />
<AdvancedSearch ref="AdvancedSearchRef" v-model="listView.state.isShowAdvancedSearch"
:modelFilter="state.advancedSearchParams" v-model:model-controlinput="state.controlinput" :filters="state.filters"
@get-model-controlinput="getAdvancedSearchControlinput" @getData="getAdvancedSearchData">
</AdvancedSearch>
</div>
</template>
<script lang="ts" setup name="<%= permissionPrefix.replaceAll(':','-') %>">
import { ref, reactive, onMounted, getCurrentInstance, onBeforeMount, defineAsyncComponent, onActivated, onDeactivated } from 'vue'
import { formatterTime } from '/@/utils/format'
import { <%= dirName %>ListOutput } from '/@/api/interface'
import { getDictLabel } from '/@/utils/dictUtils';
import { useDictListInfo } from '/@/stores/dictListInfo';
import { storeToRefs } from 'pinia';
import {
<%= lowerCasedirName %>GetPage,
<%= lowerCasedirName %>BatchDelete,
<%= lowerCasedirName %>Delete,
<%= lowerCasedirName %>BatchSoftDelete,
<%= lowerCasedirName %>BatchRecovery,
<%= lowerCasedirName %>DownloadTemplate,
<%= lowerCasedirName %>SoftDelete,
<%= lowerCasedirName %>Recovery,
} from '/@/api/controller'
import { useListView } from '/@/hooks/useListView'
const storesUseUserInfo = useDictListInfo()
const { dictListInfo } = storeToRefs(storesUseUserInfo)
// 引入组件
const AdvancedSearch = defineAsyncComponent(() => import('/@/components/AdvancedSearch/index.vue'))
const FormDialog = defineAsyncComponent(() => import('./components/form-dialog.vue'))
const DetailDialog = defineAsyncComponent(() => import('./components/detail-dialog.vue'))
const MySelectInput = defineAsyncComponent(() => import('/@/components/my-select-input/index.vue'))
const { proxy } = getCurrentInstance() as any
const FormDialogRef = ref()
const detailDialogRef = ref()
const listView = useListView()
const state = reactive({
//基础搜索
basic: {} as DynamicFilterInfo,
//AdvancedSearch组件中的ControlScreenInput组件 作用:回显
controlinput: [] as Array<DynamicFilterInfo>,
//高级搜索参数
advancedSearchParams: {},
//高级搜索
filters: [
<% filters.forEach(function(itemKey,itemIndex) { %>{
field: '<%= itemKey.field %>',
operator: '<%= itemKey.operator %>',
description: '<%= itemKey.description %>',
componentName: '<%= itemKey.componentName %>',
defaultSelect: <%= !itemIndex %>,
},<% }) %>
] as Array<DynamicFilterInfo>,
})
//处理获取列表的请求参数
function initListParams() {
//state.controlinput 为 ControlScreenInput组件过滤的参数
//state.filter 为 其余筛选组件过滤的参数
let params = [state.basic, ...Object.values(state.advancedSearchParams)]
console.log(state.advancedSearchParams);
let filters = params.map((item: any) => {
if ((typeof item.value === 'object' && item.value.length) || (typeof item.value == 'string' && item.value) || typeof item.value == 'number' || typeof item.value == 'boolean') {
return item
} else {
return {}
}
}).filter(obj => Object.keys(obj).length !== 0)
listView.state.pageInput.dynamicFilter = {
...listView.state.pageInput.dynamicFilter,
//用来筛选表中没有储存的数据
filters: filters
}
}
function onQuery() {
//注意这里的<%= lowerCasedirName %>GetPage的规则是 接口的http请求方式 + 接口的完整路径) (驼峰命名,首字母小写)
initListParams()
listView.onQuery(<%= lowerCasedirName %>GetPage)
}
//搜索
function onSearch() {
listView.initPageInput()
onQuery()
}
const selected: any = ref([])
//表格多选
const handleSelectionChange = (selection: any) => {
selected.value = selection
}
//将选中的多选内容装换成只含id的数组
function initSelectParams(): number[] | [] {
return selected.value.map((item: any) => {
return item.id
})
}
//批量删除
function onSelectSoftDelete() {
listView.onMultipleSoftDelete(<%= lowerCasedirName %>BatchSoftDelete, initSelectParams(), onSearch)
}
//批量彻底删除
function onSelectDelete() {
listView.onMultipleDelete(<%= lowerCasedirName %>BatchDelete, initSelectParams(), onSearch)
}
//批量恢复
function onSelectRefresh() {
listView.onMultipleRecovery(<%= lowerCasedirName %>BatchRecovery, initSelectParams(), onSearch)
}
//恢复 注意修改row.name
const onRefresh = async (row: <%= dirName %>ListOutput) => {
proxy.$modal
.confirmDelete(\`确定要恢复当前数据?\`)
.then(async () => {
if (row.id) {
await <%= lowerCasedirName %>Recovery({ id: row.id })
onQuery()
} else {
proxy.$modal.msgError('id为空')
}
})
.catch(() => { })
}
//下载模板
function onDownload() {
listView.onDownload(<%= lowerCasedirName %>DownloadTemplate)
}
//软删除 注意修改row.name
const onSoftDelete = (row: <%= dirName %>ListOutput) => {
proxy.$modal
.confirmDelete(\`确定要删除当前数据?\`)
.then(async () => {
try {
if (row.id == undefined) return proxy.$modal.msgError('id不能为空')
let res = await <%= lowerCasedirName %>SoftDelete({ id: row.id })
if (res.success) {
onQuery()
proxy.$modal.msgSuccess('删除成功')
} else {
proxy.$modal.msgError(res.msg)
}
} catch (error) {
}
})
}
//彻底删除 注意修改row.name
const onDelete = (row: <%= dirName %>ListOutput) => {
proxy.$modal
.confirmDelete(\`确定要删除当前数据?\`)
.then(async () => {
if (row.id) {
try {
let res = await <%= lowerCasedirName %>Delete({ id: row.id })
if (res.success) {
onQuery()
proxy.$modal.msgSuccess('删除成功')
} else {
proxy.$modal.msgError(res.msg)
}
} catch (error) {
proxy.$modal.msgError(error)
}
} else {
proxy.$modal.msgError('id为空')
}
})
}
const importObject = new listView.ImportFile(onSearch, '/api/demo/demo/import')
const onAdd = () => {
console.log(FormDialogRef.value);
FormDialogRef.value.open()
}
const onEdit = (row: any) => {
FormDialogRef.value.open(row)
}
// 打开详情
const onOpenDetail = (row: any) => {
detailDialogRef.value.open(row)
}
const onSizeChange = (val: number) => {
listView.state.pageInput.pageSize = val
onQuery()
}
const onCurrentChange = (val: number) => {
listView.state.pageInput.currentPage = val
onQuery()
}
/**
* 打开高级搜索
*/
function openAdvancedSearch() {
listView.state.isShowAdvancedSearch = true
}
/**
* 重置搜索
*/
const AdvancedSearchRef = ref()
function cleanSearchParams() {
state.basic.value = ''
AdvancedSearchRef.value.exportReset()
}
/**
* 获取高级搜索中的数据
*/
function getAdvancedSearchData(pararm: any) {
state.advancedSearchParams = JSON.parse(JSON.stringify(pararm)) // 深拷贝防止修改state中的数据
}
function getAdvancedSearchControlinput(controlinput: DynamicFilterInfo[]) {
state.controlinput = JSON.parse(JSON.stringify(controlinput)) // 深拷贝防止修改state中的数据
}
onActivated(() => {
// listView.onQuery(<%= lowerCasedirName %>GetPage(state.pageInput))
// !!!!!!!!!!!注意这里<%= dirName %>需要根据列表名称进行改动,不然有可能会出问题
// 表单组件中的<%= dirName %>也需要更改
// (页面缓存时使用)
// eventBus.off('refresh<%= dirName %>')
// eventBus.on('refresh<%= dirName %>', () => {
// onQuery()
// })
})
onDeactivated(() => {
//这里销毁 (页面缓存时使用)
// eventBus.off('refresh<%= dirName %>')
})
/**
* 下一步封装计划
*
* 1. 列表中操作栏的按钮需要封装成一个按钮组件才能拥有自己单独的loading
* 2. 封装表单新增/修改方法
*
* **/
onMounted(() => {
onQuery()
})
</script>
<style scoped lang="scss"></style>
`;
let ejs = require('ejs');
/**
* 生成表格的列
* @param {*} barr { label: string, prop: string, type: string }[]
*/
function renderElTableColumn(barr) {
/**
* 生成的el-table-column数据
*/
let tableColumn = '';
// 遍历过滤后的数组
for (let i = 0; i < barr.length; i++) {
// 如果对象标签中包含字典
if (barr[i].label.indexOf('字典') != -1) {
// 调用renderDictColumn函数生成el-table-column数据
tableColumn += renderDictColumn(barr[i]);
// 如果对象标签中包含是否
} else if (barr[i].label.indexOf('是否') != -1) {
// 调用renderBooleanColumn函数生成el-table-column数据
tableColumn += renderBooleanColumn(barr[i]);
// 如果对象标签中包含日期
} else if (barr[i].label.indexOf('日期') != -1) {
// 调用renderDateColumn函数生成el-table-column数据
tableColumn += renderDateColumn(barr[i]);
// 如果对象标签中不包含字典、是否、日期
} else {
// 调用renderDateColumn函数生成el-table-column数据
tableColumn += `${`<el-table-column label="${barr[i].label}" prop="${barr[i].prop}" show-overflow-tooltip />\n`}`;
}
}
return tableColumn;
}
/**
* 生成表格的高级搜索参数
* @param {*} barr { label: string, prop: string, type: string }[]
*/
function renderFilters(barr) {
let filters = [];
for (let i = 0; i < barr.length; i++) {
// 如果对象标签中包含字典
if (barr[i].type == 'string') {
filters.push({
field: barr[i].prop,
operator: 'Contains',
description: barr[i].label,
componentName: 'el-input',
defaultSelect: !i,
});
}
}
return filters;
}
/**
* 生成表格列表页
* @param {array} arr
* @param {string} dirName 文件夹名称
* @param {string} permissionPrefix 权限前缀
* @returns
*/
function renderTable(arr, dirName, permissionPrefix) {
/**
* 生成的el-table-column数据
*/
let tableColumn = '';
let filters = [];
// 过滤掉不需要生成的字段
let filter = ['附件'];
// 过滤数组
let barr = arr.filter((item) => {
// 声明一个布尔值
let isFlag = true;
// 遍历过滤字段
filter.map((filterItem) => {
// 如果过滤字段在对象标签中则将布尔值设置为false
if (item.label.indexOf(filterItem) !== -1) {
return (isFlag = false);
}
});
// 如果布尔值为false则返回false
if (!isFlag) {
return false;
// 如果布尔值为true则返回true
} else {
return true;
}
});
tableColumn = renderElTableColumn(barr);
filters = renderFilters(barr);
let lowerCasedirName = dirName.charAt(0).toLowerCase() + dirName.slice(1);
let templateStr = ejs.render(content, { barr, permissionPrefix, tableColumn, filters: filters, dirName, lowerCasedirName });
return templateStr;
}
//生成字典行
function renderDictColumn(item) {
return `${`<el-table-column prop="${item.prop}" label="${item.label}" min-width="120" show-overflow-tooltip>
<template #default="{ row }">
{{ getDictLabel(dictListInfo.${item.prop},
row.${item.prop}) }}
</template>
</el-table-column>`}\n`;
}
//生成 是否 字段的行
function renderBooleanColumn(item) {
return `${`<el-table-column label="${item.label}" prop="${item.prop}" >
<template #default="{ row }">
{{ row.${item.prop} ? '是' : '否' }}
</template>
</el-table-column>`}\n`;
}
//生成 日期 字段的行
function renderDateColumn(item) {
return `${`<el-table-column prop="${item.prop}" label="${item.label}" :formatter="formatterTime" min-width="120" />\n`}`;
}
module.exports = {
renderTable,
};