代码调试

This commit is contained in:
BianLzhaoMin 2025-12-26 10:15:18 +08:00
parent c9093f203c
commit e49f216474
6 changed files with 281 additions and 201 deletions

View File

@ -1,5 +1,6 @@
<template> <template>
<el-select <el-select
filterable
:style="style" :style="style"
:size="size" :size="size"
v-bind="$attrs" v-bind="$attrs"

View File

@ -95,7 +95,7 @@ export const constantRoutes = [
component: () => import('@/views/planMange/monthlyPlan/edit.vue'), component: () => import('@/views/planMange/monthlyPlan/edit.vue'),
name: 'MonthlyPlanEdit', name: 'MonthlyPlanEdit',
meta: { meta: {
title: '月计划填报', title: '月计划',
activeMenu: '/plan/monthlyPlan', // 保持左侧高亮在列表菜单 activeMenu: '/plan/monthlyPlan', // 保持左侧高亮在列表菜单
}, },
}, },
@ -111,7 +111,7 @@ export const constantRoutes = [
component: () => import('@/views/planMange/dailyPlan/edit.vue'), component: () => import('@/views/planMange/dailyPlan/edit.vue'),
name: 'DailyPlanEdit', name: 'DailyPlanEdit',
meta: { meta: {
title: '日计划填报', title: '日计划',
activeMenu: '/plan/dailyPlan', // 保持左侧高亮在列表菜单 activeMenu: '/plan/dailyPlan', // 保持左侧高亮在列表菜单
}, },
}, },

View File

