|
|
@@ -70,6 +70,37 @@
|
|
|
:placeholder="t('faultForm.rHolder')" />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="附件">
|
|
|
+ <FileUpload
|
|
|
+ :device-id="undefined"
|
|
|
+ :show-folder-button="false"
|
|
|
+ @upload-success="handleUploadSuccess" />
|
|
|
+
|
|
|
+ <div
|
|
|
+ v-if="formData.attachments && formData.attachments.length > 0"
|
|
|
+ class="attachment-container">
|
|
|
+ <div class="attachment-list">
|
|
|
+ <div
|
|
|
+ v-for="(attachment, index) in formData.attachments"
|
|
|
+ :key="attachment.id || index"
|
|
|
+ class="attachment-item">
|
|
|
+ <a class="attachment-name" @click="inContent(attachment)">
|
|
|
+ {{ attachment.filename }}
|
|
|
+ </a>
|
|
|
+ <el-button type="danger" link size="small" @click="removeAttachment(index)">
|
|
|
+ 删除
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-else-if="!formData.attachments || formData.attachments.length === 0"
|
|
|
+ class="no-attachment">
|
|
|
+ 无附件
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
</el-row>
|
|
|
</div>
|
|
|
</el-form>
|
|
|
@@ -382,6 +413,8 @@ import MaterialListDrawer from '@/views/pms/iotmainworkorder/SelectedMaterialDra
|
|
|
import WorkOrderMaterial from '@/views/pms/iotmainworkorder/WorkOrderMaterial.vue'
|
|
|
import { IotDevicePersonApi } from '@/api/pms/iotdeviceperson'
|
|
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
|
|
+import FileUpload from '@/components/UploadFile/src/FileUpload.vue'
|
|
|
+import { Base64 } from 'js-base64'
|
|
|
|
|
|
/** 保养计划 表单 */
|
|
|
defineOptions({ name: 'IotMainWorkOrderAdd' })
|
|
|
@@ -421,9 +454,104 @@ const formData = ref({
|
|
|
outsourcingFlag: 0,
|
|
|
remark: undefined,
|
|
|
status: undefined,
|
|
|
- devicePersons: ''
|
|
|
+ devicePersons: '',
|
|
|
+ attachments: [] as any[]
|
|
|
})
|
|
|
|
|
|
+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'
|
|
|
+ }
|
|
|
+ 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]
|
|
|
+}
|
|
|
+
|
|
|
+const handleUploadSuccess = (result: any) => {
|
|
|
+ try {
|
|
|
+ if (!result.response) {
|
|
|
+ message.error('上传响应数据异常')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (result.response.code !== 0) {
|
|
|
+ message.error(result.response.msg || '文件上传失败')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const responseData = result.response.data
|
|
|
+
|
|
|
+ if (!responseData) {
|
|
|
+ message.error('上传数据为空')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (responseData.files && Array.isArray(responseData.files) && responseData.files.length > 0) {
|
|
|
+ responseData.files.forEach((file: any) => {
|
|
|
+ if (!file.filePath) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const attachment = {
|
|
|
+ id: undefined,
|
|
|
+ category: 'main_work_order',
|
|
|
+ bizId: formData.value.id,
|
|
|
+ type: 'attachment',
|
|
|
+ filename: file.name || '未知文件',
|
|
|
+ fileType: getFileType(file.name),
|
|
|
+ filePath: file.filePath,
|
|
|
+ fileSize: formatFileSize(file.size || 0),
|
|
|
+ remark: ''
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!formData.value.attachments) {
|
|
|
+ formData.value.attachments = []
|
|
|
+ }
|
|
|
+ formData.value.attachments.push(attachment)
|
|
|
+ })
|
|
|
+
|
|
|
+ message.success(`成功上传 ${responseData.files.length} 个文件`)
|
|
|
+ } else {
|
|
|
+ message.warning('上传成功但未获取到文件信息')
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ message.error('处理上传结果失败')
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const removeAttachment = (index: number) => {
|
|
|
+ if (formData.value.attachments && formData.value.attachments.length > index) {
|
|
|
+ formData.value.attachments.splice(index, 1)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const inContent = async (attachment: any) => {
|
|
|
+ if (!attachment || !attachment.filePath) {
|
|
|
+ message.error('附件路径不存在')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ const encodedPath = encodeURIComponent(Base64.encode(attachment.filePath))
|
|
|
+ window.open(`http://doc.deepoil.cc:8012/onlinePreview?url=${encodedPath}`)
|
|
|
+ } catch (error) {
|
|
|
+ message.error('预览附件失败')
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/** 获取当前所有设备ID集合 */
|
|
|
const getCurrentDeviceIds = (): number[] => {
|
|
|
return [...new Set(list.value.map((item) => item.deviceId))]
|
|
|
@@ -1003,7 +1131,8 @@ const resetForm = () => {
|
|
|
deviceName: undefined,
|
|
|
processInstanceId: undefined,
|
|
|
auditStatus: undefined,
|
|
|
- deptId: undefined
|
|
|
+ deptId: undefined,
|
|
|
+ attachments: []
|
|
|
}
|
|
|
formRef.value?.resetFields()
|
|
|
}
|
|
|
@@ -1087,4 +1216,44 @@ const handleDelete = async (str: string) => {
|
|
|
color: #606266;
|
|
|
background: white;
|
|
|
}
|
|
|
+
|
|
|
+.attachment-container {
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.attachment-list {
|
|
|
+ width: 100%;
|
|
|
+ padding: 10px;
|
|
|
+ margin-top: 5px;
|
|
|
+ background-color: #fafafa;
|
|
|
+ border: 1px solid #e0e0e0;
|
|
|
+ border-radius: 4px;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.attachment-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 8px 12px;
|
|
|
+ border-bottom: 1px solid #f0f0f0;
|
|
|
+}
|
|
|
+
|
|
|
+.attachment-item:last-child {
|
|
|
+ border-bottom: none;
|
|
|
+}
|
|
|
+
|
|
|
+.attachment-name {
|
|
|
+ flex: 1;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #606266;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
+.no-attachment {
|
|
|
+ padding: 10px;
|
|
|
+ margin-top: 5px;
|
|
|
+ font-style: italic;
|
|
|
+ color: #909399;
|
|
|
+}
|
|
|
</style>
|