物业主开发

This commit is contained in:
Zy
2026-05-08 11:30:28 +08:00
parent a8bb4e66ad
commit 1b738c0f4d
118 changed files with 2891 additions and 979 deletions

View File

@@ -4,13 +4,13 @@
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form ref="queryFormRef" :model="queryParams" :inline="true" @submit.prevent="handleQuery">
<el-form-item label="项目名称" prop="itemName">
<el-input v-model="queryParams.itemName" placeholder="请输入项目名称" clearable @keyup.enter="handleQuery" />
<el-input v-model="queryParams.itemName" placeholder="请输入项目名称" clearable @keyup.enter.prevent="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" @click="handleQuery">搜索</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
@@ -20,20 +20,16 @@
<el-card class="flex-1" shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['sdb:add:chargeitem']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['sdb:edit:chargeitem']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['chargeItem:chargeItem:remove']"
>删除</el-button
>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
<right-toolbar
:disable-delete="multiple"
:disable-edit="single"
:show-edit="checkPermi(['chargeItem:chargeItem:edit'])"
:show-add="checkPermi(['chargeItem:chargeItem:add'])"
:show-delete="checkPermi(['chargeItem:chargeItem:remove'])"
@update:add="handleAdd"
@update:edit="handleUpdate()"
@update:delete="handleDelete()"
></right-toolbar>
</el-row>
</template>
@@ -75,8 +71,6 @@
<template #default="scope">
<el-switch
@change="(val: string) => handleSwitch(val, scope.row)"
inactive-text="停用"
active-text="启用"
inactive-value="1"
active-value="0"
v-model="scope.row.status"
@@ -85,7 +79,7 @@
</el-table-column>
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" @click="handleUpdate(scope.row)" v-hasPermi="['sdb:edit:chargeitem']">修改</el-button>
<el-button link type="primary" @click="handleUpdate(scope.row)" v-hasPermi="['chargeItem:chargeItem:edit']">编辑</el-button>
<el-button link type="primary" @click="handleDelete(scope.row)" v-hasPermi="['chargeItem:chargeItem:remove']">删除</el-button>
</template>
</el-table-column>
@@ -99,6 +93,7 @@
<script setup name="ChargeItem" lang="ts">
import { listChargeItem, getChargeItem, delChargeItem, addChargeItem, updateChargeItem, changChargeItem } from '@/api/system/SdbChargeItem';
import { ChargeItemVO, ChargeItemQuery, ChargeItemForm } from '@/api/system/SdbChargeItem/type';
import { checkPermi } from '@/utils/permission';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_charge_item_method } = toRefs<any>(proxy?.useDict('com_charge_item_method'));

View File

