7/17 添加公区收益
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { ResidentVO, ResidentForm, ResidentQuery } from '@/api/system/resident/type';
|
||||
import { ResidentVO, ResidentForm, ResidentQuery } from '@/api/system/residentReviewProcess/resident/type';
|
||||
|
||||
/**
|
||||
* 查询住户管理列表
|
||||
63
src/api/system/revenueNotice/index.ts
Normal file
63
src/api/system/revenueNotice/index.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { RevenueNoticeVO, RevenueNoticeForm, RevenueNoticeQuery } from './type';
|
||||
|
||||
/**
|
||||
* 查询公区收益通知列表
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
export const listRevenueNotice = (query?: RevenueNoticeQuery): AxiosPromise<RevenueNoticeVO[]> => {
|
||||
return request({
|
||||
url: '/revenueNotice/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询公区收益通知详细
|
||||
* @param noticeId
|
||||
*/
|
||||
export const getRevenueNotice = (noticeId: string | number): AxiosPromise<RevenueNoticeVO> => {
|
||||
return request({
|
||||
url: '/revenueNotice/' + noticeId,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增公区收益通知
|
||||
* @param data
|
||||
*/
|
||||
export const addRevenueNotice = (data: RevenueNoticeForm) => {
|
||||
return request({
|
||||
url: '/revenueNotice',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改公区收益通知
|
||||
* @param data
|
||||
*/
|
||||
export const updateRevenueNotice = (data: RevenueNoticeForm) => {
|
||||
return request({
|
||||
url: '/revenueNotice',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除公区收益通知
|
||||
* @param noticeId
|
||||
*/
|
||||
export const delRevenueNotice = (noticeId: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/revenueNotice/' + noticeId,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
140
src/api/system/revenueNotice/type.ts
Normal file
140
src/api/system/revenueNotice/type.ts
Normal file
@@ -0,0 +1,140 @@
|
||||
export interface RevenueNoticeVO {
|
||||
/**
|
||||
* 公告ID
|
||||
*/
|
||||
noticeId: string | number;
|
||||
|
||||
/**
|
||||
* 公告标题
|
||||
*/
|
||||
noticeTitle: string;
|
||||
|
||||
/**
|
||||
* 公告内容
|
||||
*/
|
||||
noticeContent: string;
|
||||
|
||||
/**
|
||||
* 作者
|
||||
*/
|
||||
author: string;
|
||||
|
||||
/**
|
||||
* 紧急程度 0=普通 1=紧急 2=非常紧急
|
||||
*/
|
||||
urgencyLevel: number;
|
||||
|
||||
/**
|
||||
* 发布状态 0=草稿 1=已发布
|
||||
*/
|
||||
publishStatus: number;
|
||||
|
||||
/**
|
||||
* 发布人
|
||||
*/
|
||||
publishBy: string;
|
||||
|
||||
/**
|
||||
* 发布日期
|
||||
*/
|
||||
publishTime: string;
|
||||
|
||||
/**
|
||||
* 所属小区id
|
||||
*/
|
||||
villageId: string | number;
|
||||
}
|
||||
|
||||
export interface RevenueNoticeForm extends BaseEntity {
|
||||
/**
|
||||
* 公告ID
|
||||
*/
|
||||
noticeId?: string | number;
|
||||
|
||||
/**
|
||||
* 公告标题
|
||||
*/
|
||||
noticeTitle?: string;
|
||||
|
||||
/**
|
||||
* 公告内容
|
||||
*/
|
||||
noticeContent?: string;
|
||||
|
||||
/**
|
||||
* 作者
|
||||
*/
|
||||
author?: string;
|
||||
|
||||
/**
|
||||
* 紧急程度 0=普通 1=紧急 2=非常紧急
|
||||
*/
|
||||
urgencyLevel?: number;
|
||||
|
||||
/**
|
||||
* 发布状态 0=草稿 1=已发布
|
||||
*/
|
||||
publishStatus?: number;
|
||||
|
||||
/**
|
||||
* 发布人
|
||||
*/
|
||||
publishBy?: string;
|
||||
|
||||
/**
|
||||
* 发布日期
|
||||
*/
|
||||
publishTime?: string;
|
||||
|
||||
/**
|
||||
* 所属小区id
|
||||
*/
|
||||
villageId?: string | number;
|
||||
}
|
||||
|
||||
export interface RevenueNoticeQuery extends PageQuery {
|
||||
/**
|
||||
* 公告标题
|
||||
*/
|
||||
noticeTitle?: string;
|
||||
|
||||
/**
|
||||
* 公告内容
|
||||
*/
|
||||
noticeContent?: string;
|
||||
|
||||
/**
|
||||
* 作者
|
||||
*/
|
||||
author?: string;
|
||||
|
||||
/**
|
||||
* 紧急程度 0=普通 1=紧急 2=非常紧急
|
||||
*/
|
||||
urgencyLevel?: number;
|
||||
|
||||
/**
|
||||
* 发布状态 0=草稿 1=已发布
|
||||
*/
|
||||
publishStatus?: number;
|
||||
|
||||
/**
|
||||
* 发布人
|
||||
*/
|
||||
publishBy?: string;
|
||||
|
||||
/**
|
||||
* 发布日期
|
||||
*/
|
||||
publishTime?: string;
|
||||
|
||||
/**
|
||||
* 所属小区id
|
||||
*/
|
||||
villageId?: string | number;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
@@ -65,6 +65,33 @@ export const workSpaceIncomeTrendListApi = (
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 收费率统计
|
||||
* @returns {*}
|
||||
*/
|
||||
export const paymentRateApi = (
|
||||
startDate: string,
|
||||
endDate: string
|
||||
): Promise<{
|
||||
data: {
|
||||
'receivableAmount': string;
|
||||
'receivablePercent': string;
|
||||
'receivedAmount': string;
|
||||
'receivedPercent': string;
|
||||
'unpaidAmount': string;
|
||||
'unpaidPercent': string;
|
||||
};
|
||||
}> => {
|
||||
return request({
|
||||
url: '/workSpace/paymentRate',
|
||||
method: 'GET',
|
||||
params: {
|
||||
startDate: startDate,
|
||||
endDate: endDate
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询近一周支出趋势
|
||||
* @returns {*}
|
||||
|
||||
1
src/assets/icons/svg/gongqushouyi.svg
Normal file
1
src/assets/icons/svg/gongqushouyi.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1784617479089" class="icon" viewBox="0 0 1057 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1942" xmlns:xlink="http://www.w3.org/1999/xlink" width="206.4453125" height="200"><path d="M811.80137 607.92511a170.673929 170.673929 0 1 0 170.761074 170.695715 170.870006 170.870006 0 0 0-170.673929-170.673929m0-74.661674A245.357389 245.357389 0 1 1 566.443981 778.620825a245.357389 245.357389 0 0 1 245.357389-245.357389z" p-id="1943" fill="#2c2c2c"></path><path d="M873.718055 889.447768a251.413982 251.413982 0 0 1-3.442237-7.973788c-1.568614-3.616527-2.984724-6.971618-4.466193-10.348496a1687.218757 1687.218757 0 0 1-132.787541 13.529297l-4.771201 0.326794-5.816944-31.067273 4.553338-1.394324c10.32671-3.355091 30.195821-24.24816 66.666099-104.835709l2.047913-4.553338 32.309094 11.132802-2.592571 5.555509a669.209991 669.209991 0 0 1-51.08889 90.60925c26.535722-2.178631 52.505-4.945492 77.297817-8.540232a388.340922 388.340922 0 0 0-20.413769-34.967023l-3.921536-5.882302 30.50083-10.413855 2.178631 3.42045a501.455427 501.455427 0 0 1 44.378707 81.611506l2.178631 4.945492-30.740479 13.856091z m26.513935-91.502489a233.919578 233.919578 0 0 1-72.766265-114.792051l-1.263606-4.139399 28.627207-16.274371 2.047913 6.535892a209.802136 209.802136 0 0 0 66.361091 102.047062l4.204758 3.59474-23.137058 26.535722z m-204.050551-19.607676l4.357261-4.139399a236.686439 236.686439 0 0 0 61.655249-103.049232l1.786477-5.555508 30.91477 12.265691-1.633973 4.858346a277.470406 277.470406 0 0 1-67.537552 114.639548l-3.59474 3.442236z" p-id="1944" fill="#2c2c2c"></path><path d="M515.267946 643.240713l142.090294 13.311434-13.33322-140.151313 13.33322-140.020595-145.968257 13.071784-157.013914-12.810348 13.485724 135.075103-13.071784 144.138207z m-81.872942-188.887281l78.299988 6.383388 66.949321-6.034807-5.882303 61.698821 5.860517 61.524531-62.83171-5.882303-82.787966 6.535892 6.100166-67.145398z" p-id="1945" fill="#2c2c2c"></path><path d="M589.297817 900.863793a408.798264 408.798264 0 1 1 312.764223-317.317561 45.903749 45.903749 0 1 0 89.933875 18.365857 500.583975 500.583975 0 1 0-383.025063 388.602357 45.903749 45.903749 0 1 0-19.607676-89.650653z" p-id="1946" fill="#2c2c2c"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -1,17 +1,37 @@
|
||||
<template>
|
||||
<!-- 原有图片上传 -->
|
||||
<div>
|
||||
<el-upload
|
||||
v-if="type"
|
||||
action=""
|
||||
:action="uploadUrl"
|
||||
:headers="headerToken()"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:http-request="handleUploadRequest"
|
||||
class="editor-img-uploader"
|
||||
name="file"
|
||||
name="files"
|
||||
:show-file-list="false"
|
||||
>
|
||||
<i ref="uploadRef"></i>
|
||||
</el-upload>
|
||||
</div>
|
||||
|
||||
<!-- 新增:文件附件上传(Word/PDF/Excel) -->
|
||||
<div>
|
||||
<el-upload
|
||||
v-if="type"
|
||||
:action="uploadUrl"
|
||||
:headers="headerToken()"
|
||||
:before-upload="handleBeforeFileUpload"
|
||||
:http-request="handleFileUploadRequest"
|
||||
class="editor-file-uploader"
|
||||
name="files"
|
||||
accept=".pdf,.doc,.docx,.xls,.xlsx,.zip"
|
||||
:show-file-list="false"
|
||||
>
|
||||
<i ref="fileUploadRef"></i>
|
||||
</el-upload>
|
||||
</div>
|
||||
|
||||
<div class="editor">
|
||||
<quill-editor
|
||||
ref="quillEditorRef"
|
||||
@@ -19,7 +39,7 @@
|
||||
content-type="html"
|
||||
:options="options"
|
||||
:style="styles"
|
||||
@text-change="(e: any) => $emit('update:modelValue', content)"
|
||||
@text-change="() => $emit('update:modelValue', content)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -27,9 +47,11 @@
|
||||
<script setup lang="ts">
|
||||
import '@vueup/vue-quill/dist/vue-quill.snow.css';
|
||||
|
||||
import { QuillEditor, Quill } from '@vueup/vue-quill';
|
||||
import { Quill, QuillEditor } from '@vueup/vue-quill';
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
import type { UploadRequestHandler, UploadRequestOptions } from 'element-plus';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import axios from 'axios';
|
||||
|
||||
defineEmits(['update:modelValue']);
|
||||
|
||||
@@ -45,14 +67,20 @@ const props = defineProps({
|
||||
/* 上传文件大小限制(MB) */
|
||||
fileSize: propTypes.number.def(5),
|
||||
/* 类型(base64格式、url格式) */
|
||||
type: propTypes.string.def('base64')
|
||||
type: propTypes.string.def('url')
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const quillEditorRef = ref();
|
||||
const useStore = useUserStore();
|
||||
function headerToken() {
|
||||
return {
|
||||
Authorization: 'Bearer ' + useStore.token
|
||||
};
|
||||
}
|
||||
const uploadRef = ref<HTMLDivElement>();
|
||||
|
||||
const uploadUrl = import.meta.env.VITE_APP_BASE_API + '/handleLog/uploadAttachments';
|
||||
const options = ref<any>({
|
||||
theme: 'snow',
|
||||
bounds: document.body,
|
||||
@@ -70,7 +98,8 @@ const options = ref<any>({
|
||||
[{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
|
||||
[{ align: [] }], // 对齐方式
|
||||
['clean'], // 清除文本格式
|
||||
['link', 'image', 'video'] // 链接、图片、视频
|
||||
// ['image', 'video', 'link'] // 图片、视频、链接、文件
|
||||
['image'] // 图片
|
||||
],
|
||||
handlers: {
|
||||
image: (value: boolean) => {
|
||||
@@ -83,8 +112,9 @@ const options = ref<any>({
|
||||
},
|
||||
link: function (value) {
|
||||
if (value) {
|
||||
const href = prompt('输入文件链接地址');
|
||||
Quill.format('link', href);
|
||||
// const href = prompt('输入网络文件链接地址');
|
||||
// Quill.format('link', href);
|
||||
fileUploadRef.value?.click();
|
||||
} else {
|
||||
Quill.format('link', false);
|
||||
}
|
||||
@@ -140,47 +170,218 @@ const handleBeforeUpload = (file: any) => {
|
||||
};
|
||||
|
||||
// base64 模式插入图片
|
||||
const handleUploadRequest: UploadRequestHandler = (options: UploadRequestOptions) => {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
const file = options.file as File;
|
||||
const quill = toRaw(quillEditorRef.value)?.getQuill();
|
||||
if (!quill) {
|
||||
proxy?.$modal.msgError('编辑器未就绪');
|
||||
proxy?.$modal.closeLoading();
|
||||
reject(new Error('editor not ready'));
|
||||
return;
|
||||
}
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
const base64 = reader.result as string;
|
||||
const range = quill.selection?.savedRange;
|
||||
const length = range ? range.index : quill.getLength();
|
||||
quill.insertEmbed(length, 'image', base64);
|
||||
quill.setSelection(length + 1);
|
||||
proxy?.$modal.closeLoading();
|
||||
options.onSuccess?.({ url: base64 });
|
||||
resolve();
|
||||
};
|
||||
reader.onerror = () => {
|
||||
proxy?.$modal.msgError('图片插入失败');
|
||||
proxy?.$modal.closeLoading();
|
||||
const err = Object.assign(new Error('read image failed'), {
|
||||
status: 0,
|
||||
method: 'POST',
|
||||
url: options.action || ''
|
||||
});
|
||||
options.onError?.(err as any);
|
||||
reject(err);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
};
|
||||
</script>
|
||||
const handleUploadRequest: UploadRequestHandler = async (options: UploadRequestOptions) => {
|
||||
const file = options.file as File;
|
||||
const quill = toRaw(quillEditorRef.value)?.getQuill();
|
||||
if (!quill) {
|
||||
proxy?.$modal.msgError('编辑器未就绪');
|
||||
proxy?.$modal.closeLoading();
|
||||
return Promise.reject(new Error('editor not ready'));
|
||||
}
|
||||
const range = quill.selection?.savedRange;
|
||||
const insertIndex = range ? range.index : quill.getLength();
|
||||
|
||||
<style>
|
||||
.editor-img-uploader {
|
||||
display: none;
|
||||
if (props.type === 'base64') {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
const base64 = reader.result as string;
|
||||
const range = quill.selection?.savedRange;
|
||||
const length = range ? range.index : quill.getLength();
|
||||
quill.insertEmbed(length, 'image', base64);
|
||||
quill.setSelection(length + 1);
|
||||
proxy?.$modal.closeLoading();
|
||||
options.onSuccess?.({ url: base64 });
|
||||
resolve();
|
||||
};
|
||||
reader.onerror = () => {
|
||||
proxy?.$modal.msgError('图片插入失败');
|
||||
proxy?.$modal.closeLoading();
|
||||
const err = Object.assign(new Error('read image failed'), {
|
||||
status: 0,
|
||||
method: 'POST',
|
||||
url: options.action || ''
|
||||
});
|
||||
options.onError?.(err as any);
|
||||
reject(err);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
}
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('files', file); // 和ImageExtend配置name保持一致 img
|
||||
const res = await axios.post(uploadUrl, formData, {
|
||||
headers: {
|
||||
...headerToken(),
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
const successList = res.data.data.success;
|
||||
if (successList.length > 0) {
|
||||
// 多张图片依次向后插入,不覆盖光标
|
||||
let index = insertIndex;
|
||||
for (let i = 0; i < successList.length; i++) {
|
||||
// 根据后端返回结构取图片地址
|
||||
const imgUrl = successList[i].url;
|
||||
// 插入真实图片地址到富文本
|
||||
quill.insertEmbed(index, 'image', imgUrl);
|
||||
index += 1;
|
||||
proxy?.$modal.closeLoading();
|
||||
options.onSuccess?.({ url: imgUrl });
|
||||
}
|
||||
} else {
|
||||
proxy?.$modal.msgError('图片上传服务器失败');
|
||||
return Promise.reject();
|
||||
}
|
||||
return Promise.resolve(null);
|
||||
} catch (err) {
|
||||
proxy?.$modal.msgError('图片上传服务器失败');
|
||||
options.onError?.(err as any);
|
||||
return Promise.reject(err);
|
||||
} finally {
|
||||
proxy?.$modal.closeLoading();
|
||||
}
|
||||
};
|
||||
// 解决【粘贴图片自动base64】核心修复
|
||||
// 监听编辑器粘贴事件,拦截粘贴图片并调用上传接口
|
||||
let pasteHandler: ((e: ClipboardEvent) => Promise<void>) | null = null;
|
||||
watch(
|
||||
quillEditorRef,
|
||||
(val) => {
|
||||
if (!val || props.type !== 'url') return;
|
||||
const quill = toRaw(val).getQuill();
|
||||
pasteHandler = async (e: ClipboardEvent) => {
|
||||
const items = e.clipboardData?.items;
|
||||
if (!items) return;
|
||||
const fileItems = Array.from(items).filter((it) => it.kind === 'file');
|
||||
if (!fileItems.length) return;
|
||||
e.preventDefault();
|
||||
|
||||
proxy?.$modal.loading('正在上传粘贴图片...');
|
||||
for (const item of fileItems) {
|
||||
const file = item.getAsFile();
|
||||
if (!file) continue;
|
||||
const pass = handleBeforeUpload(file);
|
||||
if (!pass) {
|
||||
proxy?.$modal.closeLoading();
|
||||
return;
|
||||
}
|
||||
// 构造合法参数,去除不安全强转
|
||||
await handleUploadRequest({
|
||||
file,
|
||||
action: uploadUrl,
|
||||
onSuccess: () => {},
|
||||
onError: () => {},
|
||||
data: [],
|
||||
name: 'files'
|
||||
} as unknown as UploadRequestOptions);
|
||||
}
|
||||
};
|
||||
quill.container.addEventListener('paste', pasteHandler);
|
||||
},
|
||||
{ flush: 'post' }
|
||||
);
|
||||
|
||||
// 新增文件上传ref
|
||||
const fileUploadRef = ref<HTMLElement>();
|
||||
|
||||
// 文件上传前校验(限制文档格式)
|
||||
const handleBeforeFileUpload = (file: File) => {
|
||||
const allowTypes = [
|
||||
'application/pdf',
|
||||
'application/msword',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'application/zip'
|
||||
];
|
||||
const ext = file.name.split('.').pop();
|
||||
const allowExt = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'zip'];
|
||||
if (!allowTypes.includes(file.type) && !allowExt.includes(ext)) {
|
||||
proxy?.$modal.msgError('仅支持PDF、Word、Excel、Zip文件');
|
||||
return false;
|
||||
}
|
||||
// 文件大小限制
|
||||
const maxByte = props.fileSize * 1024 * 1024;
|
||||
if (file.size > maxByte) {
|
||||
proxy?.$modal.msgError(`文件不能超过${props.fileSize}MB`);
|
||||
return false;
|
||||
}
|
||||
proxy?.$modal.loading('附件上传中...');
|
||||
return true;
|
||||
};
|
||||
|
||||
// 文件自定义上传逻辑,上传成功插入a链接
|
||||
const handleFileUploadRequest: UploadRequestHandler = async (options) => {
|
||||
const file = options.file as File;
|
||||
const quill = toRaw(quillEditorRef.value)?.getQuill();
|
||||
if (!quill) {
|
||||
proxy?.$modal.msgError('编辑器未就绪');
|
||||
proxy?.$modal.closeLoading();
|
||||
return Promise.reject();
|
||||
}
|
||||
const insertIndex = quill.selection?.savedRange?.index ?? quill.getLength();
|
||||
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('files', file);
|
||||
const res = await axios.post(uploadUrl, formData, {
|
||||
headers: {
|
||||
...headerToken(),
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
const successList = res.data.data?.success ?? [];
|
||||
if (!successList.length) {
|
||||
throw new Error('上传无返回地址');
|
||||
}
|
||||
|
||||
// 循环插入下载链接 <a href="url" target="_blank">文件名</a>
|
||||
let curIndex = insertIndex;
|
||||
successList.forEach((item) => {
|
||||
// 拼接带下载属性的a标签HTML
|
||||
const linkHtml = `<a href="${item.url}" target="_blank" download="${file.name}" style="color:#409EFF;text-decoration:underline;margin:0 4px;">${file.name}</a>`;
|
||||
// 在光标位置插入HTML链接
|
||||
quill.clipboard.dangerouslyPasteHTML(curIndex, linkHtml);
|
||||
curIndex += linkHtml.length;
|
||||
});
|
||||
quill.setSelection(curIndex);
|
||||
options.onSuccess?.({ url: successList[0].url });
|
||||
} catch (err) {
|
||||
proxy?.$modal.msgError('附件上传失败');
|
||||
options.onError?.(err as any);
|
||||
return Promise.reject(err);
|
||||
} finally {
|
||||
proxy?.$modal.closeLoading();
|
||||
}
|
||||
};
|
||||
|
||||
onUnmounted(() => {
|
||||
const quill = toRaw(quillEditorRef.value)?.getQuill();
|
||||
if (quill) {
|
||||
if (pasteHandler) {
|
||||
quill.container.removeEventListener('paste', pasteHandler);
|
||||
pasteHandler = null;
|
||||
}
|
||||
quill.destroy();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
:deep(.ql-snow .ql-toolbar button.ql-file) {
|
||||
width: 40px;
|
||||
font-size: 12px;
|
||||
}
|
||||
:deep(.ql-snow .ql-toolbar button.ql-file::before) {
|
||||
all: unset !important;
|
||||
content: '附件';
|
||||
display: block;
|
||||
text-align: center;
|
||||
line-height: 24px;
|
||||
}
|
||||
</style>
|
||||
<style scoped>
|
||||
.editor,
|
||||
.ql-toolbar {
|
||||
white-space: pre-wrap !important;
|
||||
|
||||
@@ -76,8 +76,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { listResident } from '@/api/system/resident';
|
||||
import { ResidentVO } from '@/api/system/resident/type';
|
||||
import { listResident } from '@/api/system/residentReviewProcess/resident';
|
||||
import { ResidentVO } from '@/api/system/residentReviewProcess/resident/type';
|
||||
import { ref, nextTick, getCurrentInstance, ComponentInternalInstance, toRefs } from 'vue';
|
||||
import { useHouseStore } from '@/store/modules/house';
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ResidentVO } from '@/api/system/resident/type';
|
||||
import { ResidentVO } from '@/api/system/residentReviewProcess/resident/type';
|
||||
import { getUserByRoleKey } from '@/api/system/user';
|
||||
import { ref, watch, nextTick, getCurrentInstance, ComponentInternalInstance, toRefs } from 'vue';
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ const toggleSideBar = () => {
|
||||
};
|
||||
|
||||
const logout = async () => {
|
||||
await ElMessageBox.confirm('确定注销并退出系统吗?', '提示', {
|
||||
await ElMessageBox.confirm('确定退出系统吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
|
||||
@@ -156,9 +156,10 @@ export function toFixedMoney(num: string | number, digit = 2): number {
|
||||
* 智能金额格式化(带单位:元/万元/亿元)
|
||||
* 兼容:数字、字符串、null、undefined
|
||||
* @param {number|string} amount 金额
|
||||
* @param {number} unitNumber 保留几个小数 默认 2位
|
||||
* @returns {string} 格式化后带单位的金额
|
||||
*/
|
||||
export function formatMoneyWithUnit(amount) {
|
||||
export function formatMoneyWithUnit(amount: number | string, unitNumber: number = 2): string {
|
||||
// 空值处理
|
||||
if (amount == null || amount === '') return '0.00 元';
|
||||
|
||||
@@ -170,13 +171,13 @@ export function formatMoneyWithUnit(amount) {
|
||||
|
||||
if (absNum >= 100000000) {
|
||||
// 亿元
|
||||
return (num / 100000000).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',') + ' 亿元';
|
||||
return (num / 100000000).toFixed(unitNumber).replace(/\B(?=(\d{3})+(?!\d))/g, ',') + ' 亿元';
|
||||
} else if (absNum >= 10000) {
|
||||
// 万元
|
||||
return (num / 10000).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',') + ' 万元';
|
||||
return (num / 10000).toFixed(unitNumber).replace(/\B(?=(\d{3})+(?!\d))/g, ',') + ' 万元';
|
||||
} else {
|
||||
// 元
|
||||
return num.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',') + ' 元';
|
||||
return num.toFixed(unitNumber).replace(/\B(?=(\d{3})+(?!\d))/g, ',') + ' 元';
|
||||
}
|
||||
}
|
||||
// 带货币符号(¥)版本
|
||||
|
||||
@@ -327,6 +327,9 @@ export function printTicketDiv(elementId: string, title: string = '票据打印'
|
||||
table-layout: fixed;
|
||||
margin: 0.1cm 0;
|
||||
page-break-inside: avoid !important;
|
||||
transform-origin: top left;
|
||||
/* 初始不缩放,由JS动态控制 */
|
||||
page-break-after: avoid !important;
|
||||
}
|
||||
table th, table td {
|
||||
border: 1px solid #333;
|
||||
@@ -360,6 +363,154 @@ export function printTicketDiv(elementId: string, title: string = '票据打印'
|
||||
</html>
|
||||
`);
|
||||
win.document.close();
|
||||
win.onload = () => {
|
||||
const printContainer = win.document.getElementById(elementId);
|
||||
if (!printContainer) {
|
||||
win.close();
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
const containerHeightPx = printContainer.clientHeight;
|
||||
const contentHeightPx = printContainer.scrollHeight;
|
||||
const containerWidthPx = printContainer.clientWidth;
|
||||
const contentWidthPx = printContainer.scrollWidth;
|
||||
|
||||
// 固定顶部偏移量(约0.2cm),确保打印边缘不裁切内容╬D2╬╬2Σ╬╬╬╬2╬2222╬╬2╬22╬22╬22╬2╬╬2╬╬
|
||||
const offsetPx = 20; // 可根据实际效果调整
|
||||
|
||||
// 计算可用高度(减去偏移)
|
||||
const availableHeight = containerHeightPx - offsetPx;
|
||||
|
||||
// 如果内容高度超过可用高度,或宽度超过容器宽度,则等比缩放
|
||||
let scale = 1;
|
||||
let needScale = false;
|
||||
|
||||
if (contentHeightPx > availableHeight) {
|
||||
scale = availableHeight / contentHeightPx;
|
||||
needScale = true;
|
||||
}
|
||||
if (contentWidthPx > containerWidthPx) {
|
||||
const scaleW = containerWidthPx / contentWidthPx;
|
||||
if (scaleW < scale) {
|
||||
scale = scaleW;
|
||||
needScale = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 应用 transform:先缩放(如果需要),再整体下移固定偏移
|
||||
if (needScale) {
|
||||
printContainer.style.transform = `translateY(${offsetPx}px) scale(${scale})`;
|
||||
} else {
|
||||
// 即使不缩放,也下移避免顶部贴边
|
||||
printContainer.style.transform = `translateY(${offsetPx}px)`;
|
||||
}
|
||||
// 确保缩放原点在左上,保证缩放后位置正确
|
||||
printContainer.style.transformOrigin = 'top left';
|
||||
|
||||
// 执行打印
|
||||
win.print();
|
||||
win.close();
|
||||
callback && callback();
|
||||
}, 300); // 等待渲染完成
|
||||
};
|
||||
}
|
||||
|
||||
export function printTicketDiv2(elementId: string, title: string = '票据打印', callback?: () => void) {
|
||||
const el = document.getElementById(elementId);
|
||||
if (!el) {
|
||||
console.error('未找到打印元素');
|
||||
return;
|
||||
}
|
||||
const win = window.open('', '_blank', 'width=1200,height=1000');
|
||||
if (!win) return;
|
||||
|
||||
// 复制全局非scoped样式(Element Plus、全局公共样式)
|
||||
const styles = Array.from(document.querySelectorAll('link[rel="stylesheet"], style:not([scoped])'))
|
||||
.map((item) => item.outerHTML)
|
||||
.join('');
|
||||
|
||||
// 专属打印样式,根治空白第二页
|
||||
const printScopeStyle = `
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
html, body {
|
||||
height: auto !important;
|
||||
min-height: auto !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
background: #fff;
|
||||
font-size: 12px;
|
||||
font-family: "Microsoft YaHei", sans-serif;
|
||||
}
|
||||
|
||||
/* 隐藏弹窗无关组件:输入框、按钮、弹窗头部 */
|
||||
.el-input {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* 纸张自适应宽高,无边距 */
|
||||
@page {
|
||||
size: auto auto;
|
||||
margin: 0mm !important;
|
||||
}
|
||||
|
||||
/* 打印容器核心禁止分页 */
|
||||
#${elementId} {
|
||||
margin: 0 auto !important;
|
||||
overflow: visible;
|
||||
page-break-inside: avoid !important;
|
||||
page-break-after: avoid !important;
|
||||
break-inside: avoid !important;
|
||||
break-after: avoid !important;
|
||||
}
|
||||
|
||||
/* 表格禁止截断、压缩高度 */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100% !important;
|
||||
table-layout: fixed;
|
||||
margin: 0.1cm 0;
|
||||
page-break-inside: avoid !important;
|
||||
break-inside: avoid !important;
|
||||
}
|
||||
table th, table td {
|
||||
border: 1px solid #333;
|
||||
font-size: 10px;
|
||||
height:32px; /* 缩小行高减少整体高度 */
|
||||
min-width:80px;
|
||||
text-align: center;
|
||||
padding: 1px 2px;
|
||||
line-height: 1.1;
|
||||
white-space: normal;
|
||||
overflow: hidden;
|
||||
page-break-inside: avoid !important;
|
||||
}
|
||||
</style>
|
||||
`;
|
||||
|
||||
// 只复制票据内部innerHTML,不带外层el-dialog多余结构
|
||||
const printContent = el.innerHTML;
|
||||
|
||||
win.document.write(`
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>${title}</title>
|
||||
<meta charset="UTF-8">
|
||||
${styles}
|
||||
${printScopeStyle}
|
||||
</head>
|
||||
<body>
|
||||
<div id="${elementId}">${printContent}</div>
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
win.document.close();
|
||||
win.onload = () => {
|
||||
setTimeout(() => {
|
||||
win.print();
|
||||
|
||||
@@ -245,13 +245,13 @@ service.interceptors.response.use(
|
||||
}
|
||||
);
|
||||
// 通用下载方法
|
||||
export function download(url: string, params: any, fileName: string) {
|
||||
export function download(url: string, params: any, fileName: string, format: boolean = true) {
|
||||
downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' });
|
||||
// prettier-ignore
|
||||
return service.post(url, params, {
|
||||
transformRequest: [
|
||||
(params: any) => {
|
||||
return tansParams(params);
|
||||
return format ? tansParams(params) : JSON.stringify(params);
|
||||
}
|
||||
],
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded',silentError: 'true' },
|
||||
|
||||
@@ -108,7 +108,7 @@ import repairUser from '@/components/Holder/repairUser.vue';
|
||||
import PageHeader from '@/components/Pageheader/index.vue';
|
||||
import { getComplaint, updateComplaint } from '@/api/system/Complaint';
|
||||
import { listComplaintType } from '@/api/system/ComplainType';
|
||||
import { ResidentVO } from '@/api/system/resident/type';
|
||||
import { ResidentVO } from '@/api/system/residentReviewProcess/resident/type';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { com_complaint_status } = toRefs<any>(proxy?.useDict('com_complaint_status'));
|
||||
|
||||
|
||||
@@ -57,23 +57,25 @@
|
||||
<el-col :span="12">
|
||||
<el-form-item label="附属材料">
|
||||
<el-upload
|
||||
:auto-upload="false"
|
||||
class="upload-demo"
|
||||
:file-list="fileList"
|
||||
:action="uploadUrl"
|
||||
:multiple="true"
|
||||
:auto-upload="false"
|
||||
ref="uploadRef"
|
||||
:show-file-list="true"
|
||||
name="files"
|
||||
:headers="headerToken()"
|
||||
:show-file-list="true"
|
||||
:on-remove="handleAvatarRemove"
|
||||
:on-change="handleProgress"
|
||||
:before-upload="beforeAvatarUpload"
|
||||
accept=".doc,.docx,.xls,.xlsx,.jpg,.jpeg,.png,.gif,.bmp,.webp"
|
||||
>
|
||||
<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>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -144,14 +146,16 @@ 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 forbidSuffix = ['exe', 'msi', 'bat', 'cmd', 'sh', 'apk', 'dmg'];
|
||||
const uploadRef = ref();
|
||||
// 添加一个锁,防止 on-change 递归调用导致重复提示
|
||||
const isChecking = ref(false);
|
||||
const handleProgress: UploadProps['onChange'] = (uploadFile: UploadUserFile, uploadFiles: UploadFiles) => {
|
||||
// 如果正在校验中,直接返回,避免重复执行
|
||||
if (!beforeAvatarUpload(uploadFile)) {
|
||||
uploadRef.value.handleRemove(uploadFile);
|
||||
return;
|
||||
}
|
||||
if (isChecking.value) return;
|
||||
|
||||
// 加锁
|
||||
isChecking.value = true;
|
||||
// 创建一个新数组来存储校验通过的文件
|
||||
@@ -229,12 +233,41 @@ const handleProgress: UploadProps['onChange'] = (uploadFile: UploadUserFile, upl
|
||||
};
|
||||
|
||||
const blockedExts = ['.exe', '.bat', '.cmd', '.msi'];
|
||||
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile: UploadRawFile) => {
|
||||
const allowExts = [
|
||||
// word
|
||||
'.doc',
|
||||
'.docx',
|
||||
'.dot',
|
||||
'.dotx',
|
||||
// excel
|
||||
'.xls',
|
||||
'.xlsx',
|
||||
'.xlsm',
|
||||
'.xlsb',
|
||||
// img
|
||||
'.jpg',
|
||||
'.jpeg',
|
||||
'.png',
|
||||
'.gif',
|
||||
'.bmp',
|
||||
'.webp',
|
||||
// 专业/矢量图
|
||||
'.psd',
|
||||
'.ai',
|
||||
'.svg',
|
||||
'.tif',
|
||||
'.tiff'
|
||||
];
|
||||
const beforeAvatarUpload = (rawFile: UploadUserFile) => {
|
||||
const ext = rawFile.name.toLowerCase().slice(rawFile.name.lastIndexOf('.'));
|
||||
if (blockedExts.includes(ext)) {
|
||||
ElMessage.warning(`禁止上传 ${ext} 文件`);
|
||||
return false;
|
||||
}
|
||||
if (!allowExts.includes(ext)) {
|
||||
ElMessage.warning('只能上传word,excel,图片等文件');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
:height="500"
|
||||
:min-height="300"
|
||||
:read-only="false"
|
||||
type="url"
|
||||
:file-size="5"
|
||||
/>
|
||||
</el-form-item>
|
||||
@@ -71,7 +72,6 @@ import PageHeader from '@/components/Pageheader/index.vue';
|
||||
import { addNotice, getNotice } from '@/api/system/NoticePc';
|
||||
import { updateNotice } from '@/api/system/NoticePc';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { com_noticepc_level } = toRefs<any>(proxy?.useDict('com_noticepc_level'));
|
||||
const { com_publish_status } = toRefs<any>(proxy?.useDict('com_publish_status'));
|
||||
|
||||
const route = useRoute();
|
||||
@@ -94,6 +94,7 @@ const rules = {
|
||||
const userid = ref();
|
||||
// ! 富文本 =============================================================================================================
|
||||
function handleContent(val: string) {
|
||||
console.log(val);
|
||||
form.value.noticeContent = val.trim();
|
||||
}
|
||||
// ! 富文本 =============================================================================================================
|
||||
@@ -134,9 +135,7 @@ const submitForm = () => {
|
||||
|
||||
// 返回
|
||||
function handleBack() {
|
||||
router.push({
|
||||
path: '/repair/noticepc'
|
||||
});
|
||||
router.back();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -47,23 +47,23 @@
|
||||
<dict-tag :options="com_publish_status" :value="scope.row.publishStatus"></dict-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="已读" width="120" align="center" prop="readNum">
|
||||
<el-table-column label="已读" align="center" prop="readNum">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.readNum ?? '--' }} 人</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="未读" width="120" align="center" prop="unReadNum">
|
||||
<el-table-column label="未读" align="center" prop="unReadNum">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.unReadNum ?? '--' }} 人</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="发布人" align="center" prop="publishBy" />
|
||||
<el-table-column label="发布日期" align="center" prop="publishTime" width="100">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.publishTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="220" fixed="right" class-name="small-padding fixed-width">
|
||||
<!-- <el-table-column label="发布人" align="center" prop="publishBy" />-->
|
||||
<!-- <el-table-column label="发布日期" align="center" prop="publishTime" width="100">-->
|
||||
<!-- <template #default="scope">-->
|
||||
<!-- <span>{{ parseTime(scope.row.publishTime, '{y}-{m}-{d}') }}</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="handleMain(scope.row)">详情</el-button>
|
||||
<el-button link type="primary" @click="handleUpdate(scope.row)" v-has-permi="['notice:notice:edit']">编辑</el-button>
|
||||
@@ -94,7 +94,6 @@ import { NoticeVO, NoticeQuery, NoticeForm } from '@/api/system/NoticePc/type';
|
||||
import { checkPermi } from '@/utils/permission';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { com_noticepc_level } = toRefs<any>(proxy?.useDict('com_noticepc_level'));
|
||||
const { com_publish_status } = toRefs<any>(proxy?.useDict('com_publish_status'));
|
||||
|
||||
const noticeList = ref<NoticeVO[]>([]);
|
||||
|
||||
@@ -73,7 +73,7 @@ const { com_questionnaire_scope } = toRefs<any>(proxy?.useDict('com_questionnair
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
import { listResident } from '@/api/system/resident';
|
||||
import { listResident } from '@/api/system/residentReviewProcess/resident';
|
||||
|
||||
const form = ref({
|
||||
scope: '0',
|
||||
|
||||
@@ -218,7 +218,7 @@
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input type="textarea" show-word-limit maxlength="100" :rows="10" v-model="inComeFrom.remark"></el-input>
|
||||
<el-input type="textarea" show-word-limit maxlength="100" :rows="5" v-model="inComeFrom.remark"></el-input>
|
||||
</el-form-item>
|
||||
<div class="flex justify-end">
|
||||
<el-button @click="closer">取消</el-button>
|
||||
@@ -234,7 +234,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="printBox" id="printBox-Bill">
|
||||
<div class="printBox" id="printBox-Bill" style="padding: 0; margin: 0">
|
||||
<div class="title">{{ print_form.title }}</div>
|
||||
<div class="nav gridBox">
|
||||
<div>单据日期:{{ print_form.printDate }}</div>
|
||||
@@ -254,7 +254,7 @@
|
||||
<th style="min-width: 80px">优免金额</th>
|
||||
<th style="min-width: 80px">实收金额</th>
|
||||
<th style="min-width: 80px">收款方式</th>
|
||||
<th style="width: 200px">备注</th>
|
||||
<th style="min-width: 100px">备注</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -283,7 +283,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<p style="font-size: 10px">说明:本收据收款单位和收款具签章方为有效,本收据手写无效</p>
|
||||
<div class="flex flex-items-center" style="font-size: 12px">
|
||||
<div class="flex flex-items-center" style="font-size: 12px; margin-bottom: 0">
|
||||
<div class="flex-1">交款人:</div>
|
||||
<div class="flex-1 flex flex-items-center">
|
||||
<span style="white-space: nowrap">收款人: </span>
|
||||
@@ -488,6 +488,7 @@ function initInComeFrom() {
|
||||
discount: 0, // 优惠金额
|
||||
residentName: '' // 缴费人
|
||||
};
|
||||
totalDiscountAmount.value = 0;
|
||||
isMore = false;
|
||||
}
|
||||
// 改变优惠方式
|
||||
@@ -598,6 +599,7 @@ function handleIncome(row: billlistType | false) {
|
||||
inComeFrom.value.allCost = row.amount;
|
||||
inComeFrom.value.billResidentId = [row];
|
||||
inComeFrom.value.residentName = row.residentName;
|
||||
totalDiscountAmount.value = Number(row.amount);
|
||||
} else {
|
||||
if (ids.value.length <= 0) return ElMessage.warning('请选择账单');
|
||||
const set = new Set();
|
||||
|
||||
@@ -267,7 +267,6 @@ function handleChange(pop) {
|
||||
holderInfo.value = pop;
|
||||
form.value.userId = '';
|
||||
form.value.userName = '';
|
||||
console.log(pop);
|
||||
if (pop !== null) {
|
||||
form.value.userId = pop.user_id;
|
||||
form.value.userName = pop.user_name;
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
import Pageheader from '@/components/Pageheader/index.vue';
|
||||
import { listCar, delCar } from '@/api/system/cars/index';
|
||||
import { CarVO, CarQuery, CarForm } from '@/api/system/cars/type';
|
||||
import { listResident } from '@/api/system/resident';
|
||||
import { listResident } from '@/api/system/residentReviewProcess/resident';
|
||||
import { checkPermi } from '@/utils/permission';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
@@ -299,7 +299,7 @@ const handleChangeFile = (uploadFile: UploadFile, uploadFiles: UploadFiles) => {
|
||||
const ext = uploadFile.name.toLowerCase().slice(uploadFile.name.lastIndexOf('.'));
|
||||
if (blockedExts.includes(ext)) {
|
||||
ElMessage.warning(`禁止上传 ${ext} 文件`);
|
||||
fileList.value = uploadFiles.filter((f) => f.uid !== uploadFile.uid);
|
||||
uploadRef.value.handleRemove(uploadFile);
|
||||
return;
|
||||
}
|
||||
fileList.value = uploadFiles;
|
||||
|
||||
@@ -34,12 +34,14 @@
|
||||
</el-col>
|
||||
<el-col :span="14"></el-col>
|
||||
<el-col :span="5" style="text-align: right">
|
||||
<el-button type="warning" @click="exportCurrentPage">导出当前页</el-button>
|
||||
<el-button type="warning" @click="exportAll">导出所有</el-button>
|
||||
<el-button type="primary" @click="exportChecked">导出选中</el-button>
|
||||
<el-button type="primary" @click="exportCurrentPage">导出当前页</el-button>
|
||||
<el-button type="primary" @click="exportAll">导出所有</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<el-table v-loading="loading" border :data="itemList">
|
||||
<el-table v-loading="loading" border row-key="id" :data="itemList" @selectionChange="handleChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="日期" width="100" align="center" prop="statDate" />
|
||||
<el-table-column label="计划巡检任务" width="120" align="center" prop="totalPlans" />
|
||||
<el-table-column label="按时完成" align="center" prop="completedTasks" />
|
||||
@@ -126,6 +128,26 @@ const exportAll = () => {
|
||||
`巡检日报_${new Date().toLocaleString()}.xlsx`
|
||||
);
|
||||
};
|
||||
const multipleSelection = ref([]);
|
||||
function handleChange(val) {
|
||||
multipleSelection.value = val;
|
||||
}
|
||||
const exportChecked = () => {
|
||||
if (multipleSelection.value.length > 0) {
|
||||
const listValue = multipleSelection.value.map((item) => item.id);
|
||||
console.log(listValue);
|
||||
proxy?.download(
|
||||
'/inspection/data/export/selected',
|
||||
{
|
||||
list: listValue.join(','),
|
||||
dataType: '1'
|
||||
},
|
||||
`巡检日报_选中${listValue.length}条数据_${new Date().toLocaleString()}.xlsx`,
|
||||
);
|
||||
} else {
|
||||
ElMessage.warning('请选择数据');
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
|
||||
@@ -34,13 +34,15 @@
|
||||
</el-col>
|
||||
<el-col :span="14"> </el-col>
|
||||
<el-col :span="5" style="text-align: right">
|
||||
<el-button type="warning" @click="exportCurrentPage">导出当前页</el-button>
|
||||
<el-button type="warning" @click="exportAll">导出所有</el-button>
|
||||
<el-button type="primary" @click="exportCurrentPage">导出当前页</el-button>
|
||||
<el-button type="primary" @click="exportAll">导出所有</el-button>
|
||||
<el-button type="primary" @click="exportChecked">导出选中</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="itemList">
|
||||
<el-table v-loading="loading" border :data="itemList" @selectionChange="handleChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="日期" width="100" align="center" prop="statDate" />
|
||||
<el-table-column label="计划巡检任务" width="120" align="center" prop="totalPlans" />
|
||||
<el-table-column label="按时完成" align="center" prop="completedTasks" />
|
||||
@@ -125,6 +127,26 @@ const exportAll = () => {
|
||||
`巡检月报_${new Date().toLocaleString()}.xlsx`
|
||||
);
|
||||
};
|
||||
const multipleSelection = ref([]);
|
||||
function handleChange(val) {
|
||||
multipleSelection.value = val;
|
||||
}
|
||||
const exportChecked = () => {
|
||||
if (multipleSelection.value.length > 0) {
|
||||
const listValue = multipleSelection.value.map((item) => item.id);
|
||||
console.log(listValue);
|
||||
proxy?.download(
|
||||
'/inspection/data/export/selected',
|
||||
{
|
||||
list: listValue.join(','),
|
||||
dataType: '3'
|
||||
},
|
||||
`巡检月报_选中${listValue.length}条数据_${new Date().toLocaleString()}.xlsx`
|
||||
);
|
||||
} else {
|
||||
ElMessage.warning('请选择数据');
|
||||
}
|
||||
};
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
|
||||
@@ -34,13 +34,15 @@
|
||||
</el-col>
|
||||
<el-col :span="14"> </el-col>
|
||||
<el-col :span="5" style="text-align: right">
|
||||
<el-button type="warning" @click="exportCurrentPage">导出当前页</el-button>
|
||||
<el-button type="warning" @click="exportAll">导出所有</el-button>
|
||||
<el-button type="primary" @click="exportCurrentPage">导出当前页</el-button>
|
||||
<el-button type="primary" @click="exportAll">导出所有</el-button>
|
||||
<el-button type="primary" @click="exportChecked">导出选中</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="itemList">
|
||||
<el-table v-loading="loading" border :data="itemList" @selectionChange="handleChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="日期" width="120" align="center" prop="statDate" />
|
||||
<el-table-column label="计划巡检任务" width="120" align="center" prop="totalPlans" />
|
||||
<el-table-column label="按时完成" align="center" prop="completedTasks" />
|
||||
@@ -129,6 +131,27 @@ const exportAll = () => {
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
|
||||
const multipleSelection = ref([]);
|
||||
function handleChange(val) {
|
||||
multipleSelection.value = val;
|
||||
}
|
||||
const exportChecked = () => {
|
||||
if (multipleSelection.value.length > 0) {
|
||||
const listValue = multipleSelection.value.map((item) => item.id);
|
||||
console.log(listValue);
|
||||
proxy?.download(
|
||||
'/inspection/data/export/selected',
|
||||
{
|
||||
list: listValue.join(','),
|
||||
dataType: '2'
|
||||
},
|
||||
`巡检周报_选中${listValue.length}条数据_${new Date().toLocaleString()}.xlsx`
|
||||
);
|
||||
} else {
|
||||
ElMessage.warning('请选择数据');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -139,8 +139,8 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import PageHeader from '@/components/Pageheader/index.vue';
|
||||
import { getResident, getresidentReviewlistAPI, UpdateResidentReviewAPI } from '@/api/system/resident';
|
||||
import { ResidentVO } from '@/api/system/resident/type';
|
||||
import { getResident, getresidentReviewlistAPI, UpdateResidentReviewAPI } from '@/api/system/residentReviewProcess/resident';
|
||||
import { ResidentVO } from '@/api/system/residentReviewProcess/resident/type';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { com_review } = toRefs<any>(proxy?.useDict('com_review'));
|
||||
|
||||
@@ -107,10 +107,10 @@
|
||||
import { ref } from 'vue';
|
||||
import PageHeader from '@/components/Pageheader/index.vue';
|
||||
import { getHousePathById } from '@/utils/house';
|
||||
import { ResidentForm } from '@/api/system/resident/type';
|
||||
import { ResidentForm } from '@/api/system/residentReviewProcess/resident/type';
|
||||
import { CascaderValue, UploadFiles, UploadInstance, UploadProps, UploadRawFile } from 'element-plus';
|
||||
import { genFileId } from 'element-plus';
|
||||
import { addResident, getResident, updateResident } from '@/api/system/resident';
|
||||
import { addResident, getResident, updateResident } from '@/api/system/residentReviewProcess/resident';
|
||||
import { validator } from '@/utils/Reg';
|
||||
import { useHouseStore } from '@/store/modules/house';
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
|
||||
@@ -96,8 +96,8 @@ import pageHeader from '@/components/Pageheader/index.vue';
|
||||
import RightToolbar from '@/components/RightToolbar/index.vue';
|
||||
import DictTag from '@/components/DictTag/index.vue';
|
||||
|
||||
import { listResident, delResident } from '@/api/system/resident';
|
||||
import { ResidentVO, ResidentQuery, ResidentForm } from '@/api/system/resident/type';
|
||||
import { listResident, delResident } from '@/api/system/residentReviewProcess/resident';
|
||||
import { ResidentVO, ResidentQuery, ResidentForm } from '@/api/system/residentReviewProcess/resident/type';
|
||||
import { useHouseStore } from '@/store/modules/house';
|
||||
import { checkPermi } from '@/utils/permission';
|
||||
|
||||
|
||||
259
src/views/system/revenueNotice/addRevenueNotice.vue
Normal file
259
src/views/system/revenueNotice/addRevenueNotice.vue
Normal file
@@ -0,0 +1,259 @@
|
||||
<template>
|
||||
<div class="ResidentMainBox p-2 w-full">
|
||||
<PageHeader></PageHeader>
|
||||
<div class="ResidentMainBody">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="title">基本信息</div>
|
||||
</template>
|
||||
<div class="addBuildingFormBody">
|
||||
<div class="formbox">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="公告标题" prop="noticeTitle">
|
||||
<el-input v-model.trim="form.noticeTitle" placeholder="请输入公告标题" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- <el-col :span="12">-->
|
||||
<!-- <el-form-item label="作者" prop="author">-->
|
||||
<!-- <el-input v-model.trim="form.author" placeholder="请输入作者" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-col>-->
|
||||
</el-row>
|
||||
<el-row>
|
||||
<!-- <el-col :span="12">-->
|
||||
<!-- <el-form-item label="公告紧急程度" prop="urgencyLevel">-->
|
||||
<!-- <el-select v-model="form.urgencyLevel" clearable placeholder="请选择公告紧急程度">-->
|
||||
<!-- <el-option v-for="dict in com_noticepc_level" :key="dict.value" :label="dict.label" :value="Number(dict.value)" />-->
|
||||
<!-- </el-select>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-col>-->
|
||||
<!-- <el-col :span="12">-->
|
||||
<!-- <el-form-item label="是否发布" prop="publishStatus">-->
|
||||
<!-- <el-radio-group v-model="form.publishStatus">-->
|
||||
<!-- <el-radio v-for="dict in com_publish_status" :key="dict.value" :value="Number(dict.value)">{{-->
|
||||
<!-- dict.value === '0' ? dict.label : '发布'-->
|
||||
<!-- }}</el-radio>-->
|
||||
<!-- </el-radio-group>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-col>-->
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item label="公告详情" prop="noticeContent">
|
||||
<editor
|
||||
@update:model-value="handleContent"
|
||||
:model-value="form.noticeContent"
|
||||
:height="500"
|
||||
:min-height="300"
|
||||
:read-only="false"
|
||||
type="url"
|
||||
:file-size="5"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- <el-row>-->
|
||||
<!-- <el-col>-->
|
||||
<!-- <el-form-item label="附加上传">-->
|
||||
<!-- <el-upload-->
|
||||
<!-- v-model:file-list="fileList"-->
|
||||
<!-- class="upload-demo"-->
|
||||
<!-- name="files"-->
|
||||
<!-- :action="uploadUrl"-->
|
||||
<!-- :headers="headerToken()"-->
|
||||
<!-- :on-success="handleAvatarSuccess"-->
|
||||
<!-- :on-remove="handleRemove"-->
|
||||
<!-- :before-upload="beforeAvatarUpload"-->
|
||||
<!-- >-->
|
||||
<!-- <el-button type="primary">上传附件</el-button>-->
|
||||
<!-- </el-upload>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-col>-->
|
||||
<!-- </el-row>-->
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitForm">立即发布</el-button>
|
||||
<el-button @click="handleBack">返回</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import editor from '@/components/Editor/index.vue';
|
||||
import { ref } from 'vue';
|
||||
import PageHeader from '@/components/Pageheader/index.vue';
|
||||
import { addRevenueNotice, getRevenueNotice, updateRevenueNotice } from '@/api/system/revenueNotice';
|
||||
import { ElMessage } from 'element-plus';
|
||||
// import { useUserStore } from '@/store/modules/user';
|
||||
|
||||
// const uploadUrl = import.meta.env.VITE_APP_BASE_API + '/revenueNotice/uploadAttachments';
|
||||
|
||||
// const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
// const { com_publish_status } = toRefs<any>(proxy?.useDict('com_publish_status'));
|
||||
// const useStore = useUserStore();
|
||||
// function headerToken() {
|
||||
// return {
|
||||
// Authorization: 'Bearer ' + useStore.token
|
||||
// };
|
||||
// }
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const formRef = ref();
|
||||
const form = ref({
|
||||
'id': null,
|
||||
'author': '',
|
||||
'noticeTitle': '',
|
||||
'urgencyLevel': 0,
|
||||
'publishStatus': 1,
|
||||
'noticeContent': '',
|
||||
attachments: []
|
||||
});
|
||||
const rules = {
|
||||
noticeTitle: [{ required: true, message: '请输入公告标题', trigger: 'blur' }],
|
||||
urgencyLevel: [{ required: true, message: '请选择紧急程度', trigger: 'blur' }],
|
||||
author: [{ required: true, message: '请输入作者名称', trigger: 'blur' }],
|
||||
noticeContent: [{ required: true, message: '请输入公告内容', trigger: 'blur' }]
|
||||
};
|
||||
const userid = ref();
|
||||
function handleContent(val: string) {
|
||||
form.value.noticeContent = val.trim();
|
||||
}
|
||||
|
||||
// ! 投诉 ====================================================================================================
|
||||
function init() {
|
||||
getRevenueNotice(userid.value).then((res) => {
|
||||
form.value = {
|
||||
...form.value,
|
||||
...res.data
|
||||
};
|
||||
// fileList.value = form.value.attachments.map((item) => {
|
||||
// return {
|
||||
// name: item.fileName,
|
||||
// url: item.fileUrl
|
||||
// };
|
||||
// });
|
||||
});
|
||||
}
|
||||
|
||||
if (route.query.id) {
|
||||
userid.value = route.query.id;
|
||||
init();
|
||||
}
|
||||
|
||||
// interface myUploadUserFile extends UploadUserFile {
|
||||
// response: {
|
||||
// code: number;
|
||||
// msg: string;
|
||||
// data: {
|
||||
// success: {
|
||||
// fileName: string;
|
||||
// url: string;
|
||||
// ossId: string;
|
||||
// }[];
|
||||
// error: string[];
|
||||
// };
|
||||
// };
|
||||
// }
|
||||
|
||||
// const fileList = ref<myUploadUserFile[]>([]);
|
||||
//
|
||||
// const blockedExts = ['.exe', '.bat', '.cmd', '.msi'];
|
||||
// const beforeAvatarUpload = (rawFile: UploadUserFile) => {
|
||||
// const ext = rawFile.name.toLowerCase().slice(rawFile.name.lastIndexOf('.'));
|
||||
// if (blockedExts.includes(ext)) {
|
||||
// ElMessage.warning(`禁止上传 ${ext} 文件`);
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// };
|
||||
// const handleAvatarSuccess: UploadProps['onSuccess'] = (response, uploadFile, uploadFiles) => {};
|
||||
// const handleRemove: UploadProps['onRemove'] = (_, uploadFiles) => {};
|
||||
|
||||
// 提交
|
||||
const submitForm = () => {
|
||||
form.value.attachments = [];
|
||||
// if (fileList.value.length > 0) {
|
||||
// fileList.value.forEach((item, index) => {
|
||||
// if (item.response) {
|
||||
// const file = item.response.data.success[0];
|
||||
// const ext = file.fileName.toLowerCase().slice(file.fileName.lastIndexOf('.'));
|
||||
// form.value.attachments.push({
|
||||
// fileName: file.fileName,
|
||||
// fileUrl: file.url,
|
||||
// fileType: ext.split('.')[1],
|
||||
// sort: index
|
||||
// });
|
||||
// } else {
|
||||
// const ext = item.fileName.toLowerCase().slice(item.fileName.lastIndexOf('.'));
|
||||
// form.value.attachments.push({
|
||||
// fileName: item.fileName,
|
||||
// fileUrl: item.url,
|
||||
// fileType: ext.split('.')[1],
|
||||
// sort: index
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
formRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
if (userid.value) {
|
||||
updateRevenueNotice(form.value).then(() => {
|
||||
ElMessage.success('编辑成功');
|
||||
handleBack();
|
||||
});
|
||||
} else {
|
||||
addRevenueNotice(form.value).then(() => {
|
||||
ElMessage.success('添加成功');
|
||||
handleBack();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 返回
|
||||
function handleBack() {
|
||||
router.back();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.ResidentMainBox {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.ResidentMainBody {
|
||||
margin-top: 20px;
|
||||
flex: 1;
|
||||
|
||||
.formbox {
|
||||
width: 1000px;
|
||||
margin: 0 auto;
|
||||
.upload-demo {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
&:deep(div.el-step__head.is-process) {
|
||||
& > div.el-step__line {
|
||||
width: 0;
|
||||
border: 1px dashed gray;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
&:deep(.el-step.is-vertical .el-step__line) {
|
||||
top: 20px;
|
||||
}
|
||||
&:deep(div.el-step__head.is-finish) {
|
||||
& > div.el-step__line {
|
||||
width: 0;
|
||||
border: 1px solid var(--el-color-primary);
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
276
src/views/system/revenueNotice/index.vue
Normal file
276
src/views/system/revenueNotice/index.vue
Normal file
@@ -0,0 +1,276 @@
|
||||
<template>
|
||||
<div class="flex flex-col h-full p-2">
|
||||
<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">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="公告标题" prop="noticeTitle">
|
||||
<el-input v-model="queryParams.noticeTitle" placeholder="请输入公告标题" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="作者" prop="author">-->
|
||||
<!-- <el-input v-model="queryParams.author" placeholder="请输入作者" clearable @keyup.enter="handleQuery" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="发布人" prop="publishBy">-->
|
||||
<!-- <el-input v-model="queryParams.publishBy" placeholder="请输入发布人" clearable @keyup.enter="handleQuery" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="发布日期" prop="publishTime">-->
|
||||
<!-- <el-date-picker clearable v-model="queryParams.publishTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择发布日期" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="never" class="flex-1">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<!-- <el-col :span="1.5">-->
|
||||
<!-- <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:revenueNotice:export']">导出</el-button>-->
|
||||
<!-- </el-col>-->
|
||||
<right-toolbar
|
||||
:show-edit="checkPermi(['revenue:revenueNotice:edit'])"
|
||||
:show-delete="checkPermi(['revenue:revenueNotice:remove'])"
|
||||
:showAdd="checkPermi(['revenue:revenueNotice:add'])"
|
||||
@update:add="handleAdd"
|
||||
@update:edit="handleUpdate()"
|
||||
@update:delete="handleDelete()"
|
||||
></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="revenueNoticeList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="公告标题" align="center" prop="noticeTitle" />
|
||||
<!-- <el-table-column label="公告内容" align="center" prop="noticeContent" />-->
|
||||
<!-- <el-table-column label="作者" align="center" prop="author" />-->
|
||||
<!-- <el-table-column label="发布状态" align="center" prop="publishStatus">-->
|
||||
<!-- <template #default="scope">-->
|
||||
<!-- <dict-tag :options="com_publish_status" :value="scope.row.publishStatus"></dict-tag>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<!-- <el-table-column label="发布人" align="center" prop="publishBy" />-->
|
||||
<!-- <el-table-column label="发布日期" align="center" prop="publishTime" width="180">-->
|
||||
<!-- <template #default="scope">-->
|
||||
<!-- <span>{{ parseTime(scope.row.publishTime, '{y}-{m}-{d}') }}</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['revenue:revenueNotice:edit']">修改</el-button>
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['revenue:revenueNotice:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<!-- 添加或修改公区收益通知对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="revenueNoticeFormRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="公告标题" prop="noticeTitle">
|
||||
<el-input v-model="form.noticeTitle" placeholder="请输入公告标题" />
|
||||
</el-form-item>
|
||||
<el-form-item label="公告内容">
|
||||
<editor v-model="form.noticeContent" :min-height="192" />
|
||||
</el-form-item>
|
||||
<el-form-item label="作者" prop="author">
|
||||
<el-input v-model="form.author" placeholder="请输入作者" />
|
||||
</el-form-item>
|
||||
<el-form-item label="紧急程度 0=普通 1=紧急 2=非常紧急" prop="urgencyLevel">
|
||||
<el-input v-model="form.urgencyLevel" placeholder="请输入紧急程度" />
|
||||
</el-form-item>
|
||||
<el-form-item label="发布人" prop="publishBy">
|
||||
<el-input v-model="form.publishBy" placeholder="请输入发布人" />
|
||||
</el-form-item>
|
||||
<el-form-item label="发布日期" prop="publishTime">
|
||||
<el-date-picker clearable v-model="form.publishTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择发布日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="所属小区id" prop="villageId">
|
||||
<el-input v-model="form.villageId" placeholder="请输入所属小区id" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="RevenueNotice" lang="ts">
|
||||
import pageHeader from '@/components/Pageheader/index.vue';
|
||||
import { listRevenueNotice, delRevenueNotice, addRevenueNotice, updateRevenueNotice } from '@/api/system/revenueNotice';
|
||||
import { RevenueNoticeVO, RevenueNoticeQuery, RevenueNoticeForm } from '@/api/system/revenueNotice/type';
|
||||
import { checkPermi } from '@/utils/permission';
|
||||
import { NoticeVO } from '@/api/system/NoticePc/type';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
// const { com_publish_status } = toRefs<any>(proxy?.useDict('com_publish_status'));
|
||||
const revenueNoticeList = ref<RevenueNoticeVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const revenueNoticeFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: RevenueNoticeForm = {
|
||||
noticeId: undefined,
|
||||
noticeTitle: undefined,
|
||||
noticeContent: undefined,
|
||||
author: undefined,
|
||||
urgencyLevel: undefined,
|
||||
publishStatus: undefined,
|
||||
publishBy: undefined,
|
||||
publishTime: undefined,
|
||||
villageId: undefined
|
||||
};
|
||||
const data = reactive<PageData<RevenueNoticeForm, RevenueNoticeQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
noticeTitle: undefined,
|
||||
noticeContent: undefined,
|
||||
author: undefined,
|
||||
urgencyLevel: undefined,
|
||||
publishStatus: undefined,
|
||||
publishBy: undefined,
|
||||
publishTime: undefined,
|
||||
villageId: undefined,
|
||||
params: {}
|
||||
},
|
||||
rules: {
|
||||
noticeTitle: [{ required: true, message: '公告标题不能为空', trigger: 'blur' }],
|
||||
urgencyLevel: [{ required: true, message: '紧急程度', trigger: 'blur' }],
|
||||
publishStatus: [{ required: true, message: '发布状态', trigger: 'change' }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询公区收益通知列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listRevenueNotice(queryParams.value);
|
||||
revenueNoticeList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
revenueNoticeFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: RevenueNoticeVO[]) => {
|
||||
ids.value = selection.map((item) => item.noticeId);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
const router = useRouter();
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
router.push({
|
||||
path: '/repair/addRevenueNotice'
|
||||
});
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = (row?: NoticeVO) => {
|
||||
const _id = row?.noticeId || ids.value[0];
|
||||
router.push({
|
||||
path: '/repair/editRevenueNotice',
|
||||
query: {
|
||||
id: _id
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
revenueNoticeFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
if (form.value.noticeId) {
|
||||
await updateRevenueNotice(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addRevenueNotice(form.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: RevenueNoticeVO) => {
|
||||
const _noticeIds = row?.noticeId || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除该公区收益通知?').finally(() => (loading.value = false));
|
||||
await delRevenueNotice(_noticeIds);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
// const handleExport = () => {
|
||||
// proxy?.download(
|
||||
// 'system/revenueNotice/export',
|
||||
// {
|
||||
// ...queryParams.value
|
||||
// },
|
||||
// `revenueNotice_${new Date().getTime()}.xlsx`
|
||||
// );
|
||||
// };
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.el-table {
|
||||
height: calc(100% - 80px);
|
||||
}
|
||||
</style>
|
||||
@@ -19,9 +19,9 @@
|
||||
<div class="cardbox">
|
||||
<div>收入来源</div>
|
||||
<div class="card_InfoAll">
|
||||
<div>应缴费用:{{ formatMoneyWithUnit(sourceFrom.totalPayable) }}</div>
|
||||
<div>已收:{{ formatMoneyWithUnit(sourceFrom.totalReceived) }}</div>
|
||||
<div>待收:{{ formatMoneyWithUnit(sourceFrom.totalPending) }}</div>
|
||||
<div>应缴费用:{{ formatMoneyWithUnit(sourceFrom.totalPayable, 3) }}</div>
|
||||
<div>已收:{{ formatMoneyWithUnit(sourceFrom.totalReceived, 3) }}</div>
|
||||
<div>待收:{{ formatMoneyWithUnit(sourceFrom.totalPending, 3) }}</div>
|
||||
</div>
|
||||
<div class="cardBody" style="display: flex; flex-wrap: wrap" v-if="sourceFromIsComputed">
|
||||
<RingProgress name="停车费" color="#1a75ff" :value="sourceFrom.parkingFeePercent"></RingProgress>
|
||||
|
||||
@@ -72,7 +72,6 @@ import { listStock } from '@/api/system/Tstock';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const router = useRouter();
|
||||
const materialList = ref<MaterialVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
@@ -135,7 +134,7 @@ const handleAdd = () => {
|
||||
});
|
||||
};
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: MaterialVO) => {
|
||||
const handleUpdate = (row?: MaterialVO) => {
|
||||
const _ids = row?.materialId;
|
||||
router.push({
|
||||
path: '/warehouse/editInventory',
|
||||
|
||||
@@ -35,8 +35,6 @@ import { ref } from 'vue';
|
||||
import PageHeader from '@/components/Pageheader/index.vue';
|
||||
import { getMaterial, updateMaterial, addMaterial } from '@/api/system/Tmaterial';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
<el-form-item label="供应商名称" prop="supplierName">
|
||||
<el-input v-model.trim="form.supplierName" placeholder="请输入供应商名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="联系人" prop="contactPerson">
|
||||
<el-form-item label="联系人">
|
||||
<el-input v-model.trim="form.contactPerson" placeholder="请输入联系人" />
|
||||
</el-form-item>
|
||||
<el-form-item label="联系电话" prop="contactPhone">
|
||||
<el-form-item label="联系电话">
|
||||
<el-input v-model.trim="form.contactPhone" placeholder="请输入联系电话" />
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-form-item label="邮箱">
|
||||
<el-input v-model.trim="form.email" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
<el-form-item label="地址" prop="address">
|
||||
@@ -39,8 +39,6 @@ import PageHeader from '@/components/Pageheader/index.vue';
|
||||
import { getSupplier, updateSupplier, addSupplier } from '@/api/system/Tsupplier';
|
||||
import { validator } from '@/utils/Reg';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="归属小区" prop="villageId">
|
||||
<el-select v-model="form.villageId" placeholder="请选择归属小区">
|
||||
<el-option v-for="(item, index) in cummunitylist" :key="index" :label="item.villageName" :value="item.villageId" />
|
||||
<el-option v-for="(item, index) in communityList" :key="index" :label="item.villageName" :value="item.villageId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系人" prop="contactPerson">
|
||||
<el-form-item label="联系人">
|
||||
<el-input v-model.trim="form.contactPerson" placeholder="请输入联系人" />
|
||||
</el-form-item>
|
||||
<el-form-item label="联系电话" prop="contactPhone">
|
||||
<el-form-item label="联系电话">
|
||||
<el-input v-model.trim="form.contactPhone" placeholder="请输入联系电话" />
|
||||
</el-form-item>
|
||||
<el-form-item label="地址" prop="address">
|
||||
@@ -42,8 +42,6 @@ import { getCommunitylistAPI } from '@/api/system/community';
|
||||
import { addWarehouse, getWarehouse, updateWarehouse } from '@/api/system/Twarehouse';
|
||||
import { validator } from '@/utils/Reg';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
@@ -63,7 +61,7 @@ const rules = ref({
|
||||
contactPhone: [
|
||||
{ required: true, message: '请输入 联系电话', trigger: 'blur' },
|
||||
{
|
||||
validator: (_, value) => validator(value, 'phone'),
|
||||
validator: (_: any, value: string | number) => validator(value, 'phone'),
|
||||
message: '请输入正确的电话号码',
|
||||
trigger: 'blur'
|
||||
}
|
||||
@@ -74,10 +72,10 @@ const rules = ref({
|
||||
const userid = ref(null);
|
||||
|
||||
// 小区列表
|
||||
const cummunitylist = ref([]);
|
||||
const communityList = ref([]);
|
||||
function init() {
|
||||
getCommunitylistAPI().then((res) => {
|
||||
cummunitylist.value = res.rows;
|
||||
communityList.value = res.rows;
|
||||
});
|
||||
if (route.query.id) {
|
||||
userid.value = route.query.id;
|
||||
@@ -103,12 +101,12 @@ const submitForm = () => {
|
||||
formRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
if (userid.value) {
|
||||
updateWarehouse(form.value).then((res) => {
|
||||
updateWarehouse(form.value).then(() => {
|
||||
ElMessage.success('编辑成功');
|
||||
cancelForm();
|
||||
});
|
||||
} else {
|
||||
addWarehouse(form.value).then((res) => {
|
||||
addWarehouse(form.value).then(() => {
|
||||
ElMessage.success('添加成功');
|
||||
cancelForm();
|
||||
});
|
||||
|
||||
210
src/views/workbench/components/feeOverview.vue
Normal file
210
src/views/workbench/components/feeOverview.vue
Normal file
@@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<div class="echarts">
|
||||
<div class="nav flex flex-items-center justify-between">
|
||||
<div>
|
||||
<span class="ecarts_title">收费情况</span>
|
||||
</div>
|
||||
<div class="flex flex-items-center justify-center">
|
||||
<el-date-picker
|
||||
v-model="time"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
start-placeholder="开始日期"
|
||||
@update:model-value="handleChangeDate"
|
||||
end-placeholder="结束日期"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="echartsBody flex flex-items-center justify-between">
|
||||
<div class="flex-1 h-full echartsItems">
|
||||
<Echarts :options="options"></Echarts>
|
||||
</div>
|
||||
<div class="flex-1 h-full">
|
||||
<div class="echartsMoneyItem">
|
||||
<div class="label">应收</div>
|
||||
<div class="value">¥ {{ feeForm.receivableAmount }}</div>
|
||||
</div>
|
||||
<div class="echartsMoneyItem">
|
||||
<div class="label">已收</div>
|
||||
<div class="value">¥ {{ feeForm.receivedAmount }}</div>
|
||||
</div>
|
||||
<div class="echartsMoneyItem">
|
||||
<div class="label">待收</div>
|
||||
<div class="value">¥ {{ feeForm.unpaidAmount }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Echarts from '@/components/Echarts/index.vue';
|
||||
import { EChartsOption } from 'echarts';
|
||||
import { paymentRateApi } from '@/api/workflow';
|
||||
import { getLastNDays } from '@/utils/time';
|
||||
const time = ref([getLastNDays(30).at(0), getLastNDays(0).at(length - 1)]);
|
||||
const value = ref(0);
|
||||
const feeForm = ref({
|
||||
'receivableAmount': '',
|
||||
'receivablePercent': '',
|
||||
'receivedAmount': '',
|
||||
'receivedPercent': '',
|
||||
'unpaidAmount': '',
|
||||
'unpaidPercent': ''
|
||||
});
|
||||
const options = ref<EChartsOption>({
|
||||
tooltip: {
|
||||
show: false,
|
||||
trigger: 'item',
|
||||
formatter: '{b}: {c}%'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['50%', '80%'], // 环形大小
|
||||
center: ['50%', '50%'], // 每个图表各自居中
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
|
||||
data: [
|
||||
{
|
||||
value: 100 - value.value,
|
||||
itemStyle: {
|
||||
color: '#ebeef5' // 背景色
|
||||
},
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
color: '#ebeef5'
|
||||
},
|
||||
scale: false
|
||||
}
|
||||
},
|
||||
{
|
||||
value: value.value,
|
||||
name: '收费率',
|
||||
itemStyle: { color: '#1684fc', borderRadius: 8, borderColor: '#1684fc', borderWidth: 0 },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center', // 显示在圆环中心
|
||||
formatter: '{c}%', // 显示百分比数值
|
||||
fontSize: 25
|
||||
},
|
||||
emphasis: {
|
||||
scale: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
function handleChangeDate(date: string[]) {
|
||||
if (date) {
|
||||
paymentRateApi(date[0], date[1]).then((res) => {
|
||||
feeForm.value = res.data;
|
||||
options.value = updateOptions(res.data.receivedPercent) as EChartsOption;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleChangeDate(time.value);
|
||||
function updateOptions(value: string) {
|
||||
return {
|
||||
tooltip: {
|
||||
show: false,
|
||||
trigger: 'item',
|
||||
formatter: '{b}: {c}%'
|
||||
},
|
||||
title: {
|
||||
show: true,
|
||||
text: '收费率',
|
||||
left: 'left'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['50%', '80%'], // 环形大小
|
||||
center: ['50%', '50%'], // 每个图表各自居中
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
startAngle: 90,
|
||||
clockwise: false,
|
||||
data: [
|
||||
{
|
||||
value: 100 - Number(value),
|
||||
itemStyle: {
|
||||
color: '#ebeef5' // 背景色
|
||||
},
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
color: '#ebeef5'
|
||||
},
|
||||
scale: false
|
||||
}
|
||||
},
|
||||
{
|
||||
value: Number(value),
|
||||
name: '收费率',
|
||||
itemStyle: { color: '#1684fc', borderRadius: 8, borderColor: '#1684fc', borderWidth: 0 },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: '{c}%',
|
||||
fontSize: 25
|
||||
},
|
||||
emphasis: {
|
||||
scale: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.echarts {
|
||||
height: 512px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, #ffffff 70%);
|
||||
box-sizing: border-box;
|
||||
padding: 19px 23px;
|
||||
box-shadow: 0px 2px 6px 0px rgba(26, 117, 255, 0.15);
|
||||
border-radius: 10px;
|
||||
.echartsBody {
|
||||
margin-top: 40px;
|
||||
.echartsItems {
|
||||
border-right: 1px solid #dedede;
|
||||
}
|
||||
.echartsMoneyItem {
|
||||
box-sizing: border-box;
|
||||
border-bottom: 1px solid #dedede;
|
||||
padding: 17px 34px;
|
||||
height: 126px;
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.label {
|
||||
color: rgba(16, 16, 16, 1);
|
||||
font-size: 16px;
|
||||
height: 23px;
|
||||
line-height: 23px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.value {
|
||||
color: rgba(16, 16, 16, 1);
|
||||
font-size: 1.5rem;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -31,7 +31,7 @@ const handleRoute = () => {
|
||||
.echarts {
|
||||
margin-right: 20px;
|
||||
flex: 1;
|
||||
height: 450px;
|
||||
height: 512px;
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, #ffffff 70%);
|
||||
border: 2px solid #ffffff;
|
||||
border-radius: 12px;
|
||||
|
||||
@@ -71,6 +71,31 @@ function headerToken() {
|
||||
};
|
||||
}
|
||||
const blockedExts = ['.exe', '.bat', '.cmd', '.msi'];
|
||||
const allowExts = [
|
||||
// word
|
||||
'.doc',
|
||||
'.docx',
|
||||
'.dot',
|
||||
'.dotx',
|
||||
// excel
|
||||
'.xls',
|
||||
'.xlsx',
|
||||
'.xlsm',
|
||||
'.xlsb',
|
||||
// img
|
||||
'.jpg',
|
||||
'.jpeg',
|
||||
'.png',
|
||||
'.gif',
|
||||
'.bmp',
|
||||
'.webp',
|
||||
// 专业/矢量图
|
||||
'.psd',
|
||||
'.ai',
|
||||
'.svg',
|
||||
'.tif',
|
||||
'.tiff'
|
||||
];
|
||||
const handleAvatarRemove: UploadProps['onRemove'] = (uploadFile: UploadFile, uploadFiles: UploadFiles) => {
|
||||
fileList.value = uploadFiles;
|
||||
};
|
||||
@@ -78,7 +103,12 @@ const handleProgress: UploadProps['onChange'] = (uploadFile: UploadFile, uploadF
|
||||
const ext = uploadFile.name.toLowerCase().slice(uploadFile.name.lastIndexOf('.'));
|
||||
if (blockedExts.includes(ext)) {
|
||||
ElMessage.warning(`禁止上传 ${ext} 文件`);
|
||||
fileList.value = uploadFiles.filter((f) => f.uid !== uploadFile.uid);
|
||||
uploadRef.value.handleRemove(uploadFile);
|
||||
return;
|
||||
}
|
||||
if (!allowExts.includes(ext)) {
|
||||
ElMessage.warning('只允许上传word,excel和图片文件');
|
||||
uploadRef.value.handleRemove(uploadFile);
|
||||
return;
|
||||
}
|
||||
fileList.value = uploadFiles;
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { delResident, listResident } from '@/api/system/resident';
|
||||
import { delResident, listResident } from '@/api/system/residentReviewProcess/resident';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { com_resident_type } = toRefs<any>(proxy?.useDict('com_resident_type'));
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
<VillageAllInfo :list="list"></VillageAllInfo>
|
||||
<div class="echartsbox flex flex-items-center">
|
||||
<repairechartsAll></repairechartsAll>
|
||||
<repairechartsAll></repairechartsAll>
|
||||
<inandoutEcharts></inandoutEcharts>
|
||||
<feeOverview></feeOverview>
|
||||
</div>
|
||||
</el-col>
|
||||
<!-- tabs -->
|
||||
@@ -80,6 +79,7 @@ import weatherVue from './components/weather.vue';
|
||||
import userTable from './components/usertable.vue';
|
||||
import quick from './components/quick.vue';
|
||||
import todo from './components/todo.vue';
|
||||
import feeOverview from './components/feeOverview.vue';
|
||||
|
||||
import inandoutEcharts from './components/inandout.vue';
|
||||
import repairechartsAll from './components/repairechartsAll.vue';
|
||||
|
||||
Reference in New Issue
Block a user