|
|
@@ -24,9 +24,18 @@
|
|
|
</el-col>
|
|
|
<el-col :span="6">
|
|
|
<el-form-item label="维修类型" prop="categoryId">
|
|
|
- <el-select v-model="queryParams.categoryId" placeholder="请选择维修类型" clearable style="width: 100%">
|
|
|
- <el-option v-for="category in categoryOptions" :key="category.value" :label="category.label" :value="category.value" />
|
|
|
- </el-select>
|
|
|
+ <el-tree-select
|
|
|
+ v-model="queryParams.categoryId"
|
|
|
+ :data="categoryTreeOptions"
|
|
|
+ :props="{ value: 'id', label: 'categoryName', children: 'children' }"
|
|
|
+ value-key="id"
|
|
|
+ placeholder="请选择维修类型"
|
|
|
+ check-strictly
|
|
|
+ :render-after-expand="false"
|
|
|
+ clearable
|
|
|
+ filterable
|
|
|
+ style="width: 100%"
|
|
|
+ />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
@@ -83,7 +92,7 @@
|
|
|
</transition>
|
|
|
|
|
|
<!-- 统计卡片区域 - 仅维护管理员和超级管理员可见 -->
|
|
|
- <div v-if="canViewStatistics" class="mb-[10px]">
|
|
|
+ <!-- <div v-if="canViewStatistics" class="mb-[10px]">
|
|
|
<el-row :gutter="16">
|
|
|
<el-col :span="3">
|
|
|
<el-card shadow="hover" class="stat-card stat-card-primary">
|
|
|
@@ -190,7 +199,7 @@
|
|
|
</el-card>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
- </div>
|
|
|
+ </div> -->
|
|
|
|
|
|
<!-- 表格区域 -->
|
|
|
<el-card shadow="never" class="button-card table-card">
|
|
|
@@ -200,15 +209,13 @@
|
|
|
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['pm:repairOrder:add']">新增报修</el-button>
|
|
|
</el-col>
|
|
|
<el-col :span="1.5">
|
|
|
- <el-button icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['pm:repairOrder:edit']">修改</el-button>
|
|
|
+ <el-button icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['pm:repairOrder:edit']">修改</el-button>
|
|
|
</el-col>
|
|
|
<el-col :span="1.5">
|
|
|
- <el-button icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['pm:repairOrder:remove']"
|
|
|
- >删除</el-button
|
|
|
- >
|
|
|
+ <el-button icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['pm:repairOrder:remove']">删除</el-button>
|
|
|
</el-col>
|
|
|
<el-col :span="1.5">
|
|
|
- <el-button icon="Download" @click="handleExport" v-hasPermi="['pm:repairOrder:export']">导出</el-button>
|
|
|
+ <el-button icon="Download" @click="handleExport" v-hasPermi="['pm:repairOrder:export']">导出</el-button>
|
|
|
</el-col>
|
|
|
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
|
|
</el-row>
|
|
|
@@ -268,7 +275,7 @@
|
|
|
<span v-else>-</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="评价得分" align="center" prop="evaluationScore" width="100">
|
|
|
+ <el-table-column label="评价得分" align="center" prop="evaluationScore" width="200">
|
|
|
<template #default="scope">
|
|
|
<el-rate
|
|
|
v-if="scope.row.evaluationScore"
|
|
|
@@ -336,7 +343,7 @@
|
|
|
<el-button
|
|
|
link
|
|
|
type="warning"
|
|
|
- icon="Edit"
|
|
|
+ icon="collection"
|
|
|
@click="handleUpdateProgress(scope.row)"
|
|
|
v-hasPermi="['pm:repairOrder:updateProgress']"
|
|
|
></el-button>
|
|
|
@@ -361,7 +368,7 @@
|
|
|
<el-button
|
|
|
link
|
|
|
type="warning"
|
|
|
- icon="Edit"
|
|
|
+ icon="collection"
|
|
|
@click="handleUpdateProgress(scope.row)"
|
|
|
v-hasPermi="['pm:repairOrder:updateProgress']"
|
|
|
></el-button>
|
|
|
@@ -517,6 +524,8 @@
|
|
|
v-model:file-list="attachmentList"
|
|
|
class="upload-demo"
|
|
|
drag
|
|
|
+ list-type="picture-card"
|
|
|
+ :on-preview="handleFilePreview"
|
|
|
:action="uploadAction"
|
|
|
:headers="uploadHeaders"
|
|
|
:data="uploadData"
|
|
|
@@ -527,15 +536,43 @@
|
|
|
:on-remove="handleRemoveAttachment"
|
|
|
:on-change="handleFileChange"
|
|
|
multiple
|
|
|
- :limit="5"
|
|
|
+ :limit="15"
|
|
|
:show-file-list="true"
|
|
|
accept="image/*,video/*,.pdf,.doc,.docx,.txt"
|
|
|
>
|
|
|
- <el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
|
|
- <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
|
|
+ <!-- <el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
|
|
+ <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> -->
|
|
|
<template #tip>
|
|
|
- <div class="el-upload__tip">支持图片、视频、PDF、Word文档等格式,单个文件大小不超过10MB,最多上传5个文件</div>
|
|
|
- <div class="el-upload__tip" v-if="!form.id" style="color: #e6a23c">新增时文件将在保存工单后上传</div>
|
|
|
+ <div class="el-upload__tip">
|
|
|
+ 支持图片、视频、PDF、Word文档等格式,单个文件大小不超过10MB,最多上传15个文件。
|
|
|
+ <span class="el-upload__tip" v-if="!form.id" style="color: #ff0000">(新增时文件将在保存工单后上传)</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 调整拖拽上传图标与文字在同一行、居中对齐 -->
|
|
|
+ <div class="el-upload-dragger1">
|
|
|
+ <el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
|
|
+ <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 自定义文件卡片缩略图(含文件名) -->
|
|
|
+ <template #file="{ file }">
|
|
|
+ <div class="upload-file-card">
|
|
|
+ <!-- 缩略图区域 -->
|
|
|
+ <div class="upload-file-thumb">
|
|
|
+ <el-image
|
|
|
+ v-if="isImageFile(file) && file.url"
|
|
|
+ :src="file.url"
|
|
|
+ fit="cover"
|
|
|
+ :preview-src-list="[file.url]"
|
|
|
+ class="upload-thumb-image"
|
|
|
+ />
|
|
|
+ <div v-else class="upload-file-placeholder">
|
|
|
+ <el-icon><Document /></el-icon>
|
|
|
+ <span class="file-ext">{{ file.name }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
</el-upload>
|
|
|
</div>
|
|
|
@@ -1187,6 +1224,7 @@ import {
|
|
|
import { useUserStore } from '@/store/modules/user';
|
|
|
import { getInfo } from '@/api/login'; // 添加获取用户详细信息的API
|
|
|
import { getToken } from '@/utils/auth'; // 修复:添加getToken导入
|
|
|
+import { vLoading } from 'element-plus';
|
|
|
|
|
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
|
|
|
@@ -1253,7 +1291,7 @@ const pm_order_status = ref([
|
|
|
{ value: '3', label: '进行中' },
|
|
|
{ value: '4', label: '已完成' },
|
|
|
{ value: '5', label: '已评价' },
|
|
|
- { value: '6', label: '已归档' },
|
|
|
+ // { value: '6', label: '已归档' },
|
|
|
{ value: '9', label: '已取消' }
|
|
|
]);
|
|
|
|
|
|
@@ -1448,6 +1486,21 @@ const satisfactionLevelOptions = ref([
|
|
|
const getList = async () => {
|
|
|
loading.value = true;
|
|
|
queryParams.value.createTimeRange = daterangeCreateTime.value;
|
|
|
+
|
|
|
+ // 设置创建时间范围
|
|
|
+ queryParams.value.createTimeRange = daterangeCreateTime.value;
|
|
|
+
|
|
|
+ // 将创建时间范围写入 params,供后台 between 过滤使用
|
|
|
+ if (daterangeCreateTime.value && daterangeCreateTime.value.length === 2 && daterangeCreateTime.value[0] && daterangeCreateTime.value[1]) {
|
|
|
+ queryParams.value.params = {
|
|
|
+ ...queryParams.value.params,
|
|
|
+ beginCreateTime: daterangeCreateTime.value[0],
|
|
|
+ endCreateTime: daterangeCreateTime.value[1]
|
|
|
+ };
|
|
|
+ } else if (queryParams.value.params) {
|
|
|
+ delete queryParams.value.params.beginCreateTime;
|
|
|
+ delete queryParams.value.params.endCreateTime;
|
|
|
+ }
|
|
|
const res = await listRepairOrder(queryParams.value);
|
|
|
// 适配后端返回格式:支持新格式{total, rows, code, msg}和旧格式{code, msg, data: {total, rows}}
|
|
|
if ((res as any).rows && (res as any).total !== undefined) {
|
|
|
@@ -1992,13 +2045,13 @@ const canPreview = (attachment: any) => {
|
|
|
|
|
|
/** 显示附件详情 */
|
|
|
const showAttachmentDetail = (attachment: any) => {
|
|
|
- const details = `文件名称:${attachment.fileName}
|
|
|
-文件大小:${formatFileSize(attachment.fileSize)}
|
|
|
-文件类型:${getFileTypeLabel(attachment.fileType)}
|
|
|
-上传者:${attachment.uploaderName || '未知'}
|
|
|
-上传时间:${attachment.createTime}
|
|
|
-上传阶段:${getUploadStageText(attachment.uploadStage)}
|
|
|
-存储路径:${attachment.filePath}
|
|
|
+ const details = `文件名称:${attachment.fileName}<br/>
|
|
|
+文件大小:${formatFileSize(attachment.fileSize)}<br/>
|
|
|
+文件类型:${getFileTypeLabel(attachment.fileType)}<br/>
|
|
|
+上传者:${attachment.uploaderName || '未知'}<br/>
|
|
|
+上传时间:${attachment.createTime}<br/>
|
|
|
+上传阶段:${getUploadStageText(attachment.uploadStage)}<br/>
|
|
|
+存储路径:${attachment.filePath}<br/>
|
|
|
文件描述:${attachment.description || '无'}`;
|
|
|
|
|
|
proxy?.$modal.alert(details);
|
|
|
@@ -2600,6 +2653,56 @@ onMounted(() => {
|
|
|
getWorkerOptions();
|
|
|
getCurrentUserInfo();
|
|
|
});
|
|
|
+
|
|
|
+/** 卡片预览 */
|
|
|
+const handleFilePreview = (file: any) => {
|
|
|
+ // 如果文件已经上传成功,优先使用服务器返回的url
|
|
|
+ let url = file.url || (file.response && file.response.data && file.response.data.filePath);
|
|
|
+
|
|
|
+ // 若还未上传,则尝试使用本地预览地址
|
|
|
+ if (!url && file.raw) {
|
|
|
+ url = URL.createObjectURL(file.raw);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!url) return;
|
|
|
+
|
|
|
+ // 对图片使用图片预览,其余直接新窗口打开
|
|
|
+ const isImage = file.type ? file.type.startsWith('image') : file.raw && file.raw.type.startsWith('image');
|
|
|
+ if (isImage) {
|
|
|
+ // 利用 Element Plus ImageViewer 进行预览
|
|
|
+ const viewer = (proxy as any)?.$imageViewer;
|
|
|
+ viewer && viewer([url]);
|
|
|
+ } else {
|
|
|
+ window.open(url, '_blank');
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/** 判断是否为图片文件 */
|
|
|
+const isImageFile = (file: any): boolean => {
|
|
|
+ // 优先使用文件 MIME type 判断
|
|
|
+ const type = file.type || (file.raw && file.raw.type) || '';
|
|
|
+ if (type && type.startsWith('image')) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 编辑场景下从数据库加载的附件通常缺少 MIME type
|
|
|
+ // 通过文件名或 URL 后缀进行判断
|
|
|
+ const name: string = file.name || file.response?.data?.fileName || '';
|
|
|
+ const url: string = file.url || file.response?.data?.filePath || '';
|
|
|
+ const source = (name || url).toLowerCase();
|
|
|
+
|
|
|
+ // 常见图片扩展名
|
|
|
+ const IMAGE_EXTS = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg', '.tiff', '.ico'];
|
|
|
+
|
|
|
+ return IMAGE_EXTS.some((ext) => source.endsWith(ext));
|
|
|
+};
|
|
|
+
|
|
|
+/** 获取文件扩展名小写 */
|
|
|
+const getFileExt = (fileName: string): string => {
|
|
|
+ if (!fileName) return '';
|
|
|
+ const idx = fileName.lastIndexOf('.');
|
|
|
+ return idx !== -1 ? fileName.substring(idx + 1).toLowerCase() : '';
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
@@ -2763,7 +2866,7 @@ onMounted(() => {
|
|
|
.attachment-upload-container {
|
|
|
.upload-demo {
|
|
|
.el-upload {
|
|
|
- border: 2px dashed #d9d9d9;
|
|
|
+ /* border: 2px dashed #d9d9d9; */
|
|
|
border-radius: 6px;
|
|
|
cursor: pointer;
|
|
|
position: relative;
|
|
|
@@ -2777,9 +2880,69 @@ onMounted(() => {
|
|
|
|
|
|
.el-upload__tip {
|
|
|
font-size: 12px;
|
|
|
- color: #606266;
|
|
|
+ color: #000000;
|
|
|
margin-top: 7px;
|
|
|
}
|
|
|
+
|
|
|
+ // 调整拖拽上传图标与文字在同一行、居中对齐
|
|
|
+ .el-upload-dragger1 {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 15px;
|
|
|
+ padding: 0px !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-upload-dragger1 .el-icon--upload {
|
|
|
+ margin: 0;
|
|
|
+ padding: 0px !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 文件卡片占位封面样式 */
|
|
|
+ .upload-file-placeholder {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ color: #909399;
|
|
|
+ font-size: 14px;
|
|
|
+
|
|
|
+ .el-icon {
|
|
|
+ font-size: 28px;
|
|
|
+ margin-bottom: 4px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .file-ext {
|
|
|
+ font-size: 12px;
|
|
|
+ text-transform: uppercase;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 让附件卡片一行展示 4 个 */
|
|
|
+ :deep(.el-upload-list--picture-card) {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: repeat(4, 1fr);
|
|
|
+ gap: 9px;
|
|
|
+ margin-top: 12px;
|
|
|
+
|
|
|
+ /* 确保卡片宽度自适应 */
|
|
|
+ .el-upload-list__item {
|
|
|
+ margin: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.el-upload-dragger) {
|
|
|
+ border: 0px !important;
|
|
|
+ padding: 0px !important;
|
|
|
+ .el-upload-dragger1 {
|
|
|
+ border: 0px !important;
|
|
|
+ padding: 0px !important;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -3341,4 +3504,34 @@ onMounted(() => {
|
|
|
:deep(.el-icon) {
|
|
|
display: flex !important;
|
|
|
}
|
|
|
+
|
|
|
+/* 卡片整体布局包含文件名 */
|
|
|
+.upload-file-card {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.upload-file-thumb {
|
|
|
+ width: 100%;
|
|
|
+ aspect-ratio: 1 / 1;
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+
|
|
|
+.upload-file-thumb .el-image,
|
|
|
+.upload-file-thumb .upload-file-placeholder {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.upload-file-name {
|
|
|
+ width: 100%;
|
|
|
+ margin-top: 4px;
|
|
|
+ font-size: 12px;
|
|
|
+ text-align: center;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+}
|
|
|
</style>
|