@@ -4,13 +4,13 @@
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" label-width="120" :inline="true">
<el-form ref="queryFormRef" :model="queryParams" @submit.prevent="handleQuery" label-width="120" :inline="true">
<el-form-item label="收费类型名称" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入收费类型名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" @click="handleQuery">搜索</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
@@ -20,7 +20,7 @@
<el-card class="flex-1" shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<!-- <el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['chargeType:chargeType:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
@@ -32,8 +32,17 @@
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['chargeType:chargeType:remove']"
>删除</el-button
>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-col> -->
<right-toolbar
:disable-delete="multiple"
:disable-edit="single"
:show-add="checkPermi(['chargeType:chargeType:add'])"
:show-edit="checkPermi(['chargeType:chargeType:edit'])"
:show-delete="checkPermi(['chargeType:chargeType:remove'])"
@update:add="handleAdd"
@update:edit="handleUpdate()"
@update:delete="handleDelete()"
></right-toolbar>
</el-row>
</template>
@@ -45,21 +54,15 @@
<el-switch
@change="(val: string) => handleChange(val, scope.row)"
v-model="scope.row.status"
active-text="启用"
active-value="0"
inactive-text="停用"
inactive-value="1"
></el-switch>
</template>
</el-table-column>
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['chargeType:chargeType:edit']"></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['chargeType:chargeType:remove']"></el-button>
</el-tooltip>
<el-button link type="primary" @click="handleUpdate(scope.row)" v-hasPermi="['chargeType:chargeType:edit']">修改</el-button>
<el-button link type="primary" @click="handleDelete(scope.row)" v-hasPermi="['chargeType:chargeType:remove']">删除</el-button>
</template>
</el-table-column>
</el-table>
@@ -86,6 +89,7 @@
<script setup name="ChargeType" lang="ts">
import { listChargeType, getChargeType, delChargeType, addChargeType, updateChargeType } from '@/api/system/ChargeType';
import { ChargeTypeVO, ChargeTypeQuery, ChargeTypeForm, ChargeType2Query } from '@/api/system/ChargeType/type';
import { checkPermi } from '@/utils/permission';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;

View File

@@ -3,7 +3,7 @@
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form ref="queryFormRef" :model="queryParams" @submit.prevent="handleQuery" :inline="true">
<el-form-item label="用户ID" prop="deviceCode">
<el-input v-model="queryParams.deviceCode" placeholder="请输入用户ID" clearable @keyup.enter="handleQuery" />
</el-form-item>
@@ -26,8 +26,8 @@
<el-input v-model="queryParams.rangeFee" placeholder="请输入" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" @click="handleQuery">搜索</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
@@ -67,7 +67,7 @@
>导出</el-button
>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
<right-toolbar></right-toolbar>
</el-row>
</template>

View File

@@ -4,13 +4,13 @@
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form ref="queryFormRef" :model="queryParams" @submit.prevent="handleQuery" :inline="true">
<el-form-item label="仪表名称" prop="houseId">
<el-input v-model="queryParams.houseId" placeholder="请输入仪表名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" @click="handleQuery">搜索</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
@@ -20,15 +20,28 @@
<el-card class="flex-1" shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['sdb:add:payrecord']">新增</el-button>
<!-- <el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['payRecordList:payRecordList:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['payRecord:payRecord:remove']"
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handleDelete()"
v-hasPermi="['payRecordList:payRecordList:remove']"
>删除</el-button
>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-col> -->
<right-toolbar
:disable-delete="multiple"
:show-edit="false"
:show-add="checkPermi(['payRecordList:payRecordList:add'])"
:show-delete="checkPermi(['payRecordList:payRecordList:remove'])"
@update:add="handleAdd"
@update:delete="handleDelete()"
></right-toolbar>
</el-row>
</template>
@@ -80,6 +93,7 @@
<script setup name="PayRecord" lang="ts">
import { listPayRecord, getPayRecord, delPayRecord, addPayRecord, updatePayRecord } from '@/api/system/SdbPayRecord';
import { PayRecordVO, PayRecordQuery, PayRecordForm } from '@/api/system/SdbPayRecord/type';
import { checkPermi } from '@/utils/permission';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_waterelectricity_topup_type } = toRefs<any>(proxy?.useDict('com_waterelectricity_topup_type'));

View File

@@ -5,7 +5,7 @@
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<div class="flex flex-items-center justify-between">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form ref="queryFormRef" :model="queryParams" @submit.prevent="handleQuery" :inline="true">
<el-form-item label="精准查询">
<el-select v-model="queryParamsType" style="width: 160px; margin-right: 20px">
<el-option v-for="item in deviceCodeList" :key="item.value" :label="item.name" :value="item.value"></el-option>
@@ -13,8 +13,8 @@
<el-input v-model="queryParamsValue" placeholder="请输入" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" @click="handleQuery">搜索</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-button @click="confimu">返回</el-button>
@@ -26,7 +26,7 @@
<el-card class="flex-1" shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
<right-toolbar></right-toolbar>
</el-row>
</template>

View File

@@ -13,27 +13,35 @@
<el-option v-for="(item, index) in chargeitemlist" :key="index" :value="item.id" :label="item.itemName"></el-option>
</el-select>
</el-form-item>
<el-form-item label="收费范围" prop="chargeScope">
<!-- 水费电费 收费范围 房屋 -->
<el-form-item label="收费范围" prop="chargeScope" v-if="typeNamelist.includes(typeName)">
<el-radio-group v-model="form.chargeScope">
<el-radio v-for="(item, index) in com_bill_charge_scope_house" :key="index" :value="item.value" :label="item.label"></el-radio>
</el-radio-group>
<div @click="handleClearCheckout" v-if="form.chargeScope === '1'" class="ml-10px cursor-pointer color-red">清空</div>
</el-form-item>
<el-form-item v-if="form.chargeScope === '1'">
<!-- 其他费用 收费范围为 业主 -->
<el-form-item label="收费范围" prop="chargeScope" v-else>
<el-radio-group v-model="form.chargeScope">
<el-radio v-for="(item, index) in com_questionnaire_scope" :key="index" :value="item.value" :label="item.label"></el-radio>
</el-radio-group>
<div @click="handleClearCheckout" v-if="form.chargeScope === '1'" class="ml-10px cursor-pointer color-red">清空</div>
</el-form-item>
<el-form-item v-if="form.chargeScope === '1' && typeNamelist.includes(typeName)">
<div class="residentBox">
<ul class="checkoutSideUsesbox">
<li v-for="(item, index) in checkoutUses" :key="index">
<li v-for="(item, index) in checkoutHouses" :key="index">
<span>{{ item.buildingName }}/</span>
<span>{{ item.unitNo }}单元/</span>
<span>{{ item.floorNo }}/</span>
<span>{{ item.houseNo }}</span>
<el-icon @click="delteUse(item.houseId)">
<el-icon @click="deleteHouse(item.houseId)">
<Delete></Delete>
</el-icon>
</li>
<House returnvalue="*" ref="HolderRef" :isMultiple="true" :userid="form.houseIds.join(',')" @change="handleSelect">
<template #default>
<li @click="OpenUseTablesfun" class="add justify-center">
<li @click="OpenUseTablesfun('house')" class="add justify-center">
<el-icon>
<DocumentAdd></DocumentAdd>
</el-icon>
@@ -44,6 +52,28 @@
</ul>
</div>
</el-form-item>
<el-form-item v-if="form.chargeScope === '1' && !typeNamelist.includes(typeName)">
<div class="residentBox">
<ul class="checkoutSideUsesbox">
<li v-for="(item, index) in checkoutUser" :key="index">
<span>{{ item.house_name }} / {{ item.residentName }} / {{ item.phone }}</span>
<el-icon @click="delteUser(item.residentId)">
<Delete></Delete>
</el-icon>
</li>
<UserHolder returnvalue="*" ref="userRef" :isMultiple="true" :userid="form.residentIds" @change="handleCheckUser">
<template #default>
<li @click="OpenUseTablesfun('user')" class="add justify-center">
<el-icon>
<DocumentAdd></DocumentAdd>
</el-icon>
<span>添加业主</span>
</li>
</template>
</UserHolder>
</ul>
</div>
</el-form-item>
<el-form-item label="费用周期" prop="chargePeriod">
<el-select v-model="form.chargePeriod">
<el-option v-for="(item, index) in com_bill_charge_period" :key="index" :value="item.value" :label="item.label"></el-option>
@@ -78,14 +108,16 @@
<script setup lang="ts">
import { ref } from 'vue';
import House from '@/components/Holder/house.vue';
import UserHolder from '@/components/Holder/user.vue';
import PageHeader from '@/components/Pageheader/index.vue';
import { listChargeItem } from '@/api/system/SdbChargeItem';
import { getBill, updateBill, addBill, BillHouse, listBillHouse } from '@/api/system/SdbBill';
import { getBill, updateBill, addBill, BillHouse, listBillHouse, queryResidentList_holder } from '@/api/system/SdbBill';
import type { DatePickerType } from 'element-plus';
import { formatDate, formatDate2 } from '@/utils';
import { Delete } from '@element-plus/icons-vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_questionnaire_scope } = toRefs<any>(proxy?.useDict('com_questionnaire_scope'));
const { com_bill_charge_scope_house } = toRefs<any>(proxy?.useDict('com_bill_charge_scope_house'));
const { com_bill_charge_period } = toRefs<any>(proxy?.useDict('com_bill_charge_period'));
@@ -108,7 +140,8 @@ const form = ref({
'chargeItemId': '', // 收费项目
'chargeScope': '0', // 业主范围
'chargePeriod': '2', // 费用周期
houseIds: [], // 部分业主
houseIds: [], // 部分房屋
residentIds: [], // 部分业主
charegeTypeId: '', // typeid
'startDate': '', // 开始
'endDate': '', // 结束
@@ -135,6 +168,8 @@ const chargeitemlist = ref([]);
// 房屋列表
const houselist = ref([]);
// 住户列表
const userlist = ref([]);
async function init() {
listChargeItem().then((res) => {
chargeitemlist.value = res.rows;
@@ -142,10 +177,13 @@ async function init() {
const res = await listBillHouse({ pageNum: 1, pageSize: 999999 });
houselist.value = res.rows;
const res2 = await queryResidentList_holder({ pageNum: 1, pageSize: 999999 });
userlist.value = res2.rows;
if (route.query.id) {
userid.value = route.query.id;
getBill(userid.value).then((res) => {
if (!res.data) return;
form.value = {
...form.value,
...res.data
@@ -154,8 +192,9 @@ async function init() {
form.value.startDate = formatDate2(form.value.startDate);
form.value.endDate = formatDate2(form.value.endDate);
StartEndDate.value = [form.value.startDate, form.value.endDate];
checkoutUses.value = form.value.houseIds
// TODO houseid 有默认值, 需要处理
// TODO residentids 添加,
checkoutHouses.value = form.value.houseIds
.map((item) => {
if (item) {
const find = houselist.value.find((it) => it.houseId === item);
@@ -175,35 +214,57 @@ onMounted(() => {
init();
});
const typeNamelist = ref(['2049026484272791553', '2049026503017136129']);
const typeName = ref('');
// 获取收费类型id
function handleChange(val) {
function handleChange(val: string) {
const find = chargeitemlist.value.find((item) => item.id === val);
if (find) {
form.value.charegeTypeId = find.typeId;
typeName.value = find.typeId;
handleClearCheckout();
}
}
// !== 业主 =============================================================================
// 打开
const HolderRef = ref<InstanceType<typeof House>>();
function OpenUseTablesfun() {
HolderRef.value.open();
const userRef = ref<InstanceType<typeof UserHolder>>();
function OpenUseTablesfun(val: string) {
if (val === 'house') {
HolderRef.value.open();
} else if (val === 'user') {
userRef.value.open();
}
}
// 多选
const checkoutUses = ref<BillHouse[]>([]);
const checkoutHouses = ref<BillHouse[]>([]);
function handleSelect(val: BillHouse[]) {
checkoutUses.value = val;
form.value.houseIds = checkoutUses.value.map((item) => item.houseId);
checkoutHouses.value = val;
form.value.houseIds = checkoutHouses.value.map((item) => item.houseId);
}
// 多选
const checkoutUser = ref([]);
/** 添加 业主 */
function handleCheckUser(val) {
checkoutUser.value = val;
form.value.residentIds = checkoutUser.value.map((item) => item.residentId);
}
/** 删除房屋 */
function delteUse(id: string | number) {
checkoutUses.value = checkoutUses.value.filter((item) => item.houseId !== id);
function deleteHouse(id: string) {
checkoutHouses.value = checkoutHouses.value.filter((item) => item.houseId !== id);
}
/** 删除业主 */
function delteUser(id: string) {
checkoutUser.value = checkoutUser.value.filter((item) => item.residentId !== id);
}
/** 清空 */
function handleClearCheckout() {
checkoutUses.value = [];
checkoutHouses.value = [];
checkoutUser.value = [];
form.value.residentIds = [];
form.value.houseIds = [];
}
// !== 业主 =============================================================================
@@ -213,12 +274,12 @@ const submitForm = () => {
formRef.value?.validate(async (valid: boolean) => {
if (valid) {
if (userid.value) {
updateBill(form.value).then((res) => {
updateBill(form.value).then(() => {
ElMessage.success('编辑成功');
cancelForm();
});
} else {
addBill(form.value).then((res) => {
addBill(form.value).then(() => {
ElMessage.success('添加成功');
cancelForm();
});

View File

@@ -4,7 +4,7 @@
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form ref="queryFormRef" :model="queryParams" @submit.prevent="handleQuery" :inline="true">
<el-form-item label="收费项目" prop="chargeItemId">
<el-select v-model="queryParams.chargeItemId" placeholder="请选择收费项目">
<el-option v-for="(item, index) in chargeItems" :key="index" :value="item.id" :label="item.itemName"></el-option>
@@ -17,29 +17,28 @@
<el-input v-model="queryParams.billCode" placeholder="请输入" clearable @keyup.enter="handleQuery" />
</el-form-item> -->
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" @click="handleQuery">搜索</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</transition>
<el-card class="flex-1" shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<!-- <el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['bill:bill:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['bill:bill:edit']">修改</el-button>
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['bill:bill:edit']">编辑</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:bill:remove']"
>删除</el-button
>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-col> -->
<right-toolbar :show-add="checkPermi(['bill:bill:add'])" :show-edit="false" :show-delete="false" @update:add="handleAdd"></right-toolbar>
</el-row>
</template>
@@ -49,35 +48,35 @@
<el-table-column label="账单名称" align="center" prop="billName" />
<el-table-column label="收费范围" align="center" prop="chargeScope" width="100">
<template #default="scope">
<!-- TODO 收费类型来判断收费范围 -->
<dict-tag :options="com_bill_charge_scope_house" :value="scope.row.chargeScope"></dict-tag>
</template>
</el-table-column>
<el-table-column label="收费项目" align="center" prop="chargeItemName" />
<el-table-column label="收费周期" align="center" prop="chargePeriod" width="80">
<!-- <el-table-column label="收费周期" align="center" prop="chargePeriod" width="80">
<template #default="scope">
<dict-tag :options="com_bill_charge_period" :value="scope.row.chargePeriod"></dict-tag>
</template>
</el-table-column>
<el-table-column label="开始日期" align="center" prop="startDate" width="180">
</el-table-column> -->
<el-table-column label="起止时间" align="center">
<template #default="scope">
<span>{{ parseTime(scope.row.startDate, '{y}-{m}-{d}') }}</span>
<span>{{ parseTime(scope.row.startDate, '{y}/{m}/{d}') }}</span> -
<span>{{ parseTime(scope.row.endDate, '{y}/{m}/{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="结束日期" align="center" prop="endDate" width="180">
<el-table-column label="单价" align="center" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.endDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="单价" align="center" prop="endDate" width="180">
<template #default="scope">
<span>{{ scope.row.fixedPrice }}</span>
<div class="flex justify-center">
<span>{{ scope.row.fixedPrice }}</span> /
<dict-tag :options="com_charge_item_unit" value="0"></dict-tag>
</div>
</template>
</el-table-column>
<!-- <el-table-column label="数量" align="center" prop="chargePeriod" />
<el-table-column label="费用合计" align="center" prop="chargePeriod" /> -->
<el-table-column label="操作" width="120" align="center" fixed="right" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" @click="handleUpdate(scope.row)" v-hasPermi="['bill:bill:edit']">修改</el-button>
<el-button link type="primary" @click="handleUpdate(scope.row)" v-hasPermi="['bill:bill:edit']">编辑</el-button>
<el-button link type="primary" @click="handleMain(scope.row)" v-hasPermi="['bill:bill:query']">详情</el-button>
<!-- <el-button link type="primary" @click="handleDelete(scope.row)" v-hasPermi="['system:bill:remove']">删除</el-button> -->
</template>
@@ -93,12 +92,14 @@
import { listBill, getBill, delBill, addBill, updateBill } from '@/api/system/SdbBill/index';
import { BillVO, BillQuery, BillForm } from '@/api/system/SdbBill/type';
import { listChargeItem } from '@/api/system/SdbChargeItem';
import { checkPermi } from '@/utils/permission';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_bill_search_filter } = toRefs<any>(proxy?.useDict('com_bill_search_filter'));
const { com_questionnaire_scope } = toRefs<any>(proxy?.useDict('com_questionnaire_scope'));
const { com_bill_charge_period } = toRefs<any>(proxy?.useDict('com_bill_charge_period'));
const { com_bill_charge_scope_house } = toRefs<any>(proxy?.useDict('com_bill_charge_scope_house'));
const { com_charge_item_unit } = toRefs<any>(proxy?.useDict('com_charge_item_unit'));
const billList = ref<BillVO[]>([]);
const buttonLoading = ref(false);
@@ -133,7 +134,7 @@ const data = reactive<PageData<BillForm, BillQuery>>({
form: { ...initFormData },
queryParams: {
pageNum: 1,
pageSize: 10,
pageSize: 20,
billCode: '',
type: '',
value: ''

View File

@@ -2,85 +2,220 @@
<el-card style="margin-top: 20px; height: 100%">
<div class="p-2 flex flex-col cashierbox h-full">
<div class="flex">
<div>小区 北境碧桂园小区</div>
<div style="margin: 0 80px">小区 北境碧桂园小区</div>
<div>小区 北境碧桂园小区</div>
<div>小区{{ villageinfo.villageName ?? '---' }}</div>
<div style="margin: 0 80px">住户姓名 {{ props.query.residentName }}</div>
<div>手机号 {{ props.query.phone }}</div>
</div>
<div class="actionsbox">
<el-button type="primary">收款</el-button>
<el-button>添加临时收费</el-button>
<el-button>预存</el-button>
<el-button>打印</el-button>
<el-button type="primary" @click="openDiage">收款</el-button>
<!-- <el-button>添加临时收费</el-button> -->
<!-- <el-button>预存</el-button> -->
<!-- <el-button>打印</el-button> -->
<el-button @click="emit('Back')">返回</el-button>
</div>
<div class="tablebox">
<el-table>
<el-table-column align="center" label="序号" width="80">
<el-table :data="tabledata" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column align="center" label="房屋/车位">
<template #default="scope">
<div>{{ scope.$index }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="房屋/车位/车辆">
<template #default="scope">
<div>{{ scope.$index }}</div>
<div v-if="scope.row.chargeTypeName === '停车费'">{{ scope.row.parkingName }}</div>
<div v-else-if="scope.row.chargeTypeName === '电费' || scope.row.chargeTypeName === '水费'">{{ scope.row.houseName }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="收费项目">
<template #default="scope">
<div>{{ scope.$index }}</div>
<div>{{ scope.row.chargeItemName }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="收费周期">
<template #default="scope">
<div>{{ scope.$index }}</div>
<div>{{ scope.row.startDate }} -- {{ scope.row.endDate }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="单价">
<template #default="scope">
<div>{{ scope.$index }}</div>
<div>{{ scope.row.fixedPrice }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="数量">
<!-- <el-table-column align="center" label="数量">
<template #default="scope">
<div>{{ scope.$index }}</div>
<div>{{ scope.row.formula }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="应收金额">
<template #default="scope">
<div>{{ scope.$index }}</div>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column align="center" label="缴费状态">
<template #default="scope">
<div>{{ scope.$index }}</div>
<dict-tag v-if="!inglelist.includes(scope.row.chargeItemName)" :options="com_pay_status" :value="scope.row.payStatus"></dict-tag>
<div v-else>--</div>
</template>
</el-table-column>
<el-table-column align="center" label="应缴金额">
<template #default="scope">
<div>{{ scope.$index }}</div>
<div v-if="!inglelist.includes(scope.row.chargeItemName)">{{ scope.row.money ?? '--' }}</div>
<div v-else>--</div>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</div>
</div>
<!-- 添加或修改电 设备对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<div class="payinfo">
<div>
<span>缴费人{{ villageinfo.villageName ?? '---' }}-{{ props.query.houseName }}</span>
</div>
<div>
<span>账单名称 </span>
<span style="text-wrap: wrap; text-indent: 2rem">{{ from.billResidentId.join('、 ') }}</span>
</div>
<div>
<span>应收合计{{ from.allCost }}</span>
</div>
<div>
<span>应缴合计{{ from.allCost }}</span>
</div>
</div>
<el-form ref="formRef" :model="from" label-width="100px">
<el-form-item label="费用合计" prop="allCost">
<el-input v-model="from.allCost">
<template #suffix>
<span></span>
</template>
</el-input>
</el-form-item>
<el-form-item label="缴纳状态" prop="payStatus">
<el-radio-group v-model="from.payStatus">
<el-radio v-for="dict in com_pay_status" :key="dict.value" :label="dict.label" :value="dict.value"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="支付方式" prop="payType">
<el-select v-model="from.payType" placeholder="请选择">
<el-option v-for="dict in com_pay_method" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input type="textarea" :rows="5" v-model="from.remark"></el-input>
</el-form-item>
<div class="flex justify-end">
<el-button @click="closepay">取消</el-button>
<el-button :loading="buttonLoading" type="primary" @click="submitForm">提交</el-button>
</div>
</el-form>
</el-dialog>
</el-card>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { billlistType, billQuery } from '@/api/system/SdbCashier';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_pay_method, com_pay_status } = toRefs<any>(proxy?.useDict('com_pay_method', 'com_pay_status'));
const villageinfo = JSON.parse(localStorage.getItem('villageInfo') || '{}');
// 隐藏收费金额的 类型列表
const inglelist = ['电费', '水费'];
type querytype = {
residentId: string;
residentName: string;
houseName: string;
phone: string;
};
const props = defineProps({
query: {
type: Object as PropType<querytype>,
default: () => {
return {
'residentId': '',
'residentName': '',
'houseName': '',
'phone': ''
};
}
}
});
const ids = ref<Array<billlistType>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(100);
const queryParams = ref({
pageNum: 1,
pageSize: 10
});
const tabledata = ref([]);
const getList = () => {
console.log('getList');
billQuery({
residentId: props.query.residentId,
payStatus: '0'
}).then((res) => {
tabledata.value = res.rows;
total.value = res.total;
});
};
/** 多选框选中数据 */
const handleSelectionChange = (selection: billlistType[]) => {
// TODO: 获取选中的id
ids.value = [];
ids.value = selection;
console.log(ids.value);
console.log(selection);
single.value = selection.length != 1;
multiple.value = !selection.length;
};
onMounted(() => {
getList();
});
const emit = defineEmits(['Back']);
const formRef = ref();
const dialog = reactive<DialogOption>({
visible: false,
title: '收款'
});
const buttonLoading = ref(false);
const from = ref({
allCost: null, // 金额
billResidentId: [], // 账单id
payStatus: '0', // 0:未缴 1:已缴
payType: '0', // 0:微信 1:支付宝 2 线下
remark: ''
});
const openDiage = () => {
from.value = {
allCost: 0,
payStatus: '0',
billResidentId: ['202505电费', '202505水费'],
payType: '0',
remark: ''
};
// 计算金额
ids.value.forEach((item) => {
from.value.allCost += Number(item.money);
});
dialog.visible = true;
};
const closepay = () => {
dialog.visible = false;
dialog.title = '';
};
const submitForm = () => {
buttonLoading.value = true;
if (from.value.payStatus === '0') {
setTimeout(() => {
buttonLoading.value = false;
closepay();
}, 1000);
} else {
}
};
</script>
<style scoped lang="scss">
@@ -103,4 +238,14 @@ const emit = defineEmits(['Back']);
}
}
}
.payinfo {
color: rgba(0, 0, 0, 1);
margin-top: 20px;
padding-bottom: 10px;
margin-bottom: 30px;
border-bottom: 1px solid #d2d2d2;
& > div {
margin-bottom: 10px;
}
}
</style>

View File

@@ -1,74 +1,194 @@
<template>
<div class="p-2 flex flex-col cashierbox h-full">
<div class="flex">
<div>小区 北境碧桂园小区</div>
<div style="margin: 0 80px">小区 北境碧桂园小区</div>
<div>小区 北境碧桂园小区</div>
</div>
<div class="tablebox">
<el-table>
<el-table-column align="center" label="序号" width="80">
<template #default="scope">
<div>{{ scope.$index }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="房屋/车位/车辆">
<template #default="scope">
<div>{{ scope.$index }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="收费项目">
<template #default="scope">
<div>{{ scope.$index }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="收费周期">
<template #default="scope">
<div>{{ scope.$index }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="单价">
<template #default="scope">
<div>{{ scope.$index }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="数量">
<template #default="scope">
<div>{{ scope.$index }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="应收金额">
<template #default="scope">
<div>{{ scope.$index }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="缴费状态">
<template #default="scope">
<div>{{ scope.$index }}</div>
</template>
</el-table-column>
<el-card style="margin-top: 20px; height: 100%">
<div class="p-2 flex flex-col cashierbox h-full">
<div class="tablebox">
<el-table :data="tabledata">
<el-table-column type="selection" width="55" align="center" />
<el-table-column align="center" label="序号" width="80">
<template #default="scope">
<div>{{ scope.$index }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="房屋/车位/车辆">
<template #default="scope">
<div v-if="scope.row.houseName">{{ scope.row.parkingName }}</div>
<div v-else-if="scope.row.parkingName">{{ scope.row.parkingName }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="收费项目">
<template #default="scope">
<div>{{ scope.row.chargeItemName }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="收费周期">
<template #default="scope">
<div>{{ scope.row.startDate }} -- {{ scope.row.endDate }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="单价">
<template #default="scope">
<div>{{ scope.row.fixedPrice }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="数量">
<template #default="scope">
<div>{{ scope.row.formula }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="缴费状态">
<template #default="scope">
<dict-tag :options="com_pay_status" :value="scope.row.payStatus"></dict-tag>
</template>
</el-table-column>
<el-table-column align="center" label="应缴金额">
<template #default="scope">
<div>{{ scope.$index }}</div>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
<el-table-column align="center" label="应缴金额">
<template #default="scope">
<div>{{ scope.row.money }}</div>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</div>
</div>
</div>
<!-- 添加或修改电 设备对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<div class="payinfo">
<div>
<span>缴费人北境碧桂园小区-A栋1单元102-张姗</span>
</div>
<div>
<span>账单名称2025年车位费2025年上半年物业费 </span>
</div>
<div>
<span>应收合计1600.00 </span>
</div>
<div>
<span>应缴合计1600.00 </span>
</div>
</div>
<el-form ref="formRef" :model="from" label-width="100px">
<el-form-item label="费用合计" prop="allCost">
<el-input v-model="from.allCost">
<template #suffix>
<span></span>
</template>
</el-input>
</el-form-item>
<el-form-item label="缴纳状态" prop="startTime">
<el-radio-group v-model="from.deviceType">
<el-radio v-for="dict in com_pay_status" :key="dict.value" :label="dict.label"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="支付方式" prop="endTime">
<el-select v-model="from.deviceType" placeholder="请选择">
<el-option v-for="dict in com_pay_method" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input type="textarea" :rows="5" v-model="from.remark"></el-input>
</el-form-item>
<div class="flex justify-end">
<el-button @click="closepay">取消</el-button>
<el-button :loading="buttonLoading" type="primary" @click="submitForm">提交</el-button>
</div>
</el-form>
</el-dialog>
</el-card>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { billlistType, billQuery } from '@/api/system/SdbCashier';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_pay_method, com_pay_status } = toRefs<any>(proxy?.useDict('com_pay_method', 'com_pay_status'));
type querytype = {
residentId: string;
residentName: string;
houseName: string;
phone: string;
};
const props = defineProps({
query: {
type: Object as PropType<querytype>,
default: () => {
return {
'residentId': '',
'residentName': '',
'houseName': '',
'phone': ''
};
}
}
});
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(100);
const queryParams = ref({
pageNum: 1,
pageSize: 10
});
const tabledata = ref([]);
const getList = () => {
console.log('getList');
billQuery({
residentId: props.query.residentId,
'payStatus': '1'
}).then((res) => {
console.log(res);
tabledata.value = res.rows;
total.value = res.total;
});
};
/** 多选框选中数据 */
const handleSelectionChange = (selection: billlistType[]) => {
// TODO: 获取选中的id
ids.value = selection.map((item) => item.residentId);
single.value = selection.length != 1;
multiple.value = !selection.length;
};
onMounted(() => {
getList();
});
const emit = defineEmits(['Back']);
const formRef = ref();
const dialog = reactive<DialogOption>({
visible: false,
title: '收款'
});
const buttonLoading = ref(false);
const from = ref({
allCost: null,
sex: null,
deviceType: null,
remark: ''
});
const openDiage = () => {
from.value = {
allCost: null,
sex: null,
deviceType: null,
remark: ''
};
dialog.visible = true;
};
const closepay = () => {
dialog.visible = false;
dialog.title = '';
};
const submitForm = () => {
buttonLoading.value = true;
setTimeout(() => {
buttonLoading.value = false;
closepay();
}, 1000);
};
</script>
@@ -92,4 +212,14 @@ const getList = () => {
}
}
}
.payinfo {
color: rgba(0, 0, 0, 1);
margin-top: 20px;
padding-bottom: 10px;
margin-bottom: 30px;
border-bottom: 1px solid #d2d2d2;
& > div {
margin-bottom: 10px;
}
}
</style>

View File

@@ -3,31 +3,34 @@
<Pageheader title="收银台管理"></Pageheader>
<div class="" v-if="isSearch">
<p class="actionsmain">
功能说明可根据住户姓名住户手机号房屋号车位号车牌快速搜索对应的未缴费用修改未缴费用的优惠及滞纳金金额完成对未缴费用的收取
功能说明可根据住户姓名房屋号手机快速搜索对应的未缴费用修改未缴费用的优惠及滞纳金金额完成对未缴费用的收取
</p>
<div class="contanier flex-center">
<div class="h-full flex-1 flex flex-items-start">
<div class="typebox">
<el-select v-model="searchform.type">
<el-select v-model="searchType" @change="handleChangeSearchType">
<el-option v-for="(item, index) in com_cashier_type" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</div>
<div class="searchBox">
<el-input>
<el-input v-model="searchValue" @keyup.enter="getlist">
<template #suffix>
<el-icon>
<el-icon @click="getlist" class="cursor-pointer">
<Search></Search>
</el-icon>
</template>
</el-input>
<div class="listbox" v-show="Boolean(list.length > 0)">
<div class="listbox" v-if="list.length">
<div class="list_item">
<div class="title">
<DictTag :options="com_cashier_type" :value="searchform.type"></DictTag>
<DictTag :options="com_cashier_type" :value="searchType"></DictTag>
</div>
<div class="list_body">
<div class="list_value" @click="searchclick(item)" v-for="(item, index) in list" :key="index">
{{ item.houseName }}-{{ item.residentName }}-{{ item.phone }}
</div>
</div>
<div class="list_value" v-for="(item, index) in list" :key="index">北境碧桂园小区A栋1单元101-张姗-13899999999</div>
<div class="list_value">北境碧桂园小区A栋1单元101-张姗-13899999999</div>
</div>
</div>
</div>
@@ -36,17 +39,19 @@
</div>
<div v-else style="margin-top: 20px; height: calc(100% - 210px)">
<div class="tabsbox">
<div @click="handleChecout(index)" v-for="(item, index) in tabs" :key="index" class="tabs_item" :class="{ active: checkouttabs === index }">
<div
@click="handleChecout(item.value)"
v-for="(item, index) in tabs"
:key="index"
class="tabs_item"
:class="{ active: checkouttabs === item.value }"
>
{{ item.name }}
</div>
</div>
<div class="h-full">
<el-card style="height: 100%; margin-top: 20px" v-if="checkouttabs === 0">
<cashier @Back="handleBack"></cashier>
</el-card>
<el-card style="height: 100%; margin-top: 20px" shadow="never" v-if="checkouttabs === 1">
<history></history>
</el-card>
<cashier :query="checkeditem" @Back="handleBack" v-if="checkouttabs === 'cashier'"></cashier>
<history :query="checkeditem" v-if="checkouttabs === 'history'"></history>
</div>
</div>
</div>
@@ -59,46 +64,77 @@
// TODO 预存
// TODO 缴费
import { Search } from '@element-plus/icons-vue';
import { ref } from 'vue';
import { Component, DefineComponent, ref } from 'vue';
import cashier from './cashier.vue';
import history from './history.vue';
import { debounce } from '@/utils';
import { cashQuery } from '@/api/system/SdbCashier';
const isSearch = ref(true);
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_cashier_type } = toRefs<any>(proxy?.useDict('com_cashier_type'));
const searchform = ref({
type: '0'
});
const list = ref([]);
const searchform = ref();
const searchValue = ref('');
const searchType = ref('residentName');
function handleChangeSearchType() {
list.value = [];
searchValue.value = '';
}
const list = ref<querytype[]>([]);
// ! ===================================================================================
const checkouttabs = ref(0);
const tabs = [
// 先定义 Tab 项类型
type TabValue = 'cashier' | 'history';
interface TabItem {
name: string;
value: TabValue;
component: Component;
}
const checkouttabs = ref<TabValue>('cashier');
const tabs: TabItem[] = [
{
name: '收银台',
value: 'cashier',
component: cashier
},
{
name: '历史缴费',
value: 'history',
component: history
}
];
function handleChecout(index: number) {
type querytype = {
residentId: string;
residentName: string;
houseName: string;
phone: string;
};
const checkeditem = ref<querytype>({
'residentId': '',
'residentName': '',
'houseName': '',
'phone': ''
});
const searchclick = (row: querytype) => {
checkeditem.value = row;
isSearch.value = false;
handleChecout('cashier');
};
function handleChecout(index: TabValue) {
checkouttabs.value = index;
}
// ! ===================================================================================
// ! ===================================================================================
const total = ref(100);
const queryParams = ref({
pageNum: 1,
pageSize: 10
});
const tableData1 = ref([]);
const getList = () => {
console.log('getList');
};
function getlist() {
console.log('search2');
searchform.value = {};
searchform.value[searchType.value] = searchValue.value;
cashQuery(searchform.value).then((res) => {
list.value = res.data;
});
}
// ! ===================================================================================
const handleBack = () => {
isSearch.value = true;
};
@@ -133,7 +169,7 @@ const handleBack = () => {
}
.actionsmain {
font-size: 0.7rem;
font-size: 0.9rem;
color: #000;
padding-left: 30px;
}
@@ -173,24 +209,35 @@ const handleBack = () => {
min-height: 200px;
font-size: 16px;
.title {
color: rgba(48, 49, 51, 1);
font-size: 1rem;
font-weight: 450;
height: 40px;
line-height: 40px;
border-bottom: 1px solid rgba(204, 204, 204, 1);
}
.list_item {
padding-bottom: 30px;
}
.list_value {
height: 40px;
line-height: 40px;
border-bottom: 1px solid rgba(204, 204, 204, 1);
cursor: pointer;
&:hover {
background-color: #cccccc33;
height: 400px;
display: flex;
overflow: hidden;
flex-direction: column;
.title {
color: rgba(48, 49, 51, 1);
font-size: 1rem;
font-weight: 450;
height: 40px;
line-height: 40px;
border-bottom: 1px solid rgba(204, 204, 204, 1);
}
.list_body {
flex: 1;
overflow: auto;
overflow-x: hidden;
.list_value {
min-height: 40px;
height: 40px;
line-height: 40px;
border-bottom: 1px solid rgba(204, 204, 204, 1);
cursor: pointer;
&:hover {
background-color: #cccccc33;
}
}
}
}
}

View File

@@ -4,7 +4,7 @@
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" label-width="100px" :model="queryParams" :inline="true">
<el-form ref="queryFormRef" label-width="100px" @submit.prevent="handleQuery" :model="queryParams" :inline="true">
<!-- <el-form-item label="设备状态" prop="eleStatus">
<el-select v-model="queryParams.eleStatus">
<el-option v-for="(item, index) in com_waterdevice_on_status" :key="index" :label="item.label" :value="item.value"></el-option>
@@ -20,12 +20,12 @@
></el-option>
</el-select>
</el-form-item> -->
<el-form-item label="房号" prop="houseName">
<el-input v-model="queryParams.houseName" placeholder="请输入房间号" clearable @keyup.enter="handleQuery" />
<el-form-item label="房号" prop="houseName">
<el-input v-model="queryParams.houseName" placeholder="请输入" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" @click="handleQuery">搜索</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
@@ -35,24 +35,41 @@
<el-card class="flex-1" shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<!-- <el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleMarkqrcode" v-hasPermi="['equipment:addqrcode:electricitydevice']"
>批量生成条形码</el-button
>
</el-col>
<el-col :span="1.5">
<!-- <el-button type="success" plain icon="Upload">批量更新固件</el-button> -->
<el-button type="success" plain icon="Upload">批量更新固件</el-button>
</el-col> -->
<el-col :span="1.5">
<div style="font-size: 0.8rem">电表列表</div>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
<right-toolbar :show-add="false" :show-edit="false" :show-delete="false">
<template #dropdown>
<!-- <el-dropdown-menu> -->
<el-dropdown-item @click="handleMarkqrcode" v-if="checkPermi(['equipment:addqrcode:electricitydevice'])">
<span>批量生成条形码</span>
</el-dropdown-item>
<!-- </el-dropdown-menu> -->
<!-- <el-dropdown-item v-hasPermi="['equipment:addqrcode:electricitydevice']">
<div @click="handleMarkqrcode">批量更新固件</div>
</el-dropdown-item> -->
</template>
</right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" border :data="ElectricityDeviceList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="电表设备编码" width="250" align="center" prop="deviceCode" />
<el-table-column label="设备编码" width="250" align="center" prop="deviceCode" />
<el-table-column label="设备状态" width="100" align="center" prop="status">
<template #default="scope">
<dict-tag :options="com_waterdevice_on_status" :value="scope.row.status"></dict-tag>
<div class="readRecord" v-if="scope.row.status">
<DictTag :options="com_waterdevice_on_status" :value="scope.row.status"></DictTag>
</div>
<span v-else>---</span>
</template>
</el-table-column>
<el-table-column label="分合状态" width="100" align="center">
@@ -60,23 +77,23 @@
<div class="readRecord" v-if="scope.row.waterRecord">
<DictTag :options="com_electricity_readrecord_status" :value="scope.row.waterRecord.status"></DictTag>
</div>
<span v-else>-----</span>
<span v-else>---</span>
</template>
</el-table-column>
<el-table-column label="房屋" align="center" prop="houseName" />
<el-table-column label="房屋" align="center" prop="houseName" />
<el-table-column label="余额" width="100" align="center" prop="elePrice">
<template #defaul="scope">
<span v-if="scope.row.electricityRecord">{{ scope.row.electricityRecord.balance }}</span>
<span v-else>-----</span>
<span v-else>---</span>
</template>
</el-table-column>
<el-table-column label="条码" width="250" align="center" prop="deleted">
<el-table-column label="条码" width="250" align="center" prop="deleted">
<template #default="scope">
<el-image
v-if="scope.row.url && scope.row.url.includes('http')"
:src="scope.row.url"
:preview-src-list="[scope.row.url]"
style="width: 90px; height: 30px; border-radius: 4px; margin-right: 5px"
style="width: 90%; height: 100%"
fit="cover"
preview-teleported
>
@@ -107,7 +124,7 @@
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
<template #default="scope">
<el-row>
<el-col :span="24" class="flex flex-items-center">
<el-col :span="24" class="flex flex-items-center actions">
<el-button link type="primary" @click="handleRecode(scope.row)" v-hasPermi="['equipment:view:electricitydevice']">充值记录</el-button>
<el-button link type="primary" @click="handleQrCode(scope.row)" v-hasPermi="['equipment:addqrcode:electricitydevice']"
>生成条码</el-button
@@ -127,7 +144,7 @@
type="primary"
@click="handleOpenDialog('UpdateHouse', scope.row)"
v-hasPermi="['equipment:edithouse:electricitydevice']"
>修改</el-button
>绑定房屋</el-button
>
<!-- <el-dropdown style="vertical-align: text-top">
<el-button link type="primary">
@@ -159,7 +176,7 @@
</el-card>
<!-- 添加或修改电 设备对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form v-if="dialogType === 'usedWater'" ref="UsedWaterformRef" :model="UsedWaterform" label-width="100px">
<el-form v-if="dialogType === 'usedWater'" :rules="rules" ref="UsedWaterformRef" :model="UsedWaterform" label-width="100px">
<el-form-item label="设备编号" prop="deviceCode"> {{ UsedWaterform.deviceCode }} </el-form-item>
<el-form-item label="开始时间" prop="startTime">
<el-date-picker
@@ -245,6 +262,7 @@ import {
import { ElectricityDeviceVO } from '@/api/system/SdbElectricityDevice/type';
import { useHouseStore } from '@/store/modules/house';
import { useUserStore } from '@/store/modules/user';
import { checkPermi } from '@/utils/permission';
import { Upload } from '@element-plus/icons-vue';
import { CascaderValue, tourEmits, UploadProps, UploadRawFile } from 'element-plus';
@@ -275,9 +293,9 @@ const data = reactive({
queryParams: {
pageNum: 1,
pageSize: 10,
deviceCode: undefined,
houseName: undefined,
status: undefined
deviceCode: '',
houseName: '',
status: ''
}
});
@@ -304,6 +322,10 @@ const UsedWaterInfo = ref({
startTime: '',
endTime: ''
});
const rules = {
startTime: [{ required: true, message: '请选择开始时间', trigger: 'blur' }],
endTime: [{ required: true, message: '请选择结束时间', trigger: 'blur' }]
};
// ! =======================================================================================
// ? 上传固件 ==============================================================================================
@@ -418,8 +440,8 @@ const handleOpenDialog = (type: 'usedWater' | 'Upload' | 'UpdateHouse', row: Ele
if (type === 'usedWater') {
UsedWaterform.value.deviceCode = row.deviceCode;
UsedWaterform.value.startTime = new Date().toLocaleString();
UsedWaterform.value.endTime = new Date().toLocaleString();
UsedWaterform.value.startTime = '';
UsedWaterform.value.endTime = '';
usedWaterInfo.value = true;
} else if (type === 'Upload') {
UploadFileform.value.file = '';
@@ -447,6 +469,10 @@ const handleChangeWater = (val: string, row: ElectricityDeviceVO) => {};
/** 提交按钮 */
const submitForm = () => {
if (dialogType.value === 'usedWater') {
if (UsedWaterform.value.startTime === '' || UsedWaterform.value.endTime === '') {
ElMessage.warning('请选择时间');
return;
}
UsedWaterformRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
@@ -552,6 +578,21 @@ const download = (url: string) => {
</script>
<style lang="scss" scoped>
.actions {
:deep(.el-button > span) {
font-weight: 650;
}
}
:deep(.waterDevice_online) {
color: #3dd4a7;
background: transparent;
border: none;
}
:deep(.waterDevice_offline) {
color: #ee1c25;
background: transparent;
border: none;
}
.el-table {
height: calc(100% - 80px);
}

View File

@@ -3,9 +3,9 @@
<pageheader></pageheader>
<el-card class="flex-1 mt-10px" shadow="never">
<template #header>
<el-row :gutter="10" style="font-size: 0.8rem">
<el-row :gutter="10" style="font-size: 0.8rem; font-weight: 450">
<el-col :span="4"> 设备号 {{ routeid }} </el-col>
<el-col :span="4"> {{ housename }} </el-col>
<el-col :span="4"> {{ housename }} </el-col>
<el-col :span="14"></el-col>
<el-col :span="2">
<el-button @click="confinem">返回</el-button>

View File

@@ -4,7 +4,7 @@
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" label-width="100px" :model="queryParams" :inline="true">
<el-form ref="queryFormRef" label-width="100px" @submit.prevent="handleQuery" :model="queryParams" :inline="true">
<!-- <el-form-item label="设备状态" prop="eleStatus">
<el-select v-model="queryParams.eleStatus">
<el-option v-for="(item, index) in com_waterdevice_on_status" :key="index" :label="item.label" :value="item.value"></el-option>
@@ -15,12 +15,12 @@
<el-option v-for="(item, index) in com_water_readrecord_status" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item> -->
<el-form-item label="房间号" prop="houseName">
<el-input v-model="queryParams.houseName" placeholder="请输入房间号" clearable @keyup.enter="handleQuery" />
<el-form-item label="房" prop="houseName">
<el-input v-model="queryParams.houseName" placeholder="请输入" clearable />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" @click="handleQuery">搜索</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
@@ -29,42 +29,46 @@
<el-card class="flex-1" shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-row :gutter="10" class="mb8 flex-items-center">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleMarkqrcode" v-hasPermi="['equipment:addqrcode:waterdevice']"
>批量生成条形码</el-button
>
<div style="font-size: 0.8rem">水表列表</div>
</el-col>
<el-col :span="1.5">
<!-- <el-button type="success" plain icon="Upload">批量更新固件</el-button> -->
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
<right-toolbar :show-add="false" :show-edit="false" :show-delete="false">
<template #dropdown>
<el-dropdown-item @click="handleMarkqrcode" v-if="checkPermi(['equipment:addqrcode:waterdevice'])">
<span>批量生成条形码</span>
</el-dropdown-item>
<!-- <el-dropdown-item v-hasPermi="['equipment:addqrcode:electricitydevice']">
<div @click="handleMarkqrcode">批量更新固件</div>
</el-dropdown-item> -->
</template>
</right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" border :data="waterDeviceList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="水表设备编码" width="250" align="center" prop="deviceCode" />
<el-table-column label="设备编码" width="250" align="center" prop="deviceCode" />
<el-table-column label="设备状态" width="100" align="center" prop="eleStatus">
<template #default="scope">
<dict-tag v-if="scope.row.waterRecord" :options="com_waterdevice_on_status" :value="scope.row.waterRecord.eleStatus"></dict-tag>
<span v-else>-------</span>
<span v-else>---</span>
</template>
</el-table-column>
<el-table-column label="分合状态" width="100" align="center">
<template #default="scope">
<dict-tag v-if="scope.row.status" :options="com_electricity_readrecord_status" :value="scope.row.waterRecord.status"></dict-tag>
<span v-else>-------</span>
<dict-tag v-if="scope.row.status" :options="com_water_readrecord_status" :value="scope.row.waterRecord.status"></dict-tag>
<span v-else>---</span>
</template>
</el-table-column>
<el-table-column label="房屋" align="center" prop="houseName" />
<el-table-column label="余额" width="120" align="center" prop="deviceCode">
<template #default="scope">
<span v-if="scope.row.waterRecord">{{ scope.row.waterRecord.balance }}</span>
<span v-else>------</span>
<span v-else>---</span>
</template>
</el-table-column>
<el-table-column label="条码" width="250" align="center">
<el-table-column label="条码" width="250" align="center">
<template #default="scope">
<el-image
v-if="scope.row.url && scope.row.url.includes('http')"
@@ -83,7 +87,7 @@
</el-table-column>
<el-table-column label="抄表时间" align="center">
<template #default="scope">
<span>{{ scope.row.waterRecord ? scope.row.waterRecord.readTime : '--' }}</span>
<span>{{ scope.row.waterRecord ? scope.row.waterRecord.readTime : '---' }}</span>
</template>
</el-table-column>
<!-- <el-table-column width="150" label="启停" align="center" prop="deleted" v-hasPermi="['equipment:isUse:waterdevice']">
@@ -101,9 +105,16 @@
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
<template #default="scope">
<el-row>
<el-col :span="24" class="flex flex-items-center">
<el-col :span="24" class="flex flex-items-center actions">
<el-button link type="primary" @click="handleRecode(scope.row)" v-hasPermi="['equipment:view:waterdevice']">充值记录</el-button>
<el-button link type="primary" @click="handleQrCode(scope.row)" v-hasPermi="['equipment:addqrcode:waterdevice']">生成条码</el-button>
<el-button
link
type="primary"
:loading="loadingQRCode.includes(scope.row.id)"
@click="handleQrCode(scope.row)"
v-hasPermi="['equipment:addqrcode:waterdevice']"
>生成条码</el-button
>
<el-button link type="primary" @click="handleOpenDialog('usedWater', scope.row)" v-hasPermi="['equipment:useWater:waterdevice']"
>用水量</el-button
>
@@ -144,7 +155,7 @@
<!-- 添加或修改水 设备对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<!-- water -->
<el-form v-if="dialogType === 'usedWater'" ref="UsedWaterformRef" :model="UsedWaterform" label-width="100px">
<el-form v-if="dialogType === 'usedWater'" :rules="rules" ref="UsedWaterformRef" :model="UsedWaterform" label-width="100px">
<el-form-item label="设备编号" prop="deviceCode"> {{ UsedWaterform.deviceCode }} </el-form-item>
<el-form-item label="开始时间" prop="startTime">
<el-date-picker
@@ -260,6 +271,7 @@ import { getHousePathById } from '@/utils/house';
import { Upload } from '@element-plus/icons-vue';
import { CascaderValue, tourEmits, UploadProps, UploadRawFile } from 'element-plus';
import { formatDate } from '@/utils/time';
import { checkPermi } from '@/utils/permission';
const huhao = 3096371295;
const uploadAUrl = import.meta.env.VITE_APP_BASE_API + '/waterDevice/uploadA';
@@ -267,7 +279,7 @@ const uploadBUrl = import.meta.env.VITE_APP_BASE_API + '/waterDevice/uploadB';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_waterdevice_on_status } = toRefs<any>(proxy?.useDict('com_waterdevice_on_status'));
const { com_electricity_readrecord_status } = toRefs<any>(proxy?.useDict('com_electricity_readrecord_status'));
const { com_water_readrecord_status } = toRefs<any>(proxy?.useDict('com_water_readrecord_status'));
const waterDeviceList = ref<WaterDeviceVO[]>([]);
const buttonLoading = ref(false);
@@ -318,6 +330,10 @@ const UsedWaterInfo = ref({
startTime: '',
endTime: ''
});
const rules = {
startTime: [{ required: true, message: '请选择开始时间', trigger: 'blur' }],
endTime: [{ required: true, message: '请选择结束时间', trigger: 'blur' }]
};
// ! =======================================================================================
// ? 上传固件 ==============================================================================================
@@ -383,7 +399,7 @@ const EditHouseform = ref({
/** 批量生成 条形码 */
function handleMarkqrcode() {
if (ids.value.length > 0) {
WaterDeviceMakerQrcode(ids.value).then((res) => {
WaterDeviceMakerQrcode(ids.value).then(() => {
ElMessage.success('批量生成成功');
getList();
});
@@ -403,18 +419,23 @@ const handleSelectionChange = (selection: WaterDeviceVO[]) => {
multiple.value = !selection.length;
};
const loadingQRCode = ref([]);
/** 生成二维码 */
const handleQrCode = (row: WaterDeviceVO) => {
// 1.电表 2.水表
WaterDeviceMakerQrcode([
{
id: row.id,
deviceCode: row.deviceCode
}
]).then(() => {
ElMessage.success('生成成功');
getList();
});
loadingQRCode.value.push(row.id);
setTimeout(() => {
// 1.电表 2.水表
WaterDeviceMakerQrcode([
{
id: row.id,
deviceCode: row.deviceCode
}
]).then(() => {
ElMessage.success('生成成功');
loadingQRCode.value = loadingQRCode.value.filter((item) => item !== row.id);
getList();
});
}, 1000);
};
// * house
const treedata = ref([]);
@@ -444,7 +465,7 @@ const handleOpenDialog = (type: 'usedWater' | 'Upload' | 'UpdateHouse', row: Wat
}
dialog.visible = true;
dialogType.value = type;
dialog.title = type === 'usedWater' ? '用水量' : type === 'UpdateHouse' ? '编辑户号' : '更新固件';
dialog.title = type === 'usedWater' ? '用水量查询' : type === 'UpdateHouse' ? '编辑户号' : '更新固件';
};
function getTree() {
@@ -461,6 +482,10 @@ const handleChangeWater = (val: string, row: WaterDeviceVO) => {};
/** 提交按钮 */
const submitForm = () => {
if (dialogType.value === 'usedWater') {
if (UsedWaterform.value.startTime === '' || UsedWaterform.value.endTime === '') {
ElMessage.warning('请选择时间');
return;
}
UsedWaterformRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
@@ -570,6 +595,12 @@ const download = (url: string) => {
</script>
<style lang="scss" scoped>
.actions {
:deep(.el-button > span) {
font-weight: 650;
}
}
.example-showcase .el-dropdown + .el-dropdown {
margin-left: 15px;
}
@@ -581,6 +612,16 @@ const download = (url: string) => {
}
.el-table {
height: calc(100% - 80px);
:deep(.waterDevice_online) {
color: #3dd4a7;
background: transparent;
border: none;
}
:deep(.waterDevice_offline) {
color: #ee1c25;
background: transparent;
border: none;
}
}
.usedWaterbox {

View File

@@ -3,7 +3,7 @@
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form ref="queryFormRef" :model="queryParams" @submit.prevent="handleQuery" :inline="true">
<el-form-item label="总用电量" prop="totalEnergy">
<el-input v-model="queryParams.totalEnergy" placeholder="请输入总用电量" clearable @keyup.enter="handleQuery" />
</el-form-item>
@@ -14,8 +14,8 @@
<el-input v-model="queryParams.balance" placeholder="请输入当前余额" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" @click="handleQuery">搜索</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
@@ -41,7 +41,7 @@
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['waterRecord:waterRecord:export']">导出</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
<right-toolbar></right-toolbar>
</el-row>
</template>