mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2025-12-08 17:12:28 +08:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a39bb0ce5f | |||
| a43ccf6f31 | |||
| 1e2a74a65f | |||
| 6c362861a0 | |||
| 2a5ec11660 | |||
| 509be1e382 | |||
| 80601e0ccd | |||
| 435f467646 | |||
| 644c6801a0 | |||
| 1f75c124f1 | |||
| bcbdd383ae | |||
| 7a1d4cda96 | |||
| 8bae42049c | |||
| 09a63610cf | |||
| 46e024bfbc | |||
| c767f094fc | |||
| 42e0a938da | |||
| 3f4b40ea74 | |||
| f210df80e6 | |||
| 0f79e8efef | |||
| d6251419e6 | |||
| 7db5f7f3e9 | |||
| cd79eb7597 |
7
LICENSE
7
LICENSE
@ -199,3 +199,10 @@
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
开源协议补充
|
||||
1.允许基于本平台软件开展业务系统开发。
|
||||
2.不得基于该平台软件的基础,修改包装成一个与JeecgBoot平台软件功能类似的产品进行发布、销售,或与JeecgBoot参与同类软件产品市场的竞争。
|
||||
违反此条款属于侵权行为,须赔偿侵权经济损失,同时立即停止著作权侵权行为。
|
||||
解释权归:http://www.jeecg.com
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"ant-design-vue": "^1.7.2",
|
||||
"@jeecg/antd-online-mini": "3.0.0-beta",
|
||||
"@jeecg/antd-online-mini": "3.0.0-RC",
|
||||
"@antv/data-set": "^0.11.4",
|
||||
"viser-vue": "^2.4.8",
|
||||
"axios": "^0.18.0",
|
||||
@ -35,8 +35,8 @@
|
||||
"vue-splitpane": "^1.0.4",
|
||||
"vuedraggable": "^2.20.0",
|
||||
"codemirror": "^5.46.0",
|
||||
"@tinymce/tinymce-vue": "^2.1.0",
|
||||
"tinymce": "^5.3.2",
|
||||
"@tinymce/tinymce-vue": "2.1.0",
|
||||
"tinymce": "5.4.1",
|
||||
"@toast-ui/editor": "^2.1.2",
|
||||
"vue-area-linkage": "^5.1.0",
|
||||
"china-area-data": "^5.0.1",
|
||||
|
||||
@ -90,6 +90,8 @@
|
||||
}
|
||||
console.log(val);
|
||||
this.$emit('change', val);
|
||||
//LOWCOD-2146 【菜单】数据规则,选择自定义SQL 规则值无法输入空格
|
||||
this.$emit('input', val);
|
||||
},
|
||||
setCurrentDictOptions(dictOptions){
|
||||
this.dictOptions = dictOptions
|
||||
|
||||
@ -144,8 +144,12 @@ export default {
|
||||
const v = this.cronValue_c
|
||||
if (this.hideYear || this.hideSecond) return v
|
||||
const vs = v.split(' ')
|
||||
if (vs.length >= 6) {
|
||||
// 转成 Quartz 的规则
|
||||
vs[5] = this.convertWeekToQuartz(vs[5])
|
||||
}
|
||||
return vs.slice(0, vs.length - 1).join(' ')
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
cronValue(newVal, oldVal) {
|
||||
@ -226,6 +230,37 @@ export default {
|
||||
if (values.length > i) this.year = values[i]
|
||||
this.assignInput()
|
||||
},
|
||||
// Quartz 的规则:
|
||||
// 1 = 周日,2 = 周一,3 = 周二,4 = 周三,5 = 周四,6 = 周五,7 = 周六
|
||||
convertWeekToQuartz(week) {
|
||||
let convert = (v) => {
|
||||
if (v === '0') {
|
||||
return '1'
|
||||
}
|
||||
if (v === '1') {
|
||||
return '0'
|
||||
}
|
||||
return (Number.parseInt(v) - 1).toString()
|
||||
}
|
||||
// 匹配示例 1-7 or 1/7
|
||||
let patten1 = /^([0-7])([-/])([0-7])$/
|
||||
// 匹配示例 1,4,7
|
||||
let patten2 = /^([0-7])(,[0-7])+$/
|
||||
if (/^[0-7]$/.test(week)) {
|
||||
return convert(week)
|
||||
} else if (patten1.test(week)) {
|
||||
return week.replace(patten1, ($0, before, separator, after) => {
|
||||
if (separator === '/') {
|
||||
return convert(before) + separator + after
|
||||
} else {
|
||||
return convert(before) + separator + convert(after)
|
||||
}
|
||||
})
|
||||
} else if (patten2.test(week)) {
|
||||
return week.split(',').map(v => convert(v)).join(',')
|
||||
}
|
||||
return week
|
||||
},
|
||||
calTriggerList: simpleDebounce(function () {
|
||||
this.calTriggerListInner()
|
||||
}, 500),
|
||||
|
||||
@ -51,14 +51,14 @@ import mixin from './mixin'
|
||||
import { replaceWeekName, WEEK_MAP_EN } from './const.js'
|
||||
|
||||
const WEEK_MAP = {
|
||||
'周一': 1,
|
||||
'周二': 2,
|
||||
'周三': 3,
|
||||
'周四': 4,
|
||||
'周五': 5,
|
||||
'周六': 6,
|
||||
'周一': 2,
|
||||
'周二': 3,
|
||||
'周三': 4,
|
||||
'周四': 5,
|
||||
'周五': 6,
|
||||
'周六': 7,
|
||||
// 按照国人习惯,将周日放到每周的最后一天
|
||||
'周日': 7,
|
||||
'周日': 1,
|
||||
}
|
||||
|
||||
export default {
|
||||
|
||||
@ -62,8 +62,9 @@
|
||||
import { getAction } from '@/api/manage'
|
||||
import Ellipsis from '@/components/Ellipsis'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import { cloneObject, pushIfNotExist } from '@/utils/util'
|
||||
import { pushIfNotExist } from '@/utils/util'
|
||||
import JSelectBizQueryItem from './JSelectBizQueryItem'
|
||||
import {cloneDeep} from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'JSelectBizComponentModal',
|
||||
@ -177,11 +178,24 @@
|
||||
computed: {
|
||||
// 表头
|
||||
innerColumns() {
|
||||
let columns = cloneObject(this.columns)
|
||||
let columns = cloneDeep(this.columns)
|
||||
columns.forEach(column => {
|
||||
// 给所有的列加上过长裁剪
|
||||
if (this.ellipsisLength !== -1) {
|
||||
column.customRender = (text) => this.renderEllipsis(text)
|
||||
// JSelectBizComponent columns 建议开放customRender等方法类配置
|
||||
// https://github.com/jeecgboot/jeecg-boot/issues/3203
|
||||
let myCustomRender = column.customRender
|
||||
column.customRender = (text, record, index) => {
|
||||
let value = text
|
||||
if (typeof myCustomRender === 'function') {
|
||||
// noinspection JSVoidFunctionReturnValueUsed
|
||||
value = myCustomRender(text, record, index)
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
return this.renderEllipsis(value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
}
|
||||
})
|
||||
return columns
|
||||
@ -192,7 +206,7 @@
|
||||
deep: true,
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
this.innerValue = cloneObject(val)
|
||||
this.innerValue = cloneDeep(val)
|
||||
this.selectedRowKeys = []
|
||||
this.valueWatchHandler(val)
|
||||
this.queryOptionsByValue(val)
|
||||
|
||||
@ -117,7 +117,8 @@
|
||||
//返回选中的部门信息
|
||||
backDeparInfo(){
|
||||
if(this.backDepart===true){
|
||||
if(this.departIds && this.departIds.length>0){
|
||||
//LOWCOD-2147 【用户管理】选择部门和上级以后,负责部门没有数据可选 (陶炎改造自定义返回字段导致)
|
||||
if(this.storeVals && this.storeVals.length>0){
|
||||
let arr1 = this.storeVals.split(',')
|
||||
let arr2 = this.textVals.split(',')
|
||||
let info = []
|
||||
|
||||
@ -21,8 +21,8 @@
|
||||
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
|
||||
:treeData="departTree"
|
||||
:expandAction="false"
|
||||
:expandedKeys.sync="expandedKeys"
|
||||
@select="onDepSelect"
|
||||
:load-data="onLoadDepartment"
|
||||
/>
|
||||
</a-card>
|
||||
</a-col>
|
||||
@ -57,7 +57,7 @@
|
||||
|
||||
<script>
|
||||
import { pushIfNotExist, filterObj } from '@/utils/util'
|
||||
import {queryDepartTreeList, getUserList, queryUserByDepId} from '@/api/api'
|
||||
import {queryDepartTreeList, getUserList, queryUserByDepId, queryDepartTreeSync} from '@/api/api'
|
||||
import { getAction } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
@ -297,14 +297,35 @@
|
||||
})
|
||||
},
|
||||
queryDepartTree() {
|
||||
queryDepartTreeList().then((res) => {
|
||||
//update-begin-author:taoyan date:20211202 for: 异步加载部门树 https://github.com/jeecgboot/jeecg-boot/issues/3196
|
||||
this.expandedKeys = []
|
||||
this.departTree = []
|
||||
queryDepartTreeSync().then((res) => {
|
||||
if (res.success) {
|
||||
this.departTree = res.result;
|
||||
// 默认展开父节点
|
||||
this.expandedKeys = this.departTree.map(item => item.id)
|
||||
for (let i = 0; i < res.result.length; i++) {
|
||||
let temp = res.result[i]
|
||||
this.departTree.push(temp)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
onLoadDepartment(treeNode){
|
||||
return new Promise(resolve => {
|
||||
queryDepartTreeSync({pid:treeNode.dataRef.id}).then((res) => {
|
||||
if (res.success) {
|
||||
//判断chidlren是否为空,并修改isLeaf属性值
|
||||
if(res.result.length == 0){
|
||||
treeNode.dataRef['isLeaf']=true
|
||||
return;
|
||||
}else{
|
||||
treeNode.dataRef['children']= res.result;
|
||||
}
|
||||
}
|
||||
})
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
//update-end-author:taoyan date:20211202 for: 异步加载部门树 https://github.com/jeecgboot/jeecg-boot/issues/3196
|
||||
modalFormOk() {
|
||||
this.loadData();
|
||||
}
|
||||
|
||||
@ -888,10 +888,10 @@
|
||||
cssnano-preset-default "^4.0.0"
|
||||
postcss "^7.0.0"
|
||||
|
||||
"@jeecg/antd-online-mini@3.0.0-beta":
|
||||
version "3.0.0-beta"
|
||||
resolved "https://registry.npmjs.org/@jeecg/antd-online-mini/-/antd-online-mini-3.0.0-beta.tgz#bd7cbbd30c7c2cdee9d816ad996cd9a58378dc95"
|
||||
integrity sha512-V2JwKeBy8WinDrIcGaZyr+FwmF63aItR8dEO570qVhw+Gfz+E9p+fE7SNmSDdbjNu4yiKfsavzdl2JvG4pwgXA==
|
||||
"@jeecg/antd-online-mini@3.0.0-RC":
|
||||
version "3.0.0-RC"
|
||||
resolved "https://registry.npmjs.org/@jeecg/antd-online-mini/-/antd-online-mini-3.0.0-RC.tgz#8b220234d39bfcd9b8b1ce2c78ca1bd92b86da0b"
|
||||
integrity sha512-oNYRPsnlKUPpJKJvQSaqgX6XenDPKwFLHcLYFdrmEYnSCGU46x1p/coqea9r8lI6s1Y2Az0+xAOdwOMPnu/AtQ==
|
||||
|
||||
"@mrmlnc/readdir-enhanced@^2.2.1":
|
||||
version "2.2.1"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -114,7 +114,7 @@
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>hibernate-re</artifactId>
|
||||
<version>3.0.0-beta</version>
|
||||
<version>3.0.02</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 数据库驱动 -->
|
||||
|
||||
@ -103,6 +103,16 @@ public class Result<T> implements Serializable {
|
||||
return r;
|
||||
}
|
||||
|
||||
public static<T> Result<T> OK(String msg) {
|
||||
Result<T> r = new Result<T>();
|
||||
r.setSuccess(true);
|
||||
r.setCode(CommonConstant.SC_OK_200);
|
||||
r.setMessage(msg);
|
||||
//Result OK(String msg)方法会造成兼容性问题 issues/I4IP3D
|
||||
r.setResult((T) msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static<T> Result<T> OK(T data) {
|
||||
Result<T> r = new Result<T>();
|
||||
r.setSuccess(true);
|
||||
|
||||
@ -154,7 +154,7 @@ public class OssBootUtil {
|
||||
*/
|
||||
public static String getOriginalUrl(String url) {
|
||||
String originalDomain = "https://" + bucketName + "." + endPoint;
|
||||
if(url.indexOf(staticDomain)!=-1){
|
||||
if(oConvertUtils.isNotEmpty(staticDomain) && url.indexOf(staticDomain)!=-1){
|
||||
url = url.replace(staticDomain,originalDomain);
|
||||
}
|
||||
return url;
|
||||
|
||||
@ -41,7 +41,10 @@ public class WebMvcConfiguration implements WebMvcConfigurer {
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/**")
|
||||
.addResourceLocations("file:" + upLoadPath + "//", "file:" + webAppPath + "//")
|
||||
//update-begin-author:taoyan date:20211116 for: jeecg.path.webapp配置无效 #3126
|
||||
.addResourceLocations("file:" + upLoadPath + "//")
|
||||
.addResourceLocations("file:" + webAppPath + "//")
|
||||
//update-end-author:taoyan date:20211116 for: jeecg.path.webapp配置无效 #3126
|
||||
.addResourceLocations(staticLocations.split(","));
|
||||
}
|
||||
|
||||
@ -72,9 +75,9 @@ public class WebMvcConfiguration implements WebMvcConfigurer {
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加Long转json精度丢失的配置
|
||||
* @Return: void
|
||||
*/
|
||||
* 添加Long转json精度丢失的配置
|
||||
* @Return: void
|
||||
*/
|
||||
@Override
|
||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
|
||||
|
||||
@ -4,12 +4,13 @@ MAINTAINER jeecgos@163.com
|
||||
|
||||
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||
|
||||
RUN mkdir -p /jeecg-boot
|
||||
RUN mkdir -p /jeecg-boot/config/jeecg/
|
||||
|
||||
WORKDIR /jeecg-boot
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
ADD ./src/main/resources/jeecg ./config/jeecg
|
||||
ADD ./target/jeecg-boot-module-system-3.0.jar ./
|
||||
|
||||
CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-3.0.jar
|
||||
@ -205,7 +205,10 @@ public class SysDepartRoleController extends JeecgController<SysDepartRole, ISys
|
||||
List<SysDepartRole> roleList = sysDepartRoleService.list(new QueryWrapper<SysDepartRole>().eq("depart_id",departId));
|
||||
List<String> roleIds = roleList.stream().map(SysDepartRole::getId).collect(Collectors.toList());
|
||||
//根据角色id,用户id查询已授权角色
|
||||
List<SysDepartRoleUser> roleUserList = departRoleUserService.list(new QueryWrapper<SysDepartRoleUser>().eq("user_id",userId).in("drole_id",roleIds));
|
||||
List<SysDepartRoleUser> roleUserList = null;
|
||||
if(roleIds!=null && roleIds.size()>0){
|
||||
roleUserList = departRoleUserService.list(new QueryWrapper<SysDepartRoleUser>().eq("user_id",userId).in("drole_id",roleIds));
|
||||
}
|
||||
result.setSuccess(true);
|
||||
result.setResult(roleUserList);
|
||||
return result;
|
||||
|
||||
@ -126,9 +126,11 @@
|
||||
<select id="queryTreeList" parameterType="Object" resultType="org.jeecg.modules.system.model.TreeSelectModel">
|
||||
select ${text} as "title",
|
||||
${code} as "key",
|
||||
<!-- udapte-begin-author:taoyan date:20211115 for: 自定义树控件只显示父节点,子节点无法展开 (此处还原不可再改) /issues/I4HZAL -->
|
||||
<if test="hasChildField != null and hasChildField != ''">
|
||||
${hasChildField} as "isLeaf",
|
||||
(case when ${hasChildField} = '1' then 0 else 1 end) as isLeaf,
|
||||
</if>
|
||||
<!-- udapte-end-author:taoyan date:20211115 for: 自定义树控件只显示父节点,子节点无法展开 (此处还原不可再改) /issues/I4HZAL -->
|
||||
${pidField} as parentId
|
||||
from ${table}
|
||||
where
|
||||
|
||||
@ -288,6 +288,9 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
public List<String> getMySubDepIdsByDepId(String departIds) {
|
||||
//根据部门id获取所负责部门
|
||||
String[] codeArr = this.getMyDeptParentOrgCode(departIds);
|
||||
if(codeArr==null || codeArr.length==0){
|
||||
return null;
|
||||
}
|
||||
return this.baseMapper.getSubDepIdsByOrgCodes(codeArr);
|
||||
}
|
||||
|
||||
|
||||
@ -1,244 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<#assign list_need_category=false>
|
||||
<#assign list_need_pca=false>
|
||||
<#assign bpm_flag=false>
|
||||
|
||||
<#-- 开始循环 -->
|
||||
<#list columns as po>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.classType=='cat_tree' && po.dictText?default("")?trim?length == 0>
|
||||
<#assign list_need_category=true>
|
||||
</#if>
|
||||
<#if po.classType=='pca'>
|
||||
<#assign list_need_pca=true>
|
||||
</#if>
|
||||
</#list>
|
||||
<#-- 结束循环 -->
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
|
||||
<ExcelButton :config="excelConfig"></ExcelButton>
|
||||
<a-dropdown v-if="checkedKeys.length > 0">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="batchHandleDelete">
|
||||
<Icon icon="ant-design:delete-outlined"></Icon>
|
||||
删除
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button>批量操作
|
||||
<Icon icon="mdi:chevron-down"></Icon>
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
|
||||
</template>
|
||||
<!--字段回显插槽-->
|
||||
<template #htmlSlot="{text}">
|
||||
<div v-html="text"></div>
|
||||
</template>
|
||||
<template #fileSlot="{text}">
|
||||
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
|
||||
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<${entityName}Modal @register="registerModal" @success="handleSuccess"></${entityName}Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed, unref} from 'vue';
|
||||
import {BasicTable, useTable, TableAction} from '/@/components/Table';
|
||||
import ExcelButton from '/@/components/jeecg/ExcelButton.vue'
|
||||
import {useModal} from '/@/components/Modal';
|
||||
import ${entityName}Modal from './components/${entityName}Modal.vue'
|
||||
import {columns, searchFormSchema} from './${entityName?uncap_first}.data';
|
||||
import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName?uncap_first}.api';
|
||||
<#if list_need_category>
|
||||
import { loadCategoryData } from '/@/api/common/api'
|
||||
import { getAuthCache, setAuthCache } from '/@/utils/auth';
|
||||
import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
|
||||
</#if>
|
||||
const checkedKeys = ref<Array<string | number>>([]);
|
||||
//注册model
|
||||
const [registerModal, {openModal}] = useModal();
|
||||
//注册table数据
|
||||
const [registerTable, {reload}] = useTable({
|
||||
title: '${tableVo.ftlDescription}',
|
||||
api: list,
|
||||
rowKey: 'id',
|
||||
columns,
|
||||
formConfig: {
|
||||
labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter:true,
|
||||
showAdvancedButton:true,
|
||||
fieldMapToTime: [
|
||||
<#list columns as po>
|
||||
<#if po.isQuery=='Y'>
|
||||
<#if po.queryMode!='single'>
|
||||
<#if po.classType=='date'>
|
||||
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD'],
|
||||
<#elseif po.classType=='datetime'>
|
||||
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD HH:mm:ss'],
|
||||
</#if>
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
],
|
||||
},
|
||||
striped: true,
|
||||
useSearchForm: true,
|
||||
showTableSetting: true,
|
||||
clickToRowSelect: false,
|
||||
bordered: true,
|
||||
showIndexColumn: false,
|
||||
tableSetting: {fullScreen: true},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
slots: {customRender: 'action'},
|
||||
fixed: 'right',
|
||||
},
|
||||
})
|
||||
/**
|
||||
* excel导入导出配置
|
||||
*/
|
||||
const excelConfig = {
|
||||
export: {
|
||||
name:'${tableVo.ftlDescription}',
|
||||
url: getExportUrl,
|
||||
},
|
||||
import: {
|
||||
url: getImportUrl,
|
||||
success: reload,
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 选择列配置
|
||||
*/
|
||||
const rowSelection = {
|
||||
type: 'checkbox',
|
||||
columnWidth: 30,
|
||||
selectedRowKeys: checkedKeys,
|
||||
onChange: onSelectChange
|
||||
}
|
||||
/**
|
||||
* 选择事件
|
||||
*/
|
||||
function onSelectChange(selectedRowKeys: (string | number)[]) {
|
||||
checkedKeys.value = selectedRowKeys;
|
||||
}
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await deleteOne({id: record.id}, reload);
|
||||
}
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
await batchDelete({ids: checkedKeys.value}, reload);
|
||||
}
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record){
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
}
|
||||
]
|
||||
}
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record){
|
||||
return [
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
}, {
|
||||
label: '删除',
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
<#if list_need_category>
|
||||
/**
|
||||
* 初始化字典配置
|
||||
*/
|
||||
function initDictConfig(){
|
||||
<#list columns as po>
|
||||
<#if (po.isQuery=='Y' || po.isShowList=='Y') && po.classType!='popup'>
|
||||
<#if po.classType=='cat_tree' && list_need_category==true>
|
||||
loadCategoryData({code:'${po.dictField?default("")}'}).then((res) => {
|
||||
if (res) {
|
||||
let allDictDate = getAuthCache(DB_DICT_DATA_KEY);
|
||||
if(!allDictDate['${po.dictField?default("")}']){
|
||||
Object.assign(allDictDate,{'${po.dictField?default("")}':res})
|
||||
}
|
||||
setAuthCache(DB_DICT_DATA_KEY,allDictDate)
|
||||
}
|
||||
})
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
initDictConfig();
|
||||
</#if>
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,61 +0,0 @@
|
||||
import {defHttp} from '/@/utils/http/axios';
|
||||
import {Modal} from 'ant-design-vue';
|
||||
|
||||
enum Api {
|
||||
list = '/${entityPackage}/${entityName?uncap_first}/list',
|
||||
save='/${entityPackage}/${entityName?uncap_first}/add',
|
||||
edit='/${entityPackage}/${entityName?uncap_first}/edit',
|
||||
deleteOne = '/${entityPackage}/${entityName?uncap_first}/delete',
|
||||
deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch',
|
||||
importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel',
|
||||
exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls',
|
||||
}
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
/**
|
||||
* 导入api
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) =>
|
||||
defHttp.get({url: Api.list, params});
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params,handleSuccess) => {
|
||||
return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
*/
|
||||
export const batchDelete = (params, handleSuccess) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
let url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({url: url, params});
|
||||
}
|
||||
@ -1,352 +0,0 @@
|
||||
import {BasicColumn} from '/@/components/Table';
|
||||
import {FormSchema} from '/@/components/Table';
|
||||
import { rules} from '/@/utils/helper/validator';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
<#list columns as po>
|
||||
<#if po.isShowList =='Y' && po.fieldName !='id'>
|
||||
{
|
||||
title: '${po.filedComment}',
|
||||
align:"center",
|
||||
<#if po.sort=='Y'>
|
||||
sorter: true,
|
||||
</#if>
|
||||
<#if po.classType=='date'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:({text}) =>{
|
||||
return !text?"":(text.length>10?text.substr(0,10):text)
|
||||
},
|
||||
<#elseif po.fieldDbType=='Blob'>
|
||||
dataIndex: '${po.fieldName}String'
|
||||
<#elseif po.classType=='umeditor'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'htmlSlot' },
|
||||
<#elseif po.classType=='pca'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'pcaSlot' },//TODO 未翻译
|
||||
<#elseif po.classType=='file'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'fileSlot' },
|
||||
<#elseif po.classType=='image'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:render.renderAvatar,
|
||||
<#elseif po.classType=='switch'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#assign switch_extend_arr=['Y','N']>
|
||||
<#if po.dictField?default("")?contains("[")>
|
||||
<#assign switch_extend_arr=po.dictField?eval>
|
||||
</#if>
|
||||
<#list switch_extend_arr as a>
|
||||
<#if a_index == 0>
|
||||
<#assign switch_extend_arr1=a>
|
||||
<#else>
|
||||
<#assign switch_extend_arr2=a>
|
||||
</#if>
|
||||
</#list>
|
||||
customRender:({text}) => {
|
||||
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
|
||||
},
|
||||
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||
dataIndex: '${po.fieldName}_dictText'
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#if po.dictText?default("")?trim?length == 0>
|
||||
customRender:({text}) => {
|
||||
return render.renderCategoryTree(text,'${po.dictField?default("")}')
|
||||
},
|
||||
<#else>
|
||||
customRender: (text, record) => (text ? record['${po.dictText}'] : '')
|
||||
</#if>
|
||||
<#else>
|
||||
dataIndex: '${po.fieldName}'
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
<#-- 开始循环 -->
|
||||
<#list columns as po>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isQuery=='Y'>
|
||||
<#assign query_flag=true>
|
||||
<#assign query_field_dictCode="">
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictField}">
|
||||
</#if>
|
||||
<#if po.queryMode=='single'>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
},
|
||||
<#elseif po.classType=='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
<#elseif po.classType=='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType=='list_multi'>
|
||||
component: 'JMultiSelectTag',//暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"query_field_dictCode?default("")"
|
||||
},
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题
|
||||
},
|
||||
<#elseif po.classType=='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.classType=='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType=='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:"${po.dictField}",
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
},
|
||||
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
<#else>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='date'>
|
||||
component: 'RangePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'RangePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#else>
|
||||
component: 'Input', //TODO 范围查询
|
||||
</#if>
|
||||
colProps: {span: 6},
|
||||
},
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
<#-- 结束循环 -->
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
<#assign form_cat_tree = false>
|
||||
<#assign form_cat_back = "">
|
||||
<#assign bpm_flag=false>
|
||||
<#list columns as po><#rt/>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isShow =='Y'>
|
||||
<#assign form_field_dictCode="">
|
||||
<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
|
||||
<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
<#assign form_field_dictCode="${po.dictField}">
|
||||
</#if>
|
||||
{
|
||||
label: '${po.filedComment}',
|
||||
field: '${po.fieldName}',
|
||||
<#if po.classType =='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.fieldType =='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.fieldType =='time'>
|
||||
component: 'TimePicker',
|
||||
<#elseif po.classType =='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:${po.dictField},
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
}
|
||||
<#elseif po.classType =='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType =='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:${po.dictField}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType =='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType =='markdown'>
|
||||
component: 'JMarkdownEditor',//注意string转换问题
|
||||
<#elseif po.classType =='password'>
|
||||
component: 'InputPassword',
|
||||
<#elseif po.classType =='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
componentProps:{
|
||||
labelKey:'realname',
|
||||
}
|
||||
<#elseif po.classType =='textarea'>
|
||||
component: 'InputTextArea',//TODO 注意string转换问题
|
||||
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
<#assign form_cat_tree = true>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||
}
|
||||
<#if po.dictText?default("")?trim?length gt 1>
|
||||
<#assign form_cat_back = "${po.dictText}">
|
||||
</#if>
|
||||
<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||
component: 'InputNumber',
|
||||
<#elseif po.classType=='file'>
|
||||
component: 'JUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
maxCount:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='image'>
|
||||
component: 'JImageUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
fileMax:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='umeditor'>
|
||||
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||
<#elseif po.classType == 'sel_tree'>
|
||||
component: 'JTreeSelect',
|
||||
componentProps:{
|
||||
<#if po.dictText??>
|
||||
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>
|
||||
dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}",
|
||||
<#elseif po.dictText?split(',')[1]??>
|
||||
pidField:"${po.dictText?split(',')[1]}",
|
||||
<#elseif po.dictText?split(',')[3]??>
|
||||
hasChildField:"${po.dictText?split(',')[3]}",
|
||||
</#if>
|
||||
</#if>
|
||||
pidValue:"${po.dictField}",
|
||||
}
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
<#include "/common/utils.ftl">
|
||||
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||
dynamicRules: ({model,schema}) => {
|
||||
<#if po.fieldName != 'id'>
|
||||
<#assign fieldValidType = po.fieldValidType!''>
|
||||
return [
|
||||
<#-- 非空校验 -->
|
||||
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||
{ required: true, message: '请输入${po.filedComment}!'},
|
||||
<#elseif fieldValidType!=''>
|
||||
{ required: false},
|
||||
</#if>
|
||||
<#-- 唯一校验 -->
|
||||
<#if fieldValidType == 'only'>
|
||||
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||
<#-- 6到16位数字 -->
|
||||
<#elseif fieldValidType == 'n6-16'>
|
||||
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||
<#-- 6到16位任意字符 -->
|
||||
<#elseif fieldValidType == '*6-16'>
|
||||
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||
<#-- 6到18位字符串 -->
|
||||
<#elseif fieldValidType == 's6-18'>
|
||||
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||
<#-- 网址 -->
|
||||
<#elseif fieldValidType == 'url'>
|
||||
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||
<#-- 电子邮件 -->
|
||||
<#elseif fieldValidType == 'e'>
|
||||
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||
<#-- 手机号码 -->
|
||||
<#elseif fieldValidType == 'm'>
|
||||
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||
<#-- 邮政编码 -->
|
||||
<#elseif fieldValidType == 'p'>
|
||||
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||
<#-- 字母 -->
|
||||
<#elseif fieldValidType == 's'>
|
||||
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||
<#-- 数字 -->
|
||||
<#elseif fieldValidType == 'n'>
|
||||
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||
<#-- 整数 -->
|
||||
<#elseif fieldValidType == 'z'>
|
||||
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||
<#-- 金额 -->
|
||||
<#elseif fieldValidType == 'money'>
|
||||
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||
<#-- 正则校验 -->
|
||||
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||
<#-- 无校验 -->
|
||||
<#else>
|
||||
<#t>
|
||||
</#if>
|
||||
];
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
<#if po.readonly=='Y'>
|
||||
dynamicDisabled:true
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
@ -1,58 +0,0 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm"/>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed, unref} from 'vue';
|
||||
import {BasicModal, useModalInner} from '/@/components/Modal';
|
||||
import {BasicForm, useForm} from '/@/components/Form/index';
|
||||
import {formSchema} from '../${entityName?uncap_first}.data';
|
||||
import {saveOrUpdate} from '../${entityName?uncap_first}.api';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register','success']);
|
||||
const isUpdate = ref(true);
|
||||
//表单配置
|
||||
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setModalProps({confirmLoading: false,showFooter:!!data?.showFooter});
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
setProps({ disabled: !data?.showFooter })
|
||||
});
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
//表单提交事件
|
||||
async function handleSubmit(v) {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({confirmLoading: true});
|
||||
//提交表单
|
||||
await saveOrUpdate(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({confirmLoading: false});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
||||
@ -1,82 +0,0 @@
|
||||
import {defHttp} from "/@/utils/http/axios";
|
||||
import {Modal} from 'ant-design-vue';
|
||||
|
||||
enum Api {
|
||||
list = '/${entityPackage}/${entityName?uncap_first}/rootList',
|
||||
save='/${entityPackage}/${entityName?uncap_first}/add',
|
||||
edit='/${entityPackage}/${entityName?uncap_first}/edit',
|
||||
delete${entityName} = '/sys/${entityName?uncap_first}/delete',
|
||||
deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch',
|
||||
importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel',
|
||||
exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls',
|
||||
loadTreeData = '/${entityPackage}/${entityName?uncap_first}/loadTreeRoot',
|
||||
getChildList = '/${entityPackage}/${entityName?uncap_first}/childList',
|
||||
getChildListBatch = '/${entityPackage}/${entityName?uncap_first}/getChildListBatch',
|
||||
}
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
/**
|
||||
* 导入api
|
||||
* @param params
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) =>
|
||||
defHttp.get({url: Api.list, params});
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
export const delete${entityName} = (params,handleSuccess) => {
|
||||
return defHttp.delete({url: Api.delete${entityName}, params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
*/
|
||||
export const batchDelete${entityName} = (params, handleSuccess) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
*/
|
||||
export const saveOrUpdateDict = (params, isUpdate) => {
|
||||
let url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({url: url, params});
|
||||
}
|
||||
/**
|
||||
* 查询全部树形节点数据
|
||||
* @param params
|
||||
*/
|
||||
export const loadTreeData = (params) =>
|
||||
defHttp.get({url: Api.loadTreeData,params});
|
||||
/**
|
||||
* 查询子节点数据
|
||||
* @param params
|
||||
*/
|
||||
export const getChildList = (params) =>
|
||||
defHttp.get({url: Api.getChildList, params});
|
||||
/**
|
||||
* 批量查询子节点数据
|
||||
* @param params
|
||||
*/
|
||||
export const getChildListBatch = (params) =>
|
||||
defHttp.get({url: Api.getChildListBatch, params},{isTransformResponse:false});
|
||||
@ -1,352 +0,0 @@
|
||||
import {BasicColumn} from '/@/components/Table';
|
||||
import {FormSchema} from '/@/components/Table';
|
||||
import { rules} from '/@/utils/helper/validator';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
<#list columns as po>
|
||||
<#if po.isShowList =='Y' && po.fieldName !='id'>
|
||||
{
|
||||
title: '${po.filedComment}',
|
||||
align:"center",
|
||||
<#if po.sort=='Y'>
|
||||
sorter: true,
|
||||
</#if>
|
||||
<#if po.classType=='date'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:({text}) =>{
|
||||
return !text?"":(text.length>10?text.substr(0,10):text)
|
||||
},
|
||||
<#elseif po.fieldDbType=='Blob'>
|
||||
dataIndex: '${po.fieldName}String'
|
||||
<#elseif po.classType=='umeditor'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'htmlSlot' },
|
||||
<#elseif po.classType=='pca'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'pcaSlot' },//TODO 未翻译
|
||||
<#elseif po.classType=='file'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'fileSlot' },
|
||||
<#elseif po.classType=='image'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:render.renderAvatar,
|
||||
<#elseif po.classType=='switch'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#assign switch_extend_arr=['Y','N']>
|
||||
<#if po.dictField?default("")?contains("[")>
|
||||
<#assign switch_extend_arr=po.dictField?eval>
|
||||
</#if>
|
||||
<#list switch_extend_arr as a>
|
||||
<#if a_index == 0>
|
||||
<#assign switch_extend_arr1=a>
|
||||
<#else>
|
||||
<#assign switch_extend_arr2=a>
|
||||
</#if>
|
||||
</#list>
|
||||
customRender:({text}) => {
|
||||
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
|
||||
},
|
||||
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||
dataIndex: '${po.fieldName}_dictText'
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#if po.dictText?default("")?trim?length == 0>
|
||||
customRender:({text}) => {
|
||||
return render.renderCategoryTree(text,'${po.dictField?default("")}')
|
||||
},
|
||||
<#else>
|
||||
customRender: (text, record) => (text ? record['${po.dictText}'] : '')
|
||||
</#if>
|
||||
<#else>
|
||||
dataIndex: '${po.fieldName}'
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
<#-- 开始循环 -->
|
||||
<#list columns as po>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isQuery=='Y'>
|
||||
<#assign query_flag=true>
|
||||
<#assign query_field_dictCode="">
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictField}">
|
||||
</#if>
|
||||
<#if po.queryMode=='single'>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
},
|
||||
<#elseif po.classType=='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
<#elseif po.classType=='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType=='list_multi'>
|
||||
component: 'JMultiSelectTag',//暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"query_field_dictCode?default("")"
|
||||
},
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题
|
||||
},
|
||||
<#elseif po.classType=='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.classType=='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType=='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:"${po.dictField}",
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
},
|
||||
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
<#else>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='date'>
|
||||
component: 'RangePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'RangePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#else>
|
||||
component: 'Input', //TODO 范围查询
|
||||
</#if>
|
||||
colProps: {span: 6},
|
||||
},
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
<#-- 结束循环 -->
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
<#assign form_cat_tree = false>
|
||||
<#assign form_cat_back = "">
|
||||
<#assign bpm_flag=false>
|
||||
<#list columns as po><#rt/>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isShow =='Y'>
|
||||
<#assign form_field_dictCode="">
|
||||
<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
|
||||
<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
<#assign form_field_dictCode="${po.dictField}">
|
||||
</#if>
|
||||
{
|
||||
label: '${po.filedComment}',
|
||||
field: '${po.fieldName}',
|
||||
<#if po.classType =='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.fieldType =='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.fieldType =='time'>
|
||||
component: 'TimePicker',
|
||||
<#elseif po.classType =='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:${po.dictField},
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
}
|
||||
<#elseif po.classType =='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType =='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:${po.dictField}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType =='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType =='markdown'>
|
||||
component: 'JMarkdownEditor',//注意string转换问题
|
||||
<#elseif po.classType =='password'>
|
||||
component: 'InputPassword',
|
||||
<#elseif po.classType =='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
componentProps:{
|
||||
labelKey:'realname',
|
||||
}
|
||||
<#elseif po.classType =='textarea'>
|
||||
component: 'InputTextArea',//TODO 注意string转换问题
|
||||
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
<#assign form_cat_tree = true>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||
}
|
||||
<#if po.dictText?default("")?trim?length gt 1>
|
||||
<#assign form_cat_back = "${po.dictText}">
|
||||
</#if>
|
||||
<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||
component: 'InputNumber',
|
||||
<#elseif po.classType=='file'>
|
||||
component: 'JUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
maxCount:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='image'>
|
||||
component: 'JImageUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
fileMax:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='umeditor'>
|
||||
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||
<#elseif po.classType == 'sel_tree'>
|
||||
component: 'JTreeSelect',
|
||||
componentProps:{
|
||||
<#if po.dictText??>
|
||||
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>
|
||||
dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}",
|
||||
<#elseif po.dictText?split(',')[1]??>
|
||||
pidField:"${po.dictText?split(',')[1]}",
|
||||
<#elseif po.dictText?split(',')[3]??>
|
||||
hasChildField:"${po.dictText?split(',')[3]}",
|
||||
</#if>
|
||||
</#if>
|
||||
pidValue:"${po.dictField}",
|
||||
}
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
<#include "/common/utils.ftl">
|
||||
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||
dynamicRules: ({model,schema}) => {
|
||||
<#if po.fieldName != 'id'>
|
||||
<#assign fieldValidType = po.fieldValidType!''>
|
||||
return [
|
||||
<#-- 非空校验 -->
|
||||
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||
{ required: true, message: '请输入${po.filedComment}!'},
|
||||
<#elseif fieldValidType!=''>
|
||||
{ required: false},
|
||||
</#if>
|
||||
<#-- 唯一校验 -->
|
||||
<#if fieldValidType == 'only'>
|
||||
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||
<#-- 6到16位数字 -->
|
||||
<#elseif fieldValidType == 'n6-16'>
|
||||
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||
<#-- 6到16位任意字符 -->
|
||||
<#elseif fieldValidType == '*6-16'>
|
||||
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||
<#-- 6到18位字符串 -->
|
||||
<#elseif fieldValidType == 's6-18'>
|
||||
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||
<#-- 网址 -->
|
||||
<#elseif fieldValidType == 'url'>
|
||||
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||
<#-- 电子邮件 -->
|
||||
<#elseif fieldValidType == 'e'>
|
||||
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||
<#-- 手机号码 -->
|
||||
<#elseif fieldValidType == 'm'>
|
||||
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||
<#-- 邮政编码 -->
|
||||
<#elseif fieldValidType == 'p'>
|
||||
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||
<#-- 字母 -->
|
||||
<#elseif fieldValidType == 's'>
|
||||
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||
<#-- 数字 -->
|
||||
<#elseif fieldValidType == 'n'>
|
||||
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||
<#-- 整数 -->
|
||||
<#elseif fieldValidType == 'z'>
|
||||
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||
<#-- 金额 -->
|
||||
<#elseif fieldValidType == 'money'>
|
||||
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||
<#-- 正则校验 -->
|
||||
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||
<#-- 无校验 -->
|
||||
<#else>
|
||||
<#t>
|
||||
</#if>
|
||||
];
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
<#if po.readonly=='Y'>
|
||||
dynamicDisabled:true
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
@ -1,87 +0,0 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm"/>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed, unref} from 'vue';
|
||||
import {BasicModal, useModalInner} from '/src/components/Modal';
|
||||
import {BasicForm, useForm} from '/src/components/Form';
|
||||
import {formSchema} from '../${entityName?uncap_first}.data';
|
||||
import {loadTreeData, saveOrUpdateDict} from '../${entityName?uncap_first}.api';
|
||||
// 获取emit
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
const expandedRowKeys = ref([]);
|
||||
const treeData = ref([]);
|
||||
//表单配置
|
||||
const [registerForm, {resetFields, setFieldsValue, validate, updateSchema}] = useForm({
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 4 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 18 },
|
||||
},
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
expandedRowKeys.value = [];
|
||||
setModalProps({confirmLoading: false, minHeight: 80});
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
if (data?.record) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
}
|
||||
//父级节点树信息
|
||||
treeData.value = await loadTreeData({'async': false,'pcode':''});
|
||||
updateSchema({
|
||||
field: 'pid',
|
||||
componentProps: {treeData},
|
||||
});
|
||||
});
|
||||
//设置标题
|
||||
const getTitle = computed(() => (!unref(isUpdate) ? '新增字典' : '编辑字典'));
|
||||
|
||||
/**
|
||||
* 根据pid获取展开的节点
|
||||
* @param pid
|
||||
* @param arr
|
||||
*/
|
||||
function getExpandKeysByPid(pid,arr){
|
||||
if(pid && arr && arr.length>0){
|
||||
for(let i=0;i<arr.length;i++){
|
||||
if(arr[i].key==pid && unref(expandedRowKeys).indexOf(pid)<0){
|
||||
expandedRowKeys.value.push(arr[i].key);
|
||||
getExpandKeysByPid(arr[i]['parentId'],unref(treeData))
|
||||
}else{
|
||||
getExpandKeysByPid(pid,arr[i].children)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({confirmLoading: true});
|
||||
//提交表单
|
||||
await saveOrUpdateDict(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//展开的节点信息
|
||||
await getExpandKeysByPid(values['pid'],unref(treeData))
|
||||
//刷新列表(isUpdate:是否编辑;values:表单信息;expandedArr:展开的节点信息)
|
||||
emit('success', {isUpdate: unref(isUpdate), values:{...values},expandedArr: unref(expandedRowKeys).reverse()});
|
||||
} finally {
|
||||
setModalProps({confirmLoading: false});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,295 +0,0 @@
|
||||
<template>
|
||||
<div class="p-4">
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection" :expandedRowKeys="expandedRowKeys" @expand="handleExpand" @fetch-success="onFetchSuccess">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleCreate"> 新增</a-button>
|
||||
<a-upload name="file" :showUploadList="false" :customRequest="(file)=>handleImportXls(file,getImportUrl,importSuccess)">
|
||||
<a-button type="primary" preIcon="ant-design:import-outlined">导入</a-button>
|
||||
</a-upload>
|
||||
<a-button type="primary" preIcon="ant-design:export-outlined" @click="handleExportXls('${tableVo.ftlDescription}管理',getExportUrl)"> 导出</a-button>
|
||||
|
||||
<a-dropdown v-if="checkedKeys.length > 0">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="batchHandleDelete">
|
||||
<Icon icon="ant-design:delete-outlined"></Icon>
|
||||
删除
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button>批量操作
|
||||
<Icon icon="ant-design:down-outlined"></Icon>
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)"/>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!--字典弹窗-->
|
||||
<${entityName}Modal @register="registerModal" @success="handleSuccess"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
//ts语法
|
||||
import {ref, computed, unref, toRaw, nextTick} from 'vue';
|
||||
import {BasicTable, useTable, TableAction} from '/src/components/Table';
|
||||
import {useDrawer} from '/src/components/Drawer';
|
||||
import ${entityName}Modal from './components/${entityName}Modal.vue';
|
||||
import {useModal} from '/src/components/Modal';
|
||||
import {useMethods} from '/src/hooks/system/useMethods';
|
||||
import {columns} from './${entityName}.data';
|
||||
import {list, delete${entityName}, batchDelete${entityName}, getExportUrl,getImportUrl, getChildList,getChildListBatch} from './${entityName}.api';
|
||||
|
||||
const checkedKeys = ref<Array<string | number>>([]);
|
||||
const expandedRowKeys = ref([]);
|
||||
const {handleExportXls,handleImportXls} = useMethods();
|
||||
//字典model
|
||||
const [registerModal, {openModal}] = useModal();
|
||||
//注册table数据
|
||||
const [registerTable, {reload, collapseAll, updateTableDataRecord, findTableDataRecord,getDataSource}] = useTable({
|
||||
api: list,
|
||||
rowKey: 'id',
|
||||
columns,
|
||||
striped: true,
|
||||
useSearchForm: false,
|
||||
showTableSetting: true,
|
||||
clickToRowSelect: false,
|
||||
bordered: true,
|
||||
showIndexColumn: false,
|
||||
tableSetting: {fullScreen: true},
|
||||
canResize: false,
|
||||
actionColumn: {
|
||||
width: 80,
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
slots: {customRender: 'action'},
|
||||
fixed: undefined,
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
* 选择列配置
|
||||
*/
|
||||
const rowSelection = {
|
||||
type: 'checkbox',
|
||||
columnWidth: 10,
|
||||
selectedRowKeys: checkedKeys,
|
||||
onChange: onSelectChange
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择事件
|
||||
*/
|
||||
function onSelectChange(selectedRowKeys: (string | number)[]) {
|
||||
checkedKeys.value = selectedRowKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleCreate() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
async function handleEdit(record) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
async function handleDetail(record) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
hideFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await delete${entityName}({id: record.id}, importSuccess);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
const ids = checkedKeys.value.filter(item => !item.includes('loading'))
|
||||
await batchDelete${entityName}({ids: ids}, importSuccess);
|
||||
}
|
||||
/**
|
||||
* 导入
|
||||
*/
|
||||
function importSuccess() {
|
||||
reload() && (expandedRowKeys.value = []);
|
||||
}
|
||||
/**
|
||||
* 添加下级
|
||||
*/
|
||||
function handleAddSub(record) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
async function handleSuccess({isUpdate, values, expandedArr}) {
|
||||
if (isUpdate) {
|
||||
//编辑回调
|
||||
updateTableDataRecord(values.id, values);
|
||||
} else {
|
||||
if(!values['pid']){
|
||||
//新增根节点
|
||||
reload();
|
||||
}else{
|
||||
//新增子集
|
||||
expandedRowKeys.value = [];
|
||||
for (let key of unref(expandedArr)) {
|
||||
await expandTreeNode(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口请求成功后回调
|
||||
*/
|
||||
function onFetchSuccess(result) {
|
||||
getDataByResult(result.items)&&loadDataByExpandedRows();
|
||||
}
|
||||
/**
|
||||
* 根据已展开的行查询数据(用于保存后刷新时异步加载子级的数据)
|
||||
*/
|
||||
async function loadDataByExpandedRows() {
|
||||
if (unref(expandedRowKeys).length > 0) {
|
||||
const res = await getChildListBatch({ parentIds: unref(expandedRowKeys).join(',')});
|
||||
if (res.success && res.result.records.length>0) {
|
||||
//已展开的数据批量子节点
|
||||
let records = res.result.records
|
||||
const listMap = new Map();
|
||||
for (let item of records) {
|
||||
let pid = item['pid'];
|
||||
if (unref(expandedRowKeys).includes(pid)) {
|
||||
let mapList = listMap.get(pid);
|
||||
if (mapList == null) {
|
||||
mapList = [];
|
||||
}
|
||||
mapList.push(item);
|
||||
listMap.set(pid, mapList);
|
||||
}
|
||||
}
|
||||
let childrenMap = listMap;
|
||||
let fn = (list) => {
|
||||
if(list) {
|
||||
list.forEach(data => {
|
||||
if (unref(expandedRowKeys).includes(data.id)) {
|
||||
data.children = getDataByResult(childrenMap.get(data.id))
|
||||
fn(data.children)
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
fn(getDataSource())
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 处理数据集
|
||||
*/
|
||||
function getDataByResult(result){
|
||||
if(result && result.length>0){
|
||||
return result.map(item=>{
|
||||
//判断是否标记了带有子节点
|
||||
if(item["hasChild"]=='1'){
|
||||
let loadChild = { id: item.id+'_loadChild', name: 'loading...', isLoading: true }
|
||||
item.children = [loadChild]
|
||||
}
|
||||
return item
|
||||
})
|
||||
}
|
||||
}
|
||||
/**
|
||||
*树节点展开合并
|
||||
* */
|
||||
async function handleExpand(expanded, record) {
|
||||
// 判断是否是展开状态,展开状态(expanded)并且存在子集(children)并且未加载过(isLoading)的就去查询子节点数据
|
||||
if (expanded) {
|
||||
expandedRowKeys.value.push(record.id)
|
||||
if (record.children.length > 0 && !!record.children[0].isLoading) {
|
||||
let result = await getChildList({pid: record.id});
|
||||
result=result.records?result.records:result;
|
||||
if (result && result.length > 0) {
|
||||
record.children = getDataByResult(result);
|
||||
} else {
|
||||
record.children = null
|
||||
record.hasChild = '0'
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let keyIndex = expandedRowKeys.value.indexOf(record.id)
|
||||
if (keyIndex >= 0) {
|
||||
expandedRowKeys.value.splice(keyIndex, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
*操作表格后处理树节点展开合并
|
||||
* */
|
||||
async function expandTreeNode(key) {
|
||||
let record = findTableDataRecord(key)
|
||||
expandedRowKeys.value.push(key);
|
||||
let result = await getChildList({pid: key});
|
||||
if (result && result.length > 0) {
|
||||
record.children = getDataByResult(result);
|
||||
} else {
|
||||
record.children = null
|
||||
record.hasChild = '0'
|
||||
}
|
||||
updateTableDataRecord(key, record);
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
popConfirm: {
|
||||
title: '确定删除吗?',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '添加下级',
|
||||
onClick: handleAddSub.bind(null, {pid: record.id}),
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,244 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<#assign list_need_category=false>
|
||||
<#assign list_need_pca=false>
|
||||
<#assign bpm_flag=false>
|
||||
|
||||
<#-- 开始循环 -->
|
||||
<#list columns as po>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.classType=='cat_tree' && po.dictText?default("")?trim?length == 0>
|
||||
<#assign list_need_category=true>
|
||||
</#if>
|
||||
<#if po.classType=='pca'>
|
||||
<#assign list_need_pca=true>
|
||||
</#if>
|
||||
</#list>
|
||||
<#-- 结束循环 -->
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
|
||||
<ExcelButton :config="excelConfig"></ExcelButton>
|
||||
<a-dropdown v-if="checkedKeys.length > 0">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="batchHandleDelete">
|
||||
<Icon icon="ant-design:delete-outlined"></Icon>
|
||||
删除
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button>批量操作
|
||||
<Icon icon="mdi:chevron-down"></Icon>
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
|
||||
</template>
|
||||
<!--字段回显插槽-->
|
||||
<template #htmlSlot="{text}">
|
||||
<div v-html="text"></div>
|
||||
</template>
|
||||
<template #fileSlot="{text}">
|
||||
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
|
||||
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<${entityName}Modal @register="registerModal" @success="handleSuccess"></${entityName}Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed, unref} from 'vue';
|
||||
import {BasicTable, useTable, TableAction} from '/@/components/Table';
|
||||
import ExcelButton from '/@/components/jeecg/ExcelButton.vue'
|
||||
import {useModal} from '/@/components/Modal';
|
||||
import ${entityName}Modal from './components/${entityName}Modal.vue'
|
||||
import {columns, searchFormSchema} from './${entityName?uncap_first}.data';
|
||||
import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName?uncap_first}.api';
|
||||
<#if list_need_category>
|
||||
import { loadCategoryData } from '/@/api/common/api'
|
||||
import { getAuthCache, setAuthCache } from '/@/utils/auth';
|
||||
import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
|
||||
</#if>
|
||||
const checkedKeys = ref<Array<string | number>>([]);
|
||||
//注册model
|
||||
const [registerModal, {openModal}] = useModal();
|
||||
//注册table数据
|
||||
const [registerTable, {reload}] = useTable({
|
||||
title: '${tableVo.ftlDescription}',
|
||||
api: list,
|
||||
rowKey: 'id',
|
||||
columns,
|
||||
formConfig: {
|
||||
labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter:true,
|
||||
showAdvancedButton:true,
|
||||
fieldMapToTime: [
|
||||
<#list columns as po>
|
||||
<#if po.isQuery=='Y'>
|
||||
<#if po.queryMode!='single'>
|
||||
<#if po.classType=='date'>
|
||||
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD'],
|
||||
<#elseif po.classType=='datetime'>
|
||||
['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD HH:mm:ss'],
|
||||
</#if>
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
],
|
||||
},
|
||||
striped: true,
|
||||
useSearchForm: true,
|
||||
showTableSetting: true,
|
||||
clickToRowSelect: false,
|
||||
bordered: true,
|
||||
showIndexColumn: false,
|
||||
tableSetting: {fullScreen: true},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
slots: {customRender: 'action'},
|
||||
fixed: 'right',
|
||||
},
|
||||
})
|
||||
/**
|
||||
* excel导入导出配置
|
||||
*/
|
||||
const excelConfig = {
|
||||
export: {
|
||||
name:'${tableVo.ftlDescription}',
|
||||
url: getExportUrl,
|
||||
},
|
||||
import: {
|
||||
url: getImportUrl,
|
||||
success: reload,
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 选择列配置
|
||||
*/
|
||||
const rowSelection = {
|
||||
type: 'checkbox',
|
||||
columnWidth: 30,
|
||||
selectedRowKeys: checkedKeys,
|
||||
onChange: onSelectChange
|
||||
}
|
||||
/**
|
||||
* 选择事件
|
||||
*/
|
||||
function onSelectChange(selectedRowKeys: (string | number)[]) {
|
||||
checkedKeys.value = selectedRowKeys;
|
||||
}
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await deleteOne({id: record.id}, reload);
|
||||
}
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
await batchDelete({ids: checkedKeys.value}, reload);
|
||||
}
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record){
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
}
|
||||
]
|
||||
}
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record){
|
||||
return [
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
}, {
|
||||
label: '删除',
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
<#if list_need_category>
|
||||
/**
|
||||
* 初始化字典配置
|
||||
*/
|
||||
function initDictConfig(){
|
||||
<#list columns as po>
|
||||
<#if (po.isQuery=='Y' || po.isShowList=='Y') && po.classType!='popup'>
|
||||
<#if po.classType=='cat_tree' && list_need_category==true>
|
||||
loadCategoryData({code:'${po.dictField?default("")}'}).then((res) => {
|
||||
if (res) {
|
||||
let allDictDate = getAuthCache(DB_DICT_DATA_KEY);
|
||||
if(!allDictDate['${po.dictField?default("")}']){
|
||||
Object.assign(allDictDate,{'${po.dictField?default("")}':res})
|
||||
}
|
||||
setAuthCache(DB_DICT_DATA_KEY,allDictDate)
|
||||
}
|
||||
})
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
initDictConfig();
|
||||
</#if>
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,72 +0,0 @@
|
||||
import {defHttp} from '/@/utils/http/axios';
|
||||
import {Modal} from 'ant-design-vue';
|
||||
|
||||
enum Api {
|
||||
list = '/${entityPackage}/${entityName?uncap_first}/list',
|
||||
save='/${entityPackage}/${entityName?uncap_first}/add',
|
||||
edit='/${entityPackage}/${entityName?uncap_first}/edit',
|
||||
deleteOne = '/${entityPackage}/${entityName?uncap_first}/delete',
|
||||
deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch',
|
||||
importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel',
|
||||
exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls',
|
||||
<#list subTables as sub><#rt/>
|
||||
${sub.entityName?uncap_first}List = '/${entityPackage}/${entityName?uncap_first}/query${sub.entityName}ByMainId',
|
||||
</#list>
|
||||
}
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
|
||||
/**
|
||||
* 导入api
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
<#list subTables as sub><#rt/>
|
||||
/**
|
||||
* 查询子表数据
|
||||
* @param params
|
||||
*/
|
||||
export const ${sub.entityName?uncap_first}List = Api.${sub.entityName?uncap_first}List;
|
||||
</#list>
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) =>
|
||||
defHttp.get({url: Api.list, params});
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params,handleSuccess) => {
|
||||
return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
*/
|
||||
export const batchDelete = (params, handleSuccess) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
let url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({url: url, params});
|
||||
}
|
||||
@ -1,698 +0,0 @@
|
||||
import {BasicColumn} from '/@/components/Table';
|
||||
import {FormSchema} from '/@/components/Table';
|
||||
import { rules} from '/@/utils/helper/validator';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
import {JVxeTypes,JVxeColumn} from '/@/components/jeecg/JVxeTable/types'
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
<#list columns as po>
|
||||
<#if po.isShowList =='Y' && po.fieldName !='id'>
|
||||
{
|
||||
title: '${po.filedComment}',
|
||||
align:"center",
|
||||
<#if po.sort=='Y'>
|
||||
sorter: true,
|
||||
</#if>
|
||||
<#if po.classType=='date'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:({text}) =>{
|
||||
return !text?"":(text.length>10?text.substr(0,10):text)
|
||||
},
|
||||
<#elseif po.fieldDbType=='Blob'>
|
||||
dataIndex: '${po.fieldName}String'
|
||||
<#elseif po.classType=='umeditor'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'htmlSlot' },
|
||||
<#elseif po.classType=='pca'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'pcaSlot' },//TODO 未翻译
|
||||
<#elseif po.classType=='file'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
slots: { customRender: 'fileSlot' },
|
||||
<#elseif po.classType=='image'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
customRender:render.renderAvatar,
|
||||
<#elseif po.classType=='switch'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#assign switch_extend_arr=['Y','N']>
|
||||
<#if po.dictField?default("")?contains("[")>
|
||||
<#assign switch_extend_arr=po.dictField?eval>
|
||||
</#if>
|
||||
<#list switch_extend_arr as a>
|
||||
<#if a_index == 0>
|
||||
<#assign switch_extend_arr1=a>
|
||||
<#else>
|
||||
<#assign switch_extend_arr2=a>
|
||||
</#if>
|
||||
</#list>
|
||||
customRender:({text}) => {
|
||||
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
|
||||
},
|
||||
<#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'>
|
||||
dataIndex: '${po.fieldName}_dictText'
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
dataIndex: '${po.fieldName}',
|
||||
<#if po.dictText?default("")?trim?length == 0>
|
||||
customRender:({text}) => {
|
||||
return render.renderCategoryTree(text,'${po.dictField?default("")}')
|
||||
},
|
||||
<#else>
|
||||
customRender: (text, record) => (text ? record['${po.dictText}'] : '')
|
||||
</#if>
|
||||
<#else>
|
||||
dataIndex: '${po.fieldName}'
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
<#-- 开始循环 -->
|
||||
<#list columns as po>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isQuery=='Y'>
|
||||
<#assign query_flag=true>
|
||||
<#assign query_field_dictCode="">
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
<#assign query_field_dictCode="${po.dictField}">
|
||||
</#if>
|
||||
<#if po.queryMode=='single'>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
},
|
||||
<#elseif po.classType=='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
<#elseif po.classType=='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#elseif po.classType=='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType=='list_multi'>
|
||||
component: 'JMultiSelectTag',//暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"query_field_dictCode?default("")"
|
||||
},
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题
|
||||
},
|
||||
<#elseif po.classType=='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.classType=='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType=='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:"${po.dictField}",
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
},
|
||||
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
|
||||
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
<#if po.dictTable?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictTable},${po.dictText},${po.dictField}"
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
dictCode:"${po.dictField}"
|
||||
</#if>
|
||||
},
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
<#else>
|
||||
{
|
||||
label: "${po.filedComment}",
|
||||
field: "${po.fieldName}",
|
||||
<#if po.classType=='date'>
|
||||
component: 'RangePicker',
|
||||
<#elseif po.classType=='datetime'>
|
||||
component: 'RangePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#else>
|
||||
component: 'Input', //TODO 范围查询
|
||||
</#if>
|
||||
colProps: {span: 6},
|
||||
},
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
<#-- 结束循环 -->
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
<#assign form_cat_tree = false>
|
||||
<#assign form_cat_back = "">
|
||||
<#assign bpm_flag=false>
|
||||
<#list columns as po><#rt/>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isShow =='Y'>
|
||||
<#assign form_field_dictCode="">
|
||||
<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
|
||||
<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
<#assign form_field_dictCode="${po.dictField}">
|
||||
</#if>
|
||||
{
|
||||
label: '${po.filedComment}',
|
||||
field: '${po.fieldName}',
|
||||
<#if po.classType =='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.fieldType =='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.fieldType =='time'>
|
||||
component: 'TimePicker',
|
||||
<#elseif po.classType =='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:${po.dictField},
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
}
|
||||
<#elseif po.classType =='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType =='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:${po.dictField}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType =='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType =='markdown'>
|
||||
component: 'JMarkdownEditor',//注意string转换问题
|
||||
<#elseif po.classType =='password'>
|
||||
component: 'InputPassword',
|
||||
<#elseif po.classType =='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
componentProps:{
|
||||
labelKey:'realname',
|
||||
}
|
||||
<#elseif po.classType =='textarea'>
|
||||
component: 'InputTextArea',//TODO 注意string转换问题
|
||||
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
<#assign form_cat_tree = true>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||
}
|
||||
<#if po.dictText?default("")?trim?length gt 1>
|
||||
<#assign form_cat_back = "${po.dictText}">
|
||||
</#if>
|
||||
<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||
component: 'InputNumber',
|
||||
<#elseif po.classType=='file'>
|
||||
component: 'JUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
maxCount:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='image'>
|
||||
component: 'JImageUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
fileMax:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='umeditor'>
|
||||
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||
<#elseif po.classType == 'sel_tree'>
|
||||
component: 'JTreeSelect',
|
||||
componentProps:{
|
||||
<#if po.dictText??>
|
||||
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>
|
||||
dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}",
|
||||
<#elseif po.dictText?split(',')[1]??>
|
||||
pidField:"${po.dictText?split(',')[1]}",
|
||||
<#elseif po.dictText?split(',')[3]??>
|
||||
hasChildField:"${po.dictText?split(',')[3]}",
|
||||
</#if>
|
||||
</#if>
|
||||
pidValue:"${po.dictField}",
|
||||
}
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
<#include "/common/utils.ftl">
|
||||
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||
dynamicRules: ({model,schema}) => {
|
||||
<#if po.fieldName != 'id'>
|
||||
<#assign fieldValidType = po.fieldValidType!''>
|
||||
return [
|
||||
<#-- 非空校验 -->
|
||||
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||
{ required: true, message: '请输入${po.filedComment}!'},
|
||||
<#elseif fieldValidType!=''>
|
||||
{ required: false},
|
||||
</#if>
|
||||
<#-- 唯一校验 -->
|
||||
<#if fieldValidType == 'only'>
|
||||
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||
<#-- 6到16位数字 -->
|
||||
<#elseif fieldValidType == 'n6-16'>
|
||||
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||
<#-- 6到16位任意字符 -->
|
||||
<#elseif fieldValidType == '*6-16'>
|
||||
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||
<#-- 6到18位字符串 -->
|
||||
<#elseif fieldValidType == 's6-18'>
|
||||
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||
<#-- 网址 -->
|
||||
<#elseif fieldValidType == 'url'>
|
||||
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||
<#-- 电子邮件 -->
|
||||
<#elseif fieldValidType == 'e'>
|
||||
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||
<#-- 手机号码 -->
|
||||
<#elseif fieldValidType == 'm'>
|
||||
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||
<#-- 邮政编码 -->
|
||||
<#elseif fieldValidType == 'p'>
|
||||
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||
<#-- 字母 -->
|
||||
<#elseif fieldValidType == 's'>
|
||||
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||
<#-- 数字 -->
|
||||
<#elseif fieldValidType == 'n'>
|
||||
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||
<#-- 整数 -->
|
||||
<#elseif fieldValidType == 'z'>
|
||||
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||
<#-- 金额 -->
|
||||
<#elseif fieldValidType == 'money'>
|
||||
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||
<#-- 正则校验 -->
|
||||
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||
<#-- 无校验 -->
|
||||
<#else>
|
||||
<#t>
|
||||
</#if>
|
||||
];
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
<#if po.readonly=='Y'>
|
||||
dynamicDisabled:true
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
//子表单数据
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
|
||||
<#assign form_cat_tree = false>
|
||||
<#assign form_cat_back = "">
|
||||
<#assign bpm_flag=false>
|
||||
<#list sub.colums as po><#rt/>
|
||||
<#if po.fieldDbName=='bpm_status'>
|
||||
<#assign bpm_flag=true>
|
||||
</#if>
|
||||
<#if po.isShow =='Y'>
|
||||
<#assign form_field_dictCode="">
|
||||
<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
|
||||
<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
|
||||
<#elseif po.dictField?default("")?trim?length gt 1>
|
||||
<#assign form_field_dictCode="${po.dictField}">
|
||||
</#if>
|
||||
{
|
||||
label: '${po.filedComment}',
|
||||
field: '${po.fieldName}',
|
||||
<#if po.classType =='date'>
|
||||
component: 'DatePicker',
|
||||
<#elseif po.fieldType =='datetime'>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime:true
|
||||
},
|
||||
<#elseif po.fieldType =='time'>
|
||||
component: 'TimePicker',
|
||||
<#elseif po.classType =='popup'>
|
||||
component: 'JPopup',
|
||||
componentProps: ({ formActionType }) => {
|
||||
const {setFieldsValue} = formActionType;
|
||||
return{
|
||||
setFieldsValue:setFieldsValue,
|
||||
code:"${po.dictTable}",
|
||||
fieldConfig:${po.dictField},
|
||||
multi:${po.extendParams.popupMulti?c},
|
||||
}
|
||||
}
|
||||
<#elseif po.classType =='sel_depart'>
|
||||
component: 'JSelectDept',
|
||||
<#elseif po.classType =='switch'>
|
||||
component: 'JSwitch',
|
||||
componentProps:{
|
||||
<#if po.dictField != 'is_open'>
|
||||
options:${po.dictField}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType =='pca'>
|
||||
component: 'JAreaLinkage',
|
||||
<#elseif po.classType =='markdown'>
|
||||
component: 'JMarkdownEditor',//注意string转换问题
|
||||
<#elseif po.classType =='password'>
|
||||
component: 'InputPassword',
|
||||
<#elseif po.classType =='sel_user'>
|
||||
component: 'JSelectUserByDept',
|
||||
componentProps:{
|
||||
labelKey:'realname',
|
||||
}
|
||||
<#elseif po.classType =='textarea'>
|
||||
component: 'InputTextArea',//TODO 注意string转换问题
|
||||
<#elseif po.classType=='list' || po.classType=='radio'>
|
||||
component: 'JDictSelectTag',
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='list_multi' || po.classType=='checkbox'>
|
||||
component: 'JMultiSelectTag',//TODO 暂无该组件
|
||||
componentProps:{
|
||||
dictCode:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='sel_search'>
|
||||
component: 'JSearchSelect',
|
||||
componentProps:{
|
||||
dict:"${form_field_dictCode}"
|
||||
}
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
<#assign form_cat_tree = true>
|
||||
component: 'JCategorySelect',
|
||||
componentProps:{
|
||||
pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题
|
||||
}
|
||||
<#if po.dictText?default("")?trim?length gt 1>
|
||||
<#assign form_cat_back = "${po.dictText}">
|
||||
</#if>
|
||||
<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||
component: 'InputNumber',
|
||||
<#elseif po.classType=='file'>
|
||||
component: 'JUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
maxCount:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='image'>
|
||||
component: 'JImageUpload',
|
||||
componentProps:{
|
||||
<#if po.uploadnum??>
|
||||
fileMax:${po.uploadnum}
|
||||
</#if>
|
||||
}
|
||||
<#elseif po.classType=='umeditor'>
|
||||
component: 'JCodeEditor', //TODO String后缀暂未添加
|
||||
<#elseif po.classType == 'sel_tree'>
|
||||
component: 'JTreeSelect',
|
||||
componentProps:{
|
||||
<#if po.dictText??>
|
||||
<#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>
|
||||
dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}",
|
||||
<#elseif po.dictText?split(',')[1]??>
|
||||
pidField:"${po.dictText?split(',')[1]}",
|
||||
<#elseif po.dictText?split(',')[3]??>
|
||||
hasChildField:"${po.dictText?split(',')[3]}",
|
||||
</#if>
|
||||
</#if>
|
||||
pidValue:"${po.dictField}",
|
||||
}
|
||||
<#else>
|
||||
component: 'Input',
|
||||
</#if>
|
||||
<#include "/common/utils.ftl">
|
||||
<#if po.isShow == 'Y' && poHasCheck(po)>
|
||||
dynamicRules: ({model,schema}) => {
|
||||
<#if po.fieldName != 'id'>
|
||||
<#assign fieldValidType = po.fieldValidType!''>
|
||||
return [
|
||||
<#-- 非空校验 -->
|
||||
<#if po.nullable == 'N' || fieldValidType == '*'>
|
||||
{ required: true, message: '请输入${po.filedComment}!'},
|
||||
<#elseif fieldValidType!=''>
|
||||
{ required: false},
|
||||
</#if>
|
||||
<#-- 唯一校验 -->
|
||||
<#if fieldValidType == 'only'>
|
||||
{...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]},
|
||||
<#-- 6到16位数字 -->
|
||||
<#elseif fieldValidType == 'n6-16'>
|
||||
{ pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'},
|
||||
<#-- 6到16位任意字符 -->
|
||||
<#elseif fieldValidType == '*6-16'>
|
||||
{ pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'},
|
||||
<#-- 6到18位字符串 -->
|
||||
<#elseif fieldValidType == 's6-18'>
|
||||
{ pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'},
|
||||
<#-- 网址 -->
|
||||
<#elseif fieldValidType == 'url'>
|
||||
{ pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'},
|
||||
<#-- 电子邮件 -->
|
||||
<#elseif fieldValidType == 'e'>
|
||||
{ pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'},
|
||||
<#-- 手机号码 -->
|
||||
<#elseif fieldValidType == 'm'>
|
||||
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'},
|
||||
<#-- 邮政编码 -->
|
||||
<#elseif fieldValidType == 'p'>
|
||||
{ pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'},
|
||||
<#-- 字母 -->
|
||||
<#elseif fieldValidType == 's'>
|
||||
{ pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'},
|
||||
<#-- 数字 -->
|
||||
<#elseif fieldValidType == 'n'>
|
||||
{ pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'},
|
||||
<#-- 整数 -->
|
||||
<#elseif fieldValidType == 'z'>
|
||||
{ pattern: /^-?\d+$/, message: '请输入整数!'},
|
||||
<#-- 金额 -->
|
||||
<#elseif fieldValidType == 'money'>
|
||||
{ pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'},
|
||||
<#-- 正则校验 -->
|
||||
<#elseif fieldValidType != '' && fieldValidType != '*'>
|
||||
{ pattern: '${fieldValidType}', message: '不符合校验规则!'},
|
||||
<#-- 无校验 -->
|
||||
<#else>
|
||||
<#t>
|
||||
</#if>
|
||||
];
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
<#if po.readonly=='Y'>
|
||||
dynamicDisabled:true
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
];
|
||||
</#if>
|
||||
</#list>
|
||||
//子表表格配置
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
|
||||
<#assign popupBackFields = "">
|
||||
|
||||
<#-- 循环子表的列 开始 -->
|
||||
<#list sub.colums as col><#rt/>
|
||||
<#if col.isShow =='Y'>
|
||||
<#if col.filedComment !='外键' >
|
||||
{
|
||||
title: '${col.filedComment}',
|
||||
key: '${autoStringSuffixForModel(col)}',
|
||||
<#if col.classType =='date'>
|
||||
type: JVxeTypes.date,
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='datetime'>
|
||||
type: JVxeTypes.datetime,
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='textarea'>
|
||||
type: JVxeTypes.textarea,
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif "int,decimal,double,"?contains(col.classType)>
|
||||
type: JVxeTypes.inputNumber,
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='list' || col.classType =='radio'>
|
||||
type: JVxeTypes.select,
|
||||
options:[],
|
||||
<#if col.dictTable?default("")?trim?length gt 1>
|
||||
dictCode:"${col.dictTable},${col.dictText},${col.dictField}",
|
||||
<#else>
|
||||
dictCode:"${col.dictField}",
|
||||
</#if>
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='list_multi' || col.classType =='checkbox'>
|
||||
type: JVxeTypes.selectMultiple,
|
||||
options:[],
|
||||
<#if col.dictTable?default("")?trim?length gt 1>
|
||||
dictCode:"${col.dictTable},${col.dictText},${col.dictField}",
|
||||
<#else>
|
||||
dictCode:"${col.dictField}",
|
||||
</#if>
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='sel_search'>
|
||||
type: JVxeTypes.selectSearch,
|
||||
<#if col.dictTable?default("")?trim?length gt 1>
|
||||
dictCode:"${col.dictTable},${col.dictText},${col.dictField}",
|
||||
<#else>
|
||||
dictCode:"${col.dictField}",
|
||||
</#if>
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='image'>
|
||||
type: JVxeTypes.image,
|
||||
token:true,
|
||||
responseName:"message",
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#if col.uploadnum??>
|
||||
number: ${col.uploadnum},
|
||||
</#if>
|
||||
<#elseif col.classType =='file'>
|
||||
type: JVxeTypes.file,
|
||||
token:true,
|
||||
responseName:"message",
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#if col.uploadnum??>
|
||||
number: ${col.uploadnum},
|
||||
</#if>
|
||||
<#elseif col.classType =='switch'>
|
||||
type: JVxeTypes.checkbox,
|
||||
<#if col.dictField == 'is_open'>
|
||||
customValue: ['Y', 'N'],
|
||||
<#else>
|
||||
customValue: ${col.dictField},
|
||||
</#if>
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#elseif col.classType =='popup'>
|
||||
<#if popupBackFields?length gt 0>
|
||||
<#assign popupBackFields = "${popupBackFields}"+","+"${col.dictText}">
|
||||
<#else>
|
||||
<#assign popupBackFields = "${col.dictText}">
|
||||
</#if>
|
||||
type: JVxeTypes.popup,
|
||||
popupCode:"${col.dictTable}",
|
||||
field:"${col.dictField}",
|
||||
orgFields:"${col.dictField}",
|
||||
destFields:"${Format.underlineToHump(col.dictText)}",
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
<#else>
|
||||
type: JVxeTypes.input,
|
||||
<#if col.readonly=='Y'>
|
||||
disabled:true,
|
||||
</#if>
|
||||
</#if>
|
||||
<#if col.classType =='list_multi' || col.classType =='checkbox'>
|
||||
width:"250px",
|
||||
<#else>
|
||||
width:"200px",
|
||||
</#if>
|
||||
<#if col.classType =='file'>
|
||||
placeholder: '请选择文件',
|
||||
<#else>
|
||||
placeholder: '请输入${'$'}{title}',
|
||||
</#if>
|
||||
<#if col.defaultVal??>
|
||||
<#if col.fieldDbType=="BigDecimal" || col.fieldDbType=="double" || col.fieldDbType=="int">
|
||||
defaultValue:${col.defaultVal},
|
||||
<#else>
|
||||
defaultValue:"${col.defaultVal}",
|
||||
</#if>
|
||||
<#else>
|
||||
defaultValue:'',
|
||||
</#if>
|
||||
<#-- 子表的校验 -->
|
||||
<#assign subFieldValidType = col.fieldValidType!''>
|
||||
<#-- 非空校验 -->
|
||||
<#if col.nullable == 'N' || subFieldValidType == '*'>
|
||||
validateRules: [{ required: true, message: '${'$'}{title}不能为空' }],
|
||||
<#-- 其他情况下,只要有值就被认为是正则校验 -->
|
||||
<#elseif subFieldValidType?length gt 0>
|
||||
<#assign subMessage = '格式不正确'>
|
||||
<#if subFieldValidType == 'only' >
|
||||
<#assign subMessage = '不能重复'>
|
||||
</#if>
|
||||
validateRules: [{ pattern: "${subFieldValidType}", message: "${'$'}{title}${subMessage}" }],
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
<#-- 循环子表的列 结束 -->
|
||||
]
|
||||
</#if>
|
||||
</#list>
|
||||
@ -1,179 +0,0 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm" ref="formRef"/>
|
||||
<!-- 子表单区域 -->
|
||||
<a-tabs v-model:activeKey="activeKey" @change="handleChangeTabs">
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
<a-tab-pane tab="${sub.ftlDescription}" :key="refKeys[${sub_index}]" :forceRender="true">
|
||||
<${sub.entityName}Form ref="${sub.entityName?uncap_first}Form"></${sub.entityName}Form>
|
||||
</a-tab-pane>
|
||||
|
||||
<#else>
|
||||
<a-tab-pane tab="${sub.ftlDescription}" :key="refKeys[${sub_index}]" :forceRender="true">
|
||||
<JVxeTable
|
||||
keep-source
|
||||
resizable
|
||||
:ref="refKeys[${sub_index}]"
|
||||
:loading="${sub.entityName?uncap_first}Table.loading"
|
||||
:columns="${sub.entityName?uncap_first}Table.columns"
|
||||
:dataSource="${sub.entityName?uncap_first}Table.dataSource"
|
||||
:maxHeight="300"
|
||||
:rowNumber="true"
|
||||
:rowSelection="true"
|
||||
:toolbar="true"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
</#if>
|
||||
</#list>
|
||||
</a-tabs>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed, unref,reactive} from 'vue';
|
||||
import {BasicModal, useModalInner} from '/@/components/Modal';
|
||||
import {BasicForm, useForm} from '/@/components/Form/index';
|
||||
import { JVxeTable } from '/@/components/jeecg/JVxeTable'
|
||||
import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods.ts'
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
import ${sub.entityName}Form from './${sub.entityName}Form.vue'
|
||||
</#if>
|
||||
</#list>
|
||||
import {formSchema<#list subTables as sub><#if sub.foreignRelationType =='0'>,${sub.entityName?uncap_first}Columns</#if></#list>} from '../${entityName?uncap_first}.data';
|
||||
import {saveOrUpdate<#list subTables as sub>,${sub.entityName?uncap_first}List</#list>} from '../${entityName?uncap_first}.api';
|
||||
import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils'
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register','success']);
|
||||
const isUpdate = ref(true);
|
||||
const refKeys = ref([<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>]);
|
||||
<#assign hasOne2Many = false>
|
||||
<#assign hasOne2One = false>
|
||||
const activeKey = ref('${subTables[0].entityName?uncap_first}');
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
<#assign hasOne2Many = true>
|
||||
const ${sub.entityName?uncap_first} = ref();
|
||||
</#if>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
<#assign hasOne2One = true>
|
||||
const ${sub.entityName?uncap_first}Form = ref();
|
||||
</#if>
|
||||
</#list>
|
||||
const tableRefs = {<#list subTables as sub><#if sub.foreignRelationType =='0'>${sub.entityName?uncap_first}, <#assign hasOne2Many = true></#if></#list>};
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
const ${sub.entityName?uncap_first}Table = reactive({
|
||||
loading: false,
|
||||
dataSource: [],
|
||||
columns:${sub.entityName?uncap_first}Columns
|
||||
})
|
||||
</#if>
|
||||
</#list>
|
||||
//表单配置
|
||||
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await reset();
|
||||
setModalProps({confirmLoading: false,showCancelBtn:data?.showFooter,showOkBtn:data?.showFooter});
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
${sub.entityName?uncap_first}Form.value.initFormData(${sub.entityName?uncap_first}List,data?.record?.id)
|
||||
</#if>
|
||||
</#list>
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
requestSubTableData(${sub.entityName?uncap_first}List, {id:data?.record?.id}, ${sub.entityName?uncap_first}Table)
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
setProps({ disabled: !data?.showFooter })
|
||||
});
|
||||
//方法配置
|
||||
const [handleChangeTabs,handleSubmit,requestSubTableData,formRef] = useJvxeMethod(requestAddOrEdit,classifyIntoFormData,tableRefs,activeKey,refKeys<#if hasOne2One==true>,validateSubForm</#if>);
|
||||
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
|
||||
async function reset(){
|
||||
await resetFields();
|
||||
activeKey.value = ref('${subTables[0].entityName?uncap_first}');
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
${sub.entityName?uncap_first}Table.dataSource = [];
|
||||
</#if>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
${sub.entityName?uncap_first}Form.value.resetFields();
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
function classifyIntoFormData(allValues) {
|
||||
let main = Object.assign({}, allValues.formValue)
|
||||
return {
|
||||
...main, // 展开
|
||||
<#assign subManyIndex = 0>
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='0'>
|
||||
${sub.entityName?uncap_first}List: allValues.tablesValue[${subManyIndex}].tableData,
|
||||
<#assign subManyIndex = subManyIndex+1>
|
||||
<#else>
|
||||
${sub.entityName?uncap_first}List: ${sub.entityName?uncap_first}Form.value.getFormData(),
|
||||
</#if>
|
||||
</#list>
|
||||
}
|
||||
}
|
||||
<#if hasOne2One==true>
|
||||
//校验所有一对一子表表单
|
||||
function validateSubForm(allValues){
|
||||
return new Promise((resolve,reject)=>{
|
||||
Promise.all([
|
||||
<#list subTables as sub><#rt/>
|
||||
<#if sub.foreignRelationType =='1'>
|
||||
${sub.entityName?uncap_first}Form.value.validateForm(${sub_index}),
|
||||
</#if>
|
||||
</#list>
|
||||
]).then(() => {
|
||||
resolve(allValues)
|
||||
}).catch(e => {
|
||||
if (e.error === VALIDATE_FAILED) {
|
||||
// 如果有未通过表单验证的子表,就自动跳转到它所在的tab
|
||||
activeKey.value = e.index == null ? unref(activeKey) : refKeys.value[e.index]
|
||||
} else {
|
||||
console.error(e)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
</#if>
|
||||
//表单提交事件
|
||||
async function requestAddOrEdit(values) {
|
||||
try {
|
||||
setModalProps({confirmLoading: true});
|
||||
//提交表单
|
||||
await saveOrUpdate(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({confirmLoading: false});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
||||
@ -1,64 +0,0 @@
|
||||
<#list subTables as sub>
|
||||
<#if sub.foreignRelationType=='1'>
|
||||
#segment#${sub.entityName}Form.vue
|
||||
<template>
|
||||
<BasicForm @register="registerForm"/>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue';
|
||||
import {BasicForm, useForm} from '/@/components/Form/index';
|
||||
import {${sub.entityName?uncap_first}FormSchema} from '../${entityName?uncap_first}.data';
|
||||
import {defHttp} from '/@/utils/http/axios';
|
||||
import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils'
|
||||
|
||||
export default defineComponent({
|
||||
name:"${sub.entityName}Form",
|
||||
components: {BasicForm},
|
||||
emits:['register'],
|
||||
setup(_,{emit}) {
|
||||
const [registerForm, {resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: ${sub.entityName?uncap_first}FormSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
/**
|
||||
*初始化加载数据
|
||||
*/
|
||||
function initFormData(url,id){
|
||||
if(id){
|
||||
defHttp.get({url,params:{id}},{isTransformResponse:false}).then(res=>{
|
||||
res.success && setFieldsValue({...res.result[0]});
|
||||
})
|
||||
}
|
||||
}
|
||||
/**
|
||||
*获取表单数据
|
||||
*/
|
||||
function getFormData(){
|
||||
return [getFieldsValue()];
|
||||
}
|
||||
/**
|
||||
*表单校验
|
||||
*/
|
||||
function validateForm(index){
|
||||
return new Promise((resolve, reject) => {
|
||||
// 验证子表表单
|
||||
validate().then(()=>{
|
||||
return resolve()
|
||||
}).catch(()=> {
|
||||
return reject({ error: VALIDATE_FAILED ,index})
|
||||
})
|
||||
})
|
||||
}
|
||||
return {
|
||||
registerForm,
|
||||
resetFields,
|
||||
initFormData,
|
||||
getFormData,
|
||||
validateForm
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</#if>
|
||||
</#list>
|
||||
@ -42,7 +42,7 @@
|
||||
<java-jwt.version>3.11.0</java-jwt.version>
|
||||
<shiro-redis.version>3.1.0</shiro-redis.version>
|
||||
<codegenerate.version>1.3.7</codegenerate.version>
|
||||
<autopoi-web.version>1.3.5</autopoi-web.version>
|
||||
<autopoi-web.version>1.3.6</autopoi-web.version>
|
||||
<minio.version>8.0.3</minio.version>
|
||||
<justauth-spring-boot-starter.version>1.3.4</justauth-spring-boot-starter.version>
|
||||
<dom4j.version>1.6.1</dom4j.version>
|
||||
|
||||
Reference in New Issue
Block a user