8/10 新增删除账单功能,收费分类-关联
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { ChargeTypeVO, ChargeTypeForm, ChargeTypeQuery } from './type';
|
||||
import { ChargeTypeVO, ChargeTypeForm, ChargeTypeQuery, ChargeTypeRelationQuery } from './type';
|
||||
|
||||
/**
|
||||
* 查询收费类型列表
|
||||
@@ -61,3 +61,37 @@ export const delChargeType = (id: string | number | Array<string | number>) => {
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询收费类型关联列表
|
||||
* @param query
|
||||
*/
|
||||
export const getChargeTypeRelation = (query?: ChargeTypeRelationQuery) => {
|
||||
return request({
|
||||
url: '/chargeType/relation/list',
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增收费类型关联
|
||||
* @param data
|
||||
*/
|
||||
export const addChargeTypeRelation = (data: ChargeTypeRelationQuery) => {
|
||||
return request({
|
||||
url: '/chargeType/relation',
|
||||
method: 'POST',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 新增收费类型关联
|
||||
* @param data
|
||||
*/
|
||||
export const editChargeTypeRelation = (data: ChargeTypeRelationQuery) => {
|
||||
return request({
|
||||
url: '/chargeType/relation',
|
||||
method: 'PUT',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
@@ -64,3 +64,20 @@ export interface ChargeType2Query extends PageQuery {
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export interface ChargeTypeRelationQuery {
|
||||
/**
|
||||
* 主收费类型表id
|
||||
*/
|
||||
masterTypeId?: string;
|
||||
/**
|
||||
* 子收费类型表id
|
||||
*/
|
||||
slaveTypeIds?: string;
|
||||
id?: string;
|
||||
// 状态 0启用 1停用
|
||||
status?: string;
|
||||
}
|
||||
|
||||
@@ -77,6 +77,14 @@ export const billPrint = (data: { 'detailsIds': string[]; 'residentId': string }
|
||||
});
|
||||
};
|
||||
|
||||
// 删除账单
|
||||
export const billDelete = (ids: string | string[]) => {
|
||||
return request({
|
||||
url: `/cash/bill/${ids}`,
|
||||
method: 'DELETE'
|
||||
});
|
||||
};
|
||||
|
||||
export type BillPrintType = {
|
||||
'totalAccount': string;
|
||||
'residentName': string;
|
||||
|
||||
@@ -5,11 +5,11 @@ import { addBuildingType, addHouseType, BuildingUnit, BuildingVo } from './type'
|
||||
// 楼栋---------------------------------------------------------------------------------------
|
||||
|
||||
/** 根据 小区id 和 类型 查询楼栋信息 */
|
||||
export function getBuildinglistAPI(): AxiosPromise<BuildingVo[]> {
|
||||
export function getBuildinglistAPI(query = {}): AxiosPromise<BuildingVo[]> {
|
||||
return request({
|
||||
url: '/building/byVillage',
|
||||
method: 'get',
|
||||
params: {}
|
||||
params: query
|
||||
});
|
||||
}
|
||||
/** 获取所有楼栋 */
|
||||
|
||||
@@ -124,6 +124,7 @@ export interface HouseRentalSigningVO {
|
||||
'tenantPhone': string;
|
||||
'chargeMode': string;
|
||||
'chargeStandard': string;
|
||||
'contractName': string;
|
||||
'contractStatus': string;
|
||||
'leaseStartDate': string;
|
||||
'leaseEndDate': string;
|
||||
|
||||
@@ -20,16 +20,22 @@
|
||||
<el-card class="flex-1" shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<right-toolbar
|
||||
:disable-delete="multiple"
|
||||
:disable-edit="single"
|
||||
:show-add="checkPermi(['chargeType:chargeType:add'])"
|
||||
:show-edit="false"
|
||||
:show-delete="false"
|
||||
@update:add="handleAdd"
|
||||
@update:edit="handleUpdate()"
|
||||
@update:delete="handleDelete()"
|
||||
></right-toolbar>
|
||||
<el-col :span="22"> </el-col>
|
||||
<el-col :span="2">
|
||||
<div class="flex justify-end items-center">
|
||||
<el-button style="margin-right: 10px" type="primary" @click="handleContainer">关联收费</el-button>
|
||||
<right-toolbar
|
||||
:disable-delete="multiple"
|
||||
:disable-edit="single"
|
||||
:show-add="checkPermi(['chargeType:chargeType:add'])"
|
||||
:show-edit="false"
|
||||
:show-delete="false"
|
||||
@update:add="handleAdd"
|
||||
@update:edit="handleUpdate()"
|
||||
@update:delete="handleDelete()"
|
||||
></right-toolbar>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
@@ -70,15 +76,64 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog :title="dialog2.title" v-model="dialog2.visible" width="500px" append-to-body>
|
||||
<el-form ref="chargeTypeForm2Ref" :model="form2" :rules="rules2" label-width="100px">
|
||||
<el-form-item label="主收费类型">
|
||||
<el-select
|
||||
@change="handleChangeMasterType"
|
||||
style="width: 220px; margin-right: 10px"
|
||||
v-model="form2.masterTypeId"
|
||||
placeholder="请选择收费类型"
|
||||
>
|
||||
<el-option v-for="item in TypeList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="次收费类型" v-for="(_, index) in slaveTypeIdsList" :key="index">
|
||||
<div class="flex flex-items-center">
|
||||
<el-select
|
||||
@change="handleChangeMasterType"
|
||||
style="width: 220px; margin-right: 10px"
|
||||
v-model="slaveTypeIdsList[index]"
|
||||
placeholder="请选择收费类型"
|
||||
>
|
||||
<el-option :disabled="item.disabled" v-for="item in TypeList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
<div class="addBox" @click="handleAddType" v-if="index === 0 && slaveTypeIdsList.length < TypeList.length - 1">
|
||||
<el-icon size="23" color="#ffffff"><Plus /></el-icon>
|
||||
</div>
|
||||
<el-icon @click="deleteType(index)" v-else-if="slaveTypeIdsList.length > 1" size="24" color="red"><Delete /></el-icon>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否启用关联">
|
||||
<el-switch v-model="form2.status" active-value="0" inactive-value="1" active-text="启用" inactive-text="禁用" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading2" type="primary" @click="submitForm2">确 定</el-button>
|
||||
<el-button @click="cancel2">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="ChargeType" lang="ts">
|
||||
import PageHeader from '@/components/Pageheader/index.vue';
|
||||
import pagination from '@/components/Pagination/index.vue';
|
||||
import { listChargeType, getChargeType, delChargeType, addChargeType, updateChargeType } from '@/api/system/ChargeType';
|
||||
import {
|
||||
listChargeType,
|
||||
getChargeType,
|
||||
delChargeType,
|
||||
addChargeType,
|
||||
updateChargeType,
|
||||
getChargeTypeRelation,
|
||||
addChargeTypeRelation,
|
||||
editChargeTypeRelation
|
||||
} from '@/api/system/ChargeType';
|
||||
import { ChargeTypeVO, ChargeTypeForm, ChargeType2Query } from '@/api/system/ChargeType/type';
|
||||
import { checkPermi } from '@/utils/permission';
|
||||
import { Delete, Plus } from '@element-plus/icons-vue';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
@@ -110,8 +165,7 @@ const data = reactive<PageData<ChargeTypeForm, ChargeType2Query>>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
name: undefined,
|
||||
status: undefined,
|
||||
params: {}
|
||||
status: undefined
|
||||
}
|
||||
});
|
||||
|
||||
@@ -209,6 +263,85 @@ const handleDelete = async (row?: ChargeTypeVO) => {
|
||||
await getList();
|
||||
};
|
||||
|
||||
const dialog2 = ref({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
const form2 = ref({
|
||||
'id': undefined,
|
||||
'masterTypeId': undefined,
|
||||
'status': '0',
|
||||
'slaveTypeIds': undefined,
|
||||
'remark': undefined
|
||||
});
|
||||
const rules2 = {};
|
||||
// 子收费类型
|
||||
const slaveTypeIdsList = ref([null]);
|
||||
// 收费类型
|
||||
const TypeList = ref([]);
|
||||
// 关联收费
|
||||
function handleContainer() {
|
||||
TypeList.value = chargeTypeList.value.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
disabled: false
|
||||
};
|
||||
});
|
||||
getChargeTypeRelation().then((res) => {
|
||||
if (res.rows.length > 0) {
|
||||
form2.value = res.rows[0];
|
||||
slaveTypeIdsList.value = form2.value.slaveTypeIds.split(',');
|
||||
handleChangeMasterType();
|
||||
}
|
||||
});
|
||||
dialog2.value.visible = true;
|
||||
dialog2.value.title = '关联收费';
|
||||
}
|
||||
|
||||
function handleChangeMasterType() {
|
||||
const selectedValues = [form2.value.masterTypeId, ...slaveTypeIdsList.value.filter((item) => item !== null && item !== undefined && item !== '')];
|
||||
// 根据当前选中状态重新计算 disabled
|
||||
TypeList.value.forEach((item) => {
|
||||
item.disabled = selectedValues.includes(item.id);
|
||||
});
|
||||
}
|
||||
|
||||
function handleAddType() {
|
||||
slaveTypeIdsList.value.length++;
|
||||
}
|
||||
function deleteType(index: number) {
|
||||
slaveTypeIdsList.value.splice(index, 1);
|
||||
}
|
||||
function cancel2() {
|
||||
dialog2.value.visible = false;
|
||||
TypeList.value = [];
|
||||
slaveTypeIdsList.value = [null];
|
||||
dialog2.value.title = '';
|
||||
}
|
||||
const buttonLoading2 = ref(false);
|
||||
function submitForm2() {
|
||||
form2.value.slaveTypeIds = slaveTypeIdsList.value.filter((item) => item !== null).join(',');
|
||||
buttonLoading2.value = true;
|
||||
if (form2.value.id) {
|
||||
// edit
|
||||
editChargeTypeRelation(form2.value)
|
||||
.then(() => {
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
cancel2();
|
||||
getList();
|
||||
})
|
||||
.finally(() => (buttonLoading2.value = false));
|
||||
} else {
|
||||
// add
|
||||
addChargeTypeRelation(form2.value)
|
||||
.then(() => {
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
cancel2();
|
||||
getList();
|
||||
})
|
||||
.finally(() => (buttonLoading2.value = false));
|
||||
}
|
||||
}
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
@@ -218,4 +351,13 @@ onMounted(() => {
|
||||
.el-table {
|
||||
height: calc(100% - 80px);
|
||||
}
|
||||
|
||||
.addBox {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background-color: rgba(26, 117, 255, 1);
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
<div class="actions">
|
||||
<el-button @click="handleIncome(false)" :disabled="!single">收费</el-button>
|
||||
<el-button @click="printPIaoJuByOnly(false)" :disabled="!printSingle">打印票据</el-button>
|
||||
<el-button @click="handleDelete(false)">批量删除</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-card class="flex-1" shadow="never">
|
||||
@@ -153,14 +154,11 @@
|
||||
<el-table-column label="缴费人" width="120" align="center" prop="residentName" />
|
||||
<el-table-column label="缴费时间" width="200" align="center" prop="payTime" />
|
||||
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="110" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" v-if="scope.row.payStatus !== '1'" @click="handleIncome(scope.row)" v-has-permi="['bill:bill:edit']"
|
||||
>收款</el-button
|
||||
>
|
||||
<el-button link type="success" v-if="scope.row.payStatus === '1'" @click="printPIaoJuByOnly(scope.row)" v-has-permi="['bill:bill:query']"
|
||||
>打印票据</el-button
|
||||
>
|
||||
<el-button link type="primary" v-if="scope.row.payStatus !== '1'" @click="handleIncome(scope.row)">收款</el-button>
|
||||
<el-button link type="success" v-if="scope.row.payStatus === '1'" @click="printPIaoJuByOnly(scope.row)">打印票据</el-button>
|
||||
<el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -431,7 +429,7 @@ import pagination from '@/components/Pagination/index.vue';
|
||||
import DictTag from '@/components/DictTag/index.vue';
|
||||
import { getBuildinglistAPI, getHouselistAPI } from '@/api/system/house';
|
||||
import { getCommunitylistAPI } from '@/api/system/community';
|
||||
import { billEdit, billlistType, billPrint, BillPrintType, billQuery } from '@/api/system/SdbCashier';
|
||||
import { billDelete, billEdit, billlistType, billPrint, BillPrintType, billQuery } from '@/api/system/SdbCashier';
|
||||
import { listChargeItem } from '@/api/system/SdbChargeItem';
|
||||
import { ref } from 'vue';
|
||||
import { add, div, eq, eqMoney, gtMoney, ltMoney, minMoney, moneyAdd, mul, sub, sum, toBig } from '@/utils/money';
|
||||
@@ -541,7 +539,9 @@ function handleChangeVillage(val: string) {
|
||||
buildingList.value = [];
|
||||
unitList.value = [];
|
||||
if (val) {
|
||||
getBuildinglistAPI().then((res) => {
|
||||
getBuildinglistAPI({
|
||||
villageId: val
|
||||
}).then((res) => {
|
||||
buildingList.value = res.data;
|
||||
handleChargeItem(val);
|
||||
});
|
||||
@@ -1042,6 +1042,26 @@ function conFimPrint() {
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// 删除
|
||||
async function handleDelete(row: billlistType | false) {
|
||||
if (row) {
|
||||
await proxy?.$modal.confirm('该信息删除后无法恢复,确定要删除吗?');
|
||||
billDelete(row.detailsId).then(() => {
|
||||
ElMessage.success('删除成功');
|
||||
getList();
|
||||
});
|
||||
} else {
|
||||
if (ids.value.length <= 0) {
|
||||
return ElMessage.warning('请选择账单!');
|
||||
}
|
||||
await proxy?.$modal.confirm('该信息删除后无法恢复,确定要删除吗?');
|
||||
billDelete(ids.value.map((item) => item.detailsId)).then(() => {
|
||||
ElMessage.success('删除成功');
|
||||
getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
queryParams.value.villageId = villageId;
|
||||
getList();
|
||||
@@ -1143,10 +1163,7 @@ function handlePayListIsEmpt() {
|
||||
item.payAmount === undefined ||
|
||||
item.payAmount === ''
|
||||
);
|
||||
if (invalidIndex !== -1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return invalidIndex === -1;
|
||||
}
|
||||
|
||||
// 校验数字
|
||||
|
||||
@@ -216,6 +216,7 @@ type HouseRentalFormType = HouseRentalSigningVO & {
|
||||
};
|
||||
|
||||
const initFormData: HouseRentalFormType = {
|
||||
contractName: '',
|
||||
'createTime': undefined,
|
||||
'id': undefined,
|
||||
'rentalId': undefined,
|
||||
@@ -290,7 +291,7 @@ const data = reactive<PageData<HouseRentalFormType, HouseRentalQuery>>({
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询房屋租赁管理列表╬₧2╬╬ */
|
||||
/** 查询房屋租赁管理列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
listHouseRental(queryParams.value)
|
||||
@@ -402,10 +403,11 @@ function sign(row: HouseRentalVO) {
|
||||
form.value.villageId = info.villageId;
|
||||
form.value.rentalId = row.id;
|
||||
if (row.signingList && row.signingList.length > 0) {
|
||||
const names = row.signingList[0].contractName ? row.signingList[0].contractName.split(',') : [];
|
||||
showImgList.value = row.signingList[0].contractUrl.split(',').map((item, index) => {
|
||||
return {
|
||||
uid: index,
|
||||
name: item.split('.com/')[1].split('/')[3],
|
||||
name: names[index] || item.split('.com/')[1].split('/')[3],
|
||||
url: item,
|
||||
isLink: true
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="iconbox">
|
||||
<div
|
||||
class="icon_box_text"
|
||||
:title="`${weather_icon.title} ${weather_icon.wind_direction} ${weather_icon.wind_power} 温度${weather_icon.temperature}°C`"
|
||||
:title="`${weather_icon.title} ${weather_icon.wind_direction} ${weather_icon.wind_power} 温度${weather_icon.temperature ?? ''}°C`"
|
||||
>
|
||||
{{ getWeatherIcon(weather_icon.iconvalue) }}
|
||||
</div>
|
||||
@@ -15,7 +15,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="villageinfo flex-1">
|
||||
<div class="villagename">{{ props.villageinfo.villageName }}</div>
|
||||
<div class="villagename" :title="props.villageinfo.villageName">
|
||||
{{ props.villageinfo.villageName }}
|
||||
</div>
|
||||
<div class="week">
|
||||
<span style="padding-right: 10px">{{
|
||||
new Intl.DateTimeFormat('zh-cn', {
|
||||
@@ -74,7 +76,6 @@ const weather_icon = ref({
|
||||
|
||||
gap: 30px;
|
||||
.tips {
|
||||
font-size: small;
|
||||
color: #ffffff77;
|
||||
margin-top: 10px;
|
||||
font-size: 0.8rem;
|
||||
@@ -91,14 +92,11 @@ const weather_icon = ref({
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
cursor: default;
|
||||
margin-right: 20px;
|
||||
margin: 0 auto;
|
||||
|
||||
.icon_box_text {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
line-height: 1;
|
||||
font-size: 70px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
@@ -113,6 +111,10 @@ const weather_icon = ref({
|
||||
.villageinfo {
|
||||
margin-left: 20px;
|
||||
.villagename {
|
||||
width: 200px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
height: 30px;
|
||||
font-weight: 500;
|
||||
font-size: 1.2rem;
|
||||
|
||||
Reference in New Issue
Block a user