前端和后端源码,合并到一个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,187 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit" width="70%">
<a-form ref="formRef" :model="orderMainModel" :label-col="labelCol" :wrapper-col="wrapperCol" :rules="validatorRules">
<a-row class="form-row" :gutter="16">
<a-col :lg="8">
<a-form-item label="订单号" name="orderCode">
<a-input v-model:value="orderMainModel.orderCode" placeholder="请输入订单号" />
</a-form-item>
</a-col>
<a-col :lg="8">
<a-form-item label="订单类型">
<a-select placeholder="请选择订单类型" v-model:value="orderMainModel.ctype">
<a-select-option value="1">国内订单</a-select-option>
<a-select-option value="2">国际订单</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :lg="8">
<a-form-item label="订单日期">
<a-date-picker showTime valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="orderMainModel.orderDate" />
</a-form-item>
</a-col>
</a-row>
<a-row class="form-row" :gutter="16">
<a-col :lg="8">
<a-form-item label="订单金额">
<a-input v-model:value="orderMainModel.orderMoney" placeholder="请输入订单金额" />
</a-form-item>
</a-col>
<a-col :lg="8">
<a-form-item label="订单备注">
<a-input v-model:value="orderMainModel.content" placeholder="请输入订单备注" />
</a-form-item>
</a-col>
</a-row>
<a-tabs defaultActiveKey="1">
<a-tab-pane tab="客户信息" key="1">
<a-row class="form-row" :gutter="16">
<a-col :lg="8">
<a-form-item label="客户姓名">
<a-input v-model:value="orderMainModel.jeecgOrderCustomerList.name" placeholder="请输入客户姓名" />
</a-form-item>
</a-col>
<a-col :lg="8">
<a-form-item label="手机号">
<a-input v-model:value="orderMainModel.jeecgOrderCustomerList.telphone" placeholder="请输入手机号" />
</a-form-item>
</a-col>
</a-row>
</a-tab-pane>
<a-tab-pane tab="机票信息" key="2" forceRender>
<a-row class="form-row" :gutter="16">
<a-col :lg="8">
<a-form-item label="航班号">
<a-input v-model:value="orderMainModel.jeecgOrderTicketList.ticketCode" placeholder="请输入航班号" />
</a-form-item>
</a-col>
<a-col :lg="8">
<a-form-item label="起飞时间">
<a-date-picker showTime valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="orderMainModel.jeecgOrderTicketList.tickectDate" />
</a-form-item>
</a-col>
</a-row>
</a-tab-pane>
</a-tabs>
</a-form>
</BasicModal>
</template>
<script lang="ts">
import { defineComponent, ref, reactive, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface';
import { saveOrUpdate } from './jvxetable/jvxetable.api';
import { orderCustomerList, orderTicketList } from './api';
export default defineComponent({
name: 'OneToOneModal',
components: { BasicModal },
emits: ['success', 'register'],
setup(props, { emit }) {
const isUpdate = ref(true);
const rowId = ref('');
const formRef = ref();
const labelCol = reactive({
xs: { span: 24 },
sm: { span: 5 },
});
const wrapperCol = reactive({
xs: { span: 24 },
sm: { span: 16 },
});
const validatorRules = {
orderCode: [{ required: true, message: '订单号不能为空', trigger: 'blur' }],
};
const orderMainModel = reactive({
id: null,
orderCode: '',
orderMoney: '',
ctype: '',
content: '',
jeecgOrderCustomerList: {
name: '',
telphone: '',
},
jeecgOrderTicketList: {
ticketCode: '',
tickectDate: '',
},
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
setModalProps({ confirmLoading: false });
reset();
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
rowId.value = data.record.id;
Object.assign(orderMainModel, data.record);
let params = { id: orderMainModel.id };
const customerList = await orderCustomerList(params);
//update-begin---author:wangshuai ---date:20220629 for[VUEN-1484]在一对多示例页面编辑一行青岛订单A0001客户信息无法填入------------
orderMainModel.jeecgOrderCustomerList = customerList[0]?customerList[0]:{};
//update-end---author:wangshuai ---date:20220629 for[VUEN-1484]在一对多示例页面编辑一行青岛订单A0001客户信息无法填入--------------
const ticketList = await orderTicketList(params);
//update-begin---author:wangshuai ---date:20220629 for[VUEN-1484]在一对多示例页面编辑一行青岛订单A0001客户信息无法填入------------
orderMainModel.jeecgOrderTicketList = ticketList[0]?ticketList[0]:{};
//update-end---author:wangshuai ---date:20220629 for[VUEN-1484]在一对多示例页面编辑一行青岛订单A0001客户信息无法填入--------------
}
});
const getTitle = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
function reset() {
orderMainModel.id = null;
orderMainModel.orderCode = '';
orderMainModel.orderMoney = '';
orderMainModel.orderDate = null;
orderMainModel.ctype = '';
orderMainModel.content = '';
orderMainModel.jeecgOrderCustomerList = {};
orderMainModel.jeecgOrderTicketList = {};
}
async function handleSubmit() {
formRef.value
.validate()
.then(async () => {
try {
console.log('formData', JSON.stringify(orderMainModel));
setModalProps({ confirmLoading: true });
orderMainModel.jeecgOrderCustomerList =
Object.keys(orderMainModel.jeecgOrderCustomerList).length > 0 ? [orderMainModel.jeecgOrderCustomerList] : [];
orderMainModel.jeecgOrderTicketList =
Object.keys(orderMainModel.jeecgOrderTicketList).length > 0 ? [orderMainModel.jeecgOrderTicketList] : [];
await saveOrUpdate(orderMainModel, unref(isUpdate));
closeModal();
emit('success');
} finally {
setModalProps({ confirmLoading: false });
}
})
.catch((error: ValidateErrorEntity<any>) => {
console.log('error', error);
});
}
return { formRef, validatorRules, orderMainModel, registerModal, getTitle, labelCol, wrapperCol, handleSubmit };
},
});
</script>
<style scoped>
.ant-btn {
padding: 0 10px;
margin-left: 3px;
}
.ant-form-item-control {
line-height: 0px;
}
/** 主表单行间距 */
.ant-form .ant-form-item {
margin-bottom: 10px;
}
/** Tab页面行间距 */
.ant-tabs-content .ant-form-item {
margin-bottom: 0px;
}
</style>

