2 Commits

Autor SHA1 Mensagem Data
  liuzhuo 3b61133828 Merge branch 'develop' of http://123.206.9.27:3000/ShinSoft_Xxhsyb/Proj_SafePlat_Vue_Sgh5 into develop 1 semana atrás
  liuzhuo df53106a6d 事故案例库移动端完成 1 semana atrás
2 arquivos alterados com 253 adições e 27 exclusões
  1. 55
    7
      src/view/knowledge/accident.vue
  2. 198
    20
      src/view/knowledge/accidentList.vue

+ 55
- 7
src/view/knowledge/accident.vue Ver arquivo

24
                   <template #label>
24
                   <template #label>
25
                       <div>案例编号:{{ item.caseNumber }} </div>
25
                       <div>案例编号:{{ item.caseNumber }} </div>
26
                       <div>事故等级:{{ item.accidentLevel }}</div>
26
                       <div>事故等级:{{ item.accidentLevel }}</div>
27
-                      <div>下载量:{{ item.downloadCount }} 浏览量:{{item.viewCount}}</div>
27
+                      <div> 浏览量:{{item.viewCount}}</div>
28
 
28
 
29
 <!--                    <div style="width: 112px" :class="getStatusClass(item.isFinish)">
29
 <!--                    <div style="width: 112px" :class="getStatusClass(item.isFinish)">
30
                       类型:
30
                       类型:
42
             </template>
42
             </template>
43
 
43
 
44
             <template #right>
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
             </template>
46
             </template>
47
           </van-swipe-cell>
47
           </van-swipe-cell>
48
         </div>
48
         </div>
