admin-vben5/apps/web-antd/src/views/property/greenPlantRentalManagement/leasePogramManagement/rentalPlan-modal.vue
fyy 33f2197ea8
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run
feat: 构架绿植租赁方案管理页面
2025-07-01 17:48:47 +08:00

254 lines
7.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { computed, ref } from 'vue';
import { Button, Table } from 'ant-design-vue';
import { useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { cloneDeep } from '@vben/utils';
import { useVbenForm } from '#/adapter/form';
import { rentalPlanAdd, rentalPlanInfo, rentalPlanUpdate } from '#/api/property/rentalPlan';
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';
import { modalSchema } from './data';
import productDetailModal from './rentalPlan-detial-modal.vue';
const emit = defineEmits<{ reload: [] }>();
const isUpdate = ref(false);
const isReadonly = ref(false);
const title = computed(() => {
return isUpdate.value ? $t('pages.common.edit') : isReadonly.value ? '详情' : $t('pages.common.add');
});
const [BasicForm, formApi] = useVbenForm({
commonConfig: {
// 默认占满两列
formItemClass: 'col-span-1',
// 默认label宽度 px
labelWidth: 120,
// 通用配置项 会影响到所有表单项
componentProps: computed(() => ({
class: 'w-full',
disabled: isReadonly.value,
})),
},
schema: modalSchema(),
showDefaultActions: false,
wrapperClass: 'grid-cols-2',
});
const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff(
{
initializedGetter: defaultFormValueGetter(formApi),
currentGetter: defaultFormValueGetter(formApi),
},
);
const [BasicModal, modalApi] = useVbenModal({
// 在这里更改宽度
class: 'w-[70%]',
fullscreenButton: false,
onBeforeClose,
onClosed: handleClosed,
onConfirm: handleConfirm,
onOpenChange: async (isOpen) => {
if (!isOpen) {
return null;
}
console.log(isOpen);
modalApi.modalLoading(true);
console.log(modalApi.getData(),'====================');
const { id, readonly } = modalApi.getData() as { id?: number | string, readonly?: boolean; };
isReadonly.value = !!readonly;
if(isReadonly.value){
isUpdate.value = false;
}else{
isUpdate.value = !!id;
}
// 查看与编辑时需要获取详情
if ((isUpdate.value || isReadonly.value) && id) {
const record = await rentalPlanInfo(id);
await formApi.setValues(record);
}
await markInitialized();
modalApi.modalLoading(false);
},
});
const detailTable = ref<any>([]);
async function handleConfirm() {
try {
modalApi.lock(true);
const { valid } = await formApi.validate();
if (!valid) {
return;
}
// getValues获取为一个readonly的对象 需要修改必须先深拷贝一次
const data = cloneDeep(await formApi.getValues());
console.log(data);
console.log(detailTable.value);
data.productIds = detailTable.value.map((item:any) => item.id);
await (isUpdate.value ? rentalPlanUpdate(data) : rentalPlanAdd(data));
resetInitialized();
emit('reload');
modalApi.close();
} catch (error) {
console.error(error);
} finally {
modalApi.lock(false);
}
}
async function handleClosed() {
detailTable.value = [];
await formApi.resetForm();
resetInitialized();
}
const [ProductDetailModal, detailModalApi] = useVbenModal({
connectedComponent: productDetailModal,
});
const detailColumns = [
{ title: '序号', key: 'index' },
{ title: '产品编号', dataIndex: 'plantCode', key: 'plantCode' },
{ title: '产品名称', dataIndex: 'plantName', key: 'plantName' },
{ title: '产品分类', dataIndex: 'plantType', key: 'plantType' },
{
title: '图片',
dataIndex: 'imgPath',
key: 'imgPath',
},
{
title: '规格',
dataIndex: 'specification',
key: 'specification',
},
{ title: '租金', dataIndex: 'rent', key: 'rent' },
{ title: '备注', dataIndex: 'remark', key: 'remark' },
{
title: '状态',
dataIndex: 'state',
key: 'state',
customRender: ({ value }: { value: number }) =>
value === 1 ? '上架' : '下架',
},
{
title: '操作',
key: 'action',
fixed: 'right' as const,
},
];
function handleAddDetail() {
detailModalApi.setData({});
detailModalApi.open();
}
//添加植物组合包产品
function handleDetailReload (data: any) {
detailTable.value.push(data);
}
// 编辑植物组合包产品
function handleEditDetailReload (data: any) {
detailTable.value[data.index] = data;
}
// 删除植物组合包产品
function handleDeleteDetail(record: any, index: number) {
detailTable.value.splice(index, 1);
}
// 查看产品详情
function handleViewDetail(record: any) {
detailModalApi.setData({ ...record, readonly: true });
detailModalApi.open();
}
// 编辑产品详情
function handleEditDetail(record: any, index: number) {
detailModalApi.setData({ ...record, index, readonly: false });
detailModalApi.open();
}
</script>
<template>
<BasicModal :title="title">
<BasicForm />
<!-- 添加产品部分 -->
<div class="mt-4">
<div class="mb-2 flex items-center justify-between">
<h3 class="text-lg font-medium">{{ isUpdate ? '编辑植物组合包产品' : isReadonly ? '查看植物组合包产品' : '添加植物组合包产品' }} </h3>
<a-button v-if="!isReadonly" type="primary" @click="handleAddDetail">
{{ $t('pages.common.add') }}
</a-button>
</div>
<Table
:data-source="detailTable"
:columns="detailColumns"
:pagination="false"
>
<template #bodyCell="{ column, index, record }">
<template v-if="column.key === 'index'">
{{ index + 1 }}
</template>
<template v-else-if="column.key === 'action'">
<template v-if="isReadonly">
<Button @click="handleViewDetail(record)">查看</Button>
</template>
<template v-else >
<Button type="primary" size="small" style="margin-right: 5px;" @click="handleViewDetail(record)">查看</Button>
<Button type="primary" size="small" style="margin-right: 5px;" @click="handleEditDetail(record, index)">编辑</Button>
<Button danger size="small" @click="handleDeleteDetail(record, index)">
删除
</Button>
</template>
</template>
</template>
</Table>
<!-- <div>费用合计{{ totalSumPeices }}</div> -->
</div>
<ProductDetailModal @reload="handleDetailReload" @editReload="handleEditDetailReload"/>
</BasicModal>
</template>
<style scoped>
.mt-4 {
margin-top: 1rem;
}
.mb-2 {
margin-bottom: 0.5rem;
}
.flex {
display: flex;
}
.items-center {
align-items: center;
}
.justify-between {
justify-content: space-between;
}
.text-lg {
font-size: 1.125rem;
line-height: 1.75rem;
}
.font-medium {
font-weight: 500;
}
/* 使用 :deep() 穿透 scoped 样式,影响子组件 */
:deep(.ant-input[disabled]),
:deep(.ant-input-number-disabled .ant-input-number-input),
:deep(.ant-select-disabled .ant-select-selection-item),
:deep(.ant-picker-disabled .ant-picker-input > input) {
/* 设置一个更深的颜色 */
color: rgb(0 0 0 / 65%) !important;
/* 有些浏览器需要这个来覆盖默认颜色 */
-webkit-text-fill-color: rgb(0 0 0 / 65%) !important;
}
</style>