View File

@ -0,0 +1,190 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit" width="70%">
<a-form ref="formRef" :model="orderMainModel" :label-col="labelCol" :wrapper-col="wrapperCol" :rules="validatorRules">
<a-row class="form-row" :gutter="16">
<a-col :lg="8">
<a-form-item label="订单号" name="orderCode">
<a-input v-model:value="orderMainModel.orderCode" placeholder="请输入订单号" />
</a-form-item>
</a-col>
<a-col :lg="8">
<a-form-item label="订单类型">
<a-select placeholder="请选择订单类型" v-model:value="orderMainModel.ctype">
<a-select-option value="1">国内订单</a-select-option>
<a-select-option value="2">国际订单</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :lg="8">
<a-form-item label="订单日期">
<a-date-picker showTime valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="orderMainModel.orderDate" />
</a-form-item>
</a-col>
</a-row>
<a-row class="form-row" :gutter="16">
<a-col :lg="8">
<a-form-item label="订单金额">
<a-input v-model:value="orderMainModel.orderMoney" placeholder="请输入订单金额" />
</a-form-item>
</a-col>
<a-col :lg="8">
<a-form-item label="订单备注">
<a-input v-model:value="orderMainModel.content" placeholder="请输入订单备注" />
</a-form-item>
</a-col>
</a-row>
<a-tabs defaultActiveKey="1">
<a-tab-pane tab="客户信息" key="1">
<vxe-toolbar>
<template #buttons>
<vxe-button icon="fa fa-plus" @click="insertEvent()">新增</vxe-button>
<vxe-button @click="$refs.xTable.removeCheckboxRow()">删除选中</vxe-button>
</template>
</vxe-toolbar>
<vxe-table
border
show-overflow
keep-source
ref="xTable"
max-height="400"
:data="orderMainModel.jeecgOrderCustomerList"
:edit-config="{ trigger: 'click', mode: 'row', icon: 'fa fa-pencil', showStatus: true }"
>
<vxe-column type="checkbox" width="60" align="center"></vxe-column>
<vxe-column type="seq" width="60" align="center"></vxe-column>
<vxe-column field="name" title="客户名" sortable :edit-render="{ name: 'input', defaultValue: '' }"></vxe-column>
<vxe-column field="sex" title="性别" :edit-render="{ name: '$select', options: sexList }"></vxe-column>
<vxe-column field="idcard" title="身份证" sortable :edit-render="{ name: 'input', defaultValue: '' }"></vxe-column>
<vxe-column field="telphone" title="手机" sortable :edit-render="{ name: 'input', defaultValue: '' }"></vxe-column>
</vxe-table>
</a-tab-pane>
<a-tab-pane tab="机票信息" key="2" forceRender> </a-tab-pane>
</a-tabs>
</a-form>
</BasicModal>
</template>
<script lang="ts">
import { defineComponent, ref, reactive, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface';
import { VxeTableInstance } from 'vxe-table';
export default defineComponent({
name: 'VexTableModal',
components: { BasicModal },
emits: ['success', 'register'],
setup(props, { emit }) {
const isUpdate = ref(true);
const xTable = ref({} as VxeTableInstance);
const rowId = ref('');
const formRef = ref();
const labelCol = reactive({
xs: { span: 24 },
sm: { span: 5 },
});
const wrapperCol = reactive({
xs: { span: 24 },
sm: { span: 16 },
});
const sexList = ref([
{ label: '', value: '' },
{ label: '男', value: '1' },
{ label: '女', value: '2' },
]);
const validatorRules = {
orderCode: [{ required: true, message: '订单号不能为空', trigger: 'blur' }],
};
const orderMainModel = reactive({
id: null,
orderCode: '',
orderMoney: '',
ctype: '',
content: '',
jeecgOrderCustomerList: [],
jeecgOrderTicketList: [],
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
orderMainModel.orderCode = '';
setModalProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
rowId.value = data.record.id;
orderMainModel.orderCode = data.record.orderCode;
}
});
const tableData = ref([]);
const getTitle = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
//动态添加行
async function insertEvent(row: any) {
const $table = xTable.value;
const record = {
name: '',
sex: '1',
idcard: '',
telphone: '',
};
const { row: newRow } = await $table.insertAt(record, row);
await $table.setActiveCell(newRow, 'sex');
}
async function handleSubmit() {
formRef.value
.validate()
.then(() => {
try {
const $table = xTable.value;
const { fullData } = $table.getTableData();
orderMainModel.jeecgOrderCustomerList = fullData;
console.log('formData', JSON.stringify(orderMainModel));
setModalProps({ confirmLoading: true });
closeModal();
emit('success', { isUpdate: unref(isUpdate), values: { id: rowId.value } });
} finally {
setModalProps({ confirmLoading: false });
}
})
.catch((error: ValidateErrorEntity<any>) => {
console.log('error', error);
});
}
return {
xTable,
tableData,
sexList,
formRef,
validatorRules,
orderMainModel,
registerModal,
getTitle,
labelCol,
wrapperCol,
insertEvent,
handleSubmit,
};
},
});
</script>
<style scoped>
.ant-btn {
padding: 0 10px;
margin-left: 3px;
}
.ant-form-item-control {
line-height: 0px;
}
/** 主表单行间距 */
.ant-form .ant-form-item {
margin-bottom: 10px;
}
/** Tab页面行间距 */
.ant-tabs-content .ant-form-item {
margin-bottom: 0px;
}
</style>

