8/25 dev bug

This commit is contained in:
Zy
2026-08-25 17:18:28 +08:00
parent 981d059ceb
commit b83735e993
37 changed files with 505 additions and 302 deletions

View File

@@ -106,7 +106,7 @@ export interface HouseRentalForm extends BaseEntity {
houseImageUrl: string; //房屋图片 houseImageUrl: string; //房屋图片
supInfo: string; //补充租房信息 supInfo: string; //补充租房信息
vx: string; //微信 vx: string; //微信
houseUse: string; //房屋用途 houseUse?: string; //房屋用途
rentalStatus: number; //租赁状态 rentalStatus: number; //租赁状态
buildingId: string; //楼栋id buildingId: string; //楼栋id
unitNoId: string; //单元id unitNoId: string; //单元id

View File

@@ -1,10 +1,18 @@
import request from '@/utils/request'; import request from '@/utils/request';
import { Response } from '@/api/system/report/dailyFeeReport/type'; import { FilterResponse, Response } from '@/api/system/report/dailyFeeReport/type';
export const getDailyFeeReportList = (data = {}): Promise<Response> => { export const getDailyFeeReportList = (data = {}): Promise<Response> => {
return request({ return request({
url: '/dailyFeeReport/list', url: '/dailyFeeReport/list',
method: 'GET', method: 'POST',
params: data data: data
});
};
// 获取动态查询数据
export const getDailyFeeReportDynamicList = (data = {}): Promise<FilterResponse> => {
return request({
url: '/dailyFeeReport/filters',
method: 'GET',
data: data
}); });
}; };

View File

@@ -33,3 +33,16 @@ export type ChargeTypeAmounts = {
startDate?: string; startDate?: string;
}; };
}; };
export type FilterResponse = {
code: number;
data: {
'field': string;
'label': string;
'type': string;
'placeholder': string;
'chargeTypeName': null;
'subField': null;
}[];
msg: string;
};

View File

