|
|
@@ -465,6 +465,62 @@
|
|
|
</el-form>
|
|
|
</ContentWrap>
|
|
|
|
|
|
+ <div
|
|
|
+ v-if="companyName === 'ry'"
|
|
|
+ class="my-6 bg-white p-4 border-1 border-solid border-[var(--el-border-color-light)]"
|
|
|
+ >
|
|
|
+ <h3 style="margin-bottom: 20px">附件</h3>
|
|
|
+ <el-form-item size="default" label="工程设计">
|
|
|
+ <el-upload
|
|
|
+ v-model:file-list="constructionFiles"
|
|
|
+ :action="uploadUrl"
|
|
|
+ multiple
|
|
|
+ :headers="{ 'tenant-id': 1, 'device-id': 'undefined' }"
|
|
|
+ name="files"
|
|
|
+ class="w-50%"
|
|
|
+ >
|
|
|
+ <el-button type="primary">上传工程设计</el-button>
|
|
|
+ <template #tip>
|
|
|
+ <div class="el-upload__tip">文件大小不能超过50MB </div>
|
|
|
+ </template>
|
|
|
+ </el-upload>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item size="default" label="地质设计">
|
|
|
+ <el-upload
|
|
|
+ v-model:file-list="geologicalFiles"
|
|
|
+ :action="uploadUrl"
|
|
|
+ multiple
|
|
|
+ :headers="{ 'tenant-id': 1, 'device-id': 'undefined' }"
|
|
|
+ name="files"
|
|
|
+ class="w-50%"
|
|
|
+ >
|
|
|
+ <el-button type="primary">上传地质设计</el-button>
|
|
|
+ <template #tip>
|
|
|
+ <div class="el-upload__tip">文件大小不能超过50MB </div>
|
|
|
+ </template>
|
|
|
+ </el-upload>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item size="default" label="完井报告">
|
|
|
+ <el-upload
|
|
|
+ v-model:file-list="completionFiles"
|
|
|
+ :action="uploadUrl"
|
|
|
+ multiple
|
|
|
+ :headers="{ 'tenant-id': 1, 'device-id': 'undefined' }"
|
|
|
+ name="files"
|
|
|
+ class="w-50%"
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ :disabled="!(tableData[0].rigStatus === 'wg' && tableData[0].repairStatus === 'wg')"
|
|
|
+ type="primary"
|
|
|
+ >上传完井报告</el-button
|
|
|
+ >
|
|
|
+ <template #tip>
|
|
|
+ <div class="el-upload__tip">文件大小不能超过50MB </div>
|
|
|
+ </template>
|
|
|
+ </el-upload>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+
|
|
|
<ContentWrap v-if="currentTask.platformWell === '1'">
|
|
|
<h3 style="margin-bottom: 20px">平台井</h3>
|
|
|
<el-table :data="currentTask.platformWellDetails" style="width: 100%">
|
|
|
@@ -764,19 +820,25 @@ import { IotDeviceApi, IotDeviceVO } from '@/api/pms/device'
|
|
|
import * as UserApi from '@/api/system/user'
|
|
|
import { IotProjectTaskAttrsApi } from '@/api/pms/iotprojecttaskattrs'
|
|
|
import { DICT_TYPE, getStrDictOptions, getDictLabel } from '@/utils/dict'
|
|
|
+import { IotOpeationFillApi } from '@/api/pms/iotopeationfill'
|
|
|
// 在导入部分添加Plus图标
|
|
|
// import { Plus } from '@element-plus/icons-vue'
|
|
|
|
|
|
const { query, params, name } = useRoute() // 查询参数
|
|
|
const id = params.id
|
|
|
|
|
|
+const uploadUrl = import.meta.env.VITE_BASE_URL + '/admin-api/rq/file/upload'
|
|
|
+const constructionFiles = ref<any>([])
|
|
|
+const geologicalFiles = ref<any>([])
|
|
|
+const completionFiles = ref<any>([])
|
|
|
+
|
|
|
// 修改projectId获取逻辑:优先使用params.projectId,其次使用query.projectId
|
|
|
const projectId = ref<string>('')
|
|
|
// 获取projectId的逻辑
|
|
|
if (params.projectId) {
|
|
|
projectId.value = Array.isArray(params.projectId) ? params.projectId[0] : params.projectId
|
|
|
} else if (query.projectId) {
|
|
|
- projectId.value = Array.isArray(query.projectId)
|
|
|
+ projectId.value = Array.isArray(query.projectId as any)
|
|
|
? query.projectId[0]
|
|
|
: (query.projectId as string)
|
|
|
}
|
|
|
@@ -818,7 +880,7 @@ const submitterList = ref([]) // 所有填报人列表
|
|
|
const selectedSubmitterIds = ref([]) // 选中的日报填报人ID
|
|
|
|
|
|
// 动态属性相关变量
|
|
|
-const dynamicAttrs = ref([]) // 存储动态属性列表
|
|
|
+const dynamicAttrs = ref<any[]>([]) // 存储动态属性列表
|
|
|
|
|
|
// 跟踪是否已从任务数据中获取动态属性
|
|
|
const hasDynamicAttrsFromTask = ref(false)
|
|
|
@@ -1805,6 +1867,8 @@ const getAllDeviceNames = (deviceIds: number[]) => {
|
|
|
return deviceNames.join(', ') || '无有效设备'
|
|
|
}
|
|
|
|
|
|
+const companyName = ref('')
|
|
|
+
|
|
|
/** 打开弹窗 */
|
|
|
const open = async () => {
|
|
|
resetForm()
|
|
|
@@ -1820,6 +1884,9 @@ const open = async () => {
|
|
|
const data = await IotProjectTaskApi.getIotProjectTaskPage(queryParams)
|
|
|
tableData.value = data.list
|
|
|
|
|
|
+ const company = await IotOpeationFillApi.getOrgName(tableData.value[0].deptId)
|
|
|
+ companyName.value = company
|
|
|
+
|
|
|
// 收集所有设备ID
|
|
|
const allDeviceIds = new Set<number>()
|
|
|
// 收集所有责任人ID
|
|
|
@@ -1968,6 +2035,36 @@ const open = async () => {
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
+
|
|
|
+ const attachments = tableData.value[0].attachments || []
|
|
|
+
|
|
|
+ constructionFiles.value = attachments
|
|
|
+ .filter((item) => item.type === 'CONSTRUCTION_DESIGN')
|
|
|
+ .map((item) => ({
|
|
|
+ name: item.filename,
|
|
|
+ percentage: 100,
|
|
|
+ response: { data: item },
|
|
|
+ status: 'success',
|
|
|
+ uid: item.createTime
|
|
|
+ }))
|
|
|
+ geologicalFiles.value = attachments
|
|
|
+ .filter((item) => item.type === 'GEOLIGICAL_DESIGN')
|
|
|
+ .map((item) => ({
|
|
|
+ name: item.filename,
|
|
|
+ percentage: 100,
|
|
|
+ response: { data: item },
|
|
|
+ status: 'success',
|
|
|
+ uid: item.createTime
|
|
|
+ }))
|
|
|
+ completionFiles.value = attachments
|
|
|
+ .filter((item) => item.type === 'COMPLETION_DESIGN')
|
|
|
+ .map((item) => ({
|
|
|
+ name: item.filename,
|
|
|
+ percentage: 100,
|
|
|
+ response: { data: item },
|
|
|
+ status: 'success',
|
|
|
+ uid: item.createTime
|
|
|
+ }))
|
|
|
}
|
|
|
} finally {
|
|
|
formLoading.value = false
|
|
|
@@ -2324,6 +2421,46 @@ const submitForm = async () => {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+ const getFileType = (filename: string) => {
|
|
|
+ const ext = filename.split('.').pop()?.toLowerCase()
|
|
|
+ if (['jpg', 'jpeg', 'png', 'gif', 'bmp'].includes(ext || '')) {
|
|
|
+ return 'image'
|
|
|
+ } else if (['pdf'].includes(ext || '')) {
|
|
|
+ return 'pdf'
|
|
|
+ } else if (['doc', 'docx'].includes(ext || '')) {
|
|
|
+ return 'word'
|
|
|
+ } else if (['xls', 'xlsx'].includes(ext || '')) {
|
|
|
+ return 'excel'
|
|
|
+ } else {
|
|
|
+ return 'other'
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const formatFileSize = (bytes: number) => {
|
|
|
+ if (bytes === 0) return '0 Bytes'
|
|
|
+ const k = 1024
|
|
|
+ const sizes = ['Bytes', 'KB', 'MB', 'GB']
|
|
|
+ const i = Math.floor(Math.log(bytes) / Math.log(k))
|
|
|
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
|
|
|
+ }
|
|
|
+
|
|
|
+ function formatterAttachments(attachments: any[], type: string, taskId: number) {
|
|
|
+ return attachments.flatMap((item) => {
|
|
|
+ if (item.response.data.files) {
|
|
|
+ return item.response.data.files.map((file) => ({
|
|
|
+ category: 'DAILY_REPORT',
|
|
|
+ bizId: taskId,
|
|
|
+ filename: file.name || '未知文件',
|
|
|
+ fileType: getFileType(file.name),
|
|
|
+ filePath: file.filePath,
|
|
|
+ fileSize: formatFileSize(file.size || 0),
|
|
|
+ remark: '',
|
|
|
+ type
|
|
|
+ }))
|
|
|
+ } else return item.response.data
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
// 处理动态属性数据
|
|
|
const processedTableData = tableData.value.map((task) => {
|
|
|
// 获取当前任务的工作量数据并转换为dropdownList格式
|
|
|
@@ -2352,7 +2489,10 @@ const submitForm = async () => {
|
|
|
return {
|
|
|
...task,
|
|
|
dictType: task.dictType || currentDictLabel.value, // 确保每个任务都有dictType
|
|
|
- extProperty: extProperties
|
|
|
+ extProperty: extProperties,
|
|
|
+ attachments: formatterAttachments(constructionFiles.value, 'CONSTRUCTION_DESIGN', task.id)
|
|
|
+ .concat(formatterAttachments(geologicalFiles.value, 'GEOLOGICAL_DESIGN', task.id))
|
|
|
+ .concat(formatterAttachments(completionFiles.value, 'COMPLETION_REPORT', task.id))
|
|
|
}
|
|
|
})
|
|
|
|
|
|
@@ -2366,6 +2506,7 @@ const submitForm = async () => {
|
|
|
const data = {
|
|
|
taskList: processedTableData
|
|
|
}
|
|
|
+
|
|
|
if (formType.value === 'create') {
|
|
|
await IotProjectTaskApi.createIotProjectTask(data)
|
|
|
message.success(t('common.createSuccess'))
|
|
|
@@ -2963,11 +3104,13 @@ onMounted(async () => {
|
|
|
.edit-input {
|
|
|
margin-right: 10px;
|
|
|
}
|
|
|
+
|
|
|
.error-message {
|
|
|
- color: #f56c6c;
|
|
|
- font-size: 12px;
|
|
|
margin-top: 5px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #f56c6c;
|
|
|
}
|
|
|
+
|
|
|
.action-cell {
|
|
|
display: flex;
|
|
|
gap: 8px;
|
|
|
@@ -2975,8 +3118,8 @@ onMounted(async () => {
|
|
|
|
|
|
/* 1. 穿梭框父容器:居中 + 内边距 */
|
|
|
.transfer-container {
|
|
|
+ padding: 0; /* 上下内边距,避免紧贴对话框边缘 */
|
|
|
text-align: center;
|
|
|
- padding: 0px; /* 上下内边距,避免紧贴对话框边缘 */
|
|
|
}
|
|
|
|
|
|
/* 2. 穿梭框组件:控制宽度,避免过窄或过宽 */
|
|
|
@@ -2993,22 +3136,26 @@ onMounted(async () => {
|
|
|
/* 3. 深度选择器:修改el-transfer选项样式(解决内容省略问题) */
|
|
|
:deep(.el-transfer-panel__item) {
|
|
|
/* white-space: nowrap; 文本不换行,保证一行显示 */
|
|
|
+
|
|
|
/* overflow: hidden; 超出部分隐藏 */
|
|
|
+
|
|
|
/* text-overflow: ellipsis; 超出显示省略号 */
|
|
|
+
|
|
|
/* max-width: 100%; 确保文本不超出选项容器宽度 */
|
|
|
+
|
|
|
/* padding: 6px 6px; 适当增加内边距,优化点击体验 */
|
|
|
}
|
|
|
|
|
|
:deep(.el-transfer-panel__item) {
|
|
|
display: flex !important;
|
|
|
- align-items: center !important;
|
|
|
height: 32px !important;
|
|
|
- line-height: 32px !important;
|
|
|
padding: 0 8px !important;
|
|
|
margin: 0 !important;
|
|
|
- white-space: nowrap;
|
|
|
overflow: hidden;
|
|
|
+ line-height: 32px !important;
|
|
|
text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ align-items: center !important;
|
|
|
}
|
|
|
|
|
|
/* 4. 选项文本:确保继承父容器宽度,省略号正常生效 */
|
|
|
@@ -3019,10 +3166,10 @@ onMounted(async () => {
|
|
|
|
|
|
/* 设备名称显示区域样式 */
|
|
|
.device-names {
|
|
|
- white-space: nowrap;
|
|
|
+ max-width: 200px; /* 根据实际列宽调整 */
|
|
|
overflow: hidden;
|
|
|
text-overflow: ellipsis;
|
|
|
- max-width: 200px; /* 根据实际列宽调整 */
|
|
|
+ white-space: nowrap;
|
|
|
}
|
|
|
|
|
|
:deep(.el-transfer-panel__list) {
|
|
|
@@ -3031,35 +3178,35 @@ onMounted(async () => {
|
|
|
|
|
|
/* 责任人名称显示区域样式 */
|
|
|
.responsible-names {
|
|
|
- white-space: nowrap;
|
|
|
+ max-width: 200px; /* 根据实际列宽调整 */
|
|
|
overflow: hidden;
|
|
|
text-overflow: ellipsis;
|
|
|
- max-width: 200px; /* 根据实际列宽调整 */
|
|
|
+ white-space: nowrap;
|
|
|
}
|
|
|
|
|
|
/* 添加部门名称的样式 */
|
|
|
.dept-names {
|
|
|
- white-space: nowrap;
|
|
|
+ display: inline-block;
|
|
|
+ max-width: 200px; /* 根据实际列宽调整 */
|
|
|
overflow: hidden;
|
|
|
text-overflow: ellipsis;
|
|
|
- max-width: 200px; /* 根据实际列宽调整 */
|
|
|
- display: inline-block;
|
|
|
+ white-space: nowrap;
|
|
|
vertical-align: bottom;
|
|
|
}
|
|
|
|
|
|
/* 部门选择器样式优化 */
|
|
|
:deep(.department-tree-select .el-select__tags) {
|
|
|
- white-space: nowrap;
|
|
|
overflow: hidden;
|
|
|
text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
flex-wrap: nowrap;
|
|
|
}
|
|
|
|
|
|
:deep(.department-tree-select .el-select__tags .el-tag) {
|
|
|
+ display: inline-block;
|
|
|
max-width: 120px;
|
|
|
overflow: hidden;
|
|
|
text-overflow: ellipsis;
|
|
|
- display: inline-block;
|
|
|
}
|
|
|
|
|
|
:deep(.department-tree-select .el-select__tags .el-tag + .el-tag) {
|
|
|
@@ -3075,29 +3222,29 @@ onMounted(async () => {
|
|
|
|
|
|
/* 当有多个标签被折叠时显示的 "+N" 标签样式 */
|
|
|
:deep(.department-tree-select .el-select__collapse-tags) {
|
|
|
- white-space: nowrap;
|
|
|
display: inline-block;
|
|
|
+ white-space: nowrap;
|
|
|
}
|
|
|
|
|
|
.task-edit-form {
|
|
|
- margin-bottom: 20px;
|
|
|
padding: 20px;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ background-color: #fafafa;
|
|
|
border: 1px solid #ebeef5;
|
|
|
border-radius: 4px;
|
|
|
- background-color: #fafafa;
|
|
|
}
|
|
|
|
|
|
/* 按钮文字样式 - 红色字体 */
|
|
|
:deep(.workload-add-btn .btn-text) {
|
|
|
- color: #ff0000 !important;
|
|
|
- font-weight: 900; /* 更粗的字体 */
|
|
|
font-size: 18px; /* 更大的字号 */
|
|
|
+ font-weight: 900; /* 更粗的字体 */
|
|
|
line-height: 1;
|
|
|
+ color: #f00 !important;
|
|
|
}
|
|
|
|
|
|
/* 设计工作量加号按钮 - 启用状态(深蓝色) */
|
|
|
:deep(.workload-add-btn .el-icon) {
|
|
|
- color: #ff0000 !important; /* Element Plus 主色调深蓝色,可替换为 #003366 等自定义深蓝色 */
|
|
|
+ color: #f00 !important; /* Element Plus 主色调深蓝色,可替换为 #003366 等自定义深蓝色 */
|
|
|
}
|
|
|
|
|
|
/* 按钮禁用状态 */
|
|
|
@@ -3108,53 +3255,53 @@ onMounted(async () => {
|
|
|
/* 调整按钮整体样式,确保icon居中 */
|
|
|
:deep(.workload-add-btn) {
|
|
|
display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- padding: 0 8px;
|
|
|
- min-width: auto;
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
+ min-width: auto;
|
|
|
+ padding: 0 8px;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
}
|
|
|
|
|
|
/* 调整输入框append部分的宽度 */
|
|
|
:deep(.workload-input-with-button .el-input-group__append) {
|
|
|
- padding: 0;
|
|
|
width: 45px; /* 稍微增加宽度以容纳文字 */
|
|
|
+ padding: 0;
|
|
|
}
|
|
|
|
|
|
/* 确保按钮在禁用状态下有正确的样式 */
|
|
|
:deep(.workload-add-btn:disabled) {
|
|
|
+ cursor: not-allowed;
|
|
|
background-color: #f5f7fa;
|
|
|
border-color: #e4e7ed;
|
|
|
- cursor: not-allowed;
|
|
|
}
|
|
|
|
|
|
/* 设计工作量错误输入框样式 */
|
|
|
:deep(.error-input .el-input__inner) {
|
|
|
- border-color: #f56c6c !important;
|
|
|
background-color: #fef0f0 !important;
|
|
|
- box-shadow: 0 0 0 1px rgba(245, 108, 108, 0.4) !important;
|
|
|
+ border-color: #f56c6c !important;
|
|
|
+ box-shadow: 0 0 0 1px rgb(245 108 108 / 40%) !important;
|
|
|
}
|
|
|
|
|
|
:deep(.error-input .el-input__inner:hover) {
|
|
|
- border-color: #f56c6c !important;
|
|
|
background-color: #fef0f0 !important;
|
|
|
+ border-color: #f56c6c !important;
|
|
|
}
|
|
|
|
|
|
:deep(.error-input .el-input__inner:focus) {
|
|
|
- border-color: #f56c6c !important;
|
|
|
background-color: #fef0f0 !important;
|
|
|
- box-shadow: 0 0 0 1px rgba(245, 108, 108, 0.2) !important;
|
|
|
+ border-color: #f56c6c !important;
|
|
|
+ box-shadow: 0 0 0 1px rgb(245 108 108 / 20%) !important;
|
|
|
}
|
|
|
|
|
|
/* 设计工作量tooltip样式 */
|
|
|
:deep(.workload-design-tooltip) {
|
|
|
- background: #fef0f0 !important;
|
|
|
- border: 1px solid #fbc4c4 !important;
|
|
|
- color: #f56c6c !important;
|
|
|
max-width: 300px;
|
|
|
- font-size: 12px;
|
|
|
padding: 8px 12px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #f56c6c !important;
|
|
|
+ background: #fef0f0 !important;
|
|
|
+ border: 1px solid #fbc4c4 !important;
|
|
|
}
|
|
|
|
|
|
/* 隐藏 Tooltip 箭头 */
|