View File

@ -0,0 +1,32 @@
import { defHttp } from '/@/utils/http/axios';
enum Api {
list = '/test/jeecgOrderMain/list',
delete = '/test/jeecgOrderMain/delete',
orderCustomerList = '/test/jeecgOrderMain/queryOrderCustomerListByMainId',
orderTicketList = '/test/jeecgOrderMain/queryOrderTicketListByMainId',
}
/**
* 列表接口
* @param params
*/
export const list = (params) => defHttp.get({ url: Api.list, params });
/**
* 子表单信息
* @param params
*/
export const orderTicketList = (params) => defHttp.get({ url: Api.orderTicketList, params });
/**
* 子表单信息
* @param params
*/
export const orderCustomerList = (params) => defHttp.get({ url: Api.orderCustomerList, params });
/**
* 删除用户
*/
export const deleteOne = (params, handleSuccess) => {
return defHttp.delete({ url: Api.delete, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
};

View File

@ -0,0 +1,154 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
import { usePermission } from '/@/hooks/web/usePermission';
import { JVxeColumn, JVxeTypes } from '/@/components/jeecg/JVxeTable/types';
const { isDisabledAuth, hasPermission, initBpmFormData} = usePermission();
export const columns: BasicColumn[] = [
{
title: '订单号',
dataIndex: 'orderCode',
width: 260,
},
{
title: '订单类型',
dataIndex: 'ctype',
slots: { customRender: 'ctype' },
},
{
title: '订单日期',
dataIndex: 'orderDate',
width: 300,
},
{
title: '订单金额',
width: 200,
dataIndex: 'orderMoney',
},
{
title: '订单备注',
width: 200,
dataIndex: 'content',
},
{
title: '流程状态',
width: 200,
dataIndex: 'bpmStatus',
customRender: ({ text }) => {
if (!text || text == '1') {
return '待提交';
} else if (text == '2') {
return '处理中';
} else if (text == '2') {
return '已完成';
} else {
return text;
}
},
},
];
export function getBpmFormSchema(formData) {
//注入流程节点表单权限
initBpmFormData(formData);
const formSchema2: FormSchema[] = [
{
label: '订单号',
field: 'orderCode',
component: 'Input',
show: ({ values }) => {
return hasPermission('order:orderCode');
},
},
{
label: '订单类型',
field: 'ctype',
component: 'Select',
componentProps: {
options: [
{ label: '国内订单', value: '1', key: '1' },
{ label: '国际订单', value: '2', key: '2' },
],
},
},
{
label: '订单日期',
field: 'orderDate',
component: 'DatePicker',
componentProps: {
valueFormat: 'YYYY-MM-DD HH:mm:ss',
style: {
width: '100%',
},
},
},
{
label: '订单金额',
field: 'orderMoney',
component: 'Input',
},
{
label: '订单备注',
field: 'content',
component: 'Input',
},
];
return formSchema2;
}
export function getOrderCustomerFormSchema(formData) {
//注入流程节点表单权限
initBpmFormData(formData);
const formSchema2: FormSchema[] = [
{
label: '客户名',
field: 'name',
component: 'Input',
dynamicDisabled: ({ values }) => {
return isDisabledAuth('order:name');
},
},
{
label: '性别',
field: 'sex',
component: 'Select',
componentProps: {
options: [
{ label: '男', value: '1', key: '1' },
{ label: '女', value: '2', key: '2' },
],
},
},
{
label: '身份证号',
field: 'idcard',
component: 'Input',
},
{
label: '手机号',
field: 'telphone',
component: 'Input',
},
];
return formSchema2;
}
export const jeecgOrderTicketColumns: JVxeColumn[] = [
{
title: '航班号',
key: 'ticketCode',
width: 180,
type: JVxeTypes.input,
placeholder: '请输入${title}',
defaultValue: '',
},
{
title: '航班时间',
key: 'tickectDate',
width: 180,
type: JVxeTypes.date,
placeholder: '请选择${title}',
defaultValue: '',
},
];

View File

@ -0,0 +1,38 @@
<template>
<BasicDrawer v-bind="$attrs" @register="registerDrawer" showFooter :title="getTitle" width="500px" @ok="handleSubmit"> </BasicDrawer>
</template>
<script lang="ts">
import { defineComponent, ref, computed, unref } from 'vue';
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
export default defineComponent({
name: 'tableDrawer',
components: { BasicDrawer },
emits: ['success', 'register'],
setup(_, { emit }) {
const isUpdate = ref(true);
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
setDrawerProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
});
const getTitle = computed(() => (!unref(isUpdate) ? '新增角色' : '编辑角色'));
async function handleSubmit() {
try {
setDrawerProps({ confirmLoading: true });
closeDrawer();
emit('success');
} finally {
setDrawerProps({ confirmLoading: false });
}
}
return {
registerDrawer,
getTitle,
handleSubmit,
};
},
});
</script>

View File