@ -1,5 +1,5 @@
import axios from 'axios' import axios from 'axios'
import { ElNotification , ElMessageBox, ElMessage, ElLoading } from 'element-plus' import { ElNotification, ElMessageBox, ElMessage, ElLoading } from 'element-plus'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode' import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from '@/utils/ruoyi' import { tansParams, blobValidate } from '@/utils/ruoyi'
@ -17,11 +17,12 @@ const service = axios.create({
// axios中请求配置有baseURL选项表示请求URL公共部分 // axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: import.meta.env.VITE_APP_BASE_API, baseURL: import.meta.env.VITE_APP_BASE_API,
// 超时 // 超时
timeout: 10000 timeout: 10000,
}) })
// request拦截器 // request拦截器
service.interceptors.request.use(config => { service.interceptors.request.use(
(config) => {
// 是否需要设置 token // 是否需要设置 token
const isToken = (config.headers || {}).isToken === false const isToken = (config.headers || {}).isToken === false
// 是否需要防止数据重复提交 // 是否需要防止数据重复提交
@ -40,12 +41,14 @@ service.interceptors.request.use(config => {
const requestObj = { const requestObj = {
url: config.url, url: config.url,
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
time: new Date().getTime() time: new Date().getTime(),
} }
const requestSize = Object.keys(JSON.stringify(requestObj)).length // 请求数据大小 const requestSize = Object.keys(JSON.stringify(requestObj)).length // 请求数据大小
const limitSize = 5 * 1024 * 1024 // 限制存放数据5M const limitSize = 5 * 1024 * 1024 // 限制存放数据5M
if (requestSize >= limitSize) { if (requestSize >= limitSize) {
console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制无法进行防重复提交验证。') console.warn(
`[${config.url}]: ` + '请求数据大小超出允许的5M限制无法进行防重复提交验证。',
)
return config return config
} }
const sessionObj = cache.session.getJSON('sessionObj') const sessionObj = cache.session.getJSON('sessionObj')
@ -56,7 +59,11 @@ service.interceptors.request.use(config => {
const s_data = sessionObj.data // 请求数据 const s_data = sessionObj.data // 请求数据
const s_time = sessionObj.time // 请求时间 const s_time = sessionObj.time // 请求时间
const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交 const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交
if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) { if (
s_data === requestObj.data &&
requestObj.time - s_time < interval &&
s_url === requestObj.url
) {
const message = '数据正在处理,请勿重复提交' const message = '数据正在处理,请勿重复提交'
console.warn(`[${s_url}]: ` + message) console.warn(`[${s_url}]: ` + message)
return Promise.reject(new Error(message)) return Promise.reject(new Error(message))
@ -66,13 +73,16 @@ service.interceptors.request.use(config => {
} }
} }
return config return config
}, error => { },
(error) => {
console.log(error) console.log(error)
Promise.reject(error) Promise.reject(error)
}) },
)
// 响应拦截器 // 响应拦截器
service.interceptors.response.use(res => { service.interceptors.response.use(
(res) => {
// 未设置状态码则默认成功状态 // 未设置状态码则默认成功状态
const code = res.data.code || 200 const code = res.data.code || 200
// 获取错误信息 // 获取错误信息
@ -84,12 +94,20 @@ service.interceptors.response.use(res => {
if (code === 401) { if (code === 401) {
if (!isRelogin.show) { if (!isRelogin.show) {
isRelogin.show = true isRelogin.show = true
ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { ElMessageBox.confirm(
'登录状态已过期,您可以继续留在该页面,或者重新登录',
'系统提示',
{ confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' },
)
.then(() => {
isRelogin.show = false isRelogin.show = false
useUserStore().logOut().then(() => { useUserStore()
.logOut()
.then(() => {
location.href = '/index' location.href = '/index'
}) })
}).catch(() => { })
.catch(() => {
isRelogin.show = false isRelogin.show = false
}) })
} }
@ -107,30 +125,39 @@ service.interceptors.response.use(res => {
return Promise.resolve(res.data) return Promise.resolve(res.data)
} }
}, },
error => { (error) => {
console.log('err' + error) console.log('err' + error)
let { message } = error let { message } = error
if (message == "Network Error") { if (message == 'Network Error') {
message = "后端接口连接异常" message = '后端接口连接异常'
} else if (message.includes("timeout")) { } else if (message.includes('timeout')) {
message = "系统接口请求超时" message = '系统接口请求超时'
} else if (message.includes("Request failed with status code")) { } else if (message.includes('Request failed with status code')) {
message = "系统接口" + message.substr(message.length - 3) + "异常" message = '系统接口' + message.substr(message.length - 3) + '异常'
} }
ElMessage({ message: message, type: 'error', duration: 5 * 1000 }) ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
return Promise.reject(error) return Promise.reject(error)
} },
) )
// 通用下载方法 // 通用下载方法
export function download(url, params, filename, config) { export function download(url, params, filename, config) {
downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)", }) downloadLoadingInstance = ElLoading.service({
return service.post(url, params, { text: '正在下载数据,请稍候',
transformRequest: [(params) => { return tansParams(params) }], background: 'rgba(0, 0, 0, 0.7)',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, })
return service
.post(url, params, {
transformRequest: [
(params) => {
return tansParams(params)
},
],
headers: { ...config?.headers, 'Content-Type': 'application/x-www-form-urlencoded' },
responseType: 'blob', responseType: 'blob',
...config ...config,
}).then(async (data) => { })
.then(async (data) => {
const isBlob = blobValidate(data) const isBlob = blobValidate(data)
if (isBlob) { if (isBlob) {
const blob = new Blob([data]) const blob = new Blob([data])
@ -142,7 +169,8 @@ export function download(url, params, filename, config) {
ElMessage.error(errMsg) ElMessage.error(errMsg)
} }
downloadLoadingInstance.close() downloadLoadingInstance.close()
}).catch((r) => { })
.catch((r) => {
console.error(r) console.error(r)
ElMessage.error('下载文件出现错误,请联系管理员!') ElMessage.error('下载文件出现错误,请联系管理员!')
downloadLoadingInstance.close() downloadLoadingInstance.close()

View File

@ -1,57 +1,49 @@
import { reactive } from 'vue' import { reactive } from 'vue'
import dayjs from 'dayjs' import dayjs from 'dayjs'
// 静态选项(可后续替换为接口下拉)
const stationOptions = [
{ label: '昆明运检站', value: 1 },
{ label: '大理运检站', value: 2 },
]
const majorOptions = [
{ label: '输电专业', value: 1 },
{ label: '变电专业', value: 2 },
]
const businessTypeOptions = [
{ label: '日常巡视', value: 1 },
{ label: '缺陷处理', value: 2 },
]
const riskLevelOptions = [
{ label: '低风险', value: 1 },
{ label: '中风险', value: 2 },
{ label: '高风险', value: 3 },
]
// 月计划列表搜索表单配置 // 月计划列表搜索表单配置
export const buildFormColumns = () => [ export const buildFormColumns = (
inspectionStationOptions,
majorOptions,
businessTypeOptions,
riskLevelOptions,
) => [
{ {
type: 'month', type: 'month',
prop: 'month', prop: 'monthlyPlan',
placeholder: '请选择月份', placeholder: '请选择月份',
}, },
{ {
type: 'select', type: 'select',
prop: 'stationId', prop: 'inspectionStationId',
placeholder: '请选择运检站', placeholder: '请选择运检站',
options: stationOptions, options: inspectionStationOptions.map((item) => ({
label: item.value,
value: item.id,
})),
}, },
{ {
type: 'input', type: 'input',
prop: 'keyword', prop: 'keyWord',
placeholder: '请输入关键字', placeholder: '请输入关键字',
}, },
{ {
type: 'select', type: 'select',
prop: 'majorId', prop: 'planMajorId',
placeholder: '请选择专业', placeholder: '请选择专业',
options: majorOptions, options: majorOptions.map((item) => ({
label: item.planMajorName,
value: item.planMajorId,
})),
}, },
{ {
type: 'select', type: 'select',
prop: 'businessTypeId', prop: 'businessTypeId',
placeholder: '请选择业务类型', placeholder: '请选择业务类型',
options: businessTypeOptions, options: businessTypeOptions.map((item) => ({
label: item.planMajorName,
value: item.planMajorId,
})),
}, },
{ {
type: 'select', type: 'select',

View File

@ -208,7 +208,7 @@
@click="onOpenPersonPicker" @click="onOpenPersonPicker"
v-model="selectedManagerNames" v-model="selectedManagerNames"
> >
<template #suffix> <template #suffix v-if="!isDetail">
<el-icon <el-icon
class="clickable-suffix" class="clickable-suffix"
@click.stop="onOpenPersonPicker" @click.stop="onOpenPersonPicker"
@ -306,7 +306,7 @@
<div class="card-header">人员排班</div> <div class="card-header">人员排班</div>
</template> </template>
<div class="schedule-wrapper"> <div class="schedule-wrapper">
<div class="schedule-tip"> <div class="schedule-tip" v-if="!isDetail">
<span class="schedule-tip-extra"> <span class="schedule-tip-extra">
仅在计划开始时间 ~ 仅在计划开始时间 ~
计划结束时间范围内可排班表单中的计划投入管理人员只是模板不会被日历上的增删影响 计划结束时间范围内可排班表单中的计划投入管理人员只是模板不会被日历上的增删影响
@ -350,10 +350,10 @@
</template> </template>
<div class="popover-list"> <div class="popover-list">
<el-tag <el-tag
v-for="person in day.managers"
:key="person.id"
size="small" size="small"
closable :key="person.id"
:closable="!isDetail"
v-for="person in day.managers"
@close.stop="onRemovePersonFromDay(day.date, person)" @close.stop="onRemovePersonFromDay(day.date, person)"
> >
{{ person.name }} {{ person.name }}
@ -364,9 +364,9 @@
<div class="person-tags"> <div class="person-tags">
<el-tag <el-tag
size="small" size="small"
v-for="person in day.managers"
:key="person.id" :key="person.id"
closable :closable="!isDetail"
v-for="person in day.managers"
@close.stop="onRemovePersonFromDay(day.date, person)" @close.stop="onRemovePersonFromDay(day.date, person)"
> >
{{ person.name }} {{ person.name }}
@ -483,8 +483,8 @@
<div class="selected-list"> <div class="selected-list">
<div> <div>
<el-tag <el-tag
closable
:key="item.id" :key="item.id"
:closable="!isDetail"
class="selected-tag" class="selected-tag"
@close="onRemoveManager(item)" @close="onRemoveManager(item)"
v-for="item in managerDialog.selected" v-for="item in managerDialog.selected"
@ -512,7 +512,7 @@
</template> </template>
<script setup name="MonthlyPlanEdit"> <script setup name="MonthlyPlanEdit">
import { ref, reactive, computed, getCurrentInstance, nextTick } from 'vue' import { ref, reactive, computed, getCurrentInstance, nextTick, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { updatePlanAPI } from '@/api/planMange/plan.js' import { updatePlanAPI } from '@/api/planMange/plan.js'
import { import {
@ -630,23 +630,6 @@ const getInitFormData = () => ({
const formData = ref(getInitFormData()) const formData = ref(getInitFormData())
//
const stationOptions = [
{ label: '昆明运检站', value: 1 },
{ label: '大理运检站', value: 2 },
]
const businessTypeOptions = [
{ label: '日常巡视', value: 1 },
{ label: '缺陷处理', value: 2 },
]
const riskLevelOptions = [
{ label: '低风险', value: 1 },
{ label: '中风险', value: 2 },
{ label: '高风险', value: 3 },
]
const rules = { const rules = {
planMajorId: [{ required: true, message: '请选择专业', trigger: 'change' }], planMajorId: [{ required: true, message: '请选择专业', trigger: 'change' }],
businessTypeId: [{ required: true, message: '请选择业务类型', trigger: 'change' }], businessTypeId: [{ required: true, message: '请选择业务类型', trigger: 'change' }],
@ -674,8 +657,8 @@ const rules = {
} }
const onBack = () => { const onBack = () => {
// router.back() //
router.push({ proxy.$tab.closeOpenPage({
path: '/plan/monthlyPlan', path: '/plan/monthlyPlan',
}) })
} }

View File

@ -61,27 +61,60 @@
<script setup name="MonthlyPlan"> <script setup name="MonthlyPlan">
import { ref, computed, getCurrentInstance } from 'vue' import { ref, computed, getCurrentInstance } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useOptions } from '@/hooks/useOptions'
import { import {
listMonthlyPlanAPI, listMonthlyPlanAPI,
addMonthlyPlanAPI, addMonthlyPlanAPI,
delMonthlyPlanAPI, delMonthlyPlanAPI,
} from '@/api/planMange/monthlyPlan.js' } from '@/api/planMange/monthlyPlan.js'
import { getInspectionStationSelectAPI, getMajorTypeCategorySelectAPI } from '@/api/common.js'
import config from './config' import config from './config'
import ComTable from '@/components/ComTable/index.vue' import ComTable from '@/components/ComTable/index.vue'
import ComButton from '@/components/ComButton/index.vue' import ComButton from '@/components/ComButton/index.vue'
import ComDialog from '@/components/ComDialog/index.vue' import ComDialog from '@/components/ComDialog/index.vue'
import AddForm from './addForm.vue' import AddForm from './addForm.vue'
const router = useRouter()
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
const { plan_risk_level } = proxy.useDict('plan_risk_level')
const router = useRouter()
const { tableColumns, dialogConfig, buildFormColumns } = config const { tableColumns, dialogConfig, buildFormColumns } = config
const comTableRef = ref(null) const comTableRef = ref(null)
const addFormRef = ref(null) const addFormRef = ref(null)
//
const { options: inspectionStationOptions } = useOptions(
'inspectionStationOptions',
getInspectionStationSelectAPI,
{ category: 0 },
)
//
const { options: majorTypeCategoryOptions } = useOptions(
'majorTypeCategoryOptions',
getMajorTypeCategorySelectAPI,
{
category: 0,
},
)
//
const { options: planBusinessTypeOptions } = useOptions(
'planBusinessTypeOptions',
getMajorTypeCategorySelectAPI,
{
category: 1,
},
)
// 使 // 使
const formColumns = computed(() => buildFormColumns()) const formColumns = computed(() =>
buildFormColumns(
inspectionStationOptions.value,
majorTypeCategoryOptions.value,
planBusinessTypeOptions.value,
plan_risk_level.value,
),
)
// //
const actionColumns = [ const actionColumns = [
@ -90,9 +123,25 @@ const actionColumns = [
type: 'primary', type: 'primary',
link: true, link: true,
handler: (row) => { handler: (row) => {
const {
monthlyPlanId,
inspectionStationName,
projectName,
workContent,
plannedStartTime,
plannedEndTime,
} = row
router.push({ router.push({
path: '/plan/monthlyPlanEdit/index', path: '/plan/monthlyPlanEdit/index',
query: { id: row.planId, mode: 'detail' }, query: {
projectName,
workContent,
monthlyPlanId,
mode: 'detail',
plannedEndTime,
plannedStartTime,
inspectionStationName,
},
}) })
}, },
}, },
@ -112,12 +161,12 @@ const actionColumns = [
router.push({ router.push({
path: '/plan/monthlyPlanEdit/index', path: '/plan/monthlyPlanEdit/index',
query: { query: {
monthlyPlanId,
inspectionStationName,
projectName, projectName,
workContent, workContent,
plannedStartTime, monthlyPlanId,
plannedEndTime, plannedEndTime,
plannedStartTime,
inspectionStationName,
}, },
}) })
}, },
@ -180,23 +229,50 @@ const onCloseDialogOuter = (visible) => {
// //
const onExportPersonArrange = (queryParams) => { const onExportPersonArrange = (queryParams) => {
console.log('queryParams', queryParams) console.log('queryParams', queryParams)
// proxy.download( proxy.download(
// 'xxx/xxx', '/monthlyPlan/export',
// { {
// ...queryParams.value, ...queryParams,
// }, },
// `job_${new Date().getTime()}.xlsx`, `人员安排表.xlsx`,
// ) {
headers: {
'Content-Type': 'application/json',
},
},
)
} }
// //
const onExportOverallSummary = (queryParams) => { const onExportOverallSummary = (queryParams) => {
console.log('queryParams', queryParams) proxy.download(
'/monthlyPlan/exportResourceSummary',
{
...queryParams,
},
`整体汇总表.xlsx`,
{
headers: {
'Content-Type': 'application/json',
},
},
)
} }
// //
const onExportWorkloadSummary = (queryParams) => { const onExportWorkloadSummary = (queryParams) => {
console.log('queryParams', queryParams) proxy.download(
'/monthlyPlan/exportWorkloadSummary',
{
...queryParams,
},
`工作量汇总表.xlsx`,
{
headers: {
'Content-Type': 'application/json',
},
},
)
} }
</script> </script>