72
 const onClickLeft = () => {
72
 const onClickLeft = () => {
73
   history.back();
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
 const headers = ref({
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
 const switchIconState = (idx) => {
85
 const switchIconState = (idx) => {
81
   openStatus.value[idx] = !openStatus.value[idx]
86
   openStatus.value[idx] = !openStatus.value[idx]
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
   kz.value = true;
140
   kz.value = true;
129
   form.value = { ...row };
141
   form.value = { ...row };
130
   router.push({ path: "/accidentList",
142
   router.push({ path: "/accidentList",
152
   downloadCount:''
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
 const isRefreshing = ref(false);
192
 const isRefreshing = ref(false);
157
 const isLoading = ref(false);
193
 const isLoading = ref(false);
255
   handleSearch();
291
   handleSearch();
256
 });
292
 });
257
 
293
 
294
+
258
 const handleSearch = () => {
295
 const handleSearch = () => {
259
 /!*  currentPage.value = 1;
296
 /!*  currentPage.value = 1;
260
   isFinished.value = false;
297
   isFinished.value = false;
307
 };
344
 };
308
 
345
 
309
 const handleDetailLook = (row) => {
346
 const handleDetailLook = (row) => {
347
+
310
   form.value = { ...row };
348
   form.value = { ...row };
311
   proxy.$router.push({
349
   proxy.$router.push({
312
     name: 'taiZhang_detail',
350
     name: 'taiZhang_detail',
319
 const deleteData=ref({})
357
 const deleteData=ref({})
320
 
358
 
321
 const handleDelete = (item) => {
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
   deleteData.value=item
371
   deleteData.value=item
324
   const now = new Date();
372
   const now = new Date();
325
   const year = now.getFullYear();
373
   const year = now.getFullYear();

+ 198
- 20
src/view/knowledge/accidentList.vue Ver arquivo

109
 let planInfo = {}
109
 let planInfo = {}
110
 const  userName1=localStorage.getItem('userName');
110
 const  userName1=localStorage.getItem('userName');
111
 const isEdit = ref(route.query.mark === '1');
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
 const result=ref('')
114
 const result=ref('')
114
 const fromVue=ref({})
115
 const fromVue=ref({})
115
 if (route.query.mark) {
116
 if (route.query.mark) {
116
   planInfo = JSON.parse(route.query.mark)
117
   planInfo = JSON.parse(route.query.mark)
117
 }
118
 }
118
 console.log(planInfo);
119
 console.log(planInfo);
120
+// 新增模式
119
 if (planInfo==-1){
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
   console.log( result.value);
143
   console.log( result.value);
122
 }
144
 }
123
 
145
 
143
   console.log(planInfo);
165
   console.log(planInfo);
144
   title = '修改事故案例'
166
   title = '修改事故案例'
145
   fromVue.value= JSON.parse(route.query.data)
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
  const  whether=ref(false)
178
  const  whether=ref(false)
151
 
179
 
152
 const planLevelList1=ref([])
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
 const showActionSheet = ref(false)
256
 const showActionSheet = ref(false)
260
     message: '加载中',
360
     message: '加载中',
261
     forbidClick: true
361
     forbidClick: true
262
   })
362
   })
363
+  
364
+  fromVue.value.fileId = result.value
365
+
263
   var url = '/sgsafe/Manager/saveAccident';
366
   var url = '/sgsafe/Manager/saveAccident';
264
   const params = {
367
   const params = {
265
     json: JSON.stringify(fromVue.value)
368
     json: JSON.stringify(fromVue.value)
306
   const month = today.getMonth() + 1 // 月份从 0 开始
409
   const month = today.getMonth() + 1 // 月份从 0 开始
307
   const day = today.getDate()
410
   const day = today.getDate()
308
   currentDate.value = [year, month, day]
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
   //selectedDateText.value = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`
430
   //selectedDateText.value = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`
310
   getDicList()
431
   getDicList()
311
 })
432
 })
361
 <!--          :rules="[{required: true, message: '请输入文件编号'}]"-->
482
 <!--          :rules="[{required: true, message: '请输入文件编号'}]"-->
362
 <!--        />-->
483
 <!--        />-->
363
         <van-field
484
         <van-field
364
-            v-model="generatedCode"
485
+            v-model="fromVue.caseNumber"
365
         label="案例编号"
486
         label="案例编号"
366
         name="caseNumber"
487
         name="caseNumber"
367
-            :readonly="isCaseSubmitted"
488
+            readonly
368
         :rules="[{required: true, message: '编号生成失败,请点击“重新生成”'}]"
489
         :rules="[{required: true, message: '编号生成失败,请点击“重新生成”'}]"
369
         />
490
         />
370
 
491
 
372
           v-model="fromVue.caseTitle"
493
           v-model="fromVue.caseTitle"
373
           label="案例标题"
494
           label="案例标题"
374
           name="caseTitle"
495
           name="caseTitle"
496
+          :readonly="isCaseSubmitted"
375
           required
497
           required
376
           placeholder="请输入案例标题"
498
           placeholder="请输入案例标题"
377
-          :rules="[{required: true, message: '请输入文件名称'}]"
499
+          :rules="[{required: true, message: '请输入标题名称'}]"
378
         />
500
         />
379
 
501
 
380
         <van-field
502
         <van-field
382
           readonly
504
           readonly
383
           label="案例来源"
505
           label="案例来源"
384
           name="caseSource"
506
           name="caseSource"
385
-          required
386
-          @click="caseSourceFlag = true"
507
+          :readonly="isCaseSubmitted"
508
+          @click="!isCaseSubmitted && (caseSourceFlag = true)"
387
         />
509
         />
388
         <van-field
510
         <van-field
389
           readonly
511
           readonly
390
           v-model="fromVue.accidentLevel"
512
           v-model="fromVue.accidentLevel"
391
           label="事故等级"
513
           label="事故等级"
392
           name="accidentLevel"
514
           name="accidentLevel"
393
-          @click="accidentLevelFlag = true"
515
+          :readonly="isCaseSubmitted"
516
+          @click="!isCaseSubmitted && (accidentLevelFlag = true)"
394
         />
517
         />
395
 
518
 
396
-
397
-
398
         <van-field
519
         <van-field
399
             v-model="fromVue.accidentDept"
520
             v-model="fromVue.accidentDept"
400
             label="事故单位"
521
             label="事故单位"
401
             name="accidentDept"
522
             name="accidentDept"
402
-            required
403
             placeholder="请输入事故单位"
523
             placeholder="请输入事故单位"
524
+            :readonly="isCaseSubmitted"
404
             :rules="[{required: true, message: '请输入事故单位'}]"
525
             :rules="[{required: true, message: '请输入事故单位'}]"
405
         />
526
         />
406
 
527
 
408
             v-model="fromVue.accidentLocation"
529
             v-model="fromVue.accidentLocation"
409
             label="事故地点"
530
             label="事故地点"
410
             name="accidentLocation"
531
             name="accidentLocation"
411
-            required
532
+            :readonly="isCaseSubmitted"
412
             placeholder="请输入事故地点"
533
             placeholder="请输入事故地点"
413
             :rules="[{required: true, message: '请输入事故地点'}]"
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
         <van-field
599
         <van-field
420
             v-model="fromVue.casualtyCount"
600
             v-model="fromVue.casualtyCount"
421
             label="事故造成后果"
601
             label="事故造成后果"
422
             name="casualtyCount"
602
             name="casualtyCount"
423
-            required
424
             rows="1"
603
             rows="1"
425
             autosize
604
             autosize
426
             type="textarea"
605
             type="textarea"
427
             placeholder="请输入事故造成后果"
606
             placeholder="请输入事故造成后果"
607
+            :readonly="isCaseSubmitted"
428
             :rules="[{required: true, message: '请输入事故造成后果'}]"
608
             :rules="[{required: true, message: '请输入事故造成后果'}]"
429
         />
609
         />
430
         <van-field
610
         <van-field
431
             v-model="fromVue.accidentSummary"
611
             v-model="fromVue.accidentSummary"
432
             label="事故简要经过"
612
             label="事故简要经过"
433
             name="accidentSummary"
613
             name="accidentSummary"
434
-            required
435
             rows="3"
614
             rows="3"
436
             autosize
615
             autosize
437
             type="textarea"
616
             type="textarea"
438
             placeholder="请输入事故简要经过"
617
             placeholder="请输入事故简要经过"
618
+            :readonly="isCaseSubmitted"
439
             :rules="[{required: true, message: '请输入事故简要经过'}]"
619
             :rules="[{required: true, message: '请输入事故简要经过'}]"
440
         />
620
         />
441
         <van-field
621
         <van-field
442
             v-model="fromVue.preventiveMeasures"
622
             v-model="fromVue.preventiveMeasures"
443
             label="防范与整改措施"
623
             label="防范与整改措施"
444
             name="preventiveMeasures"
624
             name="preventiveMeasures"
445
-            required
446
             rows="3"
625
             rows="3"
447
             autosize
626
             autosize
448
             type="textarea"
627
             type="textarea"
449
             placeholder="请输入防范与整改措施"
628
             placeholder="请输入防范与整改措施"
629
+            :readonly="isCaseSubmitted"
450
             :rules="[{required: true, message: '请输入防范与整改措施'}]"
630
             :rules="[{required: true, message: '请输入防范与整改措施'}]"
451
         />
631
         />
452
 
632
 
453
-
454
-
455
         <van-field label="附件上传" >
633
         <van-field label="附件上传" >
456
           <template #input>
634
           <template #input>
457
             <AttachmentS3 :f-id="result" />
635
             <AttachmentS3 :f-id="result" />
458
           </template>
636
           </template>
459
         </van-field>
637
         </van-field>
460
         <div style="margin: 16px;">
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
             {{ isEdit ? '保存' : '提交' }}
640
             {{ isEdit ? '保存' : '提交' }}
463
           </van-button>
641
           </van-button>
464
         </div>
642
         </div>

Carregando…
Cancelar
Salvar