@ -0,0 +1,67 @@
<template>
<BasicForm @register="registerForm"></BasicForm>
</template>
<script>
import { BasicForm, useForm } from '/@/components/Form/index';
import { computed, defineComponent, toRaw } from 'vue';
import { defHttp } from '/@/utils/http/axios';
import { propTypes } from '/@/utils/propTypes';
import { getOrderCustomerFormSchema } from '../data';
export default defineComponent({
name: 'JeecgOrderCustomerForm',
components: {
BasicForm,
},
props: {
formData: propTypes.object.def({}),
},
setup(props) {
const [registerForm, { setFieldsValue, setProps, getFieldsValue, updateSchema }] = useForm({
labelWidth: 150,
schemas: getOrderCustomerFormSchema(props.formData),
showActionButtonGroup: false,
baseColProps: { span: 8 },
});
const formDisabled = computed(() => {
if (props.formData.disabled === false) {
return false;
}
return true;
});
let orderCustomerFormData = {};
const queryByIdUrl = '/test/jeecgOrderMain/queryOrderCustomerListByMainId';
async function initFormData(mainId) {
let params = { id: mainId };
const data = await defHttp.get({ url: queryByIdUrl, params });
console.log('data', data);
if (data && data.length > 0) {
let temp = data[0];
orderCustomerFormData = { ...temp };
//设置表单的值
await setFieldsValue(orderCustomerFormData);
await setProps({ disabled: formDisabled.value });
}
}
async function getFormData() {
let subFormData = { ...orderCustomerFormData };
if (Object.keys(subFormData).length > 0) {
return subFormData;
}
return false;
}
return {
registerForm,
formDisabled,
initFormData,
getFormData,
};
},
});
</script>
<style scoped></style>

View File

@ -0,0 +1,155 @@
<template>
<div class="jeecg-flow-demo">
<BasicForm @register="registerForm"></BasicForm>
<a-tabs v-model:activeKey="activeKey" @change="handleChangeTabs">
<a-tab-pane tab="客户信息" key="jeecgOrderCustomerForm" :forceRender="true">
<JeecgOrderCustomerForm ref="jeecgOrderCustomerFormRef" :formData="formData"></JeecgOrderCustomerForm>
</a-tab-pane>
<a-tab-pane tab="机票信息" key="jeecgOrderTicket" :forceRender="true">
<JVxeTable v-if="ok" ref="jeecgOrderTicketRef" stripe rowSelection keepSource :maxHeight="300" :loading="table2.loading" :columns="table2.columns" :dataSource="table2.dataSource"> </JVxeTable>
</a-tab-pane>
</a-tabs>
</div>
</template>
<script>
import { BasicForm, useForm } from '/@/components/Form/index';
import { computed, defineComponent, ref, reactive } from 'vue';
import { defHttp } from '/@/utils/http/axios';
import { propTypes } from '/@/utils/propTypes';
import { getBpmFormSchema, jeecgOrderTicketColumns } from '../data';
import JeecgOrderCustomerForm from './JeecgOrderCustomerForm.vue';
export default defineComponent({
name: 'JeecgOrderMainForm',
components: {
BasicForm,
JeecgOrderCustomerForm,
},
props: {
formData: propTypes.object.def({}),
formBpm: propTypes.bool.def(true),
},
setup(props) {
const [registerForm, { setFieldsValue, setProps, getFieldsValue, updateSchema }] = useForm({
labelWidth: 150,
schemas: getBpmFormSchema(props.formData),
showActionButtonGroup: false,
baseColProps: { span: 8 },
});
const formDisabled = computed(() => {
if (props.formData.disabled === false) {
return false;
}
return true;
});
const jeecgOrderCustomerFormRef = ref();
const jeecgOrderTicketRef = ref();
const ok = ref(false);
let formData = {};
const queryByIdUrl = '/test/jeecgOrderMain/queryById';
async function initFormData() {
console.log('props.formData', props.formData);
let params = { id: props.formData.dataId };
const data = await defHttp.get({ url: queryByIdUrl, params });
console.log('data', data);
formData = { ...data };
//设置表单的值
await setFieldsValue(formData);
await setProps({ disabled: formDisabled.value });
await jeecgOrderCustomerFormRef.value.initFormData(props.formData.dataId);
await loadOrderTicketData(props.formData.dataId);
ok.value = true;
}
async function submitForm() {
let data = getFieldsValue();
let params = Object.assign({}, formData, data);
console.log('表单数据', params);
await saveOrUpdate(params, true);
}
initFormData();
const activeKey = ref('jeecgOrderCustomerForm');
function handleChangeTabs() {}
// 机票信息
const table2 = reactive({
loading: false,
dataSource: [],
columns: filterSubTableColnmns(jeecgOrderTicketColumns, 'order:'),
});
async function loadOrderTicketData(mainId) {
const queryByIdUrl = '/test/jeecgOrderMain/queryOrderTicketListByMainId';
let params = { id: mainId };
table2.dataSource = [];
const data = await defHttp.get({ url: queryByIdUrl, params });
if (data && data.length > 0) {
table2.dataSource = [...data];
}
}
//新增权限处理方法
function filterSubTableColnmns(columns, pre) {
let authList = props.formData.permissionList;
//注意:如果子表配置显示反向 这里不处理其逻辑 即隐藏无法在流程表单中实现,请使用全局表单权限实现
let temp = columns.filter((item) => {
let oneAuth = authList.find((auth) => {
return auth.action === pre + item.key;
});
if (!oneAuth) {
return true;
}
//代码严谨处理,防止一个授权标识,配置多次
if (oneAuth instanceof Array) {
oneAuth = oneAuth[0];
}
//禁用逻辑
if (oneAuth.type == '2' && !oneAuth.isAuth) {
item['disabled'] = true;
return true;
}
//隐藏逻辑逻辑
if (oneAuth.type == '1' && !oneAuth.isAuth) {
return false;
}
return true;
});
return temp;
}
return {
registerForm,
formDisabled,
submitForm,
jeecgOrderCustomerFormRef,
activeKey,
handleChangeTabs,
table2,
jeecgOrderTicketRef,
ok,
};
},
});
</script>
<style lang="less">
/*.jeecg-flow-demo{
.vxe-header--row{
.vxe-header--column .vxe-cell{
width: 180px !important;
}
.vxe-header--column:first-child .vxe-cell{
width: 40px !important;
}
}
}*/
</style>

