yusheng 3 godzin temu
rodzic
commit
35942624b8

+ 116 - 109
components/myCard.vue

@@ -1,7 +1,7 @@
 <template>
   <view class="card_container">
     <view class="card_box">
-      <!-- 标题区域 - 独立出来,宽度100% -->
+      <!-- 标题区域 -->
       <view class="header_box" v-if="title">
         <view class="title_left">
           <view class="round" v-if="index">{{ index }}</view>
@@ -9,10 +9,38 @@
             title
           }}</view>
         </view>
-        <!-- 状态 - 固定在右上角 -->
+        <!-- 状态标签 -->
         <view class="status-tag" v-if="status">{{ status }}</view>
+        <!-- 单选/多选控件 -->
+        <view class="select-tag" v-if="showRadio" @click.stop>
+          <!-- 单选模式:使用 u-radio-group(每个卡片独立,互斥) -->
+          <u-radio-group
+            v-if="selectionMode === 'single'"
+            v-model="radioValueModel"
+            placement="row"
+            @change="handleRadioChange"
+          >
+            <u-radio
+              :name="item.id"
+              :iconSize="44"
+              activeColor="#3c9cff"
+              :labelSize="0"
+            ></u-radio>
+          </u-radio-group>
+          <!-- 多选模式:使用独立 u-checkbox,由父组件控制选中状态 -->
+          <u-checkbox
+            v-else
+            :name="item.id"
+            :checked="isChecked"
+            :iconSize="44"
+            activeColor="#3c9cff"
+            :labelSize="0"
+            @change="handleCheckboxChange"
+          ></u-checkbox>
+        </view>
       </view>
 
+      <!-- 内容区域(与原代码相同,省略...) -->
       <view class="item_box rx-bc" v-for="(_item, i) in columns" :key="i">
         <template v-for="val in _item">
           <view
@@ -22,7 +50,6 @@
             :key="val.prop"
             v-if="!val.isNone"
           >
-            <!-- 操作行 -->
             <view class="item_one rx-sc" v-if="val.type == 'action'">
               <view class="lable">{{ val.label }}</view>
               <view class="text" style="flex-wrap: wrap">
@@ -40,25 +67,22 @@
                 </template>
               </view>
             </view>
-
-            <!-- 普通信息行 -->
             <view class="item_one rx-sc kk" v-else>
               <view class="lable">{{ val.label }}</view>
               <view class="text" :class="val.valueClass" v-if="val.formatter">{{
-                val.formatter(item) || ""
+                val.formatter(item) || ''
               }}</view>
               <view class="text" :class="val.valueClass" v-else-if="val.slot">
                 <slot :name="val.slot"></slot>
               </view>
               <view class="text" :class="val.valueClass" v-else>{{
-                item[val.prop] || ""
+                item[val.prop] || ''
               }}</view>
             </view>
           </view>
         </template>
       </view>
 
-      <!-- 查看详情 -->
       <view class="footer-link" v-if="showDetail" @click="goDetail">
         <text>查看详情</text>
         <u-icon name="arrow-right" size="24" color="#999999"></u-icon>
@@ -70,31 +94,17 @@
 <script>
 export default {
   props: {
-    btnList: {
-      type: Array,
-      default: () => [],
-    },
-    item: {
-      type: Object,
-      default: () => ({}),
-    },
-    columns: {
-      type: Array,
-      default: () => [],
-    },
-    title: {
-      type: String,
-      default: "",
-    },
-    status: {
-      type: String,
-      default: "",
-    },
-    index: "",
-    showDetail: {
-      type: Boolean,
-      default: true,
-    },
+    btnList: { type: Array, default: () => [] },
+    item: { type: Object, default: () => ({}) },
+    columns: { type: Array, default: () => [] },
+    title: { type: String, default: '' },
+    status: { type: String, default: '' },
+    index: { type: [String, Number], default: '' },
+    showDetail: { type: Boolean, default: true },
+    showRadio: { type: Boolean, default: false },
+    radioValue: { type: [String, Number], default: null },
+    selectionMode: { type: String, default: 'single' }, // 'single' or 'multiple'
+    checkboxValue: { type: Array, default: () => [] },   // 父组件传入的选中ID数组
   },
   computed: {
     judge() {
@@ -118,38 +128,60 @@ export default {
         }
       };
     },
-  },
-  data() {
-    return {};
+    // 单选模式下的绑定值
+    radioValueModel: {
+      get() {
+        return this.radioValue;
+      },
+      set(val) {
+        if (val === this.item.id) {
+          this.$emit('radioChange', this.item);
+        }
+      },
+    },
+    // 多选模式下的选中状态(根据 checkboxValue 数组判断)
+    isChecked() {
+      return this.checkboxValue.includes(this.item.id);
+    },
   },
   methods: {
     action(item) {
       if (item.type == 1) {
         uni.navigateTo({
-          url: item.pageUrl + "?id=" + this.item.id + (item.query || ""),
+          url: item.pageUrl + '?id=' + this.item.id + (item.query || ''),
         });
       } else {
         this.$emit(item.apiName);
       }
     },
     goDetail() {
-      this.$emit("goDetail", this.item);
+      this.$emit('goDetail', this.item);
+    },
+    handleRadioChange(val) {
+      if (val === this.item.id) {
+        this.$emit('radioChange', this.item);
+      }
+    },
+    // 多选:点击 checkbox 时,通知父组件变更
+    handleCheckboxChange(e) {
+      this.$emit('checkboxChange', {
+        checked: e,        // e 为 boolean,表示当前 checkbox 是否被选中
+        item: this.item,
+      });
     },
   },
 };
 </script>
