实现主从表结构生成;

提取企业版共用组件AuthForm、AuthTable、AuthSelect;
修复大量已知Bug
This commit is contained in:
yubaolee
2021-09-05 21:37:12 +08:00
parent 4d7af5bedf
commit 3c20deb3df
19 changed files with 2792 additions and 1270 deletions

View File

@@ -14,6 +14,7 @@ namespace OpenAuth.WebApi.Controllers
/// </summary>
[Route("api/[controller]/[action]")]
[ApiController]
[ApiExplorerSettings(GroupName = "{ModuleName}接口_{ClassName}s")]
public class {ClassName}sController : ControllerBase
{
private readonly {ModuleCode} _app;

View File

@@ -2,6 +2,6 @@
{
public class Query{ClassName}ListReq : PageReq
{
{ForeignKeyTemplate}
}
}

View File

@@ -1,256 +0,0 @@
<template>
<div class="flex-column">
<sticky :className="'sub-navbar'">
<div class="filter-container">
<el-input @keyup.enter.native="handleFilter" size="mini" style="width: 200px;" class="filter-item" :placeholder="'搜索关键字'" v-model="listQuery.key">
</el-input>
<el-button class="filter-item" size="mini" v-waves icon="el-icon-search" @click="handleFilter">搜索</el-button>
<permission-btn moduleName='{TableName}s' size="mini" v-on:btn-event="onBtnClicked"></permission-btn>
</div>
</sticky>
<div class="app-container flex-item">
<div class="bg-white" style="height: 100%;">
<el-table ref="mainTable" height="calc(100% - 52px)" :key='tableKey' :data="list" v-loading="listLoading" border fit highlight-current-row
style="width: 100%;" @row-click="rowClick" @selection-change="handleSelectionChange">
<el-table-column type="selection" align="center" width="55"></el-table-column>
<template v-for="(headerItem,index) in headerList">
<el-table-column :label="headerItem.description" min-width="120px" :key="index">
<template slot-scope="scope">
<span>{{scope.row[headerItem.key]}}</span>
</template>
</el-table-column>
</template>
<el-table-column align="center" :label="'操作'" width="230" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button>
<el-button v-if="scope.row.disable!=true" size="mini" type="danger" @click="handleModifyStatus(scope.row,true)">停用</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="handleCurrentChange" />
</div>
<el-dialog v-el-drag-dialog class="dialog-mini" width="500px" :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
<el-form :rules="rules" ref="dataForm" :model="temp" label-position="right" label-width="100px">
{DialogFormItem}
</el-form>
<div slot="footer" >
<el-button size="mini" @click="dialogFormVisible = false">取消</el-button>
<el-button size="mini" v-if="dialogStatus=='create'" type="primary" @click="createData">确认</el-button>
<el-button size="mini" v-else type="primary" @click="updateData">确认</el-button>
</div>
</el-dialog>
</div>
</div>
</template>
<script>
import * as {TableName}s from '@/api/{TableName}s'
import waves from '@/directive/waves' // 水波纹指令
import Sticky from '@/components/Sticky'
import permissionBtn from '@/components/PermissionBtn'
import Pagination from '@/components/Pagination'
import elDragDialog from '@/directive/el-dragDialog'
import extend from "@/extensions/delRows.js"
export default {
name: '{TableName}',
components: { Sticky, permissionBtn, Pagination },
mixins: [extend],
directives: {
waves,
elDragDialog
},
data() {
return {
multipleSelection: [], // 列表checkbox选中的值
tableKey: 0,
list: null,
total: 0,
listLoading: true,
listQuery: { // 查询条件
page: 1,
limit: 20,
key: undefined,
appId: undefined
},
statusOptions: [
{ key: true, display_name: '停用' },
{ key: false, display_name: '正常' }
],
temp: {
{Temp}
},
dialogFormVisible: false,
dialogStatus: '',
textMap: {
update: '编辑',
create: '添加'
},
dialogPvVisible: false,
pvData: [],
rules: {
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }]
},
downloadLoading: false,
headerList: []
}
},
filters: {
statusFilter(disable) {
const statusMap = {
false: 'color-success',
true: 'color-danger'
}
return statusMap[disable]
}
},
created() {
this.getList()
},
methods: {
rowClick(row) {
this.$refs.mainTable.clearSelection()
this.$refs.mainTable.toggleRowSelection(row)
},
handleSelectionChange(val) {
this.multipleSelection = val
},
onBtnClicked: function(domId) {
console.log('you click:' + domId)
switch (domId) {
case 'btnAdd':
this.handleCreate()
break
case 'btnEdit':
if (this.multipleSelection.length !== 1) {
this.$message({
message: '只能选中一个进行编辑',
type: 'error'
})
return
}
this.handleUpdate(this.multipleSelection[0])
break
case 'btnDel':
if (this.multipleSelection.length < 1) {
this.$message({
message: '至少删除一个',
type: 'error'
})
return
}
this.handleDelete(this.multipleSelection)
break
default:
break
}
},
getList() {
this.listLoading = true
{TableName}s.getList(this.listQuery).then(response => {
this.list = response.data
response.columnHeaders.forEach((item) => {
item.key = item.key.substring(0, 1).toLowerCase() + item.key.substring(1)
})
this.headerList = response.columnHeaders.filter(u => u.browsable)
this.total = response.count
this.listLoading = false
})
},
handleFilter() {
this.listQuery.page = 1
this.getList()
},
handleSizeChange(val) {
this.listQuery.limit = val
this.getList()
},
handleCurrentChange(val) {
this.listQuery.page = val.page
this.listQuery.limit = val.limit
this.getList()
},
handleModifyStatus(row, disable) { // 模拟修改状态
this.$message({
message: '操作成功',
type: 'success'
})
row.disable = disable
},
resetTemp() {
this.temp = {
{Temp}
}
},
handleCreate() { // 弹出添加框
this.resetTemp()
this.dialogStatus = 'create'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
createData() { // 保存提交
this.$refs['dataForm'].validate((valid) => {
if (valid) {
{TableName}s.add(this.temp).then(() => {
this.list.unshift(this.temp)
this.dialogFormVisible = false
this.$notify({
title: '成功',
message: '创建成功',
type: 'success',
duration: 2000
})
})
}
})
},
handleUpdate(row) { // 弹出编辑框
this.temp = Object.assign({}, row) // copy obj
this.dialogStatus = 'update'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
updateData() { // 更新提交
this.$refs['dataForm'].validate((valid) => {
if (valid) {
const tempData = Object.assign({}, this.temp)
{TableName}s.update(tempData).then(() => {
for (const v of this.list) {
if (v.id === this.temp.id) {
const index = this.list.indexOf(v)
this.list.splice(index, 1, this.temp)
break
}
}
this.dialogFormVisible = false
this.$notify({
title: '成功',
message: '更新成功',
type: 'success',
duration: 2000
})
})
}
})
},
handleDelete(rows) { // 多行删除
this.delrows({TableName}s, rows)
}
}
}
</script>
<style>
.dialog-mini .el-select{
width:100%;
}
</style>

View File

@@ -0,0 +1,414 @@
<!--
* @description: 入库订单界面
* @author: liyubao | xufuxing
* @version: 1.0
* @updateDate: 代码生成器自动生成
-->
<template>
<div class="flex-column">
<sticky :className="'sub-navbar'">
<div class="filter-container">
<el-input @keyup.enter.native="handleFilter" size="mini" style="width: 200px;" class="filter-item" :placeholder="'名称'" v-model="firstQuery.key"> </el-input>
<el-button class="filter-item" size="mini" v-waves icon="el-icon-search" @click="handleFilter">搜索</el-button>
<permission-btn size="mini" v-on:btn-event="onBtnClicked"></permission-btn>
</div>
</sticky>
<div class="app-container flex-item flex-column">
<div class="flex-item">
<el-card shadow="nerver" class="demo-card fh">
<auth-table style="height:calc(100% - 52px)" ref="mainTable" :select-type="'radio'" :table-fields="firstHeaderList" :data="mainList" :v-loading="listLoading" @row-click="rowClickFirstTable"></auth-table>
<pagination v-show="firstTotal > 0" :total="firstTotal" :page.sync="firstQuery.page" :limit.sync="firstQuery.limit" @pagination="handleCurrentChange" />
</el-card>
</div>
<el-row class="flex-item">
<el-col :span="showTitleDialog ? 12 : 0" class="fh form-card">
<el-card shadow="nerver" class="demo-card fh">
<div slot="header">
<span v-if="radio == ''">头信息</span>
<span v-else>{{ radio }}头信息</span>
</div>
<auth-form ref="dataForm" :edit-model="editModel" :form-fields="firstHeaderList" :data="firstTemp" :col-num="3"></auth-form>
</el-card>
</el-col>
<!-- 第二部分多选 -->
<el-col :span="!showTitleDialog ? 24 : 12" class="fh detail-card">
<el-card shadow="nerver" class="demo-card fh" id="secondCard">
<div slot="header">
<i class="show-title-button" :class="showTitleDialog ? 'el-icon-d-arrow-left' : 'el-icon-d-arrow-right'" :title="showTitleDialog ? '展开' : '收缩'" @click="showTitleDialog = !showTitleDialog"></i>
<span v-if="radio == ''">明细</span>
<span v-else>{{ radio }}明细</span>
<div class="edit-buttons">
<el-button v-if="editModel" class="filter-item edit-button" size="mini" v-waves icon="el-icon-plus" @click="onBtnClicked('btnAddDetail')">添加</el-button>
<el-button v-if="editModel" class="filter-item edit-button delete-button" size="mini" v-waves icon="el-icon-delete" @click="onBtnClicked('btnDelDetail')">删除</el-button>
</div>
</div>
<auth-table style="height:calc(100% - 52px - 34px)" ref="secondTable" border :editModel="editModel" :table-fields="secondHeaderList" :data="secondList" @row-click="rowClickSecondTable" @selection-change="selChangeSecondTable"></auth-table>
<pagination v-show="secondTotal > 0" :total="secondTotal" :page.sync="secondQuery.page" :limit.sync="secondQuery.limit" @pagination="handleSecondPage" />
</el-card>
</el-col>
</el-row>
<el-card shadow="nerver" v-if="editModel" style="text-align: right;padding-bottom: 10px;">
<el-row>
<el-col :span="24"
><el-button size="mini" @click="editModel = false">取消</el-button>
<el-button size="mini" v-if="dialogStatus == 'create'" type="primary" @click="createData">确认</el-button>
<el-button size="mini" v-else type="primary" @click="updateData">确认</el-button></el-col
>
</el-row>
</el-card>
</div>
</div>
</template>
<script>
import * as {FirstTableName}s from '@/api/{FirstTableName}s'
import * as {SecondTableName}s from '@/api/{SecondTableName}s'
import waves from '@/directive/waves' // 水波纹指令
import Sticky from '@/components/Sticky'
import { mapGetters } from 'vuex'
import permissionBtn from '@/components/PermissionBtn'
import Pagination from '@/components/Pagination'
import elDragDialog from '@/directive/el-dragDialog'
import { parseTime, defaultVal } from '@/utils/index'
import AuthForm from '@/components/Base/AuthForm'
import AuthTable from '@/components/Base/AuthTable'
export default {
name: '{FirstTableName}',
components: {
Sticky,
permissionBtn,
Pagination,
AuthForm,
AuthTable
},
directives: {
waves,
elDragDialog
},
data() {
return {
// ------------------------主列表数据(头)-----------------------------
firstHeaderList: [], // 主列表列定义
radio: '', // 主列表选中项
firstQuery: {
// 主列表查询条件
page: 1,
limit: 20,
key: undefined,
appId: undefined
},
mainList: null, // 主列表值
firstTotal: 0, // 主列表总条数
listLoading: true, // 主列表记录总数
tableKey: 0,
showTitleDialog: true,
editModel: false, // 是否为编辑模式
editType: 'edit', // 编辑类型
dialogStatus: '', // 主修改对话框状态create/update
selectRow: {},
firstTemp: {}, // 当前选中的头信息
// ------------------------明细列表数据-------------------------------------
secondHeaderList: [], // 明细列表列定义
secondList: [], // 明细列表值
secondQuery: {}, // 明细列表的过滤条件,如页码、每页条数,搜索关键字等
secondTotal: 0, // 明细列表总条数
multipleSelection: [], // 明细列表checkbox选中的值,
// ------------------------通用数据项-------------------------------------
textMap: {
update: '编辑',
create: '添加'
}
}
},
computed: {
...mapGetters(['defaultorgid'])
},
created() {
this.firstHeaderList = [
{FirstHeaderList}
]
this.secondHeaderList = [
{SecondHeaderList}
]
this.getList()
},
methods: {
// ------------------------通用处理函数-------------------------------------
onBtnClicked: function(domId, callback) {
console.log('you click:' + domId)
switch (domId) {
case 'btnAdd': // 添加新记录
this.resetFirstTemp()
this.secondList = []
this.dialogStatus = 'create'
this.editModel = true
this.editType = 'add'
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
break
case 'btnEdit': // 编辑头
this.firstTemp = Object.assign({}, this.selectRow)
if (this.firstTemp.id === '') {
this.editModel = false
this.$message({
message: '请选择要修改的项',
type: 'error'
})
return
}
this.dialogStatus = 'update'
this.editModel = true
this.editType = 'edit'
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
break
case 'btnDel': // 删除主表
if (this.firstTemp.id === '') {
this.$message({
message: '请选择要删除的项',
type: 'error'
})
return
}
this.handleFirstDel(this.firstTemp)
break
case 'btnAddDetail': // 添加明细行
this.handleAddOrderDetail()
break
case 'btnDelDetail': // 删除明细行
if (this.multipleSelection.length < 1) {
this.$message({
message: '至少删除一个',
type: 'error'
})
return
}
this.handleSecondDel(this.multipleSelection)
break
case 'btnExport':
this.$refs.mainTable.exportExcel(`订单${parseTime(new Date())}`, callback)
break
default:
break
}
},
// ------------------------主数据列表处理------------------------------------
getList() {
this.listLoading = true
{FirstTableName}s.getList(this.firstQuery).then((response) => {
this.mainList = response.data
this.firstTotal = response.count
if (this.firstTotal > 0) {
this.rowClickFirstTable(this.mainList[0])
}
this.listLoading = false
})
},
rowClickFirstTable(row) {
// 点击行
this.radio = row.id
this.secondQuery.page = 1
this.secondQuery.limit = 10
this.querySecondList(this.radio)
this.showTitleDetail(row)
},
handleFilter() {
this.firstQuery.page = 1
this.getList()
},
handleSizeChange(val) {
this.firstQuery.limit = val
this.getList()
},
handleCurrentChange(val) {
this.firstQuery.page = val.page
this.firstQuery.limit = val.limit
this.getList()
},
resetFirstTemp() {
this.firstHeaderList.forEach((item) => {
this.firstTemp[item.columnName] = defaultVal(item.entityType)
})
},
createData() {
// 保存提交
this.$refs['dataForm'].validate(() => {
let tempData = Object.assign({}, this.firstTemp)
tempData = this.setDetails(tempData)
tempData.OrgId = this.defaultorgid
{FirstTableName}s.add(tempData).then(() => {
this.mainList.unshift(this.firstTemp)
this.editModel = false
this.$notify({
title: '成功',
message: '创建成功',
type: 'success',
duration: 2000
})
})
})
},
showTitleDetail(row) {
// 弹出编辑框
this.selectRow = Object.assign({}, row) // 新增订单时保存当前选中行
this.firstTemp = Object.assign({}, row) // copy obj
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
setDetails(tempData) {
// 处理明细
tempData.{SecondTableName}Reqs = []
this.secondList.length > 0 &&
this.secondList.forEach((item) => {
const obj = {}
this.secondHeaderList.forEach((header) => {
obj[header.columnName] = item[header.columnName] || defaultVal(header.entityType)
})
tempData.{SecondTableName}Reqs.push(obj)
})
return tempData
},
updateData() {
// 更新提交
this.$refs['dataForm'].validate(() => {
let tempData = Object.assign({}, this.firstTemp)
tempData = this.setDetails(tempData)
{FirstTableName}s.update(tempData).then(() => {
for (const v of this.mainList) {
if (v.id === this.firstTemp.id) {
const index = this.mainList.indexOf(v)
this.mainList.splice(index, 1, this.firstTemp)
break
}
}
this.editModel = false
this.$notify({
title: '成功',
message: '更新成功',
type: 'success',
duration: 2000
})
})
})
},
handleFirstDel(row) {
// 删除头
{FirstTableName}s.del([row.id]).then(() => {
this.$notify({
title: '成功',
message: '删除成功',
type: 'success',
duration: 2000
})
this.mainList = this.mainList.filter((item) => item.id !== row.id)
this.resetFirstTemp()
this.secondList = []
})
},
// ------------------------明细列表处理-------------------------------------
handleSecondPage(e) {
this.secondQuery = e
this.querySecondList(this.radio)
},
querySecondList(id) {
{SecondTableName}s
.getList({
{ParentTableId}: id,
page: this.secondQuery.page,
limit: this.secondQuery.limit,
key: this.secondQuery.customerKey
})
.then((res) => {
this.secondTotal = res.count
this.secondList = res.data
})
},
rowClickSecondTable(row) {
// 行点击事件
this.$refs.secondTable.clearSelection()
this.$refs.secondTable.toggleRowSelection(row)
},
handleSecondDel(rows) {
// 删除明细时,只删除前端
rows.forEach((row) => {
this.secondList = this.secondList.filter((item) => item.id !== row.id)
})
},
selChangeSecondTable(val) {
// 明细选中事件
this.multipleSelection = val
},
handleAddOrderDetail() {
// 添加明细
const obj = {}
this.secondHeaderList.forEach((header) => {
obj[header.columnName] = defaultVal(header.entityType)
})
obj.{ParentTableId} = this.firstTemp.id
this.secondList.push(Object.assign({}, obj))
}
}
}
</script>
<style lang="scss">
.nomal-form label {
font-weight: 500 !important;
}
.demo-card .el-card__header {
padding: 10px !important;
line-height: 1;
position: relative;
}
.el-card__body {
padding: 10px 10px 0 10px !important;
height: 100%;
}
.form-card .el-card__body {
padding-right: 0 !important;
}
.form-card .el-form {
padding-right: 5px;
}
.dialog-small .el-dialog__header {
padding: 10px;
border-bottom: 1px solid #efefef;
}
.dialog-small .el-dialog__headerbtn {
top: 15px;
}
.dialog-small .el-dialog__body {
padding: 10px;
}
.el-form-item__error {
padding-top: 0;
}
.edit-buttons {
position: absolute !important;
top: 2px;
right: 10px;
}
</style>

View File

@@ -0,0 +1,416 @@
<!--
* @description: 入库订单界面
* @author: liyubao | xufuxing
* @version: 1.0
* @updateDate: 代码生成器自动生成
-->
<template>
<div class="flex-column">
<sticky :className="'sub-navbar'">
<div class="filter-container">
<el-input @keyup.enter.native="handleFilter" size="mini" style="width: 200px;" class="filter-item" :placeholder="'名称'" v-model="firstQuery.key"> </el-input>
<el-button class="filter-item" size="mini" v-waves icon="el-icon-search" @click="handleFilter">搜索</el-button>
<permission-btn size="mini" v-on:btn-event="onBtnClicked"></permission-btn>
</div>
</sticky>
<div class="app-container flex-item flex-column">
<div class="flex-item">
<el-card shadow="nerver" class="demo-card fh">
<auth-table style="height:calc(100% - 52px)" ref="mainTable" :select-type="'radio'" :table-fields="firstHeaderList" :data="mainList" :v-loading="listLoading" @row-click="rowClickFirstTable"></auth-table>
<pagination v-show="firstTotal > 0" :total="firstTotal" :page.sync="firstQuery.page" :limit.sync="firstQuery.limit" @pagination="handleCurrentChange" />
</el-card>
</div>
<el-row class="flex-item">
<el-col :span="showTitleDialog ? 12 : 0" class="fh form-card">
<el-card shadow="nerver" class="demo-card fh">
<div slot="header">
<span v-if="radio == ''">头信息</span>
<span v-else>{{ radio }}头信息</span>
</div>
<auth-form ref="dataForm" :edit-model="editModel" :form-fields="firstHeaderList" :data="firstTemp" :col-num="3"></auth-form>
</el-card>
</el-col>
<!-- 第二部分多选 -->
<el-col :span="!showTitleDialog ? 24 : 12" class="fh detail-card">
<el-card shadow="nerver" class="demo-card fh" id="secondCard">
<div slot="header">
<i class="show-title-button" :class="showTitleDialog ? 'el-icon-d-arrow-left' : 'el-icon-d-arrow-right'" :title="showTitleDialog ? '展开' : '收缩'" @click="showTitleDialog = !showTitleDialog"></i>
<span v-if="radio == ''">明细</span>
<span v-else>{{ radio }}明细</span>
<div class="edit-buttons">
<el-button v-if="editModel" class="filter-item edit-button" size="mini" v-waves icon="el-icon-plus" @click="onBtnClicked('btnAddDetail')">添加</el-button>
<el-button v-if="editModel" class="filter-item edit-button delete-button" size="mini" v-waves icon="el-icon-delete" @click="onBtnClicked('btnDelDetail')">删除</el-button>
</div>
</div>
<auth-table style="height:calc(100% - 52px - 34px)" ref="secondTable" border :editModel="editModel" :table-fields="secondHeaderList" :data="secondList" @row-click="rowClickSecondTable" @selection-change="selChangeSecondTable"></auth-table>
<pagination v-show="secondTotal > 0" :total="secondTotal" :page.sync="secondQuery.page" :limit.sync="secondQuery.limit" @pagination="handleSecondPage" />
</el-card>
</el-col>
</el-row>
<el-card shadow="nerver" v-if="editModel" style="text-align: right;padding-bottom: 10px;">
<el-row>
<el-col :span="24"
><el-button size="mini" @click="editModel = false">取消</el-button>
<el-button size="mini" v-if="dialogStatus == 'create'" type="primary" @click="createData">确认</el-button>
<el-button size="mini" v-else type="primary" @click="updateData">确认</el-button></el-col
>
</el-row>
</el-card>
</div>
</div>
</template>
<script>
import * as {FirstTableName}s from '@/api/{FirstTableName}s'
import * as {SecondTableName}s from '@/api/{SecondTableName}s'
import waves from '@/directive/waves' // 水波纹指令
import Sticky from '@/components/Sticky'
import { mapGetters } from 'vuex'
import permissionBtn from '@/components/PermissionBtn'
import Pagination from '@/components/Pagination'
import elDragDialog from '@/directive/el-dragDialog'
import { parseTime, defaultVal } from '@/utils/index'
import AuthForm from '@/components/Base/AuthForm'
import AuthTable from '@/components/Base/AuthTable'
export default {
name: '{FirstTableName}',
components: {
Sticky,
permissionBtn,
Pagination,
AuthForm,
AuthTable
},
directives: {
waves,
elDragDialog
},
data() {
return {
// ------------------------主列表数据(头)-----------------------------
firstHeaderList: [], // 主列表列定义
radio: '', // 主列表选中项
firstQuery: {
// 主列表查询条件
page: 1,
limit: 20,
key: undefined,
appId: undefined
},
mainList: null, // 主列表值
firstTotal: 0, // 主列表总条数
listLoading: true, // 主列表记录总数
tableKey: 0,
showTitleDialog: true,
editModel: false, // 是否为编辑模式
editType: 'edit', // 编辑类型
dialogStatus: '', // 主修改对话框状态create/update
selectRow: {},
firstTemp: {}, // 当前选中的头信息
// ------------------------明细列表数据-------------------------------------
secondHeaderList: [], // 明细列表列定义
secondList: [], // 明细列表值
secondQuery: {}, // 明细列表的过滤条件,如页码、每页条数,搜索关键字等
secondTotal: 0, // 明细列表总条数
multipleSelection: [], // 明细列表checkbox选中的值,
// ------------------------通用数据项-------------------------------------
textMap: {
update: '编辑',
create: '添加'
}
}
},
computed: {
...mapGetters(['defaultorgid'])
},
created() {
this.getList()
},
methods: {
// ------------------------通用处理函数-------------------------------------
onBtnClicked: function(domId, callback) {
console.log('you click:' + domId)
switch (domId) {
case 'btnAdd': // 添加新记录
this.resetFirstTemp()
this.secondList = []
this.dialogStatus = 'create'
this.editModel = true
this.editType = 'add'
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
break
case 'btnEdit': // 编辑头
this.firstTemp = Object.assign({}, this.selectRow)
if (this.firstTemp.id === '') {
this.editModel = false
this.$message({
message: '请选择要修改的项',
type: 'error'
})
return
}
this.dialogStatus = 'update'
this.editModel = true
this.editType = 'edit'
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
break
case 'btnDel': // 删除主表
if (this.firstTemp.id === '') {
this.$message({
message: '请选择要删除的项',
type: 'error'
})
return
}
this.handleFirstDel(this.firstTemp)
break
case 'btnAddDetail': // 添加明细行
this.handleAddOrderDetail()
break
case 'btnDelDetail': // 删除明细行
if (this.multipleSelection.length < 1) {
this.$message({
message: '至少删除一个',
type: 'error'
})
return
}
this.handleSecondDel(this.multipleSelection)
break
case 'btnExport':
this.$refs.mainTable.exportExcel(`订单${parseTime(new Date())}`, callback)
break
default:
break
}
},
// ------------------------主数据列表处理------------------------------------
getList() {
this.listLoading = true
{FirstTableName}s.getList(this.firstQuery).then((response) => {
response.columnFields.forEach((item) => {
// 首字母小写
item.columnName = item.columnName.substring(0, 1).toLowerCase() + item.columnName.substring(1)
})
this.firstHeaderList = response.columnFields
this.mainList = response.data
this.firstTotal = response.count
if (this.firstTotal > 0) {
this.rowClickFirstTable(this.mainList[0])
}
this.listLoading = false
})
},
rowClickFirstTable(row) {
// 点击行
this.radio = row.id
this.secondQuery.page = 1
this.secondQuery.limit = 10
this.querySecondList(this.radio)
this.showTitleDetail(row)
},
handleFilter() {
this.firstQuery.page = 1
this.getList()
},
handleSizeChange(val) {
this.firstQuery.limit = val
this.getList()
},
handleCurrentChange(val) {
this.firstQuery.page = val.page
this.firstQuery.limit = val.limit
this.getList()
},
resetFirstTemp() {
this.firstHeaderList.forEach((item) => {
this.firstTemp[item.columnName] = defaultVal(item.entityType)
})
},
createData() {
// 保存提交
this.$refs['dataForm'].validate(() => {
let tempData = Object.assign({}, this.firstTemp)
tempData = this.setDetails(tempData)
tempData.OrgId = this.defaultorgid
{FirstTableName}s.add(tempData).then(() => {
this.mainList.unshift(this.firstTemp)
this.editModel = false
this.$notify({
title: '成功',
message: '创建成功',
type: 'success',
duration: 2000
})
})
})
},
showTitleDetail(row) {
// 弹出编辑框
this.selectRow = Object.assign({}, row) // 新增订单时保存当前选中行
this.firstTemp = Object.assign({}, row) // copy obj
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
setDetails(tempData) {
// 处理明细
tempData.{SecondTableName}Reqs = []
this.secondList.length > 0 &&
this.secondList.forEach((item) => {
const obj = {}
this.secondHeaderList.forEach((header) => {
obj[header.columnName] = item[header.columnName] || defaultVal(header.entityType)
})
tempData.{SecondTableName}Reqs.push(obj)
})
return tempData
},
updateData() {
// 更新提交
this.$refs['dataForm'].validate(() => {
let tempData = Object.assign({}, this.firstTemp)
tempData = this.setDetails(tempData)
{FirstTableName}s.update(tempData).then(() => {
for (const v of this.mainList) {
if (v.id === this.firstTemp.id) {
const index = this.mainList.indexOf(v)
this.mainList.splice(index, 1, this.firstTemp)
break
}
}
this.editModel = false
this.$notify({
title: '成功',
message: '更新成功',
type: 'success',
duration: 2000
})
})
})
},
handleFirstDel(row) {
// 删除头
{FirstTableName}s.del([row.id]).then(() => {
this.$notify({
title: '成功',
message: '删除成功',
type: 'success',
duration: 2000
})
this.mainList = this.mainList.filter((item) => item.id !== row.id)
this.resetFirstTemp()
this.secondList = []
})
},
// ------------------------明细列表处理-------------------------------------
handleSecondPage(e) {
this.secondQuery = e
this.querySecondList(this.radio)
},
querySecondList(id) {
{SecondTableName}s
.getList({
{ParentTableId}: id,
page: this.secondQuery.page,
limit: this.secondQuery.limit,
key: this.secondQuery.customerKey
})
.then((res) => {
res.columnFields.forEach((item) => {
// 首字母小写
item.columnName = item.columnName.substring(0, 1).toLowerCase() + item.columnName.substring(1)
})
this.secondHeaderList = res.columnFields
this.secondTotal = res.count
this.secondList = res.data
})
},
rowClickSecondTable(row) {
// 行点击事件
this.$refs.secondTable.clearSelection()
this.$refs.secondTable.toggleRowSelection(row)
},
handleSecondDel(rows) {
// 删除明细时,只删除前端
rows.forEach((row) => {
this.secondList = this.secondList.filter((item) => item.id !== row.id)
})
},
selChangeSecondTable(val) {
// 明细选中事件
this.multipleSelection = val
},
handleAddOrderDetail() {
// 添加明细
const obj = {}
this.secondHeaderList.forEach((header) => {
obj[header.columnName] = defaultVal(header.entityType)
})
obj.{ParentTableId} = this.firstTemp.id
this.secondList.push(Object.assign({}, obj))
}
}
}
</script>
<style lang="scss">
.nomal-form label {
font-weight: 500 !important;
}
.demo-card .el-card__header {
padding: 10px !important;
line-height: 1;
position: relative;
}
.el-card__body {
padding: 10px 10px 0 10px !important;
height: 100%;
}
.form-card .el-card__body {
padding-right: 0 !important;
}
.form-card .el-form {
padding-right: 5px;
}
.dialog-small .el-dialog__header {
padding: 10px;
border-bottom: 1px solid #efefef;
}
.dialog-small .el-dialog__headerbtn {
top: 15px;
}
.dialog-small .el-dialog__body {
padding: 10px;
}
.el-form-item__error {
padding-top: 0;
}
.edit-buttons {
position: absolute !important;
top: 2px;
right: 10px;
}
</style>

View File

@@ -0,0 +1,68 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Infrastructure;
using OpenAuth.App.Interface;
using OpenAuth.App.Request;
using OpenAuth.App.Response;
using OpenAuth.Repository;
using OpenAuth.Repository.Domain;
using OpenAuth.Repository.Interface;
namespace OpenAuth.App
{
public class {ModuleCode} : {BaseAppName}<{ClassName},OpenAuthDBContext>
{
/// <summary>
/// 加载列表
/// </summary>
public async Task<TableData> Load(Query{ClassName}ListReq request)
{
var loginContext = _auth.GetCurrentUser();
if (loginContext == null)
{
throw new CommonException("登录已过期", Define.INVALID_TOKEN);
}
var result = new TableData();
var objs = GetDataPrivilege("u");
if (!string.IsNullOrEmpty(request.key))
{
//增加筛选条件,如:
//objs = objs.Where(u => u.Name.Contains(request.key));
}
{ForeignKeyTemplate}
result.data = objs.OrderBy(u => u.Id)
.Skip((request.page - 1) * request.limit)
.Take(request.limit);
result.count = objs.Count();
return result;
}
public void Add(AddOrUpdate{ClassName}Req obj)
{
//程序类型取入口应用的名称,可以根据自己需要调整
var addObj = obj.MapTo<{ClassName}>();
//addObj.Time = DateTime.Now;
Repository.Add(addObj);
}
public void Update(AddOrUpdate{ClassName}Req obj)
{
UnitWork.Update<{ClassName}>(u => u.Id == obj.Id, u => new {ClassName}
{
//todo:要修改的字段赋值
});
}
public {ModuleCode}(IUnitWork<OpenAuthDBContext> unitWork, IRepository<{ClassName},OpenAuthDBContext> repository, IAuth auth) : base(unitWork, repository, auth)
{
}
}
}

View File

@@ -23,26 +23,27 @@ namespace OpenAuth.App
var loginContext = _auth.GetCurrentUser();
if (loginContext == null)
{
throw new CommonException("登录已过期", Define.INVALID_TOKEN);
throw new CommonException("登录已过期", Define.INVALID_TOKEN);
}
var properties = loginContext.GetProperties("{ClassName}");
if (properties == null || properties.Count == 0)
var columnFields = loginContext.GetTableColumns("{ClassName}");
if (columnFields == null || columnFields.Count == 0)
{
throw new Exception("当前登录用户没有访问该模块字段的权限,请联系管理员配置");
throw new Exception("请在代码生成界面配置Resource表的字段属性");
}
var result = new TableData();
var objs = GetDataPrivilege("u");
if (!string.IsNullOrEmpty(request.key))
{
//增加筛选条件,如:
//objs = objs.Where(u => u.Name.Contains(request.key));
//增加筛选条件,如:
//objs = objs.Where(u => u.Name.Contains(request.key));
}
var propertyStr = string.Join(',', properties.Select(u => u.Key));
result.columnHeaders = properties;
{ForeignKeyTemplate}
var propertyStr = string.Join(',', columnFields.Select(u => u.ColumnName));
result.columnFields = columnFields;
result.data = objs.OrderBy(u => u.Id)
.Skip((request.page - 1) * request.limit)
.Take(request.limit).Select($"new ({propertyStr})");

View File

@@ -0,0 +1,234 @@
<!--
* @description: 代码生成器自动生成
* @author: liyubao | xufuxing
* @version: 1.0
-->
<template>
<div class="flex-column">
<sticky :className="'sub-navbar'">
<div class="filter-container">
<el-input @keyup.enter.native="handleFilter" size="mini" style="width: 200px;" class="filter-item" :placeholder="'名称'" v-model="listQuery.key"> </el-input>
<el-button class="filter-item" size="mini" v-waves icon="el-icon-search" @click="handleFilter">搜索</el-button>
<permission-btn size="mini" v-on:btn-event="onBtnClicked"></permission-btn>
</div>
</sticky>
<div class="app-container flex-item">
<div class="bg-white" style="height: 100%;">
<auth-table
style="height:calc(100% - 60px)"
ref="mainTable"
:select-type="'checkbox'"
:table-fields="headerList"
:data="list"
:v-loading="listLoading"
@row-click="rowClick"
@selection-change="handleSelectionChange"
></auth-table>
<pagination v-show="total > 0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="handleCurrentChange" />
</div>
<el-dialog v-el-drag-dialog class="dialog-mini" width="500px" :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
<auth-form ref="dataForm" :rules="rules" :edit-model="true" :form-fields="headerList" :data="temp" :col-num="2"></auth-form>
<div slot="footer">
<el-button size="mini" @click="dialogFormVisible = false">取消</el-button>
<el-button size="mini" v-if="dialogStatus == 'create'" type="primary" @click="createData">确认</el-button>
<el-button size="mini" v-else type="primary" @click="updateData">确认</el-button>
</div>
</el-dialog>
</div>
</div>
</template>
<script>
import * as {TableName}s from '@/api/{TableName}s'
import waves from '@/directive/waves' // 水波纹指令
import Sticky from '@/components/Sticky'
import permissionBtn from '@/components/PermissionBtn'
import Pagination from '@/components/Pagination'
import elDragDialog from '@/directive/el-dragDialog'
import { defaultVal } from '@/utils/index'
import extend from '@/extensions/delRows.js'
import AuthForm from '../../components/Base/AuthForm.vue'
import AuthTable from '../../components/Base/AuthTable.vue'
import ColumnDefine from '@/interface/columnDefine'
export default {
name: '{TableName}',
components: { Sticky, permissionBtn, Pagination, AuthTable, AuthForm, },
directives: {
waves,
elDragDialog,
},
mixins: [extend],
data() {
return {
headerList: [], // 主列表列定义
multipleSelection: [], // 列表checkbox选中的值
tableKey: 0,
list: null,
total: 0,
listLoading: true,
listQuery: {
// 查询条件
page: 1,
limit: 20,
key: undefined,
},
temp: { },
dialogFormVisible: false,
dialogStatus: '',
textMap: {
update: '编辑',
create: '添加',
},
rules: {
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
},
}
},
created() {
this.headerList = [
{HeaderList}
]
this.getList()
},
methods: {
rowClick(row) {
this.$refs.mainTable.clearSelection()
this.$refs.mainTable.toggleRowSelection(row)
},
handleSelectionChange(val) {
this.multipleSelection = val
},
onBtnClicked: function(domId,callback) {
console.log('you click:' + domId)
switch (domId) {
case 'btnAdd':
this.handleCreate()
break
case 'btnEdit':
if (this.multipleSelection.length !== 1) {
this.$message({
message: '只能选中一个进行编辑',
type: 'error',
})
return
}
this.handleUpdate(this.multipleSelection[0])
break
case 'btnDel':
if (this.multipleSelection.length < 1) {
this.$message({
message: '至少删除一个',
type: 'error',
})
return
}
this.handleDelete(this.multipleSelection)
break
case 'btnExport':
this.$refs.mainTable.exportExcel('资源文件',callback)
break
default:
break
}
},
getList() {
this.listLoading = true
{TableName}s.getList(this.listQuery).then((response) => {
this.list = response.data
this.total = response.count
this.listLoading = false
})
},
handleFilter() {
this.listQuery.page = 1
this.getList()
},
handleSizeChange(val) {
this.listQuery.limit = val
this.getList()
},
handleCurrentChange(val) {
this.listQuery.page = val.page
this.listQuery.limit = val.limit
this.getList()
},
handleModifyStatus(row, disable) {
// 模拟修改状态
this.$message({
message: '操作成功',
type: 'success',
})
row.disable = disable
},
resetTemp() {
this.headerList.forEach((item) => {
this.temp[item.columnName] = defaultVal(item.entityType)
})
},
handleCreate() {
// 弹出添加框
this.resetTemp()
this.dialogStatus = 'create'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
createData() {
// 保存提交
this.$refs['dataForm'].validate(() => {
{TableName}s.add(this.temp).then(() => {
this.list.unshift(this.temp)
this.dialogFormVisible = false
this.$notify({
title: '成功',
message: '创建成功',
type: 'success',
duration: 2000,
})
})
})
},
handleUpdate(row) {
// 弹出编辑框
this.temp = Object.assign({}, row) // copy obj
this.dialogStatus = 'update'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
updateData() {
// 更新提交
this.$refs['dataForm'].validate(() => {
const tempData = Object.assign({}, this.temp)
{TableName}s.update(tempData).then(() => {
for (const v of this.list) {
if (v.id === this.temp.id) {
const index = this.list.indexOf(v)
this.list.splice(index, 1, this.temp)
break
}
}
this.dialogFormVisible = false
this.$notify({
title: '成功',
message: '更新成功',
type: 'success',
duration: 2000,
})
})
})
},
handleDelete(rows) {
// 多行删除
this.delrows({TableName}s, rows)
},
},
}
</script>
<style>
.dialog-mini .el-select {
width: 100%;
}
</style>

View File

@@ -0,0 +1,235 @@
<!--
* @description: 代码生成器自动生成
* @author: liyubao | xufuxing
* @version: 1.0
-->
<template>
<div class="flex-column">
<sticky :className="'sub-navbar'">
<div class="filter-container">
<el-input @keyup.enter.native="handleFilter" size="mini" style="width: 200px;" class="filter-item" :placeholder="'名称'" v-model="listQuery.key"> </el-input>
<el-button class="filter-item" size="mini" v-waves icon="el-icon-search" @click="handleFilter">搜索</el-button>
<permission-btn size="mini" v-on:btn-event="onBtnClicked"></permission-btn>
</div>
</sticky>
<div class="app-container flex-item">
<div class="bg-white" style="height: 100%;">
<auth-table
style="height:calc(100% - 60px)"
ref="mainTable"
:select-type="'checkbox'"
:table-fields="headerList"
:data="list"
:v-loading="listLoading"
@row-click="rowClick"
@selection-change="handleSelectionChange"
></auth-table>
<pagination v-show="total > 0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="handleCurrentChange" />
</div>
<el-dialog v-el-drag-dialog class="dialog-mini" width="500px" :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
<auth-form ref="dataForm" :rules="rules" :edit-model="true" :form-fields="headerList" :data="temp" :col-num="2"></auth-form>
<div slot="footer">
<el-button size="mini" @click="dialogFormVisible = false">取消</el-button>
<el-button size="mini" v-if="dialogStatus == 'create'" type="primary" @click="createData">确认</el-button>
<el-button size="mini" v-else type="primary" @click="updateData">确认</el-button>
</div>
</el-dialog>
</div>
</div>
</template>
<script>
import * as {TableName}s from '@/api/{TableName}s'
import waves from '@/directive/waves' // 水波纹指令
import Sticky from '@/components/Sticky'
import permissionBtn from '@/components/PermissionBtn'
import Pagination from '@/components/Pagination'
import elDragDialog from '@/directive/el-dragDialog'
import { defaultVal } from '@/utils/index'
import extend from '@/extensions/delRows.js'
import AuthForm from '../../components/Base/AuthForm.vue'
import AuthTable from '../../components/Base/AuthTable.vue'
export default {
name: '{TableName}',
components: { Sticky, permissionBtn, Pagination, AuthTable, AuthForm, },
directives: {
waves,
elDragDialog,
},
mixins: [extend],
data() {
return {
headerList: [], // 主列表列定义
multipleSelection: [], // 列表checkbox选中的值
tableKey: 0,
list: null,
total: 0,
listLoading: true,
listQuery: {
// 查询条件
page: 1,
limit: 20,
key: undefined,
},
temp: { },
dialogFormVisible: false,
dialogStatus: '',
textMap: {
update: '编辑',
create: '添加',
},
rules: {
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
},
}
},
created() {
this.getList()
},
methods: {
rowClick(row) {
this.$refs.mainTable.clearSelection()
this.$refs.mainTable.toggleRowSelection(row)
},
handleSelectionChange(val) {
this.multipleSelection = val
},
onBtnClicked: function(domId,callback) {
console.log('you click:' + domId)
switch (domId) {
case 'btnAdd':
this.handleCreate()
break
case 'btnEdit':
if (this.multipleSelection.length !== 1) {
this.$message({
message: '只能选中一个进行编辑',
type: 'error',
})
return
}
this.handleUpdate(this.multipleSelection[0])
break
case 'btnDel':
if (this.multipleSelection.length < 1) {
this.$message({
message: '至少删除一个',
type: 'error',
})
return
}
this.handleDelete(this.multipleSelection)
break
case 'btnExport':
this.$refs.mainTable.exportExcel('资源文件',callback)
break
default:
break
}
},
getList() {
this.listLoading = true
{TableName}s.getList(this.listQuery).then((response) => {
this.list = response.data
response.columnFields.forEach((item) => {
// 首字母小写
item.columnName = item.columnName.substring(0, 1).toLowerCase() + item.columnName.substring(1)
})
this.headerList = response.columnFields
this.total = response.count
this.listLoading = false
})
},
handleFilter() {
this.listQuery.page = 1
this.getList()
},
handleSizeChange(val) {
this.listQuery.limit = val
this.getList()
},
handleCurrentChange(val) {
this.listQuery.page = val.page
this.listQuery.limit = val.limit
this.getList()
},
handleModifyStatus(row, disable) {
// 模拟修改状态
this.$message({
message: '操作成功',
type: 'success',
})
row.disable = disable
},
resetTemp() {
this.headerList.forEach((item) => {
this.temp[item.columnName] = defaultVal(item.entityType)
})
},
handleCreate() {
// 弹出添加框
this.resetTemp()
this.dialogStatus = 'create'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
createData() {
// 保存提交
this.$refs['dataForm'].validate(() => {
{TableName}s.add(this.temp).then(() => {
this.list.unshift(this.temp)
this.dialogFormVisible = false
this.$notify({
title: '成功',
message: '创建成功',
type: 'success',
duration: 2000,
})
})
})
},
handleUpdate(row) {
// 弹出编辑框
this.temp = Object.assign({}, row) // copy obj
this.dialogStatus = 'update'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
updateData() {
// 更新提交
this.$refs['dataForm'].validate(() => {
const tempData = Object.assign({}, this.temp)
{TableName}s.update(tempData).then(() => {
for (const v of this.list) {
if (v.id === this.temp.id) {
const index = this.list.indexOf(v)
this.list.splice(index, 1, this.temp)
break
}
}
this.dialogFormVisible = false
this.$notify({
title: '成功',
message: '更新成功',
type: 'success',
duration: 2000,
})
})
})
},
handleDelete(rows) {
// 多行删除
this.delrows({TableName}s, rows)
},
},
}
</script>
<style>
.dialog-mini .el-select {
width: 100%;
}
</style>