View File

@ -0,0 +1,144 @@
<template>
<div class="p-4">
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<template #tableTitle>
<a-dropdown>
<template #overlay>
<a-menu @click="handleCreate">
<a-menu-item :key="1">一对一示例</a-menu-item>
<a-menu-item :key="2">一对多示例</a-menu-item>
<a-menu-item :key="3">一对多(JVexTable)</a-menu-item>
</a-menu>
</template>
<a-button type="primary">新增 <DownOutlined /></a-button>
</a-dropdown>
</template>
<template #ctype="{ text }">
{{ text === '1' ? '国内订单' : text === '2' ? '国际订单' : text }}
</template>
<template #action="{ record }">
<TableAction :actions="getAction(record)" :dropDownActions="getDropDownActions(record)" />
</template>
</BasicTable>
<!-- <TableDrawer @register="registerDrawer" @success="handleSuccess" />-->
<TableModal @register="registerModal" @success="handleSuccess" />
<JVxeTableModal @register="registerVexTableModal" @success="handleSuccess"></JVxeTableModal>
<OneToOneModal @register="registerOneToOneModal" @success="handleSuccess"></OneToOneModal>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import TableDrawer from './drawer.vue';
import TableModal from './modal.vue';
import VexTableModal from './VexTableModal.vue';
import JVxeTableModal from './jvxetable/JVxeTableModal.vue';
import OneToOneModal from './OneToOneModal.vue';
import { DownOutlined } from '@ant-design/icons-vue';
import { useListPage } from '/@/hooks/system/useListPage';
import { useModal } from '/@/components/Modal';
import { columns } from './data';
import { list, deleteOne } from './api';
import { defHttp } from '/@/utils/http/axios';
const [registerModal, { openModal }] = useModal();
const [registerOneToOneModal, { openModal: openOneToOneModal }] = useModal();
const [registerVexTableModal, { openModal: openVexTableModal }] = useModal();
//定义表格行操作
const getAction = (record) => {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
];
};
const getDropDownActions = (record) => {
let arr = [
{
label: '删除',
popConfirm: {
title: '是否删除?',
confirm: handleDelete.bind(null, record),
},
},
];
return arr;
};
// 列表页面公共参数、方法
const { tableContext } = useListPage({
tableProps: {
api: list,
columns: columns,
useSearchForm: false,
actionColumn: {
width: 160,
title: '操作',
dataIndex: 'action',
slots: { customRender: 'action' },
},
},
});
//注册table数据
const [registerTable, { reload }, { rowSelection }] = tableContext;
//新增类型
//update-begin---author:wangshuai ---date:20220720 for[VUEN-1661]一对多示例,编辑的时候,有时候是一对一,有时候是一对多,默认一对多------------
const addType = ref(3);
//update-end---author:wangshuai ---date:20220720 for[VUEN-1661]一对多示例,编辑的时候,有时候是一对一,有时候是一对多,默认一对多--------------
//添加事件
function handleCreate(e) {
addType.value = e.key;
let type = addType.value;
if (type == 1) {
openOneToOneModal(true, {
isUpdate: false,
});
}
if (type == 2) {
openModal(true, {
isUpdate: false,
});
}
if (type == 3) {
openVexTableModal(true, {
isUpdate: false,
});
}
}
//编辑事件
function handleEdit(record: Recordable) {
let type = addType.value;
if (type == 1) {
openOneToOneModal(true, {
record,
isUpdate: true,
});
}
if (type == 2) {
openModal(true, {
record,
isUpdate: true,
});
}
if (type == 3) {
openVexTableModal(true, {
record,
isUpdate: true,
});
}
}
async function handleDelete(record: Recordable) {
await deleteOne({ id: record.id }, reload);
}
function handleSuccess() {
reload();
}
</script>

View File

