add 巡检
parent
7e83fc530c
commit
a7eb823208
|
|
@ -0,0 +1,50 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
// 项目巡检内容 VO
|
||||
export interface ProjectInspectionDataVO {
|
||||
id: number // 主键ID
|
||||
configType: number // 巡检配置类型
|
||||
name: string // 名称
|
||||
isRequired: boolean // 是否必填:0-否,1-是
|
||||
type: number // 类型,1-文本,2-数字,3-单选,4-多选,5-日期,6-图片,7-文件
|
||||
options: string // 选项内容
|
||||
sortOrder: number // 排序序号
|
||||
status: boolean // 状态:0-停用,1-启用
|
||||
remark: string // 备注
|
||||
}
|
||||
|
||||
|
||||
// 查询项目巡检内容分页
|
||||
export const getProjectInspectionDataPage = async (params: any) => {
|
||||
return await request.get({ url: `/crm/project-inspection-data/page`, params })
|
||||
}
|
||||
|
||||
// 查询项目巡检内容详情
|
||||
export const getProjectInspectionData = async (id: number) => {
|
||||
return await request.get({ url: `/crm/project-inspection-data/get?id=` + id })
|
||||
}
|
||||
|
||||
// 新增项目巡检内容
|
||||
export const createProjectInspectionData = async (data: ProjectInspectionDataVO) => {
|
||||
return await request.post({ url: `/crm/project-inspection-data/create`, data })
|
||||
}
|
||||
|
||||
// 修改项目巡检内容
|
||||
export const updateProjectInspectionData = async (data: ProjectInspectionDataVO) => {
|
||||
return await request.put({ url: `/crm/project-inspection-data/update`, data })
|
||||
}
|
||||
|
||||
// 删除项目巡检内容
|
||||
export const deleteProjectInspectionData = async (id: number) => {
|
||||
return await request.delete({ url: `/crm/project-inspection-data/delete?id=` + id })
|
||||
}
|
||||
|
||||
// 导出项目巡检内容 Excel
|
||||
export const exportProjectInspectionData = async (params) => {
|
||||
return await request.download({ url: `/crm/project-inspection-data/export-excel`, params })
|
||||
}
|
||||
// 获取项目巡检内容列表
|
||||
export const getProjectInspectionDataList = async (type: number) => {
|
||||
return await request.get({ url: `/crm/project-inspection-data/list?configType=` + type })
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
// 项目巡检配置 VO
|
||||
export interface ProjectInspectionConfigVO {
|
||||
projectId: number // 项目ID
|
||||
configId: number // 配置ID
|
||||
configName: string // 配置名称
|
||||
frequency: string // 巡检频率
|
||||
managementParty: string // 管理方
|
||||
contactPerson: string // 联系人
|
||||
contactPhone: string // 联系电话
|
||||
responsiblePersonId: string // 负责人
|
||||
status: boolean // 状态:0-停用,1-启用
|
||||
remark: string // 备注
|
||||
}
|
||||
|
||||
// 查询项目巡检配置分页
|
||||
export const getProjectInspectionConfigPage = async (params: any) => {
|
||||
return await request.get({ url: `/crm/project-inspection-config/page`, params })
|
||||
}
|
||||
|
||||
// 查询项目巡检配置详情
|
||||
export const getProjectInspectionConfig = async (id: number) => {
|
||||
return await request.get({ url: `/crm/project-inspection-config/get?id=` + id })
|
||||
}
|
||||
|
||||
// 新增项目巡检配置
|
||||
export const createProjectInspectionConfig = async (data: ProjectInspectionConfigVO) => {
|
||||
return await request.post({ url: `/crm/project-inspection-config/create`, data })
|
||||
}
|
||||
|
||||
// 修改项目巡检配置
|
||||
export const updateProjectInspectionConfig = async (data: ProjectInspectionConfigVO) => {
|
||||
return await request.put({ url: `/crm/project-inspection-config/update`, data })
|
||||
}
|
||||
|
||||
// 删除项目巡检配置
|
||||
export const deleteProjectInspectionConfig = async (id: number) => {
|
||||
return await request.delete({ url: `/crm/project-inspection-config/delete?id=` + id })
|
||||
}
|
||||
|
||||
// 导出项目巡检配置 Excel
|
||||
export const exportProjectInspectionConfig = async (params: any) => {
|
||||
return await request.download({ url: `/crm/project-inspection-config/export-excel`, params })
|
||||
}
|
||||
|
|
@ -229,6 +229,8 @@ export enum DICT_TYPE {
|
|||
CRM_FINANCE_INVOICE_AUXILIARY_TYPE = 'crm_finance_invoice_auxiliary_type', // CRM 票据辅助类型
|
||||
CRM_FINANCE_INVOICE_WRITE_OFF_STATUS = 'crm_finance_invoice_write_off_status', // CRM 票据核销状态
|
||||
CRM_PROJECT_SETTLEMENT_STATUS = 'crm_project_settlement_status', // CRM 项目结算状态
|
||||
CRM_PROJECT_INSPECTION_CHECKPOINT = 'crm_project_inspection_checkpoint', // CRM 项目巡检配置
|
||||
CRM_PROJECT_INSPECTION_DATA_TYPE = 'crm_project_inspection_data_type', // CRM 项目巡检内容类型
|
||||
|
||||
|
||||
// ========== ERP - 企业资源计划模块 ==========
|
||||
|
|
|
|||
|
|
@ -0,0 +1,333 @@
|
|||
<template>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
<el-tabs v-model="activeTab" type="border-card">
|
||||
<el-tab-pane v-for="tab in tabs" :key="tab.key" :label="tab.label" :name="tab.key">
|
||||
<div class="tab-content">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="启用" :prop="`${tab.key}.enabled`">
|
||||
<el-switch
|
||||
v-model="formData[tab.key].enabled"
|
||||
active-text="启用"
|
||||
inactive-text="禁用"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="管理方" :prop="`${tab.key}.management`">
|
||||
<el-input
|
||||
v-model="formData[tab.key].management"
|
||||
placeholder="请输入管理方"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系人" :prop="`${tab.key}.contact`">
|
||||
<el-input
|
||||
v-model="formData[tab.key].contact"
|
||||
placeholder="请输入联系人"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系电话" :prop="`${tab.key}.phone`">
|
||||
<el-input
|
||||
v-model="formData[tab.key].phone"
|
||||
placeholder="请输入联系电话"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="责任人" :prop="`${tab.key}.responsiblePersonId`">
|
||||
<el-select
|
||||
v-model="formData[tab.key].responsiblePersonId"
|
||||
placeholder="请选择责任人"
|
||||
clearable
|
||||
filterable
|
||||
class="!w-full"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in userList"
|
||||
:key="item.id"
|
||||
:label="item.nickname"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="巡检周期" :prop="`${tab.key}.cycle`">
|
||||
<Crontab
|
||||
v-model="formData[tab.key].cycle"
|
||||
placeholder="请输入或选择Cron表达式"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注" :prop="`${tab.key}.remark`">
|
||||
<el-input
|
||||
v-model="formData[tab.key].remark"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
resize="both"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Crontab } from '@/components/Crontab'
|
||||
import * as UserApi from '@/api/system/user'
|
||||
import * as ProjectInspectionConfigApi from '@/api/crm/project/inspection'
|
||||
import * as ProjectInspectionCheckpointApi from '@/api/crm/project/inspection/checkpoint'
|
||||
|
||||
defineProps<{
|
||||
disabled?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
submit: [data: any]
|
||||
}>()
|
||||
|
||||
const formLoading = ref(false)
|
||||
const activeTab = ref('')
|
||||
const formRef = ref()
|
||||
const userList = ref<UserApi.UserVO[]>([]) // 用户列表
|
||||
|
||||
// 动态显示的 tabs(根据查询结果)
|
||||
const tabs = ref<Array<{ key: string; label: string; id: number }>>([])
|
||||
|
||||
// 初始化表单数据
|
||||
const formData = ref<Record<string, any>>({})
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = ref({})
|
||||
|
||||
// 加载检查点列表并生成标签页
|
||||
const loadCheckpointList = async () => {
|
||||
try {
|
||||
const response = await ProjectInspectionCheckpointApi.getProjectInspectionCheckpointSimpleList()
|
||||
const checkpointList = response.data || []
|
||||
|
||||
// 根据查询结果生成标签页,按 sort 排序
|
||||
tabs.value = checkpointList
|
||||
.slice() // 创建副本以避免修改原数组
|
||||
.sort((a, b) => (a.sort || 0) - (b.sort || 0)) // 先按 sort 排序
|
||||
.map((item: ProjectInspectionCheckpointApi.ProjectInspectionCheckpointVO) => ({
|
||||
key: String(item.id), // 使用 id 作为 key
|
||||
label: item.configName, // 使用 configName 作为标签名称
|
||||
id: item.id
|
||||
}))
|
||||
|
||||
// 如果有标签页,默认选中第一个
|
||||
if (tabs.value.length > 0) {
|
||||
activeTab.value = tabs.value[0].key
|
||||
}
|
||||
|
||||
// 初始化表单数据
|
||||
initFormData()
|
||||
} catch (error) {
|
||||
console.error('加载检查点列表失败:', error)
|
||||
ElMessage.error('加载检查点列表失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化数据 - 在组件创建时立即初始化
|
||||
const initFormData = () => {
|
||||
tabs.value.forEach(tab => {
|
||||
formData.value[tab.key] = {
|
||||
enabled: false,
|
||||
management: '', // 管理方
|
||||
contact: '', // 联系人
|
||||
phone: '', // 联系电话
|
||||
responsiblePersonId: undefined, // 责任人ID
|
||||
cycle: '0 0 0 * * ?', // 默认cron表达式:每天零点
|
||||
remark: '' // 备注
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
const resetForm = () => {
|
||||
formRef.value?.resetFields()
|
||||
initFormData()
|
||||
}
|
||||
|
||||
/** 打开表单并加载数据 */
|
||||
const open = async (projectId?: number) => {
|
||||
resetForm()
|
||||
formLoading.value = true
|
||||
try {
|
||||
// 先加载检查点列表,生成标签页
|
||||
await loadCheckpointList()
|
||||
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载配置数据失败:', error)
|
||||
ElMessage.error('加载配置数据失败')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const submitForm = async () => {
|
||||
try {
|
||||
// 验证表单
|
||||
const valid = await formRef.value?.validate()
|
||||
if (!valid) {
|
||||
return
|
||||
}
|
||||
|
||||
// 只提交启用状态的配置
|
||||
const submitData: any = {}
|
||||
tabs.value.forEach(tab => {
|
||||
if (formData.value[tab.key]?.enabled) {
|
||||
submitData[tab.key] = {
|
||||
enabled: formData.value[tab.key].enabled,
|
||||
management: formData.value[tab.key].management,
|
||||
contact: formData.value[tab.key].contact,
|
||||
phone: formData.value[tab.key].phone,
|
||||
responsiblePersonId: formData.value[tab.key].responsiblePersonId,
|
||||
cycle: formData.value[tab.key].cycle,
|
||||
remark: formData.value[tab.key].remark
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
formLoading.value = true
|
||||
emit('submit', submitData)
|
||||
ElMessage.success('提交成功')
|
||||
} catch (error) {
|
||||
console.error('表单验证失败:', error)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 初始化,加载用户列表和检查点列表 */
|
||||
onMounted(async () => {
|
||||
userList.value = await UserApi.getSimpleUserList()
|
||||
await loadCheckpointList()
|
||||
})
|
||||
|
||||
// 暴露方法和属性供父组件调用
|
||||
defineExpose({
|
||||
open,
|
||||
submitForm,
|
||||
resetForm,
|
||||
formData,
|
||||
formRules,
|
||||
formRef
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.tab-content {
|
||||
padding: 20px;
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
// 优化选项卡标签样式
|
||||
:deep(.el-tabs__header) {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__item) {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
padding: 12px 20px;
|
||||
color: #606266;
|
||||
border-radius: 6px 6px 0 0;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
color: #409eff;
|
||||
font-weight: 600;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-tabs__item.is-active::before) {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background-color: #409eff;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__nav-wrap::after) {
|
||||
background-color: #e4e7ed;
|
||||
}
|
||||
|
||||
:deep(.el-tabs--border-card > .el-tabs__header .el-tabs__item) {
|
||||
&.is-active {
|
||||
color: #409eff;
|
||||
background-color: #fff;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-bottom: 2px solid #409eff;
|
||||
}
|
||||
|
||||
&:not(.is-active) {
|
||||
border: 1px solid transparent;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
background-color: #f5f7fa;
|
||||
|
||||
&:hover {
|
||||
background-color: #ecf5ff;
|
||||
border-color: #b3d8ff;
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-tabs__content) {
|
||||
min-height: 300px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
:deep(.el-tabs--border-card) {
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
@ -100,8 +100,16 @@
|
|||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.projectStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" fixed="right" align="center" min-width="120px">
|
||||
<el-table-column label="操作" fixed="right" align="center" min-width="180px">
|
||||
<template #default="scope">
|
||||
<!-- <el-button
|
||||
link
|
||||
type="warning"
|
||||
@click="openConfigDialog(scope.row.id)"
|
||||
v-hasPermi="['crm:project:update']"
|
||||
>
|
||||
配置
|
||||
</el-button> -->
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
|
|
@ -132,6 +140,21 @@
|
|||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<ProjectForm ref="formRef" @success="getList" />
|
||||
|
||||
<!-- 配置表单弹窗 -->
|
||||
<!-- <Dialog
|
||||
v-model="configDialogVisible"
|
||||
title="巡检配置"
|
||||
width="40%"
|
||||
>
|
||||
<ProjectInspectConfigForm ref="configFormRef" />
|
||||
<template #footer>
|
||||
<el-button type="primary" @click="handleConfigSubmit" :loading="configSubmitting">
|
||||
提交
|
||||
</el-button>
|
||||
<el-button @click="configDialogVisible = false">取消</el-button>
|
||||
</template>
|
||||
</Dialog> -->
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
|
@ -140,6 +163,7 @@ import download from '@/utils/download'
|
|||
import * as ProjectApi from '@/api/crm/project'
|
||||
import * as DeptApi from '@/api/system/dept'
|
||||
import ProjectForm from './ProjectForm.vue'
|
||||
import ProjectInspectConfigForm from './component/ProjectInspectConfigForm.vue'
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
|
||||
/** CRM 项目信息 列表 */
|
||||
|
|
@ -166,6 +190,12 @@ const queryFormRef = ref() // 搜索的表单
|
|||
const exportLoading = ref(false) // 导出的加载中
|
||||
const deptList = ref<DeptApi.DeptVO[]>([])
|
||||
|
||||
// // 配置表单相关
|
||||
// const configDialogVisible = ref(false) // 配置弹窗是否显示
|
||||
// const configFormRef = ref() // 配置表单引用
|
||||
// const currentProjectId = ref<number>() // 当前操作的项目ID
|
||||
// const configSubmitting = ref(false) // 配置提交中
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
|
|
@ -245,6 +275,62 @@ const calculateCostPerPile = (row) => {
|
|||
return parseFloat(cost); // 转为数字类型避免显示多余的0
|
||||
};
|
||||
|
||||
// /** 打开配置弹窗 */
|
||||
// const openConfigDialog = async (projectId: number) => {
|
||||
// currentProjectId.value = projectId
|
||||
// configDialogVisible.value = true
|
||||
// // 加载配置数据
|
||||
// await nextTick()
|
||||
// configFormRef.value?.open(projectId)
|
||||
// }
|
||||
|
||||
// /** 处理配置提交 */
|
||||
// const handleConfigSubmit = async () => {
|
||||
// try {
|
||||
// // 从配置表单获取数据
|
||||
// const formData = configFormRef.value?.formData || {}
|
||||
|
||||
// // 验证启用的配置项
|
||||
// const enabledKeys = Object.keys(formData).filter(key => formData[key]?.enabled)
|
||||
|
||||
// for (const key of enabledKeys) {
|
||||
// if (!formData[key]?.responsiblePersonId) {
|
||||
// message.error(`${key}的责任人不能为空`)
|
||||
// return
|
||||
// }
|
||||
// if (!formData[key]?.cycle) {
|
||||
// message.error(`${key}的巡检周期不能为空`)
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 构建提交数据
|
||||
// const submitData: any = {}
|
||||
// enabledKeys.forEach(key => {
|
||||
// submitData[key] = {
|
||||
// enabled: formData[key].enabled,
|
||||
// management: formData[key].management,
|
||||
// contact: formData[key].contact,
|
||||
// phone: formData[key].phone,
|
||||
// responsiblePersonId: formData[key].responsiblePersonId,
|
||||
// cycle: formData[key].cycle,
|
||||
// remark: formData[key].remark
|
||||
// }
|
||||
// })
|
||||
|
||||
// configSubmitting.value = true
|
||||
// // TODO: 这里可以调用API保存配置数据
|
||||
// // await ProjectApi.saveInspectConfig(currentProjectId.value, submitData)
|
||||
// message.success('配置保存成功')
|
||||
// configDialogVisible.value = false
|
||||
// } catch (error) {
|
||||
// console.error('配置保存失败:', error)
|
||||
// message.error('配置保存失败')
|
||||
// } finally {
|
||||
// configSubmitting.value = false
|
||||
// }
|
||||
// }
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(async () => {
|
||||
await getList()
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
class="!w-240px"
|
||||
placeholder="请选择客户"
|
||||
@keyup.enter="handleQuery"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in customerList"
|
||||
|
|
|
|||
Loading…
Reference in New Issue