8/1 限制前端输入字数
This commit is contained in:
@@ -9,9 +9,9 @@ VITE_APP_ENV='development'
|
||||
# 开发环境
|
||||
VITE_APP_BASE_API='/dev-api'
|
||||
# # 开发环境 接口代理地址
|
||||
#VITE_APP_PROXY_API='http://192.168.1.222:8080'
|
||||
VITE_APP_PROXY_API='http://192.168.1.222:8080'
|
||||
# 开发环境 接口代理地址
|
||||
VITE_APP_PROXY_API='http://192.168.1.6:8080'
|
||||
#VITE_APP_PROXY_API='http://192.168.1.6:8080'
|
||||
# 图片基础地址
|
||||
VITE_IMG_URL='http://192.168.1.222:8080'
|
||||
|
||||
|
||||
@@ -69,7 +69,6 @@ export const income_scourcApi = (datetime?: string): AxiosPromise<sourceType> =>
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
export interface PayMentMethod {
|
||||
'wechatAmount': string;
|
||||
'wechatPercent': string;
|
||||
@@ -89,7 +88,6 @@ export const payment_methodApi = (datetime?: string): AxiosPromise<PayMentMethod
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
export interface Arrears_distrubution {
|
||||
month: number;
|
||||
amount: string;
|
||||
@@ -133,17 +131,19 @@ export interface payment_trendType {
|
||||
'unpaidAmount': string;
|
||||
}
|
||||
|
||||
|
||||
// 缴费走势分析
|
||||
export const payment_trendApi = (startDate?: string, endDate?: string): AxiosPromise<{
|
||||
items:payment_trendType[]
|
||||
export const payment_trendApi = (
|
||||
startDate?: string,
|
||||
endDate?: string
|
||||
): AxiosPromise<{
|
||||
items: payment_trendType[];
|
||||
}> => {
|
||||
return request({
|
||||
url: '/api/analysis/income/payment_trend',
|
||||
method: 'get',
|
||||
params: {
|
||||
startDate,
|
||||
endDate,
|
||||
endDate
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -93,8 +93,6 @@ export const get_movein_moveout_list = (query?: {
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const get_person_age = (query?: {
|
||||
dateTime: string;
|
||||
}): AxiosPromise<
|
||||
|
||||
@@ -53,6 +53,10 @@ export interface ChargeItemVO {
|
||||
* 小区id
|
||||
*/
|
||||
villageId: string;
|
||||
/**
|
||||
* 状态 0正常 1停用
|
||||
*/
|
||||
status: string;
|
||||
}
|
||||
|
||||
export interface ChargeItemForm extends BaseEntity {
|
||||
|
||||
@@ -88,7 +88,6 @@ export interface WarehouseQuery extends PageQuery {
|
||||
*/
|
||||
warehouseName?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 联系人*
|
||||
*/
|
||||
|
||||
@@ -82,9 +82,7 @@ export interface AppUserList {
|
||||
/**
|
||||
* 获取用户端app-用户
|
||||
* */
|
||||
export const getAppUser = (
|
||||
data
|
||||
): AxiosPromise<AppUserList[]> => {
|
||||
export const getAppUser = (data): AxiosPromise<AppUserList[]> => {
|
||||
return request({
|
||||
url: '/car/getAppUserList',
|
||||
method: 'GET',
|
||||
|
||||
@@ -150,7 +150,6 @@ export interface VersionQuery extends PageQuery {
|
||||
*/
|
||||
downloadUrl?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 0-禁用 1-启用
|
||||
*/
|
||||
|
||||
@@ -259,4 +259,3 @@ aside {
|
||||
.el-button {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,11 +80,7 @@ export function buildHousePathCache(treeData: Tree[]) {
|
||||
pathCache.set('label', new Map());
|
||||
pathCache.set('value', new Map());
|
||||
|
||||
const stack: [Tree, (string | number)[], (string | number)[]][] = treeData.map(node => [
|
||||
node,
|
||||
[node.label],
|
||||
[node.value]
|
||||
]);
|
||||
const stack: [Tree, (string | number)[], (string | number)[]][] = treeData.map((node) => [node, [node.label], [node.value]]);
|
||||
|
||||
while (stack.length) {
|
||||
const [node, labelPath, valPath] = stack.pop()!;
|
||||
@@ -99,11 +95,7 @@ export function buildHousePathCache(treeData: Tree[]) {
|
||||
if (node.children?.length) {
|
||||
const reverseChildren = [...node.children].reverse();
|
||||
for (const child of reverseChildren) {
|
||||
stack.push([
|
||||
child,
|
||||
[...labelPath, child.label],
|
||||
[...valPath, child.value]
|
||||
]);
|
||||
stack.push([child, [...labelPath, child.label], [...valPath, child.value]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +190,6 @@ export function neqMoney(a: string | number, b: string | number): boolean {
|
||||
return !toBig(a).eq(toBig(b));
|
||||
}
|
||||
|
||||
|
||||
// 保留2位小数(金额专用)
|
||||
export function toFixed2(val) {
|
||||
return Number(val).toFixed(2);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" label-width="90px" label-position="left" :model="queryParams" :inline="true">
|
||||
<el-form-item label="投诉类型" prop="typeId">
|
||||
<el-select v-model="queryParams.typeId" placeholder="请选择投诉类型" style="width: 240px">
|
||||
<el-select @clear="handleClear" clearable v-model="queryParams.typeId" placeholder="请选择投诉类型" style="width: 240px">
|
||||
<el-option :disabled="item.status === '1'" v-for="item in complainTypeList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@@ -120,6 +120,11 @@ const handleQuery = () => {
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 清空投诉类型 */
|
||||
const handleClear = () => {
|
||||
queryParams.value.typeId = undefined;
|
||||
handleQuery();
|
||||
};
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<div class="title">基本信息</div>
|
||||
</template>
|
||||
<div class="addBuildingFormBody">
|
||||
<div class="formbox">
|
||||
<div class="formBox">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
@@ -37,14 +37,7 @@
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="装修押金(元)" prop="decorationDeposit">
|
||||
<el-input
|
||||
type="number"
|
||||
min="0"
|
||||
step="0.01"
|
||||
maxlength="8"
|
||||
placeholder="请输入装修押金,最多保留2位小数"
|
||||
v-model.trim.number="form.decorationDeposit"
|
||||
/>
|
||||
<el-input maxlength="8" placeholder="请输入装修押金,最多保留2位小数" v-model.number.trim="form.decorationDeposit" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -64,6 +57,7 @@ import { ref } from 'vue';
|
||||
import PageHeader from '@/components/Pageheader/index.vue';
|
||||
import { addDecoration, getDecoration, updateDecoration } from '@/api/system/Decoration';
|
||||
import { useHouseStore } from '@/store/modules/house';
|
||||
import { validator } from '@/utils/Reg';
|
||||
|
||||
const houseStore = useHouseStore();
|
||||
const treedata = ref([]);
|
||||
@@ -77,39 +71,12 @@ const form = ref({
|
||||
'buildingId': null,
|
||||
'unitNoId': null,
|
||||
'applyName': '',
|
||||
'inspectionResult': '0',
|
||||
'decorationCompany': '',
|
||||
'decorationContent': '',
|
||||
'decorationDeposit': null
|
||||
});
|
||||
|
||||
/**
|
||||
* 通用金额校验器
|
||||
* @param value 输入值
|
||||
* @param type money金额 / num整数
|
||||
* @returns 校验提示信息,空则校验通过
|
||||
*/
|
||||
const validator = (value: number | null, type: 'money' | 'num') => {
|
||||
// 空值由 required 规则拦截,这里只处理有值的情况
|
||||
if (value === null || value === undefined) return '';
|
||||
|
||||
// 转字符串处理小数位数
|
||||
const strVal = String(value);
|
||||
// 禁止负数
|
||||
if (value < 0) return '金额不能为负数';
|
||||
|
||||
if (type === 'money') {
|
||||
// 匹配最多两位小数
|
||||
const reg = /^\d+(\.\d{1,2})?$/;
|
||||
if (!reg.test(strVal)) return '金额仅支持最多两位小数';
|
||||
// 限制金额上限(可按需修改)
|
||||
if (value > 9999999.99) return '押金金额不能超过9999999.99元';
|
||||
} else if (type === 'num') {
|
||||
const reg = /^\d+$/;
|
||||
if (!reg.test(strVal)) return '只能输入正整数';
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
const rules = {
|
||||
houseId: [{ required: true, message: '请选择具体房屋', trigger: 'blur' }],
|
||||
applyName: [{ required: true, message: '请输入申请人', trigger: 'blur' }],
|
||||
@@ -120,9 +87,18 @@ const rules = {
|
||||
if (val === '' || val === null) {
|
||||
return callback(new Error('请输入装修押金'));
|
||||
}
|
||||
const msg = validator(val, 'money');
|
||||
if (msg) callback(new Error(msg));
|
||||
else callback();
|
||||
const num = Number(val);
|
||||
console.log(val);
|
||||
if (Number.isNaN(num)) {
|
||||
return callback(new Error('请输入装修押金'));
|
||||
}
|
||||
if (num < 0) {
|
||||
return callback(new Error('装修押金不能为负数'));
|
||||
}
|
||||
if (num > 99999999) {
|
||||
return callback(new Error('装修押金过大'));
|
||||
}
|
||||
return validator(val, 'money');
|
||||
},
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
@@ -184,9 +160,7 @@ const submitForm = () => {
|
||||
|
||||
// 返回
|
||||
function handleBack() {
|
||||
router.push({
|
||||
path: '/repair/decoration'
|
||||
});
|
||||
router.back();
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -198,7 +172,7 @@ function handleBack() {
|
||||
margin-top: 20px;
|
||||
flex: 1;
|
||||
|
||||
.formbox {
|
||||
.formBox {
|
||||
width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<el-input maxlength="20" v-model="queryParams.applyName" placeholder="请输入申请人姓名" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="装修验收结果" prop="inspectionResult">
|
||||
<el-select v-model="queryParams.inspectionResult" placeholder="请选择装修验收结果" style="width: 240px">
|
||||
<el-select clearable @clear="handleClear" v-model="queryParams.inspectionResult" placeholder="请选择装修验收结果" style="width: 240px">
|
||||
<el-option v-for="item in com_decoration_status" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@@ -59,11 +59,16 @@
|
||||
link
|
||||
type="primary"
|
||||
v-if="scope.row.inspectionResult !== '1'"
|
||||
@click="handleInspection(scope.row, 0, '验收')"
|
||||
@click="handleInspection(scope.row, EditType.Add, '验收')"
|
||||
v-has-permi="['repair:edit:decoration']"
|
||||
>验收</el-button
|
||||
>
|
||||
<el-button link type="primary" v-else @click="handleInspection(scope.row, 1, '详情')" v-has-permi="['decoration:decoration:query']"
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
v-else
|
||||
@click="handleInspection(scope.row, EditType.Detail, '详情')"
|
||||
v-has-permi="['decoration:decoration:query']"
|
||||
>详情</el-button
|
||||
>
|
||||
<el-button link type="primary" @click="handleUpdate(scope.row)" v-has-permi="['decoration:decoration:edit']">编辑</el-button>
|
||||
@@ -77,42 +82,47 @@
|
||||
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="decorationFormRef" :model="form" :rules="rules" label-width="120px">
|
||||
<el-form-item label="小区名称" prop="villageName" v-if="isedit === 1">
|
||||
<el-input :disabled="isedit === 1" v-model="form.villageName" />
|
||||
<div v-if="isEditComputed">
|
||||
<el-form-item label="小区名称" prop="villageName">
|
||||
<el-input :disabled="isEditComputed" v-model="form.villageName" />
|
||||
</el-form-item>
|
||||
<el-form-item label="房屋号" prop="houseName" v-if="isedit === 1">
|
||||
<el-input :disabled="isedit === 1" v-model="form.houseName" />
|
||||
<el-form-item label="房屋号" prop="houseName">
|
||||
<el-input :disabled="isEditComputed" v-model="form.houseName" />
|
||||
</el-form-item>
|
||||
<el-form-item label="申请人" prop="applyName" v-if="isedit === 1">
|
||||
<el-input :disabled="isedit === 1" v-model="form.applyName" />
|
||||
<el-form-item label="申请人" prop="applyName">
|
||||
<el-input :disabled="isEditComputed" v-model="form.applyName" />
|
||||
</el-form-item>
|
||||
<el-form-item label="装修公司" prop="decorationCompany" v-if="isedit === 1">
|
||||
<el-input :disabled="isedit === 1" v-model="form.decorationCompany" />
|
||||
<el-form-item label="装修公司" prop="decorationCompany">
|
||||
<el-input :disabled="isEditComputed" v-model="form.decorationCompany" />
|
||||
</el-form-item>
|
||||
<el-form-item label="装修内容" prop="decorationContent" v-if="isedit === 1">
|
||||
<el-input :disabled="isedit === 1" v-model="form.decorationContent" />
|
||||
<el-form-item label="装修内容" prop="decorationContent">
|
||||
<el-input :disabled="isEditComputed" v-model="form.decorationContent" />
|
||||
</el-form-item>
|
||||
<el-form-item label="装修押金" prop="decorationDeposit" v-if="isedit === 1">
|
||||
<el-input :disabled="isedit === 1" v-model="form.decorationDeposit" />
|
||||
<el-form-item label="装修押金" prop="decorationDeposit">
|
||||
<el-input :disabled="isEditComputed" v-model="form.decorationDeposit" />
|
||||
</el-form-item>
|
||||
<el-form-item label="验收结果" prop="inspectionResult">
|
||||
<el-select :disabled="isedit === 1" v-model="form.inspectionResult" placeholder="请选择装修验收结果">
|
||||
<el-option
|
||||
v-for="item in com_decoration_status.filter((item) => item.value !== '0')"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</div>
|
||||
<el-form-item label="验收结果" :prop="isEditComputed ? '' : 'inspectionResult'">
|
||||
<el-select :disabled="isEditComputed" v-model="form.inspectionResult" placeholder="请选择装修验收结果">
|
||||
<el-option v-for="item in com_decoration_status" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="验收人" prop="inspectionName">
|
||||
<el-input :disabled="isedit === 1" v-model="form.inspectionName" />
|
||||
<el-form-item label="验收人" :prop="isEditComputed ? '' : 'inspectionName'">
|
||||
<el-input :disabled="isEditComputed" v-model="form.inspectionName" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input :disabled="isedit === 1" v-model="form.remark" type="textarea" placeholder="请输入" :rows="5"></el-input>
|
||||
<el-input
|
||||
:disabled="isEditComputed"
|
||||
v-model="form.remark"
|
||||
type="textarea"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
:placeholder="isEditComputed ? '' : '请输入'"
|
||||
:rows="5"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer v-if="isedit !== 1">
|
||||
<template #footer v-if="!isEditComputed">
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
@@ -123,7 +133,7 @@
|
||||
</template>
|
||||
|
||||
<script setup name="Decoration" lang="ts">
|
||||
import { listDecoration, delDecoration, updateDecoration } from '@/api/system/Decoration/index';
|
||||
import { listDecoration, delDecoration, updateDecoration } from '@/api/system/Decoration';
|
||||
import { DecorationVO, DecorationQuery, DecorationForm } from '@/api/system/Decoration/type';
|
||||
import { checkPermi } from '@/utils/permission';
|
||||
|
||||
@@ -208,6 +218,11 @@ const handleQuery = () => {
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 清空按钮操作 */
|
||||
const handleClear = () => {
|
||||
queryParams.value.inspectionResult = undefined;
|
||||
handleQuery();
|
||||
};
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
@@ -230,7 +245,7 @@ const handleAdd = () => {
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: DecorationVO) => {
|
||||
const handleUpdate = (row?: DecorationVO) => {
|
||||
const _id = row?.id || ids.value[0];
|
||||
router.push({
|
||||
path: '/repair/editDecoration',
|
||||
@@ -240,16 +255,24 @@ const handleUpdate = async (row?: DecorationVO) => {
|
||||
});
|
||||
};
|
||||
|
||||
const isedit = ref(1);
|
||||
enum EditType {
|
||||
/** 验收 */
|
||||
const handleInspection = (row: DecorationVO, edit: number, type: string) => {
|
||||
Add = 1,
|
||||
/** 详情 */
|
||||
Detail = 2
|
||||
}
|
||||
const isEdit = ref(EditType.Add);
|
||||
const isEditComputed = computed(() => isEdit.value !== EditType.Add);
|
||||
|
||||
/** 验收 */
|
||||
const handleInspection = (row: DecorationVO, edit: EditType, type: string) => {
|
||||
form.value = {
|
||||
...form.value,
|
||||
...row
|
||||
};
|
||||
dialog.visible = true;
|
||||
dialog.title = type;
|
||||
isedit.value = edit;
|
||||
isEdit.value = edit;
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
|
||||
@@ -73,17 +73,21 @@
|
||||
ref="uploadRef"
|
||||
:show-file-list="true"
|
||||
name="files"
|
||||
:on-exceed="handleExceed"
|
||||
:headers="headerToken()"
|
||||
:on-remove="handleAvatarRemove"
|
||||
:on-change="handleProgress"
|
||||
:before-upload="beforeAvatarUpload"
|
||||
accept=".doc,.docx,.xls,.xlsx,.jpg,.jpeg,.png,.gif,.bmp,.webp"
|
||||
accept=".doc,.docx,.xls,.xlsx,.jpg,.jpeg,.png,.gif,.bmp,.webp,.zip"
|
||||
>
|
||||
<div class="uploadBtn flex flex-items-center">
|
||||
<el-icon><Upload /></el-icon>
|
||||
<span>上传文件</span>
|
||||
</div>
|
||||
<template #tip>仅支持doc/docx/xls/xlsx/jpg/png/gif等</template>
|
||||
<template #tip>
|
||||
<div>仅支持doc/docx/xls/xlsx/jpg/png/gif/bmp/webp/zip等格式</div>
|
||||
<span style="font-size: smaller">最多上传 {{ MAX_FILE_COUNT }} 个文件</span>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -108,7 +112,7 @@ import { addHandleLog, getHandleLog, updateHandleLog, uploadAttachments } from '
|
||||
import { UploadFiles, UploadProps, UploadRawFile, UploadUserFile } from 'element-plus';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { Upload } from '@element-plus/icons-vue'; // 确保引入图标
|
||||
import { Upload } from '@element-plus/icons-vue'; // 确保引入图标组件╬╬╬
|
||||
|
||||
const uploadUrl = import.meta.env.VITE_APP_BASE_API + '/handleLog/uploadAttachments';
|
||||
const route = useRoute();
|
||||
@@ -152,33 +156,29 @@ const handleAvatarRemove: UploadProps['onRemove'] = (uploadFile: UploadUserFile,
|
||||
};
|
||||
|
||||
// 定义大小限制常量 (单位: MB)
|
||||
const MAX_SINGLE_FILE_SIZE = 10 * 1024 * 1024; // 10MB in bytes
|
||||
const MAX_TOTAL_FILE_SIZE = 20 * 1024 * 1024; // 20MB in bytes
|
||||
const MAX_SINGLE_FILE_SIZE = 10 * 1024 * 1024; // 10MB
|
||||
const MAX_TOTAL_FILE_SIZE = 20 * 1024 * 1024; // 20MB
|
||||
const MAX_FILE_COUNT = 9; // 最大上传文件数量
|
||||
const uploadRef = ref();
|
||||
// 添加一个锁,防止 on-change 递归调用导致重复提示
|
||||
const isChecking = ref(false);
|
||||
const handleExceed: UploadProps['onExceed'] = (files, uploadFiles) => {
|
||||
ElMessage.warning(`最多只能上传 ${MAX_FILE_COUNT} 个文件,当前已上传 ${uploadFiles.length} 个文件`);
|
||||
};
|
||||
const handleProgress: UploadProps['onChange'] = (uploadFile: UploadUserFile, uploadFiles: UploadFiles) => {
|
||||
// 如果正在校验中,直接返回,避免重复执行
|
||||
// 先校验当前触发的文件类型
|
||||
if (!beforeAvatarUpload(uploadFile)) {
|
||||
uploadRef.value.handleRemove(uploadFile);
|
||||
uploadRef.value?.handleRemove(uploadFile);
|
||||
return;
|
||||
}
|
||||
if (isChecking.value) return;
|
||||
// 加锁
|
||||
isChecking.value = true;
|
||||
// 创建一个新数组来存储校验通过的文件
|
||||
|
||||
const validFiles: CustomUploadFile[] = [];
|
||||
let newFilesTotalSize = 0;
|
||||
let hasError = false;
|
||||
let errorMsg = '';
|
||||
|
||||
// 1. 遍历所有文件,筛选出符合单文件大小要求的文件,并计算新文件总大小
|
||||
// 遍历所有文件,校验新文件
|
||||
for (const file of uploadFiles) {
|
||||
// 只校验新上传的文件 (有 raw 属性)
|
||||
if (file.raw) {
|
||||
// 检查单个文件大小
|
||||
if (file.raw.size > MAX_SINGLE_FILE_SIZE) {
|
||||
// 如果发现单个文件超标,标记错误,并不将该文件加入 validFiles
|
||||
if (!hasError) {
|
||||
errorMsg = `文件 ${file.name} 大小超过 10MB,已自动移除`;
|
||||
hasError = true;
|
||||
@@ -187,57 +187,37 @@ const handleProgress: UploadProps['onChange'] = (uploadFile: UploadUserFile, upl
|
||||
}
|
||||
newFilesTotalSize += file.raw.size;
|
||||
}
|
||||
// 将非超标文件(包括旧文件和未超标的新文件)暂时加入
|
||||
console.log(file);
|
||||
validFiles.push({
|
||||
...file,
|
||||
ossId: (file as CustomUploadFile).ossId ?? null
|
||||
});
|
||||
}
|
||||
|
||||
// 2. 如果存在单文件超标的情况,先处理这部分逻辑
|
||||
if (hasError) {
|
||||
ElMessage.error(errorMsg);
|
||||
// 更新 fileList 为移除了超标文件的列表
|
||||
fileList.value = validFiles;
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 检查新文件总大小是否超过 20MB
|
||||
if (newFilesTotalSize > MAX_TOTAL_FILE_SIZE) {
|
||||
ElMessage.error(`所有新上传文件的总大小不能超过 20MB,当前已选新文件总大小约为 ${(newFilesTotalSize / 1024 / 1024).toFixed(2)}MB`);
|
||||
|
||||
// 策略:移除最后添加的那个导致超标的文件
|
||||
// 注意:这里需要找到最后添加的那个文件。uploadFile 参数就是当前触发的文件
|
||||
// 但如果是一次性选择多个文件,uploadFile 可能是其中一个。
|
||||
// 更稳妥的方式是:如果总和超标,则移除所有新文件中最后加入的那个,或者提示用户手动减少。
|
||||
// 这里我们尝试移除最后加入的一个新文件
|
||||
|
||||
// 找出所有新文件
|
||||
const newFiles = validFiles.filter((f) => f.raw);
|
||||
if (newFiles.length > 0) {
|
||||
// 移除最后一个新文件
|
||||
const lastNewFile = newFiles[newFiles.length - 1];
|
||||
const filteredFiles = validFiles.filter((f) => f.uid !== lastNewFile.uid);
|
||||
fileList.value = filteredFiles;
|
||||
} else {
|
||||
// 理论上不会走到这里,因为如果没有新文件,总大小不会增加
|
||||
fileList.value = validFiles;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. 校验全部通过,更新 fileList
|
||||
// 只有当 validFiles 与当前 fileList 不同时才赋值,避免不必要的触发
|
||||
if (validFiles.length !== fileList.value.length || validFiles.some((f, i) => f.uid !== fileList.value[i]?.uid)) {
|
||||
// 只有文件列表真正变化时才更新,避免不必要的响应式触发
|
||||
const currentList = fileList.value;
|
||||
if (validFiles.length !== currentList.length || validFiles.some((f, i) => f.uid !== currentList[i]?.uid)) {
|
||||
fileList.value = validFiles;
|
||||
}
|
||||
|
||||
// 解锁,允许下一次变更触发校验
|
||||
// 使用 nextTick 或 setTimeout 确保 DOM 更新后再解锁,防止极快连续操作的问题
|
||||
setTimeout(() => {
|
||||
isChecking.value = false;
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const blockedExts = ['.exe', '.bat', '.cmd', '.msi'];
|
||||
@@ -259,6 +239,8 @@ const allowExts = [
|
||||
'.gif',
|
||||
'.bmp',
|
||||
'.webp',
|
||||
// archive
|
||||
'.zip',
|
||||
// 专业/矢量图
|
||||
'.psd',
|
||||
'.ai',
|
||||
@@ -389,7 +371,7 @@ function handleBack() {
|
||||
width: 100%;
|
||||
}
|
||||
&:deep(.el-upload-list) {
|
||||
max-height: 200px;
|
||||
max-height: 250px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="flex flex-col h-full p-2">
|
||||
<pageheader title="办事记录"></pageheader>
|
||||
<pageheader></pageheader>
|
||||
<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">
|
||||
@@ -37,7 +37,7 @@
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="办事内容" align="center" prop="content">
|
||||
<template #default="scope">
|
||||
<div class="color-blue" v-html="scope.row.content"></div>
|
||||
<div class="color-blue moreRowEllipsis" v-html="scope.row.content"></div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="求助人" align="center" prop="seekName" width="120" />
|
||||
@@ -50,7 +50,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="附属材料" width="100" align="center" prop="handlePosition">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" @click="openDiage(scope.row)" link>点击查看</el-button>
|
||||
<el-button type="primary" v-if="scope.row.handleLogFileList?.length > 0" @click="openDialog(scope.row)" link>点击查看</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||
@@ -64,15 +64,15 @@
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
<!-- 添加或修改办事记录对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<ul class="ulbox" v-if="dialog.files.length > 0">
|
||||
<ul class="ulBox" v-if="dialog.files.length > 0">
|
||||
<li @click="handleDown(item)" class="files_item" v-for="(item, index) in dialog.files" :key="index">
|
||||
<div>
|
||||
{{ item.fileName }}
|
||||
</div>
|
||||
<span class="clickdown">点击下载</span>
|
||||
<span class="clickDown">点击下载</span>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="ulbox" v-else>
|
||||
<ul class="ulBox" v-else>
|
||||
<li class="files_item_no">
|
||||
<div>暂无数据</div>
|
||||
</li>
|
||||
@@ -83,14 +83,13 @@
|
||||
</template>
|
||||
|
||||
<script setup name="HandleLog" lang="ts">
|
||||
import { listHandleLog, delHandleLog } from '@/api/system/HandleLog/index';
|
||||
import { HandleLogVO, HandleLogQuery, HandleLogForm } from '@/api/system/HandleLog/type';
|
||||
import { listHandleLog, delHandleLog } from '@/api/system/HandleLog';
|
||||
import { HandleLogVO, HandleLogQuery, HandleLogForm, FileVO } from '@/api/system/HandleLog/type';
|
||||
import { checkPermi } from '@/utils/permission';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const handleLogList = ref<HandleLogVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
@@ -99,7 +98,6 @@ const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const handleLogFormRef = ref<ElFormInstance>();
|
||||
|
||||
const initFormData: HandleLogForm = {
|
||||
id: undefined,
|
||||
@@ -126,7 +124,7 @@ const data = reactive<PageData<HandleLogForm, HandleLogQuery>>({
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
const { queryParams } = toRefs(data);
|
||||
|
||||
/** 查询办事记录列表 */
|
||||
const getList = async () => {
|
||||
@@ -169,7 +167,7 @@ const handleAdd = () => {
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: HandleLogVO) => {
|
||||
const handleUpdate = (row?: HandleLogVO) => {
|
||||
const _id = row ? row.id : ids.value[0];
|
||||
router.push({
|
||||
path: '/repair/editHandleLog',
|
||||
@@ -192,14 +190,14 @@ const dialog = reactive({
|
||||
title: '',
|
||||
files: []
|
||||
});
|
||||
|
||||
const openDiage = (row) => {
|
||||
// 查看附属材料
|
||||
const openDialog = (row: HandleLogVO) => {
|
||||
dialog.visible = true;
|
||||
dialog.title = '查看附属材料';
|
||||
console.log(row);
|
||||
dialog.files = row.handleLogFileList ?? [];
|
||||
};
|
||||
const handleDown = (item) => {
|
||||
// 下载文件
|
||||
const handleDown = (item: FileVO) => {
|
||||
proxy?.$download.oss(item.ossId);
|
||||
};
|
||||
onMounted(() => {
|
||||
@@ -210,8 +208,16 @@ onMounted(() => {
|
||||
<style lang="scss" scoped>
|
||||
.el-table {
|
||||
height: calc(100% - 80px);
|
||||
// 超出部分省略号 3 行
|
||||
.moreRowEllipsis {
|
||||
word-break: break-all;
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
.ulbox {
|
||||
}
|
||||
.ulBox {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
@@ -233,12 +239,12 @@ onMounted(() => {
|
||||
&:hover {
|
||||
background-color: #f5f5f5;
|
||||
color: #409eff;
|
||||
.clickdown {
|
||||
.clickDown {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
.clickdown {
|
||||
.clickDown {
|
||||
color: #cccc;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="公告标题" prop="noticeTitle">
|
||||
<el-input maxlength="30" v-model.trim="form.noticeTitle" placeholder="请输入公告标题" />
|
||||
<el-input maxlength="50" v-model.trim="form.noticeTitle" placeholder="请输入公告标题" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- <el-col :span="12">-->
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</el-radio-group>
|
||||
<Holder v-if="form.scope === '1'" returnvalue="id" ref="HolderRef" :isMultiple="true" :userid="checkoutUses" @change="handleSelect">
|
||||
<template #default>
|
||||
<el-button type="primary" link @click="OpenUseTablesfun">选择业主</el-button>
|
||||
<el-button type="primary" link @click="OpenUseTablesFun">选择业主</el-button>
|
||||
</template>
|
||||
</Holder>
|
||||
</div>
|
||||
@@ -26,9 +26,9 @@
|
||||
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="时间范围" prop="timedata">
|
||||
<el-form-item label="时间范围" prop="timeData">
|
||||
<el-date-picker
|
||||
v-model="timedata"
|
||||
v-model="timeData"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
type="datetimerange"
|
||||
@@ -73,18 +73,16 @@ const { com_questionnaire_scope } = toRefs<any>(proxy?.useDict('com_questionnair
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
import { listResident } from '@/api/system/residentReviewProcess/resident';
|
||||
|
||||
const form = ref({
|
||||
scope: '0',
|
||||
residents: '',
|
||||
remark: ''
|
||||
});
|
||||
const timedata = ref([]);
|
||||
const timeData = ref([]);
|
||||
// ! 路由参数 --------------------------------------------------------------------------------
|
||||
// 打开
|
||||
const HolderRef = ref<InstanceType<typeof Holder>>();
|
||||
function OpenUseTablesfun() {
|
||||
function OpenUseTablesFun() {
|
||||
HolderRef.value.open(form.value.residents.split(',').filter((item) => item));
|
||||
}
|
||||
// 多选
|
||||
@@ -92,8 +90,8 @@ const checkoutUses = ref([]);
|
||||
function handleSelect(val) {
|
||||
checkoutUses.value = val;
|
||||
form.value.residents = val
|
||||
.map((item) => item)
|
||||
.filter((item) => item)
|
||||
.map((item: string) => item)
|
||||
.filter((item: string) => item)
|
||||
.join(',');
|
||||
}
|
||||
|
||||
@@ -104,25 +102,21 @@ const editData = ref<QuestionComponentnaireForm>(null);
|
||||
// ! 路由参数 --------------------------------------------------------------------------------
|
||||
const userid = ref(null);
|
||||
|
||||
onMounted(() => {
|
||||
if (route.query.id) {
|
||||
userid.value = route.query.id;
|
||||
handleEdit(userid.value);
|
||||
} else {
|
||||
handleAdd();
|
||||
}
|
||||
|
||||
//
|
||||
const tableData = ref([]);
|
||||
|
||||
});
|
||||
// 新增问卷
|
||||
function handleAdd() {
|
||||
editData.value = null;
|
||||
questionnaireEditRef.value?.reset();
|
||||
}
|
||||
// 编辑问卷
|
||||
async function handleEdit(id: string | number) {
|
||||
const res = await listResident();
|
||||
tableData.value = res.rows;
|
||||
function handleEdit(id: string | number) {
|
||||
// 父组件自己调用接口获取数据
|
||||
getQuestionnaire(id).then((res) => {
|
||||
editData.value = res.data as QuestionComponentnaireForm;
|
||||
@@ -137,7 +131,7 @@ async function handleEdit(id: string | number) {
|
||||
.split(',')
|
||||
.filter((item) => item)
|
||||
.map((item) => item);
|
||||
timedata.value = [res.data.startTime, res.data.endTime];
|
||||
timeData.value = [res.data.startTime, res.data.endTime];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -145,13 +139,13 @@ async function handleEdit(id: string | number) {
|
||||
async function handleSave(data: QuestionComponentnaireForm) {
|
||||
try {
|
||||
// 父组件自己调用接口提交
|
||||
if (userid.value) {
|
||||
if (userid.value !== null) {
|
||||
await updateQuestionnaire({
|
||||
...data,
|
||||
content: JSON.stringify(data.content),
|
||||
status: '0', // 草稿状态
|
||||
startTime: timedata.value[0],
|
||||
endTime: timedata.value[1],
|
||||
startTime: timeData.value[0],
|
||||
endTime: timeData.value[1],
|
||||
...form.value
|
||||
});
|
||||
} else {
|
||||
@@ -159,8 +153,8 @@ async function handleSave(data: QuestionComponentnaireForm) {
|
||||
...data,
|
||||
content: JSON.stringify(data.content),
|
||||
status: '0', // 草稿状态
|
||||
startTime: timedata.value[0],
|
||||
endTime: timedata.value[1],
|
||||
startTime: timeData.value[0],
|
||||
endTime: timeData.value[1],
|
||||
...form.value
|
||||
});
|
||||
}
|
||||
@@ -175,13 +169,13 @@ async function handleSave(data: QuestionComponentnaireForm) {
|
||||
// 发布问卷
|
||||
async function handlePublish(data: QuestionComponentnaireForm) {
|
||||
try {
|
||||
if (userid.value) {
|
||||
if (userid.value !== null) {
|
||||
await updateQuestionnaire({
|
||||
...data,
|
||||
content: JSON.stringify(data.content),
|
||||
status: '1', // 发布状态
|
||||
startTime: timedata.value[0],
|
||||
endTime: timedata.value[1],
|
||||
startTime: timeData.value[0],
|
||||
endTime: timeData.value[1],
|
||||
...form.value
|
||||
});
|
||||
} else {
|
||||
@@ -189,8 +183,8 @@ async function handlePublish(data: QuestionComponentnaireForm) {
|
||||
...data,
|
||||
content: JSON.stringify(data.content),
|
||||
status: '1', // 发布状态
|
||||
endTime: timedata.value[1],
|
||||
startTime: timedata.value[0],
|
||||
endTime: timeData.value[1],
|
||||
startTime: timeData.value[0],
|
||||
...form.value
|
||||
});
|
||||
}
|
||||
@@ -224,7 +218,7 @@ function handleCancel() {
|
||||
position: relative;
|
||||
|
||||
.formBody {
|
||||
.checkoutSideUsesbox {
|
||||
.checkoutSideUsesBox {
|
||||
margin-left: 130px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
</template>
|
||||
|
||||
<div class="question-title-area">
|
||||
<el-input maxlength="20" show-word-limit v-model="form.title" placeholder="请输入问卷标题" class="title-input" />
|
||||
<el-input maxlength="200" show-word-limit v-model="form.description" type="textarea" placeholder="请输入问卷描述(选填)" />
|
||||
<el-input maxlength="20" show-word-limit v-model.trim="form.title" placeholder="请输入问卷标题" class="title-input" />
|
||||
<el-input maxlength="200" show-word-limit v-model.trim="form.description" type="textarea" placeholder="请输入问卷描述(选填)" />
|
||||
</div>
|
||||
|
||||
<draggable v-model="form.content" group="components" item-key="cid" class="question-list" @add="handleAddQuestion">
|
||||
@@ -72,16 +72,21 @@
|
||||
</template>
|
||||
<el-form style="position: sticky; top: 60px" label-width="80px">
|
||||
<el-form-item label="题目标题">
|
||||
<el-input v-model="activeQuestion.title" placeholder="请输入题目标题" />
|
||||
<el-input maxlength="20" v-model.trim="activeQuestion.title" placeholder="请输入题目标题" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否必填">
|
||||
<el-switch v-model="activeQuestion.required" />
|
||||
<el-switch v-model.trim="activeQuestion.required" />
|
||||
</el-form-item>
|
||||
<!-- 单选/多选特有属性 -->
|
||||
<template v-if="activeQuestion.type === 'radio' || activeQuestion.type === 'checkbox'">
|
||||
<el-divider content-position="left">选项设置</el-divider>
|
||||
<div v-for="(opt, idx) in activeQuestion.options" :key="idx" class="option-item">
|
||||
<el-input v-model="opt.label" placeholder="选项内容" style="width: 200px; margin-right: 10px; margin-bottom: 10px" />
|
||||
<el-input
|
||||
maxlength="20"
|
||||
v-model.trim="opt.label"
|
||||
placeholder="选项内容"
|
||||
style="width: 200px; margin-right: 10px; margin-bottom: 10px"
|
||||
/>
|
||||
<el-button link type="danger" :icon="Delete" @click="activeQuestion.options.splice(idx, 1)"> 删除 </el-button>
|
||||
</div>
|
||||
<el-button type="primary" @click="activeQuestion.options.push({ label: '新选项' })"> 添加选项 </el-button>
|
||||
|
||||
@@ -82,7 +82,8 @@
|
||||
v-model:file-list="fileList"
|
||||
:action="uploadUrl"
|
||||
list-type="picture-card"
|
||||
:limit="1"
|
||||
:limit="9"
|
||||
:on-exceed="handleExceed"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:on-remove="handleRemove"
|
||||
:before-upload="handleChangeFile"
|
||||
@@ -213,6 +214,9 @@ const handleChangeFile: UploadProps['beforeUpload'] = (rawFile: UploadRawFile) =
|
||||
return true;
|
||||
};
|
||||
|
||||
const handleExceed: UploadProps['onExceed'] = () => {
|
||||
ElMessage.warning(`最多只能上传 9 个文件`);
|
||||
};
|
||||
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
|
||||
dialogImageUrl.value = uploadFile.url!;
|
||||
dialogVisible.value = true;
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="收费类型" prop="typeId">
|
||||
<el-select v-model="form.typeId">
|
||||
<el-option v-for="(item, index) in chargeitemlist" :key="index" :value="item.id" :label="item.name"></el-option>
|
||||
<el-option
|
||||
:disabled="item.status === '1'"
|
||||
v-for="(item, index) in chargeItemList"
|
||||
:key="index"
|
||||
:value="item.id"
|
||||
:label="item.name"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="计费方式" prop="billingType">
|
||||
@@ -84,7 +90,6 @@ const { com_charge_item_method } = toRefs<any>(proxy?.useDict('com_charge_item_m
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
const formRef = ref();
|
||||
const form = ref({
|
||||
'id': null,
|
||||
@@ -107,7 +112,7 @@ const rules = ref({
|
||||
{ required: true, message: '请输入 费用单价', trigger: 'blur' },
|
||||
{
|
||||
validator: (_: any, value: string | number, callback: (arg0?: Error) => any) => {
|
||||
if (value === '' || value === null) {
|
||||
if (value === '' || value === null || value === undefined || value === 0) {
|
||||
return callback(new Error('请输入费用单价'));
|
||||
} else {
|
||||
const val = Number(value);
|
||||
@@ -128,9 +133,9 @@ const rules = ref({
|
||||
carryMethod: [{ required: true, message: '请选择 进位方式', trigger: 'blur' }]
|
||||
});
|
||||
const userid = ref(null);
|
||||
const chargeitemlist = ref([]);
|
||||
const chargeItemList = ref([]);
|
||||
listChargeType().then((res) => {
|
||||
chargeitemlist.value = res.rows;
|
||||
chargeItemList.value = res.rows;
|
||||
});
|
||||
if (route.query.id) {
|
||||
userid.value = route.query.id;
|
||||
@@ -151,12 +156,12 @@ const submitForm = () => {
|
||||
formRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
if (userid.value) {
|
||||
updateChargeItem(form.value).then((res) => {
|
||||
updateChargeItem(form.value).then(() => {
|
||||
ElMessage.success('编辑成功');
|
||||
cancelForm();
|
||||
});
|
||||
} else {
|
||||
addChargeItem(form.value).then((res) => {
|
||||
addChargeItem(form.value).then(() => {
|
||||
ElMessage.success('添加成功');
|
||||
cancelForm();
|
||||
});
|
||||
@@ -170,9 +175,9 @@ const cancelForm = () => {
|
||||
};
|
||||
|
||||
// 车位费 物业费
|
||||
const typeNamelist = ref(['2049026520314445826']);
|
||||
const typeNameList = ref(['2049026520314445826']);
|
||||
function placeHolderFun(typeId: string) {
|
||||
return typeNamelist.value.includes(typeId) ? '请输入每日费用单价' : '请输入费用单价';
|
||||
return typeNameList.value.includes(typeId) ? '请输入每日费用单价' : '请输入费用单价';
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -31,7 +31,13 @@
|
||||
<div>
|
||||
<el-form-item label="收费项目" prop="itemId">
|
||||
<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>
|
||||
<el-option
|
||||
:disabled="item.status === '1'"
|
||||
v-for="(item, index) in chargeItems"
|
||||
:key="index"
|
||||
:value="item.id"
|
||||
:label="item.itemName"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="缴费周期" prop="chargePeriod">
|
||||
@@ -171,7 +177,6 @@
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="650px" append-to-body>
|
||||
<div class="payInfo">
|
||||
<div>
|
||||
@@ -237,7 +242,7 @@
|
||||
<el-tooltip class="box-item" effect="light" placement="top">
|
||||
<el-icon color="#909399" style="vertical-align: middle"><QuestionFilled /></el-icon>
|
||||
<template #content>
|
||||
<span>有账单 应缴费用 不足 优惠金额╬╬</span>
|
||||
<span>有账单 应缴费用 不足 优惠金额</span>
|
||||
</template>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
@@ -418,8 +423,7 @@ import { getCommunitylistAPI } from '@/api/system/community';
|
||||
import { billEdit, billlistType, billPrint, BillPrintType, billQuery } from '@/api/system/SdbCashier';
|
||||
import { listChargeItem } from '@/api/system/SdbChargeItem';
|
||||
import { ref } from 'vue';
|
||||
// import { printTicket, printTicketDiv } from '@/utils/print';
|
||||
import { add, div, eq, eqMoney, gtMoney, ltMoney, maxMoney, minMoney, moneyAdd, mul, sub, sum, toBig } from '@/utils/money';
|
||||
import { add, div, eq, eqMoney, gtMoney, ltMoney, minMoney, moneyAdd, mul, sub, sum, toBig } from '@/utils/money';
|
||||
import { BuildingUnitlist, BuildingVo, FloorsType } from '@/api/system/house/type';
|
||||
import { ChargeItemVO } from '@/api/system/SdbChargeItem/type';
|
||||
import { communitylist_rows_type } from '@/api/system/community/type';
|
||||
@@ -429,8 +433,8 @@ import { CirclePlus, Delete, QuestionFilled } from '@element-plus/icons-vue';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { com_pay_status, com_pay_method, com_charge_item_unit, com_bill_charge_period } = toRefs<any>(
|
||||
proxy?.useDict('com_pay_status', 'com_pay_method', 'com_charge_item_unit', 'com_bill_charge_period')
|
||||
const { com_pay_status, com_pay_method, com_charge_item_unit } = toRefs<any>(
|
||||
proxy?.useDict('com_pay_status', 'com_pay_method', 'com_charge_item_unit')
|
||||
);
|
||||
|
||||
const userStore = useUserStore();
|
||||
@@ -461,20 +465,34 @@ const villageId = localStorage.getItem('villageid') ?? undefined;
|
||||
const queryParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
// 收款状态
|
||||
payStatus: null,
|
||||
// 小区id
|
||||
villageId: villageId,
|
||||
// 楼栋id
|
||||
buildingId: undefined,
|
||||
// 单元id
|
||||
unitNoId: undefined,
|
||||
// 房屋id
|
||||
houseId: undefined,
|
||||
// 缴费周期
|
||||
chargePeriod: undefined,
|
||||
// 房屋类型id
|
||||
houseUseTypeId: undefined,
|
||||
// 缴费时间
|
||||
payTime: undefined,
|
||||
// 缴费人
|
||||
residentName: undefined,
|
||||
// 缴费项目id
|
||||
chargeItemId: undefined,
|
||||
period: undefined,
|
||||
// 缴费时间开始
|
||||
payTimeBegin: undefined,
|
||||
// 缴费时间结束
|
||||
payTimeEnd: undefined,
|
||||
// 开始时间
|
||||
startDate: undefined,
|
||||
// 结束时间
|
||||
endDate: undefined
|
||||
});
|
||||
|
||||
@@ -510,6 +528,7 @@ function handleChangeVillage(val: string) {
|
||||
queryParams.value.unitNoId = undefined;
|
||||
queryParams.value.buildingId = undefined;
|
||||
queryParams.value.chargeItemId = undefined;
|
||||
queryParams.value.houseId = undefined;
|
||||
buildingList.value = [];
|
||||
unitList.value = [];
|
||||
if (val) {
|
||||
@@ -523,7 +542,8 @@ function handleChangeVillage(val: string) {
|
||||
// 获取收费项目
|
||||
function handleChargeItem(id: string) {
|
||||
listChargeItem({
|
||||
villageId: id
|
||||
villageId: id,
|
||||
status: '0'
|
||||
}).then((res) => {
|
||||
chargeItems.value = res.rows;
|
||||
});
|
||||
@@ -582,6 +602,8 @@ const handleQuery = () => {
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
payTime.value = [];
|
||||
chargePeriod.value = [];
|
||||
queryParams.value = {
|
||||
chargePeriod: undefined,
|
||||
payTime: undefined,
|
||||
@@ -601,6 +623,7 @@ const resetQuery = () => {
|
||||
startDate: undefined,
|
||||
endDate: undefined
|
||||
};
|
||||
queryParams.value.villageId = villageId;
|
||||
handleQuery();
|
||||
};
|
||||
// 控制收费 按钮 不能有已缴纳的(后端会校验)
|
||||
@@ -998,11 +1021,13 @@ function conFimPrint() {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
queryParams.value.villageId = villageId;
|
||||
getList();
|
||||
getHouseTypeList();
|
||||
// 全部小区
|
||||
getCommunitylistAPI().then((res) => {
|
||||
villageList.value = res.rows;
|
||||
handleChangeVillage(queryParams.value.villageId);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -30,19 +30,25 @@
|
||||
<div class="main">{{ form.visitorPhone }}</div>
|
||||
</div>
|
||||
<div class="carinfo_item">
|
||||
<div class="label">访问日期:</div>
|
||||
<div class="label">访问人数:</div>
|
||||
<div class="main" style="text-wrap: wrap">
|
||||
<span>{{ form.startTime }}</span>
|
||||
<span>{{ form.visitorNum }}人</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="carinfo_item">
|
||||
<div class="label">访问时长:</div>
|
||||
<div class="main">{{ formatTimeDiff(form.startTime, form.endTime) }}</div>
|
||||
</div>
|
||||
<div class="carinfo_item">
|
||||
<div class="label">访问日期:</div>
|
||||
<div class="main" style="text-wrap: wrap">
|
||||
<span>{{ form.startTime }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="carinfo_item">
|
||||
<div class="label">访问业主:</div>
|
||||
<div class="main flex align-items-center">
|
||||
<div>去丽丽</div>
|
||||
<div>去丽丽╬╬╬╬</div>
|
||||
<div class="ml-20px color-blue cursor-pointer">住户详情</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
@@ -278,7 +278,7 @@ const rules = ref({
|
||||
{
|
||||
validator: (_: any, value: string | number, callback: (arg0?: Error) => void) => {
|
||||
if (value === '' || value === null || value === 0) {
|
||||
return callback(new Error('请输入房屋面积'));
|
||||
return callback();
|
||||
}
|
||||
const val = Number(value);
|
||||
if (Number.isNaN(val)) {
|
||||
@@ -371,7 +371,8 @@ const handleExceed = () => {
|
||||
ElMessage.warning('最多上传9张图片');
|
||||
};
|
||||
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
|
||||
dialogImageUrl.value = uploadFile.url!;
|
||||
dialogImageUrl.value = '';
|
||||
dialogImageUrl.value = uploadFile.url;
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
const handleRemove: UploadProps['onRemove'] = (_, uploadFiles) => {
|
||||
|
||||
@@ -142,7 +142,7 @@ const exportChecked = () => {
|
||||
list: listValue.join(','),
|
||||
dataType: '1'
|
||||
},
|
||||
`巡检日报_选中${listValue.length}条数据_${new Date().toLocaleString()}.xlsx`,
|
||||
`巡检日报_选中${listValue.length}条数据_${new Date().toLocaleString()}.xlsx`
|
||||
);
|
||||
} else {
|
||||
ElMessage.warning('请选择数据');
|
||||
|
||||
@@ -168,7 +168,7 @@ const data = reactive<PageData<NoticeForm, NoticeQuery>>({
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询公告列表╬ */
|
||||
/** 查询公告列表╬╬╬╬╬ */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
listNotice(queryParams.value)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="公告标题" prop="noticeTitle">
|
||||
<el-input maxlength="20" v-model.trim="form.noticeTitle" placeholder="请输入公告标题" />
|
||||
<el-input maxlength="50" v-model.trim="form.noticeTitle" placeholder="请输入公告标题" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- <el-col :span="12">-->
|
||||
|
||||
Reference in New Issue
Block a user