@ -0,0 +1,39 @@
<template>
<div style="padding: 5px">
<vxe-toolbar>
<template #buttons>
<vxe-button @click="allAlign = 'left'">新增</vxe-button>
</template>
</vxe-toolbar>
<vxe-table :align="allAlign" :data="tableData1">
<vxe-table-column type="seq" width="60"></vxe-table-column>
<vxe-table-column field="name" title="Name"></vxe-table-column>
<vxe-table-column field="sex" title="Sex"></vxe-table-column>
<vxe-table-column field="age" title="Age"></vxe-table-column>
</vxe-table>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { CollapseContainer } from '/@/components/Container/index';
export default defineComponent({
components: { CollapseContainer },
setup() {
const allAlign = ref(null);
const tableData1 = ref([
{ id: 10001, name: 'Test1', role: 'Develop', sex: 'Man', age: 28, address: 'vxe-table 从入门到放弃' },
{ id: 10002, name: 'Test2', role: 'Test', sex: 'Women', age: 22, address: 'Guangzhou' },
{ id: 10003, name: 'Test3', role: 'PM', sex: 'Man', age: 32, address: 'Shanghai' },
{ id: 10004, name: 'Test4', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' },
]);
return {
allAlign,
tableData1,
};
},
});
</script>
<style lang="css" scoped></style>

View File

@ -0,0 +1,205 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit" width="70%" @fullScreen="handleFullScreen">
<a-form ref="formRef" :model="orderMainModel" :label-col="labelCol" :wrapper-col="wrapperCol" :rules="validatorRules">
<!-- update-begin--author:liaozhiyang---date:20230803---forQQYUN-5866鼠标放上去有左右滚动条 -->
<div style="overflow-x: hidden">
<a-row class="form-row" :gutter="16">
<a-col :lg="8">
<a-form-item label="订单号" name="orderCode">
<a-input v-model:value="orderMainModel.orderCode" placeholder="请输入订单号" />
</a-form-item>
</a-col>
<a-col :lg="8">
<a-form-item label="订单类型" name="ctype">
<a-select placeholder="请选择订单类型" v-model:value="orderMainModel.ctype">
<a-select-option value="1">国内订单</a-select-option>
<a-select-option value="2">国际订单</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :lg="8">
<a-form-item label="订单日期" name="orderDate">
<a-date-picker showTime valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="orderMainModel.orderDate" />
</a-form-item>
</a-col>
</a-row>
<a-row class="form-row" :gutter="16">
<a-col :lg="8">
<a-form-item label="订单金额" name="orderMoney">
<a-input v-model:value="orderMainModel.orderMoney" placeholder="请输入订单金额" />
</a-form-item>
</a-col>
<a-col :lg="8">
<a-form-item label="订单备注" name="content">
<a-input v-model:value="orderMainModel.content" placeholder="请输入订单备注" />
</a-form-item>
</a-col>
</a-row>
</div>
<!-- update-end--author:liaozhiyang---date:20230803---for【QQYUN-5866】鼠标放上去有左右滚动条 -->
<!-- 子表单区域 -->
<a-tabs v-model:activeKey="activeKey" @change="handleChangeTabs">
<a-tab-pane tab="客户信息" key="tableRef1">
<JVxeTable
ref="tableRef1"
stripe
toolbar
rowNumber
rowSelection
resizable
keepSource
:height="tableH"
:checkbox-config="{ range: true }"
:loading="table1.loading"
:columns="table1.columns"
:dataSource="table1.dataSource"
></JVxeTable>
</a-tab-pane>
<a-tab-pane tab="机票信息" key="tableRef2" forceRender>
<JVxeTable
ref="tableRef2"
stripe
toolbar
rowNumber
rowSelection
resizable
keepSource
:height="tableH"
:checkbox-config="{ range: true }"
:loading="table2.loading"
:columns="table2.columns"
:dataSource="table2.dataSource"
></JVxeTable>
</a-tab-pane>
</a-tabs>
</a-form>
</BasicModal>
</template>
<script lang="ts">
import { defineComponent, ref, reactive, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '/src/components/Modal';
import { JVxeTable } from '/src/components/jeecg/JVxeTable';
import { columns, columns1 } from './jvxetable.data';
import { orderCustomerList, orderTicketList, saveOrUpdate } from './jvxetable.api';
import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods.ts';
export default defineComponent({
name: 'JVexTableModal',
components: { BasicModal, JVxeTable },
emits: ['success', 'register'],
setup(props, { emit }) {
const tableH = ref(300);
const isUpdate = ref(true);
const tableRef1 = ref();
const tableRef2 = ref();
const refKeys = ref(['tableRef1', 'tableRef2']);
const activeKey = ref('tableRef1');
const tableRefs = { tableRef1, tableRef2 };
const labelCol = reactive({
xs: { span: 24 },
sm: { span: 5 },
});
const wrapperCol = reactive({
xs: { span: 24 },
sm: { span: 16 },
});
// 客户信息
const table1 = reactive({
loading: false,
dataSource: [],
columns,
});
// 机票信息
const table2 = reactive({
loading: false,
dataSource: [],
columns: columns1,
});
const orderMainModel = reactive({
id: null,
orderCode: '',
orderMoney: '',
ctype: '',
content: '',
jeecgOrderCustomerList: [],
jeecgOrderTicketList: [],
});
const [handleChangeTabs, handleSubmit, requestSubTableData, formRef] = useJvxeMethod(
requestAddOrEdit,
classifyIntoFormData,
tableRefs,
activeKey,
refKeys
);
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
setModalProps({ confirmLoading: false });
reset();
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
Object.assign(orderMainModel, data.record);
//加载子表数据
let params = { id: orderMainModel.id };
requestSubTableData(orderCustomerList, params, table1);
requestSubTableData(orderTicketList, params, table2);
}
});
const validatorRules = { orderCode: [{ required: true, message: '订单号不能为空', trigger: 'blur' }] };
const getTitle = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
function classifyIntoFormData(allValues) {
let orderMain = Object.assign(orderMainModel, allValues.formValue);
return {
...orderMain, // 展开
jeecgOrderCustomerList: allValues.tablesValue[0].tableData,
jeecgOrderTicketList: allValues.tablesValue[1].tableData,
};
}
function reset() {
orderMainModel.id = null;
orderMainModel.orderCode = '';
orderMainModel.orderMoney = '';
orderMainModel.orderDate = null;
orderMainModel.ctype = '';
orderMainModel.content = '';
orderMainModel.jeecgOrderCustomerList = [];
orderMainModel.jeecgOrderTicketList = [];
table1.dataSource = [];
table2.dataSource = [];
}
async function requestAddOrEdit(values) {
setModalProps({ confirmLoading: true });
//提交表单
await saveOrUpdate(values, unref(isUpdate));
//关闭弹窗
closeModal();
//刷新列表
emit('success');
}
// update-begin--author:liaozhiyang---date:20230804---for【QQYUN-5866】放大行数自适应
const handleFullScreen = (val) => {
tableH.value=val ? document.documentElement.clientHeight - 387 : 300;
};
// update-end--author:liaozhiyang---date:20230804---for【QQYUN-5866】放大行数自适应
return {
formRef,
activeKey,
table1,
table2,
tableRef1,
tableRef2,
getTitle,
labelCol,
wrapperCol,
validatorRules,
orderMainModel,
registerModal,
handleChangeTabs,
handleSubmit,
handleFullScreen,
tableH,
};
},
});
</script>
<style scoped></style>

