Compare commits

..

No commits in common. '53c378ca4bfb50f183b179cb3500c2ea0cab133d' and '85d2f097d761648985d9c6a3a888b88b401f44d5' have entirely different histories.

  1. 16
      src/api/request.ts
  2. 24
      src/api/warning/business.ts
  3. 107
      src/components/file/upload.vue
  4. 55
      src/components/reportAudit/finishDistrbute.vue
  5. 17
      src/views/report/edit/controlPrice.vue
  6. 9
      src/views/warning/business.vue
  7. 75
      src/views/warning/index.vue

16
src/api/request.ts

@ -13,7 +13,7 @@ type Options = {
params?: Record<string, any>, params?: Record<string, any>,
body?: string | FormData | Record<string, any>, body?: string | FormData | Record<string, any>,
config?:Object config?:Object
showErrorMsg?: boolean showErrorMsg: bool
}; };
function get(options: Options) { function get(options: Options) {
@ -90,7 +90,7 @@ function ajax(url: string, options: Options) {
headers: { ...headers, ...options.headers } headers: { ...headers, ...options.headers }
}).then(response => { }).then(response => {
if (response.status === 413) { if (response.status === 413) {
throw new Error('请求内容过大,请缩小文件后重试'); return;
} }
if( isBlob){ if( isBlob){
return response.blob(); return response.blob();
@ -127,20 +127,10 @@ function ajax(url: string, options: Options) {
// }else{ // }else{
// feedback.msgError("请联系开发人员,数据存在问题") // feedback.msgError("请联系开发人员,数据存在问题")
// } // }
if (options.showErrorMsg) { console.log(message)
feedback.msgError(message || '操作失败,请稍后重试')
}
reject(res) reject(res)
} }
} }
}).catch(error => {
if (options.showErrorMsg) {
const message = error?.message === '请求内容过大,请缩小文件后重试'
? error.message
: '网络异常,请检查网络后重试'
feedback.msgError(message)
}
reject(error)
}) })
}) })
} }

24
src/api/warning/business.ts

