Przeglądaj źródła

feat(equipManage): 完成设备台账页面的完整开发

1. 新增设备台账API接口文件,包含增删改查和导出导入接口
2. 重构设备台账页面表单、表格字段适配后端新实体
3. 添加权限控制、分页、字典渲染、导入导出功能
4. 新增定检记录管理和自检到期日期自动计算逻辑
5. 优化序号渲染、表单校验和用户选择组件使用
huoyi 1 miesiąc temu
rodzic
commit
ed88a1e668

+ 54 - 0
src/api/equipManage/equipLedger.js

@@ -0,0 +1,54 @@
1
+import request from '@/utils/request'
2
+
3
+// 查询设备台账列表
4
+export function listEquipLedger(query) {
5
+  return request({
6
+    url: '/equipment/ledger/list',
7
+    method: 'get',
8
+    params: query
9
+  })
10
+}
11
+
12
+// 获取设备台账详细信息
13
+export function getEquipLedger(ledgerId) {
14
+  return request({
15
+    url: '/equipment/ledger/' + ledgerId,
16
+    method: 'get'
17
+  })
18
+}
19
+
20
+// 新增设备台账
21
+export function addEquipLedger(data) {
22
+  return request({
23
+    url: '/equipment/ledger',
24
+    method: 'post',
25
+    data: data
26
+  })
27
+}
28
+
29
+// 修改设备台账
30
+export function updateEquipLedger(data) {
31
+  return request({
32
+    url: '/equipment/ledger',
33
+    method: 'put',
34
+    data: data
35
+  })
36
+}
37
+
38
+// 删除设备台账
39
+export function delEquipLedger(ledgerIds) {
40
+  return request({
41
+    url: '/equipment/ledger/' + ledgerIds,
42
+    method: 'delete'
43
+  })
44
+}
45
+
46
+// 导出设备台账列表
47
+export function exportEquipLedger(data) {
48
+  return request({
49
+    url: '/equipment/ledger/export',
50
+    method: 'post',
51
+    data: data,
52
+    responseType: 'blob'
53
+  })
54
+}

+ 318 - 149
src/views/equipManage/equipLedger/index.vue

@@ -3,20 +3,19 @@
3
     <!-- 查询条件 -->
3
     <!-- 查询条件 -->
4
     <div class="filter-container">
4
     <div class="filter-container">
5
       <el-form :model="queryParams" ref="queryFormRef" :inline="true" class="search-form">
5
       <el-form :model="queryParams" ref="queryFormRef" :inline="true" class="search-form">
6
-        <el-form-item label="设备名称" prop="equipName">
7
-          <el-input v-model="queryParams.equipName" placeholder="请输入设备名称" clearable style="width: 200px" />
6
+        <el-form-item label="设备名称" prop="equipmentName">
7
+          <el-input v-model="queryParams.equipmentName" placeholder="请输入设备名称" clearable style="width: 200px" />
8
         </el-form-item>
8
         </el-form-item>
9
         <el-form-item label="使用状态" prop="usageStatus">
9
         <el-form-item label="使用状态" prop="usageStatus">
10
           <el-select v-model="queryParams.usageStatus" placeholder="请选择使用状态" clearable style="width: 200px">
10
           <el-select v-model="queryParams.usageStatus" placeholder="请选择使用状态" clearable style="width: 200px">
11
-            <el-option label="使用中" value="1" />
12
-            <el-option label="已停用" value="0" />
11
+            <el-option v-for="dict in equipment_usage_status" :key="dict.value" :label="dict.label" :value="dict.value" />
13
           </el-select>
12
           </el-select>
14
         </el-form-item>
13
         </el-form-item>
15
-        <el-form-item label="最近定/自检日期" prop="lastCheckDate">
16
-          <el-date-picker v-model="queryParams.lastCheckDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择日期" style="width: 200px" />
14
+        <el-form-item label="最近定/自检日期" prop="inspectionSelfCheckDate">
15
+          <el-date-picker v-model="queryParams.inspectionSelfCheckDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择日期" style="width: 200px" />
17
         </el-form-item>
16
         </el-form-item>
18
-        <el-form-item label="检查成员" prop="checkMember">
19
-          <el-input v-model="queryParams.checkMember" placeholder="请输入检查成员" clearable style="width: 200px" />
17
+        <el-form-item label="检查成员" prop="inspectionTeamUserName">
18
+          <el-input v-model="queryParams.inspectionTeamUserName" placeholder="请输入检查成员" clearable style="width: 200px" />
20
         </el-form-item>
19
         </el-form-item>
21
         <el-form-item>
20
         <el-form-item>
22
           <el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
21
           <el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
@@ -27,31 +26,39 @@
27
 
26
 
28
     <!-- 操作按钮 -->
27
     <!-- 操作按钮 -->
29
     <div class="operation-container">
28
     <div class="operation-container">
30
-      <el-button type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
31
-      <el-button type="danger" plain icon="Delete" :disabled="single" @click="handleBatchDelete">删除</el-button>
32
-      <el-button type="warning" plain icon="Download" @click="handleExport">导出</el-button>
33
-      <el-button type="info" plain icon="Upload" @click="handleImport">导入</el-button>
29
+      <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['equipment:ledger:add']">新增</el-button>
30
+      <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleBatchDelete" v-hasPermi="['equipment:ledger:delete']">删除</el-button>
31
+      <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['equipment:ledger:export']">导出</el-button>
32
+      <el-button type="info" plain icon="Upload" @click="handleImport" v-hasPermi="['equipment:ledger:import']">导入</el-button>
34
     </div>
