Files
admin-vben5/apps/web-antd/src/views/property/greenPlantRentalManagement/leasePogramManagement/rentalPlan-modal.vue

327 lines
9.0 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, message, 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';
import { getDictOptions } from '#/utils/dict';
import { Item } from 'ant-design-vue/es/menu';
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 editId = ref<string | number | undefined>('');
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;
}
modalApi.modalLoading(true);
const { id, readonly } = modalApi.getData() as {
id?: number | string;
readonly?: boolean;
};
editId.value = id || '';
isReadonly.value = !!readonly;
if (isReadonly.value) {
isUpdate.value = false;
} else {
isUpdate.value = !!id;
}
// 查看与编辑时需要获取详情
if ((isUpdate.value || isReadonly.value) && id) {
const record = await rentalPlanInfo(id);
// 后端返回绿植产品包列表结构处理
// detailTable.value = record.productList.map((item:any) => {...item.product,item.productNum,});
detailTable.value = record.productList.map((item: any) => ({
...item.product,
productNum: item.productNum,
productId: item.productId,
}));
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());
// data.productIds = detailTable.value.map((item:any) => item.productId);
data.productList = detailTable.value;
if (data.productList.length == 0) {
message.error('请添加植物组合包产品');
return;
}
await (isUpdate.value
? rentalPlanUpdate({ ...data, id: editId.value })
: 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: 'productNum', key: 'productNum' },
// {
// 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() {
// 传递已选产品id列表
const selectedIds = detailTable.value.map(
(item: any) => item.productId || item.plantName,
);
detailModalApi.setData({ selectedIds, add: true });
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) {
// 编辑时排除当前项id
const selectedIds = detailTable.value
.filter((_: any, i: number) => i !== index)
.map((item: any) => item.productId || item.plantName);
detailModalApi.setData({ ...record, index, selectedIds, edit: true });
detailModalApi.open();
}
//分类字典
function getPlantTypeLabel(value: string | number) {
const opts = getDictOptions('pro_product_classification');
const found = opts.find((opt) => opt.value == value);
return found ? found.label : value;
}
</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 === 'plantType'">
<div>{{ getPlantTypeLabel(record.plantType) }}</div>
</template>
<template v-else-if="column.key === 'action'">
<template v-if="isReadonly">
<Button
type="primary"
size="small"
style="margin-right: 5px"
@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>