7/17 添加公区收益
This commit is contained in:
@@ -9,9 +9,9 @@ VITE_APP_ENV='development'
|
|||||||
# 开发环境
|
# 开发环境
|
||||||
VITE_APP_BASE_API='/dev-api'
|
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'
|
VITE_IMG_URL='http://192.168.1.222:8080'
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import request from '@/utils/request';
|
import request from '@/utils/request';
|
||||||
import { AxiosPromise } from 'axios';
|
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 {*}
|
* @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>
|
<template>
|
||||||
|
<!-- 原有图片上传 -->
|
||||||
<div>
|
<div>
|
||||||
<el-upload
|
<el-upload
|
||||||
v-if="type"
|
v-if="type"
|
||||||
action=""
|
:action="uploadUrl"
|
||||||
|
:headers="headerToken()"
|
||||||
:before-upload="handleBeforeUpload"
|
:before-upload="handleBeforeUpload"
|
||||||
:http-request="handleUploadRequest"
|
:http-request="handleUploadRequest"
|
||||||
class="editor-img-uploader"
|
class="editor-img-uploader"
|
||||||
name="file"
|
name="files"
|
||||||
:show-file-list="false"
|
:show-file-list="false"
|
||||||
>
|
>
|
||||||
<i ref="uploadRef"></i>
|
<i ref="uploadRef"></i>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</div>
|
</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">
|
<div class="editor">
|
||||||
<quill-editor
|
<quill-editor
|
||||||
ref="quillEditorRef"
|
ref="quillEditorRef"
|
||||||
@@ -19,7 +39,7 @@
|
|||||||
content-type="html"
|
content-type="html"
|
||||||
:options="options"
|
:options="options"
|
||||||
:style="styles"
|
:style="styles"
|
||||||
@text-change="(e: any) => $emit('update:modelValue', content)"
|
@text-change="() => $emit('update:modelValue', content)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -27,9 +47,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import '@vueup/vue-quill/dist/vue-quill.snow.css';
|
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 { propTypes } from '@/utils/propTypes';
|
||||||
import type { UploadRequestHandler, UploadRequestOptions } from 'element-plus';
|
import type { UploadRequestHandler, UploadRequestOptions } from 'element-plus';
|
||||||
|
import { useUserStore } from '@/store/modules/user';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
defineEmits(['update:modelValue']);
|
defineEmits(['update:modelValue']);
|
||||||
|
|
||||||
@@ -45,14 +67,20 @@ const props = defineProps({
|
|||||||
/* 上传文件大小限制(MB) */
|
/* 上传文件大小限制(MB) */
|
||||||
fileSize: propTypes.number.def(5),
|
fileSize: propTypes.number.def(5),
|
||||||
/* 类型(base64格式、url格式) */
|
/* 类型(base64格式、url格式) */
|
||||||
type: propTypes.string.def('base64')
|
type: propTypes.string.def('url')
|
||||||
});
|
});
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
|
||||||
const quillEditorRef = ref();
|
const quillEditorRef = ref();
|
||||||
|
const useStore = useUserStore();
|
||||||
|
function headerToken() {
|
||||||
|
return {
|
||||||
|
Authorization: 'Bearer ' + useStore.token
|
||||||
|
};
|
||||||
|
}
|
||||||
const uploadRef = ref<HTMLDivElement>();
|
const uploadRef = ref<HTMLDivElement>();
|
||||||
|
const uploadUrl = import.meta.env.VITE_APP_BASE_API + '/handleLog/uploadAttachments';
|
||||||
const options = ref<any>({
|
const options = ref<any>({
|
||||||
theme: 'snow',
|
theme: 'snow',
|
||||||
bounds: document.body,
|
bounds: document.body,
|
||||||
@@ -70,7 +98,8 @@ const options = ref<any>({
|
|||||||
[{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
|
[{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
|
||||||
[{ align: [] }], // 对齐方式
|
[{ align: [] }], // 对齐方式
|
||||||
['clean'], // 清除文本格式
|
['clean'], // 清除文本格式
|
||||||
['link', 'image', 'video'] // 链接、图片、视频
|
// ['image', 'video', 'link'] // 图片、视频、链接、文件
|
||||||
|
['image'] // 图片
|
||||||
],
|
],
|
||||||
handlers: {
|
handlers: {
|
||||||
image: (value: boolean) => {
|
image: (value: boolean) => {
|
||||||
@@ -83,8 +112,9 @@ const options = ref<any>({
|
|||||||
},
|
},
|
||||||
link: function (value) {
|
link: function (value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
const href = prompt('输入文件链接地址');
|
// const href = prompt('输入网络文件链接地址');
|
||||||
Quill.format('link', href);
|
// Quill.format('link', href);
|
||||||
|
fileUploadRef.value?.click();
|
||||||
} else {
|
} else {
|
||||||
Quill.format('link', false);
|
Quill.format('link', false);
|
||||||
}
|
}
|
||||||
@@ -140,16 +170,19 @@ const handleBeforeUpload = (file: any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// base64 模式插入图片
|
// base64 模式插入图片
|
||||||
const handleUploadRequest: UploadRequestHandler = (options: UploadRequestOptions) => {
|
const handleUploadRequest: UploadRequestHandler = async (options: UploadRequestOptions) => {
|
||||||
return new Promise<void>((resolve, reject) => {
|
|
||||||
const file = options.file as File;
|
const file = options.file as File;
|
||||||
const quill = toRaw(quillEditorRef.value)?.getQuill();
|
const quill = toRaw(quillEditorRef.value)?.getQuill();
|
||||||
if (!quill) {
|
if (!quill) {
|
||||||
proxy?.$modal.msgError('编辑器未就绪');
|
proxy?.$modal.msgError('编辑器未就绪');
|
||||||
proxy?.$modal.closeLoading();
|
proxy?.$modal.closeLoading();
|
||||||
reject(new Error('editor not ready'));
|
return Promise.reject(new Error('editor not ready'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
const range = quill.selection?.savedRange;
|
||||||
|
const insertIndex = range ? range.index : quill.getLength();
|
||||||
|
|
||||||
|
if (props.type === 'base64') {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onload = () => {
|
reader.onload = () => {
|
||||||
const base64 = reader.result as string;
|
const base64 = reader.result as string;
|
||||||
@@ -174,13 +207,181 @@ const handleUploadRequest: UploadRequestHandler = (options: UploadRequestOptions
|
|||||||
};
|
};
|
||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file);
|
||||||
});
|
});
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.editor-img-uploader {
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
|
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,
|
.editor,
|
||||||
.ql-toolbar {
|
.ql-toolbar {
|
||||||
white-space: pre-wrap !important;
|
white-space: pre-wrap !important;
|
||||||
|
|||||||
@@ -76,8 +76,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { listResident } from '@/api/system/resident';
|
import { listResident } from '@/api/system/residentReviewProcess/resident';
|
||||||
import { ResidentVO } from '@/api/system/resident/type';
|
import { ResidentVO } from '@/api/system/residentReviewProcess/resident/type';
|
||||||
import { ref, nextTick, getCurrentInstance, ComponentInternalInstance, toRefs } from 'vue';
|
import { ref, nextTick, getCurrentInstance, ComponentInternalInstance, toRefs } from 'vue';
|
||||||
import { useHouseStore } from '@/store/modules/house';
|
import { useHouseStore } from '@/store/modules/house';
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<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 { getUserByRoleKey } from '@/api/system/user';
|
||||||
import { ref, watch, nextTick, getCurrentInstance, ComponentInternalInstance, toRefs } from 'vue';
|
import { ref, watch, nextTick, getCurrentInstance, ComponentInternalInstance, toRefs } from 'vue';
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ const toggleSideBar = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const logout = async () => {
|
const logout = async () => {
|
||||||
await ElMessageBox.confirm('确定注销并退出系统吗?', '提示', {
|
await ElMessageBox.confirm('确定退出系统吗?', '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
|
|||||||
@@ -156,9 +156,10 @@ export function toFixedMoney(num: string | number, digit = 2): number {
|
|||||||
* 智能金额格式化(带单位:元/万元/亿元)
|
* 智能金额格式化(带单位:元/万元/亿元)
|
||||||
* 兼容:数字、字符串、null、undefined
|
* 兼容:数字、字符串、null、undefined
|
||||||
* @param {number|string} amount 金额
|
* @param {number|string} amount 金额
|
||||||
|
* @param {number} unitNumber 保留几个小数 默认 2位
|
||||||
* @returns {string} 格式化后带单位的金额
|
* @returns {string} 格式化后带单位的金额
|
||||||
*/
|
*/
|
||||||
export function formatMoneyWithUnit(amount) {
|
export function formatMoneyWithUnit(amount: number | string, unitNumber: number = 2): string {
|
||||||
// 空值处理
|
// 空值处理
|
||||||
if (amount == null || amount === '') return '0.00 元';
|
if (amount == null || amount === '') return '0.00 元';
|
||||||
|
|
||||||
@@ -170,13 +171,13 @@ export function formatMoneyWithUnit(amount) {
|
|||||||
|
|
||||||
if (absNum >= 100000000) {
|
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) {
|
} 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 {
|
} 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;
|
table-layout: fixed;
|
||||||
margin: 0.1cm 0;
|
margin: 0.1cm 0;
|
||||||
page-break-inside: avoid !important;
|
page-break-inside: avoid !important;
|
||||||
|
transform-origin: top left;
|
||||||
|
/* 初始不缩放,由JS动态控制 */
|
||||||
|
page-break-after: avoid !important;
|
||||||
}
|
}
|
||||||
table th, table td {
|
table th, table td {
|
||||||
border: 1px solid #333;
|
border: 1px solid #333;
|
||||||
@@ -360,6 +363,154 @@ export function printTicketDiv(elementId: string, title: string = '票据打印'
|
|||||||
</html>
|
</html>
|
||||||
`);
|
`);
|
||||||
win.document.close();
|
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 = () => {
|
win.onload = () => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
win.print();
|
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)' });
|
downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' });
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return service.post(url, params, {
|
return service.post(url, params, {
|
||||||
transformRequest: [
|
transformRequest: [
|
||||||
(params: any) => {
|
(params: any) => {
|
||||||
return tansParams(params);
|
return format ? tansParams(params) : JSON.stringify(params);
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded',silentError: 'true' },
|
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 PageHeader from '@/components/Pageheader/index.vue';
|
||||||
import { getComplaint, updateComplaint } from '@/api/system/Complaint';
|
import { getComplaint, updateComplaint } from '@/api/system/Complaint';
|
||||||
import { listComplaintType } from '@/api/system/ComplainType';
|
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 { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
const { com_complaint_status } = toRefs<any>(proxy?.useDict('com_complaint_status'));
|
const { com_complaint_status } = toRefs<any>(proxy?.useDict('com_complaint_status'));
|
||||||
|
|
||||||
|
|||||||
@@ -57,23 +57,25 @@
|
|||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="附属材料">
|
<el-form-item label="附属材料">
|
||||||
<el-upload
|
<el-upload
|
||||||
:auto-upload="false"
|
|
||||||
class="upload-demo"
|
class="upload-demo"
|
||||||
:file-list="fileList"
|
:file-list="fileList"
|
||||||
:action="uploadUrl"
|
:action="uploadUrl"
|
||||||
:multiple="true"
|
:multiple="true"
|
||||||
|
:auto-upload="false"
|
||||||
ref="uploadRef"
|
ref="uploadRef"
|
||||||
|
:show-file-list="true"
|
||||||
name="files"
|
name="files"
|
||||||
:headers="headerToken()"
|
:headers="headerToken()"
|
||||||
:show-file-list="true"
|
|
||||||
:on-remove="handleAvatarRemove"
|
:on-remove="handleAvatarRemove"
|
||||||
:on-change="handleProgress"
|
:on-change="handleProgress"
|
||||||
:before-upload="beforeAvatarUpload"
|
:before-upload="beforeAvatarUpload"
|
||||||
|
accept=".doc,.docx,.xls,.xlsx,.jpg,.jpeg,.png,.gif,.bmp,.webp"
|
||||||
>
|
>
|
||||||
<div class="uploadBtn flex flex-items-center">
|
<div class="uploadBtn flex flex-items-center">
|
||||||
<el-icon><Upload /></el-icon>
|
<el-icon><Upload /></el-icon>
|
||||||
<span>上传文件</span>
|
<span>上传文件</span>
|
||||||
</div>
|
</div>
|
||||||
|
<template #tip>仅支持doc/docx/xls/xlsx/jpg/png/gif等</template>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -144,14 +146,16 @@ const handleAvatarRemove: UploadProps['onRemove'] = (uploadFile: UploadUserFile,
|
|||||||
// 定义大小限制常量 (单位: MB)
|
// 定义大小限制常量 (单位: MB)
|
||||||
const MAX_SINGLE_FILE_SIZE = 10 * 1024 * 1024; // 10MB in bytes
|
const MAX_SINGLE_FILE_SIZE = 10 * 1024 * 1024; // 10MB in bytes
|
||||||
const MAX_TOTAL_FILE_SIZE = 20 * 1024 * 1024; // 20MB in bytes
|
const MAX_TOTAL_FILE_SIZE = 20 * 1024 * 1024; // 20MB in bytes
|
||||||
// 禁止的危险文件后缀
|
const uploadRef = ref();
|
||||||
const forbidSuffix = ['exe', 'msi', 'bat', 'cmd', 'sh', 'apk', 'dmg'];
|
|
||||||
// 添加一个锁,防止 on-change 递归调用导致重复提示
|
// 添加一个锁,防止 on-change 递归调用导致重复提示
|
||||||
const isChecking = ref(false);
|
const isChecking = ref(false);
|
||||||
const handleProgress: UploadProps['onChange'] = (uploadFile: UploadUserFile, uploadFiles: UploadFiles) => {
|
const handleProgress: UploadProps['onChange'] = (uploadFile: UploadUserFile, uploadFiles: UploadFiles) => {
|
||||||
// 如果正在校验中,直接返回,避免重复执行
|
// 如果正在校验中,直接返回,避免重复执行
|
||||||
|
if (!beforeAvatarUpload(uploadFile)) {
|
||||||
|
uploadRef.value.handleRemove(uploadFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (isChecking.value) return;
|
if (isChecking.value) return;
|
||||||
|
|
||||||
// 加锁
|
// 加锁
|
||||||
isChecking.value = true;
|
isChecking.value = true;
|
||||||
// 创建一个新数组来存储校验通过的文件
|
// 创建一个新数组来存储校验通过的文件
|
||||||
@@ -229,12 +233,41 @@ const handleProgress: UploadProps['onChange'] = (uploadFile: UploadUserFile, upl
|
|||||||
};
|
};
|
||||||
|
|
||||||
const blockedExts = ['.exe', '.bat', '.cmd', '.msi'];
|
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('.'));
|
const ext = rawFile.name.toLowerCase().slice(rawFile.name.lastIndexOf('.'));
|
||||||
if (blockedExts.includes(ext)) {
|
if (blockedExts.includes(ext)) {
|
||||||
ElMessage.warning(`禁止上传 ${ext} 文件`);
|
ElMessage.warning(`禁止上传 ${ext} 文件`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!allowExts.includes(ext)) {
|
||||||
|
ElMessage.warning('只能上传word,excel,图片等文件');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
:height="500"
|
:height="500"
|
||||||
:min-height="300"
|
:min-height="300"
|
||||||
:read-only="false"
|
:read-only="false"
|
||||||
|
type="url"
|
||||||
:file-size="5"
|
:file-size="5"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -71,7 +72,6 @@ import PageHeader from '@/components/Pageheader/index.vue';
|
|||||||
import { addNotice, getNotice } from '@/api/system/NoticePc';
|
import { addNotice, getNotice } from '@/api/system/NoticePc';
|
||||||
import { updateNotice } from '@/api/system/NoticePc';
|
import { updateNotice } from '@/api/system/NoticePc';
|
||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
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 { com_publish_status } = toRefs<any>(proxy?.useDict('com_publish_status'));
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
@@ -94,6 +94,7 @@ const rules = {
|
|||||||
const userid = ref();
|
const userid = ref();
|
||||||
// ! 富文本 =============================================================================================================
|
// ! 富文本 =============================================================================================================
|
||||||
function handleContent(val: string) {
|
function handleContent(val: string) {
|
||||||
|
console.log(val);
|
||||||
form.value.noticeContent = val.trim();
|
form.value.noticeContent = val.trim();
|
||||||
}
|
}
|
||||||
// ! 富文本 =============================================================================================================
|
// ! 富文本 =============================================================================================================
|
||||||
@@ -134,9 +135,7 @@ const submitForm = () => {
|
|||||||
|
|
||||||
// 返回
|
// 返回
|
||||||
function handleBack() {
|
function handleBack() {
|
||||||
router.push({
|
router.back();
|
||||||
path: '/repair/noticepc'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -47,23 +47,23 @@
|
|||||||
<dict-tag :options="com_publish_status" :value="scope.row.publishStatus"></dict-tag>
|
<dict-tag :options="com_publish_status" :value="scope.row.publishStatus"></dict-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="已读" width="120" align="center" prop="readNum">
|
<el-table-column label="已读" align="center" prop="readNum">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span>{{ scope.row.readNum ?? '--' }} 人</span>
|
<span>{{ scope.row.readNum ?? '--' }} 人</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="未读" width="120" align="center" prop="unReadNum">
|
<el-table-column label="未读" align="center" prop="unReadNum">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span>{{ scope.row.unReadNum ?? '--' }} 人</span>
|
<span>{{ scope.row.unReadNum ?? '--' }} 人</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="发布人" align="center" prop="publishBy" />
|
<!-- <el-table-column label="发布人" align="center" prop="publishBy" />-->
|
||||||
<el-table-column label="发布日期" align="center" prop="publishTime" width="100">
|
<!-- <el-table-column label="发布日期" align="center" prop="publishTime" width="100">-->
|
||||||
<template #default="scope">
|
<!-- <template #default="scope">-->
|
||||||
<span>{{ parseTime(scope.row.publishTime, '{y}-{m}-{d}') }}</span>
|
<!-- <span>{{ parseTime(scope.row.publishTime, '{y}-{m}-{d}') }}</span>-->
|
||||||
</template>
|
<!-- </template>-->
|
||||||
</el-table-column>
|
<!-- </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" fixed="right" class-name="small-padding fixed-width">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button link type="primary" @click="handleMain(scope.row)">详情</el-button>
|
<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>
|
<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';
|
import { checkPermi } from '@/utils/permission';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
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 { com_publish_status } = toRefs<any>(proxy?.useDict('com_publish_status'));
|
||||||
|
|
||||||
const noticeList = ref<NoticeVO[]>([]);
|
const noticeList = ref<NoticeVO[]>([]);
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ const { com_questionnaire_scope } = toRefs<any>(proxy?.useDict('com_questionnair
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
import { listResident } from '@/api/system/resident';
|
import { listResident } from '@/api/system/residentReviewProcess/resident';
|
||||||
|
|
||||||
const form = ref({
|
const form = ref({
|
||||||
scope: '0',
|
scope: '0',
|
||||||
|
|||||||
@@ -218,7 +218,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
<el-form-item label="备注" prop="remark">
|
<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>
|
</el-form-item>
|
||||||
<div class="flex justify-end">
|
<div class="flex justify-end">
|
||||||
<el-button @click="closer">取消</el-button>
|
<el-button @click="closer">取消</el-button>
|
||||||
@@ -234,7 +234,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</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="title">{{ print_form.title }}</div>
|
||||||
<div class="nav gridBox">
|
<div class="nav gridBox">
|
||||||
<div>单据日期:{{ print_form.printDate }}</div>
|
<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="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>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -283,7 +283,7 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<p style="font-size: 10px">说明:本收据收款单位和收款具签章方为有效,本收据手写无效</p>
|
<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">交款人:</div>
|
||||||
<div class="flex-1 flex flex-items-center">
|
<div class="flex-1 flex flex-items-center">
|
||||||
<span style="white-space: nowrap">收款人: </span>
|
<span style="white-space: nowrap">收款人: </span>
|
||||||
@@ -488,6 +488,7 @@ function initInComeFrom() {
|
|||||||
discount: 0, // 优惠金额
|
discount: 0, // 优惠金额
|
||||||
residentName: '' // 缴费人
|
residentName: '' // 缴费人
|
||||||
};
|
};
|
||||||
|
totalDiscountAmount.value = 0;
|
||||||
isMore = false;
|
isMore = false;
|
||||||
}
|
}
|
||||||
// 改变优惠方式
|
// 改变优惠方式
|
||||||
@@ -598,6 +599,7 @@ function handleIncome(row: billlistType | false) {
|
|||||||
inComeFrom.value.allCost = row.amount;
|
inComeFrom.value.allCost = row.amount;
|
||||||
inComeFrom.value.billResidentId = [row];
|
inComeFrom.value.billResidentId = [row];
|
||||||
inComeFrom.value.residentName = row.residentName;
|
inComeFrom.value.residentName = row.residentName;
|
||||||
|
totalDiscountAmount.value = Number(row.amount);
|
||||||
} else {
|
} else {
|
||||||
if (ids.value.length <= 0) return ElMessage.warning('请选择账单');
|
if (ids.value.length <= 0) return ElMessage.warning('请选择账单');
|
||||||
const set = new Set();
|
const set = new Set();
|
||||||
|
|||||||
@@ -267,7 +267,6 @@ function handleChange(pop) {
|
|||||||
holderInfo.value = pop;
|
holderInfo.value = pop;
|
||||||
form.value.userId = '';
|
form.value.userId = '';
|
||||||
form.value.userName = '';
|
form.value.userName = '';
|
||||||
console.log(pop);
|
|
||||||
if (pop !== null) {
|
if (pop !== null) {
|
||||||
form.value.userId = pop.user_id;
|
form.value.userId = pop.user_id;
|
||||||
form.value.userName = pop.user_name;
|
form.value.userName = pop.user_name;
|
||||||
|
|||||||
@@ -66,7 +66,7 @@
|
|||||||
import Pageheader from '@/components/Pageheader/index.vue';
|
import Pageheader from '@/components/Pageheader/index.vue';
|
||||||
import { listCar, delCar } from '@/api/system/cars/index';
|
import { listCar, delCar } from '@/api/system/cars/index';
|
||||||
import { CarVO, CarQuery, CarForm } from '@/api/system/cars/type';
|
import { CarVO, CarQuery, CarForm } from '@/api/system/cars/type';
|
||||||
import { listResident } from '@/api/system/resident';
|
import { listResident } from '@/api/system/residentReviewProcess/resident';
|
||||||
import { checkPermi } from '@/utils/permission';
|
import { checkPermi } from '@/utils/permission';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ const handleChangeFile = (uploadFile: UploadFile, uploadFiles: UploadFiles) => {
|
|||||||
const ext = uploadFile.name.toLowerCase().slice(uploadFile.name.lastIndexOf('.'));
|
const ext = uploadFile.name.toLowerCase().slice(uploadFile.name.lastIndexOf('.'));
|
||||||
if (blockedExts.includes(ext)) {
|
if (blockedExts.includes(ext)) {
|
||||||
ElMessage.warning(`禁止上传 ${ext} 文件`);
|
ElMessage.warning(`禁止上传 ${ext} 文件`);
|
||||||
fileList.value = uploadFiles.filter((f) => f.uid !== uploadFile.uid);
|
uploadRef.value.handleRemove(uploadFile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fileList.value = uploadFiles;
|
fileList.value = uploadFiles;
|
||||||
|
|||||||
@@ -34,12 +34,14 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="14"></el-col>
|
<el-col :span="14"></el-col>
|
||||||
<el-col :span="5" style="text-align: right">
|
<el-col :span="5" style="text-align: right">
|
||||||
<el-button type="warning" @click="exportCurrentPage">导出当前页</el-button>
|
<el-button type="primary" @click="exportChecked">导出选中</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-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</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="100" align="center" prop="statDate" />
|
||||||
<el-table-column label="计划巡检任务" width="120" align="center" prop="totalPlans" />
|
<el-table-column label="计划巡检任务" width="120" align="center" prop="totalPlans" />
|
||||||
<el-table-column label="按时完成" align="center" prop="completedTasks" />
|
<el-table-column label="按时完成" align="center" prop="completedTasks" />
|
||||||
@@ -126,6 +128,26 @@ const exportAll = () => {
|
|||||||
`巡检日报_${new Date().toLocaleString()}.xlsx`
|
`巡检日报_${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(() => {
|
onMounted(() => {
|
||||||
getList();
|
getList();
|
||||||
|
|||||||
@@ -34,13 +34,15 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="14"> </el-col>
|
<el-col :span="14"> </el-col>
|
||||||
<el-col :span="5" style="text-align: right">
|
<el-col :span="5" style="text-align: right">
|
||||||
<el-button type="warning" @click="exportCurrentPage">导出当前页</el-button>
|
<el-button type="primary" @click="exportCurrentPage">导出当前页</el-button>
|
||||||
<el-button type="warning" @click="exportAll">导出所有</el-button>
|
<el-button type="primary" @click="exportAll">导出所有</el-button>
|
||||||
|
<el-button type="primary" @click="exportChecked">导出选中</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</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="100" align="center" prop="statDate" />
|
||||||
<el-table-column label="计划巡检任务" width="120" align="center" prop="totalPlans" />
|
<el-table-column label="计划巡检任务" width="120" align="center" prop="totalPlans" />
|
||||||
<el-table-column label="按时完成" align="center" prop="completedTasks" />
|
<el-table-column label="按时完成" align="center" prop="completedTasks" />
|
||||||
@@ -125,6 +127,26 @@ const exportAll = () => {
|
|||||||
`巡检月报_${new Date().toLocaleString()}.xlsx`
|
`巡检月报_${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(() => {
|
onMounted(() => {
|
||||||
getList();
|
getList();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -34,13 +34,15 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="14"> </el-col>
|
<el-col :span="14"> </el-col>
|
||||||
<el-col :span="5" style="text-align: right">
|
<el-col :span="5" style="text-align: right">
|
||||||
<el-button type="warning" @click="exportCurrentPage">导出当前页</el-button>
|
<el-button type="primary" @click="exportCurrentPage">导出当前页</el-button>
|
||||||
<el-button type="warning" @click="exportAll">导出所有</el-button>
|
<el-button type="primary" @click="exportAll">导出所有</el-button>
|
||||||
|
<el-button type="primary" @click="exportChecked">导出选中</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</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="statDate" />
|
||||||
<el-table-column label="计划巡检任务" width="120" align="center" prop="totalPlans" />
|
<el-table-column label="计划巡检任务" width="120" align="center" prop="totalPlans" />
|
||||||
<el-table-column label="按时完成" align="center" prop="completedTasks" />
|
<el-table-column label="按时完成" align="center" prop="completedTasks" />
|
||||||
@@ -129,6 +131,27 @@ const exportAll = () => {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList();
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -139,8 +139,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import PageHeader from '@/components/Pageheader/index.vue';
|
import PageHeader from '@/components/Pageheader/index.vue';
|
||||||
import { getResident, getresidentReviewlistAPI, UpdateResidentReviewAPI } from '@/api/system/resident';
|
import { getResident, getresidentReviewlistAPI, UpdateResidentReviewAPI } from '@/api/system/residentReviewProcess/resident';
|
||||||
import { ResidentVO } from '@/api/system/resident/type';
|
import { ResidentVO } from '@/api/system/residentReviewProcess/resident/type';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
const { com_review } = toRefs<any>(proxy?.useDict('com_review'));
|
const { com_review } = toRefs<any>(proxy?.useDict('com_review'));
|
||||||
|
|||||||
@@ -107,10 +107,10 @@
|
|||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import PageHeader from '@/components/Pageheader/index.vue';
|
import PageHeader from '@/components/Pageheader/index.vue';
|
||||||
import { getHousePathById } from '@/utils/house';
|
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 { CascaderValue, UploadFiles, UploadInstance, UploadProps, UploadRawFile } from 'element-plus';
|
||||||
import { genFileId } 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 { validator } from '@/utils/Reg';
|
||||||
import { useHouseStore } from '@/store/modules/house';
|
import { useHouseStore } from '@/store/modules/house';
|
||||||
import { Plus } from '@element-plus/icons-vue';
|
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 RightToolbar from '@/components/RightToolbar/index.vue';
|
||||||
import DictTag from '@/components/DictTag/index.vue';
|
import DictTag from '@/components/DictTag/index.vue';
|
||||||
|
|
||||||
import { listResident, delResident } from '@/api/system/resident';
|
import { listResident, delResident } from '@/api/system/residentReviewProcess/resident';
|
||||||
import { ResidentVO, ResidentQuery, ResidentForm } from '@/api/system/resident/type';
|
import { ResidentVO, ResidentQuery, ResidentForm } from '@/api/system/residentReviewProcess/resident/type';
|
||||||
import { useHouseStore } from '@/store/modules/house';
|
import { useHouseStore } from '@/store/modules/house';
|
||||||
import { checkPermi } from '@/utils/permission';
|
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 class="cardbox">
|
||||||
<div>收入来源</div>
|
<div>收入来源</div>
|
||||||
<div class="card_InfoAll">
|
<div class="card_InfoAll">
|
||||||
<div>应缴费用:{{ formatMoneyWithUnit(sourceFrom.totalPayable) }}</div>
|
<div>应缴费用:{{ formatMoneyWithUnit(sourceFrom.totalPayable, 3) }}</div>
|
||||||
<div>已收:{{ formatMoneyWithUnit(sourceFrom.totalReceived) }}</div>
|
<div>已收:{{ formatMoneyWithUnit(sourceFrom.totalReceived, 3) }}</div>
|
||||||
<div>待收:{{ formatMoneyWithUnit(sourceFrom.totalPending) }}</div>
|
<div>待收:{{ formatMoneyWithUnit(sourceFrom.totalPending, 3) }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="cardBody" style="display: flex; flex-wrap: wrap" v-if="sourceFromIsComputed">
|
<div class="cardBody" style="display: flex; flex-wrap: wrap" v-if="sourceFromIsComputed">
|
||||||
<RingProgress name="停车费" color="#1a75ff" :value="sourceFrom.parkingFeePercent"></RingProgress>
|
<RingProgress name="停车费" color="#1a75ff" :value="sourceFrom.parkingFeePercent"></RingProgress>
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ import { listStock } from '@/api/system/Tstock';
|
|||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const materialList = ref<MaterialVO[]>([]);
|
const materialList = ref<MaterialVO[]>([]);
|
||||||
const buttonLoading = ref(false);
|
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
const showSearch = ref(true);
|
const showSearch = ref(true);
|
||||||
const ids = ref<Array<string | number>>([]);
|
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;
|
const _ids = row?.materialId;
|
||||||
router.push({
|
router.push({
|
||||||
path: '/warehouse/editInventory',
|
path: '/warehouse/editInventory',
|
||||||
|
|||||||
@@ -35,8 +35,6 @@ import { ref } from 'vue';
|
|||||||
import PageHeader from '@/components/Pageheader/index.vue';
|
import PageHeader from '@/components/Pageheader/index.vue';
|
||||||
import { getMaterial, updateMaterial, addMaterial } from '@/api/system/Tmaterial';
|
import { getMaterial, updateMaterial, addMaterial } from '@/api/system/Tmaterial';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
<el-form-item label="供应商名称" prop="supplierName">
|
<el-form-item label="供应商名称" prop="supplierName">
|
||||||
<el-input v-model.trim="form.supplierName" placeholder="请输入供应商名称" />
|
<el-input v-model.trim="form.supplierName" placeholder="请输入供应商名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="联系人" prop="contactPerson">
|
<el-form-item label="联系人">
|
||||||
<el-input v-model.trim="form.contactPerson" placeholder="请输入联系人" />
|
<el-input v-model.trim="form.contactPerson" placeholder="请输入联系人" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="联系电话" prop="contactPhone">
|
<el-form-item label="联系电话">
|
||||||
<el-input v-model.trim="form.contactPhone" placeholder="请输入联系电话" />
|
<el-input v-model.trim="form.contactPhone" placeholder="请输入联系电话" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="邮箱" prop="email">
|
<el-form-item label="邮箱">
|
||||||
<el-input v-model.trim="form.email" placeholder="请输入邮箱" />
|
<el-input v-model.trim="form.email" placeholder="请输入邮箱" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="地址" prop="address">
|
<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 { getSupplier, updateSupplier, addSupplier } from '@/api/system/Tsupplier';
|
||||||
import { validator } from '@/utils/Reg';
|
import { validator } from '@/utils/Reg';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,13 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="归属小区" prop="villageId">
|
<el-form-item label="归属小区" prop="villageId">
|
||||||
<el-select v-model="form.villageId" placeholder="请选择归属小区">
|
<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-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="联系人" prop="contactPerson">
|
<el-form-item label="联系人">
|
||||||
<el-input v-model.trim="form.contactPerson" placeholder="请输入联系人" />
|
<el-input v-model.trim="form.contactPerson" placeholder="请输入联系人" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="联系电话" prop="contactPhone">
|
<el-form-item label="联系电话">
|
||||||
<el-input v-model.trim="form.contactPhone" placeholder="请输入联系电话" />
|
<el-input v-model.trim="form.contactPhone" placeholder="请输入联系电话" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="地址" prop="address">
|
<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 { addWarehouse, getWarehouse, updateWarehouse } from '@/api/system/Twarehouse';
|
||||||
import { validator } from '@/utils/Reg';
|
import { validator } from '@/utils/Reg';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
@@ -63,7 +61,7 @@ const rules = ref({
|
|||||||
contactPhone: [
|
contactPhone: [
|
||||||
{ required: true, message: '请输入 联系电话', trigger: 'blur' },
|
{ required: true, message: '请输入 联系电话', trigger: 'blur' },
|
||||||
{
|
{
|
||||||
validator: (_, value) => validator(value, 'phone'),
|
validator: (_: any, value: string | number) => validator(value, 'phone'),
|
||||||
message: '请输入正确的电话号码',
|
message: '请输入正确的电话号码',
|
||||||
trigger: 'blur'
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
@@ -74,10 +72,10 @@ const rules = ref({
|
|||||||
const userid = ref(null);
|
const userid = ref(null);
|
||||||
|
|
||||||
// 小区列表
|
// 小区列表
|
||||||
const cummunitylist = ref([]);
|
const communityList = ref([]);
|
||||||
function init() {
|
function init() {
|
||||||
getCommunitylistAPI().then((res) => {
|
getCommunitylistAPI().then((res) => {
|
||||||
cummunitylist.value = res.rows;
|
communityList.value = res.rows;
|
||||||
});
|
});
|
||||||
if (route.query.id) {
|
if (route.query.id) {
|
||||||
userid.value = route.query.id;
|
userid.value = route.query.id;
|
||||||
@@ -103,12 +101,12 @@ const submitForm = () => {
|
|||||||
formRef.value?.validate(async (valid: boolean) => {
|
formRef.value?.validate(async (valid: boolean) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (userid.value) {
|
if (userid.value) {
|
||||||
updateWarehouse(form.value).then((res) => {
|
updateWarehouse(form.value).then(() => {
|
||||||
ElMessage.success('编辑成功');
|
ElMessage.success('编辑成功');
|
||||||
cancelForm();
|
cancelForm();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
addWarehouse(form.value).then((res) => {
|
addWarehouse(form.value).then(() => {
|
||||||
ElMessage.success('添加成功');
|
ElMessage.success('添加成功');
|
||||||
cancelForm();
|
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 {
|
.echarts {
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 450px;
|
height: 512px;
|
||||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, #ffffff 70%);
|
background: linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, #ffffff 70%);
|
||||||
border: 2px solid #ffffff;
|
border: 2px solid #ffffff;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
|
|||||||
@@ -71,6 +71,31 @@ function headerToken() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
const blockedExts = ['.exe', '.bat', '.cmd', '.msi'];
|
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) => {
|
const handleAvatarRemove: UploadProps['onRemove'] = (uploadFile: UploadFile, uploadFiles: UploadFiles) => {
|
||||||
fileList.value = uploadFiles;
|
fileList.value = uploadFiles;
|
||||||
};
|
};
|
||||||
@@ -78,7 +103,12 @@ const handleProgress: UploadProps['onChange'] = (uploadFile: UploadFile, uploadF
|
|||||||
const ext = uploadFile.name.toLowerCase().slice(uploadFile.name.lastIndexOf('.'));
|
const ext = uploadFile.name.toLowerCase().slice(uploadFile.name.lastIndexOf('.'));
|
||||||
if (blockedExts.includes(ext)) {
|
if (blockedExts.includes(ext)) {
|
||||||
ElMessage.warning(`禁止上传 ${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;
|
return;
|
||||||
}
|
}
|
||||||
fileList.value = uploadFiles;
|
fileList.value = uploadFiles;
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<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 { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
const { com_resident_type } = toRefs<any>(proxy?.useDict('com_resident_type'));
|
const { com_resident_type } = toRefs<any>(proxy?.useDict('com_resident_type'));
|
||||||
|
|||||||
@@ -7,8 +7,7 @@
|
|||||||
<VillageAllInfo :list="list"></VillageAllInfo>
|
<VillageAllInfo :list="list"></VillageAllInfo>
|
||||||
<div class="echartsbox flex flex-items-center">
|
<div class="echartsbox flex flex-items-center">
|
||||||
<repairechartsAll></repairechartsAll>
|
<repairechartsAll></repairechartsAll>
|
||||||
<repairechartsAll></repairechartsAll>
|
<feeOverview></feeOverview>
|
||||||
<inandoutEcharts></inandoutEcharts>
|
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- tabs -->
|
<!-- tabs -->
|
||||||
@@ -80,6 +79,7 @@ import weatherVue from './components/weather.vue';
|
|||||||
import userTable from './components/usertable.vue';
|
import userTable from './components/usertable.vue';
|
||||||
import quick from './components/quick.vue';
|
import quick from './components/quick.vue';
|
||||||
import todo from './components/todo.vue';
|
import todo from './components/todo.vue';
|
||||||
|
import feeOverview from './components/feeOverview.vue';
|
||||||
|
|
||||||
import inandoutEcharts from './components/inandout.vue';
|
import inandoutEcharts from './components/inandout.vue';
|
||||||
import repairechartsAll from './components/repairechartsAll.vue';
|
import repairechartsAll from './components/repairechartsAll.vue';
|
||||||
|
|||||||
Reference in New Issue
Block a user