33
     </div>
35
 
34
 
36
     <!-- 数据表格 -->
35
     <!-- 数据表格 -->
37
     <el-table v-loading="loading" :data="tableData" border @selection-change="handleSelectionChange">
36
     <el-table v-loading="loading" :data="tableData" border @selection-change="handleSelectionChange">
38
       <el-table-column type="selection" width="55" align="center" />
37
       <el-table-column type="selection" width="55" align="center" />
39
-      <el-table-column label="序号" prop="rowIndex" width="70" align="center" />
40
-      <el-table-column label="设备编号" prop="equipCode" align="center" min-width="120" />
41
-      <el-table-column label="设备名称" prop="equipName" align="center" min-width="150" show-overflow-tooltip />
42
-      <el-table-column label="设备序列号" prop="serialNumber" align="center" min-width="150" show-overflow-tooltip />
43
-      <el-table-column label="安装位置" prop="installLocation" align="center" min-width="150" show-overflow-tooltip />
38
+      <el-table-column label="序号" prop="rowIndex" width="70" align="center">
39
+        <template #default="scope">
40
+          {{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}
41
+        </template>
42
+      </el-table-column>
43
+      <el-table-column label="设备编号" prop="equipmentCode" align="center" min-width="120">
44
+        <template #default="scope">
45
+          <el-link type="primary" @click="handleDetail(scope.row)">{{ scope.row.equipmentCode }}</el-link>
46
+        </template>
47
+      </el-table-column>
48
+      <el-table-column label="设备名称" prop="equipmentName" align="center" min-width="150" show-overflow-tooltip />
49
+      <el-table-column label="设备序列号" prop="equipmentSerialNumber" align="center" min-width="150" show-overflow-tooltip />
50
+      <el-table-column label="安装位置" prop="installationLocation" align="center" min-width="150" show-overflow-tooltip />
44
       <el-table-column label="使用状态" prop="usageStatus" align="center" min-width="100">
51
       <el-table-column label="使用状态" prop="usageStatus" align="center" min-width="100">
45
         <template #default="scope">
52
         <template #default="scope">
46
-          <el-tag :type="scope.row.usageStatus === '1' ? 'success' : 'danger'">
47
-            {{ scope.row.usageStatus === '1' ? '使用中' : '已停用' }}
48
-          </el-tag>
53
+          <dict-tag :options="equipment_usage_status" :value="scope.row.usageStatus" />
54
+          
49
         </template>
55
         </template>
50
       </el-table-column>
56
       </el-table-column>
51
-      <el-table-column label="定/自检小组组长" prop="checkTeamLeader" align="center" min-width="120" show-overflow-tooltip />
52
-      <el-table-column label="定/自检小组组员" prop="checkTeamMembers" align="center" min-width="120" show-overflow-tooltip />
53
-      <el-table-column label="最近定检/自检日期" prop="lastCheckDate" align="center" min-width="120" />
54
-      <el-table-column label="操作" align="center" width="180" fixed="right">
57
+      <el-table-column label="定/自检小组组长" prop="inspectionTeamLeaderName" align="center" min-width="120" show-overflow-tooltip />
58
+      <el-table-column label="定/自检小组组员1" prop="inspectionTeamMember1Name" align="center" min-width="120" show-overflow-tooltip />
59
+      <el-table-column label="定/自检小组组员2" prop="inspectionTeamMember2Name" align="center" min-width="120" show-overflow-tooltip />
60
+      <el-table-column label="最近定检/自检日期" prop="inspectionSelfCheckDate" align="center" min-width="120" />
61
+      <el-table-column label="操作" align="center" width="220" fixed="right">
55
         <template #default="scope">
62
         <template #default="scope">
56
           <el-button link type="primary" icon="View" @click="handleDetail(scope.row)">详情</el-button>
63
           <el-button link type="primary" icon="View" @click="handleDetail(scope.row)">详情</el-button>
57
           <el-button link type="primary" icon="Edit" @click="handleEdit(scope.row)">编辑</el-button>
64
           <el-button link type="primary" icon="Edit" @click="handleEdit(scope.row)">编辑</el-button>
@@ -60,38 +67,41 @@
60
       </el-table-column>
67
       </el-table-column>
61
     </el-table>
68
     </el-table>
62
 
69
 
70
+    <!-- 分页 -->
71
+    <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
72
+
63
     <!-- 编辑/详情弹窗 -->
73
     <!-- 编辑/详情弹窗 -->
64
-    <el-dialog :title="dialog.title" v-model="dialog.visible" width="900px" :close-on-click-modal="false">
74
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="1000px" :close-on-click-modal="false">
65
       <el-form :model="form" ref="formRef" :rules="rules" label-width="140px">
75
       <el-form :model="form" ref="formRef" :rules="rules" label-width="140px">
66
         <el-row :gutter="20">
76
         <el-row :gutter="20">
67
           <el-col :span="12">
77
           <el-col :span="12">
68
-            <el-form-item label="设备名称" prop="equipName">
69
-              <el-input v-model="form.equipName" placeholder="请输入设备名称" :disabled="formDisabled" />
78
+            <el-form-item label="设备名称" prop="equipmentName">
79
+              <el-input v-model="form.equipmentName" placeholder="请输入设备名称" :disabled="formDisabled" />
70
             </el-form-item>
80
             </el-form-item>
71
           </el-col>
81
           </el-col>
72
           <el-col :span="12">
82
           <el-col :span="12">
73
-            <el-form-item label="设备种类" prop="equipType">
74
-              <el-input v-model="form.equipType" placeholder="请输入设备种类" :disabled="formDisabled" />
83
+            <el-form-item label="设备种类" prop="equipmentType">
84
+              <el-input v-model="form.equipmentType" placeholder="请输入设备种类" :disabled="formDisabled" />
75
             </el-form-item>
85
             </el-form-item>
76
           </el-col>
86
           </el-col>
77
           <el-col :span="12">
87
           <el-col :span="12">
78
-            <el-form-item label="设备类别" prop="equipCategory">
79
-              <el-input v-model="form.equipCategory" placeholder="请输入设备类别" :disabled="formDisabled" />
88
+            <el-form-item label="设备类别" prop="equipmentCategory">
89
+              <el-input v-model="form.equipmentCategory" placeholder="请输入设备类别" :disabled="formDisabled" />
80
             </el-form-item>
90
             </el-form-item>
81
           </el-col>
91
           </el-col>
82
           <el-col :span="12">
92
           <el-col :span="12">
83
-            <el-form-item label="设备品牌" prop="equipBrand">
84
-              <el-input v-model="form.equipBrand" placeholder="请输入设备品牌" :disabled="formDisabled" />
93
+            <el-form-item label="设备品牌" prop="equipmentBrand">
94
+              <el-input v-model="form.equipmentBrand" placeholder="请输入设备品牌" :disabled="formDisabled" />
85
             </el-form-item>
95
             </el-form-item>
86
           </el-col>
96
           </el-col>
87
           <el-col :span="12">
97
           <el-col :span="12">
88
-            <el-form-item label="设备型号" prop="equipModel">
89
-              <el-input v-model="form.equipModel" placeholder="请输入设备型号" :disabled="formDisabled" />
98
+            <el-form-item label="设备型号" prop="equipmentModel">
99
+              <el-input v-model="form.equipmentModel" placeholder="请输入设备型号" :disabled="formDisabled" />
90
             </el-form-item>
100
             </el-form-item>
91
           </el-col>
101
           </el-col>
92
           <el-col :span="12">
102
           <el-col :span="12">
93
-            <el-form-item label="设备序列号" prop="serialNumber">
94
-              <el-input v-model="form.serialNumber" placeholder="请输入设备序列号" :disabled="formDisabled" />
103
+            <el-form-item label="设备序列号" prop="equipmentSerialNumber">
104
+              <el-input v-model="form.equipmentSerialNumber" placeholder="请输入设备序列号" :disabled="formDisabled" />
95
             </el-form-item>
105
             </el-form-item>
96
           </el-col>
106
           </el-col>
97
           <el-col :span="12">
107
           <el-col :span="12">
@@ -100,71 +110,75 @@
100
             </el-form-item>
110
             </el-form-item>
101
           </el-col>
111
           </el-col>
102
           <el-col :span="12">
112
           <el-col :span="12">
103
-            <el-form-item label="出厂日期" prop="factoryDate">
104
-              <el-date-picker v-model="form.factoryDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择出厂日期" :disabled="formDisabled" />
113
+            <el-form-item label="出厂日期" prop="manufacturingDate">
114
+              <el-date-picker v-model="form.manufacturingDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择出厂日期" :disabled="formDisabled" />
105
             </el-form-item>
115
             </el-form-item>
106
           </el-col>
116
           </el-col>
107
           <el-col :span="12">
117
           <el-col :span="12">
108
-            <el-form-item label="绩效日期" prop="performanceDate">
109
-              <el-date-picker v-model="form.performanceDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择绩效日期" :disabled="formDisabled" />
118
+            <el-form-item label="验收日期" prop="acceptanceDate">
119
+              <el-date-picker v-model="form.acceptanceDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择验收日期" :disabled="formDisabled" />
110
             </el-form-item>
120
             </el-form-item>
111
           </el-col>
121
           </el-col>
112
           <el-col :span="12">
122
           <el-col :span="12">
113
-            <el-form-item label="启用日期" prop="enableDate">
114
-              <el-date-picker v-model="form.enableDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择启用日期" :disabled="formDisabled" />
123
+            <el-form-item label="启用日期" prop="commissioningDate">
124
+              <el-date-picker v-model="form.commissioningDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择启用日期" :disabled="formDisabled" />
115
             </el-form-item>
125
             </el-form-item>
116
           </el-col>
126
           </el-col>
117
           <el-col :span="12">
127
           <el-col :span="12">
118
             <el-form-item label="使用状态" prop="usageStatus">
128
             <el-form-item label="使用状态" prop="usageStatus">
119
               <el-select v-model="form.usageStatus" placeholder="请选择使用状态" :disabled="formDisabled">
129
               <el-select v-model="form.usageStatus" placeholder="请选择使用状态" :disabled="formDisabled">
120
-                <el-option label="使用中" value="1" />
121
-                <el-option label="已停用" value="0" />
130
+                <el-option v-for="dict in equipment_usage_status" :key="dict.value" :label="dict.label" :value="dict.value" />
122
               </el-select>
131
               </el-select>
123
             </el-form-item>
132
             </el-form-item>
124
           </el-col>
133
           </el-col>
125
           <el-col :span="12">
134
           <el-col :span="12">
126
-            <el-form-item label="报废日期" prop="retireDate">
127
-              <el-date-picker v-model="form.retireDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择报废日期" :disabled="formDisabled" />
135
+            <el-form-item label="报废日期" prop="scrappingDate">
136
+              <el-date-picker v-model="form.scrappingDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择报废日期" :disabled="formDisabled" />
137
+            </el-form-item>
138
+          </el-col>
139
+          <el-col :span="12">
140
+            <el-form-item label="安装位置" prop="installationLocation">
141
+              <el-input v-model="form.installationLocation" placeholder="请输入安装位置" :disabled="formDisabled" />
128
             </el-form-item>
142
             </el-form-item>
129
           </el-col>
143
           </el-col>
130
           <el-col :span="12">
144
           <el-col :span="12">
131
-            <el-form-item label="安装位置" prop="installLocation">
132
-              <el-input v-model="form.installLocation" placeholder="请输入安装位置" :disabled="formDisabled" />
145
+            <el-form-item label="定/自检日期" prop="inspectionSelfCheckDate">
146
+              <el-date-picker v-model="form.inspectionSelfCheckDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择定/自检日期" :disabled="formDisabled" @change="calculateDueDate" />
133
             </el-form-item>
147
             </el-form-item>
134
           </el-col>
148
           </el-col>
135
           <el-col :span="12">
149
           <el-col :span="12">
136
-            <el-form-item label="定/自检日期" prop="checkDate">
137
-              <el-date-picker v-model="form.checkDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择定/自检日期" :disabled="formDisabled" />
150
+            <el-form-item label="定/自检周期" prop="inspectionSelfCheckCycle">
151
+              <el-input-number v-model="form.inspectionSelfCheckCycle" placeholder="请输入定/自检周期" :min="0" :precision="0" :disabled="formDisabled" @change="calculateDueDate" />&nbsp;月
138
             </el-form-item>
152
             </el-form-item>
139
           </el-col>
153
           </el-col>
140
           <el-col :span="12">
154
           <el-col :span="12">
141
-            <el-form-item label="定/自检周期" prop="checkCycle">
142
-              <el-input-number v-model="form.checkCycle" placeholder="请输入定/自检周期" :min="0" :disabled="formDisabled" />
155
+            <el-form-item label="最近定/自检到期日期" prop="nextInspectionDueDate">
156
+              <el-date-picker v-model="form.nextInspectionDueDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择最近定/自检到期日期" :disabled="formDisabled" />
143
             </el-form-item>
157
             </el-form-item>
144
           </el-col>
158
           </el-col>
145
           <el-col :span="12">
159
           <el-col :span="12">
146
-            <el-form-item label="定/自检到期日期" prop="checkExpireDate">
147
-              <el-date-picker v-model="form.checkExpireDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择定/自检到期日期" :disabled="formDisabled" />
160
+            <el-form-item label="定/自检小组组长" prop="inspectionTeamLeaderId">
161
+              <UserSelect v-model="form.inspectionTeamLeaderId" :disabled="formDisabled" width="100%" placeholder="请选择组长" />
148
             </el-form-item>
162
             </el-form-item>
149
           </el-col>
163
           </el-col>
150
           <el-col :span="12">
164
           <el-col :span="12">
151
-            <el-form-item label="定/自检小组组长" prop="checkTeamLeader">
152
-              <el-input v-model="form.checkTeamLeader" placeholder="请输入定/自检小组组长" :disabled="formDisabled" />
165
+            <el-form-item label="定/自检小组组员1" prop="inspectionTeamMember1Id">
166
+              <UserSelect v-model="form.inspectionTeamMember1Id" :disabled="formDisabled" width="100%" placeholder="请选择组员1" />
153
             </el-form-item>
167
             </el-form-item>
154
           </el-col>
168
           </el-col>
155
           <el-col :span="12">
169
           <el-col :span="12">
156
-            <el-form-item label="定/自检小组组员" prop="checkTeamMembers">
157
-              <el-input v-model="form.checkTeamMembers" placeholder="请输入定/自检小组组员" :disabled="formDisabled" />
170
+            <el-form-item label="定/自检小组组员2" prop="inspectionTeamMember2Id">
171
+              <UserSelect v-model="form.inspectionTeamMember2Id" :disabled="formDisabled" width="100%" placeholder="请选择组员2" />
158
             </el-form-item>
172
             </el-form-item>
159
           </el-col>
173
           </el-col>
160
           <el-col :span="24">
174
           <el-col :span="24">
161
-            <el-form-item label="首次验收情况" prop="firstAcceptance">
162
-              <el-input v-model="form.firstAcceptance" type="textarea" :rows="3" placeholder="请输入首次验收情况" :disabled="formDisabled" />
175
+            <el-form-item label="首次验收情况" prop="initialAcceptanceStatus">
176
+              <el-input v-model="form.initialAcceptanceStatus" type="textarea" :rows="3" placeholder="请输入首次验收情况" :disabled="formDisabled" />
163
             </el-form-item>
177
             </el-form-item>
164
           </el-col>
178
           </el-col>
165
           <el-col :span="24">
179
           <el-col :span="24">
166
-            <el-form-item label="设备图片" prop="equipImages">
167
-              <ImageUpload v-model="form.equipImages" :disabled="formDisabled" />
180
+            <el-form-item label="设备图片" prop="baseAttachmentList">
181
+              <ImageUpload v-model="form.baseAttachmentList" :disabled="formDisabled" :limit="3" />
168
             </el-form-item>
182
             </el-form-item>
169
           </el-col>
183
           </el-col>
170
         </el-row>
184
         </el-row>
@@ -172,33 +186,32 @@
172
         <!-- 定检记录表格 -->
186
         <!-- 定检记录表格 -->
173
         <el-divider content-position="left">定检记录</el-divider>
187
         <el-divider content-position="left">定检记录</el-divider>
174
         <el-button type="primary" plain icon="Plus" @click="addCheckRecord" v-if="!formDisabled">新增定检记录</el-button>
188
         <el-button type="primary" plain icon="Plus" @click="addCheckRecord" v-if="!formDisabled">新增定检记录</el-button>
175
-        <el-table :data="form.checkRecords" border style="margin-top: 10px">
176
-          <el-table-column label="定检日期" prop="checkRecordDate">
189
+        <el-table :data="form.equipmentInspectionRecordList" border style="margin-top: 10px">
190
+          <el-table-column label="定检日期" prop="inspectionDate">
177
             <template #default="scope">
191
             <template #default="scope">
178
-              <el-date-picker v-model="scope.row.checkRecordDate" type="date" value-format="YYYY-MM-DD" placeholder="选择日期" :disabled="formDisabled" />
192
+              <el-date-picker v-model="scope.row.inspectionDate" type="date" value-format="YYYY-MM-DD" placeholder="选择日期" :disabled="formDisabled" @change="handleInspectionDateChange(scope.row, scope.$index)" />
179
             </template>
193
             </template>
180
           </el-table-column>
194
           </el-table-column>
181
-          <el-table-column label="定检小组" prop="checkTeam">
195
+          <el-table-column label="定检小组" prop="inspectionTeamName">
182
             <template #default="scope">
196
             <template #default="scope">
183
-              <el-input v-model="scope.row.checkTeam" placeholder="定检小组" :disabled="formDisabled" />
197
+              <UserSelect v-model="scope.row.inspectionTeamIds" :multiple="true" :disabled="formDisabled" width="100%" placeholder="请选择" />
184
             </template>
198
             </template>
185
           </el-table-column>
199
           </el-table-column>
186
-          <el-table-column label="定检结论" prop="checkConclusion">
200
+          <el-table-column label="定检结论" prop="inspectionResult">
187
             <template #default="scope">
201
             <template #default="scope">
188
-              <el-input v-model="scope.row.checkConclusion" placeholder="定检结论" :disabled="formDisabled" />
202
+              <el-input v-model="scope.row.inspectionResult" placeholder="定检结论" :disabled="formDisabled" />
189
             </template>
203
             </template>
190
           </el-table-column>
204
           </el-table-column>
191
-          <el-table-column label="定检性质" prop="checkNature">
205
+          <el-table-column label="定检性质" prop="inspectionNature">
192
             <template #default="scope">
206
             <template #default="scope">
193
-              <el-select v-model="scope.row.checkNature" placeholder="请选择" :disabled="formDisabled">
194
-                <el-option label="重大维修" value="major_repair" />
195
-                <el-option label="移机" value="relocation" />
207
+              <el-select v-model="scope.row.inspectionNature" placeholder="请选择" :disabled="formDisabled">
208
+                <el-option v-for="dict in equipment_inspection_nature" :key="dict.value" :label="dict.label" :value="dict.value" />
196
               </el-select>
209
               </el-select>
197
             </template>
210
             </template>
198
           </el-table-column>
211
           </el-table-column>
199
           <el-table-column label="操作" width="80" v-if="!formDisabled">
212
           <el-table-column label="操作" width="80" v-if="!formDisabled">
200
             <template #default="scope">
213
             <template #default="scope">
201
-              <el-button type="danger" link icon="Delete" @click="removeCheckRecord(scope.$index)">删除</el-button>
214
+              <el-button type="danger" link icon="Delete" @click="removeCheckRecord(scope.$index)" v-hasPermi="['equipment:ledger:delete']">删除</el-button>
202
             </template>
215
             </template>
203
           </el-table-column>
216
           </el-table-column>
204
         </el-table>
217
         </el-table>
@@ -210,66 +223,114 @@
210
       </template>
223
       </template>
211
     </el-dialog>
224
     </el-dialog>
212
 
225
 
213
-    
226
+    <!-- 导入对话框 -->
227
+    <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
228
+      <el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
229
+        <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
230
+        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
231
+        <template #tip>
232
+          <div class="el-upload__tip text-center">
233
+            <span>仅允许导入xls、xlsx格式文件。</span>
234
+            <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板</el-link>
235
+          </div>
236
+        </template>
237
+      </el-upload>
238
+      <template #footer>
239
+        <div class="dialog-footer">
240
+          <el-button type="primary" @click="submitFileForm">确 定</el-button>
241
+          <el-button @click="upload.open = false">取 消</el-button>
242
+        </div>
243
+      </template>
244
+    </el-dialog>
214
   </div>
245
   </div>
215
 </template>
246
 </template>
216
 
247
 
217
 <script setup>
248
 <script setup>
218
-import { ref, reactive } from 'vue'
249
+import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
219
 import { ElMessage } from 'element-plus'
250
 import { ElMessage } from 'element-plus'
251
+import { UploadFilled } from '@element-plus/icons-vue'
220
 import ImageUpload from '@/components/ImageUpload/index.vue'
252
 import ImageUpload from '@/components/ImageUpload/index.vue'
253
+import UserSelect from '@/components/UserSelect/index.vue'
254
+import { listEquipLedger, getEquipLedger, addEquipLedger, updateEquipLedger, delEquipLedger, exportEquipLedger } from '@/api/equipManage/equipLedger'
255
+import { getUser } from '@/api/system/user'
256
+import { getToken } from '@/utils/auth'
257
+
258
+const { proxy } = getCurrentInstance()
259
+
260
+const { equipment_usage_status, equipment_inspection_nature } = proxy.useDict('equipment_usage_status', 'equipment_inspection_nature')
221
 
261
 
222
 const loading = ref(false)
262
 const loading = ref(false)
223
 const queryFormRef = ref()
263
 const queryFormRef = ref()
224
 const formRef = ref()
264
 const formRef = ref()
225
 const tableData = ref([])
265
 const tableData = ref([])
266
+const total = ref(0)
226
 const single = ref(true)
267
 const single = ref(true)
227
 const multiple = ref(true)
268
 const multiple = ref(true)
228
 const queryParams = reactive({
269
 const queryParams = reactive({
229
-  equipName: '',
270
+  pageNum: 1,
271
+  pageSize: 10,
272
+  equipmentName: '',
230
   usageStatus: '',
273
   usageStatus: '',
231
-  lastCheckDate: '',
232
-  checkMember: ''
274
+  inspectionSelfCheckDate: '',
275
+  inspectionTeamUserName: ''
233
 })
276
 })
234
 const dialog = reactive({
277
 const dialog = reactive({
235
   visible: false,
278
   visible: false,
236
   title: ''
279
   title: ''
237
 })
280
 })
238
-const detailVisible = ref(false)
239
 const formDisabled = ref(false)
281
 const formDisabled = ref(false)
240
 const form = reactive({
282
 const form = reactive({
241
-  equipName: '',
242
-  equipType: '',
243
-  equipCategory: '',
244
-  equipBrand: '',
245
-  equipModel: '',
246
-  serialNumber: '',
283
+  id: null,
284
+  equipmentName: '',
285
+  equipmentType: '',
286
+  equipmentCategory: '',
287
+  equipmentBrand: '',
288
+  equipmentModel: '',
289
+  equipmentSerialNumber: '',
247
   manufacturer: '',
290
   manufacturer: '',
248
-  factoryDate: '',
249
-  performanceDate: '',
250
-  enableDate: '',
291
+  manufacturingDate: '',
292
+  acceptanceDate: '',
293
+  commissioningDate: '',
251
   usageStatus: '1',
294
   usageStatus: '1',
252
-  retireDate: '',
253
-  installLocation: '',
254
-  checkDate: '',
255
-  checkCycle: 0,
256
-  checkExpireDate: '',
257
-  checkTeamLeader: '',
258
-  checkTeamMembers: '',
259
-  firstAcceptance: '',
260
-  checkRecords: []
295
+  scrappingDate: '',
296
+  installationLocation: '',
297
+  inspectionSelfCheckDate: '',
298
+  inspectionSelfCheckCycle: 0,
299
+  nextInspectionDueDate: '',
300
+  inspectionTeamLeaderId: '',
301
+  inspectionTeamMember1Id: '',
302
+  inspectionTeamMember2Id: '',
303
+  initialAcceptanceStatus: '',
304
+  baseAttachmentList: [],
305
+  equipmentInspectionRecordList: []
261
 })
306
 })
262
 const rules = {
307
 const rules = {
263
-  equipName: [{ required: true, message: '设备名称不能为空', trigger: 'blur' }],
264
-  serialNumber: [{ required: true, message: '设备序列号不能为空', trigger: 'blur' }]
308
+  equipmentName: [{ required: true, message: '设备名称不能为空', trigger: 'blur' }],
309
+  equipmentSerialNumber: [{ required: true, message: '设备序列号不能为空', trigger: 'blur' }]
265
 }
310
 }
266
 const selectedIds = ref([])
311
 const selectedIds = ref([])
267
 
312
 
268
-function handleQuery() {
313
+const upload = reactive({
314
+  open: false,
315
+  title: '',
316
+  isUploading: false,
317
+  updateSupport: 0,
318
+  headers: { Authorization: 'Bearer ' + getToken() },
319
+  url: import.meta.env.VITE_APP_BASE_API + '/equipment/ledger/importData'
320
+})
321
+
322
+function getList() {
269
   loading.value = true
323
   loading.value = true
270
-  setTimeout(() => {
324
+  listEquipLedger(queryParams).then(response => {
325
+    tableData.value = response.rows
326
+    total.value = response.total
271
     loading.value = false
327
     loading.value = false
272
-  }, 300)
328
+  })
329
+}
330
+
331
+function handleQuery() {
332
+  queryParams.pageNum = 1
333
+  getList()
273
 }
334
 }
274
 
335
 
275
 function resetQuery() {
336
 function resetQuery() {
@@ -280,7 +341,7 @@ function resetQuery() {
280
 function handleSelectionChange(selection) {
341
 function handleSelectionChange(selection) {
281
   selectedIds.value = selection.map(item => item.id)
342
   selectedIds.value = selection.map(item => item.id)
282
   single.value = selection.length !== 1
343
   single.value = selection.length !== 1
283
-  multiple.value = selection.length > 0
344
+  multiple.value = !selection.length
284
 }
345
 }
285
 
346
 
286
 function handleAdd() {
347
 function handleAdd() {
@@ -291,85 +352,194 @@ function handleAdd() {
291
 }
352
 }
292
 
353
 
293
 function handleEdit(row) {
354
 function handleEdit(row) {
294
-  Object.assign(form, row)
295
-  formDisabled.value = false
296
-  dialog.title = '编辑设备'
297
-  dialog.visible = true
355
+  getEquipLedger(row.id).then(response => {
356
+    Object.assign(form, response.data)
357
+    if (!form.equipmentInspectionRecordList || !Array.isArray(form.equipmentInspectionRecordList)) {
358
+      form.equipmentInspectionRecordList = []
359
+    }
360
+    formDisabled.value = false
361
+    dialog.title = '编辑设备'
362
+    dialog.visible = true
363
+  })
298
 }
364
 }
299
 
365
 
300
 function handleDetail(row) {
366
 function handleDetail(row) {
301
-  Object.assign(form, row)
302
-  formDisabled.value = true
303
-  dialog.title = '设备详情'
304
-  dialog.visible = true
367
+  getEquipLedger(row.id).then(response => {
368
+    Object.assign(form, response.data)
369
+    if (!form.equipmentInspectionRecordList || !Array.isArray(form.equipmentInspectionRecordList)) {
370
+      form.equipmentInspectionRecordList = []
371
+    }
372
+    formDisabled.value = true
373
+    dialog.title = '设备详情'
374
+    dialog.visible = true
375
+  })
305
 }
376
 }
306
 
377
 
307
 function handleDelete(row) {
378
 function handleDelete(row) {
308
-  ElMessage.success('删除成功')
379
+  proxy.$modal.confirm('是否确认删除该设备?').then(function () {
380
+    return delEquipLedger(row.id)
381
+  }).then(() => {
382
+    getList()
383
+    proxy.$modal.msgSuccess('删除成功')
384
+  }).catch(() => { })
309
 }
385
 }
310
 
386
 
311
 function handleBatchDelete() {
387
 function handleBatchDelete() {
312
-  ElMessage.success('批量删除成功')
388
+  proxy.$modal.confirm('是否确认删除选中的设备?').then(function () {
389
+    return delEquipLedger(selectedIds.value.join(','))
390
+  }).then(() => {
391
+    getList()
392
+    proxy.$modal.msgSuccess('删除成功')
393
+  }).catch(() => { })
313
 }
394
 }
314
 
395
 
315
 function handleExport() {
396
 function handleExport() {
316
-  ElMessage.success('导出功能开发中')
397
+  proxy.download('equipment/ledger/export', {
398
+    ...queryParams
399
+  }, `equipLedger_${new Date().getTime()}.xlsx`)
317
 }
400
 }
318
 
401
 
319
 function handleImport() {
402
 function handleImport() {
320
-  ElMessage.info('导入功能开发中')
403
+  upload.title = '设备台账导入'
404
+  upload.open = true
405
+}
406
+
407
+function importTemplate() {
408
+  proxy.download('equipment/ledger/importTemplate', {}, `equipLedger_template_${new Date().getTime()}.xlsx`)
321
 }
409
 }
322
 
410
 
323
 function resetForm() {
411
 function resetForm() {
324
   Object.assign(form, {
412
   Object.assign(form, {
325
-    equipName: '',
326
-    equipType: '',
327
-    equipCategory: '',
328
-    equipBrand: '',
329
-    equipModel: '',
330
-    serialNumber: '',
413
+    id: null,
414
+    equipmentName: '',
415
+    equipmentType: '',
416
+    equipmentCategory: '',
417
+    equipmentBrand: '',
418
+    equipmentModel: '',
419
+    equipmentSerialNumber: '',
331
     manufacturer: '',
420
     manufacturer: '',
332
-    factoryDate: '',
333
-    performanceDate: '',
334
-    enableDate: '',
421
+    manufacturingDate: '',
422
+    acceptanceDate: '',
423
+    commissioningDate: '',
335
     usageStatus: '1',
424
     usageStatus: '1',
336
-    retireDate: '',
337
-    installLocation: '',
338
-    checkDate: '',
339
-    checkCycle: 0,
340
-    checkExpireDate: '',
341
-    checkTeamLeader: '',
342
-    checkTeamMembers: '',
343
-    firstAcceptance: '',
344
-    checkRecords: []
425
+    scrappingDate: '',
426
+    installationLocation: '',
427
+    inspectionSelfCheckDate: '',
428
+    inspectionSelfCheckCycle: 0,
429
+    nextInspectionDueDate: '',
430
+    inspectionTeamLeaderId: '',
431
+    inspectionTeamMember1Id: '',
432
+    inspectionTeamMember2Id: '',
433
+    initialAcceptanceStatus: '',
434
+    baseAttachmentList: '',
435
+    equipmentInspectionRecordList: []
345
   })
436
   })
346
 }
437
 }
347
 
438
 
348
-function submitForm() {
349
-  formRef.value?.validate(valid => {
439
+async function submitForm() {
440
+  formRef.value?.validate(async valid => {
350
     if (valid) {
441
     if (valid) {
351
-      ElMessage.success('保存成功')
352
-      dialog.visible = false
353
-      handleQuery()
442
+      const submitData = { ...form }
443
+      
444
+      try {
445
+        if (submitData.inspectionTeamLeaderId) {
446
+          const leaderRes = await getUser(submitData.inspectionTeamLeaderId)
447
+          submitData.inspectionTeamLeaderName = leaderRes.data?.nickName || ''
448
+        }
449
+        if (submitData.inspectionTeamMember1Id) {
450
+          const member1Res = await getUser(submitData.inspectionTeamMember1Id)
451
+          submitData.inspectionTeamMember1Name = member1Res.data?.nickName || ''
452
+        }
453
+        if (submitData.inspectionTeamMember2Id) {
454
+          const member2Res = await getUser(submitData.inspectionTeamMember2Id)
455
+          submitData.inspectionTeamMember2Name = member2Res.data?.nickName || ''
456
+        }
457
+      } catch (error) {
458
+        console.error('获取用户信息失败:', error)
459
+      }
460
+
461
+      if (submitData.id != null) {
462
+        updateEquipLedger(submitData).then(response => {
463
+          proxy.$modal.msgSuccess('修改成功')
464
+          dialog.visible = false
465
+          getList()
466
+        })
467
+      } else {
468
+        addEquipLedger(submitData).then(response => {
469
+          proxy.$modal.msgSuccess('新增成功')
470
+          dialog.visible = false
471
+          getList()
472
+        })
473
+      }
354
     }
474
     }
355
   })
475
   })
356
 }
476
 }
357
 
477
 
358
 function addCheckRecord() {
478
 function addCheckRecord() {
359
-  form.checkRecords.push({
360
-    checkRecordDate: '',
361
-    checkTeam: '',
362
-    checkConclusion: '',
363
-    checkNature: ''
479
+  const teamIds = []
480
+  if (form.inspectionTeamLeaderId) {
481
+    teamIds.push(form.inspectionTeamLeaderId)
482
+  }
483
+  if (form.inspectionTeamMember1Id) {
484
+    teamIds.push(form.inspectionTeamMember1Id)
485
+  }
486
+  if (form.inspectionTeamMember2Id) {
487
+    teamIds.push(form.inspectionTeamMember2Id)
488
+  }
489
+  form.equipmentInspectionRecordList.push({
490
+    inspectionDate: '',
491
+    inspectionTeamIds: teamIds,
492
+    inspectionTeamName: '',
493
+    inspectionResult: '',
494
+    inspectionNature: ''
364
   })
495
   })
365
 }
496
 }
366
 
497
 
367
 function removeCheckRecord(index) {
498
 function removeCheckRecord(index) {
368
-  form.checkRecords.splice(index, 1)
499
+  form.equipmentInspectionRecordList.splice(index, 1)
500
+}
501
+
502
+function handleInspectionDateChange(row, index) {
503
+  if (row.inspectionDate) {
504
+    const recordDate = new Date(row.inspectionDate)
505
+    const checkDate = form.inspectionSelfCheckDate ? new Date(form.inspectionSelfCheckDate) : null
506
+    
507
+    if (!checkDate || recordDate > checkDate) {
508
+      form.inspectionSelfCheckDate = row.inspectionDate
509
+      calculateDueDate()
510
+    }
511
+  }
512
+}
513
+
514
+function calculateDueDate() {
515
+  if (form.inspectionSelfCheckDate && form.inspectionSelfCheckCycle && form.inspectionSelfCheckCycle > 0) {
516
+    const checkDate = new Date(form.inspectionSelfCheckDate)
517
+    checkDate.setMonth(checkDate.getMonth() + form.inspectionSelfCheckCycle)
518
+    const year = checkDate.getFullYear()
519
+    const month = String(checkDate.getMonth() + 1).padStart(2, '0')
520
+    const day = String(checkDate.getDate()).padStart(2, '0')
521
+    form.nextInspectionDueDate = `${year}-${month}-${day}`
522
+  }
523
+}
524
+
525
+function handleFileUploadProgress(event, file, fileList) {
526
+  upload.isUploading = true
527
+}
528
+
529
+function handleFileSuccess(response, file, fileList) {
530
+  upload.open = false
531
+  upload.isUploading = false
532
+  proxy.$refs['uploadRef'].handleRemove(file)
533
+  proxy.$alert('<div style="overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;">' + response.msg + '</div>', '导入结果', { dangerouslyUseHTMLString: true })
534
+  getList()
535
+}
536
+
537
+function submitFileForm() {
538
+  proxy.$refs['uploadRef'].submit()
369
 }
539
 }
370
 
540
 
371
 onMounted(() => {
541
 onMounted(() => {
372
-  handleQuery()
542
+  getList()
373
 })
543
 })
374
 </script>
544
 </script>
375
 
545
 
@@ -379,7 +549,6 @@ onMounted(() => {
379
 }
549
 }
380
 
550
 
381
 .filter-container {
551
 .filter-container {
382
-  margin-bottom: 20px;
383
 }
552
 }
384
 
553
 
385
 .operation-container {
554
 .operation-container {
@@ -391,4 +560,4 @@ onMounted(() => {
391
   flex-wrap: wrap;
560
   flex-wrap: wrap;
392
   gap: 10px;
561
   gap: 10px;
393
 }
562
 }
394
-</style>
563
+</style>