2 Commits

Author SHA1 Message Date
  liuzhuo 3b61133828 Merge branch 'develop' of http://123.206.9.27:3000/ShinSoft_Xxhsyb/Proj_SafePlat_Vue_Sgh5 into develop 1 week ago
  liuzhuo df53106a6d 事故案例库移动端完成 1 week ago
2 changed files with 253 additions and 27 deletions
  1. 55
    7
      src/view/knowledge/accident.vue
  2. 198
    20
      src/view/knowledge/accidentList.vue

+ 55
- 7
src/view/knowledge/accident.vue View File

@@ -24,7 +24,7 @@
24 24
                   <template #label>
25 25
                       <div>案例编号:{{ item.caseNumber }} </div>
26 26
                       <div>事故等级:{{ item.accidentLevel }}</div>
27
-                      <div>下载量:{{ item.downloadCount }} 浏览量:{{item.viewCount}}</div>
27
+                      <div> 浏览量:{{item.viewCount}}</div>
28 28
 
29 29
 <!--                    <div style="width: 112px" :class="getStatusClass(item.isFinish)">
30 30
                       类型:
@@ -42,7 +42,7 @@
42 42
             </template>
43 43
 
44 44
             <template #right>
45
-              <van-button  square class="delete-button" text="删除" @click="handleDelete(item)" />
45
+              <van-button v-if="item.canDelete" square class="delete-button" text="删除" @click="handleDelete(item)" />
46 46
             </template>
47 47
           </van-swipe-cell>
48 48
         </div>
@@ -72,10 +72,15 @@ const { proxy } = getCurrentInstance();
72 72
 const onClickLeft = () => {
73 73
   history.back();
74 74
 };
75
+// const headers = ref({
76
+//   token: localStorage.getItem('token'),
77
+//   userId: localStorage.getItem('userId'),
78
+//   dept: JSON.parse(localStorage.getItem('dept'))[0].deptCode
79
+// });
75 80
 const headers = ref({
76
-  token: localStorage.getItem('token'),
77
-  userId: localStorage.getItem('userId'),
78
-  dept: JSON.parse(localStorage.getItem('dept'))[0].deptCode
81
+  token: localStorage.getItem('token') || '',
82
+  userId: localStorage.getItem('userId') || '', // 防止 null/undefined
83
+  dept: JSON.parse(localStorage.getItem('dept'))?.[0]?.deptCode || ''
79 84
 });
80 85
 const switchIconState = (idx) => {
81 86
   openStatus.value[idx] = !openStatus.value[idx]
@@ -123,8 +128,15 @@ const goaddPeo = (item) => {
123 128
   })
124 129
 }
125 130
 