View File

@ -0,0 +1,17 @@
import { defHttp } from '/@/utils/http/axios';
enum Api {
save = '/test/jeecgOrderMain/add',
edit = '/test/jeecgOrderMain/edit',
orderCustomerList = '/test/jeecgOrderMain/queryOrderCustomerListByMainId',
orderTicketList = '/test/jeecgOrderMain/queryOrderTicketListByMainId',
}
export const orderCustomerList = Api.orderCustomerList;
export const orderTicketList = Api.orderTicketList;
/**
* 保存或者更新
* @param params
*/
export const saveOrUpdate = (params, isUpdate) => {
let url = isUpdate ? Api.edit : Api.save;
return defHttp.post({ url: url, params });
};

View File

@ -0,0 +1,73 @@
import { JVxeTypes, JVxeColumn } from '/@/components/jeecg/JVxeTable/types';
export const columns: JVxeColumn[] = [
{
title: '客户名',
key: 'name',
width: 180,
type: JVxeTypes.input,
defaultValue: '',
placeholder: '请输入${title}',
validateRules: [{ required: true, message: '${title}不能为空' }],
},
{
title: '性别',
key: 'sex',
width: 180,
type: JVxeTypes.select,
options: [
// 下拉选项
{ title: '男', value: '1' },
{ title: '女', value: '2' },
],
defaultValue: '',
placeholder: '请选择${title}',
},
{
title: '身份证号',
key: 'idcard',
width: 180,
type: JVxeTypes.input,
defaultValue: '',
placeholder: '请输入${title}',
validateRules: [
{
pattern: '^\\d{6}(18|19|20)?\\d{2}(0[1-9]|1[012])(0[1-9]|[12]\\d|3[01])\\d{3}(\\d|[xX])$',
message: '${title}格式不正确',
},
],
},
{
title: '手机号',
key: 'telphone',
width: 180,
type: JVxeTypes.input,
defaultValue: '',
placeholder: '请输入${title}',
validateRules: [
{
pattern: '^1[3456789]\\d{9}$',
message: '${title}格式不正确',
},
],
},
];
export const columns1: JVxeColumn[] = [
{
title: '航班号',
key: 'ticketCode',
width: 180,
type: JVxeTypes.input,
defaultValue: '',
placeholder: '请输入${title}',
validateRules: [{ required: true, message: '${title}不能为空' }],
},
{
title: '航班时间',
key: 'tickectDate',
width: 180,
type: JVxeTypes.date,
placeholder: '请选择${title}',
defaultValue: '',
},
];

View File