-
 <style lang="scss" scoped>
 .card_container {
-  padding: 20rpx 24rpx;
-  background: #f5f5f5;
+  padding: 16rpx 0;
 }
 
 .card_box {
   background: #ffffff;
-  border-radius: 16rpx;
-  padding: 28rpx;
-  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
+  border-radius: 24rpx;
+  padding: 24rpx;
+  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
   position: relative;
 
   .rx-bc {
@@ -158,7 +190,7 @@ export default {
     flex-flow: row wrap;
 
     > view {
-      margin-top: 28rpx;
+      margin-top: 24rpx;
 
       &:first-child,
       &:nth-child(2) {
@@ -172,19 +204,19 @@ export default {
     align-items: flex-start;
   }
 
-  // 头部样式
   .header_box {
     display: flex;
     justify-content: space-between;
     align-items: center;
     width: 100%;
     position: relative;
-    background: linear-gradient(135deg, #e8f5e9 0%, #f1f8e9 100%);
+    background: linear-gradient(135deg, #eef5ff 0%, #f5f9ff 100%);
     padding: 20rpx 24rpx;
-    border-radius: 12rpx 12rpx 0 0;
-    margin: -28rpx -28rpx 28rpx -28rpx;
-    width: calc(100% + 56rpx);
+    border-radius: 20rpx 20rpx 0 0;
+    margin: -24rpx -24rpx 24rpx -24rpx;
+    width: calc(100% + 48rpx);
     box-sizing: border-box;
+
     .round {
       width: 44rpx;
       height: 44rpx;
@@ -199,8 +231,8 @@ export default {
     }
 
     .orderId {
-      color: #333333;
-      font-size: 32rpx;
+      color: #1f2b3c;
+      font-size: 30rpx;
       font-weight: 600;
       white-space: nowrap;
       overflow: hidden;
@@ -211,17 +243,16 @@ export default {
       display: flex;
       align-items: center;
       flex: 1;
-      padding-right: 140rpx;
+      padding-right: 120rpx;
       overflow: hidden;
     }
 
-    // 状态标签
     .status-tag {
       background: #e3f2fd;
       color: #2196f3;
       font-size: 24rpx;
-      padding: 8rpx 20rpx;
-      border-radius: 24rpx;
+      padding: 6rpx 20rpx;
+      border-radius: 30rpx;
       font-weight: 500;
       position: absolute;
       top: 50%;
@@ -229,6 +260,24 @@ export default {
       right: 24rpx;
       z-index: 1;
     }
+
+    .select-tag {
+      position: absolute;
+      top: 50%;
+      transform: translateY(-50%);
+      right: 24rpx;
+      z-index: 2;
+      background: transparent;
+
+      /deep/ .u-radio-group,
+      /deep/ .u-checkbox-group {
+        .u-radio,
+        .u-checkbox {
+          padding: 0;
+          margin-right: 0;
+        }
+      }
+    }
   }
 
   .item_box {
@@ -266,14 +315,14 @@ export default {
       align-items: flex-start;
 
       .lable {
-        color: #666666;
+        color: #8e9aae;
         flex-shrink: 0;
-        margin-right: 12rpx;
-        font-size: 28rpx;
+        margin-right: 16rpx;
+        font-size: 26rpx;
       }
 
       .text {
-        color: #000;
+        color: #1f2b3c;
         font-size: 28rpx;
         flex: 1;
         white-space: nowrap;
@@ -281,17 +330,12 @@ export default {
         text-overflow: ellipsis;
         min-width: 0;
 
-        // 高亮值样式
         &.highlight {
           color: #4caf50;
         }
       }
     }
 
-    .gylx {
-      color: $theme-color;
-    }
-
     .perce50 {
       width: 50%;
       box-sizing: border-box;
@@ -302,6 +346,7 @@ export default {
         padding-left: 20rpx;
       }
     }
+
     .perce100 {
       width: 100%;
     }
@@ -313,59 +358,21 @@ export default {
     }
   }
 
-  // 底部查看详情
   .footer-link {
     display: flex;
     justify-content: center;
     align-items: center;
-    margin-top: 28rpx;
-    padding-top: 24rpx;
-    border-top: 1rpx solid #f0f0f0;
-    color: #666666;
+    margin-top: 24rpx;
+    padding-top: 20rpx;
+    border-top: 2rpx solid #f0f2f5;
+    color: #8e9aae;
     font-size: 28rpx;
     cursor: pointer;
+    gap: 8rpx;
 
     &:active {
       opacity: 0.7;
     }
   }
 }
-
-/deep/.u-input {
-  padding: 0 !important;
-  height: 44rpx !important;
-  font-size: 26rpx !important;
-}
-
-/deep/.u-input__content__field-wrapper__field {
-  font-size: 26rpx !important;
-}
-
-/deep/.uni-date-editor--x .uni-date__icon-clear {
-  border: none !important;
-}
-
-/deep/.uni-date__x-input,
-/deep/.uni-date-x {
-  padding: 0 !important;
-  height: 44rpx !important;
-  font-size: 26rpx !important;
-}
-
-/deep/.input-value {
-  font-size: 26rpx !important;
-  height: 44rpx !important;
-
-  uni-text {
-    font-size: 26rpx !important;
-  }
-}
-
-/deep/.u-textarea {
-  padding: 2px !important;
-}
-
-/deep/.u-textarea__field {
-  font-size: 26rpx !important;
-}
-</style>
+</style>

+ 1 - 0
pages/ehs/snapshot/common-style.scss

@@ -45,5 +45,6 @@
   display: flex;
   align-items: center;
   justify-content: center;
+  z-index: 999;
   box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.2);
 }

+ 230 - 64
pages/ehs/snapshot/components/discardDialog.vue

@@ -1,74 +1,240 @@
-<!-- components/discardDialog.vue - 废弃弹窗 -->
 <template>
-  <uni-popup ref="popup" type="center">
-    <view class="discard-dialog">
-      <view class="title">废弃</view>
-      <uni-forms ref="form" :modelValue="formData" :rules="rules" label-width="100px">
-        <uni-forms-item label="废弃原因" name="handleOpinion">
-          <textarea v-model="formData.handleOpinion" placeholder="请输入废弃原因(100字以内)" maxlength="100" />
-        </uni-forms-item>
-        <uni-forms-item label="废弃人">
-          <input v-model="formData.handlerName" disabled />
-        </uni-forms-item>
-      </uni-forms>
-      <view class="footer">
-        <button @click="close">取消</button>
-        <button type="primary" @click="handleSubmit">确定</button>
-      </view>
-    </view>
-  </uni-popup>
+	<u-popup :show="visible" :round="0" :closeOnClickOverlay="false" :zIndex="99999" @close="handleCancel"
+		class="u-popup-my">
+		<view class="popup-content">
+			<view class="popup-header">
+				<text class="popup-title">废弃</text>
+				<view class="close-btn" @click="handleCancel">×</view>
+			</view>
+
+			<scroll-view class="popup-body" scroll-y>
+				<view class="page">
+					<view class="card-a">
+						<!-- 头部 -->
+						<view class="a-header">
+							<text class="a-main-title">废弃随手拍</text>
+						</view>
+
+						<!-- 废弃信息 -->
+						<view class="card-section">
+							<view class="section-title">📋 废弃信息</view>
+							<view class="info-list">
+								<view class="info-item">
+									<text class="info-label">废弃原因</text>
+									<textarea
+										v-if="!isView"
+										class="info-textarea"
+										v-model="formData.handleOpinion"
+										placeholder="请输入废弃原因(100字以内)"
+										maxlength="100"
+									/>
+									<text v-else class="info-value readonly">{{ formData.handleOpinion || '无' }}</text>
+								</view>
+								<view class="info-item">
+									<text class="info-label">废弃人</text>
+									<text class="info-value readonly">{{ formData.handlerName }}</text>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</scroll-view>
+
+			<view class="popup-footer">
+				<template v-if="isView">
+					<u-button type="default" @click="handleCancel">关闭</u-button>
+				</template>
+				<template v-else>
+					<u-button type="default" @click="handleCancel">取消</u-button>
+					<u-button type="primary" @click="handleSubmit" :loading="loading">确定</u-button>
+				</template>
+			</view>
+		</view>
+		<u-toast ref="uToast"></u-toast>
+	</u-popup>
 </template>
 
 <script>
 export default {
-  emits: ['confirm'],
-  data() {
-    return {
-      formData: { id: '', handleOpinion: '', handlerName: '' },
-      rules: { handleOpinion: { required: true, message: '请输入废弃原因', trigger: 'blur' } }
-    };
-  },
-  methods: {
-    open(row) {
-      const userInfo = uni.getStorageSync('userInfo') || {};
-      this.formData = {
-        id: row.id,
-        handleOpinion: row.handleOpinion || '',
-        handlerName: row.handlerName || userInfo.name || ''
-      };
-      this.$refs.popup.open();
-    },
-    close() {
-      this.$refs.popup.close();
-      this.$refs.form?.resetFields();
-    },
-    async handleSubmit() {
-      const valid = await this.$refs.form.validate();
-      if (!valid) return;
-      this.$emit('confirm', { id: this.formData.id, handleOpinion: this.formData.handleOpinion });
-      this.close();
-    }
-  }
+	emits: ['confirm'],
+	data() {
+		return {
+			visible: false,
+			loading: false,
+			dialogType: 'add',
+			formData: { id: '', handleOpinion: '', handlerName: '' },
+			rules: { handleOpinion: { required: true, message: '请输入废弃原因', trigger: 'blur' } }
+		};
+	},
+	computed: {
+		isView() {
+			return this.dialogType === 'view';
+		}
+	},
+	methods: {
+		open(row, type = 'add') {
+			this.dialogType = type;
+			const userInfo = uni.getStorageSync('userInfo') || {};
+			this.formData = {
+				id: row.id || '',
+				handleOpinion: row.handleOpinion || '',
+				handlerName: row.handlerName || userInfo.name || ''
+			};
+			this.visible = true;
+		},
+		handleCancel() {
+			this.visible = false;
+			this.formData = { id: '', handleOpinion: '', handlerName: '' };
+		},
+		async handleSubmit() {
+			if (!this.formData.handleOpinion) {
+				this.$refs.uToast.show({ type: 'error', message: '请输入废弃原因' });
+				return;
+			}
+			this.$emit('confirm', { id: this.formData.id, handleOpinion: this.formData.handleOpinion });
+			this.visible = false;
+			this.formData = { id: '', handleOpinion: '', handlerName: '' };
+		}
+	}
 };
 </script>
 
 <style lang="scss" scoped>
-.discard-dialog {
-  width: 500rpx;
-  background: #fff;
-  border-radius: 16rpx;
-  padding: 30rpx;
-  .title {
-    font-size: 36rpx;
-    font-weight: bold;
-    text-align: center;
-    margin-bottom: 30rpx;
-  }
-  .footer {
-    display: flex;
-    gap: 20rpx;
-    margin-top: 30rpx;
-    button { flex: 1; margin: 0; }
-  }
+.popup-content {
+	width: 100vw;
+	height: calc(100vh - 100px);
+	background: #fff;
+	border-radius: 0;
+	display: flex;
+	flex-direction: column;
+	background-color: #eff2f7;
+}
+
+.popup-header {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	padding: 30rpx;
+	border-bottom: 1rpx solid #e5e5e5;
+	background: #fff;
+
+	.popup-title {
+		font-size: 36rpx;
+		font-weight: bold;
+		color: #333;
+	}
+
+	.close-btn {
+		width: 60rpx;
+		height: 60rpx;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		font-size: 60rpx;
+		color: #999;
+		line-height: 1;
+	}
+}
+
+.popup-body {
+	flex: 1;
+	overflow-y: auto;
+	padding: 28rpx;
+}
+
+.page {
+	font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, sans-serif;
+}
+
+.card-a {
+	background: #ffffff;
+	border-radius: 48rpx;
+	box-shadow: 0 12rpx 40rpx rgba(0, 0, 0, 0.05);
+	overflow: hidden;
+}
+
+.a-header {
+	background: linear-gradient(135deg, #fef0f0 0%, #fff3e0 100%);
+	padding: 40rpx 32rpx 24rpx;
+	text-align: center;
+
+	.a-main-title {
+		font-size: 36rpx;
+		font-weight: 800;
+		color: #e53935;
+	}
+}
+
+.card-section {
+	padding: 30rpx 32rpx;
+	border-bottom: 2rpx solid #f0f2f5;
+
+	&:last-child {
+		border-bottom: none;
+	}
+}
+
+.section-title {
+	font-size: 30rpx;
+	font-weight: 700;
+	color: #1f2a44;
+	margin-bottom: 24rpx;
+	padding-left: 16rpx;
+	border-left: 6rpx solid #f56c6c;
+}
+
+.info-list {
+	display: flex;
+	flex-direction: column;
+	gap: 28rpx;
+}
+
+.info-item {
+	display: flex;
+	flex-direction: column;
+	gap: 8rpx;
+}
+
+.info-label {
+	font-size: 26rpx;
+	font-weight: 600;
+	color: #6c7a91;
+}
+
+.info-value {
+	font-size: 28rpx;
+	font-weight: 500;
+	color: #1e2a3a;
+	padding: 16rpx 20rpx;
+	border-radius: 24rpx;
+	border: 2rpx solid #e9edf2;
+	background: #fff;
+
+	&.readonly {
+		color: #999;
+		background: #f5f5f5;
+	}
+}
+
+.info-textarea {
+	font-size: 28rpx;
+	color: #1e2a3a;
+	min-height: 160rpx;
+	padding: 16rpx 20rpx;
+	border-radius: 24rpx;
+	border: 2rpx solid #e9edf2;
+	background: #fff;
+}
+
+.popup-footer {
+	display: flex;
+	padding: 20rpx 30rpx;
+	border-top: 1rpx solid #e5e5e5;
+	background: #fff;
+	gap: 20rpx;
+
+	/deep/ .u-button {
+		flex: 1;
+	}
 }
-</style>
+</style>

+ 509 - 470
pages/ehs/snapshot/components/snapshotDialog.vue

@@ -1,478 +1,517 @@
 <template>
-	<u-popup :show="visible" :round="0" :closeOnClickOverlay="false" :zIndex="99999" @close="handleCancel"
-		class="u-popup-my">
-		<view class="popup-content">
-			<view class="popup-header">
-				<text class="popup-title">{{ dialogTitle }}</text>
-				<view class="close-btn" @click="handleCancel">×</view>
-			</view>
-
-			<scroll-view class="popup-body" scroll-y>
-				<view class="page">
-					<view class="card-a">
-						<!-- 头部 -->
-						<view class="a-header">
-							<text class="a-main-title">随手拍记录</text>
-						</view>
-
-						<!-- 基础信息 -->
-						<view class="card-section">
-							<view class="section-title">📝 基础信息</view>
-							<view class="info-list">
-								<view class="info-item">
-									<text class="info-label">问题描述</text>
-									<textarea v-if="canEdit" class="info-textarea" v-model="formData.description"
-										placeholder="请输入问题描述" :disabled="!canEdit" />
-									<text v-else class="info-value readonly">{{ formData.description }}</text>
-								</view>
-								<view class="info-item">
-									<text class="info-label">问题所在位置</text>
-									<input v-if="canEdit" class="info-input" v-model="formData.location"
-										placeholder="请输入位置" :disabled="!canEdit" />
-									<text v-else class="info-value readonly">{{ formData.location }}</text>
-								</view>
-								<view class="info-item">
-									<text class="info-label">问题所属部门</text>
-
-
-									<view class="info-value" :class="{ disabled: !canEdit }"
-										@click="title != '详情' && $refs.treePicker._show()">
-										{{ formData.problemDeptName || "请选择" }}
-									</view>
-
-								</view>
-								<view class="info-item">
-									<text class="info-label">随手拍图片</text>
-									<fileMain v-if="canEdit" v-model="formData.attachment"
-										:type="canEdit ? '' : 'view'" />
-									<view v-else class="image-list">
-										<image v-for="(img, idx) in formData.attachment" :key="idx" :src="img.url"
-											mode="aspectFill" @click="previewImage(img.url)" />
-									</view>
-								</view>
-							</view>
-						</view>
-
-						<!-- 上报信息 -->
-						<view class="card-section">
-							<view class="section-title">👤 上报信息</view>
-							<view class="info-list">
-								<view class="info-item">
-									<text class="info-label">上报人</text>
-									<text class="info-value readonly">{{ formData.reporterName }}</text>
-								</view>
-								<view class="info-item">
-									<text class="info-label">上报人部门</text>
-									<text class="info-value readonly">{{ formData.reporterDeptName }}</text>
-								</view>
-								<view class="info-item" v-if="!canEdit">
-									<text class="info-label">处理结果</text>
-									<view class="info-value">
-										<text v-if="formData.handleResult == 0" class="status-pending">待处理</text>
-										<text v-else class="status-link" :class="{
+  <u-popup
+    :show="visible"
+    :round="0"
+    :closeOnClickOverlay="false"
+    :zIndex="99999"
+    @close="handleCancel"
+    class="u-popup-my"
+  >
+    <view class="popup-content">
+      <view class="popup-header">
+        <text class="popup-title">{{ dialogTitle }}</text>
+        <view class="close-btn" @click="handleCancel">×</view>
+      </view>
+
+      <scroll-view class="popup-body" scroll-y>
+        <view class="page">
+          <view class="card-a">
+            <!-- 头部 -->
+            <view class="a-header">
+              <text class="a-main-title">随手拍记录</text>
+            </view>
+
+            <!-- 基础信息 -->
+            <view class="card-section">
+              <view class="section-title">📝 基础信息</view>
+              <view class="info-list">
+                <view class="info-item">
+                  <text class="info-label">问题描述</text>
+                  <textarea
+                    v-if="canEdit"
+                    class="info-textarea"
+                    v-model="formData.description"
+                    placeholder="请输入问题描述"
+                    :disabled="!canEdit"
+                  />
+                  <text v-else class="info-value readonly">{{
+                    formData.description
+                  }}</text>
+                </view>
+                <view class="info-item">
+                  <text class="info-label">问题所在位置</text>
+                  <input
+                    v-if="canEdit"
+                    class="info-input"
+                    v-model="formData.location"
+                    placeholder="请输入位置"
+                    :disabled="!canEdit"
+                  />
+                  <text v-else class="info-value readonly">{{
+                    formData.location
+                  }}</text>
+                </view>
+                <view class="info-item">
+                  <text class="info-label">问题所属部门</text>
+
+                  <view
+                    class="info-value"
+                    :class="{ disabled: !canEdit }"
+                    @click="title != '详情' && $refs.treePicker._show()"
+                  >
+                    {{ formData.problemDeptName || "请选择" }}
+                  </view>
+                </view>
+                <view class="info-item">
+                  <text class="info-label">随手拍图片</text>
+                  <fileMain
+                    v-model="formData.attachment"
+                    :type="canEdit ? '' : 'view'"
+                  />
+                </view>
+              </view>
+            </view>
+
+            <!-- 上报信息 -->
+            <view class="card-section">
+              <view class="section-title">👤 上报信息</view>
+              <view class="info-list">
+                <view class="info-item">
+                  <text class="info-label">上报人</text>
+                  <text class="info-value readonly">{{
+                    formData.reporterName
+                  }}</text>
+                </view>
+                <view class="info-item">
+                  <text class="info-label">上报人部门</text>
+                  <text class="info-value readonly">{{
+                    formData.reporterDeptName
+                  }}</text>
+                </view>
+                <view class="info-item" v-if="!canEdit">
+                  <text class="info-label">处理结果</text>
+                  <view >
+                    <text
+                      v-if="formData.handleResult == 0"
+                      class="status-pending"
+                      >待处理</text
+                    >
+                    <text
+                      v-else
+                      class="status-link"
+                      :class="{
                         'status-done': formData.handleResult == 1,
-                        'status-discard': formData.handleResult == 2
-                      }" @click="handleViewResult">{{ getResultLabel(formData.handleResult) }}</text>
-									</view>
-								</view>
-							</view>
-						</view>
-					</view>
-				</view>
-			</scroll-view>
-
-			<view class="popup-footer">
-				<template v-if="isView">
-					<u-button type="default" @click="handleCancel">关闭</u-button>
-				</template>
-				<template v-else-if="isHandle">
-					<u-button type="default" @click="handleDiscard">废弃</u-button>
-					<u-button type="primary" @click="handleRectify">下发整改</u-button>
-				</template>
-				<template v-else>
-					<u-button type="default" @click="handleCancel">取消</u-button>
-					<u-button type="primary" @click="handleSubmit" :loading="loading">保存</u-button>
-				</template>
-			</view>
-		</view>
-		<u-toast ref="uToast"></u-toast>
-		<ba-tree-picker ref="treePicker" key="verify" :multiple="false" @select-change="searchDeptNodeClick"
-			title="选择部门" :localdata="classificationList" valueKey="id" textKey="name" childrenKey="children" />
-	</u-popup>
+                        'status-discard': formData.handleResult == 2,
+                      }"
+                      @click="handleViewResult"
+                      >{{ getResultLabel(formData.handleResult) }}(点击查看)</text
+                    >
+                  </view>
+                </view>
+              </view>
+            </view>
+          </view>
+        </view>
+      </scroll-view>
+
+      <view class="popup-footer">
+        <template v-if="isView">
+          <u-button type="default" @click="handleCancel">关闭</u-button>
+        </template>
+        <template v-else-if="isHandle">
+          <u-button type="default" @click="handleDiscard">废弃</u-button>
+          <u-button type="primary" @click="handleRectify">下发整改</u-button>
+        </template>
+        <template v-else>
+          <u-button type="default" @click="handleCancel">取消</u-button>
+          <u-button type="primary" @click="handleSubmit" :loading="loading"
+            >保存</u-button
+          >
+        </template>
+      </view>
+    </view>
+    <u-toast ref="uToast"></u-toast>
+    <ba-tree-picker
+      ref="treePicker"
+      key="verify"
+      :multiple="false"
+      @select-change="searchDeptNodeClick"
+      title="选择部门"
+      :localdata="classificationList"
+      valueKey="id"
+      textKey="name"
+      childrenKey="children"
+    />
+  </u-popup>
 </template>
 
 <script>
-	import {
-		getById,
-		save,
-		update
-	} from '@/api/snapshot/index.js';
-	import fileMain from "@/pages/doc/index.vue"
-	import {
-		listOrganizations
-	} from "@/api/common.js";
-	import {
-		toTreeData
-	} from "@/utils/utils.js";
-	export default {
-		emits: ['reload', 'rectify', 'discard'],
-		components: {
-			fileMain
-		},
-		data() {
-			return {
-				visible: false,
-				loading: false,
-				dialogType: 'add',
-				formData: this.getDefaultForm(),
-				classificationList: [],
-				resultOptions: [{
-						value: 1,
-						label: '下发整改'
-					},
-					{
-						value: 2,
-						label: '废弃'
-					}
-				]
-			};
-		},
-		computed: {
-			dialogTitle() {
-				const map = {
-					add: '新增随手拍',
-					edit: '编辑随手拍',
-					view: '随手拍详情',
-					handle: '随手拍处理'
-				};
-				return map[this.dialogType] || '随手拍';
-			},
-			isView() {
-				return this.dialogType === 'view';
-			},
-			isHandle() {
-				return this.dialogType === 'handle';
-			},
-			canEdit() {
-				return ['add', 'edit'].includes(this.dialogType);
-			}
-		},
-		methods: {
-			getDefaultForm() {
-				return {
-					id: '',
-					description: '',
-					location: '',
-					problemDeptId: '',
-					problemDeptName: '',
-					attachment: [],
-					reporterId: '',
-					reporterName: '',
-					reporterDeptId: '',
-					reporterDeptName: '',
-					handleResult: 0,
-					handleOpinion: '',
-					invHazardId: ''
-				};
-			},
-			async getTreeList() {
-				const data = await listOrganizations({});
-				let treeList = toTreeData({
-					data: data || [],
-					idField: "id",
-					parentIdField: "parentId",
-				});
-				this.classificationList = treeList;
-			},
-			async open(type, row = null) {
-				this.dialogType = type;
-				if (row && row.id && ['edit', 'view', 'handle'].includes(type)) {
-					try {
-						const data = await getById(row.id);
-						this.formData = {
-							...data,
-							attachment: data.attachment || []
-						};
-					} catch (e) {
-						console.error(e);
-					}
-				} else {
-					this.formData = this.getDefaultForm();
-					const userInfo = uni.getStorageSync('userInfo') || {};
-					this.formData.reporterName = userInfo.name || '';
-					this.formData.reporterId = userInfo.userId || '';
-					this.formData.reporterDeptName = userInfo.groupName || '';
-					this.formData.reporterDeptId = userInfo.groupId || '';
-				}
-				this.getTreeList();
-				this.visible = true;
-			},
-			//选择部门(搜索)
-			async searchDeptNodeClick(id, name, type) {
-				this.formData.problemDeptId = id[0];
-				this.formData.problemDeptName = name;
-	
-			},
-			handleCancel() {
-				this.visible = false;
-				this.resetForm();
-			},
-			resetForm() {
-				this.formData = this.getDefaultForm();
-			},
-			getResultLabel(result) {
-				const item = this.resultOptions.find(opt => opt.value == result);
-				return item ? item.label : '待处理';
-			},
-			previewImage(url) {
-				uni.previewImage({
-					urls: [url]
-				});
-			},
-			handleViewResult() {
-				if (this.formData.handleResult == 2) {
-					uni.showModal({
-						title: '废弃原因',
-						content: this.formData.handleOpinion || '无',
-						showCancel: false
-					});
-				} else if (this.formData.handleResult == 1 && this.formData.invHazardId) {
-					uni.navigateTo({
-						url: `/pages/hazard/detail?id=${this.formData.invHazardId}`
-					});
-				}
-			},
-			async handleSubmit() {
-				// 简单校验
-				if (!this.formData.description) {
-					this.$refs.uToast.show({
-						type: 'error',
-						message: '请输入问题描述'
-					});
-					return;
-				}
-				if (!this.formData.location) {
-					this.$refs.uToast.show({
-						type: 'error',
-						message: '请输入问题所在位置'
-					});
-					return;
-				}
-				const api = this.dialogType === 'add' ? save : update;
-				this.loading = true;
-				try {
-					await api(this.formData);
-					this.$refs.uToast.show({
-						type: 'success',
-						message: this.dialogType === 'add' ? '新增成功' : '编辑成功'
-					});
-					this.visible = false;
-					this.$emit('reload');
-					this.resetForm();
-				} catch (e) {
-					console.error(e);
-				} finally {
-					this.loading = false;
-				}
-			},
-			handleRectify() {
-				this.$emit('rectify', this.formData);
-				this.visible = false;
-			},
-			handleDiscard() {
-				this.$emit('discard', this.formData);
-				this.visible = false;
-			}
-		}
-	};
+import { getById, save, update } from "@/api/snapshot/index.js";
+import fileMain from "@/pages/doc/index.vue";
+import { listOrganizations } from "@/api/common.js";
+import { toTreeData } from "@/utils/utils.js";
+export default {
+  emits: ["reload", "rectify", "discard"],
+  components: {
+    fileMain,
+  },
+  data() {
+    return {
+      visible: false,
+      loading: false,
+      dialogType: "add",
+      formData: this.getDefaultForm(),
+      classificationList: [],
+      resultOptions: [
+        {
+          value: 1,
+          label: "下发整改",
+        },
+        {
+          value: 2,
+          label: "废弃",
+        },
+      ],
+    };
+  },
+  computed: {
+    dialogTitle() {
+      const map = {
+        add: "新增随手拍",
+        edit: "编辑随手拍",
+        view: "随手拍详情",
+        handle: "随手拍处理",
+      };
+      return map[this.dialogType] || "随手拍";
+    },
+    isView() {
+      return this.dialogType === "view";
+    },
+    isHandle() {
+      return this.dialogType === "handle";
+    },
+    canEdit() {
+      return ["add", "edit"].includes(this.dialogType);
+    },
+  },
+  methods: {
+    getDefaultForm() {
+      return {
+        id: "",
+        description: "",
+        location: "",
+        problemDeptId: "",
+        problemDeptName: "",
+        attachment: [],
+        reporterId: "",
+        reporterName: "",
+        reporterDeptId: "",
+        reporterDeptName: "",
+        handleResult: 0,
+        handleOpinion: "",
+        invHazardId: "",
+      };
+    },
+    async getTreeList() {
+      const data = await listOrganizations({});
+      let treeList = toTreeData({
+        data: data || [],
+        idField: "id",
+        parentIdField: "parentId",
+      });
+      this.classificationList = treeList;
+    },
+    async open(type, row = null) {
+      console.log(row, "type");
+      this.dialogType = type;
+      if (row && row.id && ["edit", "view", "handle"].includes(type)) {
+        try {
+          const data = await getById(row.id);
+          this.formData = {
+            ...data,
+            attachment: data.attachment || [],
+          };
+        } catch (e) {
+          console.error(e);
+        }
+      } else {
+        this.formData = this.getDefaultForm();
+        const userInfo = uni.getStorageSync("userInfo") || {};
+        this.formData.reporterName = userInfo.name || "";
+        this.formData.reporterId = userInfo.userId || "";
+        this.formData.reporterDeptName = userInfo.groupName || "";
+        this.formData.reporterDeptId = userInfo.groupId || "";
+      }
+      this.getTreeList();
+      this.visible = true;
+    },
+    //选择部门(搜索)
+    async searchDeptNodeClick(id, name, type) {
+      this.formData.problemDeptId = id[0];
+      this.formData.problemDeptName = name;
+    },
+    handleCancel() {
+      this.visible = false;
+      this.resetForm();
+    },
+    resetForm() {
+      this.formData = this.getDefaultForm();
+    },
+    getResultLabel(result) {
+      const item = this.resultOptions.find((opt) => opt.value == result);
+      return item ? item.label : "待处理";
+    },
+    previewImage(url) {
+      uni.previewImage({
+        urls: [url],
+      });
+    },
+    handleViewResult() {
+      if (this.formData.handleResult == 2) {
+        this.$emit("discard", this.formData, "view");
+      } else if (this.formData.handleResult == 1 && this.formData.invHazardId) {
+        uni.navigateTo({
+          url: `/pages/hazard/detail?id=${this.formData.invHazardId}`,
+        });
+      }
+    },
+    async handleSubmit() {
+      // 简单校验
+      if (!this.formData.description) {
+        this.$refs.uToast.show({
+          type: "error",
+          message: "请输入问题描述",
+        });
+        return;
+      }
+      if (!this.formData.location) {
+        this.$refs.uToast.show({
+          type: "error",
+          message: "请输入问题所在位置",
+        });
+        return;
+      }
+      const api = this.dialogType === "add" ? save : update;
+      this.loading = true;
+      try {
+        await api(this.formData);
+        this.$refs.uToast.show({
+          type: "success",
+          message: this.dialogType === "add" ? "新增成功" : "编辑成功",
+        });
+        this.visible = false;
+        this.$emit("reload");
+        this.resetForm();
+      } catch (e) {
+        console.error(e);
+      } finally {
+        this.loading = false;
+      }
+    },
+    handleRectify() {
+      this.$emit("rectify", this.formData);
+      this.visible = false;
+    },
+    handleDiscard() {
+      this.$emit("discard", this.formData);
+      this.visible = false;
+    },
+  },
+};
 </script>
 
 <style lang="scss" scoped>
-	.popup-content {
-		width: 100vw;
-		height: calc(100vh - 100px);
-		background: #fff;
-		border-radius: 0;
-		display: flex;
-		flex-direction: column;
-		background-color: #eff2f7;
-	}
-
-	.popup-header {
-		display: flex;
-		justify-content: space-between;
-		align-items: center;
-		padding: 30rpx;
-		border-bottom: 1rpx solid #e5e5e5;
-		background: #fff;
-
-		.popup-title {
-			font-size: 36rpx;
-			font-weight: bold;
-			color: #333;
-		}
-
-		.close-btn {
-			width: 60rpx;
-			height: 60rpx;
-			display: flex;
-			align-items: center;
-			justify-content: center;
-			font-size: 60rpx;
-			color: #999;
-			line-height: 1;
-		}
-	}
-
-	.popup-body {
-		flex: 1;
-		overflow-y: auto;
-		padding: 28rpx;
-	}
-
-	.page {
-		font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, sans-serif;
-	}
-
-	.card-a {
-		background: #ffffff;
-		border-radius: 48rpx;
-		box-shadow: 0 12rpx 40rpx rgba(0, 0, 0, 0.05);
-		overflow: hidden;
-	}
-
-	.a-header {
-		background: linear-gradient(135deg, #e8f5e9 0%, #f1f8e9 100%);
-		padding: 40rpx 32rpx 24rpx;
-		text-align: center;
-
-		.a-main-title {
-			font-size: 36rpx;
-			font-weight: 800;
-			color: #2e7d32;
-		}
-	}
-
-	.card-section {
-		padding: 30rpx 32rpx;
-		border-bottom: 2rpx solid #f0f2f5;
-
-		&:last-child {
-			border-bottom: none;
-		}
-	}
-
-	.section-title {
-		font-size: 30rpx;
-		font-weight: 700;
-		color: #1f2a44;
-		margin-bottom: 24rpx;
-		padding-left: 16rpx;
-		border-left: 6rpx solid #4caf50;
-	}
-
-	.info-list {
-		display: flex;
-		flex-direction: column;
-		gap: 28rpx;
-	}
-
-	.info-item {
-		display: flex;
-		flex-direction: column;
-		gap: 8rpx;
-	}
-
-	.info-label {
-		font-size: 26rpx;
-		font-weight: 600;
-		color: #6c7a91;
-	}
-
-	.info-value {
-		font-size: 28rpx;
-		font-weight: 500;
-		color: #1e2a3a;
-		padding: 16rpx 20rpx;
-		border-radius: 24rpx;
-		border: 2rpx solid #e9edf2;
-		background: #fff;
-
-		&.readonly {
-			color: #999;
-			background: #f5f5f5;
-		}
-	}
-
-	.info-input,
-	.info-textarea {
-		font-size: 28rpx;
-		color: #1e2a3a;
-		height: 60rpx;
-		padding: 16rpx 20rpx;
-		border-radius: 24rpx;
-		border: 2rpx solid #e9edf2;
-		background: #fff;
-	}
-
-	.info-textarea {
-		min-height: 160rpx;
-	}
-
-	.image-list {
-		display: flex;
-		flex-wrap: wrap;
-		gap: 16rpx;
-
-		image {
-			width: 160rpx;
-			height: 160rpx;
-			border-radius: 16rpx;
-			background: #f5f5f5;
-			object-fit: cover;
-		}
-	}
-
-	.status-pending {
-		color: #e6a23c;
-		background: #fff3e0;
-		padding: 8rpx 20rpx;
-		border-radius: 32rpx;
-		font-size: 26rpx;
-		display: inline-block;
-	}
-
-	.status-done {
-		color: #67c23a;
-		background: #e0f3e8;
-		padding: 8rpx 20rpx;
-		border-radius: 32rpx;
-		font-size: 26rpx;
-		display: inline-block;
-	}
-
-	.status-discard {
-		color: #f56c6c;
-		background: #fef0f0;
-		padding: 8rpx 20rpx;
-		border-radius: 32rpx;
-		font-size: 26rpx;
-		display: inline-block;
-	}
-
-	.status-link {
-		text-decoration: none;
-	}
-
-	.popup-footer {
-		display: flex;
-		padding: 20rpx 30rpx;
-		border-top: 1rpx solid #e5e5e5;
-		background: #fff;
-		gap: 20rpx;
-
-		/deep/ .u-button {
-			flex: 1;
-		}
-	}
-</style>
+.popup-content {
+  width: 100vw;
+  height: calc(100vh - 100px);
+  background: #fff;
+  border-radius: 0;
+  display: flex;
+  flex-direction: column;
+  background-color: #eff2f7;
+}
+
+.popup-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 30rpx;
+  border-bottom: 1rpx solid #e5e5e5;
+  background: #fff;
+
+  .popup-title {
+    font-size: 36rpx;
+    font-weight: bold;
+    color: #333;
+  }
+
+  .close-btn {
+    width: 60rpx;
+    height: 60rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 60rpx;
+    color: #999;
+    line-height: 1;
+  }
+}
+
+.popup-body {
+  flex: 1;
+  overflow-y: auto;
+  padding: 28rpx;
+}
+
+.page {
+  font-family:
+    system-ui,
+    -apple-system,
+    "Segoe UI",
+    Roboto,
+    Helvetica,
+    sans-serif;
+}
+
+.card-a {
+  background: #ffffff;
+  border-radius: 48rpx;
+  box-shadow: 0 12rpx 40rpx rgba(0, 0, 0, 0.05);
+  overflow: hidden;
+}
+
+.a-header {
+  background: linear-gradient(135deg, #e8f5e9 0%, #f1f8e9 100%);
+  padding: 40rpx 32rpx 24rpx;
+  text-align: center;
+
+  .a-main-title {
+    font-size: 36rpx;
+    font-weight: 800;
+    color: #2e7d32;
+  }
+}
+
+.card-section {
+  padding: 30rpx 32rpx;
+  border-bottom: 2rpx solid #f0f2f5;
+
+  &:last-child {
+    border-bottom: none;
+  }
+}
+
+.section-title {
+  font-size: 30rpx;
+  font-weight: 700;
+  color: #1f2a44;
+  margin-bottom: 24rpx;
+  padding-left: 16rpx;
+  border-left: 6rpx solid #4caf50;
+}
+
+.info-list {
+  display: flex;
+  flex-direction: column;
+  gap: 28rpx;
+}
+
+.info-item {
+  display: flex;
+  flex-direction: column;
+  gap: 8rpx;
+}
+
+.info-label {
+  font-size: 26rpx;
+  font-weight: 600;
+  color: #6c7a91;
+}
+
+.info-value {
+  font-size: 28rpx;
+  font-weight: 500;
+  color: #1e2a3a;
+  padding: 16rpx 20rpx;
+  border-radius: 24rpx;
+  border: 2rpx solid #e9edf2;
+  background: #fff;
+
+  &.readonly {
+    color: #999;
+    background: #f5f5f5;
+  }
+}
+
+.info-input,
+.info-textarea {
+  font-size: 28rpx;
+  color: #1e2a3a;
+  height: 60rpx;
+  padding: 16rpx 20rpx;
+  border-radius: 24rpx;
+  border: 2rpx solid #e9edf2;
+  background: #fff;
+}
+
+.info-textarea {
+  min-height: 160rpx;
+}
+
+.image-list {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 16rpx;
+
+  image {
+    width: 160rpx;
+    height: 160rpx;
+    border-radius: 16rpx;
+    background: #f5f5f5;
+    object-fit: cover;
+  }
+}
+
+.status-pending {
+  color: #e6a23c;
+  background: #fff3e0;
+  padding: 8rpx 20rpx;
+  border-radius: 32rpx;
+  font-size: 26rpx;
+  display: inline-block;
+}
+
+.status-done {
+  color: #67c23a;
+  background: #e0f3e8;
+  padding: 8rpx 20rpx;
+  border-radius: 32rpx;
+  font-size: 26rpx;
+  display: inline-block;
+}
+
+.status-discard {
+  color: #f56c6c;
+  background: #fef0f0;
+  padding: 8rpx 20rpx;
+  border-radius: 32rpx;
+  font-size: 26rpx;
+  display: inline-block;
+}
+
+.status-link {
+  text-decoration: none;
+}
+
+.popup-footer {
+  display: flex;
+  padding: 20rpx 30rpx;
+  border-top: 1rpx solid #e5e5e5;
+  background: #fff;
+  gap: 20rpx;
+
+  /deep/ .u-button {
+    flex: 1;
+  }
+}
+</style>

+ 316 - 0
pages/ehs/snapshot/components/snapshotList.vue

@@ -0,0 +1,316 @@
+<template>
+	<view class="mainBox">
+		<uni-nav-bar fixed="true" statusBar="true" left-icon="back" :title="navTitle" @clickLeft="back" />
+
+		<!-- 搜索区域 -->
+		<view class="top-wrapper">
+			<uni-forms :modelValue="where" label-width="100px" class="search-form">
+				<uni-forms-item label="处理结果">
+					<uni-data-select v-model="where.handleResult" :localdata="resultOptions" placeholder="全部"
+						clearable />
+				</uni-forms-item>
+			</uni-forms>
+			<button class="search_btn" @click="handleSearch">搜索</button>
+		</view>
+
+		<view class="wrapper">
+			<u-list @scrolltolower="scrolltolower" class="listContent">
+				<view v-for="(item, idx) in tableList" :key="item.id" style="position: relative">
+					<myCard :item="item" :index="idx + 1" :btnList="currentBtnList" :columns="currentColumns"
+						:title="item.description" :status="statusMap[item.handleResult]" @goDetail="goDetail"
+						@edit="handleEdit(item)" @handleDelete="handleDelete(item)" @handleProcess="handleProcess(item)" />
+				</view>
+				<view style="width: 100%; height: 40rpx"></view>
+				<view style="margin-top: 20vh" v-if="tableList.length == 0">
+					<u-empty iconSize="150" textSize="32" text="暂无数据" />
+				</view>
+			</u-list>
+		</view>
+
+		<!-- 新增/编辑/查看/处理弹窗 -->
+		<snapshot-dialog ref="snapshotDialog" @reload="reloadList" @rectify="onRectify" @discard="onDiscard" />
+		<!-- 废弃弹窗(仅管理模式) -->
+		<discard-dialog v-if="mode === 'manage'" ref="discardDialogRef" @confirm="doDiscard" />
+
+		<!-- 新增按钮(仅我的随手拍) -->
+		<view v-if="mode === 'my'" class="add" @click="handleAdd">
+			<u-icon name="plus" color="#fff"></u-icon>
+		</view>
+	</view>
+</template>
+
+<script>
+	import myCard from "@/components/myCard.vue";
+	import snapshotDialog from "./snapshotDialog.vue";
+	import discardDialog from "./discardDialog.vue";
+	import {
+		getList,
+		remove,
+		discard,
+		handle
+	} from "@/api/snapshot/index.js";
+
+	export default {
+		components: {
+			myCard,
+			snapshotDialog,
+			discardDialog
+		},
+		props: {
+			mode: {
+				type: String,
+				default: "my",
+				validator: (v) => ["my", "manage"].includes(v),
+			},
+		},
+		data() {
+			return {
+				where: {
+					handleResult: ""
+				},
+				resultOptions: [{
+						value: 0,
+						text: "待处理"
+					},
+					{
+						value: 1,
+						text: "下发整改"
+					},
+					{
+						value: 2,
+						text: "废弃"
+					},
+				],
+				statusMap: {
+					0: "待处理",
+					1: "已整改",
+					2: "已废弃"
+				},
+				tableList: [],
+				page: 1,
+				size: 10,
+				isEnd: false,
+				userInfo: {},
+				currentId: null,
+			};
+		},
+		computed: {
+			navTitle() {
+				return this.mode === "my" ? "我的随手拍" : "随手拍管理";
+			},
+			currentColumns() {
+				return [
+					[{
+						prop: "location",
+						label: "位置",
+						className: "perce100"
+					}],
+					[{
+						prop: "problemDeptName",
+						label: "所属部门",
+						className: "perce100"
+					}],
+					[{
+						prop: "reporterName",
+						label: "上报人",
+						className: "perce100"
+					}],
+					[{
+						prop: "createTime",
+						label: "上报时间",
+						className: "perce100"
+					}],
+					[{
+						prop: "handleResult",
+						label: "处理结果",
+						className: "perce100",
+						formatter: (row) => this.statusMap[row.handleResult],
+					}, ],
+					[{
+						label: "操作:",
+						prop: "action",
+						type: "action",
+						className: "perce100",
+					}, ]
+				];
+
+			},
+			currentBtnList() {
+				if (this.mode === "my") {
+					return [{
+							name: "编辑",
+							apiName: "edit",
+							btnType: "primary",
+							judge: [{
+								fn: (item) => item.handleResult === 0
+							}],
+						},
+						{
+							name: "删除",
+							apiName: "handleDelete",
+							btnType: "danger",
+							judge: [{
+								fn: (item) => item.handleResult === 0
+							}],
+						},
+					];
+				} else {
+					return [{
+						name: "处理",
+						apiName: "handleProcess",
+						btnType: "primary",
+						judge: [{
+							fn: (item) => item.handleResult === 0
+						}],
+					}, ];
+				}
+			},
+		},
+		created() {
+			this.userInfo = uni.getStorageSync("userInfo") || {};
+			this.getList();
+		},
+		methods: {
+			back() {
+				uni.navigateBack();
+			},
+
+			// 列表查看详情
+			goDetail(item) {
+				this.$refs.snapshotDialog.open("view", item);
+			},
+
+			// 新增(仅 my 模式)
+			handleAdd() {
+				this.$refs.snapshotDialog.open("add");
+			},
+
+			// 编辑(my 模式按钮)
+			handleEdit(row) {
+				this.$refs.snapshotDialog.open("edit", row);
+			},
+
+			// 删除(my 模式按钮)
+			async handleDelete(row) {
+				const res = await uni.showModal({
+					title: "提示",
+					content: "确认删除该记录吗?",
+				});
+				if (res[1].confirm) {
+					await remove([row.id]);
+					uni.showToast({
+						title: "删除成功",
+						icon: "success"
+					});
+					this.reloadList();
+				}
+			},
+
+			// 处理(manage 模式按钮)
+			handleProcess(row) {
+				this.$refs.snapshotDialog.open("handle", row);
+			},
+
+			// 下发整改(manage 模式)
+			onRectify(data) {
+				this.currentId = data.id;
+				this.$refs.hazardDialogRef &&
+					this.$refs.hazardDialogRef.open("add", "", "report", {
+						sourceType: 4,
+						sourceId: data.id,
+						sourceName: "随手拍",
+						foundUserName: data.reporterName,
+						foundUserId: data.reporterId,
+						foundTime: data.createTime,
+						description: data.location + data.description,
+						reportAttachments: data.attachment,
+					});
+			},
+			doRectify(opinion) {
+				handle({
+					id: this.currentId,
+					handleOpinion: opinion,
+					invHazardId: "下发整改",
+				}).then(() => {
+					uni.showToast({
+						title: "下发整改成功",
+						icon: "success"
+					});
+					this.reloadList();
+				});
+			},
+
+			// 废弃(manage 模式)
+			onDiscard(data,type) {
+				this.$refs.discardDialogRef.open(data,type);
+			},
+			doDiscard({
+				id,
+				handleOpinion
+			}) {
+				discard({
+					id,
+					handleOpinion
+				}).then(() => {
+					uni.showToast({
+						title: "废弃成功",
+						icon: "success"
+					});
+					this.reloadList();
+				});
+			},
+
+			// 通用方法
+			reloadList() {
+				this.page = 1;
+				this.isEnd = false;
+				this.getList();
+			},
+			handleSearch() {
+				this.page = 1;
+				this.isEnd = false;
+				this.getList();
+			},
+			async getList() {
+				if (this.isEnd) return;
+				uni.showLoading({
+					title: "加载中"
+				});
+				try {
+					const baseData = {
+						pageNum: this.page,
+						size: this.size,
+						handleResult: this.where.handleResult !== "" ?
+							this.where.handleResult :
+							undefined,
+					};
+					// 不同模式参数不同
+					if (this.mode === "my") {
+						baseData.reporterId = this.userInfo.userId;
+					}
+					const res = await getList(baseData);
+					const newList = this.mode === "my" ? res.list || [] : res.list || [];
+					if (this.page === 1) this.tableList = newList;
+					else this.tableList.push(...newList);
+					if (this.mode === "my") {
+						this.isEnd = this.tableList.length >= res.count;
+					} else {
+						this.isEnd = newList.length < this.size;
+					}
+					this.page += 1;
+				} catch (e) {
+					console.error(e);
+				} finally {
+					uni.hideLoading();
+				}
+			},
+			scrolltolower() {
+				if (!this.isEnd) this.getList();
+			},
+		},
+	};
+</script>
+
+<style lang="scss" scoped>
+	@import "../common-style.scss";
+</style>

+ 4 - 143
pages/ehs/snapshot/mySnapshot.vue

@@ -1,150 +1,11 @@
 <!-- pages/snapshot/mySnapshot.vue -->
 <template>
-  <view class="mainBox">
-    <uni-nav-bar fixed="true" statusBar="true" left-icon="back" title="我的随手拍" @clickLeft="back" />
-
-    <!-- 搜索区域 -->
-    <view class="top-wrapper">
-      <uni-forms :modelValue="where" label-width="100px" class="search-form">
-        <uni-forms-item label="处理结果">
-          <uni-data-select v-model="where.handleResult" :localdata="resultOptions" placeholder="全部" clearable />
-        </uni-forms-item>
- 
-      </uni-forms>
-      <button class="search_btn" @click="handleSearch">搜索</button>
-    </view>
-
-    <view class="wrapper">
-      <u-list @scrolltolower="scrolltolower" class="listContent">
-        <view v-for="(item, idx) in tableList" :key="item.id" style="position: relative">
-          <myCard
-            :item="item"
-            :index="idx + 1"
-            :btnList="myBtnList" 
-            :columns="columns"
-            :title="item.description"
-            :status="statusMap[item.handleResult]"
-            @goDetail="goDetail"
-            @handleDelete="handleDelete"
-          />
-        </view>
-        <view style="width: 100%; height: 40rpx"></view>
-        <view style="margin-top: 20vh" v-if="tableList.length == 0">
-          <u-empty iconSize="150" textSize="32" text="暂无数据" />
-        </view>
-      </u-list>
-    </view>
-
-    <!-- 新增/编辑/查看弹窗 -->
-    <snapshot-dialog ref="snapshotDialog" @reload="reloadList" />
-
-    <view class="add" @click="goDetail({}, 'add')">
-      <u-icon name="plus" color="#fff"></u-icon>
-    </view>
-  </view>
+  <snapshot-list mode="my" />
 </template>
- 
-<script>
-	import myCard from "@/components/myCard.vue";
-import snapshotDialog from './components/snapshotDialog.vue';
-import { getList, remove } from '@/api/snapshot/index.js';
 
+<script>
+import snapshotList from './components/snapshotList.vue';
 export default {
-  components: { myCard, snapshotDialog },
-  data() {
-    return {
-      where: { handleResult: '', createTime: '' },
-      resultOptions: [
-        { value: 0, text: '待处理' },
-        { value: 1, text: '下发整改' },
-        { value: 2, text: '废弃' }
-      ],
-      statusMap: { 0: '待处理', 1: '已整改', 2: '已废弃' },
-      columns: [
-        [{ prop: 'location', label: '位置', className: 'perce100' }],
-        [{ prop: 'problemDeptName', label: '所属部门', className: 'perce100' }],
-        [{ prop: 'createTime', label: '上报时间', className: 'perce100' }],
-        [{ prop: 'handleResult', label: '处理结果', className: 'perce100', formatter: (row) => this.statusMap[row.handleResult] }]
-      ],
-      tableList: [],
-      page: 1,
-      size: 10,
-      isEnd: false,
-      userInfo: {}
-    };
-  },
-  computed: {
-    myBtnList() {
-      return [
-        {
-          name: '编辑',
-          apiName: 'edit',
-          btnType: 'primary',
-          judge: [{ fn: (item) => item.handleResult === 0 }]
-        },
-        {
-          name: '删除',
-          apiName: 'delete',
-          btnType: 'danger',
-          judge: [{ fn: (item) => item.handleResult === 0 }]
-        }
-      ];
-    }
-  },
-  onLoad() {
-    this.userInfo = uni.getStorageSync('userInfo') || {};
-    this.getList();
-  },
-  methods: {
-    back() { uni.navigateBack(); },
-    goDetail(item, type) {
-      this.$refs.snapshotDialog.open(type, item);
-    },
-    async handleDelete(row) {
-      const res = await uni.showModal({ title: '提示', content: '确认删除该记录吗?' });
-      if (res.confirm) {
-        await remove([row.id]);
-        uni.showToast({ title: '删除成功', icon: 'success' });
-        this.reloadList();
-      }
-    },
-    reloadList() {
-      this.page = 1;
-      this.isEnd = false;
-      this.getList();
-    },
-    handleSearch() {
-      this.page = 1;
-      this.isEnd = false;
-      this.getList();
-    },
-    async getList() {
-      if (this.isEnd) return;
-      uni.showLoading({ title: '加载中' });
-      try {
-        const data = {
-          pageNum: this.page,
-          size: this.size,
-          reporterId: this.userInfo.userId,
-          handleResult: this.where.handleResult !== '' ? this.where.handleResult : undefined,
-          createTime: this.where.createTime || undefined
-        };
-        const res = await getList(data);
-        const newList = res.list || [];
-        if (this.page === 1) this.tableList = newList;
-        else this.tableList.push(...newList);
-        this.isEnd = this.tableList.length >= res.count;
-        this.page += 1;
-      } catch (e) { console.error(e); }
-      finally { uni.hideLoading(); }
-    },
-    scrolltolower() {
-      if (!this.isEnd) this.getList();
-    }
-  }
+  components: { snapshotList }
 };
 </script>
-
-<style lang="scss" scoped>
-@import './common-style.scss'; // 共用样式见下方
-</style>

+ 5 - 223
pages/ehs/snapshot/snapshotManage.vue

@@ -1,229 +1,11 @@
 <!-- pages/snapshot/snapshotManage.vue -->
 <template>
-	<view class="mainBox">
-		<uni-nav-bar fixed="true" statusBar="true" left-icon="back" title="随手拍管理" @clickLeft="back" />
-
-		<view class="top-wrapper">
-			<uni-forms :modelValue="where" label-width="100px" class="search-form">
-	
-				<uni-forms-item label="处理结果">
-					<uni-data-select v-model="where.handleResult" :localdata="resultOptions" placeholder="全部"
-						clearable />
-				</uni-forms-item>
-	
-			</uni-forms>
-			<button class="search_btn" @click="handleSearch">搜索</button>
-		</view>
-
-		<view class="wrapper">
-			<u-list @scrolltolower="scrolltolower" class="listContent">
-				<view v-for="(item, idx) in tableList" :key="item.id" style="position: relative">
-					<myCard :item="item" :index="idx + 1" :btnList="manageBtnList" :columns="columns"
-						:title="item.description" :status="statusMap[item.handleResult]" @goDetail="goDetail"
-						@handleProcess="handleProcess" />
-				</view>
-				<view style="width: 100%; height: 40rpx"></view>
-				<view style="margin-top: 20vh" v-if="tableList.length == 0">
-					<u-empty iconSize="150" textSize="32" text="暂无数据" />
-				</view>
-			</u-list>
-		</view>
-
-		<snapshot-dialog ref="snapshotDialog" @rectify="onRectify" @discard="onDiscard" />
-		<discard-dialog ref="discardDialogRef" @confirm="doDiscard" />
-		<!-- <hazardDialog ref="hazardDialogRef" @reload="doRectify" /> -->
-	</view>
+  <snapshot-list mode="manage" />
 </template>
 
 <script>
-	import myCard from "@/components/myCard.vue";
-	import snapshotDialog from './components/snapshotDialog.vue';
-	import discardDialog from './components/discardDialog.vue';
-	// import hazardDialog from '@/views/hazardManagement/hazardDialog.vue';
-	import {
-		getList,
-		discard,
-		handle
-	} from '@/api/snapshot/index.js';
-
-	export default {
-		components: {
-			myCard,
-			snapshotDialog,
-			discardDialog,
-			// hazardDialog
-		},
-		data() {
-			return {
-				where: {
-					reporterName: '',
-					handleResult: '',
-					createTime: ''
-				},
-				resultOptions: [{
-						value: 0,
-						text: '待处理'
-					},
-					{
-						value: 1,
-						text: '下发整改'
-					},
-					{
-						value: 2,
-						text: '废弃'
-					}
-				],
-				statusMap: {
-					0: '待处理',
-					1: '已整改',
-					2: '已废弃'
-				},
-				columns: [
-					[{
-						prop: 'location',
-						label: '位置',
-						className: 'perce100'
-					}],
-					[{
-						prop: 'problemDeptName',
-						label: '所属部门',
-						className: 'perce100'
-					}],
-					[{
-						prop: 'reporterName',
-						label: '上报人',
-						className: 'perce100'
-					}],
-					[{
-						prop: 'createTime',
-						label: '上报时间',
-						className: 'perce100'
-					}],
-					[{
-						prop: 'handleResult',
-						label: '处理结果',
-						className: 'perce100',
-						formatter: (row) => this.statusMap[row.handleResult]
-					}]
-				],
-				tableList: [],
-				page: 1,
-				size: 10,
-				isEnd: false,
-				currentId: null
-			};
-		},
-		computed: {
-			manageBtnList() {
-				return [{
-					name: '处理',
-					apiName: 'handleProcess',
-					btnType: 'primary',
-					judge: [{
-						fn: (item) => item.handleResult === 0
-					}]
-				}];
-			}
-		},
-		onLoad() {
-			this.getList();
-		},
-		methods: {
-			back() {
-				uni.navigateBack();
-			},
-			goDetail(item, type) {
-				this.$refs.snapshotDialog.open(type, item);
-			},
-			handleProcess(row) {
-				this.$refs.snapshotDialog.open('handle', row);
-			},
-			onRectify(data) {
-				this.currentId = data.id;
-				this.$refs.hazardDialogRef.open('add', '', 'report', {
-					sourceType: 4,
-					sourceId: data.id,
-					sourceName: '随手拍',
-					foundUserName: data.reporterName,
-					foundUserId: data.reporterId,
-					foundTime: data.createTime,
-					description: data.location + data.description,
-					reportAttachments: data.attachment
-				});
-			},
-			doRectify(opinion) {
-				handle({
-					id: this.currentId,
-					handleOpinion: opinion,
-					invHazardId: '下发整改'
-				}).then(() => {
-					uni.showToast({
-						title: '下发整改成功',
-						icon: 'success'
-					});
-					this.reloadList();
-				});
-			},
-			onDiscard(data) {
-				this.$refs.discardDialogRef.open(data);
-			},
-			doDiscard({
-				id,
-				handleOpinion
-			}) {
-				discard({
-					id,
-					handleOpinion
-				}).then(() => {
-					uni.showToast({
-						title: '废弃成功',
-						icon: 'success'
-					});
-					this.reloadList();
-				});
-			},
-			reloadList() {
-				this.page = 1;
-				this.isEnd = false;
-				this.getList();
-			},
-			handleSearch() {
-				this.page = 1;
-				this.isEnd = false;
-				this.getList();
-			},
-			async getList() {
-				if (this.isEnd) return;
-				uni.showLoading({
-					title: '加载中'
-				});
-				try {
-					const data = {
-						pageNum: this.page,
-						size: this.size,
-						reporterName: this.where.reporterName || undefined,
-						handleResult: this.where.handleResult !== '' ? this.where.handleResult : undefined,
-						createTime: this.where.createTime || undefined
-					};
-					const res = await getList(data);
-					const newList = res.rows || [];
-					if (this.page === 1) this.tableList = newList;
-					else this.tableList.push(...newList);
-					this.isEnd = newList.length < this.size;
-					this.page += 1;
-				} catch (e) {
-					console.error(e);
-				} finally {
-					uni.hideLoading();
-				}
-			},
-			scrolltolower() {
-				if (!this.isEnd) this.getList();
-			}
-		}
-	};
+import snapshotList from './components/snapshotList.vue';
+export default {
+  components: { snapshotList }
+};
 </script>
-
-<style lang="scss" scoped>
-	@import './common-style.scss';
-</style>

+ 2 - 2
pages/maintenance/service/OrderTask.vue

@@ -1,12 +1,12 @@
 <template>
 	<view class="content_box">
 		<!-- 站号筛选 -->
-		<view class="group-tab-bar rx-sc"  v-if="clientEnvironmentId == 10">
+		<!-- <view class="group-tab-bar rx-sc"  v-if="clientEnvironmentId == 10">
 			<view class="group-tab-item" v-for="(tab, idx) in groupTabs" :key="idx"
 				:class="{ active: groupId === tab.groupId }" @click="switchGroup(tab.groupId)">
 				{{ tab.label }}
 			</view>
-		</view>
+		</view> -->
 		<view class="list_box marginTop">
 			<u-list>
 				<u-list-item v-for="(item, index) in list" :key="index">

+ 1 - 1
pages/pcs/components/OrderListDialog.vue

@@ -43,7 +43,7 @@
 </template>
 
 <script>
-	import myCard from './myCard.vue';
+	import myCard from '@/components/myCard.vue';
 	import {
 		getPurchaseOrderList
 	} from '@/api/purchasingManage/index.js'

+ 1 - 1
pages/pcs/components/batchRevokeDialog.vue

@@ -41,7 +41,7 @@
 </template>
 
 <script>
-	import myCard from './myCard.vue';
+	import myCard from '@/components/myCard.vue';
 	import {
 		producetaskrulerecordQueryRecordWorkOrderPage,
 		batchRevokeOrder,

+ 0 - 378
pages/pcs/components/myCard.vue

@@ -1,378 +0,0 @@
-<template>
-  <view class="card_container">
-    <view class="card_box">
-      <!-- 标题区域 -->
-      <view class="header_box" v-if="title">
-        <view class="title_left">
-          <view class="round" v-if="index">{{ index }}</view>
-          <view class="orderId" :style="{ marginLeft: index ? '16rpx' : '' }">{{
-            title
-          }}</view>
-        </view>
-        <!-- 状态标签 -->
-        <view class="status-tag" v-if="status">{{ status }}</view>
-        <!-- 单选/多选控件 -->
-        <view class="select-tag" v-if="showRadio" @click.stop>
-          <!-- 单选模式:使用 u-radio-group(每个卡片独立,互斥) -->
-          <u-radio-group
-            v-if="selectionMode === 'single'"
-            v-model="radioValueModel"
-            placement="row"
-            @change="handleRadioChange"
-          >
-            <u-radio
-              :name="item.id"
-              :iconSize="44"
-              activeColor="#3c9cff"
-              :labelSize="0"
-            ></u-radio>
-          </u-radio-group>
-          <!-- 多选模式:使用独立 u-checkbox,由父组件控制选中状态 -->
-          <u-checkbox
-            v-else
-            :name="item.id"
-            :checked="isChecked"
-            :iconSize="44"
-            activeColor="#3c9cff"
-            :labelSize="0"
-            @change="handleCheckboxChange"
-          ></u-checkbox>
-        </view>
-      </view>
-
-      <!-- 内容区域(与原代码相同,省略...) -->
-      <view class="item_box rx-bc" v-for="(_item, i) in columns" :key="i">
-        <template v-for="val in _item">
-          <view
-            class="perce50"
-            :class="[val.className, { 'full-width': val.isFullWidth }]"
-            :style="val.style"
-            :key="val.prop"
-            v-if="!val.isNone"
-          >
-            <view class="item_one rx-sc" v-if="val.type == 'action'">
-              <view class="lable">{{ val.label }}</view>
-              <view class="text" style="flex-wrap: wrap">
-                <template v-for="(btn, bI) in btnList">
-                  <u-button
-                    :plain="true"
-                    :hairline="true"
-                    size="mini"
-                    :type="btn.btnType"
-                    v-if="judge(btn)"
-                    :text="btn.name"
-                    @click="action(btn)"
-                    :key="bI"
-                  ></u-button>
-                </template>
-              </view>
-            </view>
-            <view class="item_one rx-sc kk" v-else>
-              <view class="lable">{{ val.label }}</view>
-              <view class="text" :class="val.valueClass" v-if="val.formatter">{{
-                val.formatter(item) || ''
-              }}</view>
-              <view class="text" :class="val.valueClass" v-else-if="val.slot">
-                <slot :name="val.slot"></slot>
-              </view>
-              <view class="text" :class="val.valueClass" v-else>{{
-                item[val.prop] || ''
-              }}</view>
-            </view>
-          </view>
-        </template>
-      </view>
-
-      <view class="footer-link" v-if="showDetail" @click="goDetail">
-        <text>查看详情</text>
-        <u-icon name="arrow-right" size="24" color="#999999"></u-icon>
-      </view>
-    </view>
-  </view>
-</template>
-
-<script>
-export default {
-  props: {
-    btnList: { type: Array, default: () => [] },
-    item: { type: Object, default: () => ({}) },
-    columns: { type: Array, default: () => [] },
-    title: { type: String, default: '' },
-    status: { type: String, default: '' },
-    index: { type: [String, Number], default: '' },
-    showDetail: { type: Boolean, default: true },
-    showRadio: { type: Boolean, default: false },
-    radioValue: { type: [String, Number], default: null },
-    selectionMode: { type: String, default: 'single' }, // 'single' or 'multiple'
-    checkboxValue: { type: Array, default: () => [] },   // 父组件传入的选中ID数组
-  },
-  computed: {
-    judge() {
-      return (item) => {
-        if (item.judge) {
-          let is = true;
-          item.judge.forEach(({ key, value, authorities, fn }) => {
-            if (authorities) {
-              is = this.$isAuthorities(authorities);
-            }
-            if (value && !value.includes(this.item[key])) {
-              is = false;
-            }
-            if (fn) {
-              is = fn(this.item);
-            }
-          });
-          return is;
-        } else {
-          return true;
-        }
-      };
-    },
-    // 单选模式下的绑定值
-    radioValueModel: {
-      get() {
-        return this.radioValue;
-      },
-      set(val) {
-        if (val === this.item.id) {
-          this.$emit('radioChange', this.item);
-        }
-      },
-    },
-    // 多选模式下的选中状态(根据 checkboxValue 数组判断)
-    isChecked() {
-      return this.checkboxValue.includes(this.item.id);
-    },
-  },
-  methods: {
-    action(item) {
-      if (item.type == 1) {
-        uni.navigateTo({
-          url: item.pageUrl + '?id=' + this.item.id + (item.query || ''),
-        });
-      } else {
-        this.$emit(item.apiName);
-      }
-    },
-    goDetail() {
-      this.$emit('goDetail', this.item);
-    },
-    handleRadioChange(val) {
-      if (val === this.item.id) {
-        this.$emit('radioChange', this.item);
-      }
-    },
-    // 多选:点击 checkbox 时,通知父组件变更
-    handleCheckboxChange(e) {
-      this.$emit('checkboxChange', {
-        checked: e,        // e 为 boolean,表示当前 checkbox 是否被选中
-        item: this.item,
-      });
-    },
-  },
-};
-</script>
-<style lang="scss" scoped>
-.card_container {
-  padding: 16rpx 0;
-}
-
-.card_box {
-  background: #ffffff;
-  border-radius: 24rpx;
-  padding: 24rpx;
-  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
-  position: relative;
-
-  .rx-bc {
-    display: flex;
-    align-items: flex-start;
-    flex-flow: row wrap;
-
-    > view {
-      margin-top: 24rpx;
-
-      &:first-child,
-      &:nth-child(2) {
-        margin-top: 0;
-      }
-    }
-  }
-
-  .rx-sc {
-    display: flex;
-    align-items: flex-start;
-  }
-
-  .header_box {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    width: 100%;
-    position: relative;
-    background: linear-gradient(135deg, #eef5ff 0%, #f5f9ff 100%);
-    padding: 20rpx 24rpx;
-    border-radius: 20rpx 20rpx 0 0;
-    margin: -24rpx -24rpx 24rpx -24rpx;
-    width: calc(100% + 48rpx);
-    box-sizing: border-box;
-
-    .round {
-      width: 44rpx;
-      height: 44rpx;
-      line-height: 44rpx;
-      border-radius: 50%;
-      background: $theme-color;
-      color: #fff;
-      text-align: center;
-      font-size: 24rpx;
-      font-weight: 600;
-      flex-shrink: 0;
-    }
-
-    .orderId {
-      color: #1f2b3c;
-      font-size: 30rpx;
-      font-weight: 600;
-      white-space: nowrap;
-      overflow: hidden;
-      text-overflow: ellipsis;
-    }
-
-    .title_left {
-      display: flex;
-      align-items: center;
-      flex: 1;
-      padding-right: 120rpx;
-      overflow: hidden;
-    }
-
-    .status-tag {
-      background: #e3f2fd;
-      color: #2196f3;
-      font-size: 24rpx;
-      padding: 6rpx 20rpx;
-      border-radius: 30rpx;
-      font-weight: 500;
-      position: absolute;
-      top: 50%;
-      transform: translateY(-50%);
-      right: 24rpx;
-      z-index: 1;
-    }
-
-    .select-tag {
-      position: absolute;
-      top: 50%;
-      transform: translateY(-50%);
-      right: 24rpx;
-      z-index: 2;
-      background: transparent;
-
-      /deep/ .u-radio-group,
-      /deep/ .u-checkbox-group {
-        .u-radio,
-        .u-checkbox {
-          padding: 0;
-          margin-right: 0;
-        }
-      }
-    }
-  }
-
-  .item_box {
-    .text {
-      display: flex;
-      flex: 1;
-
-      uni-button:after {
-        border: none;
-      }
-
-      uni-button {
-        width: 100rpx;
-        margin-left: 10rpx;
-        margin-right: 0;
-        color: #fff !important;
-        border: none;
-        background: #157a2c;
-        margin-top: 3px;
-      }
-    }
-
-    .kk .text {
-      overflow: hidden;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-      display: block;
-    }
-
-    .item_one {
-      width: 100%;
-      font-size: 28rpx;
-      line-height: 44rpx;
-      display: flex;
-      align-items: flex-start;
-
-      .lable {
-        color: #8e9aae;
-        flex-shrink: 0;
-        margin-right: 16rpx;
-        font-size: 26rpx;
-      }
-
-      .text {
-        color: #1f2b3c;
-        font-size: 28rpx;
-        flex: 1;
-        white-space: nowrap;
-        overflow: hidden;
-        text-overflow: ellipsis;
-        min-width: 0;
-
-        &.highlight {
-          color: #4caf50;
-        }
-      }
-    }
-
-    .perce50 {
-      width: 50%;
-      box-sizing: border-box;
-      padding-right: 20rpx;
-
-      &:nth-child(2n) {
-        padding-right: 0;
-        padding-left: 20rpx;
-      }
-    }
-
-    .perce100 {
-      width: 100%;
-    }
-
-    .full-width {
-      width: 100% !important;
-      padding-left: 0 !important;
-      padding-right: 0 !important;
-    }
-  }
-
-  .footer-link {
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    margin-top: 24rpx;
-    padding-top: 20rpx;
-    border-top: 2rpx solid #f0f2f5;
-    color: #8e9aae;
-    font-size: 28rpx;
-    cursor: pointer;
-    gap: 8rpx;
-
-    &:active {
-      opacity: 0.7;
-    }
-  }
-}
-</style>

+ 2 - 1
pages/pcs/list.vue

@@ -74,7 +74,8 @@
 
 <script>
 	import dictMixns from "@/mixins/dictMixins";
-	import myCard from "./components/myCard.vue";
+	import myCard from "@/components/myCard.vue";
+
 	import Assign from "./components/Assign.vue";
 	import workOrderReport from "./components/workOrderReport.vue";
 	import batchRevokeDialog from "./components/batchRevokeDialog.vue";