前端和后端源码,合并到一个git仓库中,方便用户下载,避免前后端不匹配的问题

This commit is contained in:
JEECG
2024-06-23 10:39:52 +08:00
parent bb918b742e
commit 0325e34dcb
1439 changed files with 171106 additions and 0 deletions

View File

@ -0,0 +1,102 @@
/** [表格主题样式一] 表格强制列不换行 */
.j-table-force-nowrap {
td,
th {
white-space: nowrap;
}
.ant-table-selection-column {
padding: 12px 22px !important;
}
/** 列自适应,弊端会导致列宽失效 */
&.ant-table-wrapper .ant-table-content {
overflow-x: auto;
}
}
/** 查询区域通用样式*/
.table-page-search-wrapper {
.ant-form-inline {
.ant-form-item {
display: flex;
margin-bottom: 24px;
margin-right: 0;
.ant-form-item-control-wrapper {
flex: 1 1;
display: inline-block;
vertical-align: middle;
}
> .ant-form-item-label {
line-height: 32px;
padding-right: 8px;
width: auto;
}
.ant-form-item-control {
height: 32px;
line-height: 32px;
}
}
}
.table-page-search-submitButtons {
display: block;
margin-bottom: 24px;
white-space: nowrap;
}
}
/*列表上方操作按钮区域*/
.ant-card-body .table-operator {
margin-bottom: 8px;
}
/** Button按钮间距 */
.table-operator .ant-btn {
margin: 0 8px 8px 0;
}
.table-operator .ant-btn-group .ant-btn {
margin: 0;
}
.table-operator .ant-btn-group .ant-btn:last-child {
margin: 0 8px 8px 0;
}
/*列表td的padding设置 可以控制列表大小*/
.ant-table-tbody .ant-table-row td {
padding-top: 15px;
padding-bottom: 15px;
}
/*列表页面弹出modal*/
.ant-modal-cust-warp {
height: 100%;
}
/*弹出modal Y轴滚动条*/
.ant-modal-cust-warp .ant-modal-body {
height: calc(100% - 110px) !important;
overflow-y: auto;
}
/*弹出modal 先有content后有body 故滚动条控制在body上*/
.ant-modal-cust-warp .ant-modal-content {
height: 90% !important;
overflow-y: hidden;
}
/*列表中有图片的加这个样式 参考用户管理*/
.anty-img-wrap {
height: 25px;
position: relative;
}
.antd-more a {
color: #000000;
}

View File