@@ -7,7 +7,6 @@ import { ResidentVO, ResidentForm, ResidentQuery } from '@/api/system/residentRe
* @param query * @param query
* @returns {*} * @returns {*}
*/ */
export const listResident = (query?: ResidentQuery | {}): AxiosPromise<ResidentVO[]> => { export const listResident = (query?: ResidentQuery | {}): AxiosPromise<ResidentVO[]> => {
return request({ return request({
url: '/resident/list', url: '/resident/list',

View File

@@ -18,12 +18,12 @@ export interface ResidentVO {
nickName: string; nickName: string;
/** /**
* 0业主 1租户 * 0 业主 1 租户
*/ */
type: string; type: string;
/** /**
* 0 男性 1女性 * 0 男性 1 女性
*/ */
gender: string; gender: string;
@@ -104,15 +104,15 @@ export interface ResidentForm extends BaseEntity {
name?: string; name?: string;
/** /**
* 0业主 * 0 业主
* 1亲属 * 1 亲属
* 2租户 * 2 租户
* 3朋友 * 3 朋友
*/ */
ownerRelationship?: string; ownerRelationship?: string;
/** /**
* 0 男性 1女性 * 0 男性 1 女性
*/ */
gender?: string; gender?: string;

View File

@@ -63,10 +63,10 @@ export const delVersion = (id: string | number | Array<string | number>) => {
}; };
/** 获取过往版本 */ /** 获取过往版本 */
export const getPastVersion = (platform: string, appChannel: string, channel: string = 'xiaomi') => { export const getPastVersion = (platform: string, appChannel: string) => {
return request({ return request({
url: `/api/app/getPastVersion?platform=${platform}&appChannel=${appChannel}&channel=${channel}`, url: `/api/app/getPastVersion?platform=${platform}&appChannel=${appChannel}`,
method: 'get' method: 'get',
}); });
}; };
/** 切换版本启停 */ /** 切换版本启停 */

View File

@@ -373,6 +373,12 @@ onUnmounted(() => {
width: 40px; width: 40px;
font-size: 12px; font-size: 12px;
} }
:deep(.ql-snow .ql-editor) {
white-space: pre-wrap;
/* 允许在数字内部断开,消除“整串数字集体跳下一行” */
word-break: break-all;
overflow-wrap: break-word;
}
:deep(.ql-snow .ql-toolbar button.ql-file::before) { :deep(.ql-snow .ql-toolbar button.ql-file::before) {
all: unset !important; all: unset !important;
content: '附件'; content: '附件';
@@ -385,6 +391,7 @@ onUnmounted(() => {
.editor { .editor {
max-width: 800px; max-width: 800px;
} }
.editor, .editor,
.ql-toolbar { .ql-toolbar {
white-space: pre-wrap !important; white-space: pre-wrap !important;

View File

@@ -11,19 +11,23 @@
</div> </div>
</div> </div>
<el-dialog @close="conback" append-to-body v-model="dialog.dialogVisible" :title="dialog.dialogTitle" width="1050"> <el-dialog @close="conBack" append-to-body v-model="dialog.dialogVisible" :title="dialog.dialogTitle" width="1050">
<nav class="flex flex-items-center mb-8" style="margin-bottom: 20px"> <nav class="flex flex-items-center mb-8" style="margin-bottom: 20px">
<div class="flex flex-items-center flex-1" style="max-width: 200px"> <!-- <div class="flex flex-items-center flex-1" style="max-width: 200px">-->
<div style="width: 120px">住户类型</div> <!-- <div style="width: 120px">住户类型</div>-->
<el-select v-model="queryParams.ownerRelationship" placeholder="请选择" clearable> <!-- <el-select v-model="queryParams.ownerRelationship" placeholder="请选择" clearable>-->
<el-option v-for="dict in com_resident_relationship" :key="dict.value" :label="dict.label" :value="dict.value" /> <!-- <el-option v-for="dict in com_resident_relationship" :key="dict.value" :label="dict.label" :value="dict.value" />-->
</el-select> <!-- </el-select>-->
</div> <!-- </div>-->
<div class="mr-5 flex-1" style="margin: 0 20px"> <!-- <div class="mr-5 flex-1" style="margin: 0 20px">-->
<!-- <el-input maxlength="30" clearable v-model="queryParams.name" placeholder="请输入住户姓名" />-->
<!-- </div>-->
<div class="flex flex-items-center flex-1" style="max-width: 300px; margin: 0 20px">
<div style="width: 120px">住户姓名</div>
<el-input maxlength="30" clearable v-model="queryParams.name" placeholder="请输入住户姓名" /> <el-input maxlength="30" clearable v-model="queryParams.name" placeholder="请输入住户姓名" />
</div> </div>
<div> <div>
<el-button type="primary" @click="getlist">查询</el-button> <el-button type="primary" @click="getList">查询</el-button>
<el-button @click="resetQuery">重置</el-button> <el-button @click="resetQuery">重置</el-button>
</div> </div>
</nav> </nav>
@@ -64,10 +68,10 @@
:total="total" :total="total"
v-model:page="queryParams.pageNum" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" v-model:limit="queryParams.pageSize"
@pagination="getlist" @pagination="getList"
/> />
<div> <div>
<el-button @click="conback">退出</el-button> <el-button @click="conBack">退出</el-button>
<el-button type="primary" @click="confirm">确定</el-button> <el-button type="primary" @click="confirm">确定</el-button>
</div> </div>
</div> </div>
@@ -77,19 +81,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { listResident } from '@/api/system/residentReviewProcess/resident'; import { listResident } from '@/api/system/residentReviewProcess/resident';
import { ResidentVO } from '@/api/system/residentReviewProcess/resident/type'; import { ResidentQuery, ResidentVO } from '@/api/system/residentReviewProcess/resident/type';
import { ref, nextTick, getCurrentInstance, ComponentInternalInstance, toRefs } from 'vue'; import { ref, nextTick, getCurrentInstance, ComponentInternalInstance, toRefs } from 'vue';
import { useHouseStore } from '@/store/modules/house';
const houseStore = useHouseStore();
const treedata = ref([]);
function init() {
houseStore.getCurrentVilageTreeHouse().then((res) => {
treedata.value = res;
});
}
init();
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_resident_type } = toRefs<any>(proxy?.useDict('com_resident_type')); const { com_resident_type } = toRefs<any>(proxy?.useDict('com_resident_type'));
@@ -198,7 +191,7 @@ const handleUserSelection = () => {
if (isMultiple.value && Array.isArray(props.userid)) { if (isMultiple.value && Array.isArray(props.userid)) {
// 多选回显 // 多选回显
const selectedItems: tableType[] = []; const selectedItems: tableType[] = [];
props.userid.forEach((id) => { props.userid.forEach((id: string | number) => {
const findItem = tableData.value.find((item) => item.id == id || item.userId == id); const findItem = tableData.value.find((item) => item.id == id || item.userId == id);
if (findItem) { if (findItem) {
selectedItems.push(findItem); selectedItems.push(findItem);
@@ -222,12 +215,12 @@ const handleUserSelection = () => {
// 打开选择框 // 打开选择框
function choiceResidentFun() { function choiceResidentFun() {
// 初始化 // 初始化
getlist(); getList();
dialog.value.dialogVisible = true; dialog.value.dialogVisible = true;
} }
// 获取列表 // 获取列表
function getlist() { function getList() {
loading.value = true; loading.value = true;
listResident(queryParams.value) listResident(queryParams.value)
.then((res) => { .then((res) => {
@@ -253,11 +246,11 @@ function resetQuery() {
buildingId: null, buildingId: null,
unitNo: null unitNo: null
}; };
getlist(); getList();
} }
// 退出 // 退出
function conback() { function conBack() {
dialog.value.dialogVisible = false; dialog.value.dialogVisible = false;
resetQuery(); resetQuery();
} }
@@ -297,7 +290,7 @@ function confirm() {
} }
defineExpose({ defineExpose({
open: (arr) => { open: (arr?: string[], params: ResidentQuery | {} = {}) => {
if (arr && arr.length > 0) { if (arr && arr.length > 0) {
multipleSelection.value = arr.map((id) => ({ multipleSelection.value = arr.map((id) => ({
id: id id: id
@@ -305,7 +298,12 @@ defineExpose({
} else { } else {
multipleSelection.value = []; multipleSelection.value = [];
} }
getlist(); queryParams.value = {
...queryParams.value,
...params
};
console.log(queryParams.value);
getList();
dialog.value.dialogVisible = true; dialog.value.dialogVisible = true;
} }
}); });

View File

@@ -36,8 +36,15 @@
<el-button @click="resetQuery">重置</el-button> <el-button @click="resetQuery">重置</el-button>
</div> </div>
</nav> </nav>
<el-table ref="multipleTableRef" :data="tableData" border @selection-change="handleSelectionChange"> <el-table v-loading="loading" ref="multipleTableRef" :data="tableData" border>
<el-table-column type="selection" width="55" align="center" /> <el-table-column width="55" align="center">
<template #header>
<el-checkbox v-model="isSelectAll" :indeterminate="isIndeterminate" @change="handleSelectAllChange" />
</template>
<template #default="scope">
<el-checkbox :model-value="isRowSelected(scope.row)" @change="(val: boolean) => handleRowCheckChange(scope.row, val)" />
</template>
</el-table-column>
<el-table-column label="序号" align="center" width="55" type="index" /> <el-table-column label="序号" align="center" width="55" type="index" />
<el-table-column label="楼栋号" align="center"> <el-table-column label="楼栋号" align="center">
<template #default="scope"> <template #default="scope">
@@ -70,7 +77,7 @@
<div class="dialog-footer flex flex-items-center flex-justify-between"> <div class="dialog-footer flex flex-items-center flex-justify-between">
<pagination <pagination
style="margin-top: 0" style="margin-top: 0"
layout="total, prev, pager, next, jumper" layout="sizes, prev, pager, next, jumper"
v-show="total > 0" v-show="total > 0"
:total="total" :total="total"
v-model:page="queryParams.pageNum" v-model:page="queryParams.pageNum"
@@ -79,7 +86,7 @@
/> />
<div> <div>
<el-button @click="conback">退出</el-button> <el-button @click="conback">退出</el-button>
<el-button type="primary" @click="confirm"> 确定 </el-button> <el-button type="primary" @click="confirm" :loading="loading"> 确定 </el-button>
</div> </div>
</div> </div>
</template> </template>
@@ -89,7 +96,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { getBuildinglistAPI, getHouselistAPI } from '@/api/system/house'; import { getBuildinglistAPI, getHouselistAPI } from '@/api/system/house';
import { BillUserlist, queryResidentList_holder } from '@/api/system/SdbBill'; import { BillUserlist, queryResidentList_holder } from '@/api/system/SdbBill';
import { ref, nextTick, getCurrentInstance, ComponentInternalInstance, toRefs } from 'vue'; import { ComponentInternalInstance, getCurrentInstance, ref, toRefs } from 'vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { sys_user_sex } = toRefs<any>(proxy?.useDict('sys_user_sex')); const { sys_user_sex } = toRefs<any>(proxy?.useDict('sys_user_sex'));
@@ -125,7 +132,7 @@ const dialog = ref({
const queryParams = ref({ const queryParams = ref({
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 5,
buildingId: null, buildingId: null,
residentName: null, residentName: null,
@@ -137,53 +144,104 @@ const multipleTableRef = ref();
const tableData = ref<BillUserlist[]>([]); const tableData = ref<BillUserlist[]>([]);
const total = ref(0); const total = ref(0);
const loading = ref(false); const loading = ref(false);
const isFetching = ref(false); /** 存储所有选中项(跨页累计,非全选模式使用) */
// 存储选中项
const multipleSelection = ref<BillUserlist[]>([]); const multipleSelection = ref<BillUserlist[]>([]);
/** 是否已跨页全选(标记模式,不实际持有全部数据) */
const isSelectAll = ref(false);
/** 表头复选框半选状态(部分选中时为 true */
const isIndeterminate = ref(false);
/** 全选模式下被手动取消勾选的 residentId 列表 */
const deselectedIds = ref<string[]>([]);
const isMultiple = computed(() => props.isMultiple ?? false); const isMultiple = computed(() => props.isMultiple ?? false);
// 优化 handleUserSelection避免重复查找 /** 判断某行是否已选中 */
const handleUserSelection = () => { function isRowSelected(row: BillUserlist): boolean {
isFetching.value = true; if (isSelectAll.value) {
if (!multipleTableRef.value || !tableData.value.length) { // 全选模式:只要不在取消列表中就算选中
isFetching.value = false; return !deselectedIds.value.includes(row.residentId);
}
return multipleSelection.value.some((item) => item.residentId === row.residentId);
}
/** 更新表头复选框状态:全选 / 半选 / 空 */
function updateIndeterminate() {
if (isSelectAll.value) {
// 全选模式下:有取消勾选的行 → 半选,否则 → 全选
isIndeterminate.value = deselectedIds.value.length > 0;
return; return;
} }
const rowsToSelect = tableData.value.filter((row) => {
return multipleSelection.value.some((selected) => selected.residentId === row.residentId); const selectedCount = multipleSelection.value.length;
}); const totalCount = total.value;
multipleTableRef.value.clearSelection();
if (rowsToSelect.length > 0) { if (selectedCount === 0) {
nextTick(() => { isIndeterminate.value = false;
rowsToSelect.forEach((row) => { } else if (totalCount > 0 && selectedCount >= totalCount) {
multipleTableRef.value?.toggleRowSelection(row, true); // 手动逐行全选 → 切换为全选标记模式,释放 multipleSelection 内存
}); isSelectAll.value = true;
isFetching.value = false; isIndeterminate.value = false;
}); deselectedIds.value = [];
multipleSelection.value = [];
} else { } else {
isFetching.value = false; isIndeterminate.value = true;
} }
}; }
/** 跨页全选 / 取消全选(仅设标记,不拉取数据) */
function handleSelectAllChange(val: boolean) {
if (val) {
isSelectAll.value = true;
deselectedIds.value = [];
multipleSelection.value = [];
} else {
isSelectAll.value = false;
deselectedIds.value = [];
multipleSelection.value = [];
}
updateIndeterminate();
}
/** 单行勾选 / 取消勾选 */
function handleRowCheckChange(row: BillUserlist, checked: boolean) {
if (isSelectAll.value) {
// 全选模式:维护取消列表
if (checked) {
deselectedIds.value = deselectedIds.value.filter((id) => id !== row.residentId);
} else {
if (!deselectedIds.value.includes(row.residentId)) {
deselectedIds.value.push(row.residentId);
}
}
} else {
// 非全选模式:维护选中列表
if (checked) {
if (!isRowSelected(row)) {
multipleSelection.value.push(row);
}
} else {
multipleSelection.value = multipleSelection.value.filter((item) => item.residentId !== row.residentId);
}
}
updateIndeterminate();
}
// ====================== 方法 ====================== // ====================== 方法 ======================
// 获取列表 // 获取列表
function getList() { function getList() {
isFetching.value = true; // 加锁
loading.value = true; loading.value = true;
queryResidentList_holder(queryParams.value) queryResidentList_holder(queryParams.value)
.then((res) => { .then((res) => {
tableData.value = res.rows; tableData.value = res.rows;
total.value = res.total; total.value = res.total;
handleUserSelection(); updateIndeterminate();
}) })
.catch((error) => { .catch((error) => {
console.error('获取用户列表失败:', error); console.error('获取用户列表失败:', error);
}) })
.finally(() => { .finally(() => {
loading.value = false; loading.value = false;
isFetching.value = false; // 加锁
}); });
} }
@@ -215,37 +273,6 @@ function handleChangeBuilding(val: string) {
function handleChangeUnit() { function handleChangeUnit() {
getList(); getList();
} }
// ==============================================
// ✅ 新增:处理 selection-change多选专用
// ==============================================
function handleSelectionChange(selection: BillUserlist[]) {
if (isFetching.value) return;
if (isMultiple.value) {
const currentSelectedIds = new Set(selection.map((item) => item.residentId));
const otherPageSelections = multipleSelection.value.filter((item) => {
const isCurrentPageItem = tableData.value.some((row) => row.residentId === item.residentId);
if (isCurrentPageItem) {
return currentSelectedIds.has(item.residentId);
} else {
return true;
}
});
// 3. 合并:其他页保留的 + 当前页新选中的
const finalSelection = [...otherPageSelections, ...selection];
// 4. 去重(以防万一)
const uniqueMap = new Map();
finalSelection.forEach((item) => uniqueMap.set(item.residentId, item));
multipleSelection.value = Array.from(uniqueMap.values());
console.log(multipleSelection.value.map((item) => item.residentId));
} else {
// --- 单选逻辑 ---
if (selection.length > 0) {
multipleSelection.value = [selection[selection.length - 1]];
} else {
multipleSelection.value = [];
}
}
}
// 重置查询 // 重置查询
function resetQuery() { function resetQuery() {
queryParams.value = { queryParams.value = {
@@ -256,6 +283,7 @@ function resetQuery() {
residentName: null, residentName: null,
houseNo: null houseNo: null
}; };
resetSelection();
getList(); getList();
} }
@@ -265,41 +293,82 @@ function conback() {
resetQuery(); resetQuery();
} }
// ============================================== /** 重置所有选中状态 */
// ✅ 核心修改:根据 returnvalue 返回对应的值 function resetSelection() {
// ============================================== multipleSelection.value = [];
function confirm() { isSelectAll.value = false;
dialog.value.dialogVisible = false; isIndeterminate.value = false;
deselectedIds.value = [];
}
/** 根据 returnvalue 发射选中结果 */
function emitResult(data: BillUserlist[]) {
if (isMultiple.value) { if (isMultiple.value) {
// 多选
if (returnvalue.value === '*') { if (returnvalue.value === '*') {
// ✅ 返回整个对象数组 emit('change', data);
emit('change', multipleSelection.value);
} else { } else {
// 返回指定字段数组
emit( emit(
'change', 'change',
multipleSelection.value.map((item) => item[returnvalue.value as keyof BillUserlist]) data.map((item) => item[returnvalue.value as keyof BillUserlist])
); );
} }
} else { } else {
// 单选
if (returnvalue.value === '*') { if (returnvalue.value === '*') {
// ✅ 返回整个对象 emit('change', data[0]);
emit('change', multipleSelection.value[0]);
} else { } else {
// 返回指定字段 emit('change', data[0]?.[returnvalue.value as keyof BillUserlist]);
emit('change', multipleSelection.value[0][returnvalue.value as keyof BillUserlist]);
} }
} }
}
/** 确定:全选模式下按需拉取全部数据,非全选模式直接使用已选列表 */
async function confirm() {
if (isSelectAll.value) {
// 全选模式:此时才真正拉取全部数据,排除已取消勾选的行
loading.value = true;
try {
const res = await queryResidentList_holder({
...queryParams.value,
pageNum: 1,
pageSize: total.value || undefined
});
const allData: BillUserlist[] = res.rows || [];
const filteredData = allData.filter((item) => !deselectedIds.value.includes(item.residentId));
dialog.value.dialogVisible = false;
emitResult(filteredData);
} catch (error) {
console.error('获取全部数据失败:', error);
} finally {
loading.value = false;
}
} else {
// 非全选模式:直接使用已收集的选中列表
dialog.value.dialogVisible = false;
emitResult(multipleSelection.value);
}
multipleSelection.value = []; resetSelection();
multipleTableRef.value.clearSelection();
} }
defineExpose({ defineExpose({
open: (arr: string[] = []) => { open: (arr: string[] = []) => {
userid.value = arr; userid.value = arr;
// 重置查询条件,避免残留上次的筛选条件
queryParams.value = {
pageNum: 1,
pageSize: 10,
buildingId: null,
residentName: null,
houseNo: null,
unitNoId: null
};
// 立即清空旧列表数据,避免闪烁
tableData.value = [];
total.value = 0;
// 重置全选标记
isSelectAll.value = false;
deselectedIds.value = [];
// 根据传入的 ID 数组初始化选中状态
if (arr && arr.length > 0) { if (arr && arr.length > 0) {
multipleSelection.value = arr.map( multipleSelection.value = arr.map(
(id) => (id) =>
@@ -307,8 +376,10 @@ defineExpose({
residentId: id residentId: id
}) as BillUserlist }) as BillUserlist
); );
isIndeterminate.value = true;
} else { } else {
multipleSelection.value = []; multipleSelection.value = [];
isIndeterminate.value = false;
} }
getList(); getList();

View File

@@ -2,8 +2,10 @@
<div class="top-right-btn" :style="style"> <div class="top-right-btn" :style="style">
<div class="flex items-center"> <div class="flex items-center">
<!-- 添加按钮 --> <!-- 添加按钮 -->
<el-button :disabled="props.disableAdd" v-if="props.showAdd" icon="Plus" type="primary" @click="toggleSearch()"> 新建 </el-button> <el-button :disabled="props.disableAdd" v-if="props.showAdd" icon="Plus" type="primary" @click="toggleSearch()">
{{ props.addTitle }}
</el-button>
<slot name="actions"></slot>
<!-- 批量操作下拉框 --> <!-- 批量操作下拉框 -->
<el-dropdown v-if="props.showDelete || props.showEdit || $slots.dropdown" trigger="click" style="margin-left: 10px"> <el-dropdown v-if="props.showDelete || props.showEdit || $slots.dropdown" trigger="click" style="margin-left: 10px">
<el-button @click.stop="refresh"> {{ props.moreTitle }} </el-button> <el-button @click.stop="refresh"> {{ props.moreTitle }} </el-button>
@@ -12,8 +14,12 @@
<template #dropdown> <template #dropdown>
<!-- 这里直接渲染不嵌套插槽 --> <!-- 这里直接渲染不嵌套插槽 -->
<el-dropdown-menu v-if="!$slots.dropdown"> <el-dropdown-menu v-if="!$slots.dropdown">
<el-dropdown-item :disabled="props.disableEdit" v-if="props.showEdit" @click="emits('update:edit')"> 编辑 </el-dropdown-item> <el-dropdown-item :disabled="props.disableEdit" v-if="props.showEdit" @click="emits('update:edit')">
<el-dropdown-item :disabled="props.disableDelete" v-if="props.showDelete" @click="emits('update:delete')"> 批量删除 </el-dropdown-item> {{ props.editTitle }}
</el-dropdown-item>
<el-dropdown-item :disabled="props.disableDelete" v-if="props.showDelete" @click="emits('update:delete')">
{{ props.deleteTitle }}
</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
<!-- 外部自定义内容直接渲染不包任何多余标签 --> <!-- 外部自定义内容直接渲染不包任何多余标签 -->
<template v-else> <template v-else>
@@ -58,6 +64,10 @@ const props = defineProps({
showDelete: propTypes.bool.def(true), showDelete: propTypes.bool.def(true),
showEdit: propTypes.bool.def(true), showEdit: propTypes.bool.def(true),
addTitle: propTypes.string.def('新建'),
editTitle: propTypes.string.def('编辑'),
deleteTitle: propTypes.string.def('批量删除'),
disableAdd: propTypes.bool.def(false), disableAdd: propTypes.bool.def(false),
disableDelete: propTypes.bool.def(false), disableDelete: propTypes.bool.def(false),
disableEdit: propTypes.bool.def(false) disableEdit: propTypes.bool.def(false)

0
src/enums/permission.ts Normal file
View File

View File

@@ -37,7 +37,7 @@
<el-dropdown-item divided command="changecommunity" v-if="isShow"> <el-dropdown-item divided command="changecommunity" v-if="isShow">
<span>{{ proxy.$t('navbar.community') }}</span> <span>{{ proxy.$t('navbar.community') }}</span>
</el-dropdown-item> </el-dropdown-item>
<router-link to="/system/user/profile" v-if="isShow"> <router-link to="/system/user/profile" v-if="isShow" v-has-permi="['system:user:profile']">
<el-dropdown-item>{{ proxy.$t('navbar.personalCenter') }}</el-dropdown-item> <el-dropdown-item>{{ proxy.$t('navbar.personalCenter') }}</el-dropdown-item>
</router-link> </router-link>
<el-dropdown-item :divided="isShow" command="logout"> <el-dropdown-item :divided="isShow" command="logout">

View File

@@ -479,6 +479,8 @@ const cancelForm = () => {
<style scoped lang="scss"> <style scoped lang="scss">
.box { .box {
background: #deedff; background: #deedff;
height: 100%;
overflow: hidden;
.header { .header {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@@ -19,7 +19,7 @@
:min-scale="0.2" :min-scale="0.2"
:preview-src-list="item.villageImageUrl ? item.villageImageUrl.split(',') : [defaultVilageinfoImage]" :preview-src-list="item.villageImageUrl ? item.villageImageUrl.split(',') : [defaultVilageinfoImage]"
show-progress show-progress
:initial-index="4" :initial-index="0"
fit="cover" fit="cover"
:src="item.villageImageUrl ? item.villageImageUrl.split(',')[0] : defaultVilageinfoImage" :src="item.villageImageUrl ? item.villageImageUrl.split(',')[0] : defaultVilageinfoImage"
> >

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="ResidentMainBox p-2 w-full"> <div class="ResidentMainBox p-2 w-full">
<PageHeader title="活动"></PageHeader> <PageHeader></PageHeader>
<div class="ResidentMainBody"> <div class="ResidentMainBody">
<el-card> <el-card>
<template #header> <template #header>
@@ -15,9 +15,31 @@
<el-input maxlength="30" v-model.trim="form.title" placeholder="请输入活动标题" /> <el-input maxlength="30" v-model.trim="form.title" placeholder="请输入活动标题" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- <el-col :span="11">-->
<!-- <el-form-item label="活动作者" prop="author">-->
<!-- <el-input maxlength="20" v-model.trim="form.author" placeholder="请输入活动作者" />-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<el-col :span="11"> <el-col :span="11">
<el-form-item label="活动作者" prop="author"> <el-form-item label="报名截止日期" prop="applyDeadline">
<el-input maxlength="20" v-model.trim="form.author" placeholder="请输入活动作者" /> <el-date-picker
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
v-model="deadline"
style="width: 100%"
:disabled-date="disabledDate"
@update:model-value="
(data) => {
if (data) {
form.applyDeadline = data;
} else {
form.applyDeadline = '';
}
}
"
type="datetime"
placeholder="请选择报名截止日期"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@@ -53,42 +75,43 @@
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="11"> <el-col :span="13">
<el-form-item label="报名截止日期" prop="applyDeadline"> <el-form-item label="签到时间" prop="signinStartTime">
<el-date-picker <el-date-picker
v-model="SigninTime"
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
v-model="deadline" @change="
:disabled-date="disabledDate" (data: string[] | null) => {
@update:model-value="
(data) => {
if (data) { if (data) {
form.applyDeadline = data; form.signinStartTime = data[0];
form.signinEndTime = data[1];
} else { } else {
form.applyDeadline = ''; form.signinStartTime = '';
form.signinEndTime = '';
} }
} }
" "
type="datetime" type="datetimerange"
placeholder="请选择报名截止日期" range-separator=""
start-placeholder="开始签到"
end-placeholder="结束签到"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <el-col :span="11">
<el-row>
<el-col :span="12">
<el-form-item label="主办方" prop="organizer"> <el-form-item label="主办方" prop="organizer">
<el-input maxlength="20" v-model.trim="form.organizer" placeholder="请输入主办方" /> <el-input maxlength="20" v-model.trim="form.organizer" placeholder="请输入主办方" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="13">
<el-form-item label="联系人" prop="contactName"> <el-form-item label="联系人" prop="contactName">
<el-input maxlength="20" v-model.trim="form.contactName" placeholder="请输入联系人" /> <el-input maxlength="20" v-model.trim="form.contactName" placeholder="请输入联系人" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="11">
<el-form-item label="联系方式" prop="contactPhone"> <el-form-item label="联系方式" prop="contactPhone">
<el-input maxlength="20" v-model.trim="form.contactPhone" placeholder="请输入联系方式" /> <el-input maxlength="20" v-model.trim="form.contactPhone" placeholder="请输入联系方式" />
</el-form-item> </el-form-item>
@@ -124,23 +147,18 @@
</el-upload> </el-upload>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> </el-row>
<el-form-item label="招募要求"> <el-row>
<el-input <el-col>
maxlength="200" <el-form-item label="招募要求" prop="requirements">
show-word-limit <editor v-model="form.requirements" :height="200" :min-height="200" :read-only="false" :file-size="5" :type="'url'" />
:row="8"
type="textarea"
v-model.trim="form.requirements"
placeholder="请输入招募要求"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col> <el-col>
<el-form-item label="活动详情" prop="content"> <el-form-item label="活动详情" prop="content">
<editor v-model="form.content" :height="500" :min-height="300" :read-only="false" :file-size="5" :type="'url'" /> <editor v-model="form.content" :height="300" :min-height="300" :read-only="false" :file-size="5" :type="'url'" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@@ -209,7 +227,7 @@
</el-col> </el-col>
</el-row> --> </el-row> -->
<el-form-item> <el-form-item>
<el-button type="warning" @click="submitForm('0')">保存为草稿</el-button> <!-- <el-button type="warning" @click="submitForm('0')">保存为草稿</el-button>-->
<el-button type="primary" @click="submitForm('1')">发布</el-button> <el-button type="primary" @click="submitForm('1')">发布</el-button>
<el-button @click="handleBack">返回</el-button> <el-button @click="handleBack">返回</el-button>
</el-form-item> </el-form-item>
@@ -293,6 +311,8 @@ const rules = {
applyDeadline: [{ required: true, message: '请输入报名截止日期', trigger: 'blur' }], applyDeadline: [{ required: true, message: '请输入报名截止日期', trigger: 'blur' }],
startTime: [{ required: true, message: '请选择开始日期', trigger: 'blur' }], startTime: [{ required: true, message: '请选择开始日期', trigger: 'blur' }],
endTime: [{ required: true, message: '请选择结束日期', trigger: 'blur' }], endTime: [{ required: true, message: '请选择结束日期', trigger: 'blur' }],
signinStartTime: [{ required: true, message: '请选择开始签到时间', trigger: 'blur' }],
signinEndTime: [{ required: true, message: '请选择结束签到时间', trigger: 'blur' }],
address: [{ required: true, message: '请输入活动地点', trigger: 'blur' }], address: [{ required: true, message: '请输入活动地点', trigger: 'blur' }],
organizer: [ organizer: [
{ required: true, message: '请输入主办方', trigger: 'blur' }, { required: true, message: '请输入主办方', trigger: 'blur' },

View File

@@ -33,7 +33,7 @@
<el-input v-model.trim="form.link" placeholder="请输入跳转链接" /> <el-input v-model.trim="form.link" placeholder="请输入跳转链接" />
</el-form-item> </el-form-item>
<el-form-item label="排序号" prop="byOrder"> <el-form-item label="排序号" prop="byOrder">
<el-input-number v-model.trim="form.byOrder" placeholder="请输入" /> <el-input-number :min="0" :max="9999" v-model.trim="form.byOrder" placeholder="请输入" />
</el-form-item> </el-form-item>
<el-form-item style="margin-top: 30px"> <el-form-item style="margin-top: 30px">
<el-button type="primary" @click="submitForm">提交</el-button> <el-button type="primary" @click="submitForm">提交</el-button>

View File

@@ -70,9 +70,9 @@
<span>属性配置</span> <span>属性配置</span>
</div> </div>
</template> </template>
<el-form style="position: sticky; top: 60px" label-width="80px"> <el-form :rules="rules" :model="activeQuestion" style="position: sticky; top: 60px" label-width="80px">
<el-form-item label="题目标题"> <el-form-item label="题目标题" prop="title">
<el-input maxlength="20" v-model.trim="activeQuestion.title" placeholder="请输入题目标题" /> <el-input maxlength="50" v-model.trim="activeQuestion.title" placeholder="请输入题目标题" />
</el-form-item> </el-form-item>
<el-form-item label="是否必填"> <el-form-item label="是否必填">
<el-switch v-model.trim="activeQuestion.required" /> <el-switch v-model.trim="activeQuestion.required" />
@@ -87,9 +87,13 @@
placeholder="选项内容" placeholder="选项内容"
style="width: 200px; margin-right: 10px; margin-bottom: 10px" style="width: 200px; margin-right: 10px; margin-bottom: 10px"
/> />
<el-button link type="danger" :icon="Delete" @click="activeQuestion.options.splice(idx, 1)"> 删除 </el-button> <el-button link type="danger" v-if="activeQuestion.options.length > 2" :icon="Delete" @click="activeQuestion.options.splice(idx, 1)">
删除
</el-button>
</div> </div>
<el-button type="primary" @click="activeQuestion.options.push({ label: '选项' })"> 添加选项 </el-button> <el-button type="primary" @click="activeQuestion.options.push({ label: '选项' + (activeQuestion.options.length + 1) })">
添加选项
</el-button>
</template> </template>
</el-form> </el-form>
</el-card> </el-card>
@@ -141,6 +145,10 @@ const form = ref<QuestionComponentnaireForm>({
content: [] content: []
}); });
const rules = ref({
title: [{ required: true, message: '请输入问卷标题', trigger: 'blur' }]
});
const activeIndex = ref<number>(-1); const activeIndex = ref<number>(-1);
// ==================== 计算属性 ==================== // ==================== 计算属性 ====================
@@ -190,10 +198,15 @@ function deleteQuestion(index: number): void {
// ==================== 业务方法 ==================== // ==================== 业务方法 ====================
/** 表单验证 */ /** 表单验证 */
function validateForm(): boolean { function validateForm(): boolean {
// 验证问卷标题
if (!form.value.title.trim()) { if (!form.value.title.trim()) {
ElMessage.error('请输入问卷标题'); ElMessage.error('请输入问卷标题');
return false; return false;
} }
if (form.value.content.some((item) => item.title === '')) {
ElMessage.error('请填写所有题目标题');
return false;
}
return true; return true;
} }

View File

@@ -6,12 +6,12 @@
<div class="addBuildingFormBody"> <div class="addBuildingFormBody">
<el-form class="formBody" label-position="right" ref="formRef" :model="form" :rules="rules" label-width="130px"> <el-form class="formBody" label-position="right" ref="formRef" :model="form" :rules="rules" label-width="130px">
<el-row> <el-row>
<el-col :span="11"> <el-col :span="11" v-if="type === 'private'">
<el-form-item label="关联房屋" prop="houseId"> <el-form-item label="关联房屋" prop="houseId">
<el-cascader v-model="form.houseId" :options="treedata" @change="handleChangeHouse" /> <el-cascader v-model="form.houseId" :options="treedata" @change="handleChangeHouse" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="2"></el-col> <el-col :span="2" v-if="type === 'private'"></el-col>
<el-col :span="11"> <el-col :span="11">
<el-form-item label="维修项目" prop="maintenanceItemId"> <el-form-item label="维修项目" prop="maintenanceItemId">
<el-cascader <el-cascader
@@ -27,13 +27,13 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <!-- <el-row>-->
<el-col :span="24"> <!-- <el-col :span="24">-->
<el-form-item label="报修标题" prop="item"> <!-- <el-form-item label="报修标题" prop="item">-->
<el-input maxlength="30" v-model.trim="form.item" placeholder="请输入报修标题" /> <!-- <el-input maxlength="30" v-model.trim="form.item" placeholder="请输入报修标题" />-->
</el-form-item> <!-- </el-form-item>-->
</el-col> <!-- </el-col>-->
</el-row> <!-- </el-row>-->
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="问题描述" prop="problem"> <el-form-item label="问题描述" prop="problem">
@@ -63,14 +63,20 @@
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="手机号码" prop="phone"> <el-form-item label="手机号码" prop="phone">
<el-input v-model.number="form.phone" placeholder="请输入手机号码" /> <el-input v-model.number.trim="form.phone" placeholder="请输入手机号码" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="预约日期" prop="orderDate"> <el-form-item label="预约日期" prop="orderDate">
<el-date-picker v-model="form.orderDate" type="datetime" placeholder="年/月/日 时:分:秒" value-format="YYYY-MM-DD HH:mm:ss" /> <el-date-picker
:disabled-date="disabledDate"
v-model="form.orderDate"
type="datetime"
placeholder="年/月/日 时:分:秒"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@@ -142,8 +148,12 @@ const form = ref({
repairImageUrl: '', // 维修图片url repairImageUrl: '', // 维修图片url
orderDate: '' // 预约日期 orderDate: '' // 预约日期
}); });
const type = ref('private');
onMounted(() => {
type.value = (route.query.type as 'public' | 'private') || 'private';
});
const rules = ref({ const rules = ref({
houseId: [{ required: true, message: '请选择关联房屋', trigger: 'blur' }], houseId: [{ required: type.value === 'private', message: '请选择关联房屋', trigger: 'blur' }],
maintenanceItemId: [{ required: true, message: '请选择维修项目', trigger: 'blur' }], maintenanceItemId: [{ required: true, message: '请选择维修项目', trigger: 'blur' }],
phone: [ phone: [
{ required: true, message: '请输入手机号', trigger: 'blur' }, { required: true, message: '请输入手机号', trigger: 'blur' },
@@ -155,9 +165,12 @@ const rules = ref({
], ],
problem: [{ required: true, message: '请输入问题描述', trigger: 'blur' }] problem: [{ required: true, message: '请输入问题描述', trigger: 'blur' }]
}); });
const userid = ref(null); const userid = ref(null);
// 报修项目 tree 结构 // 报修项目 tree 结构
const maintenanceItemTreeData = ref(); const maintenanceItemTreeData = ref();
function init() { function init() {
gettreelistRepairProject().then((res) => { gettreelistRepairProject().then((res) => {
maintenanceItemTreeData.value = handleTreeDisable(res.data); maintenanceItemTreeData.value = handleTreeDisable(res.data);
@@ -195,15 +208,13 @@ function handleTreeDisable(TreeData: RepairProjectVO[]) {
}); });
} }
// ! 上传图片 =--================================================================== // ! 上传图片 ===================================================================
const fileList = ref<UploadUserFile[]>([]); const fileList = ref<UploadUserFile[]>([]);
const dialogImageUrl = ref(''); const dialogImageUrl = ref('');
const dialogVisible = ref(false); const dialogVisible = ref(false);
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => { const handleRemove: UploadProps['onRemove'] = () => {};
console.log(uploadFile, uploadFiles);
};
const blockedExits = ['.exe', '.bat', '.cmd', '.msi']; const blockedExits = ['.exe', '.bat', '.cmd', '.msi'];
const allUploadExits = ['.jpg', '.jpeg', '.png', '.gif', '.bmp']; const allUploadExits = ['.jpg', '.jpeg', '.png', '.gif', '.bmp'];
const handleChangeFile: UploadProps['beforeUpload'] = (rawFile: UploadRawFile) => { const handleChangeFile: UploadProps['beforeUpload'] = (rawFile: UploadRawFile) => {
@@ -231,7 +242,10 @@ const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
const holderInfo = ref(null); const holderInfo = ref(null);
const HolderRef = ref<typeof Holder>(null); const HolderRef = ref<typeof Holder>(null);
function choiceResidentFun() { function choiceResidentFun() {
HolderRef.value.open([form.value.residentId]); HolderRef.value.open([form.value.residentId], {
ownerRelationship: '0',
status: '1'
});
} }
// 选择住户 // 选择住户
function handleChange(pop) { function handleChange(pop) {
@@ -301,6 +315,11 @@ const submitForm = () => {
}); });
}; };
// 禁用日期
const disabledDate = (time: Date) => {
return time.getTime() <= Date.now();
};
const sendForm = (str: string) => { const sendForm = (str: string) => {
form.value.problemImageUrl = str; form.value.problemImageUrl = str;
if (userid.value) { if (userid.value) {
@@ -345,7 +364,7 @@ const cancelForm = () => {
} }
.formBody { .formBody {
width: 1050px; width: 800px;
margin: 0 auto; margin: 0 auto;
&:deep(.el-date-editor.el-input) { &:deep(.el-date-editor.el-input) {

View File

@@ -38,10 +38,15 @@
:show-add="checkPermi(['repair:repair:add'])" :show-add="checkPermi(['repair:repair:add'])"
:show-edit="checkPermi(['repair:repair:edit'])" :show-edit="checkPermi(['repair:repair:edit'])"
:show-delete="checkPermi(['repair:repair:remove'])" :show-delete="checkPermi(['repair:repair:remove'])"
add-title="个人报修"
@update:add="handleAdd" @update:add="handleAdd"
@update:edit="handleUpdate()" @update:edit="handleUpdate()"
@update:delete="handleDelete()" @update:delete="handleDelete()"
></right-toolbar> >
<template #actions>
<el-button type="default" icon="Plus" v-hasPermi="['repair:repair:add']" @click="handleAdd('public')">公共报修</el-button>
</template>
</right-toolbar>
</el-row> </el-row>
</template> </template>
@@ -77,7 +82,6 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card> </el-card>
</div> </div>
@@ -190,19 +194,40 @@ const handleSelectionChange = (selection: RepairVO[]) => {
}; };
/** 新增按钮操作 */ /** 新增按钮操作 */
const handleAdd = () => { const handleAdd = (type: 'public' | 'private' = 'private') => {
router.push({ router.push({
path: '/repair/addRepair' path: '/repair/addRepair',
query: {
type
}
}); });
}; };
/** 修改按钮操作 */ /** 修改按钮操作 */
const handleUpdate = (row?: RepairVO) => { const handleUpdate = (row?: RepairVO) => {
const _id = row?.id || ids.value[0]; const _id = row?.id || ids.value[0];
let type: string;
// 如果有行数据根据houseId判断类型
if (row) {
if (row.houseId) {
type = 'private';
} else {
type = 'public';
}
} else {
// 多选编辑时,根据第一个选中的行判断类型
const item = repairList.value.find((item) => item.id === _id);
if (item) {
type = item.houseId ? 'private' : 'public';
} else {
type = 'private';
}
}
router.push({ router.push({
path: '/repair/editRepair', path: '/repair/editRepair',
query: { query: {
id: _id id: _id,
type
} }
}); });
}; };

View File

@@ -26,13 +26,6 @@
</el-form-item> </el-form-item>
<el-form-item label="计算公式" prop="formula"> <el-form-item label="计算公式" prop="formula">
<el-select <el-select
@change="
(val) => {
if (val === '2') {
form.unit = null;
}
}
"
v-model="form.formula" v-model="form.formula"
> >
<el-option v-for="(item, index) in com_charge_item_formula" :key="index" :value="item.value" :label="item.label"></el-option> <el-option v-for="(item, index) in com_charge_item_formula" :key="index" :value="item.value" :label="item.label"></el-option>
@@ -162,7 +155,7 @@ if (route.query.id) {
// 提交 // 提交
const submitForm = () => { const submitForm = () => {
if (form.value.formula === '2') { if (form.value.formula === '2') {
form.value.unit = null; form.value.unit = '';
} }
formRef.value?.validate(async (valid: boolean) => { formRef.value?.validate(async (valid: boolean) => {
if (valid) { if (valid) {

View File

@@ -10,13 +10,16 @@
</el-form-item> </el-form-item>
<el-form-item label="收费项目" prop="chargeItemId"> <el-form-item label="收费项目" prop="chargeItemId">
<el-select v-model="form.chargeItemId" @change="(val: string) => handleChange(val, true)"> <el-select v-model="form.chargeItemId" @change="(val: string) => handleChange(val, true)">
<el-option <el-option :disabled="item.status === '1'" v-for="(item, index) in chargeItemList" :key="index" :value="item.id" :label="item.itemName">
:disabled="item.status === '1'" <div class="flex flex-row justify-between" style="font-size: 13px">
v-for="(item, index) in chargeItemList" <span>{{ item.itemName }}</span>
:key="index" <div class="flex flex-items-baseline" style="color: var(--el-text-color-secondary)">
:value="item.id" <span>{{ item.fixedPrice }} </span>
:label="item.itemName" <span style="margin: 0 5px" v-if="item.unit">/</span>
></el-option> <dict-tag v-if="item.unit" :options="com_charge_item_unit" :value="item.unit"></dict-tag>
</div>
</div>
</el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 水费电费 收费范围为 房屋 --> <!-- 水费电费 收费范围为 房屋 -->
@@ -160,10 +163,11 @@ import { getBill, updateBill, addBill } from '@/api/system/SdbBill';
import type { DatePickerType } from 'element-plus'; import type { DatePickerType } from 'element-plus';
import { formatDate2 } from '@/utils'; import { formatDate2 } from '@/utils';
import { QuestionFilled } from '@element-plus/icons-vue'; import { QuestionFilled } from '@element-plus/icons-vue';
import DictTag from '@/components/DictTag/index.vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_bill_charge_scope_house, com_questionnaire_scope, com_bill_charge_period } = toRefs<any>( const { com_bill_charge_scope_house, com_questionnaire_scope, com_bill_charge_period, com_charge_item_unit } = toRefs<any>(
proxy?.useDict('com_bill_charge_scope_house', 'com_questionnaire_scope', 'com_bill_charge_period') proxy?.useDict('com_bill_charge_scope_house', 'com_questionnaire_scope', 'com_bill_charge_period', 'com_charge_item_unit')
); );
type PickerConfig = { type PickerConfig = {
@@ -188,7 +192,7 @@ const form = ref({
houseIds: [], // 部分房屋 houseIds: [], // 部分房屋
residentIds: [], // 部分业主 residentIds: [], // 部分业主
parkingIds: [], parkingIds: [],
chargeTypeId: '', // typeid chargeTypeId: '', // 收费类型
periodCalcType: '0', // 周期计算维度 periodCalcType: '0', // 周期计算维度
'startDate': '', // 开始 'startDate': '', // 开始
'endDate': '', // 结束 'endDate': '', // 结束
@@ -320,6 +324,7 @@ function handleSelect(val: string[]) {
const checkoutUser = ref([]); const checkoutUser = ref([]);
/** 添加 业主 */ /** 添加 业主 */
function handleCheckUser(val: string[]) { function handleCheckUser(val: string[]) {
console.log(val);
checkoutUser.value = val; checkoutUser.value = val;
form.value.residentIds = val; form.value.residentIds = val;
} }

View File

@@ -138,10 +138,7 @@ import { listBill, manualGenerateApi } from '@/api/system/SdbBill';
import { BillVO, BillQuery, BillForm } from '@/api/system/SdbBill/type'; import { BillVO, BillQuery, BillForm } from '@/api/system/SdbBill/type';
import { listChargeItem } from '@/api/system/SdbChargeItem'; import { listChargeItem } from '@/api/system/SdbChargeItem';
import { checkPermi } from '@/utils/permission'; import { checkPermi } from '@/utils/permission';
// import House from '@/components/Holder/house.vue';
import { ref } from 'vue'; import { ref } from 'vue';
// import UserHolder from '@/components/Holder/user.vue';
// import CarUser from '@/components/Holder/CarUser.vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_questionnaire_scope } = toRefs<any>(proxy?.useDict('com_questionnaire_scope')); const { com_questionnaire_scope } = toRefs<any>(proxy?.useDict('com_questionnaire_scope'));
@@ -241,7 +238,7 @@ const handleUpdate = (row?: BillVO) => {
} }
}); });
}; };
// 详情
function handleMain(row: BillVO) { function handleMain(row: BillVO) {
router.push({ router.push({
path: '/sdb/sdbbillMain', path: '/sdb/sdbbillMain',
@@ -283,6 +280,7 @@ const BillForm = ref<{
// function handleSelect(val: string[]) { // function handleSelect(val: string[]) {
// BillForm.value.houseId = val; // BillForm.value.houseId = val;
// } // }
// 生成账单
function handleChange(row: BillVO) { function handleChange(row: BillVO) {
clearChangeBillForm(); clearChangeBillForm();
BillVisible.value = true; BillVisible.value = true;
@@ -300,6 +298,7 @@ function handleChange(row: BillVO) {
BillForm.value['year'] = []; BillForm.value['year'] = [];
} }
} }
// 生成账单
function handleChangeApi() { function handleChangeApi() {
manualGenerateApi(BillForm.value).then((res) => { manualGenerateApi(BillForm.value).then((res) => {
ElMessage.success(res.msg); ElMessage.success(res.msg);
@@ -307,6 +306,7 @@ function handleChangeApi() {
BillVisible.value = false; BillVisible.value = false;
}); });
} }
// 清空表单
function clearChangeBillForm() { function clearChangeBillForm() {
BillForm.value = { BillForm.value = {
periodCalcType: undefined, periodCalcType: undefined,
@@ -317,16 +317,10 @@ function clearChangeBillForm() {
houseId: [] houseId: []
}; };
} }
// 禁用月份
function handleDisableMonth(date: Date) { function handleDisableMonth(date: Date) {
if (!BillForm.value.startDate || !BillForm.value.endDate) return false; if (!BillForm.value.startDate || !BillForm.value.endDate) return false;
return date.getTime() < new Date(BillForm.value.startDate).getTime() || date.getTime() > new Date(BillForm.value.endDate).getTime(); return date.getTime() > new Date(BillForm.value.endDate).getTime();
}
const myQuarter = ref('2026-2');
function onQuarterChange(val: string) {
console.log(val);
} }
onMounted(() => { onMounted(() => {

View File

@@ -157,7 +157,7 @@
<span v-if="scope.row.payStatus === '0'">未缴纳</span> <span v-if="scope.row.payStatus === '0'">未缴纳</span>
<span v-else-if="scope.row.payStatus === '1'">已缴纳</span> <span v-else-if="scope.row.payStatus === '1'">已缴纳</span>
<span v-else-if="scope.row.payStatus === '2'">缴纳失败</span> <span v-else-if="scope.row.payStatus === '2'">缴纳失败</span>
<span v-else>部分缴纳</span> <span v-else-if="scope.row.payStatus === '3'">部分缴纳</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="应缴金额" width="100" align="center" prop="amount" /> <el-table-column label="应缴金额" width="100" align="center" prop="amount" />
@@ -276,7 +276,7 @@
<el-form-item label="缴纳状态" prop="payStatus"> <el-form-item label="缴纳状态" prop="payStatus">
<el-radio-group v-model="inComeFrom.payStatus"> <el-radio-group v-model="inComeFrom.payStatus">
<el-radio value="1" label="已缴纳"></el-radio> <el-radio value="1" label="已缴纳"></el-radio>
<el-radio value="2" label="部分缴纳"></el-radio> <el-radio value="3" label="部分缴纳"></el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
@@ -602,7 +602,6 @@ function getList() {
.then((res) => { .then((res) => {
tableData.value = res.rows; tableData.value = res.rows;
total.value = res.total; total.value = res.total;
handleSelectBill(res.rows);
}) })
.finally(() => { .finally(() => {
loading.value = false; loading.value = false;
@@ -695,7 +694,7 @@ function initInComeFrom() {
allCost: 0, // 总金额 allCost: 0, // 总金额
billResidentId: [], // 账单id billResidentId: [], // 账单id
payStatus: '1', // 0:未缴 1:已缴 2: 缴纳失败 3: 部分缴纳 payStatus: '1', // 0:未缴 1:已缴 2: 缴纳失败 3: 部分缴纳
payType: '2', // 0:微信 1:支付宝 2 线下 payType: '2', // 0:微信 1:支付宝
remark: '', remark: '',
discountMethod: 0, // 优惠方式 0 不优惠 1 比例 2 金额 discountMethod: 0, // 优惠方式 0 不优惠 1 比例 2 金额
discountRate: '0', // 优惠比例 10 === 10% discountRate: '0', // 优惠比例 10 === 10%
@@ -892,12 +891,19 @@ const submitForm = () => {
return; return;
} }
buttonLoading.value = true; buttonLoading.value = true;
// 部分缴纳时 不管 // 部分缴纳时 判断 支付金额 和 预计支付金额 是否相等 ,相等 则 可选择 部分缴纳 方式
console.log(totalPayAmount.value, payListAllAmount.value, eqMoney(totalPayAmount.value, payListAllAmount.value), inComeFrom.value.payStatus);
if (inComeFrom.value.payStatus === '3') {
if (eqMoney(totalPayAmount.value, payListAllAmount.value)) {
buttonLoading.value = false;
return ElMessage.warning('实缴金额等于应收金额时,请选择 【已缴纳】 状态');
}
}
// 已缴纳时 判断 支付金额 和 预计支付金额 是否相等 // 已缴纳时 判断 支付金额 和 预计支付金额 是否相等
if (inComeFrom.value.payStatus === '1') { if (inComeFrom.value.payStatus === '1') {
if (!eqMoney(totalPayAmount.value, payListAllAmount.value)) { if (!eqMoney(totalPayAmount.value, payListAllAmount.value)) {
buttonLoading.value = false; buttonLoading.value = false;
return ElMessage.warning('支付金额不足,选择 部分缴纳 方式'); return ElMessage.warning('支付金额不足,选择 部分缴纳】 状态');
} }
} }
const obj = { const obj = {
@@ -1090,8 +1096,6 @@ const totalAll = ref({
totalAccount: '0', // 总金额 totalAccount: '0', // 总金额
TotalUnPaymentAmount: '0' // 未收金额 TotalUnPaymentAmount: '0' // 未收金额
}); });
// 多选时 统计总金额,优惠总金额,实付总金额
function handleSelectBill() {}
function handleChangePayTypeId(val: string, index: number) { function handleChangePayTypeId(val: string, index: number) {
// 【可选兜底校验】防止异常数据出现重复 // 【可选兜底校验】防止异常数据出现重复

View File

@@ -66,7 +66,6 @@
import Pageheader from '@/components/Pageheader/index.vue'; import Pageheader from '@/components/Pageheader/index.vue';
import { listCar, delCar } from '@/api/system/cars/index'; import { listCar, delCar } from '@/api/system/cars/index';
import { CarVO, CarQuery, CarForm } from '@/api/system/cars/type'; import { CarVO, CarQuery, CarForm } from '@/api/system/cars/type';
import { listResident } from '@/api/system/residentReviewProcess/resident';
import { checkPermi } from '@/utils/permission'; import { checkPermi } from '@/utils/permission';
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;

View File

@@ -7,7 +7,7 @@
<el-form class="formBody" label-position="right" ref="formRef" :model="form" :rules="rules" label-width="130px"> <el-form class="formBody" label-position="right" ref="formRef" :model="form" :rules="rules" label-width="130px">
<el-form-item label="设备分类" prop="categoryId"> <el-form-item label="设备分类" prop="categoryId">
<el-select v-model="form.categoryId"> <el-select v-model="form.categoryId">
<el-option v-for="(item, index) in deviceCategorylist" :key="index" :value="item.id" :label="item.categoryName"></el-option> <el-option v-for="(item, index) in deviceCategoryList" :key="index" :value="item.id" :label="item.categoryName"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="设备名称" prop="deviceName"> <el-form-item label="设备名称" prop="deviceName">
@@ -25,7 +25,7 @@
<el-form-item label="维护人员" prop="maintainUserIds"> <el-form-item label="维护人员" prop="maintainUserIds">
<repairUser <repairUser
userType="repair" userType="repair"
:userid="checkoutuseid" :userid="checkoutUseId"
ref="repairUserRef" ref="repairUserRef"
returnvalue="*" returnvalue="*"
:is-multiple="true" :is-multiple="true"
@@ -33,7 +33,7 @@
@change="handleCheckoutUser" @change="handleCheckoutUser"
> >
<template #default> <template #default>
<div class="checkoutuserbox flex flex-items-center justify-around" v-for="(item, index) in checkoutuser" :key="index"> <div class="checkoutUserBox flex flex-items-center justify-around" v-for="(item, index) in checkoutUser" :key="index">
<span>{{ item.nickName }}</span> <span>{{ item.nickName }}</span>
<div @click="handleDelete(item.id)"> <div @click="handleDelete(item.id)">
<el-icon> <el-icon>
@@ -41,7 +41,7 @@
</el-icon> </el-icon>
</div> </div>
</div> </div>
<div class="checkoutuserbox add flex flex-items-center justify-center" @click="() => repairUserRef.open()"> <div class="checkoutUserBox add flex flex-items-center justify-center" @click="() => repairUserRef.open()">
<el-icon> <el-icon>
<Plus></Plus> <Plus></Plus>
</el-icon> </el-icon>
@@ -106,10 +106,10 @@ const rules = ref({
}); });
const userid = ref(null); const userid = ref(null);
const deviceCategorylist = ref([]); const deviceCategoryList = ref([]);
function init() { function init() {
listDeviceCategory().then((res) => { listDeviceCategory().then((res) => {
deviceCategorylist.value = res.rows; deviceCategoryList.value = res.rows;
}); });
if (route.query.id) { if (route.query.id) {
userid.value = route.query.id; userid.value = route.query.id;
@@ -127,33 +127,33 @@ function init() {
remark: res.data.remark remark: res.data.remark
}; };
checkoutuser.value = []; checkoutUser.value = [];
checkoutuser.value = res.data.maintainUserList; checkoutUser.value = res.data.maintainUserList ?? [];
}); });
} }
} }
init(); init();
const checkoutuseid = computed(() => { const checkoutUseId = computed(() => {
return checkoutuser.value return checkoutUser.value
.map((item) => item.userId) .map((item) => item.userId)
.filter((item) => item) .filter((item) => item)
.join(','); .join(',');
}); });
const checkoutuser = ref([]); const checkoutUser = ref([]);
function handleCheckoutUser(row) { function handleCheckoutUser(row: string[]) {
checkoutuser.value = row; checkoutUser.value = row;
} }
function handleDelete(id: string) { function handleDelete(id: string) {
checkoutuser.value = checkoutuser.value.filter((item) => item.id !== id); checkoutUser.value = checkoutUser.value.filter((item) => item.id !== id);
} }
// !== 提交 ============================================================================= // !== 提交 =============================================================================
// 提交 // 提交
const submitForm = () => { const submitForm = () => {
form.value.maintainUserIds = checkoutuser.value form.value.maintainUserIds = checkoutUser.value
.map((itme) => itme.userId) .map((item) => item.userId)
.filter((item) => item) .filter((item) => item)
.join(','); .join(',');
formRef.value?.validate(async (valid: boolean) => { formRef.value?.validate(async (valid: boolean) => {
@@ -205,7 +205,7 @@ const cancelForm = () => {
width: 650px; width: 650px;
margin: 0 auto; margin: 0 auto;
.checkoutuserbox { .checkoutUserBox {
width: 120px; width: 120px;
margin: 5px; margin: 5px;
border: 1px solid #ccc; border: 1px solid #ccc;

View File

@@ -237,10 +237,14 @@ const cancelForm = () => {
font-size: 15px; font-size: 15px;
.label { .label {
width: 100px; width: 100px;
min-width: 100px;
text-align: right; text-align: right;
} }
.value { .value {
font-weight: normal; font-weight: normal;
white-space: wrap;
word-break: break-word;
font-size: 14px;
} }
} }
} }

View File

@@ -138,7 +138,10 @@
<el-table-column prop="name" label="收费标准"> <el-table-column prop="name" label="收费标准">
<template #default="scope"> <template #default="scope">
<div class="flex"> <div class="flex">
<span>{{ scope.row.fixedPrice }}</span> / <span>{{ scope.row.fixedPrice }}</span>
<span v-if="scope.row.fixedPrice && scope.row.unit">/</span>
<span v-else>---</span>
<dict-tag :options="com_charge_item_unit" :value="scope.row.unit"></dict-tag> <dict-tag :options="com_charge_item_unit" :value="scope.row.unit"></dict-tag>
</div> </div>
</template> </template>

View File

@@ -197,7 +197,6 @@ const uploadUrl = import.meta.env.VITE_APP_BASE_API + '/houseRental/uploadImages
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_rental_method } = toRefs<any>(proxy?.useDict('com_rental_method')); const { com_rental_method } = toRefs<any>(proxy?.useDict('com_rental_method'));
const { com_rental_status } = toRefs<any>(proxy?.useDict('com_rental_status')); const { com_rental_status } = toRefs<any>(proxy?.useDict('com_rental_status'));
// const { com_house_use } = toRefs<any>(proxy?.useDict('com_house_use'));&╬╬╥
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
@@ -220,7 +219,6 @@ const form = ref({
houseImageUrl: '', //房屋图片 houseImageUrl: '', //房屋图片
supInfo: '', //补充租房信息 supInfo: '', //补充租房信息
vx: '', //微信 vx: '', //微信
houseUse: '', //房屋用途
rentalStatus: 1, //租赁状态 rentalStatus: 1, //租赁状态
buildingId: null, //楼栋id buildingId: null, //楼栋id
unitNoId: null, //单元id unitNoId: null, //单元id

View File

@@ -112,7 +112,7 @@
<el-input maxlength="20" show-word-limit v-model.trim="form.contractNo" placeholder="请输入合同编号" /> <el-input maxlength="20" show-word-limit v-model.trim="form.contractNo" placeholder="请输入合同编号" />
</el-form-item> </el-form-item>
<el-form-item label="合同状态" prop="contractStatus"> <el-form-item label="合同状态" prop="contractStatus">
<el-input show-word-limit maxlength="200" v-model.trim="form.contractStatus" placeholder="请输入合同状态" /> <el-input show-word-limit maxlength="40" v-model.trim="form.contractStatus" placeholder="请输入合同状态" />
</el-form-item> </el-form-item>
<el-form-item label="租赁起始日" prop="leaseStartDate"> <el-form-item label="租赁起始日" prop="leaseStartDate">
<el-date-picker <el-date-picker
@@ -413,14 +413,13 @@ function sign(row: HouseRentalVO) {
form.value.villageName = info.villageName; form.value.villageName = info.villageName;
form.value.houseName = row.name; form.value.houseName = row.name;
form.value.houseArea = row.houseArea; form.value.houseArea = row.houseArea;
form.value.tenantPhone = ''; form.value.tenantPhone = row.signingList?.[0].tenantPhone || '';
form.value.houseId = row.houseId; form.value.houseId = row.houseId;
form.value.villageId = info.villageId; form.value.villageId = info.villageId;
form.value.rentalId = row.id; form.value.rentalId = row.id;
if (row.signingList && row.signingList.length > 0) { if (row.signingList && row.signingList.length > 0) {
const names = row.signingList[0].contractName ? row.signingList[0].contractName.split(',') : []; const names = row.signingList[0].contractName ? row.signingList[0].contractName.split(',') : [];
const list = row.signingList[0].contractUrl ? row.signingList[0].contractUrl.split(',') : []; const list = row.signingList[0].contractUrl ? row.signingList[0].contractUrl.split(',') : [];
console.log(list);
if (list.length > 0) { if (list.length > 0) {
showImgList.value = list.map((item, index) => { showImgList.value = list.map((item, index) => {
return { return {
@@ -451,12 +450,12 @@ const MAX_UPLOAD_FILES = 9;
const showImgList = ref([]); const showImgList = ref([]);
// 超出总数量拦截,不再只限制单次选择 // 超出总数量拦截,不再只限制单次选择
const handleExceed = () => { const handleExceed = () => {
ElMessage.warning(`最多只能上传 ${MAX_UPLOAD_FILES} 张轮播图`); ElMessage.warning(`最多只能上传 ${MAX_UPLOAD_FILES} 个附件`);
}; };
const handleChange = (file: UploadUserFile) => { const handleChange = (file: UploadUserFile) => {
// 实时判断当前已存在图片总数 // 实时判断当前已存在图片总数
if (showImgList.value.length > MAX_UPLOAD_FILES) { if (showImgList.value.length > MAX_UPLOAD_FILES) {
ElMessage.warning(`最多上传${MAX_UPLOAD_FILES},无法继续添加`); ElMessage.warning(`最多上传${MAX_UPLOAD_FILES}个附件,无法继续添加`);
// 清除刚选中的文件,防止缓存残留 // 清除刚选中的文件,防止缓存残留
uploadRef.value?.handleRemove(file); uploadRef.value?.handleRemove(file);
return; return;

View File

@@ -232,11 +232,18 @@ const getAreaList = async () => {
getAreaList(); getAreaList();
const holderInfo = ref(null); const holderInfo = ref(null);
function choiceResidentFun() { function choiceResidentFun() {
if (form.value.residentId) { if (form.value.residentId) {
HolderRef.value.open([...form.value.residentId]); HolderRef.value.open([...form.value.residentId], {
ownerRelationship: '0',
status: '1'
});
} else { } else {
HolderRef.value.open([]); HolderRef.value.open([], {
ownerRelationship: '0',
status: '1'
});
} }
} }
function handleChange(pop) { function handleChange(pop) {

View File

@@ -38,11 +38,11 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</div> </div>
<div class="line"></div> <div class="line" v-if="queryParams.chargeTypeFilters.length > 0"></div>
<el-scrollbar> <el-scrollbar>
<div style="width: fit-content"> <div style="width: fit-content">
<!-- 搜索条件 应收/已收/未收 --> <!-- 搜索条件 应收/已收/未收 -->
<div class="queryBox_over"> <div class="queryBox_over">
<el-form-item <el-form-item
:label="`${item.chargeTypeName}(应收)`" :label="`${item.chargeTypeName}(应收)`"
@@ -472,7 +472,7 @@ const formRules = computed<FormRules>(() => {
trigger: 'blur' trigger: 'blur'
} }
]; ];
// 房 // 房
dynamicRules[`roomNumber`] = [ dynamicRules[`roomNumber`] = [
{ {
validator: (_: any, value: string, callback: (error?: any) => void) => { validator: (_: any, value: string, callback: (error?: any) => void) => {

View File

@@ -4,21 +4,11 @@
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]"> <div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover"> <el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" @submit.prevent="handleQuery" :inline="true"> <el-form label-width="auto" ref="queryFormRef" :model="queryParams" @submit.prevent="handleQuery" :inline="true">
<div class="flex justify-between"> <div class="flex justify-between flex-wrap">
<div> <div v-for="(item, index) in queryParamsList" :key="index">
<el-form-item label="项目" prop="chargeItemId"> <el-form-item :label="item[ite].label" :prop="item[ite].parameter" v-for="(ite, ind) in Object.keys(item)" :key="ind">
<el-select v-model="queryParams.villageId" placeholder="请选择"> <el-input v-model.trim="queryParams[item[ite].parameter]" :placeholder="item[ite].placeholder"></el-input>
<el-option v-for="item in villageList" :key="item.villageId" :label="item.villageName" :value="item.villageId" />
</el-select>
</el-form-item>
<el-form-item label="房屋类型" prop="houseUseTypeId">
<el-select v-model="queryParams.houseUseTypeId" placeholder="请选择">
<el-option v-for="item in houseUseList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="客户" prop="customerName">
<el-input v-model.trim="queryParams.customerName"></el-input>
</el-form-item> </el-form-item>
</div> </div>
<div> <div>
@@ -114,7 +104,7 @@ import pageHeader from '@/components/Pageheader/index.vue';
import { getCommunitylistAPI } from '@/api/system/community'; import { getCommunitylistAPI } from '@/api/system/community';
import { ColumnConfig, exportToExcel } from '@/utils/xlsx'; import { ColumnConfig, exportToExcel } from '@/utils/xlsx';
import { listHouseUseType } from '@/api/system/houseUse'; import { listHouseUseType } from '@/api/system/houseUse';
import { getDailyFeeReportList } from '@/api/system/report/dailyFeeReport'; import { getDailyFeeReportDynamicList, getDailyFeeReportList } from '@/api/system/report/dailyFeeReport';
import { Datum } from '@/api/system/report/dailyFeeReport/type'; import { Datum } from '@/api/system/report/dailyFeeReport/type';
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@@ -124,18 +114,6 @@ const showSearch = ref(true);
const total = ref(0); const total = ref(0);
const queryFormRef = ref<ElFormInstance>(); const queryFormRef = ref<ElFormInstance>();
const data = reactive({
queryParams: {
pageNum: 1,
pageSize: 10,
villageId: '',
houseUseTypeId: '',
customerName: ''
}
});
const { queryParams } = toRefs(data);
// 查询小区 // 查询小区
const villageList = ref([]); const villageList = ref([]);
function getAllVillage() { function getAllVillage() {
@@ -152,6 +130,42 @@ function getHouseUseList() {
}); });
} }
const queryParams = ref({
pageNum: 1,
pageSize: 10
});
// 参数列表
const queryParamsList = ref([]);
function getQueryParams() {
getDailyFeeReportDynamicList().then((res) => {
const obj = {};
const list = res.data.map((item) => {
const obj2 = {};
const list = item.field.split(',') ?? [];
console.log(list);
list.forEach((item2) => {
obj[item2] = '';
obj2[item2] = {
label: item.label,
parameter: item2,
placeholder: item.placeholder,
type: item.type,
subField: item.subField
};
});
return obj2;
});
queryParams.value = {
...queryParams.value,
...obj
};
queryParamsList.value = list;
console.log(list);
});
}
const rowChargeTypesList = ref([]); const rowChargeTypesList = ref([]);
/** 查询电抄记录列表 */ /** 查询电抄记录列表 */
@@ -166,7 +180,7 @@ const getList = async () => {
}); });
getDailyFeeReportList(search) getDailyFeeReportList(search)
.then((res) => { .then((res) => {
ArrearsDetailList.value = [...res.rows]; ArrearsDetailList.value = [...(res.rows ?? [])];
rowChargeTypesList.value = Object.keys(res.rows[0].chargeTypeAmounts); rowChargeTypesList.value = Object.keys(res.rows[0].chargeTypeAmounts);
total.value = res.total; total.value = res.total;
}) })
@@ -193,10 +207,7 @@ const resetQuery = () => {
queryFormRef.value?.resetFields(); queryFormRef.value?.resetFields();
queryParams.value = { queryParams.value = {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10
villageId: '-1',
houseUseTypeId: '',
customerName: ''
}; };
handleQuery(); handleQuery();
}; };
@@ -285,6 +296,7 @@ onMounted(() => {
getList(); getList();
getHouseUseList(); getHouseUseList();
getAllVillage(); getAllVillage();
getQueryParams();
}); });
</script> </script>

View File

@@ -27,8 +27,8 @@
<DictTag :options="com_id_card_type" :value="userInfo.idCardType"></DictTag> <DictTag :options="com_id_card_type" :value="userInfo.idCardType"></DictTag>
</div> </div>
<div class="userinfo_item"> <div class="userinfo_item">
<div class="title_item">住户类型</div> <div class="title_item">与主业主关系</div>
<DictTag :options="com_resident_relationship" :value="userInfo.type"></DictTag> <DictTag :options="com_resident_relationship" :value="userInfo.ownerRelationship"></DictTag>
</div> </div>
<!-- <div class="userinfo_item"> <!-- <div class="userinfo_item">
<div class="title_item">住户来源</div> <div class="title_item">住户来源</div>
@@ -163,6 +163,7 @@ const userInfo = ref<ResidentVO>({
nickName: '', nickName: '',
unitNoId: '', unitNoId: '',
idCardType: '0', idCardType: '0',
ownerRelationship: '0',
'id': null, 'id': null,
'name': '', 'name': '',
'type': '0', 'type': '0',

View File

@@ -33,7 +33,7 @@
</el-row> </el-row>
</template> </template>
<el-table class="tablebody" v-loading="loading" border :data="storeroomList" @selection-change="handleSelectionChange"> <el-table class="tableBody" v-loading="loading" border :data="storeroomList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="楼栋名" align="center" prop="buildingName" /> <el-table-column label="楼栋名" align="center" prop="buildingName" />
<el-table-column label="单元号" show-overflow-tooltip align="center" prop="unitName" /> <el-table-column label="单元号" show-overflow-tooltip align="center" prop="unitName" />
@@ -101,8 +101,7 @@ const data = reactive<PageData<StoreroomForm, StoreroomQuery>>({
shareArea: undefined, shareArea: undefined,
internalArea: undefined, internalArea: undefined,
houseId: undefined, houseId: undefined,
status: undefined, status: undefined
params: {}
}, },
rules: { rules: {
storeroomNo: [{ required: true, message: '储藏室号不能为空', trigger: 'blur' }] storeroomNo: [{ required: true, message: '储藏室号不能为空', trigger: 'blur' }]
@@ -179,7 +178,7 @@ onMounted(() => {
flex: 1; flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.tablebody { .tableBody {
flex: 1; flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@@ -12,7 +12,7 @@
<el-input maxlength="16" show-word-limit v-model.trim="form.userName" placeholder="请输入登录账号" /> <el-input maxlength="16" show-word-limit v-model.trim="form.userName" placeholder="请输入登录账号" />
</el-form-item> </el-form-item>
<el-form-item label="登录密码" v-if="form.userId == undefined" prop="password"> <el-form-item label="登录密码" v-if="form.userId == undefined" prop="password">
<el-input type="password" clearable v-model.trim="form.password" placeholder="请输入" /> <el-input type="password" show-password clearable v-model.trim="form.password" placeholder="请输入" />
</el-form-item> </el-form-item>
<el-form-item label="员工性别" prop="chargeScope"> <el-form-item label="员工性别" prop="chargeScope">
<el-select v-model="form.sex" placeholder="请选择"> <el-select v-model="form.sex" placeholder="请选择">

View File

@@ -565,7 +565,7 @@ onMounted(() => {
...JSON.parse(sessionStorage.getItem('queryParams') || '{}') ...JSON.parse(sessionStorage.getItem('queryParams') || '{}')
}; };
getViliageList(); // 初始化部门数据 getViliageList(); // 初始化部门数据
getList(); // 初始化列表数据╬«> getList(); // 初始化列表数据
proxy?.getConfigKey('sys.user.initPassword').then((response) => { proxy?.getConfigKey('sys.user.initPassword').then((response) => {
initPassword.value = response.data; initPassword.value = response.data;
}); });

View File

@@ -101,7 +101,7 @@
<el-option v-for="(item, index) in getlastVersionlist" :key="index" :label="item.versionName" :value="item.versionCode"></el-option> <el-option v-for="(item, index) in getlastVersionlist" :key="index" :label="item.versionName" :value="item.versionCode"></el-option>
</el-select> </el-select>
<el-select v-else v-model="form.minVersionCode" placeholder="请输入最低支持版本"> <el-select v-else v-model="form.minVersionCode" placeholder="请输入最低支持版本">
<el-option label="1.0.0" :value="1"></el-option> <el-option label="1.0.0" value="1"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="渠道" prop="channel"> <el-form-item label="渠道" prop="channel">
@@ -112,7 +112,7 @@
<el-radio v-if="form.platform !== appType.ios" value="vivo">vivo</el-radio> <el-radio v-if="form.platform !== appType.ios" value="vivo">vivo</el-radio>
<el-radio v-if="form.platform !== appType.ios" value="yyb">应用宝</el-radio> <el-radio v-if="form.platform !== appType.ios" value="yyb">应用宝</el-radio>
<el-radio v-if="form.platform !== appType.ios" value="honor">荣耀</el-radio> <el-radio v-if="form.platform !== appType.ios" value="honor">荣耀</el-radio>
<el-radio value="ios">ios</el-radio> <el-radio v-else value="ios">ios</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
@@ -192,7 +192,7 @@ const initFormData: VersionForm = {
downloadUrl: undefined, downloadUrl: undefined,
releaseNotes: undefined, releaseNotes: undefined,
fileSize: undefined, fileSize: undefined,
appChannel: undefined, appChannel: 'resident',
status: undefined, status: undefined,
channel: undefined channel: undefined
}; };
@@ -207,7 +207,7 @@ const data = reactive<PageData<VersionForm, VersionQuery>>({
appChannel: undefined appChannel: undefined
}, },
rules: { rules: {
channel: [{ required: true, message: 'App应用不能为空', trigger: 'blur' }], channel: [{ required: true, message: 'App渠道不能为空', trigger: 'blur' }],
platform: [{ required: true, message: 'App类型不能为空', trigger: 'blur' }], platform: [{ required: true, message: 'App类型不能为空', trigger: 'blur' }],
versionCode: [{ required: true, message: '版本号不能为空', trigger: 'blur' }], versionCode: [{ required: true, message: '版本号不能为空', trigger: 'blur' }],
versionName: [{ required: true, message: '版本名称不能为空', trigger: 'blur' }], versionName: [{ required: true, message: '版本名称不能为空', trigger: 'blur' }],
@@ -314,7 +314,7 @@ function handleChangePlatform() {
form.value.updateType = updateType.optional; form.value.updateType = updateType.optional;
form.value.method = updatePackageType.apk; form.value.method = updatePackageType.apk;
form.value.downloadUrl = ''; form.value.downloadUrl = '';
form.value.channel = '';
if (form.value.platform === 'ios') { if (form.value.platform === 'ios') {
form.value.channel = 'ios'; form.value.channel = 'ios';
handleChangeChannel(form.value.channel); handleChangeChannel(form.value.channel);