@ -7,8 +7,7 @@ import request from "@/api/request";
*/ */
export function getWarningBusiness(reportId: string) { export function getWarningBusiness(reportId: string) {
return request.get({ return request.get({
url: `/warning/business/${reportId}`, url: `/warning/business/${reportId}`
showErrorMsg: true
}); });
} }
@ -18,8 +17,7 @@ export function getWarningBusiness(reportId: string) {
export function saveWarningBusiness(data: any) { export function saveWarningBusiness(data: any) {
return request.post({ return request.post({
url: '/warning/business/save', url: '/warning/business/save',
body: data, body: data
showErrorMsg: true
}); });
} }
@ -29,8 +27,7 @@ export function saveWarningBusiness(data: any) {
export function submitWarningBusiness(data: any) { export function submitWarningBusiness(data: any) {
return request.post({ return request.post({
url: '/warning/business/submit', url: '/warning/business/submit',
body: data, body: data
showErrorMsg: true
}); });
} }
@ -40,8 +37,7 @@ export function submitWarningBusiness(data: any) {
export function endWarningBusiness(data: any) { export function endWarningBusiness(data: any) {
return request.post({ return request.post({
url: '/warning/business/end', url: '/warning/business/end',
body: data, body: data
showErrorMsg: true
}); });
} }
@ -51,8 +47,7 @@ export function endWarningBusiness(data: any) {
export function auditPassWarningDistribute(data: any) { export function auditPassWarningDistribute(data: any) {
return request.post({ return request.post({
url: '/warning/business/audit/pass/distribute', url: '/warning/business/audit/pass/distribute',
body: data, body: data
showErrorMsg: true
}); });
} }
@ -62,8 +57,7 @@ export function auditPassWarningDistribute(data: any) {
export function auditRejectWarning(data: any) { export function auditRejectWarning(data: any) {
return request.post({ return request.post({
url: '/warning/business/audit/reject', url: '/warning/business/audit/reject',
body: data, body: data
showErrorMsg: true
}); });
} }
@ -72,8 +66,7 @@ export function auditRejectWarning(data: any) {
*/ */
export function getWarningFlowList(reportId: string) { export function getWarningFlowList(reportId: string) {
return request.get({ return request.get({
url: `/warning/business/flow/${reportId}`, url: `/warning/business/flow/${reportId}`
showErrorMsg: true
}); });
} }
@ -81,7 +74,6 @@ export function getWarningFlowList(reportId: string) {
export const getCompilePage=(body)=>{ export const getCompilePage=(body)=>{
return request.post({ return request.post({
url:`/warning/business/compile/page`, url:`/warning/business/compile/page`,
body, body
showErrorMsg: true
}) })
} }

107
src/components/file/upload.vue

@ -1,7 +1,6 @@
<template> <template>
<div> <div>
<el-upload <el-upload
ref="uploadRef"
:action="`${BASE_PATH}/file/upload`" :action="`${BASE_PATH}/file/upload`"
:headers="{ Authorization: getToken() }" :headers="{ Authorization: getToken() }"
multiple multiple
@ -56,52 +55,7 @@ const props = defineProps({
const emit = defineEmits(["update:files"]); const emit = defineEmits(["update:files"]);
const uploadRef = ref();
const files = ref(props.files); const files = ref(props.files);
const allowArchiveFallback = ref(false);
const fallbackArchiveExts = ['zip', 'rar', '7z'];
const archiveExts = [...fallbackArchiveExts, 'tar', 'gz', 'bz2', 'xz', 'iso', 'dmg'];
const uploadResponseTimeout = 15000;
const responseTimers = new Map();
function getFileExt(file) {
const name = (file?.name || file?.raw?.name || '').toLowerCase();
return name.includes('.') ? name.split('.').pop() : '';
}
function enableArchiveFallback(file) {
if (archiveExts.includes(getFileExt(file))) {
return false;
}
allowArchiveFallback.value = true;
feedback.msgError('文件上传失败,已临时允许上传一个 ZIP、RAR 或 7Z 压缩包');
return true;
}
function clearResponseTimer(file) {
const timer = responseTimers.get(file?.uid);
if (timer) {
window.clearTimeout(timer);
}
responseTimers.delete(file?.uid);
}
function startUploadResponseTimer(file) {
if (archiveExts.includes(getFileExt(file)) || responseTimers.has(file?.uid)) {
return;
}
const timer = window.setTimeout(() => {
responseTimers.delete(file.uid);
uploadRef.value?.abort(file);
handleError(new Error('文件保存响应超时'), file);
}, uploadResponseTimeout);
responseTimers.set(file.uid, timer);
}
onBeforeUnmount(() => {
responseTimers.forEach((timer) => window.clearTimeout(timer));
responseTimers.clear();
});
watch( watch(
() => props.files, () => props.files,
@ -119,10 +73,13 @@ watch(files, () => {
},{immediate:true}); },{immediate:true});
function beforeUpload(file) { function beforeUpload(file) {
const ext = getFileExt(file) const name = (file?.name || '').toLowerCase()
const ext = name.includes('.') ? name.split('.').pop() : ''
// //
const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg', 'tiff', 'tif', 'ico', 'heic', 'heif'] const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg', 'tiff', 'tif', 'ico', 'heic', 'heif']
//
const archiveExts = ['zip', 'rar', '7z', 'tar', 'gz', 'bz2', 'xz', 'iso', 'dmg']
// PDF // PDF
if (imageExts.includes(ext)) { if (imageExts.includes(ext)) {
@ -130,15 +87,10 @@ function beforeUpload(file) {
return false return false
} }
//
if (archiveExts.includes(ext)) { if (archiveExts.includes(ext)) {
if (!allowArchiveFallback.value) { feedback.msgWarning('暂不支持压缩包上传')
feedback.msgWarning('压缩包仅在文件上传失败后允许上传') return false
return false
}
if (!fallbackArchiveExts.includes(ext)) {
feedback.msgWarning('文件上传失败后仅支持 ZIP、RAR 或 7Z 压缩包')
return false
}
} }
// 100MB // 100MB
@ -146,12 +98,6 @@ function beforeUpload(file) {
feedback.msgError('文件大小不能超过100MB'); feedback.msgError('文件大小不能超过100MB');
return false; return false;
} }
if (fallbackArchiveExts.includes(ext)) {
allowArchiveFallback.value = false;
}
if (!archiveExts.includes(ext)) {
allowArchiveFallback.value = false;
}
files.value.push({ files.value.push({
uid: file.uid, uid: file.uid,
percent: 0, percent: 0,
@ -163,54 +109,29 @@ function uploadProgress(progressEvent, file) {
const filterFiles = files.value.filter((item) => file.uid === item.uid); const filterFiles = files.value.filter((item) => file.uid === item.uid);
if (filterFiles.length) { if (filterFiles.length) {
const percent = parseInt(progressEvent.percent);
filterFiles[0].percent = Math.min(99, percent); filterFiles[0].percent = parseInt(progressEvent.percent);
if (percent >= 100) {
startUploadResponseTimer(file);
}
} }
} }
function handleSuccess(data, file) { function handleSuccess(data, file) {
clearResponseTimer(file);
const filterFiles = files.value.filter((item) => file.uid === item.uid); const filterFiles = files.value.filter((item) => file.uid === item.uid);
if (data.code !== 200) { if (data.code !== 200) {
if (!enableArchiveFallback(file)) { feedback.msgError(data.message);
feedback.msgError(data.message); files.value.splice(files.value.indexOf(filterFiles[0]), 1);
}
if (filterFiles.length) {
files.value.splice(files.value.indexOf(filterFiles[0]), 1);
emit("update:files", files.value);
}
return; return;
} }
if (!archiveExts.includes(getFileExt(file))) {
allowArchiveFallback.value = false;
}
if (filterFiles.length) { if (filterFiles.length) {
filterFiles[0].percent = 100;
filterFiles[0].fileName = data.data.fileName; filterFiles[0].fileName = data.data.fileName;
filterFiles[0].filePath = data.data.filePath; filterFiles[0].filePath = data.data.filePath;
window.setTimeout(() => { filterFiles[0].loading = false;
filterFiles[0].loading = false;
emit("update:files", files.value);
}, 300);
} }
console.log("file", files.value); console.log("file", files.value);
emit("update:files", files.value);
} }
function handleError(e, file) { function handleError(e, file) {
clearResponseTimer(file);
console.log(e, file); console.log(e, file);
const fileIndex = files.value.findIndex((item) => file.uid === item.uid); feedback.msgError("上传失败!");
if (fileIndex > -1) {
files.value.splice(fileIndex, 1);
emit("update:files", files.value);
}
if (enableArchiveFallback(file)) {
return;
}
feedback.msgError("上传失败,请重试!");
} }
</script> </script>

55
src/components/reportAudit/finishDistrbute.vue

@ -8,7 +8,7 @@ import {getList,save,delCommon} from '@/api/commonOpinions';
import useCatchStore from "@/stores/modules/catch"; import useCatchStore from "@/stores/modules/catch";
import useUserStore from "@/stores/modules/user"; import useUserStore from "@/stores/modules/user";
const userStore = useUserStore(); const userStore = useUserStore();
const props = defineProps(['dialog','reportId','nextNode','message',"isWarning","flowId","batchItems"]) const props = defineProps(['dialog','reportId','nextNode','message',"isWarning","flowId"])
const emits = defineEmits(['submitFeedback',"closeFun"]) const emits = defineEmits(['submitFeedback',"closeFun"])
const catchStore = useCatchStore(); const catchStore = useCatchStore();
@ -19,7 +19,6 @@ const formData = ref({
data:{} data:{}
}) })
const auditForm= ref() const auditForm= ref()
const submitLoading = ref(false)
const dict = catchStore.getDicts([ const dict = catchStore.getDicts([
"businessType", "businessType",
"suspectProblem", "suspectProblem",
@ -100,43 +99,23 @@ const closeAdd=()=>{
} }
const submitFun = async ()=>{ const submitFun = async ()=>{
await auditForm.value.validate(); await auditForm.value.validate();
const isBatch = Array.isArray(props.batchItems) && props.batchItems.length > 0 await feedback.confirm("是否确认通过?");
const targets = isBatch ? props.batchItems : [{ formData.value.reportId = props.reportId;
reportId: props.reportId, formData.value.flowId = props.flowId;
flowId: props.flowId //nextNode
}] if(props.nextNode){
await feedback.confirm(isBatch ? `是否确认批量通过选中的 ${targets.length} 个项目?` : "是否确认通过?"); formData.value.nextNode = props.nextNode;
submitLoading.value = true }
try { if(props.isWarning){
const createSubmitData = (target) => ({ const res = await auditPassWarningDistribute(formData.value);
...formData.value, // const res = await auditWarning(formData.value);
data: {...formData.value.data}, }else{
reportId: target.reportId, const res = await auditReport(formData.value);
flowId: target.flowId,
nextNode: props.nextNode || formData.value.nextNode
})
if (isBatch) {
const results = await Promise.allSettled(targets.map(target =>
auditPassWarningDistribute(createSubmitData(target))
))
const successCount = results.filter(item => item.status === 'fulfilled').length
const failCount = results.length - successCount
if (failCount > 0) {
feedback.msgError(`批量通过完成:成功 ${successCount} 个,失败 ${failCount}`)
} else {
feedback.msgSuccess(`已批量通过 ${successCount} 个项目`)
}
} else if(props.isWarning){
await auditPassWarningDistribute(createSubmitData(targets[0]));
}else{
await auditReport(createSubmitData(targets[0]));
}
emits('submitFeedback',true)
closeAdd()
} finally {
submitLoading.value = false
} }
emits('submitFeedback',true)
closeAdd()
} }
@ -316,7 +295,7 @@ watch(()=>formData.value.approverId,(val)=>{
</el-form> </el-form>
<div class="flex end"> <div class="flex end">
<el-button @click="closeAdd">关闭</el-button> <el-button @click="closeAdd">关闭</el-button>
<el-button type="primary" :loading="submitLoading" @click="submitFun">提交</el-button> <el-button type="primary" @click="submitFun">提交</el-button>
</div> </div>
</el-dialog> </el-dialog>
</template> </template>

17
src/views/report/edit/controlPrice.vue

@ -82,7 +82,6 @@ const editAll = ref(false)
// //
const delDialog = ref(false); const delDialog = ref(false);
const delFormRef = ref();
const delFormData = ref({}); const delFormData = ref({});
const deleteFlag = ref(false) const deleteFlag = ref(false)
@ -93,10 +92,6 @@ const fixPrecision = (num, precision = 2) => {
} }
const handleDel= async ()=> { const handleDel= async ()=> {
if (!delFormRef.value) return;
const isValid = await delFormRef.value.validate().catch(() => false);
if (!isValid) return;
const body ={ const body ={
id: route.query.id, id: route.query.id,
deleteReason: delFormData.value.deleteReason deleteReason: delFormData.value.deleteReason
@ -1467,9 +1462,14 @@ function hasAuditAttachment() {
<el-table-column width="50" type="index" label="序号" :index="(index)=> index+1"></el-table-column> <el-table-column width="50" type="index" label="序号" :index="(index)=> index+1"></el-table-column>
<el-table-column label="操作" prop="reportCode"></el-table-column> <el-table-column label="操作" prop="reportCode"></el-table-column>
<el-table-column label="办理人" prop="approver"></el-table-column> <el-table-column label="办理人" prop="approver"></el-table-column>
<el-table-column label="操作时间" prop="approverTime"> <el-table-column label="提交时间" prop="areportTime">
<template #default="{row}">
{{ timeFormat(row.areportTime,'yyyy-mm-dd hh:MM:ss') }}
</template>
</el-table-column>
<el-table-column label="完成时间" prop="approverTime">
<template #default="{row}"> <template #default="{row}">
{{ row.approverTime ? timeFormat(row.approverTime,'yyyy-mm-dd hh:MM:ss') : '/' }} {{ timeFormat(row.approverTime,'yyyy-mm-dd hh:MM:ss') }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="办理结果" prop="approverState"> <el-table-column label="办理结果" prop="approverState">
@ -1508,10 +1508,9 @@ function hasAuditAttachment() {
<el-form :label-width="120" :model="delFormData" ref="delFormRef"> <el-form :label-width="120" :model="delFormData" ref="delFormRef">
<el-form-item <el-form-item
label="删除原因" label="删除原因"
prop="deleteReason" prop="delReason"
:rules="{ :rules="{
required: true, required: true,
whitespace: true,
message: '请输入删除原因', message: '请输入删除原因',
}" }"
> >

9
src/views/warning/business.vue

@ -484,9 +484,14 @@ onMounted(() => {
<el-table-column width="50" type="index" label="序号" :index="(index) => index + 1"/> <el-table-column width="50" type="index" label="序号" :index="(index) => index + 1"/>
<el-table-column label="操作" prop="reportCode"/> <el-table-column label="操作" prop="reportCode"/>
<el-table-column label="办理人" prop="approver"/> <el-table-column label="办理人" prop="approver"/>
<el-table-column label="操作时间"> <el-table-column label="提交时间" prop="areportTime">
<template #default="{row}"> <template #default="{row}">
{{ row.approverTime ? timeFormat(row.approverTime, 'yyyy-mm-dd hh:MM:ss') : '/' }} {{ timeFormat(row.areportTime, 'yyyy-mm-dd hh:MM:ss') }}
</template>
</el-table-column>
<el-table-column label="完成时间" prop="approverTime">
<template #default="{row}">
{{ timeFormat(row.approverTime, 'yyyy-mm-dd hh:MM:ss') }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="办理结果" prop="approverState"> <el-table-column label="办理结果" prop="approverState">

75
src/views/warning/index.vue

@ -2,17 +2,11 @@
<script setup> <script setup>
import {warningPage, excelWarningList} from "@/api/warning/index"; import {warningPage, excelWarningList} from "@/api/warning/index";
import {auditRejectWarning} from "@/api/warning/business";
import {timeFormat} from "@/utils/util"; import {timeFormat} from "@/utils/util";
import {useRoute} from "vue-router"; import {useRoute} from "vue-router";
import feedback from "@/utils/feedback";
import finishDistrbute from '@/components/reportAudit/finishDistrbute.vue';
const route = useRoute() const route = useRoute()
const loading =ref(false) const loading =ref(false)
const exportLoading = ref(false) const exportLoading = ref(false)
const batchRejectLoading = ref(false)
const finishDialog = ref(false)
const selectedRows = ref([])
const total =ref(10) const total =ref(10)
const tableData =ref([]) const tableData =ref([])
const activeTab = ref(route.query.specialArea === 'cwlnt' ? 'cwlnt' : route.query.warningState === '1' ? '1' : '0') const activeTab = ref(route.query.specialArea === 'cwlnt' ? 'cwlnt' : route.query.warningState === '1' ? '1' : '0')
@ -50,44 +44,6 @@ const reset =()=>{
getList(); getList();
} }
const warningStateDisabled = computed(() => activeTab.value !== 'cwlnt' && activeTab.value !== 'all') const warningStateDisabled = computed(() => activeTab.value !== 'cwlnt' && activeTab.value !== 'all')
const batchItems = computed(() => selectedRows.value.map(row => ({
reportId: row.id,
flowId: row.flowId
})))
const handleSelectionChange = (rows) => {
selectedRows.value = rows
}
const selectable = (row) => Boolean(row.flowId)
const handleBatchPass = () => {
finishDialog.value = true
}
const handleBatchPassSuccess = () => {
finishDialog.value = false
selectedRows.value = []
getList()
}
const handleBatchReject = async () => {
await feedback.confirm(`确定批量驳回选中的 ${selectedRows.value.length} 个项目吗?`)
batchRejectLoading.value = true
try {
const results = await Promise.allSettled(selectedRows.value.map(row => auditRejectWarning({
flowId: row.flowId,
reportId: row.id,
approverMessage: ''
})))
const successCount = results.filter(item => item.status === 'fulfilled').length
const failCount = results.length - successCount
if (failCount > 0) {
feedback.msgError(`批量驳回完成:成功 ${successCount} 个,失败 ${failCount}`)
} else {
feedback.msgSuccess(`已批量驳回 ${successCount} 个项目`)
}
selectedRows.value = []
getList()
} finally {
batchRejectLoading.value = false
}
}
const getList = async ()=>{ const getList = async ()=>{
loading.value=true loading.value=true
const res = await warningPage(query.value) const res = await warningPage(query.value)
@ -101,7 +57,6 @@ const editFun = (row) =>{
let routeQuery ={ let routeQuery ={
// isEnd:row.reportType === "", // isEnd:row.reportType === "",
reportId:row.id, reportId:row.id,
...(row.flowId ? { flowId: row.flowId } : {}),
// isEdit:true, // isEdit:true,
backPath:'/warning', backPath:'/warning',
} }
@ -190,19 +145,6 @@ watch(()=>route.query.load,(val)=>{
</el-form> </el-form>
<div class="flex end"> <div class="flex end">
<div> <div>
<template v-if="activeTab === '2'">
<el-button
type="success"
:disabled="selectedRows.length === 0"
@click="handleBatchPass"
>批量通过</el-button>
<el-button
type="danger"
:disabled="selectedRows.length === 0"
:loading="batchRejectLoading"
@click="handleBatchReject"
>批量驳回</el-button>
</template>
<el-button type="primary" :loading="exportLoading" @click="handleExcel">导出</el-button> <el-button type="primary" :loading="exportLoading" @click="handleExcel">导出</el-button>
<el-button type="primary" @click="getList"> <el-button type="primary" @click="getList">
<template #icon> <template #icon>
@ -223,13 +165,7 @@ watch(()=>route.query.load,(val)=>{
<el-tab-pane label="已预警" name="1"></el-tab-pane> <el-tab-pane label="已预警" name="1"></el-tab-pane>
<el-tab-pane label="长望浏宁" name="cwlnt"></el-tab-pane> <el-tab-pane label="长望浏宁" name="cwlnt"></el-tab-pane>
</el-tabs> </el-tabs>
<el-table :data="tableData" @selection-change="handleSelectionChange"> <el-table :data="tableData">
<el-table-column
v-if="activeTab === '2'"
type="selection"
width="50"
:selectable="selectable"
/>
<el-table-column label="项目名称" prop="reportName" width="200" /> <el-table-column label="项目名称" prop="reportName" width="200" />
<el-table-column <el-table-column
label="报审类型" label="报审类型"
@ -357,15 +293,6 @@ watch(()=>route.query.load,(val)=>{
<p> <p>
列表根据权限范围展示涉及的可预警项目针对项目进行问题预警报审单位签收 列表根据权限范围展示涉及的可预警项目针对项目进行问题预警报审单位签收
</p> </p>
<finish-distrbute
v-if="finishDialog"
@submitFeedback="handleBatchPassSuccess"
@closeFun="finishDialog = false"
:isWarning="true"
:batchItems="batchItems"
:dialog="finishDialog"
:nextNode="'end'"
/>
</el-main> </el-main>
</div> </div>
</template> </template>

Loading…
Cancel
Save