@ -0,0 +1,419 @@
<template>
<a-card :bordered="false">
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" preIcon="ant-design:plus">新增</a-button>
<!-- <a-button type="primary" preIcon="ant-design:download" @click="handleExportExcel('单表原生列表')">导出</a-button>-->
<!-- <j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="handleImportExcel">导入</j-upload-button>-->
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
<a-menu-item key="1" @click="batchDel">
<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>
</div>
<!-- table区域-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px">
<i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a
>项
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
</div>
<a-table
ref="table"
size="middle"
:scroll="{ x: true }"
bordered
rowKey="id"
class="j-table-force-nowrap"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
@change="handleTableChange"
>
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex==='tupian'">
<span v-if="!text" style="font-size: 12px; font-style: italic">无图片</span>
<img v-else :src="getImgView(text)" :preview="record.id" alt="" class="anty-img-wrap" />
</template>
<template v-else-if="column.dataIndex==='wenjian'">
<span v-if="!text" style="font-size: 12px; font-style: italic">无文件</span>
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download" size="small" @click="downloadFile(text)"> 下载 </a-button>
</template>
<template v-else-if="column.dataIndex==='action'">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical" />
<a-dropdown>
<!-- update-begin--author:liaozhiyang---date:20230803---for【QQYUN-5838】图标改小保持一致 -->
<a class="ant-dropdown-link">更多 <Icon icon="mdi-light:chevron-down"></Icon></a>
<!-- update-end--author:liaozhiyang---date:20230803---for【QQYUN-5838】图标改小保持一致 -->
<template #overlay>
<a-menu class="antd-more">
<a-menu-item>
<a @click="handleDetail(record)">详情</a>
</a-menu-item>
<a-menu-item>
<Popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
</Popconfirm>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</template>
<!-- <template v-else-if="column.dataIndex==='htmlSlot'">
<div v-html="text"></div>
</template>
<template v-else-if="column.dataIndex==='pcaSlot'">
<div>{{ getAreaTextByCode(text) }}</div>
</template> -->
</template>
</a-table>
</div>
<OneNativeModal ref="oneProtogenesisModal" @ok="handleSuccess"></OneNativeModal>
</a-card>
</template>
<script lang="ts" setup>
import '../less/TableExpand.less';
import { onMounted, ref, reactive } from 'vue';
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
import { filterMultiDictText } from '/@/utils/dict/JDictSelectUtil.js';
import { getAreaTextByCode } from '/@/components/Form/src/utils/Area';
import OneNativeModal from './components/OneNativeModal.vue';
import { Modal, Popconfirm } from 'ant-design-vue';
import { JSelectUserByDept, JDictSelectTag, JSelectDept, JSearchSelect } from '/@/components/Form';
import Icon from '/@/components/Icon/index';
import { filterObj, getFileAccessHttpUrl } from '/@/utils/common/compUtils';
import { loadCategoryData } from '/@/api/common/api';
import { getToken } from '/@/utils/auth';
import { useMethods } from '/@/hooks/system/useMethods';
import { downloadFile } from '/@/utils/common/renderUtils';
import { initDictOptions } from '/@/utils/dict';
const { handleExportXls, handleImportXls } = useMethods();
const modalVisible = ref<boolean>(false);
const queryParam = ref<any>({});
const loading = ref<boolean>(false);
const dictOptions = ref<any>([]);
const oneProtogenesisModal = ref();
const tokenHeader = { 'X-Access-Token': getToken() };
//表头
const columns = ref<any>([
{
title: '文本',
align: 'center',
dataIndex: 'name',
},
{
title: '字典下拉',
align: 'center',
dataIndex: 'xiala',
customRender: ({ text }) => (text ? filterMultiDictText(dictOptions.value['xiala'], text) : ''),
},
{
title: '字典单选',
align: 'center',
dataIndex: 'danxuan',
customRender: ({ text }) => (text ? filterMultiDictText(dictOptions.value['danxuan'], text) : ''),
},
{
title: '字典多选',
align: 'center',
dataIndex: 'duoxuan',
customRender: ({ text }) => (text ? filterMultiDictText(dictOptions.value['duoxuan'], text) : ''),
},
{
title: '开关',
align: 'center',
dataIndex: 'kaiguan',
customRender: ({ text }) => (text ? filterMultiDictText(dictOptions.value['kaiguan'], text) : ''),
},
{
title: '日期',
align: 'center',
dataIndex: 'riqi',
customRender: function ({ text }) {
return !text ? '' : text.length > 10 ? text.substr(0, 10) : text;
},
},
{
title: '年月日时分秒',
align: 'center',
dataIndex: 'nyrsfm',
},
{
title: '时间',
align: 'center',
dataIndex: 'shijian',
},
{
title: '文件',
align: 'center',
dataIndex: 'wenjian',
},
{
title: '图片',
align: 'center',
dataIndex: 'tupian',
},
{
title: '操作',
dataIndex: 'action',
align: 'center',
fixed: 'right',
width: 147,
},
]);
const Api = reactive<any>({
list: '/test/jeecgDemo/oneNative/list',
delete: '/test/jeecgDemo/oneNative/delete',
exportXls: '/test/jeecgDemo/oneNative/exportXls',
importExcel: 'test/jeecgDemo/oneNative/importExcel',
});
const dataSource = ref<any>([]);
const toggleSearchStatus = ref<boolean>(false);
const ipagination = ref<any>({
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + ' 共' + total + '条';
},
showQuickJumper: true,
showSizeChanger: true,
total: 0,
});
const selectedRowKeys = ref<any>([]);
const selectionRows = ref<any>([]);
const iSorter = ref<any>({ column: 'createTime', order: 'desc' });
const iFilters = ref<any>({});
const { createMessage } = useMessage();
/**
* 复选框选中事件
* @param rowKeys
* @param rows
*/
function onSelectChange(rowKeys, rows) {
selectedRowKeys.value = rowKeys;
selectionRows.value = rows;
}
/**
* 表格改变事件
*/
function handleTableChange({ pagination, filters, sorter }) {
ipagination.value = pagination;
iSorter.value = sorter;
iFilters.value = { ...filters };
}
/**
* 新增
*/
function handleAdd() {
oneProtogenesisModal.value.disableSubmit = false;
oneProtogenesisModal.value.add();
}
/**
* 清除选中行
*/
function onClearSelected() {
selectedRowKeys.value = [];
selectionRows.value = [];
}
/**
* 批量删除
*/
function batchDel() {
Modal.confirm({
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
defHttp.delete({ url: Api.delete, data: { ids: selectedRowKeys.value } }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
},
});
}
/**
* 导出excel
*/
function handleExportExcel(title) {
let paramsForm = getQueryParams();
if (selectedRowKeys.value && selectedRowKeys.value.length > 0) {
paramsForm['selections'] = selectedRowKeys.join(',');
}
handleExportXls(title, Api.exportXls, filterObj(paramsForm));
}
/**
* 导入excel
*/
function handleImportExcel(file) {
handleImportXls(file, Api.importExcel, '').then(() => {
handleSuccess();
});
}
/**
* 获取查询参数
*/
function getQueryParams() {
let params = Object.assign(queryParam.value, iSorter.value, iFilters.value);
params.field = getQueryField();
params.pageNo = ipagination.value.current;
params.pageSize = ipagination.value.pageSize;
return filterObj(params);
}
/**
* 字段权限控制
*/
function getQueryField() {
let str = 'id,';
columns.value.forEach(function (value) {
str += ',' + value.dataIndex;
});
return str;
}
/**
* 初始化数据
*/
function loadData(arg?) {
if (arg === 1) {
ipagination.value.current = 1;
}
loading.value = true;
let params = getQueryParams();
defHttp
.get({ url: Api.list, params }, { isTransformResponse: false })
.then((res) => {
if (res.success) {
dataSource.value = res.result.records;
if (res.result && res.result.total) {
ipagination.value.total = res.result.total;
} else {
ipagination.value.total = 0;
}
} else {
createMessage.warning(res.message);
}
})
.finally(() => {
loading.value = false;
});
}
//查询
function searchQuery() {
loadData(1);
selectedRowKeys.value = [];
selectionRows.value = [];
}
/**
* 查询区域展开关闭
*/
function handleToggleSearch() {
toggleSearchStatus.value = !toggleSearchStatus.value;
}
/**
* 重置按钮
*/
function searchReset() {
queryParam.value = {};
loadData(1);
}
/**
* 获取预览图片
*/
function getImgView(text) {
if (text && text.indexOf(',') > 0) {
text = text.substring(0, text.indexOf(','));
}
return getFileAccessHttpUrl(text);
}
/**
* 编辑
* @param record
*/
function handleEdit(record) {
oneProtogenesisModal.value.disableSubmit = false;
oneProtogenesisModal.value.edit(record);
}
/**
* 详情
* @param record
*/
function handleDetail(record) {
oneProtogenesisModal.value.disableSubmit = true;
oneProtogenesisModal.value.edit(record);
}
/**
* 删除
* @param id
*/
function handleDelete(id) {
defHttp.delete({ url: Api.delete, data: { ids: id } }, { joinParamsToUrl: true }).then((res) => {
handleSuccess();
});
}
/**
* 初始化字典选项
*/
async function initDictConfig() {
dictOptions.value['flzds'] = await loadCategoryData({ code: 'B01' });
dictOptions.value['xiala'] = await initDictOptions('sex');
dictOptions.value['danxuan'] = await initDictOptions('sex');
dictOptions.value['duoxuan'] = await initDictOptions('urgent_level');
}
/**
* 保存表单后回调事件
*/
function handleSuccess() {
selectedRowKeys.value = [];
selectionRows.value = [];
loadData(1);
}
onMounted(() => {
dictOptions.value['kaiguan'] = [
{ text: '是', value: '1' },
{ text: '否', value: '2' },
];
//初始加载页面
loadData();
//初始化字典选项
initDictConfig();
});
</script>