@ -0,0 +1,268 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit" width="70%">
<a-form ref="formRef" :model="orderMainModel" :label-col="labelCol" :wrapper-col="wrapperCol" :rules="validatorRules">
<a-row class="form-row" :gutter="16">
<a-col :lg="8">
<a-form-item label="订单号" name="orderCode">
<a-input v-model:value="orderMainModel.orderCode" placeholder="请输入订单号" />
</a-form-item>
</a-col>
<a-col :lg="8">
<a-form-item label="订单类型">
<a-select placeholder="请选择订单类型" v-model:value="orderMainModel.ctype">
<a-select-option value="1">国内订单</a-select-option>
<a-select-option value="2">国际订单</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :lg="8">
<a-form-item label="订单日期">
<a-date-picker showTime valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="orderMainModel.orderDate" />
</a-form-item>
</a-col>
</a-row>
<a-row class="form-row" :gutter="16">
<a-col :lg="8">
<a-form-item label="订单金额">
<a-input v-model:value="orderMainModel.orderMoney" placeholder="请输入订单金额" />
</a-form-item>
</a-col>
<a-col :lg="8">
<a-form-item label="订单备注">
<a-input v-model:value="orderMainModel.content" placeholder="请输入订单备注" />
</a-form-item>
</a-col>
</a-row>
<a-tabs defaultActiveKey="1">
<a-tab-pane tab="客户信息" key="1">
<div>
<a-row type="flex" style="margin-bottom: 10px" :gutter="16">
<a-col :span="5">客户名</a-col>
<a-col :span="5">性别</a-col>
<a-col :span="6">身份证号码</a-col>
<a-col :span="6">手机号</a-col>
<a-col :span="2">操作</a-col>
</a-row>
<a-row type="flex" style="margin-bottom: 10px" :gutter="16" v-for="(item, index) in orderMainModel.jeecgOrderCustomerList" :key="index">
<a-col :span="6" style="display: none">
<a-form-item>
<a-input placeholder="id" v-model:value="item.id" />
</a-form-item>
</a-col>
<a-col :span="5">
<a-form-item>
<a-input placeholder="客户名" v-model:value="item.name" />
</a-form-item>
</a-col>
<a-col :span="5">
<a-form-item>
<a-select placeholder="性别" v-model:value="item.sex">
<a-select-option value="1">男</a-select-option>
<a-select-option value="2">女</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item
:name="['jeecgOrderCustomerList', index, 'idcard']"
:rules="[{ required: true, message: '请输入身份证号', trigger: 'blur' }]"
:key="index"
>
<a-input placeholder="身份证号" v-model:value="item.idcard" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item :name="['jeecgOrderCustomerList', index, 'telphone']">
<a-input placeholder="手机号" v-model:value="item.telphone" />
</a-form-item>
</a-col>
<a-col :span="2">
<a-form-item>
<Icon icon="ant-design:minus-outlined" @click="delRowCustom(index)" style="fontsize: 20px" />
</a-form-item>
</a-col>
</a-row>
<a-button type="dashed" style="width: 98%; margin-top: 10px" @click="addRowCustom">
<Icon icon="ph:plus-bold" />
添加客户信息
</a-button>
</div>
</a-tab-pane>
<a-tab-pane tab="机票信息" key="2" forceRender>
<a-row type="flex" style="margin-bottom: 10px" :gutter="16">
<a-col :span="6">航班号</a-col>
<a-col :span="6">航班时间</a-col>
<a-col :span="6">操作</a-col>
</a-row>
<a-row type="flex" style="margin-bottom: 10px" :gutter="16" v-for="(item, index) in orderMainModel.jeecgOrderTicketList" :key="index">
<a-col :span="6" style="display: none">
<a-form-item>
<a-input placeholder="id" v-model:value="item.id" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item
:name="['jeecgOrderTicketList', index, 'ticketCode']"
:rules="{ required: true, message: '请输入航班号', trigger: 'blur' }"
>
<a-input placeholder="航班号" v-model:value="item.ticketCode" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item>
<a-date-picker placeholder="航班时间" valueFormat="YYYY-MM-DD" v-model:value="item.tickectDate" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item>
<Icon icon="ant-design:minus-outlined" @click="delRowTicket(index)" style="fontsize: 20px" />
</a-form-item>
</a-col>
</a-row>
<a-button type="dashed" style="width: 98%; margin-top: 10px" @click="addRowTicket">
<Icon icon="ph:plus-bold" />
添加机票信息
</a-button>
</a-tab-pane>
</a-tabs>
</a-form>
</BasicModal>
</template>
<script lang="ts">
import { defineComponent, ref, reactive, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface';
import { saveOrUpdate } from './jvxetable/jvxetable.api';
import { orderCustomerList, orderTicketList } from './api';
export default defineComponent({
name: 'tableModal',
components: { BasicModal },
emits: ['success', 'register'],
setup(props, { emit }) {
const isUpdate = ref(true);
const rowId = ref('');
const formRef = ref();
const labelCol = reactive({
xs: { span: 24 },
sm: { span: 5 },
});
const wrapperCol = reactive({
xs: { span: 24 },
sm: { span: 16 },
});
const validatorRules = {
orderCode: [{ required: true, message: '订单号不能为空', trigger: 'blur' }],
};
const orderMainModel = reactive({
id: null,
orderCode: '',
orderMoney: '',
ctype: '',
content: '',
jeecgOrderCustomerList: [],
jeecgOrderTicketList: [],
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
setModalProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
reset();
if (unref(isUpdate)) {
rowId.value = data.record.id;
Object.assign(orderMainModel, data.record);
let params = { id: orderMainModel.id };
const customerList = await orderCustomerList(params);
orderMainModel.jeecgOrderCustomerList = customerList;
const ticketList = await orderTicketList(params);
orderMainModel.jeecgOrderTicketList = ticketList;
}
});
const getTitle = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
//动态添加行
function addRowCustom() {
orderMainModel.jeecgOrderCustomerList.push({});
}
//删除行
function delRowCustom(index) {
orderMainModel['jeecgOrderCustomerList'].splice(index, 1);
orderMainModel.jeecgOrderCustomerList.splice(index, 1);
}
function reset() {
orderMainModel.id = null;
orderMainModel.orderCode = '';
orderMainModel.orderMoney = '';
orderMainModel.orderDate = null;
orderMainModel.ctype = '';
orderMainModel.content = '';
orderMainModel.jeecgOrderCustomerList = [];
orderMainModel.jeecgOrderTicketList = [];
}
function addRowTicket() {
orderMainModel.jeecgOrderTicketList.push({});
}
//删除机票
function delRowTicket(index) {
orderMainModel['jeecgOrderTicketList'].splice(index, 1);
orderMainModel.jeecgOrderTicketList.splice(index, 1);
}
async function handleSubmit() {
formRef.value
.validate()
.then(async () => {
try {
console.log('formData', JSON.stringify(orderMainModel));
setModalProps({ confirmLoading: true });
await saveOrUpdate(orderMainModel, unref(isUpdate));
closeModal();
emit('success');
} finally {
setModalProps({ confirmLoading: false });
}
})
.catch((error: ValidateErrorEntity<any>) => {
console.log('error', error);
});
}
return {
formRef,
validatorRules,
orderMainModel,
registerModal,
getTitle,
labelCol,
wrapperCol,
addRowCustom,
delRowCustom,
addRowTicket,
delRowTicket,
handleSubmit,
};
},
});
</script>
<style scoped>
.ant-btn {
padding: 0 10px;
margin-left: 3px;
}
.ant-form-item-control {
line-height: 0px;
}
/** 主表单行间距 */
.ant-form .ant-form-item {
margin-bottom: 10px;
}
/** Tab页面行间距 */
.ant-tabs-content .ant-form-item {
margin-bottom: 0px;
}
</style>