126
-const edits = (row) => {
127
-  const isOwner = String(row.addId) === currentUserId;
131
+const edits = async (row) => {
132
+  const currentUserId = localStorage.getItem('userId');
133
+  const addId = row.addId;
134
+
135
+  const isOwner = String(addId).trim().toLowerCase() === String(currentUserId).trim().toLowerCase();
136
+
137
+  // 更新浏览量
138
+  await updateViewCount(row);
139
+
128 140
   kz.value = true;
129 141
   form.value = { ...row };
130 142
   router.push({ path: "/accidentList",
@@ -152,6 +164,30 @@ const form = ref({
152 164
   downloadCount:''
153 165
 });
154 166
 
167
+const updateViewCount = async (item) => {
168
+  try {
169
+    const payload = { ...item };
170
+    // 将浏览量 +1
171
+    payload.viewCount = String((Number(payload.viewCount) || 0) + 1);
172
+
173
+    const url = '/sgsafe/Manager/saveAccident';
174
+    const param = {
175
+      json: JSON.stringify(payload)
176
+    };
177
+
178
+    const response = await proxy.$axios.post(url, param);
179
+    if (response.data.code === '0' || response.data.code === 0) {
180
+      // 更新成功后,更新本地列表中的浏览量显示
181
+      const index = resultData.value.findIndex(data => data.id === item.id);
182
+      if (index !== -1) {
183
+        resultData.value[index].viewCount = payload.viewCount;
184
+      }
185
+    }
186
+  } catch (error) {
187
+    console.error('更新浏览量失败:', error);
188
+    // 即使更新失败也不阻塞页面跳转
189
+  }
190
+};
155 191
 
156 192
 const isRefreshing = ref(false);
157 193
 const isLoading = ref(false);
@@ -255,6 +291,7 @@ const basicReset = () => {
255 291
   handleSearch();
256 292
 });
257 293
 
294
+
258 295
 const handleSearch = () => {
259 296
 /!*  currentPage.value = 1;
260 297
   isFinished.value = false;
@@ -307,6 +344,7 @@ const regenerateCode = () => {
307 344
 };
308 345
 
309 346
 const handleDetailLook = (row) => {
347
+
310 348
   form.value = { ...row };
311 349
   proxy.$router.push({
312 350
     name: 'taiZhang_detail',
@@ -319,7 +357,17 @@ const handleDetailLook = (row) => {
319 357
 const deleteData=ref({})
320 358
 
321 359
 const handleDelete = (item) => {
360
+  const currentUserId = headers.value.userId;
361
+  const addId = item.addId;
322 362
 
363
+  if (!currentUserId || !addId || String(addId).trim() !== String(currentUserId).trim()) {
364
+    showToast({
365
+      type: 'warning',
366
+      message: '无权限删除!只能删除自己添加的案例。'
367
+    });
368
+    return;
369
+  }
370
+  
323 371
   deleteData.value=item
324 372
   const now = new Date();
325 373
   const year = now.getFullYear();

+ 198
- 20
src/view/knowledge/accidentList.vue View File

@@ -109,15 +109,37 @@ const route = useRoute()
109 109
 let planInfo = {}
110 110
 const  userName1=localStorage.getItem('userName');
111 111
 const isEdit = ref(route.query.mark === '1');
112
-
112
+const isReadOnly = ref(route.query.readOnly === 'true');
113
+const isCaseSubmitted = computed(() => isReadOnly.value && isEdit.value);
113 114
 const result=ref('')
114 115
 const fromVue=ref({})
115 116
 if (route.query.mark) {
116 117
   planInfo = JSON.parse(route.query.mark)
117 118
 }
118 119
 console.log(planInfo);
120
+// 新增模式
119 121
 if (planInfo==-1){
120
-  result.value=guid()
122
+  const caseNumber = generateCode();
123
+  const fileId = ref()
124
+  result.value= caseNumber
125
+  //初始化 fromVue
126
+  fromVue.value = {
127
+    caseNumber: caseNumber,
128
+    caseTitle: '',
129
+    caseSource: '',
130
+    accidentLevel: '',
131
+    accidentDept: '',
132
+    accidentLocation: '',
133
+    accidentTime: '',
134
+    accidentType: '',
135
+    accidentTags: '',
136
+    casualtyCount: '',
137
+    accidentSummary: '',
138
+    preventiveMeasures: '',
139
+    fileId: fileId,
140
+    viewCount: '0',
141
+    downloadCount: '0'
142
+  };
121 143
   console.log( result.value);
122 144
 }
123 145
 
@@ -143,14 +165,92 @@ if (planInfo==1) {
143 165
   console.log(planInfo);
144 166
   title = '修改事故案例'
145 167
   fromVue.value= JSON.parse(route.query.data)
168
+  if (!fromVue.value.fileId) {
169
+    const newFileId = guid();
170
+    fromVue.value.fileId = newFileId;
171
+    result.value = newFileId;
172
+  } else {
173
+    result.value = fromVue.value.fileId;
174
+  }
146 175
 
147
-  result.value=fromVue.value.fileId
148
-  console.log(result.value);
176
+  console.log('编辑模式 - fileId:', result.value);
149 177
 }
150 178
  const  whether=ref(false)
151 179
 
152 180
 const planLevelList1=ref([])
153 181
 
182
+const onConfirmDatetime = () => {
183
+  const year = currentDate.value[0];
184
+  const month = currentDate.value[1].toString().padStart(2, '0');
185
+  const day = currentDate.value[2].toString().padStart(2, '0');
186
+  const hours = currentTime.value[0].toString().padStart(2, '0');
187
+  const minutes = currentTime.value[1].toString().padStart(2, '0');
188
+  const seconds = currentTime.value[2].toString().padStart(2, '0');
189
+
190
+  fromVue.value.accidentTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
191
+  showDatetimePicker.value = false;
192
+  dateOrTime.value = false;
193
+};
194
+
195
+
196
+const showDatetimePicker = ref(false);
197
+const currentTime = ref();
198
+const minDate = ref();
199
+const maxDate = ref();
200
+
201
+const dateOrTime = ref(false);
202
+const onDateConfirm = () => {
203
+  // 日期选择确认后的处理
204
+  dateOrTime.value = true;
205
+};
206
+const resetDatetime = () => {
207
+  dateOrTime.value = false;
208
+
209
+  // 初始化日期和时间
210
+  if (fromVue.value.accidentTime) {
211
+    const dt = new Date(fromVue.value.accidentTime);
212
+    currentDate.value = [dt.getFullYear(), dt.getMonth() + 1, dt.getDate()];
213
+    currentTime.value = [
214
+      String(dt.getHours()).padStart(2, '0'),
215
+      String(dt.getMinutes()).padStart(2, '0'),
216
+      String(dt.getSeconds()).padStart(2, '0')
217
+    ];
218
+  } else {
219
+    const now = new Date();
220
+    currentDate.value = [now.getFullYear(), now.getMonth() + 1, now.getDate()];
221
+    currentTime.value = [
222
+      String(now.getHours()).padStart(2, '0'),
223
+      String(now.getMinutes()).padStart(2, '0'),
224
+      String(now.getSeconds()).padStart(2, '0')
225
+    ];
226
+  }
227
+};
228
+const cancelDatePicker = () => {
229
+  showDatetimePicker.value = false;
230
+  resetDatetime();
231
+};
232
+
233
+// 时间选择器取消
234
+const cancelTimePicker = () => {
235
+  resetDatetime();
236
+  // 重置为当前时间或从表单获取时间
237
+  if (fromVue.value.accidentTime) {
238
+    const dt = new Date(fromVue.value.accidentTime);
239
+    currentTime.value = [
240
+      String(dt.getHours()).padStart(2, '0'),
241
+      String(dt.getMinutes()).padStart(2, '0'),
242
+      String(dt.getSeconds()).padStart(2, '0')
243
+    ];
244
+  } else {
245
+    const now = new Date();
246
+    currentTime.value = [
247
+      String(now.getHours()).padStart(2, '0'),
248
+      String(now.getMinutes()).padStart(2, '0'),
249
+      String(now.getSeconds()).padStart(2, '0')
250
+    ];
251
+  }
252
+};
253
+
154 254
 
155 255
 /* 下拉框 */
156 256
 const showActionSheet = ref(false)
@@ -260,6 +360,9 @@ const addEmergencyDrillPlan = async () => {
260 360
     message: '加载中',
261 361
     forbidClick: true
262 362
   })
363
+  
364
+  fromVue.value.fileId = result.value
365
+
263 366
   var url = '/sgsafe/Manager/saveAccident';
264 367
   const params = {
265 368
     json: JSON.stringify(fromVue.value)
@@ -306,6 +409,24 @@ onMounted(() => {
306 409
   const month = today.getMonth() + 1 // 月份从 0 开始
307 410
   const day = today.getDate()
308 411
   currentDate.value = [year, month, day]
412
+  // 初始化时间
413
+  currentTime.value = [today.getHours(), today.getMinutes(), today.getSeconds()];
414
+  // 如果是编辑模式且有已有的事故时间,解析并初始化
415
+  if (isEdit.value && fromVue.value.accidentTime) {
416
+    try {
417
+      // 解析格式如 "2025-01-15 14:30:00" 的时间字符串
418
+      const timeStr = fromVue.value.accidentTime;
419
+      const [datePart, timePart] = timeStr.split(' ');
420
+      if (datePart && timePart) {
421
+        const [year, month, day] = datePart.split('-').map(Number);
422
+        const [hours, minutes, seconds] = timePart.split(':').map(Number);
423
+        currentDate.value = [year, month, day];
424
+        currentTime.value = [hours || 0, minutes || 0, seconds || 0];
425
+      }
426
+    } catch (error) {
427
+      console.error('解析事故时间失败:', error);
428
+    }
429
+  }
309 430
   //selectedDateText.value = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`
310 431
   getDicList()
311 432
 })
@@ -361,10 +482,10 @@ const onAccidentLevelConfirm = ({ selectedOptions }) => {
361 482
 <!--          :rules="[{required: true, message: '请输入文件编号'}]"-->
362 483
 <!--        />-->
363 484
         <van-field
364
-            v-model="generatedCode"
485
+            v-model="fromVue.caseNumber"
365 486
         label="案例编号"
366 487
         name="caseNumber"
367
-            :readonly="isCaseSubmitted"
488
+            readonly
368 489
         :rules="[{required: true, message: '编号生成失败,请点击“重新生成”'}]"
369 490
         />
370 491
 
@@ -372,9 +493,10 @@ const onAccidentLevelConfirm = ({ selectedOptions }) => {
372 493
           v-model="fromVue.caseTitle"
373 494
           label="案例标题"
374 495
           name="caseTitle"
496
+          :readonly="isCaseSubmitted"
375 497
           required
376 498
           placeholder="请输入案例标题"
377
-          :rules="[{required: true, message: '请输入文件名称'}]"
499
+          :rules="[{required: true, message: '请输入标题名称'}]"
378 500
         />
379 501
 
380 502
         <van-field
@@ -382,25 +504,24 @@ const onAccidentLevelConfirm = ({ selectedOptions }) => {
382 504
           readonly
383 505
           label="案例来源"
384 506
           name="caseSource"
385
-          required
386
-          @click="caseSourceFlag = true"
507
+          :readonly="isCaseSubmitted"
508
+          @click="!isCaseSubmitted && (caseSourceFlag = true)"
387 509
         />
388 510
         <van-field
389 511
           readonly
390 512
           v-model="fromVue.accidentLevel"
391 513
           label="事故等级"
392 514
           name="accidentLevel"
393
-          @click="accidentLevelFlag = true"
515
+          :readonly="isCaseSubmitted"
516
+          @click="!isCaseSubmitted && (accidentLevelFlag = true)"
394 517
         />
395 518
 
396
-
397
-
398 519
         <van-field
399 520
             v-model="fromVue.accidentDept"
400 521
             label="事故单位"
401 522
             name="accidentDept"
402
-            required
403 523
             placeholder="请输入事故单位"
524
+            :readonly="isCaseSubmitted"
404 525
             :rules="[{required: true, message: '请输入事故单位'}]"
405 526
         />
406 527
 
@@ -408,57 +529,114 @@ const onAccidentLevelConfirm = ({ selectedOptions }) => {
408 529
             v-model="fromVue.accidentLocation"
409 530
             label="事故地点"
410 531
             name="accidentLocation"
411
-            required
532
+            :readonly="isCaseSubmitted"
412 533
             placeholder="请输入事故地点"
413 534
             :rules="[{required: true, message: '请输入事故地点'}]"
414 535
         />
415 536
 
416 537
 <!--        //时间-->
538
+        <van-field
539
+            v-model="fromVue.accidentTime"
540
+            is-link
541
+            readonly
542
+            name="datetime"
543
+            label="发生时间"
544
+            :colon="true"
545
+            placeholder="点击选择日期和时间"
546
+            @click="showDatetimePicker = !isCaseSubmitted"
547
+            :rules="[{ required:true, message: '请选择内容' }]"
548
+        />
417 549
 
550
+        <van-popup
551
+            v-model:show="showDatetimePicker"
552
+            position="bottom"
553
+            round
554
+            style="max-height: 50vh;"
555
+        >
556
+          <van-date-picker
557
+              v-if="!dateOrTime"
558
+              v-model="currentDate"
559
+              title="选择日期"
560
+              :min-date="minDate"
561
+              :max-date="maxDate"
562
+              @confirm="onDateConfirm"
563
+              @cancel="cancelDatePicker"
564
+          >
565
+            <template #confirm>
566
+              <van-button type="primary" @click="onDateConfirm">下一步</van-button>
567
+            </template>
568
+            <template #cancel>
569
+              <van-button type="danger" @click="cancelDatePicker">取消</van-button>
570
+            </template>
571
+          </van-date-picker>
572
+
573
+          <van-time-picker
574
+              v-if="dateOrTime"
575
+              v-model="currentTime"
576
+              title="选择时间"
577
+              :columns-type="['hour', 'minute', 'second']"
578
+              @confirm="onConfirmDatetime"
579
+              @cancel="cancelTimePicker"
580
+          >
581
+            <template #confirm>
582
+              <van-button type="primary" @click="onConfirmDatetime">确定</van-button>
583
+            </template>
584
+            <template #cancel>
585
+              <van-button type="danger" @click="cancelTimePicker">取消</van-button>
586
+            </template>
587
+          </van-time-picker>
588
+        </van-popup>
418 589
 <!--        // 标签-->
590
+
591
+        <van-field
592
+            v-model="fromVue.accidentTags"
593
+            label="关键词/标签"
594
+            name="accidentTags"
595
+            :readonly="isCaseSubmitted"
596
+            :rules="[{required: true, message: '请输入事故关键词/标签”'}]"
597
+        />
598
+
419 599
         <van-field
420 600
             v-model="fromVue.casualtyCount"
421 601
             label="事故造成后果"
422 602
             name="casualtyCount"
423
-            required
424 603
             rows="1"
425 604
             autosize
426 605
             type="textarea"
427 606
             placeholder="请输入事故造成后果"
607
+            :readonly="isCaseSubmitted"
428 608
             :rules="[{required: true, message: '请输入事故造成后果'}]"
429 609
         />
430 610
         <van-field
431 611
             v-model="fromVue.accidentSummary"
432 612
             label="事故简要经过"
433 613
             name="accidentSummary"
434
-            required
435 614
             rows="3"
436 615
             autosize
437 616
             type="textarea"
438 617
             placeholder="请输入事故简要经过"
618
+            :readonly="isCaseSubmitted"
439 619
             :rules="[{required: true, message: '请输入事故简要经过'}]"
440 620
         />
441 621
         <van-field
442 622
             v-model="fromVue.preventiveMeasures"
443 623
             label="防范与整改措施"
444 624
             name="preventiveMeasures"
445
-            required
446 625
             rows="3"
447 626
             autosize
448 627
             type="textarea"
449 628
             placeholder="请输入防范与整改措施"
629
+            :readonly="isCaseSubmitted"
450 630
             :rules="[{required: true, message: '请输入防范与整改措施'}]"
451 631
         />
452 632
 
453
-
454
-
455 633
         <van-field label="附件上传" >
456 634
           <template #input>
457 635
             <AttachmentS3 :f-id="result" />
458 636
           </template>
459 637
         </van-field>
460 638
         <div style="margin: 16px;">
461
-          <van-button round block type="primary" native-type="submit">
639
+          <van-button v-if="!isReadOnly" round block type="primary" native-type="submit">
462 640
             {{ isEdit ? '保存' : '提交' }}
463 641
           </van-button>
464 642
         </div>

Loading…
Cancel
Save