View File

@ -0,0 +1,455 @@
<template>
<a-spin :spinning="confirmLoading">
<a-form class="antd-modal-form" ref="formRef" :model="formState" :rules="validatorRules">
<a-row>
<a-col :span="24">
<a-form-item label="文本" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.name">
<a-input v-model:value="formState.name" placeholder="请输入文本"></a-input>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="密码" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.miMa">
<a-input-password v-model:value="formState.miMa" placeholder="请输入密码" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="字典下拉" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.xiala">
<JDictSelectTag type="select" v-model:value="formState.xiala" dictCode="sex" placeholder="请选择字典下拉" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="字典单选" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.danxuan">
<JDictSelectTag type="radio" v-model:value="formState.danxuan" dictCode="sex" placeholder="请选择字典单选" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="字典多选" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.duoxuan">
<JCheckbox v-model:value="formState.duoxuan" dictCode="urgent_level" placeholder="请选择字典多选" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="开关" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.kaiguan">
<JSwitch v-model:value="formState.kaiguan" :options="['1', '0']"></JSwitch>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="日期" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.riqi">
<a-date-picker placeholder="请选择日期" format="YYYY-MM-DD" valueFormat="YYYY-MM-DD" v-model:value="formState.riqi" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="年月日时分秒" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.nyrsfm">
<a-date-picker show-time v-model:value="formState.nyrsfm" style="width: 100%" valueFormat="YYYY-MM-DD HH:mm:ss" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="时间" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.shijian">
<TimePicker placeholder="请选择时间" v-model:value="formState.shijian" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="文件" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.wenjian">
<JUpload v-model:value="formState.wenjian"></JUpload>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="图片" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.tupian">
<JImageUpload :fileMax="2" v-model:value="formState.tupian"></JImageUpload>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="多行文本框" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.dhwb">
<a-textarea v-model:value="formState.dhwb" rows="4" placeholder="请输入多行文本框" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="字典表下拉搜索框" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.xlss">
<JSearchSelect v-model:value="formState.xlss" dict="sys_user,realname,username" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="popup弹窗" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.popup">
<JPopup
v-model:value="formState.popup"
:fieldConfig="[
{ source: 'name', target: 'popup' },
{ source: 'id', target: 'popback' },
]"
code="report_user"
:multi="true"
:setFieldsValue="setFieldsValue"
/>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="popback" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.popback">
<a-input v-model:value="formState.popback" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="分类字典树" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.flzds">
<JCategorySelect
@change="(value) => handleFormChange('flzds', value)"
v-model:value="formState.flzds"
pcode="B02"
placeholder="请选择分类字典树"
/>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="部门选择" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.bmxz">
<JSelectDept v-model:value="formState.bmxz" :multi="true" type="array" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="用户选择" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.yhxz">
<JSelectUserByDept v-model:value="formState.yhxz" :multi="true" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="富文本" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.fwb">
<JEditor v-model:value="formState.fwb" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="markdown" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.markdownString">
<JMarkdownEditor v-model:value="formState.markdownString"></JMarkdownEditor>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="省市区JAreaSelect" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.shq">
<JAreaSelect v-model:value="formState.shq" placeholder="请输入省市区" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="省市区JAreaLinkage" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.jssq">
<JAreaLinkage v-model:value="formState.jssq" placeholder="请输入省市区" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="JInputPop" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.ldzje">
<JInputPop
v-model:value="formState.ldzje"
placeholder="请输入JInputPop"
@change="(value) => handleFormChange('ldzje', value)"
></JInputPop>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="JSelectInput" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.ldzjs">
<JSelectInput
v-model:value="formState.ldzjs"
placeholder="请选择JSelectInput"
:options="ldzjsOptions"
@change="(value) => handleFormChange('ldzjs', value)"
></JSelectInput>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="下拉多选" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.zddtjxl">
<JSelectMultiple v-model:value="formState.zddtjxl" placeholder="请选择下拉多选" dictCode="sex"></JSelectMultiple>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="用户" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.yongHu">
<JSelectUser v-model:value="formState.yongHu" placeholder="请选择用户"></JSelectUser>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="职务" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.zhiWu">
<JSelectPosition
v-model:value="formState.zhiWu"
placeholder="请选择职务"
@change="(value) => handleFormChange('zhiWu', value)"
></JSelectPosition>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="角色" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.jueSe">
<JSelectRole v-model:value="formState.jueSe" placeholder="请选择角色" @change="(value) => handleFormChange('jueSe', value)"></JSelectRole>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="自定义树" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.zdys">
<JTreeSelect
ref="treeSelect"
placeholder="请选择自定义树"
v-model:value="formState.zdys"
dict="sys_category,name,id"
pidValue="0"
loadTriggleChange
>
</JTreeSelect>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="数值" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.yuanjia">
<a-input-number v-model:value="formState.yuanjia" placeholder="请输入double类型" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="输入2到10位的字母" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.ywzz">
<a-input v-model:value="formState.ywzz" placeholder="请输入2到10位的字母"></a-input>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="JTreeDict" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.zdbxl">
<JTreeDict
v-model:value="formState.zdbxl"
placeholder="请选择JTreeDict"
@change="(value) => handleFormChange('zdbxl', value)"
></JTreeDict>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="JCodeEditor" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.zdmrz">
<JCodeEditor
v-model:value="formState.zdmrz"
placeholder="请输入JCodeEditor"
@change="(value) => handleFormChange('zdmrz', value)"
></JCodeEditor>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="参数" :labelCol="labelCol" :wrapperCol="wrapperCol" v-bind="validateInfos.jsonParam">
<JAddInput v-model:value="formState.jsonParam" placeholder="参数"></JAddInput>
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-spin>
</template>
<script lang="ts" setup>
import { ref, reactive, nextTick } from 'vue';
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
import dayjs from 'dayjs';
import { TimePicker, Form } from 'ant-design-vue';
import JCheckbox from '/@/components/Form/src/jeecg/components/JCheckbox.vue';
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
import JSwitch from '/@/components/Form/src/jeecg/components/JSwitch.vue';
import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue';
import JImageUpload from '/@/components/Form/src/jeecg/components/JImageUpload.vue';
import JSearchSelect from '/@/components/Form/src/jeecg/components/JSearchSelect.vue';
import JPopup from '/@/components/Form/src/jeecg/components/JPopup.vue';
import JCategorySelect from '/@/components/Form/src/jeecg/components/JCategorySelect.vue';
import JSelectUserByDept from '/@/components/Form/src/jeecg/components/JSelectUserByDept.vue';
import JEditor from '/@/components/Form/src/jeecg/components/JEditor.vue';
import JMarkdownEditor from '/@/components/Form/src/jeecg/components/JMarkdownEditor.vue';
import JTreeSelect from '/@/components/Form/src/jeecg/components/JTreeSelect.vue';
import JInputPop from '/@/components/Form/src/jeecg/components/JInputPop.vue';
import JSelectInput from '/@/components/Form/src/jeecg/components/JSelectInput.vue';
import JSelectPosition from '/@/components/Form/src/jeecg/components/JSelectPosition.vue';
import JSelectMultiple from '/@/components/Form/src/jeecg/components/JSelectMultiple.vue';
import JInput from '/@/components/Form/src/jeecg/components/JInput.vue';
import JSelectDept from '/@/components/Form/src/jeecg/components/JSelectDept.vue';
import JSelectUser from '/@/components/Form/src/jeecg/components/JSelectUser.vue';
import JAreaSelect from '/@/components/Form/src/jeecg/components/JAreaSelect.vue';
import JAreaLinkage from '/@/components/Form/src/jeecg/components/JAreaLinkage.vue';
import JSelectRole from '/@/components/Form/src/jeecg/components/JSelectRole.vue';
import JTreeDict from '/@/components/Form/src/jeecg/components/JTreeDict.vue';
import JCodeEditor from '/@/components/Form/src/jeecg/components/JCodeEditor.vue';
import JAddInput from '/@/components/Form/src/jeecg/components/JAddInput.vue';
import { getValueType } from '/@/utils';
const emit = defineEmits(['register', 'ok']);
//update-begin---author:wangshuai ---date:20220616 for报表示例验证修改--------------
const formState = reactive<Record<string, any>>({
name: '',
miMa: '',
ywzz: '',
xiala: '',
danxuan: '',
duoxuan: '',
riqi: '',
shijian: '',
wenjian: '',
tupian: '',
dhwb: '',
xlss: '',
popup: '',
flzds: '',
yhxz: '',
fwb: '',
shq: '',
ldzje: '',
ldzjs: '',
zddtjxl: '',
yongHu: '',
zhiWu: '',
jueSe: '',
zdys: '',
jssq: '',
zdbxl: '',
zdmrz: '',
jsonParam: '',
bmxz: '',
yuanjia: '',
nyrsfm: '',
});
//update-end---author:wangshuai ---date:20220616 for报表示例验证修改--------------
const { createMessage } = useMessage();
const formRef = ref();
const useForm = Form.useForm;
const url = reactive<any>({
duplicateCheck: '/sys/duplicate/check',
add: '/test/jeecgDemo/oneNative/add',
edit: '/test/jeecgDemo/oneNative/edit',
});
const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 5 } });
const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 16 } });
const confirmLoading = ref<boolean>(false);
//表单验证
const validatorRules = {
name: [{ required: false, message: '请输入文本!' }],
miMa: [{ required: false, message: '请输入密码!' }],
ywzz: [{ required: false }, { pattern: '^[a-z|A-Z]{2,10}$', message: '不符合校验规则!' }],
xiala: [{ required: false, message: '请选择下拉组件!' }],
danxuan: [{ required: false, message: '请选择单选组件!' }],
duoxuan: [{ required: false, message: '请选择多选组件!' }],
riqi: [{ required: false, message: '请选择日期!' }],
shijian: [{ required: false, message: '请选择时间!' }],
wenjian: [{ required: false, message: '请上传文件!' }],
tupian: [{ required: false, message: '请上传图片!' }],
dhwb: [{ required: false, message: '请填写多行文本!' }],
xlss: [{ required: false, message: '请选择字典下拉搜索!' }],
popup: [{ required: false, message: '请选择popup弹窗!' }],
flzds: [{ required: false, message: '请选择分类字典树!' }],
yhxz: [{ required: false, message: '请选择用户!' }],
fwb: [{ required: false, message: '请填写富文本!' }],
shq: [{ required: false, message: '请选择省市级!' }],
ldzje: [{ required: false, message: '请输入JInputPop!' }],
ldzjs: [{ required: false, message: '请选择下拉输入框!' }],
zddtjxl: [{ required: false, message: '请选择多选输入框!' }],
yongHu: [{ required: false, message: '请选择用户!' }],
zhiWu: [{ required: false, message: '请选择职务!' }],
jueSe: [{ required: false, message: '请选择角色!' }],
zdys: [{ required: false, message: '请选择自定义树!' }],
jssq: [{ required: false, message: '请选择三级联动!' }],
zdbxl: [{ required: false, message: '请选择JTreeDict!' }],
zdmrz: [{ required: false, message: '请输入JCodeEditor!' }],
jsonParam: [{ required: false, message: '请输入参数!' }],
bmxz: [{ required: false, message: '请选择部门!' }],
yuanjia: [{ required: false, message: '请输入数值!' }],
nyrsfm: [{ required: false, message: '请选择年月日时分秒!' }],
};
//update-begin---author:wangshuai ---date:20220616 for报表示例验证修改------------
const { resetFields, validate, validateInfos } = useForm(formState, validatorRules, { immediate: false });
//update-end---author:wangshuai ---date:20220616 for报表示例验证修改------------
const ldzjsOptions = ref([
{ label: '男', value: '1' },
{ label: '女', value: '2' },
]);
/**
* 新增
*/
function add() {
edit({});
}
/**
* 编辑
*/
function edit(record) {
nextTick(() => {
resetFields();
//赋值
Object.assign(formState, record);
});
}
/**
* 提交数据
*/
async function submitForm() {
// 触发表单验证
//update-begin---author:wangshuai ---date:20220616 for报表示例验证修改------------
await validate();
confirmLoading.value = true;
let httpurl = '';
let method = '';
//时间格式化
let model = formState;
if (!model.id) {
httpurl += url.add;
method = 'post';
} else {
httpurl += url.edit;
method = 'put';
}
//循环数据如果是数组
for (let data in formState) {
//如果该数据是数组并且是字符串类型
if (formState[data] instanceof Array) {
let valueType = getValueType(formRef.value.getProps, data);
//如果是字符串类型的需要变成以逗号分割的字符串
if (valueType === 'string') {
formState[data] = formState[data].join(',');
}
}
}
defHttp
.request(
{
url: httpurl,
params: model,
method: method,
},
{ isTransformResponse: false }
)
.then((res) => {
if (res.success) {
createMessage.success(res.message);
emit('ok');
} else {
createMessage.warning(res.message);
}
})
.finally(() => {
confirmLoading.value = false;
});
//update-end---author:wangshuai ---date:20220616 for报表示例验证修改--------------
}
/**
* popup成功回调事件
*/
function popupHandleSuccess(values) {
Object.assign(formState, values);
}
/**
* popup组件值改变事件
*/
function setFieldsValue(map) {
Object.keys(map).map((key) => {
formState[key] = map[key];
});
}
/**
* 值改变事件触发
* @param key
* @param value
*/
function handleFormChange(key, value) {
formState[key] = value;
}
defineExpose({
add,
edit,
submitForm,
});
</script>
<style lang="less" scoped>
.antd-modal-form {
padding: 24px 24px 24px 24px;
}
</style>

View File

@ -0,0 +1,65 @@
<template>
<BasicModal
:title="title"
:width="width"
:visible="visible"
:height="600"
@ok="handleOk"
:okButtonProps="{ class: { 'jee-hidden': disableSubmit } }"
@cancel="handleCancel"
cancelText="关闭"
>
<OneNativeForm ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></OneNativeForm>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, nextTick } from 'vue';
import OneNativeForm from './OneNativeForm.vue';
import { BasicModal } from '/@/components/Modal';
const title = ref<string>('');
const width = ref<number>(800);
const visible = ref<boolean>(false);
const disableSubmit = ref<boolean>(false);
const realForm = ref();
const emit = defineEmits(['register', 'ok']);
function add() {
title.value = '新增';
visible.value = true;
nextTick(() => {
realForm.value.add();
});
}
function edit(record) {
title.value = disableSubmit.value ? '详情' : '编辑';
visible.value = true;
nextTick(() => {
realForm.value.edit(record);
});
}
function handleOk() {
realForm.value.submitForm();
}
function submitCallback() {
handleCancel();
emit('ok');
}
function handleCancel() {
visible.value = false;
}
defineExpose({
add,
edit,
disableSubmit,
});
</script>
<style lang="less" scoped>
</style>